WIP: refactoring, enabling properties for flat processing

This commit is contained in:
Matthias Koefferlein 2023-01-17 00:51:21 +01:00
parent 35fb4ce3db
commit 99887a15f0
17 changed files with 270 additions and 130 deletions

View File

@ -104,7 +104,7 @@ AsIfFlatEdges::selected_interacting_generic (const Region &other, EdgeInteractio
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
AddressableEdgeDelivery e (begin_merged ());
for ( ; ! e.at_end (); ++e) {
scanner.insert1 (e.operator-> (), 0);
@ -150,7 +150,7 @@ AsIfFlatEdges::selected_interacting_generic (const Edges &edges, EdgeInteraction
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
AddressableEdgeDelivery e (begin_merged ());
for ( ; ! e.at_end (); ++e) {
scanner.insert (e.operator-> (), 0);
@ -201,7 +201,7 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Region &region, EdgeInte
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
AddressableEdgeDelivery e (begin_merged ());
for ( ; ! e.at_end (); ++e) {
scanner.insert1 (e.operator-> (), 0);
@ -245,7 +245,7 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeIntera
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
AddressableEdgeDelivery e (begin_merged ());
for ( ; ! e.at_end (); ++e) {
scanner.insert (e.operator-> (), 0);
@ -281,7 +281,7 @@ AsIfFlatEdges::pull_generic (const Edges &edges) const
{
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin (), has_valid_edges ());
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
scanner.insert (e.operator-> (), 1);
@ -310,7 +310,7 @@ AsIfFlatEdges::pull_generic (const Region &other) const
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin (), true);
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
scanner.insert1 (e.operator-> (), 0);
@ -487,7 +487,7 @@ AsIfFlatEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, c
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (count ());
AddressableEdgeDelivery e (begin (), has_valid_edges ());
AddressableEdgeDelivery e (begin ());
size_t n = 0;
for ( ; ! e.at_end (); ++e) {
@ -733,7 +733,7 @@ AsIfFlatEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Co
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (count () + (other ? other->count () : 0));
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
AddressableEdgeDelivery e (begin_merged ());
size_t n = 0;
for ( ; ! e.at_end (); ++e) {
@ -774,7 +774,7 @@ AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (count () + (other ? other->count () : 0));
AddressableEdgeDelivery e (begin (), has_valid_edges ());
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
if (! e->is_degenerate ()) {
@ -808,7 +808,7 @@ AsIfFlatEdges::boolean_andnot (const Edges *other) const
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (count () + (other ? other->count () : 0));
AddressableEdgeDelivery e (begin (), has_valid_edges ());
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
if (! e->is_degenerate ()) {

View File

@ -1493,41 +1493,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
return new EmptyRegion ();
} else {
// @@@ TODO: implement property constraint
// Generic case
db::EdgeProcessor ep (report_progress (), progress_desc ());
ep.set_base_verbosity (base_verbosity ());
// count edges and reserve memory
size_t n = 0;
for (RegionIterator p (begin ()); ! p.at_end (); ++p) {
n += p->vertices ();
}
for (RegionIterator p (other.begin ()); ! p.at_end (); ++p) {
n += p->vertices ();
}
ep.reserve (n);
// insert the polygons into the processor
n = 0;
for (RegionIterator p (begin ()); ! p.at_end (); ++p, n += 2) {
ep.insert (*p, n);
}
n = 1;
for (RegionIterator p (other.begin ()); ! p.at_end (); ++p, n += 2) {
ep.insert (*p, n);
}
std::unique_ptr<FlatRegion> new_region (new FlatRegion (true));
db::BooleanOp op (db::BooleanOp::And);
db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/);
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ());
ep.process (pg, op);
return new_region.release ();
return and_or_not_with (true, other, property_constraint);
}
}
@ -1550,8 +1516,14 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const
return clone ();
} else {
return and_or_not_with (false, other, property_constraint);
}
}
// @@@ TODO: implement property constraint
RegionDelegate *
AsIfFlatRegion::and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const
{
if (property_constraint == db::IgnoreProperties) {
// Generic case
db::EdgeProcessor ep (report_progress (), progress_desc ());
@ -1578,17 +1550,38 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const
}
std::unique_ptr<FlatRegion> new_region (new FlatRegion (true));
db::BooleanOp op (db::BooleanOp::ANotB);
db::BooleanOp op (is_and ? db::BooleanOp::And : db::BooleanOp::ANotB);
db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/);
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ());
ep.process (pg, op);
return new_region.release ();
} else {
db::generic_shape_iterator<db::PolygonWithProperties> polygons (db::make_wp_iter (begin ()));
std::unique_ptr<FlatRegion> output (new FlatRegion ());
std::vector<db::Shapes *> results;
results.push_back (&output->raw_polygons ());
db::bool_and_or_not_local_operation_with_properties<db::Polygon, db::Polygon, db::Polygon> op (is_and, output->properties_repository (), properties_repository (), &other.properties_repository (), property_constraint);
db::local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties> proc;
proc.set_base_verbosity (base_verbosity ());
proc.set_description (progress_desc ());
proc.set_report_progress (report_progress ());
std::vector<db::generic_shape_iterator<db::PolygonWithProperties> > others;
others.push_back (db::make_wp_iter (other.begin ()));
proc.run_flat (polygons, others, std::vector<bool> (), &op, results);
return output.release ();
}
}
std::pair<RegionDelegate *, RegionDelegate *>
AsIfFlatRegion::andnot_with (const Region &other, PropertyConstraint property_constraint) const
{

View File

@ -284,6 +284,7 @@ protected:
void update_bbox (const db::Box &box);
void invalidate_bbox ();
void merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc) const;
RegionDelegate *and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const;
virtual EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const;
virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options) const;

View File

@ -334,7 +334,7 @@ AsIfFlatTexts::selected_interacting_generic (const Region &other, bool inverse)
db::box_scanner2<db::Text, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
AddressableTextDelivery e (begin (), has_valid_texts ());
AddressableTextDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
scanner.insert1 (e.operator-> (), 0);
@ -380,7 +380,7 @@ AsIfFlatTexts::pull_generic (const Region &other) const
db::box_scanner2<db::Text, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
AddressableTextDelivery e (begin (), has_valid_texts ());
AddressableTextDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
scanner.insert1 (e.operator-> (), 0);

View File

@ -796,7 +796,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op, db::PropertyC
} else {
db::BoolAndOrNotLocalOperationWithProperties op (and_op, &deep_layer ().layout (), &other->deep_layer ().layout (), property_constraint);
db::BoolAndOrNotLocalOperationWithProperties op (and_op, &dl_out.layout ().properties_repository (), &deep_layer ().layout ().properties_repository (), &other->deep_layer ().layout ().properties_repository (), property_constraint);
db::local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), deep_layer ().breakout_cells (), other->deep_layer ().breakout_cells ());
proc.set_base_verbosity (base_verbosity ());

View File

@ -100,7 +100,7 @@ public:
}
};
typedef addressable_shape_delivery_gen<EdgePairsIterator> AddressableEdgePairDelivery;
typedef addressable_shape_delivery<EdgePair> AddressableEdgePairDelivery;
class EdgePairs;
@ -496,7 +496,7 @@ public:
*/
AddressableEdgePairDelivery addressable_edge_pairs () const
{
return AddressableEdgePairDelivery (begin (), has_valid_edge_pairs ());
return AddressableEdgePairDelivery (begin ());
}
/**

View File

@ -95,7 +95,7 @@ public:
}
};
typedef addressable_shape_delivery_gen<EdgesIterator> AddressableEdgeDelivery;
typedef addressable_shape_delivery<Edge> AddressableEdgeDelivery;
class Edges;
@ -1449,7 +1449,7 @@ public:
*/
AddressableEdgeDelivery addressable_edges () const
{
return AddressableEdgeDelivery (begin (), has_valid_edges ());
return AddressableEdgeDelivery (begin ());
}
/**
@ -1468,7 +1468,7 @@ public:
*/
AddressableEdgeDelivery addressable_merged_edges () const
{
return AddressableEdgeDelivery (begin_merged (), has_valid_merged_edges ());
return AddressableEdgeDelivery (begin_merged ());
}
/**

View File

@ -39,11 +39,6 @@ FlatRegion::FlatRegion ()
init ();
}
FlatRegion::~FlatRegion ()
{
// .. nothing yet ..
}
FlatRegion::FlatRegion (const FlatRegion &other)
: MutableRegion (other), mp_polygons (other.mp_polygons), mp_merged_polygons (other.mp_merged_polygons), mp_properties_repository (other.mp_properties_repository)
{
@ -69,6 +64,11 @@ FlatRegion::FlatRegion (bool is_merged)
m_is_merged = is_merged;
}
FlatRegion::~FlatRegion ()
{
// .. nothing yet ..
}
void FlatRegion::set_is_merged (bool m)
{
m_is_merged = m;

View File

@ -181,7 +181,7 @@ public:
const_cast<db::Shapes *> (mp_shapes)->update ();
}
m_iter = mp_shapes->begin (shape_flags<T> ());
m_is_addressable = shape_flags<T> () == shape_flags_pure<T> () || mp_shapes->begin (shape_flags<T> () - shape_flags_pure<T> ()).at_end ();
m_is_addressable = ! shape_flags_with_props<T> () && (shape_flags<T> () == shape_flags_pure<T> () || mp_shapes->begin (shape_flags<T> () - shape_flags_pure<T> ()).at_end ());
set ();
}
@ -305,9 +305,23 @@ public:
: mp_delegate (other.mp_delegate ? other.mp_delegate->clone () : 0)
{ }
generic_shape_iterator (generic_shape_iterator &&other)
: mp_delegate (0)
{
std::swap (mp_delegate, other.mp_delegate);
}
~generic_shape_iterator ()
{
delete mp_delegate;
mp_delegate = 0;
}
generic_shape_iterator &set_delegate (generic_shape_iterator_delegate_base<T> *delegate)
{
delete mp_delegate;
mp_delegate = delegate;
return *this;
}
generic_shape_iterator &operator= (const generic_shape_iterator &other)
@ -393,12 +407,108 @@ public:
};
/**
* @brief A helper class allowing delivery of addressable edges
* @brief Wraps a generic shape iterator to provide a property-enabled one
*/
template <class T>
class DB_PUBLIC generic_shape_iterator_with_properties_delegate
: public generic_shape_iterator_delegate_base<db::object_with_properties<T> >
{
public:
generic_shape_iterator_with_properties_delegate (generic_shape_iterator<T> &&basic)
: m_basic (basic)
{
set ();
}
generic_shape_iterator_with_properties_delegate (generic_shape_iterator_delegate_base<T> *delegate)
: m_basic (delegate)
{
set ();
}
generic_shape_iterator_with_properties_delegate (const generic_shape_iterator<T> &basic)
: m_basic (basic)
{
set ();
}
generic_shape_iterator_with_properties_delegate *clone () const
{
return new generic_shape_iterator_with_properties_delegate (m_basic);
}
virtual void do_reset (const db::Box &region, bool overlapping)
{
m_basic.reset (region, overlapping);
}
virtual db::Box bbox () const
{
return m_basic.bbox ();
}
virtual bool is_addressable () const
{
return false;
}
virtual bool at_end () const
{
return m_basic.at_end ();
}
virtual void increment ()
{
++m_basic;
set ();
}
virtual const db::object_with_properties<T> *get () const
{
return &m_object;
}
virtual db::properties_id_type prop_id () const
{
return m_object.properties_id ();
}
virtual bool equals (const generic_shape_iterator_delegate_base<db::object_with_properties<T> > *other) const
{
const generic_shape_iterator_with_properties_delegate<T> *other_cast = dynamic_cast<const generic_shape_iterator_with_properties_delegate<T> *> (other);
return other_cast && m_basic == other_cast->m_basic;
}
private:
db::generic_shape_iterator<T> m_basic;
db::object_with_properties<T> m_object;
void set ()
{
m_object = db::object_with_properties<T> (*m_basic, m_basic.prop_id ());
}
};
template <class T>
generic_shape_iterator<db::object_with_properties<T> > make_wp_iter (generic_shape_iterator<T> &&basic)
{
return generic_shape_iterator<db::object_with_properties<T> > ().set_delegate (new generic_shape_iterator_with_properties_delegate<T> (basic));
}
template <class T>
generic_shape_iterator<db::object_with_properties<T> > make_wp_iter (db::generic_shape_iterator_delegate_base<T> *delegate)
{
return generic_shape_iterator<db::object_with_properties<T> > ().set_delegate (new generic_shape_iterator_with_properties_delegate<T> (delegate));
}
/**
* @brief A helper class allowing delivery of addressable objects
*
* In some applications (i.e. box scanner), shapes need to be taken
* by address. An iterator cannot always deliver addressable objects.
* This class help providing this ability by keeping a temporary copy
* if required.
* The addressable_shape_delivery class help providing this ability by keeping temporary copies
* if required on a heap.
*/
template <class Iter>
@ -443,6 +553,11 @@ public:
}
}
const value_type &operator* () const
{
return *operator-> ();
}
db::properties_id_type prop_id () const
{
return m_iter.prop_id ();
@ -454,26 +569,6 @@ private:
std::list<value_type> m_heap;
};
template <class Iter>
class DB_PUBLIC addressable_shape_delivery_gen
: public addressable_shape_delivery_impl<Iter>
{
public:
addressable_shape_delivery_gen ()
: addressable_shape_delivery_impl<Iter> ()
{ }
explicit addressable_shape_delivery_gen (const Iter &iter, bool iterator_is_addressable)
: addressable_shape_delivery_impl<Iter> (iter, iterator_is_addressable)
{ }
addressable_shape_delivery_gen &operator++ ()
{
addressable_shape_delivery_impl<Iter>::inc ();
return *this;
}
};
template <class T>
class DB_PUBLIC addressable_shape_delivery
: public addressable_shape_delivery_impl<db::generic_shape_iterator<T> >
@ -496,6 +591,29 @@ public:
}
};
template <class T>
class DB_PUBLIC unaddressable_shape_delivery
: public addressable_shape_delivery_impl<db::generic_shape_iterator<T> >
{
public:
typedef db::generic_shape_iterator<T> iter_type;
unaddressable_shape_delivery ()
: addressable_shape_delivery_impl<iter_type> ()
{ }
explicit unaddressable_shape_delivery (const iter_type &iter)
: addressable_shape_delivery_impl<iter_type> (iter, true)
{ }
unaddressable_shape_delivery &operator++ ()
{
addressable_shape_delivery_impl<iter_type>::inc ();
return *this;
}
};
}
#endif

View File

@ -446,6 +446,7 @@ template class DB_PUBLIC local_processor_cell_context<db::Polygon, db::Edge, db:
template class DB_PUBLIC local_processor_cell_context<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_processor_cell_context<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::EdgePair>;
@ -760,6 +761,7 @@ template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Edge, db
template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Text, db::Polygon>;
template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::PolygonRef, db::EdgePair>;
@ -865,6 +867,7 @@ template class DB_PUBLIC shape_interactions<db::Polygon, db::Text>;
template class DB_PUBLIC shape_interactions<db::Polygon, db::TextRef>;
template class DB_PUBLIC shape_interactions<db::Polygon, db::Edge>;
template class DB_PUBLIC shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC shape_interactions<db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::TextRef>;
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::Text>;
@ -1337,6 +1340,7 @@ template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, d
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::TextRef>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::PolygonRef>;
@ -1400,6 +1404,7 @@ template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db
template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
@ -2246,11 +2251,10 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
if (needs_isolated_subjects) {
addressable_shape_delivery<TS> is (subjects);
unaddressable_shape_delivery<TS> is (subjects);
for ( ; !is.at_end (); ++is) {
const TS *shape = is.operator-> ();
unsigned int id = interactions.next_id ();
interactions.add_subject (id, *shape);
interactions.add_subject (id, *is);
}
unsigned int il_index = 0;
@ -2415,6 +2419,7 @@ template class DB_PUBLIC local_processor<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_processor<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_processor<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::Edge>;

View File

@ -95,6 +95,7 @@ template class DB_PUBLIC local_operation<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_operation<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_operation<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::Text, db::PolygonRef>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::TextRef, db::PolygonRef>;
@ -193,56 +194,60 @@ BoolAndOrNotLocalOperation::do_compute_local (db::Layout *layout, const shape_in
// ---------------------------------------------------------------------------------------------
// BoolAndOrNotLocalOperationWithProperties implementation
BoolAndOrNotLocalOperationWithProperties::BoolAndOrNotLocalOperationWithProperties (bool is_and, const db::Layout *subject_layout, const db::Layout *intruder_layout, db::PropertyConstraint property_constraint)
: m_is_and (is_and), m_property_constraint (property_constraint), mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout)
template <class TS, class TI, class TR>
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::bool_and_or_not_local_operation_with_properties (bool is_and, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint)
: m_is_and (is_and), m_property_constraint (property_constraint), mp_target_pr (target_pr), mp_subject_pr (subject_pr), mp_intruder_pr (intruder_pr)
{
// .. nothing yet ..
}
template <class TS, class TI, class TR>
OnEmptyIntruderHint
BoolAndOrNotLocalOperationWithProperties::on_empty_intruder_hint () const
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::on_empty_intruder_hint () const
{
return m_is_and ? Drop : Copy;
}
template <class TS, class TI, class TR>
std::string
BoolAndOrNotLocalOperationWithProperties::description () const
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::description () const
{
return m_is_and ? tl::to_string (tr ("AND operation")) : tl::to_string (tr ("NOT operation"));
}
template <class TS, class TI, class TR>
void
BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::PolygonRefWithProperties> > &results, size_t max_vertex_count, double area_ratio) const
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, size_t max_vertex_count, double area_ratio) const
{
db::PropertyMapper pms (*layout, *mp_subject_layout);
db::PropertyMapper pmi (*layout, *mp_intruder_layout);
db::PropertyMapper pms (*mp_target_pr, *mp_subject_pr);
db::PropertyMapper pmi (*mp_target_pr, *mp_intruder_pr);
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRefWithProperties> &result = results.front ();
std::unordered_set<db::object_with_properties<TR> > &result = results.front ();
db::EdgeProcessor ep;
std::map<db::properties_id_type, std::pair<tl::slist<db::PolygonRef>, std::set<db::PolygonRef> > > by_prop_id;
std::map<db::properties_id_type, std::pair<tl::slist<TS>, std::set<TI> > > by_prop_id;
for (shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (auto i = interactions.begin (); i != interactions.end (); ++i) {
const db::PolygonRefWithProperties &subject = interactions.subject_shape (i->first);
const db::object_with_properties<TS> &subject = interactions.subject_shape (i->first);
if (i->second.empty ()) {
if (! m_is_and) {
result.insert (db::PolygonRefWithProperties (subject, pms (subject.properties_id ())));
result.insert (db::object_with_properties<TR> (subject, pms (subject.properties_id ())));
}
} else {
db::properties_id_type prop_id_s = pms (subject.properties_id ());
std::pair<tl::slist<db::PolygonRef>, std::set<db::PolygonRef> > &shapes_by_prop = by_prop_id [prop_id_s];
auto &shapes_by_prop = by_prop_id [prop_id_s];
shapes_by_prop.first.push_front (subject);
for (shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
const db::PolygonRefWithProperties &intruder = interactions.intruder_shape (*j).second;
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? pmi (intruder.properties_id ()) : prop_id_s);
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
shapes_by_prop.second.insert (intruder);
@ -258,23 +263,23 @@ BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout,
ep.clear ();
size_t p1 = 0, p2 = 1;
const std::set<db::PolygonRef> &others = p2s->second.second;
const std::set<TI> &others = p2s->second.second;
db::properties_id_type prop_id = p2s->first;
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
const db::PolygonRef &subject = *s;
const TS &subject = *s;
if (others.find (subject) != others.end ()) {
if (m_is_and) {
result.insert (db::PolygonRefWithProperties (subject, prop_id));
result.insert (db::object_with_properties<TR> (subject, prop_id));
}
} else if (others.empty ()) {
// shortcut (not: keep, and: drop)
if (! m_is_and) {
result.insert (db::PolygonRefWithProperties (subject, prop_id));
result.insert (db::object_with_properties<TR> (subject, prop_id));
}
} else {
for (db::PolygonRef::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end(); ++e) {
for (auto e = subject.begin_edge (); ! e.at_end(); ++e) {
ep.insert (*e, p1);
}
p1 += 2;
@ -284,24 +289,24 @@ BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout,
if (! others.empty () && p1 > 0) {
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
for (db::PolygonRef::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) {
for (auto o = others.begin (); o != others.end (); ++o) {
for (auto e = o->begin_edge (); ! e.at_end(); ++e) {
ep.insert (*e, p2);
}
p2 += 2;
}
std::unordered_set<db::PolygonRef> result_wo_props;
std::unordered_set<TR> result_wo_props;
db::BooleanOp op (m_is_and ? db::BooleanOp::And : db::BooleanOp::ANotB);
db::PolygonRefGenerator pr (layout, result_wo_props);
db::polygon_ref_generator<TR> pr (layout, result_wo_props);
db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count);
db::PolygonGenerator pg (splitter, true, true);
ep.set_base_verbosity (50);
ep.process (pg, op);
for (auto r = result_wo_props.begin (); r != result_wo_props.end (); ++r) {
result.insert (db::PolygonRefWithProperties (*r, prop_id));
result.insert (db::object_with_properties<TR> (*r, prop_id));
}
}
@ -309,6 +314,9 @@ BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout,
}
}
template class bool_and_or_not_local_operation_with_properties<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class bool_and_or_not_local_operation_with_properties<db::Polygon, db::Polygon, db::Polygon>;
// ---------------------------------------------------------------------------------------------
// TwoBoolAndNotLocalOperation implementation

View File

@ -150,22 +150,26 @@ private:
/**
* @brief Implements a boolean AND or NOT operation with property handling
*/
class DB_PUBLIC BoolAndOrNotLocalOperationWithProperties
: public local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>
template <class TS, class TI, class TR>
class DB_PUBLIC bool_and_or_not_local_operation_with_properties
: public local_operation<db::object_with_properties<TS>, db::object_with_properties<TI>, db::object_with_properties<TR> >
{
public:
BoolAndOrNotLocalOperationWithProperties (bool is_and, const db::Layout *subject_layout, const db::Layout *intruder_layout, db::PropertyConstraint property_constraint);
bool_and_or_not_local_operation_with_properties (bool is_and, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::PolygonRefWithProperties> > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
private:
bool m_is_and;
db::PropertyConstraint m_property_constraint;
const db::Layout *mp_subject_layout, *mp_intruder_layout;
db::PropertiesRepository *mp_target_pr;
const db::PropertiesRepository *mp_subject_pr, *mp_intruder_pr;
};
typedef bool_and_or_not_local_operation_with_properties<db::PolygonRef, db::PolygonRef, db::PolygonRef> BoolAndOrNotLocalOperationWithProperties;
/**
* @brief Implements a boolean AND plus NOT operation
*

View File

@ -305,7 +305,7 @@ OriginalLayerEdges::ensure_merged_edges_valid () const
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (count ());
AddressableEdgeDelivery e (begin (), has_valid_edges ());
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
if (! e->is_degenerate ()) {

View File

@ -1122,7 +1122,7 @@ public:
/**
* @brief Boolean XOR operator with options
*
* TODO: property constraints are not implemented propertly yet.
* TODO: property constraints are not implemented properly yet.
*/
Region bool_xor (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties) const
{
@ -1147,7 +1147,7 @@ public:
* This method does not necessarily merge the region. To ensure the region
* is merged, call merge afterwards.
*
* TODO: property constraints are not implemented propertly yet.
* TODO: property constraints are not implemented properly yet.
*/
Region &bool_xor_with (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties)
{
@ -1170,7 +1170,7 @@ public:
*
* This method merges the polygons of both regions.
*
* TODO: property constraints are not implemented propertly yet.
* TODO: property constraints are not implemented properly yet.
*/
Region bool_or (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties) const
{
@ -1189,7 +1189,7 @@ public:
/**
* @brief In-place boolean OR operator with options
*
* TODO: property constraints are not implemented propertly yet.
* TODO: property constraints are not implemented properly yet.
*/
Region &bool_or_with (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties)
{

View File

@ -36,10 +36,12 @@ struct shape_flags_traits
{
static unsigned int generic () { return 0; }
static unsigned int pure () { return 0; }
static bool with_props () { return false; }
};
template <>
struct shape_flags_traits<db::PolygonRef>
: public shape_flags_traits<void>
{
static unsigned int generic () { return 1 << db::ShapeIterator::PolygonRef; }
static unsigned int pure () { return 1 << db::ShapeIterator::PolygonRef; }
@ -47,6 +49,7 @@ struct shape_flags_traits<db::PolygonRef>
template <>
struct shape_flags_traits<db::TextRef>
: public shape_flags_traits<void>
{
static unsigned int generic () { return 1 << db::ShapeIterator::TextRef; }
static unsigned int pure () { return 1 << db::ShapeIterator::TextRef; }
@ -54,6 +57,7 @@ struct shape_flags_traits<db::TextRef>
template <>
struct shape_flags_traits<db::Box>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::Boxes; }
static unsigned int pure () { return 1 << db::ShapeIterator::Box; }
@ -61,6 +65,7 @@ struct shape_flags_traits<db::Box>
template <>
struct shape_flags_traits<db::Path>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::Paths; }
static unsigned int pure () { return 1 << db::ShapeIterator::Path; }
@ -68,6 +73,7 @@ struct shape_flags_traits<db::Path>
template <>
struct shape_flags_traits<db::Polygon>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::Polygons; }
static unsigned int pure () { return 1 << db::ShapeIterator::Polygon; }
@ -75,6 +81,7 @@ struct shape_flags_traits<db::Polygon>
template <>
struct shape_flags_traits<db::SimplePolygon>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::Polygons; }
static unsigned int pure () { return 1 << db::ShapeIterator::SimplePolygon; }
@ -82,6 +89,7 @@ struct shape_flags_traits<db::SimplePolygon>
template <>
struct shape_flags_traits<db::Edge>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::Edges; }
static unsigned int pure () { return 1 << db::ShapeIterator::Edge; }
@ -89,6 +97,7 @@ struct shape_flags_traits<db::Edge>
template <>
struct shape_flags_traits<db::EdgePair>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::EdgePairs; }
static unsigned int pure () { return 1 << db::ShapeIterator::EdgePair; }
@ -96,6 +105,7 @@ struct shape_flags_traits<db::EdgePair>
template <>
struct shape_flags_traits<db::Text>
: public shape_flags_traits<void>
{
static unsigned int generic () { return db::ShapeIterator::Texts; }
static unsigned int pure () { return 1 << db::ShapeIterator::Text; }
@ -103,13 +113,14 @@ struct shape_flags_traits<db::Text>
template <class T>
struct shape_flags_traits<db::object_with_properties<T> >
: public shape_flags_traits<T>
{
static unsigned int generic () { return shape_flags_traits<T>::generic (); }
static unsigned int pure () { return shape_flags_traits<T>::pure (); }
static bool with_props () { return true; }
};
template <class T> unsigned int shape_flags () { return shape_flags_traits<T>::generic (); }
template <class T> unsigned int shape_flags_pure () { return shape_flags_traits<T>::pure (); }
template <class T> bool shape_flags_with_props () { return shape_flags_traits<T>::with_props (); }
/**
* @brief Converter helpers for changing a shape to an object of a specific type

View File

@ -100,7 +100,7 @@ public:
}
};
typedef addressable_shape_delivery_gen<TextsIterator> AddressableTextDelivery;
typedef addressable_shape_delivery<Text> AddressableTextDelivery;
class Texts;
@ -522,7 +522,7 @@ public:
*/
AddressableTextDelivery addressable_texts () const
{
return AddressableTextDelivery (begin (), has_valid_texts ());
return AddressableTextDelivery (begin ());
}
/**

View File

@ -132,15 +132,15 @@ TEST(0_Develop)
db::local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties> proc (&ly2, &top2);
{
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2, &ly2, db::SamePropertiesConstraint);
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::SamePropertiesConstraint);
proc.run (&n2n, wmetal1, wmetal2, out1);
}
{
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2, &ly2, db::DifferentPropertiesConstraint);
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::DifferentPropertiesConstraint);
proc.run (&n2n, wmetal1, wmetal2, out2);
}
{
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2, &ly2, db::NoPropertyConstraint);
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::NoPropertyConstraint);
proc.run (&n2n, wmetal1, wmetal2, out3);
}