Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GdsObjectHelpers.h
Go to the documentation of this file.
1 
8 #ifndef LIMBO_PARSERS_GDSII_GDSDB_GDSOBJECTHELPERS_H
9 #define LIMBO_PARSERS_GDSII_GDSDB_GDSOBJECTHELPERS_H
10 
11 #include <cmath>
12 #include <boost/geometry/strategies/transform.hpp>
15 #include <limbo/preprocessor/Msg.h>
16 
18 namespace GdsParser
19 {
21 namespace GdsDB
22 {
23 
30 {
36  template <typename ActionType>
37  void operator()(::GdsParser::GdsRecords::EnumType type, GdsObject* object, ActionType action) const
38  {
39  try
40  {
41  switch (type)
42  {
43  case ::GdsParser::GdsRecords::BOUNDARY:
44  {
45  GdsPolygon* ptr = dynamic_cast<GdsPolygon*>(object);
46  action(type, ptr);
47  }
48  break;
49  case ::GdsParser::GdsRecords::PATH:
50  {
51  GdsPath* ptr = dynamic_cast<GdsPath*>(object);
52  action(type, ptr);
53  }
54  break;
55  case ::GdsParser::GdsRecords::TEXT:
56  {
57  GdsText* ptr = dynamic_cast<GdsText*>(object);
58  action(type, ptr);
59  }
60  break;
61  case ::GdsParser::GdsRecords::SREF:
62  {
63  GdsCellReference* ptr = dynamic_cast<GdsCellReference*>(object);
64  action(type, ptr);
65  }
66  break;
67  case ::GdsParser::GdsRecords::AREF:
68  {
69  GdsCellArray* ptr = dynamic_cast<GdsCellArray*>(object);
70  action(type, ptr);
71  }
72  break;
73  default:
74  limboAssertMsg(0, "unsupported type %d\n", type);
75  }
76  }
77  catch (std::exception& e)
78  {
79  limboPrint(limbo::kERROR, "exception in action %s: %s\n", action.message().c_str(), e.what());
80  limboAssert(0);
81  }
82  }
83 };
84 
87 {
88  std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject*>& target;
89 
92  CopyCellObjectAction(std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject*>& t) : target(t) {}
95  CopyCellObjectAction(CopyCellObjectAction const& rhs) : target(rhs.target) {}
96 
101  template <typename ObjectType>
102  void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType* object)
103  {
104  target.first = type;
105  target.second = new ObjectType(*object);
106  }
107 
109  std::string message() const
110  {
111  return "CopyCellObjectAction";
112  }
113 };
114 
117 {
118  std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject*>& target;
119 
122  DeleteCellObjectAction(std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject*>& t) : target(t) {}
125  DeleteCellObjectAction(DeleteCellObjectAction const& rhs) : target(rhs.target) {}
126 
130  template <typename ObjectType>
131  void operator()(::GdsParser::GdsRecords::EnumType /*type*/, ObjectType* object)
132  {
133  delete object;
134  }
135 
137  std::string message() const
138  {
139  return "DeleteCellObjectAction";
140  }
141 };
142 
145 template <typename GdsWriterType>
147 {
148  GdsWriterType const& writer;
150  std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject*> const& target;
151 
156  WriteCellObjectAction(GdsWriterType const& w, ::GdsParser::GdsWriter& gw, std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject*> const& t) : writer(w), gdsWriter(gw), target(t) {}
159  WriteCellObjectAction(WriteCellObjectAction const& rhs) : writer(rhs.writer), gdsWriter(rhs.gdsWriter), target(rhs.target) {}
160 
164  template <typename ObjectType>
165  void operator()(::GdsParser::GdsRecords::EnumType /*type*/, ObjectType* object)
166  {
167  writer.write(gdsWriter, *object);
168  }
169 
171  std::string message() const
172  {
173  return "WriteCellObjectAction";
174  }
175 };
176 
179 namespace ExtractCellObjectActionDetails
180 {
181 
187 template <typename ObjectType>
188 inline void extract(GdsDB const& /*gdsDB*/, GdsCell const& /*srcCell*/, GdsCell& targetCell, ::GdsParser::GdsRecords::EnumType type, ObjectType* object)
189 {
190  ObjectType* ptr = new ObjectType (*object);
191  targetCell.objects().push_back(std::make_pair(type, ptr));
192 }
193 
200 template <>
201 inline void extract<GdsCellReference>(GdsDB const& gdsDB, GdsCell const& srcCell, GdsCell& targetCell, ::GdsParser::GdsRecords::EnumType type, GdsCellReference* object)
202 {
203  limboAssert(type == ::GdsParser::GdsRecords::SREF);
204  limboAssertMsg(srcCell.name() != object->refCell(), "self reference of cell %s", srcCell.name().c_str());
205  GdsCell const* refCell = gdsDB.getCell(object->refCell());
206  limboAssertMsg(refCell, "failed to find reference cell %s", object->refCell().c_str());
207  // generate a new cell from reference
208  GdsCell cell = object->extractCellRef(gdsDB, *refCell);
209  // directly append object pointers to target cell
210  targetCell.objects().insert(targetCell.objects().end(), cell.objects().begin(), cell.objects().end());
211  // must clear the list, otherwise, the pointers are destroyed
212  cell.objects().clear();
213 }
214 
218 template <>
219 inline void extract<GdsCellArray>(GdsDB const& /*gdsDB*/, GdsCell const& /*srcCell*/, GdsCell& /*targetCell*/, ::GdsParser::GdsRecords::EnumType type, GdsCellArray* /*object*/)
220 {
221  limboAssert(type == ::GdsParser::GdsRecords::AREF);
222  limboAssertMsg(0, "not implemented yet");
223 }
224 
225 } // namespace ExtractCellObjectActionDetails
226 
231 {
232  GdsDB const& gdsDB;
233  GdsCell const& srcCell;
235 
240  ExtractCellObjectAction(GdsDB const& db, GdsCell const& sc, GdsCell& tc) : gdsDB(db), srcCell(sc), targetCell(tc) {}
243  ExtractCellObjectAction(ExtractCellObjectAction const& rhs) : gdsDB(rhs.gdsDB), srcCell(rhs.srcCell), targetCell(rhs.targetCell) {}
244 
252  template <typename ObjectType>
253  void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType* object)
254  {
255  ExtractCellObjectActionDetails::extract(gdsDB, srcCell, targetCell, type, object);
256  }
257 
259  std::string message() const
260  {
261  return "ExtractCellObjectAction";
262  }
263 };
264 
268 namespace ApplyCellReferenceActionDetails
269 {
270 
272 struct Translate
273 {
274  GdsCellReference::point_type offset;
275 
278  Translate(GdsCellReference::point_type const& o) : offset(o) {}
279 
282  void operator()(GdsCellReference::point_type& p) const
283  {
284  p = gtl::construct<GdsCellReference::point_type>(p.x()+offset.x(), p.y()+offset.y());
285  }
286 };
288 struct Rotate
289 {
290  double angle;
291  double cosAngle;
292  double sinAngle;
293 
296  Rotate(double a) : angle(a)
297  {
298  cosAngle = cos(angle/180.0*M_PI);
299  sinAngle = sin(angle/180.0*M_PI);
300  }
301 
307  void operator()(GdsCellReference::point_type& p) const
308  {
309  p = gtl::construct<GdsCellReference::point_type>(
310  p.x()*cosAngle - p.y()*sinAngle,
311  p.x()*sinAngle + p.y()*cosAngle
312  );
313  }
314 };
316 struct MagScale
317 {
318  double scaleX;
319  double scaleY;
320 
324  MagScale(double sx, double sy) : scaleX(sx), scaleY(sy) {}
325 
328  void operator()(GdsCellReference::point_type& p) const
329  {
330  p = gtl::construct<GdsCellReference::point_type>(p.x()*scaleX, p.y()*scaleY);
331  }
332 };
335 {
338  void operator()(GdsCellReference::point_type& p) const
339  {
340  p = gtl::construct<GdsCellReference::point_type>(p.x(), -p.y());
341  }
342 };
343 
349 template <typename Iterator, typename TransformerType>
350 inline void transform(Iterator first, Iterator last, TransformerType transform)
351 {
352  for (; first != last; ++first)
353  transform(*first);
354 }
355 
360 template <typename ObjectType>
361 inline void copyToArray(std::vector<GdsCellReference::point_type>& vPoint, ObjectType* object)
362 {
363  vPoint.assign(object->begin(), object->end());
364 }
368 template <>
369 inline void copyToArray<GdsText>(std::vector<GdsCellReference::point_type>& vPoint, GdsText* object)
370 {
371  vPoint.assign(1, object->position());
372 }
377 template <typename ObjectType>
378 inline void copyFromArray(std::vector<GdsCellReference::point_type> const& vPoint, ObjectType* object)
379 {
380  object->set(vPoint.begin(), vPoint.end());
381 }
385 template <>
386 inline void copyFromArray<GdsText>(std::vector<GdsCellReference::point_type> const& vPoint, GdsText* object)
387 {
388  object->setPosition(vPoint.front());
389 }
390 
395 template <typename ObjectType>
396 inline void apply(GdsCellReference const& cellRef, ObjectType* object)
397 {
398  std::vector<GdsCellReference::point_type> vPoint;
399  copyToArray(vPoint, object);
400  // the order must be kept according to the manual
401  // strans
402  if (cellRef.strans() != std::numeric_limits<int>::max() && cellRef.strans()/32768 > 0) // apply x reflection
403  {
404  transform(vPoint.begin(), vPoint.end(), XReflection());
405  }
406  // magnification
408  {
409  transform(vPoint.begin(), vPoint.end(), MagScale(cellRef.magnification(), cellRef.magnification()));
410  }
411  // angle
412  if (cellRef.angle() != std::numeric_limits<double>::max())
413  {
414  transform(vPoint.begin(), vPoint.end(), Rotate(cellRef.angle()));
415  }
416  // position offset
417  if (cellRef.position().x() != std::numeric_limits<int>::max() && cellRef.position().y() != std::numeric_limits<int>::max())
418  {
419  transform(vPoint.begin(), vPoint.end(), Translate(cellRef.position()));
420  }
421  copyFromArray(vPoint, object);
422 }
423 
425 template <>
426 inline void apply<GdsCellReference>(GdsCellReference const& /*cellRef*/, GdsCellReference* /*object*/)
427 {
428  limboAssertMsg(0, "should not arrive here");
429 }
430 
432 template <>
433 inline void apply<GdsCellArray>(GdsCellReference const& /*cellRef*/, GdsCellArray* /*object*/)
434 {
435  limboAssertMsg(0, "should not arrive here");
436 }
437 
438 } // namespace ApplyCellReferenceActionDetails
439 
443 {
445 
448  ApplyCellReferenceAction(GdsCellReference const& cr) : cellRef(cr) {}
451  ApplyCellReferenceAction(ApplyCellReferenceAction const& rhs) : cellRef(rhs.cellRef) {}
452 
456  template <typename ObjectType>
457  void operator()(::GdsParser::GdsRecords::EnumType /*type*/, ObjectType* object)
458  {
460  }
461 
463  std::string message() const
464  {
465  return "ApplyCellReferenceAction";
466  }
467 };
468 
469 } // namespace GdsDB
470 } // namespace GdsParser
471 
472 #endif
DeleteCellObjectAction(std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > &t)
constructor
header to include PrintMsg.h and AssertMsg.h
ApplyCellReferenceAction(ApplyCellReferenceAction const &rhs)
a helper to facilitate actions on different GDSII objects.
void apply(GdsCellReference const &cellRef, ObjectType *object)
apply cell reference
ExtractCellObjectAction(GdsDB const &db, GdsCell const &sc, GdsCell &tc)
constructor
WriteCellObjectAction(WriteCellObjectAction const &rhs)
copy constructor
void copyToArray(std::vector< GdsCellReference::point_type > &vPoint, ObjectType *object)
copy points of objects to array
std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > & target
target cell
void transform(Iterator first, Iterator last, TransformerType transform)
Transform operation over an array.
void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType *object)
API to run the extraction.
point_type const & position() const
Definition: GdsObjects.h:415
Translate(GdsCellReference::point_type const &o)
constructor
GdsWriterType const & writer
wrapper of GDSII writer which will invoke GdsParser::GdsWriter to write
void apply< GdsCellArray >(GdsCellReference const &, GdsCellArray *)
no reference to cell array; it should not reach here
void operator()(::GdsParser::GdsRecords::EnumType, ObjectType *object)
API to run the copy action.
void extract< GdsCellReference >(GdsDB const &gdsDB, GdsCell const &srcCell, GdsCell &targetCell,::GdsParser::GdsRecords::EnumType type, GdsCellReference *object)
write GDSII file
void extract(GdsDB const &, GdsCell const &, GdsCell &targetCell,::GdsParser::GdsRecords::EnumType type, ObjectType *object)
std::vector< std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > > const & objects() const
Definition: GdsObjects.h:616
std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > const & target
target object
GdsDB const & gdsDB
GDSII database.
void copyFromArray< GdsText >(std::vector< GdsCellReference::point_type > const &vPoint, GdsText *object)
copy points of objects from array
ExtractCellObjectAction(ExtractCellObjectAction const &rhs)
copy constructor
void operator()(GdsCellReference::point_type &p) const
API to run operation.
Action function object to extract cell.
std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > & target
target cell
an action function for delete a cell
CopyCellObjectAction(CopyCellObjectAction const &rhs)
copy constructor
ApplyCellReferenceAction(GdsCellReference const &cr)
constructor
void extract< GdsCellArray >(GdsDB const &, GdsCell const &, GdsCell &,::GdsParser::GdsRecords::EnumType type, GdsCellArray *)
an action function for copy a cell
namespace for Limbo.GdsParser
Definition: GdsIO.h:19
void copyFromArray(std::vector< GdsCellReference::point_type > const &vPoint, ObjectType *object)
copy points of objects from array
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition: Math.h:61
Apply cell reference action. It needs to call functions in GdsParser::GdsDB::ApplyCellReferenceAction...
void apply< GdsCellReference >(GdsCellReference const &, GdsCellReference *)
no reference to cell reference; it should not reach here
GdsCellReference const & cellRef
CREF object.
#define limboAssert(condition)
custom assertion without message
Definition: AssertMsg.h:64
int limboPrint(MessageType m, const char *format,...)
formatted print with prefix
Definition: PrintMsg.h:49
void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType *object)
API to run the copy action.
WriteCellObjectAction(GdsWriterType const &w,::GdsParser::GdsWriter &gw, std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > const &t)
constructor
void operator()(::GdsParser::GdsRecords::EnumType type, GdsObject *object, ActionType action) const
API to run the actions over all GDSII objects.
read GDSII file
CopyCellObjectAction(std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > &t)
constructor
void operator()(::GdsParser::GdsRecords::EnumType, ObjectType *object)
API to run the action.
EnumType
enum type of GDSII records
Definition: GdsRecords.h:23
void operator()(GdsCellReference::point_type &p) const
API to run operation.
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition: AssertMsg.h:52
DeleteCellObjectAction(DeleteCellObjectAction const &rhs)
copy constructor
void operator()(GdsCellReference::point_type &p) const
API to run operation. Transformation matrix cos(theta) -sin(theta) sin(theta) cos(theta) ...
::GdsParser::GdsWriter & gdsWriter
GDSII writer.
void operator()(GdsCellReference::point_type &p) const
API to run operation.
void operator()(::GdsParser::GdsRecords::EnumType, ObjectType *object)
API to run the writing action.
void copyToArray< GdsText >(std::vector< GdsCellReference::point_type > &vPoint, GdsText *object)
copy points of objects to array