mirror of https://github.com/KLayout/klayout.git
WIP: DRC properties constraints now need explicit generation of output properties.
This commit is contained in:
parent
9b64224cb4
commit
38808fccf7
|
|
@ -1017,7 +1017,7 @@ EdgePairsDelegate *
|
||||||
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||||
{
|
{
|
||||||
std::unique_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
|
std::unique_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
|
||||||
if (prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (prop_constraint)) {
|
||||||
region_cop_impl<db::EdgePair> (this, &output->raw_edge_pairs (), node);
|
region_cop_impl<db::EdgePair> (this, &output->raw_edge_pairs (), node);
|
||||||
} else {
|
} else {
|
||||||
region_cop_with_properties_impl<db::EdgePair> (this, &output->raw_edge_pairs (), output->properties_repository (), node, prop_constraint);
|
region_cop_with_properties_impl<db::EdgePair> (this, &output->raw_edge_pairs (), output->properties_repository (), node, prop_constraint);
|
||||||
|
|
@ -1029,7 +1029,7 @@ RegionDelegate *
|
||||||
AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||||
{
|
{
|
||||||
std::unique_ptr<FlatRegion> output (new FlatRegion ());
|
std::unique_ptr<FlatRegion> output (new FlatRegion ());
|
||||||
if (prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (prop_constraint)) {
|
||||||
region_cop_impl<db::Polygon> (this, &output->raw_polygons (), node);
|
region_cop_impl<db::Polygon> (this, &output->raw_polygons (), node);
|
||||||
} else {
|
} else {
|
||||||
region_cop_with_properties_impl<db::Polygon> (this, &output->raw_polygons (), output->properties_repository (), node, prop_constraint);
|
region_cop_with_properties_impl<db::Polygon> (this, &output->raw_polygons (), output->properties_repository (), node, prop_constraint);
|
||||||
|
|
@ -1041,7 +1041,7 @@ EdgesDelegate *
|
||||||
AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint)
|
AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint)
|
||||||
{
|
{
|
||||||
std::unique_ptr<FlatEdges> output (new FlatEdges ());
|
std::unique_ptr<FlatEdges> output (new FlatEdges ());
|
||||||
if (prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (prop_constraint)) {
|
||||||
region_cop_impl<db::Edge> (this, &output->raw_edges (), node);
|
region_cop_impl<db::Edge> (this, &output->raw_edges (), node);
|
||||||
} else {
|
} else {
|
||||||
region_cop_with_properties_impl<db::Edge> (this, &output->raw_edges (), output->properties_repository (), node, prop_constraint);
|
region_cop_with_properties_impl<db::Edge> (this, &output->raw_edges (), output->properties_repository (), node, prop_constraint);
|
||||||
|
|
@ -1113,7 +1113,7 @@ EdgePairsDelegate *
|
||||||
AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const
|
AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const
|
||||||
{
|
{
|
||||||
// force different polygons in the different properties case to skip intra-polygon checks
|
// force different polygons in the different properties case to skip intra-polygon checks
|
||||||
if (options.prop_constraint == DifferentPropertiesConstraint) {
|
if (pc_always_different (options.prop_constraint)) {
|
||||||
different_polygons = true;
|
different_polygons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1159,7 +1159,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
|
||||||
std::vector<db::Shapes *> results;
|
std::vector<db::Shapes *> results;
|
||||||
results.push_back (&output->raw_edge_pairs ());
|
results.push_back (&output->raw_edge_pairs ());
|
||||||
|
|
||||||
if (options.prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (options.prop_constraint)) {
|
||||||
|
|
||||||
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, primary_is_merged, has_other, other_is_merged, options);
|
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, primary_is_merged, has_other, other_is_merged, options);
|
||||||
|
|
||||||
|
|
@ -1209,7 +1209,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord
|
||||||
|
|
||||||
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
||||||
|
|
||||||
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result->raw_edge_pairs (), options.negative, false /*=same polygons*/, false /*=same layers*/, options.shielded, true /*symmetric edge pairs*/, options.prop_constraint == db::IgnoreProperties ? 0 : pm (p.prop_id ()));
|
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result->raw_edge_pairs (), options.negative, false /*=same polygons*/, false /*=same layers*/, options.shielded, true /*symmetric edge pairs*/, pc_remove (options.prop_constraint) ? 0 : pm (p.prop_id ()));
|
||||||
poly2poly_check<db::Polygon> poly_check (edge_check);
|
poly2poly_check<db::Polygon> poly_check (edge_check);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
@ -1364,7 +1364,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
return new EmptyRegion ();
|
return new EmptyRegion ();
|
||||||
|
|
||||||
} else if (property_constraint == db::IgnoreProperties && is_box () && other.is_box ()) {
|
} else if (pc_skip (property_constraint) && is_box () && other.is_box ()) {
|
||||||
|
|
||||||
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
||||||
|
|
||||||
|
|
@ -1373,7 +1373,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
|
||||||
b &= other.bbox ();
|
b &= other.bbox ();
|
||||||
return region_from_box (b);
|
return region_from_box (b);
|
||||||
|
|
||||||
} else if (property_constraint == db::IgnoreProperties && is_box () && ! other.strict_handling ()) {
|
} else if (pc_skip (property_constraint) && is_box () && ! other.strict_handling ()) {
|
||||||
|
|
||||||
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
||||||
|
|
||||||
|
|
@ -1390,7 +1390,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const
|
||||||
|
|
||||||
return new_region.release ();
|
return new_region.release ();
|
||||||
|
|
||||||
} else if (property_constraint == db::IgnoreProperties && other.is_box () && ! strict_handling ()) {
|
} else if (pc_skip (property_constraint) && other.is_box () && ! strict_handling ()) {
|
||||||
|
|
||||||
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
// @@@ TODO: implement this with property constraints as that is important for the clip implementation!
|
||||||
|
|
||||||
|
|
@ -1443,7 +1443,7 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const
|
||||||
RegionDelegate *
|
RegionDelegate *
|
||||||
AsIfFlatRegion::and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const
|
AsIfFlatRegion::and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const
|
||||||
{
|
{
|
||||||
if (property_constraint == db::IgnoreProperties) {
|
if (pc_skip (property_constraint)) {
|
||||||
|
|
||||||
// Generic case
|
// Generic case
|
||||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||||
|
|
@ -1520,7 +1520,7 @@ AsIfFlatRegion::andnot_with (const Region &other, PropertyConstraint property_co
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
return std::make_pair (new EmptyRegion (), clone ());
|
return std::make_pair (new EmptyRegion (), clone ());
|
||||||
|
|
||||||
} else if (property_constraint == db::IgnoreProperties) {
|
} else if (pc_skip (property_constraint)) {
|
||||||
|
|
||||||
// Generic case
|
// Generic case
|
||||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||||
|
|
|
||||||
|
|
@ -1549,7 +1549,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
|
||||||
set_description ("check");
|
set_description ("check");
|
||||||
|
|
||||||
// force different polygons in the different properties case to skip intra-polygon checks
|
// force different polygons in the different properties case to skip intra-polygon checks
|
||||||
if (m_options.prop_constraint == DifferentPropertiesConstraint) {
|
if (pc_always_different (m_options.prop_constraint)) {
|
||||||
m_different_polygons = true;
|
m_different_polygons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1658,7 +1658,7 @@ protected:
|
||||||
|
|
||||||
for (size_t n = 0; n < results.size (); ++n) {
|
for (size_t n = 0; n < results.size (); ++n) {
|
||||||
for (auto i = results_wo_props [n].begin (); i != results_wo_props [n].end (); ++i) {
|
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));
|
results [n].insert (db::object_with_properties<TR> (*i, pc_norm (m_prop_constraint, s2p->first)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -858,7 +858,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op, db::PropertyC
|
||||||
{
|
{
|
||||||
DeepLayer dl_out (deep_layer ().derived ());
|
DeepLayer dl_out (deep_layer ().derived ());
|
||||||
|
|
||||||
if (property_constraint == db::IgnoreProperties) {
|
if (pc_skip (property_constraint)) {
|
||||||
|
|
||||||
db::BoolAndOrNotLocalOperation op (and_op);
|
db::BoolAndOrNotLocalOperation op (and_op);
|
||||||
|
|
||||||
|
|
@ -893,7 +893,7 @@ DeepRegion::and_and_not_with (const DeepRegion *other, PropertyConstraint proper
|
||||||
DeepLayer dl_out1 (deep_layer ().derived ());
|
DeepLayer dl_out1 (deep_layer ().derived ());
|
||||||
DeepLayer dl_out2 (deep_layer ().derived ());
|
DeepLayer dl_out2 (deep_layer ().derived ());
|
||||||
|
|
||||||
if (property_constraint == db::IgnoreProperties) {
|
if (pc_skip (property_constraint)) {
|
||||||
|
|
||||||
db::TwoBoolAndNotLocalOperation op;
|
db::TwoBoolAndNotLocalOperation op;
|
||||||
|
|
||||||
|
|
@ -1840,7 +1840,7 @@ EdgePairsDelegate *
|
||||||
DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||||
{
|
{
|
||||||
DeepEdgePairs *output = 0;
|
DeepEdgePairs *output = 0;
|
||||||
if (prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (prop_constraint)) {
|
||||||
output = region_cop_impl<db::EdgePair, DeepEdgePairs> (this, node);
|
output = region_cop_impl<db::EdgePair, DeepEdgePairs> (this, node);
|
||||||
} else {
|
} else {
|
||||||
output = region_cop_with_properties_impl<db::EdgePair, DeepEdgePairs> (this, node, prop_constraint);
|
output = region_cop_with_properties_impl<db::EdgePair, DeepEdgePairs> (this, node, prop_constraint);
|
||||||
|
|
@ -1856,7 +1856,7 @@ RegionDelegate *
|
||||||
DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||||
{
|
{
|
||||||
DeepRegion *output = 0;
|
DeepRegion *output = 0;
|
||||||
if (prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (prop_constraint)) {
|
||||||
output = region_cop_impl<db::PolygonRef, db::DeepRegion> (this, node);
|
output = region_cop_impl<db::PolygonRef, db::DeepRegion> (this, node);
|
||||||
} else {
|
} else {
|
||||||
output = region_cop_with_properties_impl<db::PolygonRef, DeepRegion> (this, node, prop_constraint);
|
output = region_cop_with_properties_impl<db::PolygonRef, DeepRegion> (this, node, prop_constraint);
|
||||||
|
|
@ -1872,7 +1872,7 @@ EdgesDelegate *
|
||||||
DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint)
|
||||||
{
|
{
|
||||||
DeepEdges *output = 0;
|
DeepEdges *output = 0;
|
||||||
if (prop_constraint == db::IgnoreProperties) {
|
if (pc_skip (prop_constraint)) {
|
||||||
output = region_cop_impl<db::Edge, DeepEdges> (this, node);
|
output = region_cop_impl<db::Edge, DeepEdges> (this, node);
|
||||||
} else {
|
} else {
|
||||||
output = region_cop_with_properties_impl<db::Edge, DeepEdges> (this, node, prop_constraint);
|
output = region_cop_with_properties_impl<db::Edge, DeepEdges> (this, node, prop_constraint);
|
||||||
|
|
@ -1894,7 +1894,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// force different polygons in the different properties case to skip intra-polygon checks
|
// force different polygons in the different properties case to skip intra-polygon checks
|
||||||
if (options.prop_constraint == DifferentPropertiesConstraint) {
|
if (pc_always_different (options.prop_constraint)) {
|
||||||
different_polygons = true;
|
different_polygons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2004,7 +2004,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c
|
||||||
|
|
||||||
for (db::Shapes::shape_iterator s = shapes.begin (db::ShapeIterator::Polygons); ! s.at_end (); ++s) {
|
for (db::Shapes::shape_iterator s = shapes.begin (db::ShapeIterator::Polygons); ! s.at_end (); ++s) {
|
||||||
|
|
||||||
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result, options.negative, false /*does not require different polygons*/, false /*does not require different layers*/, options.shielded, true /*symmetric edge pairs*/, options.prop_constraint == db::IgnoreProperties ? 0 : s->prop_id ());
|
edge2edge_check_negative_or_positive<db::Shapes> edge_check (check, result, options.negative, false /*does not require different polygons*/, false /*does not require different layers*/, options.shielded, true /*symmetric edge pairs*/, pc_remove (options.prop_constraint) ? 0 : s->prop_id ());
|
||||||
poly2poly_check<db::Polygon> poly_check (edge_check);
|
poly2poly_check<db::Polygon> poly_check (edge_check);
|
||||||
|
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
|
|
|
||||||
|
|
@ -341,9 +341,8 @@ separate_interactions_by_properties (const shape_interactions<db::object_with_pr
|
||||||
for (auto ii = i->second.begin (); ii != i->second.end (); ++ii) {
|
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);
|
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
|
||||||
db::properties_id_type intruder_prop_id = (property_constraint == db::NoPropertyConstraint ? prop_id : pmi (intruder.second.properties_id ()));
|
|
||||||
|
|
||||||
if ((property_constraint == db::DifferentPropertiesConstraint) == (prop_id != intruder_prop_id)) {
|
if (pc_match (property_constraint, prop_id, pmi (intruder.second.properties_id ()))) {
|
||||||
s2p.second.insert (&intruder.second);
|
s2p.second.insert (&intruder.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -382,9 +381,8 @@ separate_interactions_to_interactions_by_properties (const shape_interactions<db
|
||||||
|
|
||||||
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
|
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
|
||||||
tl_assert (intruder.first < (unsigned int) pmis.size ());
|
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)) {
|
if (pc_match (property_constraint, prop_id, pmis[intruder.first] (intruder.second.properties_id ()))) {
|
||||||
s2p.add_interaction (i->first, *ii);
|
s2p.add_interaction (i->first, *ii);
|
||||||
intruder_ids.insert (*ii);
|
intruder_ids.insert (*ii);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#define HDR_dbPropertyConstraint
|
#define HDR_dbPropertyConstraint
|
||||||
|
|
||||||
#include "dbCommon.h"
|
#include "dbCommon.h"
|
||||||
|
#include "dbTypes.h"
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
@ -56,14 +57,74 @@ enum PropertyConstraint
|
||||||
*/
|
*/
|
||||||
SamePropertiesConstraint = 2,
|
SamePropertiesConstraint = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shapes are processed if their properties are the same
|
||||||
|
*
|
||||||
|
* No properties are attached to the output.
|
||||||
|
*/
|
||||||
|
SamePropertiesConstraintDrop = 3,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shapes are processed if their properties are different
|
* @brief Shapes are processed if their properties are different
|
||||||
*
|
*
|
||||||
* Properties are attached to the outputs where applicable.
|
* Properties are attached to the outputs where applicable.
|
||||||
*/
|
*/
|
||||||
DifferentPropertiesConstraint = 3
|
DifferentPropertiesConstraint = 4,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shapes are processed if their properties are different
|
||||||
|
*
|
||||||
|
* No properties are attached to the output.
|
||||||
|
*/
|
||||||
|
DifferentPropertiesConstraintDrop = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a predicate indicating whether properties need to be considered
|
||||||
|
*/
|
||||||
|
bool inline pc_skip (PropertyConstraint pc)
|
||||||
|
{
|
||||||
|
return pc == IgnoreProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a predicate indicating whether properties are always different
|
||||||
|
*/
|
||||||
|
bool inline pc_always_different (PropertyConstraint pc)
|
||||||
|
{
|
||||||
|
return pc == DifferentPropertiesConstraint || pc == DifferentPropertiesConstraintDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a value indicating whether two properties satisfy the condition
|
||||||
|
*/
|
||||||
|
bool inline pc_match (PropertyConstraint pc, db::properties_id_type a, db::properties_id_type b)
|
||||||
|
{
|
||||||
|
if (pc == SamePropertiesConstraint || pc == SamePropertiesConstraintDrop) {
|
||||||
|
return a == b;
|
||||||
|
} else if (pc == DifferentPropertiesConstraint || pc == DifferentPropertiesConstraintDrop) {
|
||||||
|
return a != b;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a value indicating whether the property can be removed on output
|
||||||
|
*/
|
||||||
|
bool inline pc_remove (PropertyConstraint pc)
|
||||||
|
{
|
||||||
|
return pc == IgnoreProperties || pc == SamePropertiesConstraintDrop || pc == DifferentPropertiesConstraintDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a normalized property for output
|
||||||
|
*/
|
||||||
|
db::properties_id_type inline pc_norm (PropertyConstraint pc, db::properties_id_type prop_id)
|
||||||
|
{
|
||||||
|
return pc_remove (pc) ? 0 : prop_id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -782,7 +782,7 @@ check_local_operation_with_properties<TS, TI>::do_compute_local (db::Layout *lay
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto r = result.begin (); r != result.end (); ++r) {
|
for (auto r = result.begin (); r != result.end (); ++r) {
|
||||||
results.front ().insert (db::EdgePairWithProperties (*r, s2p->first));
|
results.front ().insert (db::EdgePairWithProperties (*r, pc_norm (check_local_operation_base<TS, TI>::m_options.prop_constraint, s2p->first)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1668,8 +1668,7 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
|
||||||
|
|
||||||
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
|
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
|
||||||
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
|
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
|
||||||
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s);
|
if (pc_match (m_property_constraint, prop_id_s, m_pmi (intruder.properties_id ()))) {
|
||||||
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
|
|
||||||
shapes_by_prop.second.insert (intruder);
|
shapes_by_prop.second.insert (intruder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1684,7 +1683,7 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
|
||||||
size_t p1 = 0, p2 = 1;
|
size_t p1 = 0, p2 = 1;
|
||||||
|
|
||||||
const std::set<TI> &others = p2s->second.second;
|
const std::set<TI> &others = p2s->second.second;
|
||||||
db::properties_id_type prop_id = p2s->first;
|
db::properties_id_type prop_id = pc_norm (m_property_constraint, p2s->first);
|
||||||
|
|
||||||
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
|
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
|
||||||
|
|
||||||
|
|
@ -1857,8 +1856,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
|
||||||
|
|
||||||
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
|
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
|
||||||
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
|
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
|
||||||
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s);
|
if (pc_match (m_property_constraint, prop_id_s, m_pmi (intruder.properties_id ()))) {
|
||||||
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
|
|
||||||
shapes_by_prop.second.insert (intruder);
|
shapes_by_prop.second.insert (intruder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1873,7 +1871,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
|
||||||
size_t p1 = 0, p2 = 1;
|
size_t p1 = 0, p2 = 1;
|
||||||
|
|
||||||
const std::set<TR> &others = p2s->second.second;
|
const std::set<TR> &others = p2s->second.second;
|
||||||
db::properties_id_type prop_id = p2s->first;
|
db::properties_id_type prop_id = pc_norm (m_property_constraint, p2s->first);
|
||||||
|
|
||||||
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
|
for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3172,10 +3172,20 @@ gsi::EnumIn<db::Region, db::PropertyConstraint> decl_Region_PropertyConstraint (
|
||||||
"When using this constraint - for example on a boolean operation - shapes are considered "
|
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||||
"only if their user properties are the same. Properties are generated on the output shapes where applicable."
|
"only if their user properties are the same. Properties are generated on the output shapes where applicable."
|
||||||
) +
|
) +
|
||||||
|
gsi::enum_const ("SamePropertiesConstraintDrop", db::SamePropertiesConstraintDrop,
|
||||||
|
"@brief Specifies to consider shapes only if their user properties are the same\n"
|
||||||
|
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||||
|
"only if their user properties are the same. No properties are generated on the output shapes."
|
||||||
|
) +
|
||||||
gsi::enum_const ("DifferentPropertiesConstraint", db::DifferentPropertiesConstraint,
|
gsi::enum_const ("DifferentPropertiesConstraint", db::DifferentPropertiesConstraint,
|
||||||
"@brief Specifies to consider shapes only if their user properties are different\n"
|
"@brief Specifies to consider shapes only if their user properties are different\n"
|
||||||
"When using this constraint - for example on a boolean operation - shapes are considered "
|
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||||
"only if their user properties are different. Properties are generated on the output shapes where applicable."
|
"only if their user properties are different. Properties are generated on the output shapes where applicable."
|
||||||
|
) +
|
||||||
|
gsi::enum_const ("DifferentPropertiesConstraintDrop", db::DifferentPropertiesConstraintDrop,
|
||||||
|
"@brief Specifies to consider shapes only if their user properties are different\n"
|
||||||
|
"When using this constraint - for example on a boolean operation - shapes are considered "
|
||||||
|
"only if their user properties are the same. No properties are generated on the output shapes."
|
||||||
),
|
),
|
||||||
"@brief This class represents the property constraint for boolean and check functions.\n"
|
"@brief This class represents the property constraint for boolean and check functions.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,13 @@ module DRC
|
||||||
# m1m2_overlap_connected = metal1.nets.and(metal2, props_eq)
|
# m1m2_overlap_connected = metal1.nets.and(metal2, props_eq)
|
||||||
# @/code
|
# @/code
|
||||||
#
|
#
|
||||||
|
# "props_eq" can be combined with \props_copy. In this case, properties
|
||||||
|
# are transferred to the output shapes and can be used in further processing:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# m1m2_overlap_connected = metal1.nets.and(metal2, props_eq + props_copy)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
# See also \props_ne.
|
# See also \props_ne.
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -291,6 +298,13 @@ module DRC
|
||||||
# m1m2_overlap_not_connected = metal1.nets.and(metal2, props_ne)
|
# m1m2_overlap_not_connected = metal1.nets.and(metal2, props_ne)
|
||||||
# @/code
|
# @/code
|
||||||
#
|
#
|
||||||
|
# "props_ne" can be combined with \props_copy. In this case, properties
|
||||||
|
# are transferred to the output shapes and can be used in further processing:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# m1m2_overlap_connected = metal1.nets.and(metal2, props_ne + props_copy)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
# See also \props_eq.
|
# See also \props_eq.
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
|
||||||
|
|
@ -3781,10 +3781,17 @@ CODE
|
||||||
# @code
|
# @code
|
||||||
#
|
#
|
||||||
# \props_copy is a special properties constraint that does not alter the behaviour of
|
# \props_copy is a special properties constraint that does not alter the behaviour of
|
||||||
# the checks, but copies the primary shape's properties to the output markers
|
# the checks, but copies the primary shape's properties to the output markers.
|
||||||
# (a behaviour that is implied by \props_eq and \props_ne, but not there by default).
|
|
||||||
# This constraint is applicable to \width and \notch checks too. The effect is that
|
# This constraint is applicable to \width and \notch checks too. The effect is that
|
||||||
# the original polygon's properties are copied to the error markers.
|
# the original polygon's properties are copied to the error markers.
|
||||||
|
# \props_copy can be combined with \props_eq and \props_ne to copy the original
|
||||||
|
# shape's properties to the output too:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# space_not_connected = metal1_nets.space(0.4.um, props_ne + props_copy)
|
||||||
|
# space_connected = metal1_nets.space(0.4.um, props_eq + props_copy)
|
||||||
|
# @code
|
||||||
|
#
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name space
|
# @name space
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,30 @@ module DRC
|
||||||
def initialize(v)
|
def initialize(v)
|
||||||
self.value = v
|
self.value = v
|
||||||
end
|
end
|
||||||
|
def is_eq?
|
||||||
|
self.value == RBA::Region::SamePropertiesConstraint || self.value == RBA::Region::SamePropertiesConstraintDrop
|
||||||
|
end
|
||||||
|
def is_ne?
|
||||||
|
self.value == RBA::Region::DifferentPropertiesConstraint || self.value == RBA::Region::DifferentPropertiesConstraintDrop
|
||||||
|
end
|
||||||
|
def is_copy?
|
||||||
|
self.value == RBA::Region::NoPropertyConstraint || self.value == RBA::Region::SamePropertiesConstraint || self.value == RBA::Region::DifferentPropertiesConstraint
|
||||||
|
end
|
||||||
|
def +(other)
|
||||||
|
other.is_a?(DRCPropertiesConstraint) || raise("'+' needs to be applied to two properties constraints (got #{other.inspect} for the second one)")
|
||||||
|
is_eq = self.is_eq? || other.is_eq?
|
||||||
|
is_ne = self.is_ne? || other.is_ne?
|
||||||
|
is_copy = self.is_copy? || other.is_copy?
|
||||||
|
if is_eq == is_ne
|
||||||
|
DRCPropertiesConstraint::new(is_copy ? RBA::Region::NoPropertyConstraint : RBA::Region::IgnoreProperties)
|
||||||
|
elsif is_eq
|
||||||
|
DRCPropertiesConstraint::new(is_copy ? RBA::Region::SamePropertiesConstraint : RBA::Region::SamePropertiesConstraintDrop)
|
||||||
|
elsif is_ne
|
||||||
|
DRCPropertiesConstraint::new(is_copy ? RBA::Region::DifferentPropertiesConstraint : RBA::Region::DifferentPropertiesConstraintDrop)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Negative output on checks
|
# Negative output on checks
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,15 @@ l4_wp.output(16, 0)
|
||||||
|
|
||||||
# booleans with properties constraints
|
# booleans with properties constraints
|
||||||
|
|
||||||
l3_wp.and(l4_wp, props_eq).output(20, 0)
|
l3_wp.and(l4_wp, props_eq + props_copy).output(20, 0)
|
||||||
l3_wp1.and(l4_wp, props_eq).output(21, 0)
|
l3_wp1.and(l4_wp, props_eq + props_copy).output(21, 0)
|
||||||
l3_wp2as1.and(l4_wp, props_eq).output(22, 0)
|
l3_wp2as1.and(l4_wp, props_eq + props_copy).output(22, 0)
|
||||||
l3_nowp.and(l4_wp, props_eq).output(23, 0)
|
l3_nowp.and(l4_wp, props_eq + props_copy).output(23, 0)
|
||||||
|
|
||||||
l3_wp.and(l4_wp, props_ne).output(30, 0)
|
l3_wp.and(l4_wp, props_ne + props_copy).output(30, 0)
|
||||||
l3_wp1.and(l4_wp, props_ne).output(31, 0)
|
l3_wp1.and(l4_wp, props_ne + props_copy).output(31, 0)
|
||||||
l3_wp2as1.and(l4_wp, props_ne).output(32, 0)
|
l3_wp2as1.and(l4_wp, props_ne + props_copy).output(32, 0)
|
||||||
l3_nowp.and(l4_wp, props_ne).output(33, 0)
|
l3_nowp.and(l4_wp, props_ne + props_copy).output(33, 0)
|
||||||
|
|
||||||
l3_wp.and(l4_wp, props_copy).output(40, 0)
|
l3_wp.and(l4_wp, props_copy).output(40, 0)
|
||||||
l3_wp1.and(l4_wp, props_copy).output(41, 0)
|
l3_wp1.and(l4_wp, props_copy).output(41, 0)
|
||||||
|
|
@ -79,15 +79,15 @@ l1.nets("NOTEXIST", "NOTEXIST").output(113, 0)
|
||||||
l1_nets = l1.nets
|
l1_nets = l1.nets
|
||||||
|
|
||||||
l1_nets.space(1.0.um, projection).polygons.output(200, 0)
|
l1_nets.space(1.0.um, projection).polygons.output(200, 0)
|
||||||
l1_nets.space(1.0.um, projection, props_eq).polygons.output(201, 0)
|
l1_nets.space(1.0.um, projection, props_eq + props_copy).polygons.output(201, 0)
|
||||||
l1_nets.space(1.0.um, projection, props_ne).polygons.output(202, 0)
|
l1_nets.space(1.0.um, projection, props_ne + props_copy).polygons.output(202, 0)
|
||||||
l1_nets.space(1.0.um, projection, props_copy).polygons.output(203, 0)
|
l1_nets.space(1.0.um, projection, props_copy).polygons.output(203, 0)
|
||||||
l1_nets.width(1.0.um, projection).polygons.output(204, 0)
|
l1_nets.width(1.0.um, projection).polygons.output(204, 0)
|
||||||
l1_nets.width(1.0.um, projection, props_copy).polygons.output(205, 0)
|
l1_nets.width(1.0.um, projection, props_copy).polygons.output(205, 0)
|
||||||
|
|
||||||
l1_nets.drc(space(projection) < 1.0.um).polygons.output(210, 0)
|
l1_nets.drc(space(projection) < 1.0.um).polygons.output(210, 0)
|
||||||
l1_nets.drc(space(projection) < 1.0.um, props_eq).polygons.output(211, 0)
|
l1_nets.drc(space(projection) < 1.0.um, props_eq + props_copy).polygons.output(211, 0)
|
||||||
l1_nets.drc(space(projection) < 1.0.um, props_ne).polygons.output(212, 0)
|
l1_nets.drc(space(projection) < 1.0.um, props_ne + props_copy).polygons.output(212, 0)
|
||||||
l1_nets.drc(space(projection) < 1.0.um, props_copy).polygons.output(213, 0)
|
l1_nets.drc(space(projection) < 1.0.um, props_copy).polygons.output(213, 0)
|
||||||
l1_nets.drc(width(projection) < 1.0.um).polygons.output(214, 0)
|
l1_nets.drc(width(projection) < 1.0.um).polygons.output(214, 0)
|
||||||
l1_nets.drc(width(projection) < 1.0.um, props_copy).polygons.output(215, 0)
|
l1_nets.drc(width(projection) < 1.0.um, props_copy).polygons.output(215, 0)
|
||||||
|
|
@ -103,10 +103,10 @@ l1_nets.space(1.0.um, projection, props_copy).edges.extended_in(10.nm).output(22
|
||||||
# sizing with properties
|
# sizing with properties
|
||||||
|
|
||||||
l1_nets_sized = l1_nets.sized(0.2.um)
|
l1_nets_sized = l1_nets.sized(0.2.um)
|
||||||
l1_nets_sized.and(l1_nets_sized, props_ne).output(300, 0) # overlap of different nets, same layer
|
l1_nets_sized.and(l1_nets_sized, props_ne + props_copy).output(300, 0) # overlap of different nets, same layer
|
||||||
|
|
||||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um)).output(310, 0)
|
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um)).output(310, 0)
|
||||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_ne).output(311, 0)
|
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_ne + props_copy).output(311, 0)
|
||||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_eq).output(312, 0)
|
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_eq + props_copy).output(312, 0)
|
||||||
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_copy).output(313, 0)
|
l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_copy).output(313, 0)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue