WIP: preparations for generic DRC with properties

This commit is contained in:
Matthias Koefferlein 2023-01-18 15:23:50 +01:00
parent 9f6f0e2d43
commit f1646a79fe
14 changed files with 303 additions and 56 deletions

View File

@ -976,27 +976,75 @@ void region_cop_impl (AsIfFlatRegion *region, db::Shapes *output_to, db::Compoun
proc.run_flat (polygons, others, foreign, &op, results);
}
template <class TR>
static
void region_cop_with_properties_impl (AsIfFlatRegion *region, db::Shapes *output_to, db::PropertiesRepository *target_pr, db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
db::local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::object_with_properties<TR> > proc;
proc.set_base_verbosity (region->base_verbosity ());
proc.set_description (region->progress_desc ());
proc.set_report_progress (region->report_progress ());
db::generic_shape_iterator<db::PolygonWithProperties> polygons (db::make_wp_iter (region->begin_merged ()));
std::vector<const db::PropertiesRepository *> intruder_prs;
const db::PropertiesRepository *subject_pr = region->properties_repository ();
std::vector<generic_shape_iterator<db::PolygonWithProperties> > others;
std::vector<bool> foreign;
std::vector<db::Region *> inputs = node.inputs ();
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
if (*i == subject_regionptr () || *i == foreign_regionptr ()) {
others.push_back (db::make_wp_iter (region->begin_merged ()));
foreign.push_back (*i == foreign_regionptr ());
intruder_prs.push_back (subject_pr);
} else {
others.push_back (db::make_wp_iter ((*i)->begin ()));
foreign.push_back (false);
intruder_prs.push_back (&(*i)->properties_repository ());
}
}
std::vector<db::Shapes *> results;
results.push_back (output_to);
compound_local_operation_with_properties<db::Polygon, db::Polygon, TR> op (&node, prop_constraint, target_pr, subject_pr, intruder_prs);
proc.run_flat (polygons, others, foreign, &op, results);
}
EdgePairsDelegate *
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node)
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
std::unique_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
region_cop_impl<db::EdgePair> (this, &output->raw_edge_pairs (), node);
if (prop_constraint == db::IgnoreProperties) {
region_cop_impl<db::EdgePair> (this, &output->raw_edge_pairs (), node);
} else {
region_cop_with_properties_impl<db::EdgePair> (this, &output->raw_edge_pairs (), output->properties_repository (), node, prop_constraint);
}
return output.release ();
}
RegionDelegate *
AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node)
AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
std::unique_ptr<FlatRegion> output (new FlatRegion ());
region_cop_impl<db::Polygon> (this, &output->raw_polygons (), node);
if (prop_constraint == db::IgnoreProperties) {
region_cop_impl<db::Polygon> (this, &output->raw_polygons (), node);
} else {
region_cop_with_properties_impl<db::Polygon> (this, &output->raw_polygons (), output->properties_repository (), node, prop_constraint);
}
return output.release ();
}
EdgesDelegate *
AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node)
AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint)
{
std::unique_ptr<FlatEdges> output (new FlatEdges ());
region_cop_impl<db::Edge> (this, &output->raw_edges (), node);
if (prop_constraint == db::IgnoreProperties) {
region_cop_impl<db::Edge> (this, &output->raw_edges (), node);
} else {
region_cop_with_properties_impl<db::Edge> (this, &output->raw_edges (), output->properties_repository (), node, prop_constraint);
}
return output.release ();
}

View File

@ -54,9 +54,9 @@ public:
virtual std::string to_string (size_t nmax) const;
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node);
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node);
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint);
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint);
EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const;
EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const;

View File

@ -1618,6 +1618,69 @@ private:
tl::weak_ptr<CompoundRegionOperationNode> mp_node;
};
/**
* @brief The generic local operation with property support
*
* This local operation executes the operation tree within a local processor.
* When put into a local processor, the operation tree will be executed on each interaction.
*/
template <class TS, class TI, class TR>
class DB_PUBLIC compound_local_operation_with_properties
: public local_operation<db::object_with_properties<TS>, db::object_with_properties<TI>, db::object_with_properties<TR> >
{
public:
/**
* @brief Constructor
*
* Creates a local operation which utilizes the operation tree. "node" is the root of the operation tree.
* Ownership of the node is *not* transferred to the local operation.
*/
compound_local_operation_with_properties<TS, TI, TR> (CompoundRegionOperationNode *node, db::PropertyConstraint prop_constraint, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const std::vector<const db::PropertiesRepository *> &intruder_prs)
: mp_node (node), m_prop_constraint (prop_constraint), m_pms (target_pr, subject_pr)
{
m_pmis.reserve (intruder_prs.size ());
for (auto i = intruder_prs.begin (); i != intruder_prs.end (); ++i) {
m_pmis.push_back (db::PropertyMapper (target_pr, *i));
}
}
protected:
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> > > &results, size_t max_vertex_count, double area_ratio) const
{
auto interactions_by_prop_id = separate_interactions_to_interactions_by_properties (interactions, m_prop_constraint, m_pms, m_pmis);
for (auto s2p = interactions_by_prop_id.begin (); s2p != interactions_by_prop_id.end (); ++s2p) {
std::vector<std::unordered_set<TR> > results_wo_props;
results_wo_props.resize (results.size ());
CompoundRegionOperationCache cache;
mp_node->compute_local (&cache, layout, s2p->second, results_wo_props, max_vertex_count, area_ratio);
for (size_t n = 0; n < results.size (); ++n) {
for (auto i = results_wo_props [n].begin (); i != results_wo_props [n].end (); ++i) {
results [n].insert (db::object_with_properties<TR> (*i, s2p->first));
}
}
}
}
virtual db::Coord dist () const { return mp_node->dist (); }
virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return mp_node->on_empty_intruder_hint (); }
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const { return mp_node->description (); }
const TransformationReducer *vars () const { return mp_node->vars (); }
bool wants_variants () const { return mp_node->wants_variants (); }
std::vector<db::Region *> inputs () const { return mp_node->inputs (); }
private:
tl::weak_ptr<CompoundRegionOperationNode> mp_node;
db::PropertyConstraint m_prop_constraint;
mutable db::PropertyMapper m_pms;
mutable std::vector<db::PropertyMapper> m_pmis;
};
}
#endif

View File

@ -1706,17 +1706,16 @@ Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &no
}
}
db::local_processor<db::PolygonRef, db::PolygonRef, TR> proc (const_cast<db::Layout *> (&region->deep_layer ().layout ()),
const_cast<db::Cell *> (&region->deep_layer ().initial_cell ()),
region->deep_layer ().breakout_cells ());
const db::DeepLayer &polygons (region->merged_deep_layer ());
std::unique_ptr<Output> res (new Output (polygons.derived ()));
db::local_processor<db::PolygonRef, db::PolygonRef, TR> proc (&res->deep_layer ().layout (), &res->deep_layer ().initial_cell (), region->deep_layer ().breakout_cells ());
proc.set_description (region->progress_desc ());
proc.set_report_progress (region->report_progress ());
proc.set_base_verbosity (region->base_verbosity ());
proc.set_threads (region->deep_layer ().store ()->threads ());
const db::DeepLayer &polygons (region->merged_deep_layer ());
std::vector<unsigned int> other_layers;
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
@ -1737,41 +1736,108 @@ Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &no
}
std::unique_ptr<Output> res (new Output (polygons.derived ()));
compound_local_operation<db::PolygonRef, db::PolygonRef, TR> op (&node);
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ());
return res.release ();
}
EdgePairsDelegate *
DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node)
template <class TR, class Output>
static
Output *region_cop_with_properties_impl (DeepRegion *region, db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
DeepEdgePairs *output = region_cop_impl<db::EdgePair, DeepEdgePairs> (this, node);
// Fall back to flat mode if one of the inputs is flat
std::vector<db::Region *> inputs = node.inputs ();
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
if (! is_subject_regionptr (*i) && ! dynamic_cast<const db::DeepRegion *> ((*i)->delegate ())) {
return 0;
}
}
const db::DeepLayer &polygons (region->merged_deep_layer ());
std::unique_ptr<Output> res (new Output (polygons.derived ()));
db::local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::object_with_properties<TR> > proc (&res->deep_layer ().layout (), &res->deep_layer ().initial_cell (), region->deep_layer ().breakout_cells ());
proc.set_description (region->progress_desc ());
proc.set_report_progress (region->report_progress ());
proc.set_base_verbosity (region->base_verbosity ());
proc.set_threads (region->deep_layer ().store ()->threads ());
std::vector<unsigned int> other_layers;
std::vector<const db::PropertiesRepository *> intruder_prs;
const db::PropertiesRepository *subject_pr = &polygons.layout ().properties_repository ();
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
if (is_subject_regionptr (*i)) {
if (*i == subject_regionptr ()) {
other_layers.push_back (subject_idlayer ());
} else {
other_layers.push_back (foreign_idlayer ());
}
intruder_prs.push_back (subject_pr);
} else {
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> ((*i)->delegate ());
tl_assert (other_deep != 0);
if (&other_deep->deep_layer ().layout () != &region->deep_layer ().layout () || &other_deep->deep_layer ().initial_cell () != &region->deep_layer ().initial_cell ()) {
throw tl::Exception (tl::to_string (tr ("Complex DeepRegion operations need to use the same layout and top cell for all inputs")));
}
other_layers.push_back (other_deep->deep_layer ().layer ());
intruder_prs.push_back (other_deep->properties_repository ());
}
}
compound_local_operation_with_properties<db::PolygonRef, db::PolygonRef, TR> op (&node, prop_constraint, res->properties_repository (), subject_pr, intruder_prs);
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ());
return res.release ();
}
EdgePairsDelegate *
DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
DeepEdgePairs *output = 0;
if (prop_constraint == db::IgnoreProperties) {
output = region_cop_impl<db::EdgePair, DeepEdgePairs> (this, node);
} else {
output = region_cop_with_properties_impl<db::EdgePair, DeepEdgePairs> (this, node, prop_constraint);
}
if (! output) {
return AsIfFlatRegion::cop_to_edge_pairs (node);
return AsIfFlatRegion::cop_to_edge_pairs (node, prop_constraint);
} else {
return output;
}
}
RegionDelegate *
DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node)
DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
DeepRegion *output = region_cop_impl<db::PolygonRef, db::DeepRegion> (this, node);
DeepRegion *output = 0;
if (prop_constraint == db::IgnoreProperties) {
output = region_cop_impl<db::PolygonRef, db::DeepRegion> (this, node);
} else {
output = region_cop_with_properties_impl<db::PolygonRef, DeepRegion> (this, node, prop_constraint);
}
if (! output) {
return AsIfFlatRegion::cop_to_region (node);
return AsIfFlatRegion::cop_to_region (node, prop_constraint);
} else {
return output;
}
}
EdgesDelegate *
DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node)
DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
DeepEdges *output = region_cop_impl<db::Edge, db::DeepEdges> (this, node);
DeepEdges *output = 0;
if (prop_constraint == db::IgnoreProperties) {
output = region_cop_impl<db::Edge, DeepEdges> (this, node);
} else {
output = region_cop_with_properties_impl<db::Edge, DeepEdges> (this, node, prop_constraint);
}
if (! output) {
return AsIfFlatRegion::cop_to_edges (node);
return AsIfFlatRegion::cop_to_edges (node, prop_constraint);
} else {
return output;
}

View File

@ -95,9 +95,9 @@ public:
virtual std::string to_string (size_t nmax) const;
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node);
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node);
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint);
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint);
virtual RegionDelegate *and_with (const Region &other, db::PropertyConstraint property_constraint) const;
virtual RegionDelegate *not_with (const Region &other, db::PropertyConstraint property_constraint) const;

View File

@ -98,19 +98,19 @@ EmptyRegion::processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &) co
}
EdgePairsDelegate *
EmptyRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &)
EmptyRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &, db::PropertyConstraint)
{
return new EmptyEdgePairs ();
}
RegionDelegate *
EmptyRegion::cop_to_region (db::CompoundRegionOperationNode &)
EmptyRegion::cop_to_region (db::CompoundRegionOperationNode &, db::PropertyConstraint)
{
return new EmptyRegion ();
}
EdgesDelegate *
EmptyRegion::cop_to_edges (db::CompoundRegionOperationNode &)
EmptyRegion::cop_to_edges (db::CompoundRegionOperationNode &, db::PropertyConstraint)
{
return new EmptyEdges ();
}

View File

@ -62,9 +62,9 @@ public:
virtual Box bbox () const { return Box (); }
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node);
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node);
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node, PropertyConstraint);
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node, PropertyConstraint);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint);
virtual EdgePairsDelegate *width_check (db::Coord, const RegionCheckOptions &) const;
virtual EdgePairsDelegate *space_check (db::Coord, const RegionCheckOptions &) const;

View File

@ -2448,9 +2448,11 @@ template class DB_PUBLIC local_processor_cell_context<db::Polygon, db::Text, db:
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::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePair>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_cell_context<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePair>;
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>;
@ -2468,9 +2470,11 @@ template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Text, db
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::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePair>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePair>;
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>;
@ -2504,9 +2508,11 @@ 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::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::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePair>;
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::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePair>;
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>;
@ -2532,9 +2538,11 @@ 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::Edge>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
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::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePair>;
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::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePair>;
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>;
@ -2553,9 +2561,11 @@ 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::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePair>;
template class DB_PUBLIC local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePair>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePairWithProperties>;
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

@ -83,9 +83,11 @@ 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::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgePair>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePairWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgePair>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::Text, db::PolygonRef>;

View File

@ -346,6 +346,60 @@ separate_interactions_by_properties (const shape_interactions<db::object_with_pr
return by_prop_id;
}
/**
* @brief Separates the interacting shapes by property relation
*
* Returns a map of property ID, subject shapes and intruder shapes belonging to the subject shapes.
* Depending on the property constraint the intruders will either be ones with and properties (NoPropertyConstraint),
* the same properties than the subject (SamePropertiesConstraint) or different properties (DifferentPropertiesConstraint).
*/
template <class TS, class TI>
DB_PUBLIC
std::map<db::properties_id_type, db::shape_interactions<TS, TI> >
separate_interactions_to_interactions_by_properties (const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, db::PropertyConstraint property_constraint, db::PropertyMapper &pms, std::vector<db::PropertyMapper> &pmis)
{
std::map<db::properties_id_type, db::shape_interactions<TS, TI> > by_prop_id;
std::map<db::properties_id_type, std::set<unsigned int> > intruder_ids_by_prop_id;
for (auto i = interactions.begin (); i != interactions.end (); ++i) {
const db::object_with_properties<TS> &subject = interactions.subject_shape (i->first);
db::properties_id_type prop_id = pms (subject.properties_id ());
db::shape_interactions<TS, TI> &s2p = by_prop_id [prop_id];
std::set<unsigned int> &intruder_ids = intruder_ids_by_prop_id [prop_id];
s2p.add_subject (i->first, subject);
for (auto ii = i->second.begin (); ii != i->second.end (); ++ii) {
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
tl_assert (intruder.first < (unsigned int) pmis.size ());
db::properties_id_type intruder_prop_id = (property_constraint == db::NoPropertyConstraint ? prop_id : pmis[intruder.first] (intruder.second.properties_id ()));
if ((property_constraint == db::DifferentPropertiesConstraint) == (prop_id != intruder_prop_id)) {
s2p.add_interaction (i->first, *ii);
intruder_ids.insert (*ii);
}
}
}
for (auto i = intruder_ids_by_prop_id.begin (); i != intruder_ids_by_prop_id.end (); ++i) {
db::shape_interactions<TS, TI> &s2p = by_prop_id [i->first];
const std::set<unsigned int> &intruder_ids = intruder_ids_by_prop_id [i->first];
for (auto ii = intruder_ids.begin (); ii != intruder_ids.end (); ++ii) {
auto is = interactions.intruder_shape (*ii);
s2p.add_intruder_shape (*ii, is.first, is.second);
}
}
return by_prop_id;
}
}
#endif

View File

@ -217,35 +217,35 @@ Region::mutable_region ()
}
EdgePairs
Region::cop_to_edge_pairs (db::CompoundRegionOperationNode &node)
Region::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
tl_assert (node.result_type () == db::CompoundRegionOperationNode::EdgePairs);
return EdgePairs (mp_delegate->cop_to_edge_pairs (node));
return EdgePairs (mp_delegate->cop_to_edge_pairs (node, prop_constraint));
}
Region
Region::cop_to_region (db::CompoundRegionOperationNode &node)
Region::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
tl_assert (node.result_type () == db::CompoundRegionOperationNode::Region);
return Region (mp_delegate->cop_to_region (node));
return Region (mp_delegate->cop_to_region (node, prop_constraint));
}
Edges
Region::cop_to_edges (db::CompoundRegionOperationNode &node)
Region::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
tl_assert (node.result_type () == db::CompoundRegionOperationNode::Edges);
return Edges (mp_delegate->cop_to_edges (node));
return Edges (mp_delegate->cop_to_edges (node, prop_constraint));
}
tl::Variant
Region::cop (db::CompoundRegionOperationNode &node)
Region::cop (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
{
if (node.result_type () == db::CompoundRegionOperationNode::EdgePairs) {
return tl::Variant::make_variant (new EdgePairs (mp_delegate->cop_to_edge_pairs (node)));
return tl::Variant::make_variant (new EdgePairs (mp_delegate->cop_to_edge_pairs (node, prop_constraint)));
} else if (node.result_type () == db::CompoundRegionOperationNode::Edges) {
return tl::Variant::make_variant (new Edges (mp_delegate->cop_to_edges (node)));
return tl::Variant::make_variant (new Edges (mp_delegate->cop_to_edges (node, prop_constraint)));
} else if (node.result_type () == db::CompoundRegionOperationNode::Region) {
return tl::Variant::make_variant (new Region (mp_delegate->cop_to_region (node)));
return tl::Variant::make_variant (new Region (mp_delegate->cop_to_region (node, prop_constraint)));
} else {
return tl::Variant ();
}

View File

@ -613,7 +613,7 @@ public:
* The compound operation needs to feature edge pair output, e.g.
* node.result_type() needs to be EdgePairs.
*/
EdgePairs cop_to_edge_pairs (db::CompoundRegionOperationNode &node);
EdgePairs cop_to_edge_pairs (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint = db::IgnoreProperties);
/**
* @brief Performs a compound operation rendering a region
@ -621,7 +621,7 @@ public:
* The compound operation needs to feature region output, e.g.
* node.result_type() needs to be Region.
*/
Region cop_to_region (db::CompoundRegionOperationNode &node);
Region cop_to_region (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint = db::IgnoreProperties);
/**
* @brief Performs a compound operation rendering edges
@ -629,7 +629,7 @@ public:
* The compound operation needs to feature region output, e.g.
* node.result_type() needs to be Edges.
*/
Edges cop_to_edges (db::CompoundRegionOperationNode &node);
Edges cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint = db::IgnoreProperties);
/**
* @brief A universal form of the compound operation
@ -637,7 +637,7 @@ public:
* The returned variant will be of the type requested by the
* compound operation node.
*/
tl::Variant cop (db::CompoundRegionOperationNode &node);
tl::Variant cop (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint = db::IgnoreProperties);
/**
* @brief Applies a width check and returns EdgePairs which correspond to violation markers

View File

@ -237,9 +237,9 @@ public:
virtual perimeter_type perimeter (const db::Box &box) const = 0;
virtual Box bbox () const = 0;
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node) = 0;
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node) = 0;
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node) = 0;
virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) = 0;
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) = 0;
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) = 0;
virtual EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const = 0;
virtual EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const = 0;

View File

@ -700,14 +700,14 @@ static size_t id (const db::Region *r)
}
tl::Variant complex_op (db::Region *region, db::CompoundRegionOperationNode *node)
tl::Variant complex_op (db::Region *region, db::CompoundRegionOperationNode *node, db::PropertyConstraint prop_constraint)
{
if (node->result_type () == db::CompoundRegionOperationNode::Region) {
return tl::Variant (region->cop_to_region (*node));
return tl::Variant (region->cop_to_region (*node, prop_constraint));
} else if (node->result_type () == db::CompoundRegionOperationNode::Edges) {
return tl::Variant (region->cop_to_edges (*node));
return tl::Variant (region->cop_to_edges (*node, prop_constraint));
} else if (node->result_type () == db::CompoundRegionOperationNode::EdgePairs) {
return tl::Variant (region->cop_to_edge_pairs (*node));
return tl::Variant (region->cop_to_edge_pairs (*node, prop_constraint));
} else {
return tl::Variant ();
}
@ -967,10 +967,14 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
"@brief Gets a flag indicating whether minimum coherence is selected\n"
"See \\min_coherence= for a description of this attribute.\n"
) +
method_ext ("complex_op", &complex_op, gsi::arg ("node"),
method_ext ("complex_op", &complex_op, gsi::arg ("node"), gsi::arg ("property_constraint", db::IgnoreProperties),
"@brief Executes a complex operation (see \\CompoundRegionOperationNode for details)\n"
"\n"
"This method has been introduced in version 0.27."
"\n"
"The 'property_constraint' parameter controls whether properties are considered: with 'SamePropertiesConstraint' "
"the operation is only applied between shapes with identical properties. With 'DifferentPropertiesConstraint' only "
"between shapes with different properties. This option has been introduced in version 0.28.4."
) +
method_ext ("with_perimeter", with_perimeter1, gsi::arg ("perimeter"), gsi::arg ("inverse"),
"@brief Filter the polygons by perimeter\n"