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