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