@@ -35,17 +35,9 @@ const double infinite_squares = 1e10;
3535namespace
3636{
3737
38- class PolygonPortInteractionReceiver
39- : public db::box_scanner_receiver2<const db::Polygon, size_t , const db::Polygon, size_t >
38+ class PortInteractionReceiverBase
4039{
4140public:
42- void add (const db::Polygon *obj1, const size_t &index1, const db::Polygon *obj2, const size_t &index2)
43- {
44- if (db::interact_pp (*obj1, *obj2)) {
45- m_interactions[index1].insert (index2);
46- }
47- }
48-
4941 const std::set<size_t > &interactions (size_t index) const
5042 {
5143 static std::set<size_t > empty;
@@ -57,10 +49,42 @@ class PolygonPortInteractionReceiver
5749 }
5850 }
5951
52+ protected:
53+ void insert (size_t index1, size_t index2)
54+ {
55+ m_interactions[index1].insert (index2);
56+ }
57+
6058private:
6159 std::map<size_t , std::set<size_t > > m_interactions;
6260};
6361
62+ class PolygonPortInteractionReceiver
63+ : public db::box_scanner_receiver2<const db::Polygon, size_t , const db::Polygon, size_t >,
64+ public PortInteractionReceiverBase
65+ {
66+ public:
67+ void add (const db::Polygon *obj1, const size_t &index1, const db::Polygon *obj2, const size_t &index2)
68+ {
69+ if (db::interact_pp (*obj1, *obj2)) {
70+ insert (index1, index2);
71+ }
72+ }
73+ };
74+
75+ class VertexPortInteractionReceiver
76+ : public db::box_scanner_receiver2<const db::Polygon, size_t , const db::Point, size_t >,
77+ public PortInteractionReceiverBase
78+ {
79+ public:
80+ void add (const db::Polygon *obj1, const size_t &index1, const db::Point *obj2, const size_t &index2)
81+ {
82+ if (obj1->box ().contains (*obj2) && db::inside_poly (obj1->begin_edge (), *obj2) >= 0 ) {
83+ insert (index1, index2);
84+ }
85+ }
86+ };
87+
6488struct JoinEdgeSets
6589{
6690 void operator () (std::set<db::Edge> &a, const std::set<db::Edge> &b) const
@@ -188,30 +212,60 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
188212 db::plc::Graph plc;
189213
190214 db::plc::ConvexDecomposition decomp (&plc);
191- decomp.decompose (polygon, vertex_ports, m_decomp_param, trans);
215+ decomp.decompose (polygon, m_decomp_param, trans);
192216
193- // Set up a scanner to detect interactions between polygon ports
194- // and decomposed polygons
195-
196- db::box_scanner2<const db::Polygon, size_t , const db::Polygon, size_t > scanner;
217+ // create a heap for the scanners
197218
198219 std::vector<std::pair<db::Polygon, const db::plc::Polygon *> > decomp_polygons;
199220 for (auto p = plc.begin (); p != plc.end (); ++p) {
200221 decomp_polygons.push_back (std::make_pair (db::Polygon (), p.operator -> ()));
201222 decomp_polygons.back ().first = inv_trans * p->polygon ();
202223 }
203224
204- for (auto i = decomp_polygons.begin (); i != decomp_polygons.end (); ++i) {
205- scanner.insert1 (&i->first , i - decomp_polygons.begin ());
206- }
225+ // Set up a scanner to detect interactions between polygon ports
226+ // and decomposed polygons
227+
228+ PolygonPortInteractionReceiver interactions_pp;
229+
230+ if (! decomp_polygons.empty () && ! polygon_ports.empty ()) {
231+
232+ db::box_scanner2<const db::Polygon, size_t , const db::Polygon, size_t > scanner;
233+
234+ for (auto i = decomp_polygons.begin (); i != decomp_polygons.end (); ++i) {
235+ scanner.insert1 (&i->first , i - decomp_polygons.begin ());
236+ }
237+
238+ for (auto i = polygon_ports.begin (); i != polygon_ports.end (); ++i) {
239+ scanner.insert2 (i.operator -> (), i - polygon_ports.begin ());
240+ }
241+
242+ db::box_convert<db::Polygon> bc;
243+ scanner.process (interactions_pp, 1 , bc, bc);
207244
208- for (auto i = polygon_ports.begin (); i != polygon_ports.end (); ++i) {
209- scanner.insert2 (i.operator -> (), i - polygon_ports.begin ());
210245 }
211246
212- PolygonPortInteractionReceiver interactions;
213- db::box_convert<db::Polygon> bc;
214- scanner.process (interactions, 1 , bc, bc);
247+ // Set up a scanner to detect interactions between vertex ports
248+ // and decomposed polygons
249+
250+ VertexPortInteractionReceiver interactions_vp;
251+
252+ if (! decomp_polygons.empty () && ! vertex_ports.empty ()) {
253+
254+ db::box_scanner2<const db::Polygon, size_t , const db::Point, size_t > scanner;
255+
256+ for (auto i = decomp_polygons.begin (); i != decomp_polygons.end (); ++i) {
257+ scanner.insert1 (&i->first , i - decomp_polygons.begin ());
258+ }
259+
260+ for (auto i = vertex_ports.begin (); i != vertex_ports.end (); ++i) {
261+ scanner.insert2 (i.operator -> (), i - vertex_ports.begin ());
262+ }
263+
264+ db::box_convert<db::Polygon> bc1;
265+ db::box_convert<db::Point> bc2;
266+ scanner.process (interactions_vp, 1 , bc1, bc2);
267+
268+ }
215269
216270 // Generate the internal ports: those are defined by edges connecting two polygons
217271
@@ -253,8 +307,8 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
253307 ports.clear ();
254308
255309 const db::Polygon &db_poly = p->first ;
256- const db::plc::Polygon *plc_poly = p-> second ;
257- const std::set<size_t > &pp_indexes = interactions .interactions (p - decomp_polygons.begin ());
310+ const std::set< size_t > &pp_indexes = interactions_pp. interactions (p - decomp_polygons. begin ()) ;
311+ const std::set<size_t > &vp_indexes = interactions_vp .interactions (p - decomp_polygons.begin ());
258312 const std::vector<size_t > &ip_indexes = internal_port_indexes [p - decomp_polygons.begin ()];
259313
260314 // set up the ports:
@@ -266,16 +320,12 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
266320 }
267321
268322 // 2. vertex ports
269- for (size_t i = 0 ; i < plc_poly->internal_vertexes (); ++i) {
270- auto v = plc_poly->internal_vertex (i);
271- db::Point loc = inv_trans * *v;
272- for (auto pi = v->ids ().begin (); pi != v->ids ().end (); ++pi) {
273- ports.push_back (std::make_pair (PortDefinition (pex::RNode::VertexPort, loc, *pi), (pex::RNode *) 0 ));
274- }
323+ for (auto i = vp_indexes.begin (); i != vp_indexes.end (); ++i) {
324+ db::Point loc = vertex_ports [*i];
325+ ports.push_back (std::make_pair (PortDefinition (pex::RNode::VertexPort, db::Box (loc, loc), (unsigned int ) *i), (pex::RNode *) 0 ));
275326 }
276327
277328 // 3. polygon ports
278- // (NOTE: here we only take the center of the bounding box)
279329 for (auto i = pp_indexes.begin (); i != pp_indexes.end (); ++i) {
280330 db::Box loc = polygon_ports [*i].box ();
281331 ports.push_back (std::make_pair (PortDefinition (pex::RNode::PolygonPort, loc, (unsigned int ) *i), (pex::RNode *) 0 ));
0 commit comments