Salome HOME
0020014: EDF 833 GEOM : Regression from 3.2.9 with GetInPlace
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Builder_2.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:        GEOMAlgo_Builder_2.cxx
23 // Author:      Peter KURNEV
24
25 #include <GEOMAlgo_Builder.hxx>
26
27 #include <TColStd_IndexedMapOfInteger.hxx>
28 #include <TColStd_ListOfInteger.hxx>
29
30 #include <TopAbs_Orientation.hxx>
31
32 #include <TopoDS.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Compound.hxx>
37
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <TopTools_ListOfShape.hxx>
40 #include <TopTools_MapOfShape.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42
43 #include <TopExp.hxx>
44 #include <TopExp_Explorer.hxx>
45
46 #include <BRep_Tool.hxx>
47 #include <BRep_Builder.hxx>
48 #include <BRepAlgo_Image.hxx>
49 #include <BRepTools.hxx>
50
51 #include <IntTools_Context.hxx>
52 #include <IntTools_FClass2d.hxx>
53
54 #include <BooleanOperations_OnceExplorer.hxx>
55 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
56 #include <BOPTools_ListOfPaveBlock.hxx>
57 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
58 #include <BOPTools_CArray1OfSSInterference.hxx>
59 #include <BOPTools_SSInterference.hxx>
60 #include <BOPTools_SequenceOfCurves.hxx>
61 #include <BOPTools_Curve.hxx>
62 #include <BOPTools_ListOfPaveBlock.hxx>
63 #include <BOPTools_PaveBlock.hxx>
64 #include <BOPTools_Tools3D.hxx>
65 #include <BOPTools_CArray1OfVSInterference.hxx>
66 #include <BOPTools_VSInterference.hxx>
67 #include <BOPTools_ESInterference.hxx>
68 #include <BOPTools_CArray1OfESInterference.hxx>
69
70 #include <NMTDS_ShapesDataStructure.hxx>
71 #include <NMTDS_InterfPool.hxx>
72
73 #include <NMTTools_PaveFiller.hxx>
74 #include <NMTTools_ListOfCoupleOfShape.hxx>
75 #include <NMTTools_Tools.hxx>
76 #include <NMTTools_CoupleOfShape.hxx>
77 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
78 #include <NMTTools_Tools.hxx>
79 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
80 #include <NMTTools_ListOfCommonBlock.hxx>
81 #include <NMTTools_CommonBlock.hxx>
82 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
83 //
84 #include <GEOMAlgo_Tools3D.hxx>
85 #include <GEOMAlgo_WireEdgeSet.hxx>
86 #include <GEOMAlgo_BuilderFace.hxx>
87
88 #include <GEOMAlgo_ShapeSet.hxx>
89 //
90 #include <NMTDS_BoxBndTree.hxx>
91 #include <NCollection_UBTreeFiller.hxx>
92 #include <Bnd_Box.hxx>
93 #include <BRepBndLib.hxx>
94 #include <TopTools_DataMapOfIntegerShape.hxx>
95 #include <TColStd_ListOfInteger.hxx>
96 #include <TColStd_ListIteratorOfListOfInteger.hxx>
97 #include <TopTools_DataMapOfShapeInteger.hxx>
98
99 static
100   void UpdateCandidates(const Standard_Integer ,
101                         const Standard_Integer ,
102                         NMTTools_IndexedDataMapOfIndexedMapOfInteger& );
103
104 //modified by NIZNHY-PKV Thu Feb 16 12:24:52 2012f
105 static
106   Standard_Boolean IsClosed(const TopoDS_Edge& ,
107                             const TopoDS_Face& );
108 //modified by NIZNHY-PKV Thu Feb 16 12:24:56 2012t
109
110 //=======================================================================
111 //function : FillImagesFaces
112 //purpose  :
113 //=======================================================================
114 void GEOMAlgo_Builder::FillImagesFaces()
115 {
116   myErrorStatus=0;
117   //
118   FillIn2DParts();
119   BuildSplitFaces();
120   FillSameDomainFaces();
121   FillImagesFaces1();
122   FillInternalVertices();
123 }
124
125 //=======================================================================
126 // function: FillIn2DParts
127 // purpose:
128 //=======================================================================
129 void GEOMAlgo_Builder::FillIn2DParts()
130 {
131   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
132   NMTTools_PaveFiller* pPF=myPaveFiller;
133   NMTDS_InterfPool* pIP=pPF->IP();
134   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
135   NMTTools_CommonBlockPool& aCBP=pPF->ChangeCommonBlockPool();
136   //
137   Standard_Integer  j, nSpIn, nSpSc, aNbCurves;
138   Standard_Integer aNbS, nF, aNbCBP, n1, n2, aNbFFs, aNbSpIn;
139   TopTools_MapOfShape  aMFence;
140   TopTools_ListOfShape aLSpIn;
141   TopoDS_Face aF;
142   NMTTools_ListIteratorOfListOfCommonBlock aItCB;
143   BOPTools_ListIteratorOfListOfPaveBlock aItPB;
144   //
145   myInParts.Clear();
146   //
147   aNbFFs=aFFs.Extent();
148   aNbCBP=aCBP.Extent();
149   //
150   aNbS=aDS.NumberOfShapesOfTheObject();
151   for (nF=1; nF<=aNbS; ++nF) {
152     if (aDS.GetShapeType(nF)!=TopAbs_FACE) {
153       continue;
154     }
155     //
156     aF=TopoDS::Face(aDS.Shape(nF));
157     //
158     aMFence.Clear();
159     aLSpIn.Clear();
160     //
161     // 1. In Parts
162     BOPTools_ListOfPaveBlock aLPBIn;
163     //
164     pPF->RealSplitsInFace(nF, aLPBIn);
165     //
166     aItPB.Initialize(aLPBIn);
167     for (; aItPB.More(); aItPB.Next()) {
168       const BOPTools_PaveBlock& aPB1=aItPB.Value();
169       nSpIn=aPB1.Edge();
170       const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
171       aLSpIn.Append(aSpIn);
172     }
173     //
174     // 2. Section Parts
175     for (j=1; j<=aNbFFs; ++j) {
176       BOPTools_SSInterference& aFF=aFFs(j);
177       aFF.Indices(n1, n2);
178       if (!(n1==nF || n2==nF)) {
179         continue;
180       }
181       BOPTools_SequenceOfCurves& aSC=aFF.Curves();
182       aNbCurves=aSC.Length();
183       if (!aNbCurves) {
184         continue;
185       }
186       //
187       const BOPTools_Curve& aBC=aSC(1);
188       const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
189       aItPB.Initialize(aLPB);
190       for (; aItPB.More(); aItPB.Next()) {
191         const BOPTools_PaveBlock& aPBSc=aItPB.Value();
192         nSpSc=aPBSc.Edge();
193         const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
194         if (aMFence.Add(aSpSc)){
195           aLSpIn.Append(aSpSc);
196         }
197       }
198     }
199     aNbSpIn=aLSpIn.Extent();
200     if (aNbSpIn) {
201       myInParts.Add(aF, aLSpIn);
202     }
203   }//for (nF=1; nF<=aNbS; ++nF) {
204 }
205
206 //=======================================================================
207 // function: BuildSplitFaces
208 // purpose:
209 //=======================================================================
210 void GEOMAlgo_Builder::BuildSplitFaces()
211 {
212   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
213   NMTTools_PaveFiller* pPF=myPaveFiller;
214   NMTDS_InterfPool* pIP=pPF->IP();
215   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
216   const Handle(IntTools_Context)& aCtx= pPF->Context();
217   //
218   Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
219   Standard_Integer i, aNb, aNbF, nF;
220   TopTools_MapOfShape aMFence;
221   TColStd_IndexedMapOfInteger aMFP;
222   TopExp_Explorer anExp;
223   TopoDS_Face aFF;
224   TopoDS_Edge aSp, aEE;
225   TopTools_ListIteratorOfListOfShape aIt;
226   TopAbs_Orientation anOriF, anOriE;
227   //
228   mySplitFaces.Clear();
229   //
230   // 1. Select Faces to process (MFP)
231   aNb=aDS.NumberOfShapesOfTheObject();
232   for (i=1; i<=aNb; ++i) {
233     const TopoDS_Shape& aF=aDS.Shape(i);
234     if (aF.ShapeType()!=TopAbs_FACE) {
235       continue;
236     }
237     if (!aMFence.Add(aF)) {
238       continue;
239     }
240     //
241     if (myInParts.Contains(aF)) {
242       aMFP.Add(i);
243       continue;
244     }
245     //
246     anExp.Init(aF, TopAbs_EDGE);
247     for (; anExp.More(); anExp.Next()) {
248       const TopoDS_Shape& aE=anExp.Current();
249       if (myImages.HasImage(aE)) {
250         aMFP.Add(i);
251         break;
252       }
253     }
254     //
255     //===
256     {
257       Standard_Integer aNbFFs, aNbSE, j, n1, n2;
258       //
259       aNbFFs=aFFs.Extent();
260       for (j=1; j<=aNbFFs; ++j) {
261         BOPTools_SSInterference& aFFj=aFFs(j);
262         aFFj.Indices(n1, n2);
263         if (!(n1==i || n2==i)) {
264           continue;
265         }
266         //
267         const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
268         aNbSE=aLSE.Extent();
269         if (aNbSE) {
270           aMFP.Add(i);
271           break;
272         }
273       }
274     }
275     //===
276     //
277   }// for (i=1; i<=aNb; ++i)
278   //
279   // 2. ProcessFaces
280   aNbF=aMFP.Extent();
281   for (i=1; i<=aNbF; ++i) {
282     nF=aMFP(i);
283     const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
284     anOriF=aF.Orientation();
285     aFF=aF;
286     aFF.Orientation(TopAbs_FORWARD);
287     //
288     aMFence.Clear();
289     //
290     // 2.1. Fill WES
291     GEOMAlgo_WireEdgeSet aWES;
292     aWES.SetFace(aFF);
293     //
294     //  2.1.1. Add Split parts
295     anExp.Init(aFF, TopAbs_EDGE);
296     for (; anExp.More(); anExp.Next()) {
297       const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
298       anOriE=aE.Orientation();
299       //
300       if (!myImages.HasImage(aE)) {
301         if (anOriE==TopAbs_INTERNAL) {
302           aEE=aE;
303           aEE.Orientation(TopAbs_FORWARD);
304           aWES.AddStartElement(aEE);
305           aEE.Orientation(TopAbs_REVERSED);
306           aWES.AddStartElement(aEE);
307         }
308         else {
309           aWES.AddStartElement(aE);
310         }
311         continue;
312       }
313       //
314       bIsDegenerated=BRep_Tool::Degenerated(aE);
315       //modified by NIZNHY-PKV Wed Mar 07 07:46:09 2012f
316       bIsClosed=IsClosed(aE, aF);
317       //bIsClosed=BRep_Tool::IsClosed(aE, aF);
318       //modified by NIZNHY-PKV Wed Mar 07 07:46:13 2012t
319       //
320       const TopTools_ListOfShape& aLIE=myImages.Image(aE);
321       aIt.Initialize(aLIE);
322       for (; aIt.More(); aIt.Next()) {
323         aSp=TopoDS::Edge(aIt.Value());
324         //
325         if (bIsDegenerated) {
326           aSp.Orientation(anOriE);
327           aWES.AddStartElement(aSp);
328           continue;
329         }
330         //
331         if (anOriE==TopAbs_INTERNAL) {
332           aSp.Orientation(TopAbs_FORWARD);
333           aWES.AddStartElement(aSp);
334           aSp.Orientation(TopAbs_REVERSED);
335           aWES.AddStartElement(aSp);
336           continue;
337         }
338         //
339         if (bIsClosed){
340           if (aMFence.Add(aSp)) {
341             //
342             if (!BRep_Tool::IsClosed(aSp, aF)){
343               BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
344             }
345             //
346             aSp.Orientation(TopAbs_FORWARD);
347             aWES.AddStartElement(aSp);
348             aSp.Orientation(TopAbs_REVERSED);
349             aWES.AddStartElement(aSp);
350           }
351           continue;
352         }// if (aMFence.Add(aSp))
353         //
354         aSp.Orientation(anOriE);
355         bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
356         if (bToReverse) {
357           aSp.Reverse();
358         }
359         aWES.AddStartElement(aSp);
360       }// for (; aIt.More(); aIt.Next()) {
361     }// for (; anExp.More(); anExp.Next()) {
362     //
363     // 2.1.2. Add In2D Parts
364     if (myInParts.Contains(aF)) {
365       const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF);
366       aIt.Initialize(aLE);
367       for (; aIt.More(); aIt.Next()) {
368         aSp=TopoDS::Edge(aIt.Value());
369         //
370         aSp.Orientation(TopAbs_FORWARD);
371         aWES.AddStartElement(aSp);
372         //
373         aSp.Orientation(TopAbs_REVERSED);
374         aWES.AddStartElement(aSp);
375       }
376     }
377     //
378     // 2.2. Build images Faces
379     TopTools_ListOfShape aLFR;
380     GEOMAlgo_ShapeSet aS1, aS2;
381     //
382     const TopTools_ListOfShape& aSE=aWES.StartElements();
383     aS1.Add(aSE);
384     aS2.Add(aFF, TopAbs_EDGE);
385     if (aS1.IsEqual(aS2)) {
386       aLFR.Append(aF);
387     }
388     else {
389       GEOMAlgo_BuilderFace aBF;
390       //
391       aBF.SetFace(aFF);
392       aBF.SetContext(aCtx);
393       aBF.SetShapes(aSE);
394       // <-DEB
395       aBF.Perform();
396       //
397       const TopTools_ListOfShape& aLF=aBF.Areas();
398       aIt.Initialize(aLF);
399       for (; aIt.More(); aIt.Next()) {
400         TopoDS_Shape& aFR=aIt.Value();
401         if (anOriF==TopAbs_REVERSED) {
402           aFR.Orientation(TopAbs_REVERSED);
403         }
404         aLFR.Append(aFR);
405       }
406     }
407     //
408     // 2.3. Collect draft images Faces
409     mySplitFaces.Bind(aF, aLFR);
410   }//for (i=1; i<=aNbF; ++i)
411 }
412
413 //=======================================================================
414 // function: FillSameDomainFaces
415 // purpose:
416 //=======================================================================
417 void GEOMAlgo_Builder::FillSameDomainFaces()
418 {
419   Standard_Boolean bIsSDF, bHasImage1, bHasImage2, bForward;
420   Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC, aNbSE;
421   Standard_Integer aNbF1, aNbF2, i2s, aNbSD;
422   TopTools_MapOfShape aMFence;
423   TopTools_ListOfShape aLX1, aLX2;
424   TopTools_ListIteratorOfListOfShape aItF1, aItF2;
425   NMTTools_ListOfCoupleOfShape aLCS;
426   //
427   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
428   NMTTools_PaveFiller* pPF=myPaveFiller;
429   NMTDS_InterfPool* pIP=pPF->IP();
430   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
431   const Handle(IntTools_Context)& aCtx= pPF->Context();
432   //
433   //
434   //mySameDomainShapes.Clear();
435   //
436   // 1. For each FF find among images of faces
437   //    all pairs of same domain faces (SDF) [=> aLCS]
438   aNbFF=aFFs.Extent();
439   for (i=1; i<=aNbFF; ++i) {
440     BOPTools_SSInterference& aFF=aFFs(i);
441     aFF.Indices(nF1, nF2);
442     //
443     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
444     const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
445     //
446     // if there are no in/on 2D split parts the faces nF1, nF2
447     // can not be SDF
448     const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks();
449     aNbPBInOn=aLPBInOn.Extent();
450     //
451     //===
452     const TColStd_ListOfInteger& aLSE=aFF.SharedEdges();
453     aNbSE=aLSE.Extent();
454     if (!aNbPBInOn && !aNbSE) {
455       continue;
456     }
457     //===
458     //
459     // if there is at least one section edge between faces nF1, nF2
460     // they can not be SDF
461     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
462     aNbC=aSC.Length();
463     if (aNbC) {
464       continue;
465     }
466     //
467     // the faces are suspected to be SDF.
468     // Try to find SDF among images of nF1, nF2
469     aMFence.Clear();
470     //
471     //--------------------------------------------------------
472     bHasImage1=mySplitFaces.HasImage(aF1);
473     bHasImage2=mySplitFaces.HasImage(aF2);
474     //
475     aLX1.Clear();
476     if (!bHasImage1) {
477       aLX1.Append(aF1);
478     }
479     //
480     aLX2.Clear();
481     if (!bHasImage2) {
482       aLX2.Append(aF2);
483     }
484     //
485     const TopTools_ListOfShape& aLF1r=(bHasImage1)? mySplitFaces.Image(aF1) : aLX1;
486     const TopTools_ListOfShape& aLF2r=(bHasImage2)? mySplitFaces.Image(aF2) : aLX2;
487     //
488     TopTools_DataMapOfIntegerShape aMIS;
489     TColStd_ListIteratorOfListOfInteger aItLI;
490     NMTDS_BoxBndTreeSelector aSelector;
491     NMTDS_BoxBndTree aBBTree;
492     NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
493     //
494     aNbF1=aLF1r.Extent();
495     aNbF2=aLF2r.Extent();
496     bForward=(aNbF1<aNbF2);
497     //
498     const TopTools_ListOfShape& aLF1=bForward ? aLF1r : aLF2r;
499     const TopTools_ListOfShape& aLF2=bForward ? aLF2r : aLF1r;
500     //
501     // 1. aTreeFiller
502     aItF2.Initialize(aLF2);
503     for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) {
504       Bnd_Box aBoxF2s;
505       //
506       const TopoDS_Face& aF2s=*((TopoDS_Face*)(&aItF2.Value()));
507       //
508       BRepBndLib::Add(aF2s, aBoxF2s);
509       //
510       aMIS.Bind(i2s, aF2s);
511       //
512       aTreeFiller.Add(i2s, aBoxF2s);
513     }//for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) {
514     //
515     aTreeFiller.Fill();
516     //
517     // 2.
518     aItF1.Initialize(aLF1);
519     for (j=1; aItF1.More(); aItF1.Next(), ++j) {
520       Bnd_Box aBoxF1x;
521       //
522       const TopoDS_Face& aF1x=*((TopoDS_Face*)(&aItF1.Value()));
523       //
524       BRepBndLib::Add(aF1x, aBoxF1x);
525       //
526       aSelector.Clear();
527       aSelector.SetBox(aBoxF1x);
528       aNbSD=aBBTree.Select(aSelector);
529       if (!aNbSD) {
530         continue;
531       }
532       //
533       const TColStd_ListOfInteger& aLI=aSelector.Indices();
534       aItLI.Initialize(aLI);
535       for (; aItLI.More(); aItLI.Next()) {
536         i2s=aItLI.Value();
537         const TopoDS_Face& aF2y=*((TopoDS_Face*)(&aMIS.Find(i2s)));
538         //
539         bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
540         if (bIsSDF) {
541           if (aMFence.Contains(aF1x) || aMFence.Contains(aF2y)) {
542             continue;
543           }
544           aMFence.Add(aF1x);
545           aMFence.Add(aF2y);
546           //
547           NMTTools_CoupleOfShape aCS;
548           //
549           aCS.SetShape1(aF1x);
550           aCS.SetShape2(aF2y);
551           aLCS.Append(aCS);
552           //
553           if (bForward) {
554             if (aF1x==aF1) {
555               if (!mySplitFaces.HasImage(aF1)) {
556                 mySplitFaces.Bind(aF1, aF1);
557               }
558             }
559             if (aF2y==aF2) {
560               if (!mySplitFaces.HasImage(aF2)) {
561                 mySplitFaces.Bind(aF2, aF2);
562               }
563             }
564           }
565           else {
566             if (aF1x==aF2) {
567               if (!mySplitFaces.HasImage(aF2)) {
568                 mySplitFaces.Bind(aF2, aF2);
569               }
570             }
571             if (aF2y==aF1) {
572               if (!mySplitFaces.HasImage(aF1)) {
573                 mySplitFaces.Bind(aF1, aF1);
574               }
575             }
576           }
577           //
578           break;
579         }//if (bIsSDF) {
580       }//for (; aItLI.More(); aItLI.Next()) {
581     }//for (; aItF1.More(); aItF1.Next()) {
582   }//for (i=1; i<=aNbFF; ++i)
583   //-------------------------------------------------------------
584   aNbC=aLCS.Extent();
585   if (!aNbC) {
586     return;
587   }
588   //
589   // 2. Find Chains
590   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;
591   //
592   NMTTools_Tools::FindChains(aLCS, aMC);
593   //
594   Standard_Boolean bIsImage;
595   Standard_Integer aIx, aIxMin, aNbMSDF, k, aNbMFj;
596   TopoDS_Shape aFOld, aFSDmin;
597   TopTools_IndexedMapOfShape aMFj;
598   TopTools_DataMapOfShapeInteger aDMSI;
599   //
600   aItF1.Initialize(myShapes);
601   for (j=1; aItF1.More(); aItF1.Next(), ++j) {
602     const TopoDS_Shape& aSj=aItF1.Value();
603     aMFj.Clear();
604     TopExp::MapShapes(aSj, TopAbs_FACE, aMFj);
605     aNbMFj=aMFj.Extent();
606     for (k=1; k<=aNbMFj; ++k) {
607       const TopoDS_Shape& aFk=aMFj(k);
608       if (!aDMSI.IsBound(aFk)) {
609         aDMSI.Bind(aFk, j);
610       }
611     }
612   }
613   //
614   // 3. Fill the map of SDF mySameDomainFaces
615   aNbC=aMC.Extent();
616   for (i=1; i<=aNbC; ++i) {
617    // const TopoDS_Shape& aF=aMC.FindKey(i);
618     const TopTools_IndexedMapOfShape& aMSDF=aMC(i);
619     //
620     aNbMSDF=aMSDF.Extent();
621     for (j=1; j<=aNbMSDF; ++j) {
622       const TopoDS_Shape& aFSD=aMSDF(j);
623       bIsImage=mySplitFaces.IsImage(aFSD);
624       aFOld=aFSD;
625       if (bIsImage) {
626         aFOld=mySplitFaces.ImageFrom(aFSD);
627       }
628       //
629       aIx=aDMSI.Find(aFOld);
630       if (j==1) {
631         aIxMin=aIx;
632         aFSDmin=aFSD;
633         continue;
634       }
635       else {
636         if (aIx<aIxMin) {
637           aIxMin=aIx;
638           aFSDmin=aFSD;
639         }
640       }
641     }
642     //
643     for (j=1; j<=aNbMSDF; ++j) {
644       const TopoDS_Shape& aFSD=aMSDF(j);
645       mySameDomainShapes.Add(aFSD, aFSDmin);
646     }
647   }
648   //
649 }
650
651 //=======================================================================
652 // function: FillImagesFaces1
653 // purpose:
654 //=======================================================================
655 void GEOMAlgo_Builder::FillImagesFaces1()
656 {
657   Standard_Integer i, aNb, iSense, aNbLFx;
658   TopoDS_Face aF, aFSp, aFSD;
659   TopTools_ListOfShape aLFx;
660   TopTools_ListIteratorOfListOfShape aIt;
661   //
662   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
663   //
664   aNb=aDS.NumberOfShapesOfTheObject();
665   for (i=1; i<=aNb; ++i) {
666     const TopoDS_Shape& aS=aDS.Shape(i);
667     if (aS.ShapeType()!=TopAbs_FACE) {
668       continue;
669     }
670     //
671     if (!mySplitFaces.HasImage(aS)) {
672       continue;
673     }
674     //
675     aF=*((TopoDS_Face*)&aS);
676     //
677     aLFx.Clear();
678     const TopTools_ListOfShape& aLF=mySplitFaces.Image(aF);
679     aIt.Initialize(aLF);
680     for (; aIt.More(); aIt.Next()) {
681       aFSp=*((TopoDS_Face*)(&aIt.Value()));
682       if (!mySameDomainShapes.Contains(aFSp)) {
683         aLFx.Append(aFSp);
684       }
685       else {
686         const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp);
687         aFSD=*((TopoDS_Face*)(&aSx));
688         iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD);
689         if (iSense<0) {
690           aFSD.Reverse();
691         }
692         aLFx.Append(aFSD);
693       }
694     }
695     //
696     if (!myImages.HasImage(aF)) {
697       aNbLFx=aLFx.Extent();
698       if (aNbLFx==1) {
699         const TopoDS_Shape& aFx=aLFx.First();
700         if (aF.IsSame(aFx)) {
701           continue;
702         }
703       }
704       myImages.Bind(aF, aLFx);
705     }
706   }
707 }
708
709 //=======================================================================
710 // function: FillInternalVertices
711 // purpose:
712 //=======================================================================
713 void GEOMAlgo_Builder::FillInternalVertices()
714 {
715   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
716   NMTTools_PaveFiller* pPF=myPaveFiller;
717   NMTDS_InterfPool* pIP=pPF->IP();
718   const Handle(IntTools_Context)& aCtx= pPF->Context();
719   //
720   BOPTools_CArray1OfVSInterference& aVFs=pIP->VSInterferences();
721   BOPTools_CArray1OfESInterference& aEFs=pIP->ESInterferences();
722   const NMTTools_IndexedDataMapOfIndexedMapOfInteger& aMAV=pPF->AloneVertices();
723   //
724   Standard_Boolean bHasImage;
725   Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag;
726   Standard_Integer aNbVFs, aNbAVF, aNbEFs, aNbVC, aNbE, aNbV;
727   Standard_Real aU1, aU2, aTol;
728   NMTTools_IndexedDataMapOfIndexedMapOfInteger aMFMV;
729   TopTools_MapOfShape aMFence;
730   TopTools_ListIteratorOfListOfShape aIt, aItV;
731   BRep_Builder aBB;
732   //
733   // 1. Collect face-vertex candidates [aMFMV]
734   //
735   // 1.1. VFs
736   aNbVFs=aVFs.Extent();
737   for (i=1; i<=aNbVFs; ++i) {
738     const BOPTools_VSInterference& aVS=aVFs(i);
739     aVS.Indices(n1, n2);
740     nF=n2;
741     nV=n1;
742     if (aDS.Shape(n1).ShapeType()==TopAbs_FACE) {
743       nF=n1;
744       nV=n2;
745     }
746     nVSD=pPF->FindSDVertex(nV);
747     if (nVSD) {
748       nV=nVSD;
749     }
750     //
751     UpdateCandidates(nF, nV, aMFMV);
752   }
753   //
754   // 1.2 EFs
755   aNbEFs=aEFs.Extent();
756   for (i=1; i<=aNbEFs; ++i) {
757     const BOPTools_ESInterference& aEF=aEFs(i);
758     aEF.Indices(n1, n2);
759     nV=aEF.NewShape();
760     if (!nV) {
761       continue;
762     }
763     const TopoDS_Shape& aSnew=aDS.Shape(nV);
764     if (aSnew.ShapeType()!=TopAbs_VERTEX) {
765       continue;
766     }
767     //
768     nF=(aDS.Shape(n1).ShapeType()==TopAbs_FACE) ? n1 : n2;
769     nVSD=pPF->FindSDVertex(nV);
770     if (nVSD) {
771       nV=nVSD;
772     }
773     UpdateCandidates(nF, nV, aMFMV);
774   }
775   //
776   aNbS=aDS.NumberOfShapesOfTheObject();
777   for (nF=1; nF<=aNbS; ++nF) {
778     const TopoDS_Shape& aF=aDS.Shape(nF);
779     //
780     if (aF.ShapeType()!=TopAbs_FACE) {
781       continue;
782     }
783     if (!aMFence.Add(aF)) {
784       continue;
785     }
786     //
787     const TopoDS_Face& aFF=TopoDS::Face(aF);
788     aTol=BRep_Tool::Tolerance(aFF);
789     //
790     // 1.3 FFs
791     if (aMAV.Contains(nF)) {
792       const TColStd_IndexedMapOfInteger& aMAVF=aMAV.FindFromKey(nF);
793       aNbAVF=aMAVF.Extent();
794       for (j=1; j<=aNbAVF; ++j) {
795         nV=aMAVF(j);
796         nVSD=pPF->FindSDVertex(nV);
797         if (nVSD) {
798           nV=nVSD;
799         }
800         //
801         UpdateCandidates(nF, nV, aMFMV);
802       }
803     }
804     //
805     // 1.4 Internal vertices of the face nF
806     BooleanOperations_OnceExplorer aExp(aDS);
807     aExp.Init(nF, TopAbs_VERTEX);
808     for (; aExp.More(); aExp.Next()) {
809       nV=aExp.Current();
810       const TopoDS_Shape& aV=aDS.Shape(nV);
811       if (aV.Orientation()==TopAbs_INTERNAL) {
812         nVSD=pPF->FindSDVertex(nV);
813         if (nVSD) {
814           nV=nVSD;
815         }
816         //
817         UpdateCandidates(nF, nV, aMFMV);
818       }
819     }
820     //
821     // 2. Process face nF
822     if (!aMFMV.Contains(nF)) {
823       continue;
824     }
825     //
826     const TColStd_IndexedMapOfInteger& aMVC=aMFMV.FindFromKey(nF);
827     aNbVC=aMVC.Extent();
828     if (!aNbVC) {
829       continue;
830     }
831     //
832     // 2.1 Refine candidates
833     TopTools_IndexedDataMapOfShapeListOfShape aMVE;
834     TopTools_ListOfShape aLV;
835     //
836     bHasImage=myImages.HasImage(aF);
837     if (bHasImage) {
838       const TopTools_ListOfShape& aLFx=myImages.Image(aF);
839       aIt.Initialize(aLFx);
840       for (; aIt.More(); aIt.Next()) {
841         const TopoDS_Shape& aFx=aIt.Value();
842         TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
843       }
844     }
845     else {
846       Standard_Boolean bFaceToProcess;
847       //
848       TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
849       bFaceToProcess=Standard_False;
850       for (j=1; j<=aNbVC; ++j) {
851         nV=aMVC(j);
852         const TopoDS_Shape& aV=aDS.Shape(nV);
853         if (!aMVE.Contains(aV)) {
854           bFaceToProcess=!bFaceToProcess;
855           break;
856         }
857       }
858       if (!bFaceToProcess) {
859         continue;
860       }
861     }// else
862     //
863     for (j=1; j<=aNbVC; ++j) {
864       nV=aMVC(j);
865       const TopoDS_Shape& aV=aDS.Shape(nV);
866       if (aMVE.Contains(aV)) {
867         const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
868         aNbE=aLE.Extent();
869         if (aNbE) {
870           continue;
871         }
872       }
873       aLV.Append(aV);
874     }
875     //
876     aNbV=aLV.Extent();
877     if (aNbV) {
878       //  3. Try to put vertices into the face(s)
879       aItV.Initialize(aLV);
880       for (; aItV.More(); aItV.Next()) {
881         TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value());
882         aV.Orientation(TopAbs_INTERNAL);
883         //
884         bHasImage=myImages.HasImage(aF);
885         if (bHasImage) {
886           const TopTools_ListOfShape& aLFx=myImages.Image(aF);
887           aIt.Initialize(aLFx);
888           for (; aIt.More(); aIt.Next()) {
889             TopoDS_Face aFx=TopoDS::Face(aIt.Value());
890             // update classifier
891             IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx);
892             aClsf.Init(aFx, aTol);
893             //
894             iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2);
895             if (!iFlag) {
896               aBB.Add(aFx, aV);
897               break;
898             }
899           }
900         }
901         else {
902           const TopoDS_Face& aFx=TopoDS::Face(aF);
903           // update classifier
904           IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx);
905           aClsf.Init(aFx, aTol);
906           //
907           iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2);
908           if (!iFlag) {
909             TopoDS_Face aFz;
910             //
911             GEOMAlgo_Tools3D::CopyFace(aFx, aFz);
912             aBB.Add(aFz, aV);
913             myImages.Bind(aF, aFz);
914           }
915         }
916       }// for (; aItV.More(); aItV.Next()) {
917     }// if (aNbV) {
918   }// for (nF=1; nF<=aNb; ++nF) {
919 }
920
921 //=======================================================================
922 // function: UpdateCandidates
923 // purpose:
924 //=======================================================================
925 void UpdateCandidates(const Standard_Integer theNF,
926                       const Standard_Integer theNV,
927                        NMTTools_IndexedDataMapOfIndexedMapOfInteger& theMFMV)
928 {
929   if (theMFMV.Contains(theNF)) {
930     TColStd_IndexedMapOfInteger& aMV=theMFMV.ChangeFromKey(theNF);
931     aMV.Add(theNV);
932   }
933   else {
934     TColStd_IndexedMapOfInteger aMV;
935     aMV.Add(theNV);
936     theMFMV.Add(theNF, aMV);
937   }
938 }
939
940 //=======================================================================
941 //function : IsClosed
942 //purpose  :
943 //=======================================================================
944 Standard_Boolean IsClosed(const TopoDS_Edge& aE,
945                           const TopoDS_Face& aF)
946 {
947   Standard_Boolean bRet;
948   //
949   bRet=BRep_Tool::IsClosed(aE, aF);
950   if (bRet) {
951     Standard_Integer iCnt;
952     TopoDS_Shape aE1;
953     //
954     bRet=!bRet;
955     iCnt=0;
956     TopExp_Explorer aExp(aF, TopAbs_EDGE);
957     for (; aExp.More(); aExp.Next()) {
958       const TopoDS_Shape& aEx=aExp.Current();
959       //
960       if (aEx.IsSame(aE)) {
961         ++iCnt;
962         if (iCnt==1) {
963           aE1=aEx;
964         }
965         else if (iCnt==2){
966           aE1.Reverse();
967           bRet=(aE1==aEx);
968           break;
969         }
970       }
971     }
972   }
973   return bRet;
974 }
975
976 /*
977     {
978       TopoDS_Compound aCx;
979       BRep_Builder aBBx;
980       TopTools_ListIteratorOfListOfShape aItx;
981       //
982       aBBx.MakeCompound(aCx);
983       aBBx.Add(aCx, aFF);
984       aItx.Initialize(aSE);
985       for (; aItx.More(); aItx.Next()) {
986         TopoDS_Shape& aEx=aItx.Value();
987         aBBx.Add(aCx, aEx);
988       }
989       int a=0;
990     }
991     */