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