mirror of https://github.com/KLayout/klayout.git
EdgePairs generic processor
This commit is contained in:
parent
b7277631c3
commit
ce88affa67
|
|
@ -147,6 +147,28 @@ void AsIfFlatEdgePairs::invalidate_bbox ()
|
|||
m_bbox_valid = false;
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
AsIfFlatEdgePairs::processed (const EdgePairProcessorBase &filter) const
|
||||
{
|
||||
std::unique_ptr<FlatEdgePairs> edge_pairs (new FlatEdgePairs ());
|
||||
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
edge_pairs->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
std::vector<db::EdgePair> res_edge_pairs;
|
||||
|
||||
for (EdgePairsIterator e = begin (); ! e.at_end (); ++e) {
|
||||
res_edge_pairs.clear ();
|
||||
filter.process (*e, res_edge_pairs);
|
||||
for (std::vector<db::EdgePair>::const_iterator er = res_edge_pairs.begin (); er != res_edge_pairs.end (); ++er) {
|
||||
edge_pairs->insert (*er);
|
||||
}
|
||||
}
|
||||
|
||||
return edge_pairs.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatEdgePairs::processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,8 +53,14 @@ public:
|
|||
|
||||
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const;
|
||||
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const;
|
||||
virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const;
|
||||
virtual EdgePairsDelegate *process_in_place (const EdgePairProcessorBase &proc)
|
||||
{
|
||||
return processed (proc);
|
||||
}
|
||||
|
||||
virtual EdgePairsDelegate *processed (const EdgePairProcessorBase &proc) const;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &proc) const;
|
||||
virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &proc) const;
|
||||
|
||||
virtual EdgePairsDelegate *add_in_place (const EdgePairs &other)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -451,6 +451,18 @@ DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const
|
|||
return res.release ();
|
||||
}
|
||||
|
||||
EdgePairsDelegate *DeepEdgePairs::process_in_place (const EdgePairProcessorBase &filter)
|
||||
{
|
||||
// TODO: implement to be really in-place
|
||||
return processed (filter);
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
DeepEdgePairs::processed (const EdgePairProcessorBase &filter) const
|
||||
{
|
||||
return shape_collection_processed_impl<db::EdgePair, db::EdgePair, db::DeepEdgePairs> (deep_layer (), filter);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepEdgePairs::processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ public:
|
|||
|
||||
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter);
|
||||
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const;
|
||||
virtual EdgePairsDelegate *process_in_place (const EdgePairProcessorBase &);
|
||||
virtual EdgePairsDelegate *processed (const EdgePairProcessorBase &) const;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const;
|
||||
virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -169,14 +169,19 @@ EdgePairs::properties_repository ()
|
|||
return *r;
|
||||
}
|
||||
|
||||
void EdgePairs::processed (Region &output, const EdgePairToPolygonProcessorBase &filter) const
|
||||
EdgePairs EdgePairs::processed (const EdgePairProcessorBase &proc) const
|
||||
{
|
||||
output = Region (mp_delegate->processed_to_polygons (filter));
|
||||
return EdgePairs (mp_delegate->processed (proc));
|
||||
}
|
||||
|
||||
void EdgePairs::processed (Edges &output, const EdgePairToEdgeProcessorBase &filter) const
|
||||
void EdgePairs::processed (Region &output, const EdgePairToPolygonProcessorBase &proc) const
|
||||
{
|
||||
output = Edges (mp_delegate->processed_to_edges (filter));
|
||||
output = Region (mp_delegate->processed_to_polygons (proc));
|
||||
}
|
||||
|
||||
void EdgePairs::processed (Edges &output, const EdgePairToEdgeProcessorBase &proc) const
|
||||
{
|
||||
output = Edges (mp_delegate->processed_to_edges (proc));
|
||||
}
|
||||
|
||||
void EdgePairs::polygons (Region &output, db::Coord e) const
|
||||
|
|
|
|||
|
|
@ -328,13 +328,31 @@ public:
|
|||
return EdgePairs (mp_delegate->filtered (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the edge pairs in-place
|
||||
*
|
||||
* This method will run the processor over all edge pairs and replace the collection by the results.
|
||||
*/
|
||||
EdgePairs &process (const EdgePairProcessorBase &proc)
|
||||
{
|
||||
set_delegate (mp_delegate->process_in_place (proc));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the edge pairs
|
||||
*
|
||||
* This method will run the processor over all edge pairs return a new edge pair collection with the results.
|
||||
*/
|
||||
EdgePairs processed (const EdgePairProcessorBase &proc) const;
|
||||
|
||||
/**
|
||||
* @brief Processes the edge pairs into polygons
|
||||
*
|
||||
* This method will run the processor over all edge pairs and return a region
|
||||
* with the outputs of the processor.
|
||||
*/
|
||||
void processed (Region &output, const EdgePairToPolygonProcessorBase &filter) const;
|
||||
void processed (Region &output, const EdgePairToPolygonProcessorBase &proc) const;
|
||||
|
||||
/**
|
||||
* @brief Processes the edge pairs into edges
|
||||
|
|
@ -342,7 +360,7 @@ public:
|
|||
* This method will run the processor over all edge pairs and return a edge collection
|
||||
* with the outputs of the processor.
|
||||
*/
|
||||
void processed (Edges &output, const EdgePairToEdgeProcessorBase &filter) const;
|
||||
void processed (Edges &output, const EdgePairToEdgeProcessorBase &proc) const;
|
||||
|
||||
/**
|
||||
* @brief Transforms the edge pair set
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class RegionDelegate;
|
|||
class EdgesDelegate;
|
||||
class Layout;
|
||||
|
||||
typedef shape_collection_processor<db::EdgePair, db::EdgePair> EdgePairProcessorBase;
|
||||
typedef shape_collection_processor<db::EdgePair, db::Polygon> EdgePairToPolygonProcessorBase;
|
||||
typedef shape_collection_processor<db::EdgePair, db::Edge> EdgePairToEdgeProcessorBase;
|
||||
|
||||
|
|
@ -194,8 +195,10 @@ public:
|
|||
|
||||
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter) = 0;
|
||||
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &filter) const = 0;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const = 0;
|
||||
virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const = 0;
|
||||
virtual EdgePairsDelegate *process_in_place (const EdgePairProcessorBase &proc) = 0;
|
||||
virtual EdgePairsDelegate *processed (const EdgePairProcessorBase &proc) const = 0;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &proc) const = 0;
|
||||
virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &proc) const = 0;
|
||||
|
||||
virtual RegionDelegate *polygons (db::Coord e) const = 0;
|
||||
virtual EdgesDelegate *edges () const = 0;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ public:
|
|||
|
||||
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &) { return this; }
|
||||
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const { return new EmptyEdgePairs (); }
|
||||
virtual EdgePairsDelegate *process_in_place (const EdgePairProcessorBase &) { return this; }
|
||||
virtual EdgePairsDelegate *processed (const EdgePairProcessorBase &) const { return new EmptyEdgePairs (); }
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const;
|
||||
virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,100 @@ Class<gsi::EdgePairFilterImpl> decl_EdgePairFilterImpl ("db", "EdgePairFilter",
|
|||
"This class has been introduced in version 0.29.\n"
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// EdgePairProcessor binding
|
||||
|
||||
Class<shape_processor_impl<db::EdgePairProcessorBase> > decl_EdgePairProcessor ("db", "EdgePairOperator",
|
||||
shape_processor_impl<db::EdgePairProcessorBase>::method_decls (false),
|
||||
"@brief A generic edge-pair operator\n"
|
||||
"\n"
|
||||
"Edge pair processors are an efficient way to process edge pairs from an edge pair collection. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to the \\EdgePairs#processed or \\EdgePairs#process method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge pair from the edge pair collection and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output edge_pairs derived from the input edge pair.\n"
|
||||
"The output edge pair collection is the sum over all these individual results.\n"
|
||||
"\n"
|
||||
"The magic happens when deep mode edge pair collections are involved. In that case, the processor will use as few calls as possible "
|
||||
"and exploit the hierarchical compression if possible. It needs to know however, how the operator behaves. You "
|
||||
"need to configure the operator by calling \\is_isotropic, \\is_scale_invariant or \\is_isotropic_and_scale_invariant "
|
||||
"before using it.\n"
|
||||
"\n"
|
||||
"You can skip this step, but the processor algorithm will assume the worst case then. This usually leads to cell variant "
|
||||
"formation which is not always desired and blows up the hierarchy.\n"
|
||||
"\n"
|
||||
"Here is some example that flips the edge pairs (swaps first and second edge):"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"class FlipEdgePairs < RBA::EdgePairOperator\n"
|
||||
"\n"
|
||||
" # Constructor\n"
|
||||
" def initialize\n"
|
||||
" self.is_isotropic_and_scale_invariant # orientation and scale do not matter\n"
|
||||
" end\n"
|
||||
" \n"
|
||||
" # Flips the edge pair\n"
|
||||
" def process(edge_pair)\n"
|
||||
" return [ RBA::EdgePair::new(edge_pair.second, edge_pair.first) ]\n"
|
||||
" end\n"
|
||||
"\n"
|
||||
"end\n"
|
||||
"\n"
|
||||
"edge_pairs = ... # some EdgePairs object\n"
|
||||
"flipped = edge_pairs.processed(FlipEdgePairs::new)\n"
|
||||
"@/code\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.29.\n"
|
||||
);
|
||||
|
||||
Class<shape_processor_impl<db::EdgePairToPolygonProcessorBase> > decl_EdgePairToPolygonProcessor ("db", "EdgePairToPolygonOperator",
|
||||
shape_processor_impl<db::EdgePairToPolygonProcessorBase>::method_decls (false),
|
||||
"@brief A generic edge-pair-to-polygon operator\n"
|
||||
"\n"
|
||||
"Edge pair processors are an efficient way to process edge pairs from an edge pair collection. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to the \\EdgePairs#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge pair from the edge pair collection and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output polygons derived from the input edge pair.\n"
|
||||
"The output region is the sum over all these individual results.\n"
|
||||
"\n"
|
||||
"The magic happens when deep mode edge pair collections are involved. In that case, the processor will use as few calls as possible "
|
||||
"and exploit the hierarchical compression if possible. It needs to know however, how the operator behaves. You "
|
||||
"need to configure the operator by calling \\is_isotropic, \\is_scale_invariant or \\is_isotropic_and_scale_invariant "
|
||||
"before using it.\n"
|
||||
"\n"
|
||||
"You can skip this step, but the processor algorithm will assume the worst case then. This usually leads to cell variant "
|
||||
"formation which is not always desired and blows up the hierarchy.\n"
|
||||
"\n"
|
||||
"For a basic example see the \\EdgeToPolygonOperator class, with the exception that this incarnation receives edge pairs.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.29.\n"
|
||||
);
|
||||
|
||||
Class<shape_processor_impl<db::EdgePairToEdgeProcessorBase> > decl_EdgePairToEdgeProcessor ("db", "EdgePairToEdgeOperator",
|
||||
shape_processor_impl<db::EdgePairToEdgeProcessorBase>::method_decls (false),
|
||||
"@brief A generic edge-pair-to-edge operator\n"
|
||||
"\n"
|
||||
"Edge processors are an efficient way to process edge pairs from an edge pair collection. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\EdgePairs#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge from the edge collection and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output edges derived from the input edge pair.\n"
|
||||
"The output edge pair collection is the sum over all these individual results.\n"
|
||||
"\n"
|
||||
"The magic happens when deep mode edge pair collections are involved. In that case, the processor will use as few calls as possible "
|
||||
"and exploit the hierarchical compression if possible. It needs to know however, how the operator behaves. You "
|
||||
"need to configure the operator by calling \\is_isotropic, \\is_scale_invariant or \\is_isotropic_and_scale_invariant "
|
||||
"before using it.\n"
|
||||
"\n"
|
||||
"You can skip this step, but the processor algorithm will assume the worst case then. This usually leads to cell variant "
|
||||
"formation which is not always desired and blows up the hierarchy.\n"
|
||||
"\n"
|
||||
"For a basic example see the \\EdgeToEdgePairOperator class, with the exception that this incarnation has to deliver edges and takes edge pairs.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.29.\n"
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// EdgePairs binding
|
||||
|
||||
|
|
@ -267,6 +361,30 @@ static void filter (db::EdgePairs *r, const EdgePairFilterImpl *f)
|
|||
r->filter (*f);
|
||||
}
|
||||
|
||||
static db::EdgePairs processed_epep (const db::EdgePairs *r, const shape_processor_impl<db::EdgePairProcessorBase> *f)
|
||||
{
|
||||
return r->processed (*f);
|
||||
}
|
||||
|
||||
static void process_epep (db::EdgePairs *r, const shape_processor_impl<db::EdgePairProcessorBase> *f)
|
||||
{
|
||||
r->process (*f);
|
||||
}
|
||||
|
||||
static db::Edges processed_epe (const db::EdgePairs *r, const shape_processor_impl<db::EdgePairToEdgeProcessorBase> *f)
|
||||
{
|
||||
db::Edges out;
|
||||
r->processed (out, *f);
|
||||
return out;
|
||||
}
|
||||
|
||||
static db::Region processed_epp (const db::EdgePairs *r, const shape_processor_impl<db::EdgePairToPolygonProcessorBase> *f)
|
||||
{
|
||||
db::Region out;
|
||||
r->processed (out, *f);
|
||||
return out;
|
||||
}
|
||||
|
||||
static db::EdgePairs with_distance1 (const db::EdgePairs *r, db::EdgePairs::distance_type length, bool inverse)
|
||||
{
|
||||
db::EdgePairFilterByDistance ef (length, length + 1, inverse);
|
||||
|
|
@ -717,6 +835,30 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.29.\n"
|
||||
) +
|
||||
method_ext ("process", &process_epep, gsi::arg ("process"),
|
||||
"@brief Applies a generic edge pair processor in place (replacing the edge pairs from the EdgePairs collection)\n"
|
||||
"See \\EdgePairProcessor for a description of this feature.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.\n"
|
||||
) +
|
||||
method_ext ("processed", &processed_epep, gsi::arg ("processed"),
|
||||
"@brief Applies a generic edge pair processor and returns a processed copy\n"
|
||||
"See \\EdgePairProcessor for a description of this feature.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.\n"
|
||||
) +
|
||||
method_ext ("processed", &processed_epe, gsi::arg ("processed"),
|
||||
"@brief Applies a generic edge-pair-to-edge processor and returns an edge collection with the results\n"
|
||||
"See \\EdgePairToEdgeProcessor for a description of this feature.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.\n"
|
||||
) +
|
||||
method_ext ("processed", &processed_epp, gsi::arg ("processed"),
|
||||
"@brief Applies a generic edge-pair-to-polygon processor and returns an Region with the results\n"
|
||||
"See \\EdgePairToPolygonProcessor for a description of this feature.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.\n"
|
||||
) +
|
||||
method_ext ("with_length", with_length1, gsi::arg ("length"), gsi::arg ("inverse"),
|
||||
"@brief Filters the edge pairs by length of one of their edges\n"
|
||||
"Filters the edge pairs in the edge pair collection by length of at least one of their edges. If \"inverse\" is false, only "
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ Class<gsi::EdgeFilterImpl> decl_EdgeFilterImpl ("db", "EdgeFilter",
|
|||
"@brief A generic edge filter adaptor\n"
|
||||
"\n"
|
||||
"Edge filters are an efficient way to filter edge from a Edges collection. To apply a filter, derive your own "
|
||||
"filter class and pass an instance to \\Edges#filter or \\Edges#filtered method.\n"
|
||||
"filter class and pass an instance to the \\Edges#filter or \\Edges#filtered method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge from the collection and present it to the filter's 'selected' method.\n"
|
||||
"Based on the result of this evaluation, the edge is kept or discarded.\n"
|
||||
|
|
@ -131,7 +131,7 @@ Class<shape_processor_impl<db::EdgeProcessorBase> > decl_EdgeProcessorBase ("db"
|
|||
"@brief A generic edge-to-polygon operator\n"
|
||||
"\n"
|
||||
"Edge processors are an efficient way to process edges from an edge collection. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\Edges#processed method.\n"
|
||||
"operator class and pass an instance to the \\Edges#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge from the edge collection and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output edges derived from the input edge.\n"
|
||||
|
|
@ -176,7 +176,7 @@ Class<shape_processor_impl<db::EdgeToPolygonProcessorBase> > decl_EdgeToPolygonP
|
|||
"@brief A generic edge-to-polygon operator\n"
|
||||
"\n"
|
||||
"Edge processors are an efficient way to process edges from an edge collection. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\Edges#processed method.\n"
|
||||
"operator class and pass an instance to the \\Edges#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge from the edge collection and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output polygons derived from the input edge.\n"
|
||||
|
|
@ -200,7 +200,7 @@ Class<shape_processor_impl<db::EdgeToEdgePairProcessorBase> > decl_EdgeToEdgePai
|
|||
"@brief A generic edge-to-edge-pair operator\n"
|
||||
"\n"
|
||||
"Edge processors are an efficient way to process edges from an edge collection. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\Edges#processed method.\n"
|
||||
"operator class and pass an instance to the \\Edges#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each edge from the edge collection and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output edge pairs derived from the input edge.\n"
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ Class<gsi::PolygonFilterImpl> decl_PolygonFilterImpl ("db", "PolygonFilter",
|
|||
"@brief A generic polygon filter adaptor\n"
|
||||
"\n"
|
||||
"Polygon filters are an efficient way to filter polygons from a Region. To apply a filter, derive your own "
|
||||
"filter class and pass an instance to \\Region#filter or \\Region#filtered method.\n"
|
||||
"filter class and pass an instance to the \\Region#filter or \\Region#filtered method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each polygon from the region and present it to the filter's 'selected' method.\n"
|
||||
"Based on the result of this evaluation, the polygon is kept or discarded.\n"
|
||||
|
|
@ -135,7 +135,7 @@ Class<shape_processor_impl<db::PolygonProcessorBase> > decl_PolygonOperator ("db
|
|||
"@brief A generic polygon operator\n"
|
||||
"\n"
|
||||
"Polygon processors are an efficient way to process polygons from a Region. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\Region#process or \\Region#processed method.\n"
|
||||
"operator class and pass an instance to the \\Region#process or \\Region#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each polygon from the region and present it to the operators' 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output polygons derived from the input polygon.\n"
|
||||
|
|
@ -180,7 +180,7 @@ Class<shape_processor_impl<db::PolygonToEdgeProcessorBase> > decl_PolygonToEdgeP
|
|||
"@brief A generic polygon-to-edge operator\n"
|
||||
"\n"
|
||||
"Polygon processors are an efficient way to process polygons from a Region. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\Region#processed method.\n"
|
||||
"operator class and pass an instance to the \\Region#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each polygon from the region and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output edges derived from the input polygon.\n"
|
||||
|
|
@ -204,7 +204,7 @@ Class<shape_processor_impl<db::PolygonToEdgePairProcessorBase> > decl_PolygonToE
|
|||
"@brief A generic polygon-to-edge-pair operator\n"
|
||||
"\n"
|
||||
"Polygon processors are an efficient way to process polygons from a Region. To apply a processor, derive your own "
|
||||
"operator class and pass an instance to \\Region#processed method.\n"
|
||||
"operator class and pass an instance to the \\Region#processed method.\n"
|
||||
"\n"
|
||||
"Conceptually, these methods take each polygon from the region and present it to the operator's 'process' method.\n"
|
||||
"The result of this call is a list of zero to many output edge pairs derived from the input polygon.\n"
|
||||
|
|
|
|||
|
|
@ -44,6 +44,46 @@ class PerpendicularEdgesFilter < RBA::EdgePairFilter
|
|||
|
||||
end
|
||||
|
||||
class FlipEdgePair < RBA::EdgePairOperator
|
||||
|
||||
# Constructor
|
||||
def initialize
|
||||
self.is_isotropic_and_scale_invariant # orientation and scale do not matter
|
||||
end
|
||||
|
||||
# Flips the edge pair
|
||||
def process(edge_pair)
|
||||
return [ RBA::EdgePair::new(edge_pair.second, edge_pair.first) ]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class SomeEdgePairToEdgeOperator < RBA::EdgePairToEdgeOperator
|
||||
|
||||
# Constructor
|
||||
def initialize
|
||||
self.is_isotropic_and_scale_invariant # scale or orientation do not matter
|
||||
end
|
||||
|
||||
def process(ep)
|
||||
return [ RBA::Edge::new(ep.first.p1, ep.second.p2) ]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class SomeEdgePairToPolygonOperator < RBA::EdgePairToPolygonOperator
|
||||
|
||||
# Constructor
|
||||
def initialize
|
||||
self.is_isotropic_and_scale_invariant # scale or orientation do not matter
|
||||
end
|
||||
|
||||
def process(ep)
|
||||
return [ RBA::Polygon::new(ep.bbox) ]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class DBEdgePairs_TestClass < TestBase
|
||||
|
||||
# Basics
|
||||
|
|
@ -374,6 +414,61 @@ class DBEdgePairs_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# Generic processors
|
||||
def test_generic_processors_epep
|
||||
|
||||
# Some basic tests for the processor class
|
||||
|
||||
f = FlipEdgePair::new
|
||||
assert_equal(f.wants_variants?, true)
|
||||
f.wants_variants = false
|
||||
assert_equal(f.wants_variants?, false)
|
||||
|
||||
# Smoke test
|
||||
f.is_isotropic
|
||||
f.is_scale_invariant
|
||||
|
||||
# Some application
|
||||
|
||||
edge_pairs = RBA::EdgePairs::new
|
||||
|
||||
edge_pairs.insert(RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 100), RBA::Edge::new(200, 300, 200, 500)))
|
||||
|
||||
assert_equal(edge_pairs.processed(FlipEdgePair::new).to_s, "(200,300;200,500)/(0,0;100,100)")
|
||||
assert_equal(edge_pairs.to_s, "(0,0;100,100)/(200,300;200,500)")
|
||||
edge_pairs.process(FlipEdgePair::new)
|
||||
assert_equal(edge_pairs.to_s, "(200,300;200,500)/(0,0;100,100)")
|
||||
|
||||
end
|
||||
|
||||
# Generic processors
|
||||
def test_generic_processors_epe
|
||||
|
||||
p = SomeEdgePairToEdgeOperator::new
|
||||
|
||||
edge_pairs = RBA::EdgePairs::new
|
||||
|
||||
edge_pairs.insert(RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 100), RBA::Edge::new(200, 300, 200, 500)))
|
||||
|
||||
assert_equal(edge_pairs.processed(p).to_s, "(0,0;200,500)")
|
||||
assert_equal(edge_pairs.to_s, "(0,0;100,100)/(200,300;200,500)")
|
||||
|
||||
end
|
||||
|
||||
# Generic processors
|
||||
def test_generic_processors_epp
|
||||
|
||||
p = SomeEdgePairToPolygonOperator::new
|
||||
|
||||
edge_pairs = RBA::EdgePairs::new
|
||||
|
||||
edge_pairs.insert(RBA::EdgePair::new(RBA::Edge::new(0, 0, 100, 100), RBA::Edge::new(200, 300, 200, 500)))
|
||||
|
||||
assert_equal(edge_pairs.processed(p).to_s, "(0,0;0,500;200,500;200,0)")
|
||||
assert_equal(edge_pairs.to_s, "(0,0;100,100)/(200,300;200,500)")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue