mirror of https://github.com/KLayout/klayout.git
[consider merging] Restricting transformation of shape refs and detecting some issues related to that.
This commit is contained in:
parent
8c935409ea
commit
8a9d7c6d15
|
|
@ -69,6 +69,7 @@ SOURCES = \
|
|||
dbNetlistSpiceReaderDelegate.cc \
|
||||
dbNetlistSpiceReaderExpressionParser.cc \
|
||||
dbObject.cc \
|
||||
dbObjectWithProperties.cc \
|
||||
dbPath.cc \
|
||||
dbPCellDeclaration.cc \
|
||||
dbPCellHeader.cc \
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "dbCommon.h"
|
||||
#include "dbLocalOperation.h"
|
||||
#include "dbHierProcessor.h"
|
||||
#include "dbHierProcessorUtils.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
#include "dbRegionDelegate.h"
|
||||
#include "dbRegion.h"
|
||||
|
|
@ -1331,8 +1332,10 @@ private:
|
|||
|
||||
if (! res.empty ()) {
|
||||
db::ICplxTrans tri = tr.inverted ();
|
||||
db::shape_reference_translator_with_trans<T, db::ICplxTrans> trans_op (layout);
|
||||
trans_op.set_trans (tri);
|
||||
for (auto r = res.begin (); r != res.end (); ++r) {
|
||||
results.front ().insert (tri * *r);
|
||||
results.front ().insert (trans_op (*r));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1466,8 +1469,10 @@ private:
|
|||
|
||||
if (! res.empty ()) {
|
||||
db::ICplxTrans tri = tr.inverted ();
|
||||
db::shape_reference_translator_with_trans<T, db::ICplxTrans> trans_op (layout);
|
||||
trans_op.set_trans (tri);
|
||||
for (auto r = res.begin (); r != res.end (); ++r) {
|
||||
results.front ().insert (tri * *r);
|
||||
results.front ().insert (trans_op (*r));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1070,38 +1070,14 @@ EdgeProcessor::count () const
|
|||
return mp_work_edges->size ();
|
||||
}
|
||||
|
||||
void
|
||||
EdgeProcessor::insert (const db::Edge &e, EdgeProcessor::property_type p)
|
||||
void
|
||||
EdgeProcessor::insert (const db::Edge &e, property_type p)
|
||||
{
|
||||
if (e.p1 () != e.p2 ()) {
|
||||
mp_work_edges->push_back (WorkEdge (e, p));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EdgeProcessor::insert (const db::SimplePolygon &q, EdgeProcessor::property_type p)
|
||||
{
|
||||
for (db::SimplePolygon::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (*e, p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EdgeProcessor::insert (const db::Polygon &q, EdgeProcessor::property_type p)
|
||||
{
|
||||
for (db::Polygon::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (*e, p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EdgeProcessor::insert (const db::PolygonRef &q, EdgeProcessor::property_type p)
|
||||
{
|
||||
for (db::PolygonRef::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (*e, p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EdgeProcessor::clear ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -705,20 +705,77 @@ public:
|
|||
*/
|
||||
void insert (const db::Edge &e, property_type p = 0);
|
||||
|
||||
/**
|
||||
* @brief Insert an edge with transformation
|
||||
*/
|
||||
template <class Trans>
|
||||
void insert_with_trans (const db::Edge &e, const Trans &tr, property_type p = 0)
|
||||
{
|
||||
insert (tr * e, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a polygon
|
||||
*/
|
||||
void insert (const db::Polygon &q, property_type p = 0);
|
||||
void insert (const db::Polygon &q, property_type p = 0)
|
||||
{
|
||||
for (db::Polygon::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (*e, p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a polygon with transformation
|
||||
*/
|
||||
template <class Trans>
|
||||
void insert_with_trans (const db::Polygon &q, const Trans &tr, property_type p = 0)
|
||||
{
|
||||
for (db::Polygon::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (tr * *e, p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a simple polygon
|
||||
*/
|
||||
void insert (const db::SimplePolygon &q, property_type p = 0);
|
||||
void insert (const db::SimplePolygon &q, property_type p = 0)
|
||||
{
|
||||
for (db::SimplePolygon::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (*e, p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a simple polygon with transformation
|
||||
*/
|
||||
template <class Trans>
|
||||
void insert_with_trans (const db::SimplePolygon &q, const Trans &tr, property_type p = 0)
|
||||
{
|
||||
for (db::SimplePolygon::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (tr * *e, p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a polygon reference
|
||||
*/
|
||||
void insert (const db::PolygonRef &q, property_type p = 0);
|
||||
void insert (const db::PolygonRef &q, property_type p = 0)
|
||||
{
|
||||
for (db::PolygonRef::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (*e, p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a polygon reference with transformation
|
||||
*/
|
||||
template <class Trans>
|
||||
void insert_with_trans (const db::PolygonRef &q, const Trans &tr, property_type p = 0)
|
||||
{
|
||||
for (db::PolygonRef::polygon_edge_iterator e = q.begin_edge (); ! e.at_end (); ++e) {
|
||||
insert (tr * *e, p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a sequence of edges
|
||||
|
|
|
|||
|
|
@ -257,6 +257,18 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <class Trans>
|
||||
class shape_reference_translator_with_trans<db::TextRef, Trans>
|
||||
: public shape_reference_translator_with_trans_from_shape_ref<db::TextRef, Trans>
|
||||
{
|
||||
public:
|
||||
shape_reference_translator_with_trans (db::Layout *target_layout)
|
||||
: shape_reference_translator_with_trans_from_shape_ref<db::TextRef, Trans> (target_layout)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
};
|
||||
|
||||
template <class Sh, class Trans>
|
||||
class shape_reference_translator_with_trans
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1688,7 +1688,7 @@ compute_area_and_perimeter_of_net_shapes (const db::hier_clusters<db::NetShape>
|
|||
|
||||
size_t p = 0;
|
||||
for (db::recursive_cluster_shape_iterator<db::NetShape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
|
||||
ep.insert (rci.trans () * rci->polygon_ref (), ++p);
|
||||
ep.insert_with_trans (rci->polygon_ref (), rci.trans (), ++p);
|
||||
}
|
||||
|
||||
PolygonAreaAndPerimeterCollector ap_collector;
|
||||
|
|
@ -1743,15 +1743,16 @@ get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::c
|
|||
|
||||
size_t p = 0;
|
||||
for (db::recursive_cluster_shape_iterator<db::NetShape> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
|
||||
db::PolygonRef pr = (rci.trans () * rci->polygon_ref ());
|
||||
db::PolygonRef pr = rci->polygon_ref ();
|
||||
db::PolygonRef::polygon_edge_iterator e = pr.begin_edge ();
|
||||
if (! e.at_end ()) {
|
||||
// pick one reference point for the label
|
||||
if (! any_ref || (*e).p1 () < ref) {
|
||||
ref = (*e).p1 ();
|
||||
auto p1 = (rci.trans () * *e).p1 ();
|
||||
if (! any_ref || p1 < ref) {
|
||||
ref = p1;
|
||||
any_ref = true;
|
||||
}
|
||||
ep.insert (pr, ++p);
|
||||
ep.insert_with_trans (pr, rci.trans (), ++p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "dbObjectWithProperties.h"
|
||||
#include "dbUserObject.h"
|
||||
#include "dbText.h"
|
||||
#include "dbPolygon.h"
|
||||
#include "dbBox.h"
|
||||
#include "dbPath.h"
|
||||
#include "dbPoint.h"
|
||||
#include "dbEdge.h"
|
||||
#include "dbEdgePair.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// explicit instantiations
|
||||
|
||||
template class db::object_with_properties<db::Box>;
|
||||
template class db::object_with_properties<db::UserObject>;
|
||||
template class db::object_with_properties<db::Polygon>;
|
||||
template class db::object_with_properties<db::SimplePolygon>;
|
||||
template class db::object_with_properties<db::Path>;
|
||||
template class db::object_with_properties<db::Text>;
|
||||
template class db::object_with_properties<db::Point>;
|
||||
template class db::object_with_properties<db::Edge>;
|
||||
template class db::object_with_properties<db::EdgePair>;
|
||||
|
||||
template class db::object_with_properties<db::DBox>;
|
||||
template class db::object_with_properties<db::DUserObject>;
|
||||
template class db::object_with_properties<db::DPolygon>;
|
||||
template class db::object_with_properties<db::DSimplePolygon>;
|
||||
template class db::object_with_properties<db::DPath>;
|
||||
template class db::object_with_properties<db::DText>;
|
||||
template class db::object_with_properties<db::DPoint>;
|
||||
template class db::object_with_properties<db::DEdge>;
|
||||
template class db::object_with_properties<db::DEdgePair>;
|
||||
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#define HDR_dbObjectWithProperties
|
||||
|
||||
#include "tlException.h"
|
||||
#include "tlTypeTraits.h"
|
||||
#include "dbTypes.h"
|
||||
#include "dbPolygon.h"
|
||||
#include "dbPath.h"
|
||||
|
|
@ -43,6 +44,17 @@ class ArrayRepository;
|
|||
|
||||
DB_PUBLIC bool properties_id_less (properties_id_type a, properties_id_type b);
|
||||
|
||||
template <class Obj> class object_with_properties;
|
||||
|
||||
/**
|
||||
* @brief A helper method to create an object with properties
|
||||
*/
|
||||
template <class Obj>
|
||||
inline db::object_with_properties<Obj> make_object_with_properties (const Obj &obj, db::properties_id_type pid)
|
||||
{
|
||||
return db::object_with_properties<Obj> (obj, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A object with properties template
|
||||
*
|
||||
|
|
@ -192,9 +204,36 @@ public:
|
|||
* @brief Returns the transformed object
|
||||
*/
|
||||
template <class Trans>
|
||||
object_with_properties<Obj> transformed (const Trans &tr) const
|
||||
auto transformed (const Trans &tr) const
|
||||
{
|
||||
return object_with_properties<Obj> (Obj::transformed (tr), m_id);
|
||||
return make_object_with_properties (Obj::transformed (tr), m_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In-place transformation
|
||||
*/
|
||||
template <class Trans>
|
||||
db::object_with_properties<Obj> &transform (const Trans &tr)
|
||||
{
|
||||
Obj::transform (tr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the transformed object
|
||||
*/
|
||||
db::object_with_properties<Obj> moved (const typename Obj::vector_type &v) const
|
||||
{
|
||||
return make_object_with_properties (Obj::moved (v), m_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In-place move
|
||||
*/
|
||||
db::object_with_properties<Obj> &move (const typename Obj::vector_type &v)
|
||||
{
|
||||
Obj::move (v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -246,6 +285,48 @@ typedef object_with_properties<DBox> DBoxWithProperties;
|
|||
typedef object_with_properties<db::array<db::CellInst, db::Trans> > CellInstArrayWithProperties;
|
||||
typedef object_with_properties<db::array<db::CellInst, db::DTrans> > DCellInstArrayWithProperties;
|
||||
|
||||
/**
|
||||
* @brief Binary * operator (transformation)
|
||||
*
|
||||
* Transforms the object with the given transformation and
|
||||
* returns the result.
|
||||
*
|
||||
* @param t The transformation to apply
|
||||
* @param obj The object to transform
|
||||
* @return t * obj
|
||||
*/
|
||||
|
||||
template <class R>
|
||||
struct result_of_transformation;
|
||||
|
||||
template <class R, class Obj, class Tr>
|
||||
struct result_of_transformation<R (Obj::*) (const Tr &) const>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template <class Tr, class Obj>
|
||||
inline db::object_with_properties<typename result_of_transformation<decltype (& Obj::template transformed<Tr>)>::type>
|
||||
operator* (const Tr &t, const db::object_with_properties<Obj> &obj)
|
||||
{
|
||||
return db::object_with_properties<typename result_of_transformation<decltype (& Obj::template transformed<Tr>)>::type> (obj.Obj::transformed (t), obj.properties_id ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Binary * operator (scaling)
|
||||
*
|
||||
* @param obj The object to scale.
|
||||
* @param s The scaling factor
|
||||
*
|
||||
* @return The scaled object
|
||||
*/
|
||||
template <class Obj>
|
||||
inline db::object_with_properties<Obj>
|
||||
operator* (const db::object_with_properties<Obj> &obj, double s)
|
||||
{
|
||||
return db::object_with_properties<Obj> (((const Obj &) obj) * s, obj.properties_id ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Output stream insertion operator
|
||||
*/
|
||||
|
|
@ -256,16 +337,6 @@ operator<< (std::ostream &os, const object_with_properties<T> &p)
|
|||
return (os << p.to_string ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transformation of an object with properties
|
||||
*/
|
||||
template <class Tr, class T>
|
||||
inline db::object_with_properties<T>
|
||||
operator* (const Tr &t, const db::object_with_properties<T> &s)
|
||||
{
|
||||
return db::object_with_properties<T> (s.transformed (t), s.properties_id ());
|
||||
}
|
||||
|
||||
} // namespace db
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1016,9 +1016,8 @@ struct path_ref
|
|||
*
|
||||
* The path pointer passed is assumed to reside in a proper repository.
|
||||
*/
|
||||
template <class TransIn>
|
||||
path_ref (const path_type *p, const TransIn &t)
|
||||
: shape_ref<Path, Trans> (p, Trans (t))
|
||||
path_ref (const path_type *p, const Trans &t)
|
||||
: shape_ref<Path, Trans> (p, t)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -1035,19 +1034,6 @@ struct path_ref
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The transformation translation constructor
|
||||
*
|
||||
* This constructor allows one to copy a path reference with a certain transformation
|
||||
* to one with another transformation
|
||||
*/
|
||||
template <class TransIn>
|
||||
path_ref (const path_ref<Path, TransIn> &ref)
|
||||
: shape_ref<Path, Trans> (ref.ptr (), Trans (ref.trans ()))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The point iterator begin function
|
||||
*
|
||||
|
|
@ -1080,7 +1066,7 @@ struct path_ref
|
|||
template <class TargetTrans>
|
||||
path_ref<Path, TargetTrans> transformed (const TargetTrans &t) const
|
||||
{
|
||||
path_ref<Path, TargetTrans> pref (*this);
|
||||
path_ref<Path, TargetTrans> pref (this->ptr (), this->trans ());
|
||||
pref.transform (t);
|
||||
return pref;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,17 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move (equivalent to +=)
|
||||
* This alias is needed for compatibility with other shapes
|
||||
*/
|
||||
point<C> &move (const vector<C> &v)
|
||||
{
|
||||
m_x += v.x ();
|
||||
m_y += v.y ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief method version of operator+ (mainly for automation purposes)
|
||||
*/
|
||||
|
|
@ -148,6 +159,17 @@ public:
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Moved point (equivalent to add)
|
||||
* This alias is needed for compatibility with other shapes
|
||||
*/
|
||||
point<C> moved (const vector<C> &v) const
|
||||
{
|
||||
point<C> r (*this);
|
||||
r += v;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subtract from operation
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3309,9 +3309,8 @@ public:
|
|||
*
|
||||
* The polygon pointer passed is assumed to reside in a proper repository.
|
||||
*/
|
||||
template <class TransIn>
|
||||
polygon_ref (const polygon_type *p, const TransIn &t)
|
||||
: shape_ref<Poly, Trans> (p, Trans (t))
|
||||
polygon_ref (const polygon_type *p, const Trans &t)
|
||||
: shape_ref<Poly, Trans> (p, t)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -3329,19 +3328,6 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief The transformation translation constructor
|
||||
*
|
||||
* This constructor allows one to copy a polygon reference with a certain transformation
|
||||
* to one with another transformation
|
||||
*/
|
||||
template <class TransIn>
|
||||
polygon_ref (const polygon_ref<Poly, TransIn> &ref)
|
||||
: shape_ref<Poly, Trans> (ref.ptr (), Trans (ref.trans ()))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The edge iterator
|
||||
*
|
||||
* The edge iterator delivers all edges of the polygon.
|
||||
|
|
@ -3480,7 +3466,7 @@ public:
|
|||
template <class TargetTrans>
|
||||
polygon_ref<Poly, TargetTrans> transformed (const TargetTrans &t) const
|
||||
{
|
||||
polygon_ref<Poly, TargetTrans> pref (*this);
|
||||
polygon_ref<Poly, TargetTrans> pref (this->ptr (), this->trans ());
|
||||
pref.transform (t);
|
||||
return pref;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ Shape::polygon_ref_type Shape::polygon_ref () const
|
|||
return *basic_ptr (polygon_ref_type::tag ());
|
||||
} else if (m_type == PolygonPtrArrayMember) {
|
||||
tl_assert (m_trans.rot () == 0);
|
||||
return polygon_ref_type (&basic_ptr (polygon_ptr_array_type::tag ())->object ().obj (), m_trans.disp ());
|
||||
return polygon_ref_type (&basic_ptr (polygon_ptr_array_type::tag ())->object ().obj (), db::Disp (m_trans.disp ()));
|
||||
} else {
|
||||
raise_no_general_polygon ();
|
||||
}
|
||||
|
|
@ -345,7 +345,7 @@ Shape::simple_polygon_ref_type Shape::simple_polygon_ref () const
|
|||
return *basic_ptr (simple_polygon_ref_type::tag ());
|
||||
} else if (m_type == SimplePolygonPtrArrayMember) {
|
||||
tl_assert (m_trans.rot () == 0);
|
||||
return simple_polygon_ref_type (&basic_ptr (simple_polygon_ptr_array_type::tag ())->object ().obj (), m_trans.disp ());
|
||||
return simple_polygon_ref_type (&basic_ptr (simple_polygon_ptr_array_type::tag ())->object ().obj (), db::Disp (m_trans.disp ()));
|
||||
} else {
|
||||
raise_no_simple_polygon ();
|
||||
}
|
||||
|
|
@ -423,7 +423,7 @@ Shape::path_ref_type Shape::path_ref () const
|
|||
return *basic_ptr (path_ref_type::tag ());
|
||||
} else if (m_type == PathPtrArrayMember) {
|
||||
tl_assert (m_trans.rot () == 0);
|
||||
return path_ref_type (&basic_ptr (path_ptr_array_type::tag ())->object ().obj (), m_trans.disp ());
|
||||
return path_ref_type (&basic_ptr (path_ptr_array_type::tag ())->object ().obj (), db::Disp (m_trans.disp ()));
|
||||
} else {
|
||||
raise_no_path ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ struct shape_ref
|
|||
{
|
||||
typedef Sh shape_type;
|
||||
typedef typename Sh::coord_type coord_type;
|
||||
typedef typename Sh::vector_type vector_type;
|
||||
typedef Trans trans_type;
|
||||
typedef db::generic_repository<coord_type> repository_type;
|
||||
typedef db::object_tag<shape_ref<Sh, Trans> > tag;
|
||||
|
|
|
|||
|
|
@ -863,7 +863,7 @@ public:
|
|||
|
||||
// expand arrays in editable mode
|
||||
if (! arr.begin ().at_end ()) {
|
||||
insert_array_typeof (*arr.begin () * Obj () /*for typeof*/, arr);
|
||||
insert_array_typeof (Obj ().transformed (*arr.begin ()) /*for typeof*/, arr);
|
||||
}
|
||||
|
||||
return shape_type ();
|
||||
|
|
|
|||
|
|
@ -924,19 +924,6 @@ struct text_ref
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The transformation translation constructor
|
||||
*
|
||||
* This constructor allows one to copy a text reference with a certain transformation
|
||||
* to one with another transformation
|
||||
*/
|
||||
template <class TransIn>
|
||||
text_ref (const text_ref<Text, TransIn> &ref)
|
||||
: shape_ref<Text, Trans> (ref.ptr (), Trans (ref.trans ()))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the transformed object
|
||||
*
|
||||
|
|
@ -945,7 +932,7 @@ struct text_ref
|
|||
template <class TargetTrans>
|
||||
text_ref<Text, TargetTrans> transformed (const TargetTrans &t) const
|
||||
{
|
||||
text_ref<Text, TargetTrans> tref (*this);
|
||||
text_ref<Text, TargetTrans> tref (this->ptr (), this->trans ());
|
||||
tref.transform (t);
|
||||
return tref;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "dbTrans.h"
|
||||
#include "dbObjectTag.h"
|
||||
#include "dbBox.h"
|
||||
#include "dbVector.h"
|
||||
#include "dbMemStatistics.h"
|
||||
#include "tlClassRegistry.h"
|
||||
|
||||
|
|
@ -170,6 +171,7 @@ public:
|
|||
typedef C coord_type;
|
||||
typedef db::box<C> box_type;
|
||||
typedef db::point<C> point_type;
|
||||
typedef db::vector<C> vector_type;
|
||||
typedef db::object_tag< user_object<C> > tag;
|
||||
|
||||
/**
|
||||
|
|
@ -348,17 +350,18 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Transform the object with the given transformation
|
||||
* @brief Transforms the object with the given transformation
|
||||
*
|
||||
* @param t The transformation to apply.
|
||||
* The actual behaviour is implemented by the base object.
|
||||
*/
|
||||
template <class Trans>
|
||||
void transform (const Trans &t)
|
||||
db::user_object<C> &transform (const Trans &t)
|
||||
{
|
||||
if (mp_obj) {
|
||||
mp_obj->transform (t);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -366,6 +369,7 @@ public:
|
|||
*
|
||||
* @param t The transformation to apply.
|
||||
* The actual behaviour is implemented by the base object.
|
||||
* NOTE: user object can't be transformed into a different coordinate type as of now.
|
||||
*/
|
||||
template <class Trans>
|
||||
db::user_object<C> transformed (const Trans &t) const
|
||||
|
|
@ -375,6 +379,39 @@ public:
|
|||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Moves the object
|
||||
*
|
||||
* @param v The move vector to apply.
|
||||
*/
|
||||
db::user_object<C> &move (const vector_type &v)
|
||||
{
|
||||
if (mp_obj) {
|
||||
mp_obj->transform (db::simple_trans<C> (v));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the moved object
|
||||
*
|
||||
* @param v The move vector to apply.
|
||||
*/
|
||||
db::user_object<C> moved (const vector_type &v) const
|
||||
{
|
||||
user_object o (*this);
|
||||
o.move (v);
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a string describing the object
|
||||
*/
|
||||
std::string to_string () const
|
||||
{
|
||||
return mp_obj ? mp_obj->to_string () : std::string ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief swap with another object
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -158,6 +158,11 @@ struct trans_defs
|
|||
return edge.transformed (*t);
|
||||
}
|
||||
|
||||
static db::edge_pair<coord_type> trans_edge_pair (const C *t, const db::edge_pair<coord_type> &edge_pair)
|
||||
{
|
||||
return edge_pair.transformed (*t);
|
||||
}
|
||||
|
||||
static db::box<coord_type> trans_box (const C *t, const db::box<coord_type> &box)
|
||||
{
|
||||
return box.transformed (*t);
|
||||
|
|
@ -168,6 +173,11 @@ struct trans_defs
|
|||
return polygon.transformed (*t);
|
||||
}
|
||||
|
||||
static db::simple_polygon<coord_type> trans_simple_polygon (const C *t, const db::simple_polygon<coord_type> &polygon)
|
||||
{
|
||||
return polygon.transformed (*t);
|
||||
}
|
||||
|
||||
static db::path<coord_type> trans_path (const C *t, const db::path<coord_type> &path)
|
||||
{
|
||||
return path.transformed (*t);
|
||||
|
|
@ -178,6 +188,41 @@ struct trans_defs
|
|||
return text.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::edge<coord_type> > trans_edge_wp (const C *t, const db::object_with_properties<db::edge<coord_type> > &edge)
|
||||
{
|
||||
return edge.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::edge_pair<coord_type> > trans_edge_pair_wp (const C *t, const db::object_with_properties<db::edge_pair<coord_type> > &edge_pair)
|
||||
{
|
||||
return edge_pair.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::box<coord_type> > trans_box_wp (const C *t, const db::object_with_properties<db::box<coord_type> > &box)
|
||||
{
|
||||
return box.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::polygon<coord_type> > trans_polygon_wp (const C *t, const db::object_with_properties<db::polygon<coord_type> > &polygon)
|
||||
{
|
||||
return polygon.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::simple_polygon<coord_type> > trans_simple_polygon_wp (const C *t, const db::object_with_properties<db::simple_polygon<coord_type> > &polygon)
|
||||
{
|
||||
return polygon.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::path<coord_type> > trans_path_wp (const C *t, const db::object_with_properties<db::path<coord_type> > &path)
|
||||
{
|
||||
return path.transformed (*t);
|
||||
}
|
||||
|
||||
static db::object_with_properties<db::text<coord_type> > trans_text_wp (const C *t, const db::object_with_properties<db::text<coord_type> > &text)
|
||||
{
|
||||
return text.transformed (*t);
|
||||
}
|
||||
|
||||
static size_t hash_value (const C *t)
|
||||
{
|
||||
return std::hfunc (*t);
|
||||
|
|
@ -316,6 +361,16 @@ struct trans_defs
|
|||
"\n"
|
||||
"This convenience method has been introduced in version 0.25."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_edge_pair, arg ("edge_pair"),
|
||||
"@brief Transforms an edge pair\n"
|
||||
"\n"
|
||||
"'t*edge_pair' or 't.trans(edge_pair)' is equivalent to edge_pair.transformed(t).\n"
|
||||
"\n"
|
||||
"@param edge_pair The edge pair to transform\n"
|
||||
"@return The transformed edge pair\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_polygon, arg ("polygon"),
|
||||
"@brief Transforms a polygon\n"
|
||||
"\n"
|
||||
|
|
@ -326,6 +381,16 @@ struct trans_defs
|
|||
"\n"
|
||||
"This convenience method has been introduced in version 0.25."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_simple_polygon, arg ("simple_polygon"),
|
||||
"@brief Transforms a simple polygon\n"
|
||||
"\n"
|
||||
"'t*polygon' or 't.trans(simple_polygon)' is equivalent to simple_polygon.transformed(t).\n"
|
||||
"\n"
|
||||
"@param simple_polygon The simple polygon to transform\n"
|
||||
"@return The transformed simple polygon\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_path, arg ("path"),
|
||||
"@brief Transforms a path\n"
|
||||
"\n"
|
||||
|
|
@ -346,6 +411,76 @@ struct trans_defs
|
|||
"\n"
|
||||
"This convenience method has been introduced in version 0.25."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_box_wp, arg ("box"),
|
||||
"@brief Transforms a box with properties\n"
|
||||
"\n"
|
||||
"'t*box' or 't.trans(box)' is equivalent to box.transformed(t).\n"
|
||||
"\n"
|
||||
"@param box The box to transform\n"
|
||||
"@return The transformed box\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_edge_wp, arg ("edge"),
|
||||
"@brief Transforms an edge with properties\n"
|
||||
"\n"
|
||||
"'t*edge' or 't.trans(edge)' is equivalent to edge.transformed(t).\n"
|
||||
"\n"
|
||||
"@param edge The edge to transform\n"
|
||||
"@return The transformed edge\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_edge_pair_wp, arg ("edge_pair"),
|
||||
"@brief Transforms an edge pair with properties\n"
|
||||
"\n"
|
||||
"'t*edge_pair' or 't.trans(edge_pair)' is equivalent to edge_pair.transformed(t).\n"
|
||||
"\n"
|
||||
"@param edge_pair The edge pair to transform\n"
|
||||
"@return The transformed edge pair\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_polygon_wp, arg ("polygon"),
|
||||
"@brief Transforms a polygon with properties\n"
|
||||
"\n"
|
||||
"'t*polygon' or 't.trans(polygon)' is equivalent to polygon.transformed(t).\n"
|
||||
"\n"
|
||||
"@param polygon The polygon to transform\n"
|
||||
"@return The transformed polygon\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_simple_polygon_wp, arg ("simple_polygon"),
|
||||
"@brief Transforms a simple polygon with properties\n"
|
||||
"\n"
|
||||
"'t*polygon' or 't.trans(simple_polygon)' is equivalent to simple_polygon.transformed(t).\n"
|
||||
"\n"
|
||||
"@param simple_polygon The simple polygon to transform\n"
|
||||
"@return The transformed simple polygon\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_path_wp, arg ("path"),
|
||||
"@brief Transforms a path with properties\n"
|
||||
"\n"
|
||||
"'t*path' or 't.trans(path)' is equivalent to path.transformed(t).\n"
|
||||
"\n"
|
||||
"@param path The path to transform\n"
|
||||
"@return The transformed path\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("trans|*", &trans_text_wp, arg ("text"),
|
||||
"@brief Transforms a text with properties\n"
|
||||
"\n"
|
||||
"'t*text' or 't.trans(text)' is equivalent to text.transformed(t).\n"
|
||||
"\n"
|
||||
"@param text The text to transform\n"
|
||||
"@return The transformed text\n"
|
||||
"\n"
|
||||
"This convenience method has been introduced in version 0.30."
|
||||
) +
|
||||
method ("*!", &C::concat, arg ("t"),
|
||||
"@brief Returns the concatenated transformation\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ TEST(10_LocalClusterBasic)
|
|||
EXPECT_EQ (cluster.bbox ().to_string (), "(0,0;1000,1000)");
|
||||
|
||||
db::local_cluster<db::PolygonRef> cluster2;
|
||||
cluster2.add (db::PolygonRef (poly, repo).transformed (db::Trans (db::Vector (10, 20))), 1);
|
||||
cluster2.add (db::PolygonRef (poly, repo).transformed (db::Disp (db::Vector (10, 20))), 1);
|
||||
cluster2.add_attr (2);
|
||||
|
||||
cluster.join_with (cluster2);
|
||||
|
|
|
|||
|
|
@ -972,7 +972,7 @@ TEST(100_UndoOfDeleteLayer)
|
|||
{
|
||||
db::Manager m;
|
||||
db::Layout l (&m);
|
||||
db::Cell &top = l.cell (l.add_cell ("TOP"));
|
||||
l.cell (l.add_cell ("TOP"));
|
||||
|
||||
unsigned int li = 0, li2 = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -251,17 +251,17 @@ unsigned int read_testdata (db::Layout &layout, unsigned int what = 0xff)
|
|||
shapes.insert (p1);
|
||||
shapes.insert (p2);
|
||||
shapes.insert (p3);
|
||||
shapes.insert (db::Shape::simple_polygon_ref_type (&p1, db::Trans (db::Vector (-10, 15))));
|
||||
shapes.insert (db::Shape::simple_polygon_ref_type (&p2, db::Trans (db::Vector (-110, 115))));
|
||||
shapes.insert (db::Shape::simple_polygon_ref_type (&p3, db::Trans (db::Vector (-210, 215))));
|
||||
shapes.insert (db::Shape::simple_polygon_ref_type (&p1, db::Disp (db::Vector (-10, 15))));
|
||||
shapes.insert (db::Shape::simple_polygon_ref_type (&p2, db::Disp (db::Vector (-110, 115))));
|
||||
shapes.insert (db::Shape::simple_polygon_ref_type (&p3, db::Disp (db::Vector (-210, 215))));
|
||||
if (with_arrays) shapes.insert (db::Shape::simple_polygon_ptr_array_type (db::Shape::simple_polygon_ptr_type (&p1, db::UnitTrans ()), db::Disp (db::Vector (0, 5)), db::Vector (0, 10000), db::Vector (11000, 0), 3, 4));
|
||||
|
||||
shapes.insert (db::object_with_properties<db::SimplePolygon> (p1, 1));
|
||||
shapes.insert (db::object_with_properties<db::SimplePolygon> (p2, 2));
|
||||
shapes.insert (db::object_with_properties<db::SimplePolygon> (p3, 3));
|
||||
shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ref_type> (db::Shape::simple_polygon_ref_type (&p1, db::Trans (db::Vector (-10, 15))), 5));
|
||||
shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ref_type> (db::Shape::simple_polygon_ref_type (&p2, db::Trans (db::Vector (-110, 115))), 6));
|
||||
shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ref_type> (db::Shape::simple_polygon_ref_type (&p3, db::Trans (db::Vector (-210, 215))), 7));
|
||||
shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ref_type> (db::Shape::simple_polygon_ref_type (&p1, db::Disp (db::Vector (-10, 15))), 5));
|
||||
shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ref_type> (db::Shape::simple_polygon_ref_type (&p2, db::Disp (db::Vector (-110, 115))), 6));
|
||||
shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ref_type> (db::Shape::simple_polygon_ref_type (&p3, db::Disp (db::Vector (-210, 215))), 7));
|
||||
if (with_arrays) shapes.insert (db::object_with_properties<db::Shape::simple_polygon_ptr_array_type> (db::Shape::simple_polygon_ptr_array_type (db::Shape::simple_polygon_ptr_type (&p1, db::UnitTrans ()), db::Disp (db::Vector (0, 5)), db::Vector (0, 10000), db::Vector (11000, 0), 3, 4), 8));
|
||||
}
|
||||
|
||||
|
|
@ -273,17 +273,17 @@ unsigned int read_testdata (db::Layout &layout, unsigned int what = 0xff)
|
|||
shapes.insert (q1);
|
||||
shapes.insert (q2);
|
||||
shapes.insert (q3);
|
||||
shapes.insert (db::Shape::polygon_ref_type (&q1, db::Trans (db::Vector (-10, 15))));
|
||||
shapes.insert (db::Shape::polygon_ref_type (&q2, db::Trans (db::Vector (-110, 115))));
|
||||
shapes.insert (db::Shape::polygon_ref_type (&q3, db::Trans (db::Vector (-210, 215))));
|
||||
shapes.insert (db::Shape::polygon_ref_type (&q1, db::Disp (db::Vector (-10, 15))));
|
||||
shapes.insert (db::Shape::polygon_ref_type (&q2, db::Disp (db::Vector (-110, 115))));
|
||||
shapes.insert (db::Shape::polygon_ref_type (&q3, db::Disp (db::Vector (-210, 215))));
|
||||
if (with_arrays) shapes.insert (db::Shape::polygon_ptr_array_type (db::Shape::polygon_ptr_type (&q1, db::UnitTrans ()), db::Disp (db::Vector (0, 5)), db::Vector (0, 10000), db::Vector (11000, 0), 3, 4));
|
||||
|
||||
shapes.insert (db::object_with_properties<db::Polygon> (q1, 1));
|
||||
shapes.insert (db::object_with_properties<db::Polygon> (q2, 2));
|
||||
shapes.insert (db::object_with_properties<db::Polygon> (q3, 3));
|
||||
shapes.insert (db::object_with_properties<db::Shape::polygon_ref_type> (db::Shape::polygon_ref_type (&q1, db::Trans (db::Vector (-10, 15))), 5));
|
||||
shapes.insert (db::object_with_properties<db::Shape::polygon_ref_type> (db::Shape::polygon_ref_type (&q2, db::Trans (db::Vector (-110, 115))), 6));
|
||||
shapes.insert (db::object_with_properties<db::Shape::polygon_ref_type> (db::Shape::polygon_ref_type (&q3, db::Trans (db::Vector (-210, 215))), 7));
|
||||
shapes.insert (db::object_with_properties<db::Shape::polygon_ref_type> (db::Shape::polygon_ref_type (&q1, db::Disp (db::Vector (-10, 15))), 5));
|
||||
shapes.insert (db::object_with_properties<db::Shape::polygon_ref_type> (db::Shape::polygon_ref_type (&q2, db::Disp (db::Vector (-110, 115))), 6));
|
||||
shapes.insert (db::object_with_properties<db::Shape::polygon_ref_type> (db::Shape::polygon_ref_type (&q3, db::Disp (db::Vector (-210, 215))), 7));
|
||||
if (with_arrays) shapes.insert (db::object_with_properties<db::Shape::polygon_ptr_array_type> (db::Shape::polygon_ptr_array_type (db::Shape::polygon_ptr_type (&q1, db::UnitTrans ()), db::Disp (db::Vector (0, 5)), db::Vector (0, 10000), db::Vector (11000, 0), 3, 4), 8));
|
||||
}
|
||||
|
||||
|
|
@ -301,17 +301,17 @@ unsigned int read_testdata (db::Layout &layout, unsigned int what = 0xff)
|
|||
shapes.insert (r1);
|
||||
shapes.insert (r2);
|
||||
shapes.insert (r3);
|
||||
shapes.insert (db::Shape::path_ref_type (&r1, db::Trans (db::Vector (-10, 15))));
|
||||
shapes.insert (db::Shape::path_ref_type (&r2, db::Trans (db::Vector (-110, 115))));
|
||||
shapes.insert (db::Shape::path_ref_type (&r3, db::Trans (db::Vector (-210, 215))));
|
||||
shapes.insert (db::Shape::path_ref_type (&r1, db::Disp (db::Vector (-10, 15))));
|
||||
shapes.insert (db::Shape::path_ref_type (&r2, db::Disp (db::Vector (-110, 115))));
|
||||
shapes.insert (db::Shape::path_ref_type (&r3, db::Disp (db::Vector (-210, 215))));
|
||||
if (with_arrays) shapes.insert (db::Shape::path_ptr_array_type (db::Shape::path_ptr_type (&r1, db::UnitTrans ()), db::Disp (db::Vector (0, 5)), db::Vector (0, 10000), db::Vector (11000, 0), 3, 4));
|
||||
|
||||
shapes.insert (db::object_with_properties<db::Path> (r1, 1));
|
||||
shapes.insert (db::object_with_properties<db::Path> (r2, 2));
|
||||
shapes.insert (db::object_with_properties<db::Path> (r3, 3));
|
||||
shapes.insert (db::object_with_properties<db::Shape::path_ref_type> (db::Shape::path_ref_type (&r1, db::Trans (db::Vector (-10, 15))), 5));
|
||||
shapes.insert (db::object_with_properties<db::Shape::path_ref_type> (db::Shape::path_ref_type (&r2, db::Trans (db::Vector (-110, 115))), 6));
|
||||
shapes.insert (db::object_with_properties<db::Shape::path_ref_type> (db::Shape::path_ref_type (&r3, db::Trans (db::Vector (-210, 215))), 7));
|
||||
shapes.insert (db::object_with_properties<db::Shape::path_ref_type> (db::Shape::path_ref_type (&r1, db::Disp (db::Vector (-10, 15))), 5));
|
||||
shapes.insert (db::object_with_properties<db::Shape::path_ref_type> (db::Shape::path_ref_type (&r2, db::Disp (db::Vector (-110, 115))), 6));
|
||||
shapes.insert (db::object_with_properties<db::Shape::path_ref_type> (db::Shape::path_ref_type (&r3, db::Disp (db::Vector (-210, 215))), 7));
|
||||
if (with_arrays) shapes.insert (db::object_with_properties<db::Shape::path_ptr_array_type> (db::Shape::path_ptr_array_type (db::Shape::path_ptr_type (&r1, db::UnitTrans ()), db::Disp (db::Vector (0, 5)), db::Vector (0, 10000), db::Vector (11000, 0), 3, 4), 8));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue