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