Salome HOME
Change comments style in geompy.py for right processing with HappyDoc
[modules/geom.git] / src / NMTAlgo / NMTAlgo_Builder.cxx
1 // File:        NMTAlgo_Inter3d.cxx
2 // Created:     Tue Jan 27 15:14:13 2004
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <NMTAlgo_Builder.ixx>
8
9 #include <TColStd_IndexedMapOfInteger.hxx>
10
11 #include <TopoDS_Face.hxx>
12 #include <TopoDS.hxx>
13 #include <TopoDS_Compound.hxx>
14 #include <TopoDS_Edge.hxx>
15 #include <TopoDS_Shape.hxx>
16
17 #include <TopExp.hxx>
18 #include <TopExp_Explorer.hxx>
19
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22
23 #include <TopTools_IndexedMapOfShape.hxx>
24 #include <TopTools_ListOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
26
27 #include <BOPTColStd_Dump.hxx>
28 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
29
30 #include <IntTools_Context.hxx>
31
32 #include <BOPTools_Tools3D.hxx>
33 #include <BOPTools_CArray1OfSSInterference.hxx>
34 #include <BOPTools_InterferencePool.hxx>
35 #include <BOPTools_SSInterference.hxx>
36 #include <BOPTools_SequenceOfCurves.hxx>
37 #include <BOPTools_Curve.hxx>
38 #include <BOPTools_SequenceOfCurves.hxx>
39 #include <BOPTools_SplitShapesPool.hxx>
40 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
41 #include <BOPTools_ListOfPaveBlock.hxx>
42 #include <BOPTools_PaveBlock.hxx>
43
44 #include <BOP_WireEdgeSet.hxx>
45 #include <BOP_FaceBuilder.hxx>
46 #include <BOP_BuilderTools.hxx>
47
48 #include <NMTDS_ShapesDataStructure.hxx>
49
50 #include <NMTTools_PaveFiller.hxx>
51 #include <NMTTools_ListOfCoupleOfShape.hxx>
52 #include <NMTTools_Tools.hxx>
53 #include <NMTTools_CoupleOfShape.hxx>
54 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
55 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
56
57 #include <TopoDS_Shell.hxx>
58 #include <NMTAlgo_Tools.hxx>
59 #include <TColStd_IndexedMapOfInteger.hxx>
60 #include <TopExp_Explorer.hxx>
61 #include <TopoDS_Iterator.hxx>
62
63 //=======================================================================
64 // function: NMTAlgo_Inter3d::NMTAlgo_Inter3d()
65 // purpose: 
66 //=======================================================================
67   NMTAlgo_Builder::NMTAlgo_Builder()
68 :
69   NMTAlgo_Algo()
70 {
71 }
72 //=======================================================================
73 // function: ~NMTAlgo_Builder
74 // purpose: 
75 //=======================================================================
76   NMTAlgo_Builder::~NMTAlgo_Builder()
77 {
78   Clear();
79 }
80 //=======================================================================
81 // function: Clear
82 // purpose: 
83 //=======================================================================
84   void NMTAlgo_Builder::Clear()
85 {
86   NMTAlgo_Algo::Clear();
87   //
88   myImagesEdges.Clear();
89   myImagesFaces.Clear();
90   myIn2DParts.Clear();
91   mySectionParts.Clear();
92   mySDFaces.Clear();
93 }
94 //=======================================================================
95 // function: ComputeWithFiller
96 // purpose: 
97 //=======================================================================
98   void NMTAlgo_Builder::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
99 {
100   myErrorStatus=0;
101   myIsDone=Standard_False;
102   //
103   SetFiller(aDSF);
104   // edges
105   FillImagesEdges();
106   // faces
107   FillIn2DParts();
108   FillImagesFaces();
109   FillSDFaces();
110 }
111
112 //=======================================================================
113 // function: FillSDFaces
114 // purpose: 
115 //=======================================================================
116   void NMTAlgo_Builder::FillSDFaces()
117 {
118   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
119   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
120   BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
121   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
122   IntTools_Context& aCtx= pPF->ChangeContext();
123   //
124   Standard_Boolean bIsSDF;
125   Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC;
126   TopTools_ListIteratorOfListOfShape aItF1, aItF2;
127   NMTTools_ListOfCoupleOfShape aLCS;   
128   //
129   mySDFaces.Clear();
130   //
131   // 1. For each FF find among images of faces
132   //    all pairs of same domain faces (SDF) [=> aLCS]
133   aNbFF=aFFs.Extent();
134   for (i=1; i<=aNbFF; ++i) {
135     BOPTools_SSInterference& aFF=aFFs(i);
136     aFF.Indices(nF1, nF2);
137     //
138     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
139     const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
140     //
141     // if there are no in/on 2D split parts the faces nF1, nF2
142     // can not be SDF
143     const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks();
144     aNbPBInOn=aLPBInOn.Extent();
145     if (!aNbPBInOn) {
146       continue;
147     }
148     //
149     // if there is at least one section edge between faces nF1, nF2
150     // they can not be SDF
151     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
152     aNbC=aSC.Length();
153     if (aNbC) {
154       continue;
155     }
156     //
157     // the faces are suspected to be SDF.
158     // Try to find SDF among images of nF1, nF2
159     const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
160     const TopTools_ListOfShape& aLF2=myImagesFaces.Image(aF2);
161     //
162     aItF1.Initialize(aLF1);
163     for (; aItF1.More(); aItF1.Next()) {
164       const TopoDS_Face& aF1x=TopoDS::Face(aItF1.Value());
165       //
166       aItF2.Initialize(aLF2);
167       for (; aItF2.More(); aItF2.Next()) {
168         const TopoDS_Face& aF2y=TopoDS::Face(aItF2.Value());
169         bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
170         if (bIsSDF) {
171           NMTTools_CoupleOfShape aCS;
172           //
173           aCS.SetShape1(aF1x);
174           aCS.SetShape2(aF2y);
175           aLCS.Append(aCS);
176         }
177       }
178     }
179   }//for (i=1; i<=aNbFF; ++i)
180   //
181   aNbC=aLCS.Extent();
182   if (!aNbC) {
183     return;
184   }
185   //
186   // 2. Find Chains
187   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;  
188   //
189   NMTTools_Tools::FindChains(aLCS, aMC); 
190   //
191   // 3. Fill the map of SDF mySDFaces
192   aNbC=aMC.Extent();
193   for (i=1; i<=aNbC; ++i) {
194     const TopoDS_Shape& aF=aMC.FindKey(i);
195     const TopTools_IndexedMapOfShape& aMSDF=aMC(i);
196     //
197     aNbFF=aMSDF.Extent();
198     for (j=1; j<=aNbFF; ++j) {
199       const TopoDS_Shape& aFSD=aMSDF(j);
200       mySDFaces.Add(aFSD, aF);
201     }
202   }
203   //
204 }
205 //=======================================================================
206 // function: FillImagesFaces
207 // purpose: 
208 //=======================================================================
209   void NMTAlgo_Builder::FillImagesFaces()
210 {
211   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
212   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
213   IntTools_Context& aCtx= pPF->ChangeContext();
214   //
215   Standard_Integer i, j, aNb, aNbE;
216   TopTools_IndexedMapOfShape aMFence, aME;
217   TColStd_IndexedMapOfInteger aMFP;
218   //
219   // 1. Select Faces to process (MFP)
220   aNb=aDS.NumberOfShapesOfTheObject();
221   for (i=1; i<=aNb; ++i) {
222     const TopoDS_Shape& aF=aDS.Shape(i);
223     if (aF.ShapeType()!=TopAbs_FACE) {
224       continue;
225     }
226     if (aMFence.Contains(aF)) {
227       continue;
228     }
229     aMFence.Add(aF);
230     //
231     if (myIn2DParts.Contains(aF)) {
232       aMFP.Add(i);
233       continue;
234     }
235     //
236     if (mySectionParts.Contains(aF)) {
237       aMFP.Add(i);
238       continue;
239     }
240     //
241     aME.Clear();
242     TopExp::MapShapes(aF, TopAbs_EDGE, aME);
243     //
244     aNbE=aME.Extent();
245     for(j=1; j<=aNbE; ++j) {
246       const TopoDS_Shape& aE=aME(j);
247       //
248       if (myImagesEdges.HasImage(aE)) {
249         aMFP.Add(i);
250         break;
251       }
252     }
253   }// for (i=1; i<=aNb; ++i)
254   //
255   // 2. ProcessFaces
256   Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
257   Standard_Integer aNbF, nF;
258   TopoDS_Face aFF;
259   TopoDS_Edge aSp;
260   TopExp_Explorer anExp;
261   TopTools_ListIteratorOfListOfShape aIt;
262   BRepAlgo_Image aImagesFaces;
263   TopAbs_Orientation anOriF;
264   //
265   aNbF=aMFP.Extent();
266   for (i=1; i<=aNbF; ++i) {
267     nF=aMFP(i);
268     const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
269     anOriF=aF.Orientation();
270     aFF=aF;
271     aFF.Orientation(TopAbs_FORWARD);
272     //
273     aMFence.Clear();
274     //
275     // 2.1. Fill WES 
276     BOP_WireEdgeSet aWES;
277     aWES.Initialize(aFF);
278     //
279     //  2.1.1. Add Split parts
280     anExp.Init(aFF, TopAbs_EDGE);
281     for (; anExp.More(); anExp.Next()) {
282       const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
283       //
284       if (!myImagesEdges.HasImage(aE)) {
285         aWES.AddStartElement(aE);
286         continue;
287       }
288       //
289       bIsDegenerated=BRep_Tool::Degenerated(aE);
290       bIsClosed=BRep_Tool::IsClosed(aE, aF);
291       //
292       const TopTools_ListOfShape& aLIE=myImagesEdges.Image(aE);
293       aIt.Initialize(aLIE);
294       for (; aIt.More(); aIt.Next()) {
295         aSp=TopoDS::Edge(aIt.Value());
296         //
297         if (bIsDegenerated) {
298           aSp.Orientation(aE.Orientation());
299           aWES.AddStartElement(aSp);
300           continue;
301         }
302         //
303         if (bIsClosed){
304           if (!aMFence.Contains(aSp)){
305             aMFence.Add(aSp);
306             //
307             if (!BRep_Tool::IsClosed(aSp, aF)){
308               BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
309             }
310             //
311             aSp.Orientation(TopAbs_FORWARD);
312             aWES.AddStartElement(aSp);
313             //
314             aSp.Orientation(TopAbs_REVERSED);
315             aWES.AddStartElement(aSp);
316             continue;
317           }
318         }
319         //
320         bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
321         if (bToReverse) {
322           aSp.Reverse();
323         }
324         aWES.AddStartElement(aSp);
325       }
326     }
327     //
328     // 2.1.2. Add In2D Parts
329     if (myIn2DParts.Contains(aF)) {
330       const TopTools_ListOfShape& aLE=myIn2DParts.FindFromKey(aF);
331       aIt.Initialize(aLE);
332       for (; aIt.More(); aIt.Next()) {
333         aSp=TopoDS::Edge(aIt.Value());
334         //
335         aSp.Orientation(TopAbs_FORWARD);
336         aWES.AddStartElement(aSp);
337         //
338         aSp.Orientation(TopAbs_REVERSED);
339         aWES.AddStartElement(aSp);
340         }
341     }
342     //
343     // 2.1.3. Add Section Parts
344     if (mySectionParts.Contains(aF)) {
345       const TopTools_ListOfShape& aLE=mySectionParts.FindFromKey(aF);
346       aIt.Initialize(aLE);
347       for (; aIt.More(); aIt.Next()) {
348         aSp=TopoDS::Edge(aIt.Value());
349         //
350         aSp.Orientation(TopAbs_FORWARD);
351         aWES.AddStartElement(aSp);
352         //
353         aSp.Orientation(TopAbs_REVERSED);
354         aWES.AddStartElement(aSp);
355       }
356     }
357     //
358     // 2.2. Build images Faces
359     BOP_FaceBuilder aFB;
360     //
361     aFB.SetTreatment(0);  // 0-Do Internal Edges
362     aFB.SetTreatSDScales(0); // what is 0 ??
363     //
364     aFB.Do(aWES);
365     //
366     TopTools_ListOfShape aLFR;
367     //
368     const TopTools_ListOfShape& aLF=aFB.NewFaces();
369
370     aIt.Initialize(aLF);
371     for (; aIt.More(); aIt.Next()) {
372       TopoDS_Shape& aFR=aIt.Value();
373       if (anOriF==TopAbs_REVERSED) {
374         aFR.Orientation(TopAbs_REVERSED);
375       }
376       aLFR.Append(aFR);
377     }
378     
379     //
380     // 2.3. Collect images Faces
381     myImagesFaces.Bind(aF, aLFR);
382   }//for (i=1; i<=aNbF; ++i)
383 }
384 //=======================================================================
385 // function: FillIn2DParts
386 // purpose: 
387 //=======================================================================
388   void NMTAlgo_Builder::FillIn2DParts()
389 {
390   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
391   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
392   BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
393   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
394   //
395   Standard_Integer i, j, aNb, nF1, nF2, aNbFF, iFF, nSpIn, nSpSc, aNbCurves;
396   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
397   BOPTools_ListOfPaveBlock aLPBIn, aLPBSc;
398   BOPTools_ListIteratorOfListOfPaveBlock aItPBIn, aItPBSc;
399   TopTools_IndexedMapOfShape aMF, aMFence;
400   TopTools_ListOfShape aLSpIn, aLSpSc;
401   //
402   BOP_BuilderTools::DoMap(aFFs, aFFMap);
403   //
404   // 1. Collect Splits In 2D   (myIn2DParts) and 
405   //            Section Edges  (mySectionParts) 
406   //    for each source face that involved in FF
407   aNb=aFFMap.Extent();
408   for (i=1; i<=aNb; ++i) {
409     nF1=aFFMap.FindKey(i);
410     const TopoDS_Shape& aF=aDS.Shape(nF1);
411     //
412     if (aMF.Contains(aF)) {
413       continue;
414     }
415     aMF.Add(aF);
416     //
417     aLPBIn.Clear();
418     aLPBSc.Clear();
419     //
420     const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
421     //
422     aNbFF=aFFIndicesMap.Extent();
423     for (j=1; j<=aNbFF; ++j) {
424       iFF=aFFIndicesMap(j);
425       BOPTools_SSInterference& aFF=aFFs(iFF);
426       nF2=aFF.OppositeIndex(nF1);
427       //
428       // In 2D
429       pPF->RealSplitsInFace(0, nF2, nF1, aLPBIn);
430       //
431       // Sections
432       BOPTools_SequenceOfCurves& aSC=aFF.Curves();
433       aNbCurves=aSC.Length();
434       if (!aNbCurves) {
435         continue;
436       }
437       //
438       const BOPTools_Curve& aBC=aSC(1);
439       const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
440       //
441       aItPBSc.Initialize(aLPB);
442       for (; aItPBSc.More(); aItPBSc.Next()) {
443         const BOPTools_PaveBlock& aPBSc=aItPBSc.Value();
444         aLPBSc.Append(aPBSc);
445       }
446     }// for (j=1; j<=aNbFF; ++j) 
447     //
448     // In 2D Parts 
449     aMFence.Clear();
450     //
451     aLSpIn.Clear();
452     aItPBIn.Initialize(aLPBIn);
453     for (; aItPBIn.More(); aItPBIn.Next()) {
454       const BOPTools_PaveBlock& aPBR=aItPBIn.Value();
455       nSpIn=aPBR.Edge();
456       const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
457       if (!aMFence.Contains(aSpIn)){
458         aMFence.Add(aSpIn);
459         aLSpIn.Append(aSpIn);
460       }
461     }
462     myIn2DParts.Add(aF, aLSpIn);
463     //
464     // Section Parts
465     aLSpSc.Clear();
466     aItPBSc.Initialize(aLPBSc);
467     for (; aItPBSc.More(); aItPBSc.Next()) {
468       const BOPTools_PaveBlock& aPBSc=aItPBSc.Value();
469       nSpSc=aPBSc.Edge();
470       const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
471       if (!aMFence.Contains(aSpSc)){
472         aMFence.Add(aSpSc);
473         aLSpSc.Append(aSpSc);
474       }
475     }
476     mySectionParts.Add(aF, aLSpSc);
477   } //for (i=1; i<=aNb; ++i)
478 }
479
480 //=======================================================================
481 // function: FillImagesEdges
482 // purpose: 
483 //=======================================================================
484   void NMTAlgo_Builder::FillImagesEdges()
485 {
486   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
487   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
488   const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
489   //
490   Standard_Integer nE, aNb, aNbSp, nSp;
491   BOPTools_ListIteratorOfListOfPaveBlock aIt;
492   TopTools_IndexedMapOfShape aMFence;
493   TopTools_ListOfShape aLSp;
494   //
495   aNb=aDS.NumberOfShapesOfTheObject();
496   for (nE=1; nE<=aNb; ++nE) {
497     const TopoDS_Shape& aE=aDS.Shape(nE);
498     if (aE.ShapeType()!=TopAbs_EDGE) {
499       continue;
500     }
501     if (aMFence.Contains(aE)) {
502       continue;
503     }
504     aMFence.Add(aE);
505     //
506     const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(nE));
507     aNbSp=aLPB.Extent();
508     //
509     if (!aNbSp) {// no splits  
510       //myImagesEdges.Bind(aE, aE);
511       continue;
512     }
513     //
514     aLSp.Clear();
515     aIt.Initialize(aLPB);
516     for (; aIt.More(); aIt.Next()) {
517       const BOPTools_PaveBlock& aPB=aIt.Value();
518       const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB);
519       nSp=aPBR.Edge();
520       const TopoDS_Shape& aSp=aDS.Shape(nSp);
521       aLSp.Append(aSp);
522     }
523     myImagesEdges.Bind(aE, aLSp); 
524   }
525 }
526 //=======================================================================
527 // function: SplitVertices
528 // purpose: 
529 //=======================================================================
530   void NMTAlgo_Builder::SplitVertices()
531 {
532   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
533   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
534   const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
535   //
536   Standard_Integer nE, aNb, aNbSp, nV1, nV2;
537   BOPTools_ListIteratorOfListOfPaveBlock aIt;
538   //
539   myQueryShapes.Clear();
540   //
541   aNb=aDS.NumberOfShapesOfTheObject();
542   for (nE=1; nE<=aNb; ++nE) {
543     const TopoDS_Shape& aE=aDS.Shape(nE);
544     if (aE.ShapeType()!=TopAbs_EDGE) {
545       continue;
546     }
547     //
548     const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(nE));
549     aNbSp=aLPB.Extent();
550     //
551     if (!aNbSp) {// no splits  
552       continue;
553     }
554     //
555     aIt.Initialize(aLPB);
556     for (; aIt.More(); aIt.Next()) {
557       const BOPTools_PaveBlock& aPB=aIt.Value();
558       const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB);
559       //
560       nV1=aPBR.Pave1().Index();
561       if (aDS.IsNewShape(nV1)) {
562         const TopoDS_Shape& aV1=aDS.Shape(nV1);
563         myQueryShapes.Add(aV1);
564       }
565       //
566       nV2=aPBR.Pave2().Index();
567       if (aDS.IsNewShape(nV2)) {
568         const TopoDS_Shape& aV2=aDS.Shape(nV2);
569         myQueryShapes.Add(aV2);
570       }
571     }
572   }
573 }
574 //=======================================================================
575 // function: IsSectionEdge
576 // purpose: 
577 //=======================================================================
578   Standard_Boolean NMTAlgo_Builder::IsSectionEdge(const TopoDS_Edge& aE)const
579 {
580   return myImagesEdges.HasImage(aE);
581 }
582 //=======================================================================
583 // function: IsSameDomainF
584 // purpose: 
585 //=======================================================================
586   Standard_Boolean NMTAlgo_Builder::HasSameDomainF(const TopoDS_Face& aF1)const
587 {
588   Standard_Boolean bFlag=Standard_False;
589   TopTools_ListIteratorOfListOfShape aItF1;
590   //
591   const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
592   aItF1.Initialize(aLF1);
593   for (; aItF1.More(); aItF1.Next()) {
594     const TopoDS_Shape& aF1x=aItF1.Value();
595     //
596     if (mySDFaces.Contains(aF1x)){
597       return !bFlag;
598     }
599   }
600   return bFlag;
601 }
602 //=======================================================================
603 // function: IsSameDomainF
604 // purpose: 
605 //=======================================================================
606   Standard_Boolean NMTAlgo_Builder::IsSameDomainF(const TopoDS_Face& aF1,
607                                                   const TopoDS_Face& aF2)const
608 {
609   Standard_Boolean bFlag=Standard_False;
610   TopTools_ListIteratorOfListOfShape aItF1, aItF2;
611   //
612   const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
613   const TopTools_ListOfShape& aLF2=myImagesFaces.Image(aF2);
614   //
615   aItF1.Initialize(aLF1);
616   for (; aItF1.More(); aItF1.Next()) {
617     const TopoDS_Shape& aF1x=aItF1.Value();
618     //
619     if (!mySDFaces.Contains(aF1x)){
620       continue;
621     }
622     const TopoDS_Shape& aFSD1x=mySDFaces.FindFromKey(aF1x);
623     //
624     aItF2.Initialize(aLF2);
625     for (; aItF2.More(); aItF2.Next()) {
626       const TopoDS_Shape& aF2y=aItF2.Value();
627       if (!mySDFaces.Contains(aF2y)){
628         continue;
629       }
630       const TopoDS_Shape& aFSD2y=mySDFaces.FindFromKey(aF2y);
631       if (aFSD1x.IsSame(aFSD2y)) {
632         return !bFlag;
633       }
634     }
635   }
636   return bFlag;
637 }