bad86325a3675e3fb371e2b58dfcf7b83135f2ac
[occt.git] / src / BOP / BOP_SectionHistoryCollector.cxx
1 #include <BOP_SectionHistoryCollector.ixx>
2
3 #include <TopExp.hxx>
4 #include <TopExp_Explorer.hxx>
5 #include <TopTools_IndexedMapOfShape.hxx>
6 #include <TopTools_ListIteratorOfListOfShape.hxx>
7 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
8 #include <BooleanOperations_ShapesDataStructure.hxx>
9 #include <BOPTools_DSFiller.hxx>
10 #include <BOPTools_InterferencePool.hxx>
11 #include <BOPTools_SSInterference.hxx>
12 #include <BOPTools_ListOfPaveBlock.hxx>
13 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
14 #include <BOPTools_ListIteratorOfListOfPave.hxx>
15 #include <BOPTools_PaveBlock.hxx>
16 #include <BOPTools_Curve.hxx>
17 #include <BOPTools_PavePool.hxx>
18 #include <BOPTools_PaveFiller.hxx>
19 #include <BOPTools_VVInterference.hxx>
20 #include <BOPTools_VEInterference.hxx>
21 #include <BOPTools_VSInterference.hxx>
22 #include <TopoDS.hxx>
23 #include <TopTools_MapOfShape.hxx>
24
25 static Standard_Boolean AddNewShape(const TopoDS_Shape&                 theKey,
26                                     const TopoDS_Shape&                 theItem,
27                                     TopTools_DataMapOfShapeListOfShape& theMap);
28
29 // ============================================================================================
30 // function: Constructor
31 // purpose: 
32 // ============================================================================================
33 BOP_SectionHistoryCollector::BOP_SectionHistoryCollector(const TopoDS_Shape& theShape1,
34                                                          const TopoDS_Shape& theShape2) :
35 BOP_HistoryCollector(theShape1,theShape2, BOP_SECTION)
36 {
37 }
38
39 // ============================================================================================
40 // function: SetResult
41 // purpose: 
42 // ============================================================================================
43 void BOP_SectionHistoryCollector::SetResult(const TopoDS_Shape&       theResult,
44                                             const BOPTools_PDSFiller& theDSFiller) 
45 {
46   myResult = theResult;
47
48   if(myResult.IsNull())
49     return;
50
51   TopAbs_ShapeEnum aResultType = TopAbs_EDGE;
52   Standard_Boolean bcontainsface1 = Standard_False;
53   Standard_Boolean bcontainsface2 = Standard_False;
54
55   Standard_Boolean bcontainsedge1 = Standard_False;
56   Standard_Boolean bcontainsedge2 = Standard_False;
57
58   TopExp_Explorer anExp(myS1, TopAbs_FACE);
59
60   if(anExp.More()) {
61     bcontainsface1 = Standard_True;
62     bcontainsedge1 = Standard_True;
63   }
64   else {
65     anExp.Init(myS1, TopAbs_EDGE);
66
67     if(anExp.More()) {
68       bcontainsedge1 = Standard_True;
69     }
70   }
71   anExp.Init(myS2, TopAbs_FACE);
72
73   if(anExp.More()) {
74     bcontainsface2 = Standard_True;
75     bcontainsedge2 = Standard_True;
76   }
77   else {
78     anExp.Init(myS2, TopAbs_EDGE);
79
80     if(anExp.More()) {
81       bcontainsedge2 = Standard_True;
82     }
83   }
84
85   if(bcontainsface1 && bcontainsface2)
86     aResultType = TopAbs_EDGE;
87   else if(bcontainsedge1 && bcontainsedge2)
88     aResultType = TopAbs_VERTEX;
89   else
90     return;
91
92   myHasDeleted = Standard_True;
93
94
95   TopTools_IndexedMapOfShape aMap;
96   TopExp::MapShapes(myResult, aResultType, aMap);
97
98   if(aResultType == TopAbs_EDGE) {
99     FillFaceSection(theDSFiller, aMap);
100
101     TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
102     TopTools_IndexedDataMapOfShapeListOfShape aVEMap;
103
104     TopExp::MapShapesAndAncestors(myResult, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
105     TopExp::MapShapesAndAncestors(myS1,       TopAbs_EDGE, TopAbs_FACE, aEFMap);
106     TopExp::MapShapesAndAncestors(myS2,       TopAbs_EDGE, TopAbs_FACE, aEFMap);
107
108     TopTools_IndexedMapOfShape aResultMap, aFreeBoundaryMap;
109     Standard_Integer i = 0;
110
111     for(i = 1; i <= aEFMap.Extent(); i++) {
112       if(aEFMap.FindFromIndex(i).Extent() < 2)
113         aFreeBoundaryMap.Add(aEFMap.FindKey(i));
114     }
115
116     for(i = 1; i <= aFreeBoundaryMap.Extent(); i++) {
117       const TopoDS_Shape& anEdge = aFreeBoundaryMap.FindKey(i);
118       FillEdgeSection(anEdge, theDSFiller, aMap, aVEMap, aEFMap);
119     }
120   }
121 }
122
123 // ============================================================================================
124 // function: FillFaceSection
125 // purpose: 
126 // ============================================================================================
127 void BOP_SectionHistoryCollector::FillFaceSection(const BOPTools_PDSFiller&         theDSFiller,
128                                                   const TopTools_IndexedMapOfShape& theResultMap) 
129 {
130   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
131   const BOPTools_InterferencePool& anInterfPool = theDSFiller->InterfPool();
132   BOPTools_InterferencePool* pInterfPool = (BOPTools_InterferencePool*) &anInterfPool;
133   BOPTools_CArray1OfSSInterference& aFFs = pInterfPool->SSInterferences();
134   //
135   TopTools_IndexedMapOfShape aMap;
136   Standard_Integer aNbFFs = aFFs.Extent();
137   Standard_Integer i = 0, j = 0;
138
139   for (i=1; i<=aNbFFs; ++i) {
140     BOPTools_SSInterference& aFFi = aFFs(i);
141     //
142     Standard_Integer nF1 = aFFi.Index1();
143     Standard_Integer nF2 = aFFi.Index2();
144     TopoDS_Shape aF1 = aDS.Shape(nF1);
145     TopoDS_Shape aF2 = aDS.Shape(nF2);
146     Standard_Integer nSect = 0;
147
148     // Old Section Edges
149     const BOPTools_ListOfPaveBlock& aSectList = aFFi.PaveBlocks();
150     BOPTools_ListIteratorOfListOfPaveBlock anIt(aSectList);
151
152     for (; anIt.More();anIt.Next()) {
153       const BOPTools_PaveBlock& aPB=anIt.Value();
154       nSect = aPB.Edge();
155       const TopoDS_Shape& aS = aDS.GetShape(nSect);
156
157       if(theResultMap.Contains(aS)) {
158         TopTools_ListOfShape thelist;
159         if(!myGenMap.IsBound(aF1))
160           myGenMap.Bind(aF1, thelist );
161
162         if(!myGenMap.IsBound(aF2))
163           myGenMap.Bind(aF2, thelist);
164
165         for(Standard_Integer fit = 0; fit < 2; fit++) {
166           if(fit == 0)
167             AddNewShape(aF1, aS, myGenMap);
168           else
169             AddNewShape(aF2, aS, myGenMap);
170         }
171       }
172     }
173
174     // New Section Edges
175     BOPTools_SequenceOfCurves& aBCurves = aFFi.Curves();
176     Standard_Integer aNbCurves = aBCurves.Length();
177
178     for (j = 1; j <= aNbCurves; j++) {
179       BOPTools_Curve& aBC = aBCurves(j);
180       const BOPTools_ListOfPaveBlock& aSectEdges = aBC.NewPaveBlocks();
181
182       BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
183
184       for (; aPBIt.More(); aPBIt.Next()) {
185         BOPTools_PaveBlock& aPB = aPBIt.Value();
186         nSect = aPB.Edge();
187         const TopoDS_Shape& aS = aDS.GetShape(nSect);
188
189         if(theResultMap.Contains(aS) && !aMap.Contains(aS)) {
190           TopTools_ListOfShape thelist1;
191
192           if(!myGenMap.IsBound(aF1)) {
193             myGenMap.Bind(aF1, thelist1);
194           }
195           myGenMap.ChangeFind(aF1).Append(aS);
196
197           if(!myGenMap.IsBound(aF2))
198             myGenMap.Bind(aF2, thelist1);
199           myGenMap.ChangeFind(aF2).Append(aS);
200           aMap.Add(aS);
201         }
202       }
203     }
204   }
205 }
206
207 //  Modified by skv - Wed Nov  5 15:52:48 2003 OCC3644 Begin
208 // ============================================================================================
209 // function: IsEdgeToAdd
210 // purpose: 
211 // ============================================================================================
212
213 static Standard_Boolean IsEdgeToAdd
214        (const TopoDS_Shape                              &theEdge,
215         const TopTools_IndexedMapOfShape                &theResultMap,
216         const TopTools_IndexedDataMapOfShapeListOfShape &theVEMapRes,
217         const BOPTools_PDSFiller                        &theDSFiller)
218 {
219   if (theEdge.ShapeType() != TopAbs_EDGE)
220     return Standard_True;
221
222   const BooleanOperations_ShapesDataStructure &aDS=theDSFiller->DS();
223   const BOPTools_PaveFiller      &aPvFiller=theDSFiller->PaveFiller();
224   const BOPTools_SplitShapesPool &aSplitShapesPool=aPvFiller.SplitShapesPool();
225   Standard_Integer                aNbE1 = aDS.ShapeIndex(theEdge, 1);
226   Standard_Integer                aNbE2 = aDS.ShapeIndex(theEdge, 2);
227   Standard_Integer                aNbE  = (aNbE1 == 0) ? aNbE2 : aNbE1;
228
229   if (aNbE == 0)
230     return Standard_False;
231
232   const BOPTools_ListOfPaveBlock         &aLPB=aSplitShapesPool(aDS.RefEdge(aNbE));
233   BOPTools_ListIteratorOfListOfPaveBlock  aPBIt(aLPB);
234
235   for (; aPBIt.More(); aPBIt.Next()) {
236     const BOPTools_PaveBlock& aPB      = aPBIt.Value();
237     Standard_Integer          aSplitNb = aPB.Edge();
238     const TopoDS_Shape&       aSplit   = aDS.Shape(aSplitNb);
239
240     if (theResultMap.Contains(aSplit)) {
241       TopoDS_Vertex aVf;
242       TopoDS_Vertex aVl;
243       TopoDS_Edge   anEdge = TopoDS::Edge(aSplit);
244
245       TopExp::Vertices(anEdge, aVf, aVl);
246
247       if (theVEMapRes.FindFromKey(aVf).Extent() < 2 ||
248           theVEMapRes.FindFromKey(aVl).Extent() < 2)
249         return Standard_False;
250     }
251   }
252
253   return Standard_True;
254 }
255 //  Modified by skv - Wed Nov  5 15:52:50 2003 OCC3644 End
256
257 // ============================================================================================
258 // function: FillEdgeSection
259 // purpose: 
260 // ============================================================================================
261 void BOP_SectionHistoryCollector::FillEdgeSection
262                   (const TopoDS_Shape                              &theEdge,
263                    const BOPTools_PDSFiller                        &theDSFiller,
264                    const TopTools_IndexedMapOfShape                &theResultMap,
265                    const TopTools_IndexedDataMapOfShapeListOfShape &theVEMapRes,
266                    const TopTools_IndexedDataMapOfShapeListOfShape &theEFMap)
267 {
268   if(myResult.IsNull())
269     return;
270
271   TopTools_IndexedDataMapOfShapeListOfShape aMapOfOldNewVertex;
272
273   BOPTools_InterferencePool* pIntrPool = (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
274   const BOPTools_PavePool& aPavePool = theDSFiller->PaveFiller().PavePool();
275   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
276
277   Standard_Integer anIndex = 0;
278   const BooleanOperations_IndexedDataMapOfShapeInteger& aMap1 = theDSFiller->DS().ShapeIndexMap(1);
279   const BooleanOperations_IndexedDataMapOfShapeInteger& aMap2 = theDSFiller->DS().ShapeIndexMap(2);
280
281   if(aMap1.Contains(theEdge))
282     anIndex = aMap1.FindFromKey(theEdge);
283   else if(aMap2.Contains(theEdge))
284     anIndex = aMap2.FindFromKey(theEdge);
285   else
286     return;
287
288   const BOPTools_PaveSet& aPaveSet = aPavePool.Value(aDS.RefEdge(anIndex));
289   const BOPTools_ListOfPave& aListOfPave = aPaveSet.Set();
290   BOPTools_ListIteratorOfListOfPave anIt(aListOfPave);
291
292   for(; anIt.More(); anIt.Next()) {
293     const BOPTools_Pave& aPave = anIt.Value();
294     const BooleanOperations_KindOfInterference aPaveType = aPave.Type();
295
296     if((aPaveType == BooleanOperations_EdgeSurface)) {
297       BOPTools_PShapeShapeInterference anInter = pIntrPool->GetInterference(aPave.Interference(), aPaveType);
298
299       if(anInter == NULL)
300         continue;
301
302       const TopoDS_Shape& aS1 = aDS.Shape(anInter->Index1());
303       const TopoDS_Shape& aS2 = aDS.Shape(anInter->Index2());
304       const TopoDS_Shape& aNewShape = aDS.Shape(anInter->NewShape());
305
306       if((aNewShape.ShapeType() != TopAbs_VERTEX) ||
307          (!theVEMapRes.Contains(aNewShape)))
308         continue;
309
310       if(theVEMapRes.FindFromKey(aNewShape).Extent() >= 2)
311         continue;
312
313       if(aS1.IsSame(aNewShape) || aS2.IsSame(aNewShape)) {
314         TopTools_ListOfShape thelist;
315         if(!aMapOfOldNewVertex.Contains(aNewShape))
316           aMapOfOldNewVertex.Add(aNewShape, thelist);
317         aMapOfOldNewVertex.ChangeFromKey(aNewShape).Append(aNewShape);
318         continue;
319       }
320       Standard_Boolean addfirst = Standard_True;
321       Standard_Boolean addsecond = Standard_True;
322
323       for(Standard_Integer sit = 0; sit < 2; sit++) {
324         if(((sit == 0) && !addfirst) || ((sit != 0) && !addsecond))
325           continue;
326         const TopoDS_Shape& aS = (sit == 0) ? aS1 : aS2;
327 //  Modified by skv - Wed Nov  5 17:11:41 2003 OCC3644 Begin
328 //      AddNewShape(aS, aNewShape, myGenMap);
329         if (IsEdgeToAdd(aS, theResultMap, theVEMapRes, theDSFiller))
330           AddNewShape(aS, aNewShape, myGenMap);
331 //  Modified by skv - Wed Nov  5 17:11:49 2003 OCC3644 End
332       }
333     } else if (aPaveType == BooleanOperations_EdgeEdge ||
334                aPaveType == BooleanOperations_VertexEdge) {
335       // Special treatment of case Edge-Edge and Edge-Vertex interference.
336       BOPTools_PShapeShapeInterference anInter = pIntrPool->GetInterference(aPave.Interference(), aPaveType);
337
338       if(anInter == NULL)
339         continue;
340
341       const TopoDS_Shape& aS1 = aDS.Shape(anInter->Index1());
342       const TopoDS_Shape& aS2 = aDS.Shape(anInter->Index2());
343       const TopoDS_Shape& aNewShape = aDS.Shape(anInter->NewShape());
344
345       if((aNewShape.ShapeType() != TopAbs_VERTEX) ||
346          (!theVEMapRes.Contains(aNewShape)))
347         continue;
348
349       if(theVEMapRes.FindFromKey(aNewShape).Extent() >= 2)
350         continue;
351
352       Standard_Boolean isAddObj  = IsEdgeToAdd(aS1, theResultMap, theVEMapRes, theDSFiller);
353       Standard_Boolean isAddTool = IsEdgeToAdd(aS2, theResultMap, theVEMapRes, theDSFiller);
354
355       if (!isAddObj) {
356         if (!theEFMap.Contains(aS1))
357           continue;
358
359         AddNewShape(aS2, aNewShape, myGenMap);
360
361         const TopTools_ListOfShape         &aFaces = theEFMap.FindFromKey(aS1);
362         TopTools_ListIteratorOfListOfShape  aFIter(aFaces);
363
364         for (; aFIter.More(); aFIter.Next()) {
365           const TopoDS_Shape &anAncFace = aFIter.Value();
366
367           AddNewShape(anAncFace, aNewShape, myGenMap);
368         }
369       } else if (!isAddTool) {
370         if (!theEFMap.Contains(aS2))
371           continue;
372
373         AddNewShape(aS1, aNewShape, myGenMap);
374
375         const TopTools_ListOfShape         &aFaces = theEFMap.FindFromKey(aS2);
376         TopTools_ListIteratorOfListOfShape  aFIter(aFaces);
377
378         for (; aFIter.More(); aFIter.Next()) {
379           const TopoDS_Shape &anAncFace = aFIter.Value();
380
381           AddNewShape(anAncFace, aNewShape, myGenMap);
382         }
383       } else {
384         if (!theEFMap.Contains(aS1) || !theEFMap.Contains(aS2))
385           continue;
386
387         AddNewShape(aS1, aNewShape, myGenMap);
388         AddNewShape(aS2, aNewShape, myGenMap);
389
390         const TopTools_ListOfShape         &aFaces1 = theEFMap.FindFromKey(aS1);
391         const TopTools_ListOfShape         &aFaces2 = theEFMap.FindFromKey(aS1);
392         TopTools_ListIteratorOfListOfShape  aFIter(aFaces1);
393
394         for (; aFIter.More(); aFIter.Next()) {
395           const TopoDS_Shape &anAncFace = aFIter.Value();
396
397           AddNewShape(anAncFace, aNewShape, myGenMap);
398         }
399
400         for (aFIter.Initialize(aFaces2); aFIter.More(); aFIter.Next()) {
401           const TopoDS_Shape &anAncFace = aFIter.Value();
402
403           AddNewShape(anAncFace, aNewShape, myGenMap);
404         }
405       }
406     }
407   }
408
409   Standard_Integer i = 0, j = 0;
410
411   for(j = 1; j <= aDS.NumberOfSuccessors(anIndex); j++) {
412     Standard_Integer avindex = aDS.GetSuccessor(anIndex, j);
413
414     BOPTools_CArray1OfVVInterference& VVs = pIntrPool->VVInterferences();
415     Standard_Integer aNb = VVs.Extent();
416     
417     for (i = 1; i <= aNb; i++) {
418       BOPTools_VVInterference& VV=VVs(i);
419       Standard_Integer anIndex1 = VV.Index1();
420       Standard_Integer anIndex2 = VV.Index2();
421
422       if((avindex == anIndex1) || (avindex == anIndex2)) {
423         Standard_Integer aNewShapeIndex = VV.NewShape();
424         TopoDS_Shape aNewShape = aDS.Shape(aNewShapeIndex);
425
426         if(!theVEMapRes.Contains(aNewShape))
427           continue;
428
429         if(theVEMapRes.FindFromKey(aNewShape).Extent() >= 2)
430           continue;
431
432         for(Standard_Integer vit = 0; vit < 2; vit++) {
433           TopoDS_Shape aShape = (vit == 0) ? aDS.Shape(anIndex1) : aDS.Shape(anIndex2);
434           TopTools_ListOfShape thelist1;
435           if(!aMapOfOldNewVertex.Contains(aShape))
436             aMapOfOldNewVertex.Add(aShape, thelist1);
437           aMapOfOldNewVertex.ChangeFromKey(aShape).Append(aNewShape);
438         }
439         break;
440       }
441     }
442
443     for(Standard_Integer aninterit = 0; aninterit < 2; aninterit++) {
444
445       if(aninterit == 0)
446         aNb = pIntrPool->VEInterferences().Extent();
447       else
448         aNb = pIntrPool->VSInterferences().Extent();
449     
450       for (i = 1; i <= aNb; i++) {
451         BOPTools_ShapeShapeInterference* anInterference = NULL;
452         
453         if(aninterit == 0)
454           anInterference = (BOPTools_ShapeShapeInterference*)(&pIntrPool->VEInterferences().Value(i));
455         else
456           anInterference = (BOPTools_ShapeShapeInterference*)(&pIntrPool->VSInterferences().Value(i));
457         Standard_Integer anIndex1 = anInterference->Index1();
458         Standard_Integer anIndex2 = anInterference->Index2();
459
460         if((avindex == anIndex1) || (avindex == anIndex2)) {
461           Standard_Integer aNewShapeIndex = anInterference->NewShape();
462           TopoDS_Shape aNewShape = aDS.Shape(aNewShapeIndex);
463
464           if(!theVEMapRes.Contains(aNewShape))
465             continue;
466
467           if(theVEMapRes.FindFromKey(aNewShape).Extent() >= 2)
468             continue;
469           TopoDS_Shape aShape1 = aDS.Shape(avindex);
470           TopoDS_Shape aShape2 = (avindex == anIndex1) ? aDS.Shape(anIndex2) : aDS.Shape(anIndex1);
471
472           if(aninterit == 0) {
473             TopTools_ListOfShape thelist2;
474             if(!aMapOfOldNewVertex.Contains(aShape1))
475               aMapOfOldNewVertex.Add(aShape1, thelist2);
476             aMapOfOldNewVertex.ChangeFromKey(aShape1).Append(aNewShape);
477           } else {
478             Standard_Integer aRank     = 1;
479             Standard_Integer aVtxIndex = aDS.ShapeIndex(aShape1, aRank);
480
481             if (aVtxIndex == 0) {
482               aRank     = 2;
483               aVtxIndex = aDS.ShapeIndex(aShape1, aRank);
484             }
485
486             if (aVtxIndex != 0) {
487               Standard_Integer    aNbEdges = aDS.NumberOfAncestors(aVtxIndex);
488               Standard_Integer    anEdgeInd;
489               TopTools_MapOfShape anAddedFaces;
490
491               for (anEdgeInd = 1; anEdgeInd <= aNbEdges; anEdgeInd++) {
492                 Standard_Integer    anEdgeId = aDS.GetAncestor(aVtxIndex, anEdgeInd);
493                 const TopoDS_Shape &anEdge   = aDS.GetShape(anEdgeId);
494
495                 if (IsEdgeToAdd(anEdge, theResultMap, theVEMapRes, theDSFiller))
496                   AddNewShape(anEdge, aNewShape, myGenMap);
497               }
498             }
499           }
500
501 //  Modified by skv - Wed Nov  5 17:11:41 2003 OCC3644 Begin
502 //        AddNewShape(aShape2, aNewShape, myGenMap);
503           if (IsEdgeToAdd(aShape2, theResultMap, theVEMapRes, theDSFiller))
504             AddNewShape(aShape2, aNewShape, myGenMap);
505 //  Modified by skv - Wed Nov  5 17:11:49 2003 OCC3644 End
506         }
507       }
508     }
509   }
510
511   if(!aMapOfOldNewVertex.IsEmpty()) {
512     Standard_Integer vit = 0;
513     
514     for(vit = 1; vit <= aMapOfOldNewVertex.Extent(); vit++) {
515       const TopoDS_Shape& aV        = aMapOfOldNewVertex.FindKey(vit);
516       Standard_Integer    aRank     = 1;
517       Standard_Integer    aVtxIndex = aDS.ShapeIndex(aV, aRank);
518
519       if (aVtxIndex == 0) {
520         aRank     = 2;
521         aVtxIndex = aDS.ShapeIndex(aV, aRank);
522       }
523
524       if (aVtxIndex == 0)
525         continue;
526
527       Standard_Integer    aNbEdges = aDS.NumberOfAncestors(aVtxIndex);
528       Standard_Integer    anEdgeInd;
529       TopTools_MapOfShape anAddedFaces;
530       const TopTools_ListOfShape& aNewVList = aMapOfOldNewVertex.FindFromIndex(vit);
531
532       if(aNewVList.IsEmpty())
533         continue;
534
535       TopoDS_Shape aNewShape = aNewVList.First();
536
537       for (anEdgeInd = 1; anEdgeInd <= aNbEdges; anEdgeInd++) {
538         Standard_Integer            anEdgeId = aDS.GetAncestor(aVtxIndex, anEdgeInd);
539         const TopoDS_Shape         &anEdge   = aDS.GetShape(anEdgeId);
540         const TopTools_ListOfShape &aFaces   = theEFMap.FindFromKey(anEdge);
541
542         TopTools_ListIteratorOfListOfShape aFaceIter(aFaces);
543
544         for (; aFaceIter.More(); aFaceIter.Next()) {
545           const TopoDS_Shape &aFace = aFaceIter.Value();
546
547           if (!anAddedFaces.Add(aFace))
548             continue;
549
550           AddNewShape(aFace, aNewShape, myGenMap);
551         }
552       }
553     }
554   }
555 }
556
557 // --------------------------------------------------------------------------------
558 // static function: AddNewShape
559 // purpose:
560 // --------------------------------------------------------------------------------
561 Standard_Boolean AddNewShape(const TopoDS_Shape&                 theKey,
562                              const TopoDS_Shape&                 theItem,
563                              TopTools_DataMapOfShapeListOfShape& theMap) {
564
565
566   if(!theMap.IsBound(theKey)) {
567     TopTools_ListOfShape aList;
568     aList.Append(theItem);
569     theMap.Bind(theKey, aList);
570     return Standard_True;
571   }
572
573   Standard_Boolean found = Standard_False;
574   TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
575   TopTools_ListIteratorOfListOfShape aVIt(aList);
576
577   for(; aVIt.More(); aVIt.Next()) {
578     if(theItem.IsSame(aVIt.Value())) {
579       found = Standard_True;
580       break;
581     }
582   }
583
584   if(!found) {
585     aList.Append(theItem);
586   }
587   return !found;
588 }