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