Branch data Line data Source code
1 : : #include "meshkit/AF2Rule.hpp"
2 : :
3 : : // C++
4 : : #include <set>
5 : : #include <stack>
6 : :
7 : : // MeshKit
8 : : #include "meshkit/AF2Binding.hpp"
9 : : #include "meshkit/AF2RuleApplication.hpp"
10 : : #include "meshkit/Error.hpp"
11 : : using namespace MeshKit;
12 : : /**
13 : : * A template method for allocating an array to hold the contents of a list
14 : : * of pointers and copying the pointers from the list to the array.
15 : : */
16 : : template<class T>
17 : 1674 : void aF2RuleCopyListToArray(std::list<T*> const & aListOfPtr,
18 : : T** & anArrayOfPtr, unsigned int offset = 0u)
19 : : {
20 [ + - ][ + - ]: 1674 : anArrayOfPtr = new T*[offset + aListOfPtr.size()];
[ + - ][ + - ]
[ + - ]
21 : : typedef typename std::list<T*>::const_iterator ItrType;
22 : 1674 : unsigned int indx = offset;
23 [ + - ][ + - ]: 3773 : for (ItrType itr = aListOfPtr.begin(); itr != aListOfPtr.end(); ++itr)
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ]
24 : : {
25 [ + - ][ - + ]: 2099 : if (*itr == NULL)
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
26 : : {
27 [ # # ][ # # ]: 0 : MeshKit::Error badArg(MK_BAD_INPUT);
[ # # ][ # # ]
[ # # ]
28 [ # # ][ # # ]: 0 : badArg.set_string(
[ # # ][ # # ]
[ # # ]
29 : : "AF2Rule constructor arguments may not contain any null pointers.");
30 [ # # ][ # # ]: 0 : throw badArg;
[ # # ][ # # ]
[ # # ]
31 : : }
32 [ + - ][ + - ]: 2099 : anArrayOfPtr[indx] = *itr;
[ + - ][ + - ]
[ + - ]
33 : 2099 : ++indx;
34 : : }
35 : 1674 : }
36 : :
37 : : /**
38 : : * A template method for deleting the objects that are pointed to by the
39 : : * pointers in a dynamically allocated array of pointers and then deleting
40 : : * the array itself.
41 : : */
42 : : template<class T>
43 : 1395 : void aF2RuleDeepDeletePtrArray(T** & anArrayOfPtr, int arraySize)
44 : : {
45 [ + + ][ + + ]: 3747 : for (int indx = 0; indx < arraySize; ++indx)
[ + + ][ + + ]
[ + + ]
46 : : {
47 [ + - ][ + - ]: 2352 : delete anArrayOfPtr[indx];
48 : : }
49 [ + - ][ + - ]: 1395 : delete[] anArrayOfPtr;
[ + - ][ + - ]
[ + - ]
50 : 1395 : }
51 : :
52 : 279 : AF2Rule::AF2Rule(std::string const & ruleNameArg, unsigned int maxQuality,
53 : : std::list<const AF2RuleExistVertex*> const & ruleVertices,
54 : : const AF2RuleExistEdge* baselineEdge,
55 : : std::list<const AF2RuleExistEdge*> const & otherRuleEdges,
56 : : const AF2FreeZoneDef* freeZoneDef,
57 : : std::list<const AF2RuleNewVertex*> const & ruleNewVertices,
58 : : std::list<const AF2RuleNewEdge*> const & ruleNewEdges,
59 : : std::list<const AF2RuleNewFace*> const & ruleNewFaces) :
60 : : ruleName(ruleNameArg),
61 : : maxQualityLevel(maxQuality),
62 : 279 : numExVertices(ruleVertices.size()),
63 : 279 : numExEdges(1u + otherRuleEdges.size()),
64 : : freeZoneDef(freeZoneDef),
65 : 279 : numNewVertices(ruleNewVertices.size()),
66 : 279 : numNewEdges(ruleNewEdges.size()),
67 : 558 : numNewFaces(ruleNewFaces.size())
68 : : {
69 [ - + ]: 279 : if (baselineEdge == NULL)
70 : : {
71 [ # # ]: 0 : MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
72 [ # # ]: 0 : badArg.set_string("The baseline edge may not be null.");
73 [ # # ]: 0 : throw badArg;
74 : : }
75 [ - + ]: 279 : if (numExVertices < 2)
76 : : {
77 [ # # ]: 0 : MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
78 [ # # ]: 0 : badArg.set_string("AF2Rule must define at least two existing vertices.");
79 [ # # ]: 0 : throw badArg;
80 : : }
81 [ + - ]: 279 : aF2RuleCopyListToArray(ruleVertices, exVertices);
82 [ + - ]: 279 : aF2RuleCopyListToArray(otherRuleEdges, exEdges, 1u);
83 : 279 : exEdges[0] = baselineEdge;
84 [ + - ]: 279 : aF2RuleCopyListToArray(ruleNewVertices, newVertices);
85 [ + - ]: 279 : aF2RuleCopyListToArray(ruleNewEdges, newEdges);
86 [ + - ]: 279 : aF2RuleCopyListToArray(ruleNewFaces, newFaces);
87 [ + - ]: 279 : checkExEndpointsAndFindIsolatedVertices();
88 : 279 : }
89 : :
90 : 558 : AF2Rule::~AF2Rule()
91 : : {
92 [ + - ]: 279 : delete[] exIsoVertices;
93 : 279 : aF2RuleDeepDeletePtrArray(newFaces, numNewFaces);
94 : 279 : aF2RuleDeepDeletePtrArray(newEdges, numNewEdges);
95 : 279 : aF2RuleDeepDeletePtrArray(newVertices, numNewVertices);
96 : 279 : aF2RuleDeepDeletePtrArray(exEdges, numExEdges);
97 : 279 : aF2RuleDeepDeletePtrArray(exVertices, numExVertices);
98 [ + - ]: 279 : delete freeZoneDef;
99 : 279 : }
100 : :
101 : 0 : AF2Rule::AF2Rule(const AF2Rule & toCopy) :
102 : : ruleName(toCopy.ruleName),
103 : : maxQualityLevel(toCopy.maxQualityLevel),
104 : : numExVertices(toCopy.numExVertices),
105 : : numExEdges(toCopy.numExEdges),
106 [ # # ]: 0 : freeZoneDef(toCopy.freeZoneDef->clone()),
107 : : numNewVertices(toCopy.numNewVertices),
108 : : numNewEdges(toCopy.numNewEdges),
109 : 0 : numNewFaces(toCopy.numNewFaces)
110 : : {
111 [ # # ]: 0 : MeshKit::Error notImpl(MeshKit::MK_NOT_IMPLEMENTED);
112 [ # # ]: 0 : notImpl.set_string("AF2Rule copy construction is not supported.");
113 [ # # ]: 0 : throw notImpl;
114 : : }
115 : :
116 : 0 : AF2Rule& AF2Rule::operator=(const AF2Rule & rhs)
117 : : {
118 [ # # ]: 0 : MeshKit::Error notImpl(MeshKit::MK_NOT_IMPLEMENTED);
119 [ # # ]: 0 : notImpl.set_string("AF2Rule assignment operator is not supported.");
120 [ # # ]: 0 : throw notImpl;
121 : : }
122 : :
123 : 279 : void AF2Rule::checkExEndpointsAndFindIsolatedVertices()
124 : : {
125 [ + - ]: 279 : std::set<const AF2RuleExistVertex*> endPoints;
126 [ + + ]: 770 : for (unsigned int exEdgeIndx = 0; exEdgeIndx < numExEdges; ++exEdgeIndx)
127 : : {
128 [ + + ][ - + ]: 491 : if (exEdgeIndx > 0 && exEdges[exEdgeIndx] == exEdges[0])
129 : : {
130 [ # # ]: 0 : MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
131 [ # # ]: 0 : badArg.set_string("The baseline edge may not be listed in the rule's other existing edges.");
132 [ # # ]: 0 : throw badArg;
133 : : }
134 [ + - ][ + - ]: 491 : endPoints.insert(exEdges[exEdgeIndx]->getStart());
135 [ + - ][ + - ]: 491 : endPoints.insert(exEdges[exEdgeIndx]->getEnd());
136 : : }
137 : :
138 [ + - ]: 558 : std::list<const AF2RuleExistVertex*> isoVertList;
139 [ + - ]: 558 : std::set<const AF2RuleExistVertex*> allVertSet;
140 [ + + ]: 1070 : for (unsigned int exVtxIndx = 0; exVtxIndx < numExVertices; ++exVtxIndx)
141 : : {
142 [ + - ]: 791 : allVertSet.insert(exVertices[exVtxIndx]);
143 : : std::set<const AF2RuleExistVertex*>::iterator endPntItr =
144 [ + - ]: 791 : endPoints.find(exVertices[exVtxIndx]);
145 [ + - ][ + + ]: 791 : if (endPntItr == endPoints.end())
146 : : {
147 : : // the vertex is an isolated vertex rather than an endpoint of an edge
148 [ + - ]: 26 : isoVertList.push_back(exVertices[exVtxIndx]);
149 : : }
150 : : else
151 : : {
152 [ + - ]: 765 : endPoints.erase(endPntItr);
153 : : }
154 : : }
155 : :
156 [ - + ]: 279 : if (!endPoints.empty())
157 : : {
158 [ # # ]: 0 : MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
159 [ # # ]: 0 : badArg.set_string("The endpoints of the rule's existing edges are not all existing vertices.");
160 [ # # ]: 0 : throw badArg;
161 : : }
162 : :
163 [ - + ]: 279 : if (allVertSet.size() != numExVertices)
164 : : {
165 [ # # ]: 0 : MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
166 [ # # ]: 0 : badArg.set_string("There is a duplicate existing vertex.");
167 [ # # ]: 0 : throw badArg;
168 : : }
169 : :
170 : 279 : numExIsoVertices = isoVertList.size();
171 [ + - ]: 558 : aF2RuleCopyListToArray(isoVertList, exIsoVertices);
172 : 279 : }
173 : :
174 : 90 : std::string AF2Rule::getName() const
175 : : {
176 : 90 : return ruleName;
177 : : }
178 : :
179 : : std::map<const AF2RuleExistEdge*, std::list<const AF2Edge2D*>*>*
180 : 78616 : AF2Rule::findPotentialEdgeMatches(AF2Neighborhood const & ngbhd,
181 : : unsigned int matchQuality) const
182 : : {
183 : : // define a map to hold the potential match information
184 : : std::map<const AF2RuleExistEdge*, std::list<const AF2Edge2D*>*>* matchMap =
185 [ + - ]: 78616 : new std::map<const AF2RuleExistEdge*, std::list<const AF2Edge2D*>*>();
186 : :
187 : : // First match the baseline edge
188 : : std::list<const AF2Edge2D*>* baselineEdgeMatches =
189 [ + - ]: 78616 : new std::list<const AF2Edge2D*>();
190 [ + + ]: 78616 : if (isMatchingEdge(*(ngbhd.getBaselineEdge2D()), *exEdges[0], matchQuality))
191 : : {
192 [ + - ]: 75309 : baselineEdgeMatches->push_back(ngbhd.getBaselineEdge2D());
193 : : }
194 : 78616 : (*matchMap)[exEdges[0]] = baselineEdgeMatches;
195 : :
196 : : // Match any other existing edges that the rule may define
197 : 78616 : const std::list<const AF2Edge2D*>* ngbhdEdges = ngbhd.getEdges2D();
198 [ + + ]: 157417 : for (unsigned int indx = 1u; indx < numExEdges; ++indx)
199 : : {
200 : 78801 : const AF2RuleExistEdge* ruleEdge = exEdges[indx];
201 : : std::list<const AF2Edge2D*>* possMatches =
202 [ + - ][ + - ]: 78801 : new std::list<const AF2Edge2D*>();
203 [ + - + - ]: 4502062 : for (std::list<const AF2Edge2D*>::const_iterator ngbEdgeItr =
[ + + ]
204 : 2329832 : ngbhdEdges->begin(); ngbEdgeItr != ngbhdEdges->end(); ++ngbEdgeItr)
205 : : {
206 [ + - ][ + - ]: 2172230 : if (isMatchingEdge(**ngbEdgeItr, *ruleEdge, matchQuality))
[ + + ]
207 : : {
208 [ + - ][ + - ]: 24378 : possMatches->push_back(*ngbEdgeItr);
209 : : }
210 : : }
211 [ + - ]: 78801 : (*matchMap)[ruleEdge] = possMatches;
212 : : }
213 : :
214 : 78616 : return matchMap;
215 : : }
216 : :
217 : : std::map<const AF2RuleExistVertex*, std::list<const AF2Point2D*>*>*
218 : 78616 : AF2Rule::findPotentialVertexMatches(AF2Neighborhood const & ngbhd,
219 : : unsigned int matchQuality) const
220 : : {
221 : 78616 : const std::list<const AF2Point2D*>* ngbhdPoints = ngbhd.getPoints2D();
222 : : std::map<const AF2RuleExistVertex*,
223 : : std::list<const AF2Point2D*>*>* matchMap =
224 [ + - ]: 78616 : new std::map<const AF2RuleExistVertex*, std::list<const AF2Point2D*>*>();
225 [ + + ]: 88387 : for (unsigned indx = 0; indx < numExIsoVertices; ++indx)
226 : : {
227 : 9771 : const AF2RuleExistVertex* ruleVertex = exIsoVertices[indx];
228 : : std::list<const AF2Point2D*>* possMatches =
229 [ + - ][ + - ]: 9771 : new std::list<const AF2Point2D*>();
230 [ + - + - ]: 580352 : for (std::list<const AF2Point2D*>::const_iterator ngbPointItr =
[ + + ]
231 : 299947 : ngbhdPoints->begin(); ngbPointItr != ngbhdPoints->end(); ++ngbPointItr)
232 : : {
233 [ + - ][ + - ]: 280405 : if (isMatchingVertex(**ngbPointItr, *ruleVertex, matchQuality))
[ + + ]
234 : : {
235 [ + - ][ + - ]: 3589 : possMatches->push_back(*ngbPointItr);
236 : : }
237 : : }
238 [ + - ]: 9771 : (*matchMap)[ruleVertex] = possMatches;
239 : : }
240 : :
241 : 78616 : return matchMap;
242 : : }
243 : :
244 : 2250846 : bool AF2Rule::isMatchingEdge(AF2Edge2D const & edge,
245 : : AF2RuleExistEdge const & ruleEdge, unsigned int matchQuality) const
246 : : {
247 [ + + ]: 4501692 : if (!isMatchingVertex(*(edge.getStart()), *(ruleEdge.getStart()),
248 [ + + + + ]: 2544414 : matchQuality) || !isMatchingVertex(*(edge.getEnd()),
249 : 293568 : *(ruleEdge.getEnd()), matchQuality))
250 : : {
251 : 2151159 : return false;
252 : : }
253 : :
254 : 99687 : double matchTol = 0.25 + 0.15 * matchQuality;
255 : 99687 : matchTol *= matchTol;
256 : 99687 : return ruleEdge.isMatching(*(edge.getStart()), *(edge.getEnd()), matchTol);
257 : : }
258 : :
259 : 2678035 : bool AF2Rule::isMatchingVertex(AF2Point2D const & point,
260 : : AF2RuleExistVertex const & ruleVertex, unsigned int matchQuality) const
261 : : {
262 : 2678035 : double matchTol = 0.25 + 0.15 * matchQuality;
263 : 2678035 : matchTol *= matchTol;
264 : 2678035 : return ruleVertex.isMatching(point, matchTol);
265 : : }
266 : :
267 : 117498 : void AF2Rule::applyRule(AF2Neighborhood const & ngbhd,
268 : : unsigned int matchQuality, AF2RuleAppVisitor & visitor) const
269 : : {
270 [ + + ]: 117498 : if (matchQuality < maxQualityLevel)
271 : : {
272 : 117498 : return;
273 : : }
274 : :
275 : : std::map<const AF2RuleExistEdge*, std::list<const AF2Edge2D*>*>*
276 [ + - ]: 78616 : matchingEdgesMap = findPotentialEdgeMatches(ngbhd, matchQuality);
277 : : std::map<const AF2RuleExistVertex*, std::list<const AF2Point2D*>*>*
278 [ + - ]: 78616 : matchingVerticesMap = findPotentialVertexMatches(ngbhd, matchQuality);
279 : :
280 [ + - ]: 78616 : AF2Binding binding;
281 : :
282 [ + - ][ + - ]: 157232 : std::stack<std::list<const AF2Edge2D*>::const_iterator> edgeMatchItrStack;
283 : 78616 : unsigned int edgeToMatchIndx = 0;
284 : 78616 : --edgeToMatchIndx;
285 : 78616 : bool consistentMatch = true;
286 : 78616 : const AF2RuleExistEdge* edgeToMatch = NULL;
287 : : while (true)
288 : : {
289 [ + + ]: 311245 : if (consistentMatch)
290 : : {
291 : 169602 : ++edgeToMatchIndx;
292 [ + + ]: 169602 : if (edgeToMatchIndx == numExEdges)
293 : : {
294 : : // all edges have been matched
295 : : // stage two matches any isolated vertices and proceeds
296 : : // to stages three and four
297 : : applyRuleStageTwo(ngbhd, matchQuality, visitor,
298 [ + - ]: 27959 : matchingVerticesMap, binding);
299 : : // now mark the match as inconsistent, so that the edge binding
300 : : // for the final edge is released and the search continues
301 : 27959 : consistentMatch = false;
302 : : }
303 : : else
304 : : {
305 : : // not all edges have been matched yet, so set up to attempt to
306 : : // match the next edge given the current binding
307 : 141643 : edgeToMatch = exEdges[edgeToMatchIndx];
308 [ + - ][ + - ]: 169602 : edgeMatchItrStack.push((*matchingEdgesMap)[edgeToMatch]->begin());
[ + - ]
309 : : }
310 : : }
311 : :
312 [ + + ]: 311245 : if (!consistentMatch)
313 : : {
314 [ + + ]: 169602 : if (edgeToMatchIndx == 0)
315 : : {
316 : : // all edges beyond the base edge have examined all possible matches
317 : 78616 : break;
318 : : }
319 : 90986 : --edgeToMatchIndx;
320 : 90986 : edgeToMatch = exEdges[edgeToMatchIndx];
321 : : // release the edge binding from the last time edgeToMatch was bound
322 [ + - ]: 90986 : binding.release(edgeToMatch);
323 : : }
324 : :
325 : 232629 : consistentMatch = false;
326 [ + - ]: 232629 : std::list<const AF2Edge2D*>::const_iterator itr = edgeMatchItrStack.top();
327 [ + - ]: 232629 : edgeMatchItrStack.pop();
328 [ + - ][ + - ]: 327446 : for (; itr != (*matchingEdgesMap)[edgeToMatch]->end(); ++itr)
[ + - ][ + - ]
[ + + ]
329 : : {
330 : : // check consistency
331 : 94817 : consistentMatch = true;
332 [ + - ][ + - ]: 94817 : if (!binding.isConsistent(edgeToMatch, *itr))
[ + + ]
333 : : {
334 : 3831 : consistentMatch = false;
335 : : }
336 : : else
337 : : {
338 : : // bind the edge and store the next position of the iterator
339 : : // on the iterator stack for later examination
340 [ + - ][ + - ]: 90986 : binding.bind(edgeToMatch, *itr);
341 [ + - ][ + - ]: 90986 : edgeMatchItrStack.push(++itr);
342 : :
343 : : // break out of this loop and proceed to bind other edges or vertices
344 : : // or check the free zone and finish applying the rule
345 : 90986 : break;
346 : : }
347 : : }
348 : 78616 : }
349 : : }
350 : :
351 : 27959 : void AF2Rule::applyRuleStageTwo(AF2Neighborhood const & ngbhd,
352 : : unsigned int matchQuality, AF2RuleAppVisitor & visitor,
353 : : std::map<const AF2RuleExistVertex*, std::list<const AF2Point2D*>*>* const &
354 : : matchingVerticesMap, AF2Binding & binding) const
355 : : {
356 : : // Note: At this point it would be possible to filter the lists
357 : : // of vertices that are potential matches, removing any potential
358 : : // matches that are already bound as endpoints of edges, but it's
359 : : // not clear that the performance improvement, if any, would offset
360 : : // the additional memory for storing the filtered list and the
361 : : // additional computation.
362 : :
363 [ + - ][ + - ]: 27959 : std::stack<std::list<const AF2Point2D*>::const_iterator> vertexMatchItrStack;
364 : 27959 : unsigned int vertexToMatchIndx = 0;
365 : 27959 : --vertexToMatchIndx;
366 : 27959 : bool consistentMatch = true;
367 : 27959 : const AF2RuleExistVertex* vertexToMatch = NULL;
368 : : while (true)
369 : : {
370 [ + + ]: 40622 : if (consistentMatch)
371 : : {
372 : 31320 : ++vertexToMatchIndx;
373 [ + + ]: 31320 : if (vertexToMatchIndx == numExIsoVertices)
374 : : {
375 : : // all edges and all vertices have been matched
376 [ + - ]: 22018 : applyRuleStageThree(ngbhd, matchQuality, visitor, binding);
377 : : // now mark the match as inconsistent, so that the vertex binding
378 : : // for the final vertex is released and the search continues
379 : : // or (if there were no vertices to match) the search is terminated
380 : 22018 : consistentMatch = false;
381 : : }
382 : : else
383 : : {
384 : : // not all isolated vertices have been matched yet, so set up to
385 : : // attempt to match the next vertex given the current binding
386 : 9302 : vertexToMatch = exIsoVertices[vertexToMatchIndx];
387 : : vertexMatchItrStack.push(
388 [ + - ][ + - ]: 31320 : (*matchingVerticesMap)[vertexToMatch]->begin());
[ + - ]
389 : : }
390 : : }
391 : :
392 [ + + ]: 40622 : if (!consistentMatch)
393 : : {
394 [ + + ]: 31320 : if (vertexToMatchIndx == 0)
395 : : {
396 : : // all isolated vertices have explored all possible matches
397 : 27959 : break;
398 : : }
399 : 3361 : --vertexToMatchIndx;
400 : 3361 : vertexToMatch = exIsoVertices[vertexToMatchIndx];
401 : : // release the vertex binding from the last time vertexToMatch was bound
402 [ + - ]: 3361 : binding.release(vertexToMatch);
403 : : }
404 : :
405 : 12663 : consistentMatch = false;
406 : : std::list<const AF2Point2D*>::const_iterator itr =
407 [ + - ]: 12663 : vertexMatchItrStack.top();
408 [ + - ]: 12663 : vertexMatchItrStack.pop();
409 [ # # ][ + - ]: 16024 : for (; itr != (*matchingVerticesMap)[vertexToMatch]->end(); ++itr)
[ + - ][ + - ]
[ + + ]
410 : : {
411 : : // check consistency
412 : 3361 : consistentMatch = true;
413 [ + - ][ + - ]: 3361 : if (!binding.isConsistent(vertexToMatch, *itr))
[ - + ]
414 : : {
415 : 0 : consistentMatch = false;
416 : : }
417 : : else
418 : : {
419 : : // bind the vertex and store the next position of the iterator
420 : : // on the iterator stack for later examination
421 [ + - ][ + - ]: 3361 : binding.bind(vertexToMatch, *itr);
422 [ + - ][ + - ]: 3361 : vertexMatchItrStack.push(++itr);
423 : :
424 : : // break out of this loop and proceed to bind other vertices
425 : : // or check the free zone and finish applying the rule
426 : 3361 : break;
427 : : }
428 : : }
429 : 27959 : }
430 : 27959 : }
431 : :
432 : 22018 : void AF2Rule::applyRuleStageThree(AF2Neighborhood const & ngbhd,
433 : : unsigned int matchQuality, AF2RuleAppVisitor & visitor,
434 : : AF2Binding const & binding) const
435 : : {
436 : 22018 : bool emptyFreeZone = true;
437 : :
438 : 22018 : AF2FreeZone* freeZone = freeZoneDef->makeFreeZone(binding, matchQuality);
439 [ + + ]: 22018 : if (!freeZone->isConvex())
440 : : {
441 : 4 : emptyFreeZone = false;
442 : : }
443 : :
444 : 22018 : const std::list<const AF2Point2D*>* ngbhdPoints = ngbhd.getPoints2D();
445 [ + - ][ + + ]: 1574238 : for (std::list<const AF2Point2D*>::const_iterator itr = ngbhdPoints->begin();
446 [ + + ][ + - ]: 1046882 : emptyFreeZone && itr != ngbhdPoints->end(); ++itr)
[ + + ][ + + ]
[ # # ]
447 : : {
448 [ + - ][ + - ]: 505338 : emptyFreeZone = !freeZone->nearContains(**itr);
449 : : }
450 : :
451 : 22018 : const std::list<const AF2Edge2D*>* ngbhdEdges = ngbhd.getEdges2D();
452 [ + - ][ + + ]: 966408 : for (std::list<const AF2Edge2D*>::const_iterator itr = ngbhdEdges->begin();
453 [ + + ][ + - ]: 639422 : emptyFreeZone && itr != ngbhdEdges->end(); ++itr)
[ + + ][ + + ]
[ # # ]
454 : : {
455 : : emptyFreeZone = !freeZone->nearIntersects(
456 [ + - ][ + - ]: 304968 : *((*itr)->getStart()), *((*itr)->getEnd()));
[ + - ][ + - ]
[ + - ]
457 : : }
458 : :
459 [ + - ]: 22018 : delete freeZone;
460 : :
461 [ + + ]: 22018 : if (emptyFreeZone)
462 : : {
463 : : // This binding would be an acceptable way to apply the rule, so
464 : : // build an AF2RuleApplication and pass it to the visitor
465 [ + - ][ + - ]: 7468 : const AF2Point2D** newPointsArray = new const AF2Point2D*[numNewVertices];
466 [ + - ]: 7468 : std::list<const AF2Point2D*> newPointsList;
467 [ + + ]: 12201 : for (unsigned int nvi = 0; nvi < numNewVertices; ++nvi)
468 : : {
469 : 4733 : newPointsArray[nvi] =
470 [ + - ][ + - ]: 4733 : new AF2Point2D(newVertices[nvi]->getLocation(binding));
471 [ + - ]: 4733 : newPointsList.push_back(newPointsArray[nvi]);
472 : : }
473 : :
474 [ + - ]: 14936 : std::list<const AF2Polygon2D*> newPolygonsList;
475 [ + + ]: 18531 : for (unsigned int nfi = 0; nfi < numNewFaces; ++nfi)
476 : : {
477 [ + - ]: 11063 : std::list<const AF2Point2D*> polygonVertices;
478 [ + - ][ + + ]: 44252 : for (unsigned int fvi = 0; fvi < newFaces[nfi]->getNumVertices(); ++fvi)
479 : : {
480 [ + - ]: 33189 : unsigned int polyVertIndex = newFaces[nfi]->getVertexIndex(fvi);
481 [ + + ]: 33189 : if (polyVertIndex < numExVertices)
482 : : {
483 : : polygonVertices.push_back(binding.getBoundValue(
484 [ + - ][ + - ]: 24862 : exVertices[polyVertIndex]));
485 : : }
486 : : else
487 : : {
488 : : polygonVertices.push_back(
489 [ + - ]: 8327 : newPointsArray[polyVertIndex - numExVertices]);
490 : : }
491 : : }
492 [ + - ][ + - ]: 11063 : newPolygonsList.push_back(new AF2Polygon2D(polygonVertices));
[ + - ]
493 : 11063 : }
494 : :
495 : : AF2RuleApplication* ruleApplication =
496 [ + - ][ + - ]: 7468 : new AF2RuleApplication(newPointsList, newPolygonsList);
497 [ + - ]: 7468 : visitor.visit(*ruleApplication);
498 : :
499 : : // clean up memory allocated to define the rule application
500 [ + - ]: 7468 : delete ruleApplication;
501 [ + - ][ + - ]: 37062 : for (std::list<const AF2Polygon2D*>::const_iterator itr =
[ + + ]
502 [ + - ][ + - ]: 25999 : newPolygonsList.begin(); itr != newPolygonsList.end(); ++itr)
503 : : {
504 [ + - ][ + - ]: 11063 : delete *itr;
505 : : }
506 [ + + ]: 12201 : for (unsigned int nvi = 0; nvi < numNewVertices; ++nvi)
507 : : {
508 : 4733 : delete newPointsArray[nvi];
509 : : }
510 [ + - ]: 14936 : delete[] newPointsArray;
511 : : }
512 : 22018 : }
|