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