Limbo 3.5.4
Loading...
Searching...
No Matches
GdsObjectHelpers.h
Go to the documentation of this file.
1
7
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>
16
18namespace GdsParser
19{
21namespace 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) {}
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) {}
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
145template <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) {}
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
180{
181
187template <typename ObjectType>
188inline 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
200template <>
201inline 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
218template <>
219inline 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;
235
240 ExtractCellObjectAction(GdsDB const& db, GdsCell const& sc, GdsCell& tc) : gdsDB(db), srcCell(sc), targetCell(tc) {}
244
252 template <typename ObjectType>
253 void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType* object)
254 {
256 }
257
259 std::string message() const
260 {
261 return "ExtractCellObjectAction";
262 }
263};
264
269{
270
272template<typename PointType>
274{
275 PointType offset;
276
279 Translate(PointType const& o) : offset(o) {}
280
283 void operator()(PointType& p) const
284 {
285 p = gtl::construct<PointType>(p.x()+offset.x(), p.y()+offset.y());
286 }
287};
288
289template<typename PointType>
290struct Rotate
291{
292 double angle;
293 double cosAngle;
294 double sinAngle;
295
298 Rotate(double a) : angle(a)
299 {
300 cosAngle = cos(angle/180.0*M_PI);
301 sinAngle = sin(angle/180.0*M_PI);
302 }
303
309 void operator()(PointType& p) const
310 {
311 p = gtl::construct<PointType>(
312 p.x()*cosAngle - p.y()*sinAngle,
313 p.x()*sinAngle + p.y()*cosAngle
314 );
315 }
316};
317
318template<typename PointType>
319struct MagScale
320{
321 double scaleX;
322 double scaleY;
323
327 MagScale(double sx, double sy) : scaleX(sx), scaleY(sy) {}
328
331 void operator()(PointType& p) const
332 {
333 p = gtl::construct<PointType>(p.x()*scaleX, p.y()*scaleY);
334 }
335};
336
337template<typename PointType>
339{
342 void operator()(PointType& p) const
343 {
344 p = gtl::construct<PointType>(p.x(), -p.y());
345 }
346};
347
353template <typename Iterator, typename TransformerType>
354inline void transform(Iterator first, Iterator last, TransformerType transform)
355{
356 for (; first != last; ++first)
357 transform(*first);
358}
359
364template <typename ObjectType>
365inline void copyToArray(std::vector<GdsCellReference::point_type>& vPoint, ObjectType* object)
366{
367 vPoint.assign(object->begin(), object->end());
368}
369
372template <>
373inline void copyToArray<GdsText>(std::vector<GdsCellReference::point_type>& vPoint, GdsText* object)
374{
375 vPoint.assign(1, object->position());
376}
377
381template <typename ObjectType>
382inline void copyFromArray(std::vector<GdsCellReference::point_type> const& vPoint, ObjectType* object)
383{
384 object->set(vPoint.begin(), vPoint.end());
385}
386
389template <>
390inline void copyFromArray<GdsText>(std::vector<GdsCellReference::point_type> const& vPoint, GdsText* object)
391{
392 object->setPosition(vPoint.front());
393}
394
399template <typename ObjectType>
400inline void apply(GdsCellReference const& cellRef, ObjectType* object)
401{
402 std::vector<GdsCellReference::point_type> vPoint;
403 std::vector<GdsCellReference::float_point_type> vFloatPoint;
404 copyToArray(vPoint, object);
405 // copy to temporary float point array
406 // use float point type to avoid numerical issues
407 vFloatPoint.reserve(vPoint.size());
408 for (std::vector<GdsCellReference::point_type>::const_iterator it = vPoint.begin(); it != vPoint.end(); ++it)
409 {
410 vFloatPoint.push_back(gtl::construct<GdsCellReference::float_point_type>(it->x(), it->y()));
411 }
412 // the order must be kept according to the manual
413 // strans
414 if (cellRef.strans() != std::numeric_limits<int>::max() && (cellRef.strans() & 0x8000)) // apply x reflection
415 {
416 transform(vFloatPoint.begin(), vFloatPoint.end(), XReflection<GdsCellReference::float_point_type>());
417 }
418 // magnification, magnification bit in strans must be set to 1 (KLayout does not honor this bit)
419 if (/*(cellRef.strans() & 0x4) &&*/ cellRef.magnification() != std::numeric_limits<double>::max())
420 {
421 transform(vFloatPoint.begin(), vFloatPoint.end(), MagScale<GdsCellReference::float_point_type>(cellRef.magnification(), cellRef.magnification()));
422 }
423 // angle, angle bit in strans must be set to 1 (KLayout does not honor this bit)
424 if (/*(cellRef.strans() & 0x2) &&*/ cellRef.angle() != std::numeric_limits<double>::max())
425 {
426 transform(vFloatPoint.begin(), vFloatPoint.end(), Rotate<GdsCellReference::float_point_type>(cellRef.angle()));
427 }
428 // position offset
429 if (cellRef.position().x() != std::numeric_limits<int>::max() && cellRef.position().y() != std::numeric_limits<int>::max())
430 {
431 transform(vFloatPoint.begin(), vFloatPoint.end(), Translate<GdsCellReference::float_point_type>(cellRef.position()));
432 }
433
434 // copy back
435 vPoint.clear();
436 for (std::vector<GdsCellReference::float_point_type>::const_iterator it = vFloatPoint.begin(); it != vFloatPoint.end(); ++it)
437 {
438 vPoint.push_back(gtl::construct<GdsCellReference::point_type>(round(it->x()), round(it->y())));
439 }
440 copyFromArray(vPoint, object);
441}
442
444template <>
445inline void apply<GdsCellReference>(GdsCellReference const& /*cellRef*/, GdsCellReference* /*object*/)
446{
447 limboAssertMsg(0, "should not arrive here");
448}
449
451template <>
452inline void apply<GdsCellArray>(GdsCellReference const& /*cellRef*/, GdsCellArray* /*object*/)
453{
454 limboAssertMsg(0, "should not arrive here");
455}
456
457} // namespace ApplyCellReferenceActionDetails
458
462{
464
471
475 template <typename ObjectType>
476 void operator()(::GdsParser::GdsRecords::EnumType /*type*/, ObjectType* object)
477 {
479 }
480
482 std::string message() const
483 {
484 return "ApplyCellReferenceAction";
485 }
486};
487
488} // namespace GdsDB
489} // namespace GdsParser
490
491#endif
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
#define limboAssert(condition)
custom assertion without message
Definition AssertMsg.h:36
read GDSII file
write GDSII file
header to include PrintMsg.h and AssertMsg.h
std::vector< std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > > const & objects() const
Definition GdsObjects.h:632
std::string const & name() const
Definition GdsObjects.h:627
std::string const & refCell() const
Definition GdsObjects.h:424
point_type const & position() const
Definition GdsObjects.h:429
point_type const & position() const
Definition GdsObjects.h:354
An action function to apply changes to a copied cell reference. It contains various transformers.
void copyFromArray(std::vector< GdsCellReference::point_type > const &vPoint, ObjectType *object)
copy points of objects from array
void transform(Iterator first, Iterator last, TransformerType transform)
Transform operation over an array.
void copyToArray< GdsText >(std::vector< GdsCellReference::point_type > &vPoint, GdsText *object)
copy points of objects to array
void apply(GdsCellReference const &cellRef, ObjectType *object)
apply cell reference
void apply< GdsCellArray >(GdsCellReference const &, GdsCellArray *)
no reference to cell array; it should not reach here
void copyFromArray< GdsText >(std::vector< GdsCellReference::point_type > const &vPoint, GdsText *object)
copy points of objects from array
void apply< GdsCellReference >(GdsCellReference const &, GdsCellReference *)
no reference to cell reference; it should not reach here
void copyToArray(std::vector< GdsCellReference::point_type > &vPoint, ObjectType *object)
copy points of objects to array
Detailed action functions for extract objects of a cell.
void extract< GdsCellReference >(GdsDB const &gdsDB, GdsCell const &srcCell, GdsCell &targetCell, ::GdsParser::GdsRecords::EnumType type, GdsCellReference *object)
void extract(GdsDB const &, GdsCell const &, GdsCell &targetCell, ::GdsParser::GdsRecords::EnumType type, ObjectType *object)
void extract< GdsCellArray >(GdsDB const &, GdsCell const &, GdsCell &, ::GdsParser::GdsRecords::EnumType type, GdsCellArray *)
namespace for Limbo.GdsParser.GdsDB
Definition GdsIO.h:23
namespace for Limbo.GdsParser
Definition GdsIO.h:20
void operator()(PointType &p) const
API to run operation.
void operator()(PointType &p) const
API to run operation. Transformation matrix cos(theta) -sin(theta) sin(theta) cos(theta).
void operator()(PointType &p) const
API to run operation.
void operator()(PointType &p) const
API to run operation.
void operator()(::GdsParser::GdsRecords::EnumType, ObjectType *object)
API to run the action.
GdsCellReference const & cellRef
CREF object.
ApplyCellReferenceAction(GdsCellReference const &cr)
constructor
ApplyCellReferenceAction(ApplyCellReferenceAction const &rhs)
CopyCellObjectAction(std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > &t)
constructor
CopyCellObjectAction(CopyCellObjectAction const &rhs)
copy constructor
std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > & target
target cell
void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType *object)
API to run the copy action.
std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > & target
target cell
void operator()(::GdsParser::GdsRecords::EnumType, ObjectType *object)
API to run the copy action.
DeleteCellObjectAction(std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > &t)
constructor
DeleteCellObjectAction(DeleteCellObjectAction const &rhs)
copy constructor
ExtractCellObjectAction(ExtractCellObjectAction const &rhs)
copy constructor
void operator()(::GdsParser::GdsRecords::EnumType type, ObjectType *object)
API to run the extraction.
ExtractCellObjectAction(GdsDB const &db, GdsCell const &sc, GdsCell &tc)
constructor
a helper to facilitate actions on different GDSII objects.
void operator()(::GdsParser::GdsRecords::EnumType type, GdsObject *object, ActionType action) const
API to run the actions over all GDSII objects.
::GdsParser::GdsWriter & gdsWriter
GDSII writer.
GdsWriterType const & writer
wrapper of GDSII writer which will invoke GdsParser::GdsWriter to write
std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > const & target
target object
void operator()(::GdsParser::GdsRecords::EnumType, ObjectType *object)
API to run the writing action.
WriteCellObjectAction(WriteCellObjectAction const &rhs)
copy constructor
WriteCellObjectAction(GdsWriterType const &w, ::GdsParser::GdsWriter &gw, std::pair< ::GdsParser::GdsRecords::EnumType, GdsObject * > const &t)
constructor
EnumType
enum type of GDSII records
Definition GdsRecords.h:23