Salome HOME
068fbc564fb885007b2261ff540e8d4c682ab1d5
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Builder_2.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File:        GEOMAlgo_Builder_2.cxx
21 // Created:     
22 // Author:      Peter KURNEV 
23
24 #include <GEOMAlgo_Builder.hxx>
25
26 #include <TColStd_IndexedMapOfInteger.hxx>
27 #include <TColStd_ListOfInteger.hxx>
28
29 #include <TopAbs_Orientation.hxx>
30
31 #include <TopoDS.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Compound.hxx>
36
37 #include <TopTools_IndexedMapOfShape.hxx>
38 #include <TopTools_ListOfShape.hxx>
39 #include <TopTools_MapOfShape.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41
42 #include <TopExp.hxx>
43 #include <TopExp_Explorer.hxx>
44
45 #include <BRep_Tool.hxx>
46 #include <BRep_Builder.hxx>
47 #include <BRepAlgo_Image.hxx>
48 #include <BRepTools.hxx>
49
50 #include <IntTools_Context.hxx>
51 #include <IntTools_FClass2d.hxx>
52
53 #include <BooleanOperations_OnceExplorer.hxx>
54 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
55 #include <BOPTools_ListOfPaveBlock.hxx>
56 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
57 #include <BOPTools_InterferencePool.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 <NMTTools_DSFiller.hxx>
72 #include <NMTTools_PaveFiller.hxx>
73 #include <NMTTools_ListOfCoupleOfShape.hxx>
74 #include <NMTTools_Tools.hxx>
75 #include <NMTTools_CoupleOfShape.hxx>
76 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
77 #include <NMTTools_Tools.hxx>
78 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
79 #include <NMTTools_ListOfCommonBlock.hxx>
80 #include <NMTTools_CommonBlock.hxx>
81 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
82 //
83 #include <GEOMAlgo_Tools3D.hxx>
84 #include <GEOMAlgo_WireEdgeSet.hxx>
85 #include <GEOMAlgo_BuilderFace.hxx>
86
87 static
88   void UpdateCandidates(const Standard_Integer ,
89                         const Standard_Integer ,
90                         NMTTools_IndexedDataMapOfIndexedMapOfInteger& );
91
92 //=======================================================================
93 //function : FillImagesFaces
94 //purpose  : 
95 //=======================================================================
96   void GEOMAlgo_Builder::FillImagesFaces()
97 {
98   myErrorStatus=0;
99   //
100   FillIn2DParts();
101   BuildSplitFaces();
102   FillSameDomainFaces();
103   FillImagesFaces1();
104   FillInternalVertices();
105 }
106 //=======================================================================
107 // function: FillIn2DParts
108 // purpose: 
109 //=======================================================================
110   void GEOMAlgo_Builder::FillIn2DParts()
111 {
112   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
113   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
114   BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
115   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
116   NMTTools_CommonBlockPool& aCBP=pPF->ChangeCommonBlockPool();
117   //
118   Standard_Integer  j, nSpIn, nSpSc, aNbCurves;
119   Standard_Integer aNbS, nF, aNbCBP, n1, n2, aNbFFs, aNbSpIn;
120   TopTools_MapOfShape  aMFence;
121   TopTools_ListOfShape aLSpIn;
122   TopoDS_Face aF;
123   NMTTools_ListIteratorOfListOfCommonBlock aItCB;
124   BOPTools_ListIteratorOfListOfPaveBlock aItPB;
125   //
126   myInParts.Clear();
127   //
128   aNbFFs=aFFs.Extent();
129   aNbCBP=aCBP.Extent();
130   //
131   aNbS=aDS.NumberOfShapesOfTheObject();
132   for (nF=1; nF<=aNbS; ++nF) {
133     if (aDS.GetShapeType(nF)!=TopAbs_FACE) {
134       continue;
135     }
136     //
137     aF=TopoDS::Face(aDS.Shape(nF));
138     //
139     aMFence.Clear();
140     aLSpIn.Clear();
141     //
142     // 1. In Parts
143     for (j=1; j<=aNbCBP; ++j) {
144       NMTTools_ListOfCommonBlock& aLCB=aCBP(j);
145       aItCB.Initialize(aLCB);
146       for (; aItCB.More(); aItCB.Next()) {
147         NMTTools_CommonBlock& aCB=aItCB.Value();
148         if (aCB.IsPaveBlockOnFace(nF)) {
149           const BOPTools_PaveBlock& aPB1=aCB.PaveBlock1();
150           nSpIn=aPB1.Edge();
151           const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
152           if (aMFence.Add(aSpIn)){
153             aLSpIn.Append(aSpIn);
154           }
155         }
156       }
157     }
158     //
159     // 2. Section Parts
160     for (j=1; j<=aNbFFs; ++j) {
161       BOPTools_SSInterference& aFF=aFFs(j);
162       aFF.Indices(n1, n2);
163       if (!(n1==nF || n2==nF)) {
164         continue;
165       }
166       BOPTools_SequenceOfCurves& aSC=aFF.Curves();
167       aNbCurves=aSC.Length();
168       if (!aNbCurves) {
169         continue;
170       }
171       //
172       const BOPTools_Curve& aBC=aSC(1);
173       const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
174       aItPB.Initialize(aLPB);
175       for (; aItPB.More(); aItPB.Next()) {
176         const BOPTools_PaveBlock& aPBSc=aItPB.Value();
177         nSpSc=aPBSc.Edge();
178         const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
179         if (aMFence.Add(aSpSc)){
180           aLSpIn.Append(aSpSc);
181         }
182       }
183     }
184     aNbSpIn=aLSpIn.Extent();
185     if (aNbSpIn) {
186       myInParts.Add(aF, aLSpIn);
187     }
188   }//for (nF=1; nF<=aNbS; ++nF) {
189 }
190 //=======================================================================
191 // function: BuildSplitFaces
192 // purpose: 
193 //=======================================================================
194   void GEOMAlgo_Builder::BuildSplitFaces()
195 {
196   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
197   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
198   BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
199   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
200   IntTools_Context& aCtx= pPF->ChangeContext();
201   //
202   Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
203   Standard_Integer i, aNb, aNbF, nF;
204   TopTools_MapOfShape aMFence;
205   TColStd_IndexedMapOfInteger aMFP;
206   TopExp_Explorer anExp;
207   TopoDS_Face aFF;
208   TopoDS_Edge aSp, aEE;
209   TopTools_ListIteratorOfListOfShape aIt;
210   TopAbs_Orientation anOriF, anOriE;
211   //
212   mySplitFaces.Clear();
213   //
214   // 1. Select Faces to process (MFP)
215   aNb=aDS.NumberOfShapesOfTheObject();
216   for (i=1; i<=aNb; ++i) {
217     const TopoDS_Shape& aF=aDS.Shape(i);
218     if (aF.ShapeType()!=TopAbs_FACE) {
219       continue;
220     }
221     if (!aMFence.Add(aF)) {
222       continue;
223     }
224     //
225     if (myInParts.Contains(aF)) {
226       aMFP.Add(i);
227       continue;
228     }
229     //
230     anExp.Init(aF, TopAbs_EDGE);
231     for (; anExp.More(); anExp.Next()) {
232       const TopoDS_Shape& aE=anExp.Current();
233       if (myImages.HasImage(aE)) {
234         aMFP.Add(i);
235         break;
236       }
237     }
238     //
239     //===
240     {
241       Standard_Integer aNbFFs, aNbSE, j, n1, n2;
242       //
243       aNbFFs=aFFs.Extent();
244       for (j=1; j<=aNbFFs; ++j) {
245         BOPTools_SSInterference& aFFj=aFFs(j);
246         aFFj.Indices(n1, n2);
247         if (!(n1==i || n2==i)) {
248           continue;
249         }
250         //
251         const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
252         aNbSE=aLSE.Extent();
253         if (aNbSE) {
254           aMFP.Add(i);
255         }
256       }
257     }
258     //===
259     //
260   }// for (i=1; i<=aNb; ++i)
261   //
262   // 2. ProcessFaces
263   aNbF=aMFP.Extent();
264   for (i=1; i<=aNbF; ++i) {
265     nF=aMFP(i);
266     const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
267     anOriF=aF.Orientation();
268     aFF=aF;
269     aFF.Orientation(TopAbs_FORWARD);
270     //
271     aMFence.Clear();
272     //
273     // 2.1. Fill WES 
274     GEOMAlgo_WireEdgeSet aWES;
275     aWES.SetFace(aFF);
276     //
277     //  2.1.1. Add Split parts
278     anExp.Init(aFF, TopAbs_EDGE);
279     for (; anExp.More(); anExp.Next()) {
280       const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
281       anOriE=aE.Orientation();
282       //
283       if (!myImages.HasImage(aE)) {
284         if (anOriE==TopAbs_INTERNAL) {
285           aEE=aE;
286           aEE.Orientation(TopAbs_FORWARD);
287           aWES.AddStartElement(aEE);
288           aEE.Orientation(TopAbs_REVERSED);
289           aWES.AddStartElement(aEE);
290         }
291         else {
292           aWES.AddStartElement(aE);
293         }
294         continue;
295       }
296       //
297       bIsDegenerated=BRep_Tool::Degenerated(aE);
298       bIsClosed=BRep_Tool::IsClosed(aE, aF);
299       //
300       const TopTools_ListOfShape& aLIE=myImages.Image(aE);
301       aIt.Initialize(aLIE);
302       for (; aIt.More(); aIt.Next()) {
303         aSp=TopoDS::Edge(aIt.Value());
304         //
305         if (bIsDegenerated) {
306           aSp.Orientation(anOriE);
307           aWES.AddStartElement(aSp);
308           continue;
309         }
310         //
311         if (anOriE==TopAbs_INTERNAL) {
312           aSp.Orientation(TopAbs_FORWARD);
313           aWES.AddStartElement(aSp);
314           aSp.Orientation(TopAbs_REVERSED);
315           aWES.AddStartElement(aSp);
316           continue;
317         }
318         //
319         if (bIsClosed){
320           if (aMFence.Add(aSp)) {
321             //
322             if (!BRep_Tool::IsClosed(aSp, aF)){
323               BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
324             }
325             //
326             aSp.Orientation(TopAbs_FORWARD);
327             aWES.AddStartElement(aSp);
328             aSp.Orientation(TopAbs_REVERSED);
329             aWES.AddStartElement(aSp);
330           }
331           continue;
332         }// if (aMFence.Add(aSp))
333         //
334         aSp.Orientation(anOriE);
335         bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
336         if (bToReverse) {
337           aSp.Reverse();
338         }
339         aWES.AddStartElement(aSp);
340       }// for (; aIt.More(); aIt.Next()) {
341     }// for (; anExp.More(); anExp.Next()) {
342     //
343     // 2.1.2. Add In2D Parts
344     if (myInParts.Contains(aF)) {
345       const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF);
346       aIt.Initialize(aLE);
347       for (; aIt.More(); aIt.Next()) {
348         aSp=TopoDS::Edge(aIt.Value());
349         //
350         aSp.Orientation(TopAbs_FORWARD);
351         aWES.AddStartElement(aSp);
352         //
353         aSp.Orientation(TopAbs_REVERSED);
354         aWES.AddStartElement(aSp);
355       }
356     }
357     //
358     // 2.2. Build images Faces
359     GEOMAlgo_BuilderFace aBF;
360     //
361     aBF.SetFace(aFF);
362     aBF.SetContext(aCtx);
363     const TopTools_ListOfShape& aSE=aWES.StartElements();
364     aBF.SetShapes(aSE);
365     //
366     aBF.Perform();
367     //
368     const TopTools_ListOfShape& aLF=aBF.Areas();
369     //
370     TopTools_ListOfShape aLFR;
371     //
372     aIt.Initialize(aLF);
373     for (; aIt.More(); aIt.Next()) {
374       TopoDS_Shape& aFR=aIt.Value();
375       if (anOriF==TopAbs_REVERSED) {
376         aFR.Orientation(TopAbs_REVERSED);
377       }
378       aLFR.Append(aFR);
379     }
380     //
381     // 2.3. Collect draft images Faces
382     mySplitFaces.Bind(aF, aLFR);
383   }//for (i=1; i<=aNbF; ++i)
384 }
385 //=======================================================================
386 // function: FillSameDomainFaces
387 // purpose: 
388 //=======================================================================
389   void GEOMAlgo_Builder::FillSameDomainFaces()
390 {
391   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
392   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
393   BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
394   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
395   IntTools_Context& aCtx= pPF->ChangeContext();
396   //
397   Standard_Boolean bIsSDF;
398   Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC, aNbSE;
399   TopTools_MapOfShape aMFence;
400   TopTools_ListIteratorOfListOfShape aItF1, aItF2;
401   NMTTools_ListOfCoupleOfShape aLCS;   
402   //
403   //mySameDomainShapes.Clear();
404   //
405   // 1. For each FF find among images of faces
406   //    all pairs of same domain faces (SDF) [=> aLCS]
407   aNbFF=aFFs.Extent();
408   for (i=1; i<=aNbFF; ++i) {
409     BOPTools_SSInterference& aFF=aFFs(i);
410     aFF.Indices(nF1, nF2);
411     //
412     const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
413     const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
414     //
415     // if there are no in/on 2D split parts the faces nF1, nF2
416     // can not be SDF
417     const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks();
418     aNbPBInOn=aLPBInOn.Extent();
419     //
420     //===
421     const TColStd_ListOfInteger& aLSE=aFF.SharedEdges();
422     aNbSE=aLSE.Extent();
423     if (!aNbPBInOn && !aNbSE) {
424       continue;
425     }
426     //===
427     //
428     // if there is at least one section edge between faces nF1, nF2
429     // they can not be SDF
430     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
431     aNbC=aSC.Length();
432     if (aNbC) {
433       continue;
434     }
435     //
436     // the faces are suspected to be SDF.
437     // Try to find SDF among images of nF1, nF2
438     aMFence.Clear();
439     const TopTools_ListOfShape& aLF1=mySplitFaces.Image(aF1);
440     const TopTools_ListOfShape& aLF2=mySplitFaces.Image(aF2);
441     //
442     aItF1.Initialize(aLF1);
443     for (; aItF1.More(); aItF1.Next()) {
444       const TopoDS_Face& aF1x=TopoDS::Face(aItF1.Value());
445       //
446       aItF2.Initialize(aLF2);
447       for (; aItF2.More(); aItF2.Next()) {
448         const TopoDS_Face& aF2y=TopoDS::Face(aItF2.Value());
449         bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
450         if (bIsSDF) {
451           if (aMFence.Contains(aF1x) ||
452               aMFence.Contains(aF2y)) {
453             continue;
454           }
455           aMFence.Add(aF1x);
456           aMFence.Add(aF2y);
457           //
458           NMTTools_CoupleOfShape aCS;
459           //
460           aCS.SetShape1(aF1x);
461           aCS.SetShape2(aF2y);
462           aLCS.Append(aCS);
463           //
464           if (aF1x==aF1) {
465             if (!mySplitFaces.HasImage(aF1)) {
466               mySplitFaces.Bind(aF1, aF1);
467             }
468           }
469           if (aF2y==aF2) {
470             if (!mySplitFaces.HasImage(aF2)) {
471               mySplitFaces.Bind(aF2, aF2);
472             }
473           }
474           //
475           
476         }
477       }
478     }
479   }//for (i=1; i<=aNbFF; ++i)
480   //
481   aNbC=aLCS.Extent();
482   if (!aNbC) {
483     return;
484   }
485   //
486   // 2. Find Chains
487   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;  
488   //
489   NMTTools_Tools::FindChains(aLCS, aMC); 
490   //
491   // 3. Fill the map of SDF mySameDomainFaces
492   aNbC=aMC.Extent();
493   for (i=1; i<=aNbC; ++i) {
494     const TopoDS_Shape& aF=aMC.FindKey(i);
495     const TopTools_IndexedMapOfShape& aMSDF=aMC(i);
496     //
497     aNbFF=aMSDF.Extent();
498     for (j=1; j<=aNbFF; ++j) {
499       const TopoDS_Shape& aFSD=aMSDF(j);
500       mySameDomainShapes.Add(aFSD, aF);
501     }
502   }
503   //
504 }
505 //=======================================================================
506 // function: FillImagesFaces1
507 // purpose: 
508 //=======================================================================
509   void GEOMAlgo_Builder::FillImagesFaces1()
510 {
511   Standard_Integer i, aNb, iSense;
512   TopoDS_Face aF, aFSp, aFSD;
513   TopTools_ListOfShape aLFx;
514   TopTools_ListIteratorOfListOfShape aIt;
515   //
516   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
517   //
518   aNb=aDS.NumberOfShapesOfTheObject();
519   for (i=1; i<=aNb; ++i) {
520     const TopoDS_Shape& aS=aDS.Shape(i);
521     if (aS.ShapeType()!=TopAbs_FACE) {
522       continue;
523     }
524     //
525     if (!mySplitFaces.HasImage(aS)) {
526       continue;
527     }
528     //
529     aF=TopoDS::Face(aS);
530     //
531     aLFx.Clear();
532     const TopTools_ListOfShape& aLF=mySplitFaces.Image(aF);
533     aIt.Initialize(aLF);
534     for (; aIt.More(); aIt.Next()) {
535       aFSp=TopoDS::Face(aIt.Value());
536       if (!mySameDomainShapes.Contains(aFSp)) {
537         aLFx.Append(aFSp);
538       }
539       else {
540         const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp);
541         aFSD=TopoDS::Face(aSx);
542         iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD);
543         if (iSense<0) {
544           aFSD.Reverse();
545         }
546         aLFx.Append(aFSD);
547       }
548     }
549     if (!myImages.HasImage(aF)) {//XX
550       myImages.Bind(aF, aLFx);
551     }
552   }
553 }
554 //=======================================================================
555 // function: FillInternalVertices
556 // purpose: 
557 //=======================================================================
558   void GEOMAlgo_Builder::FillInternalVertices()
559 {
560   const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
561   NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
562   BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
563   IntTools_Context& aCtx= pPF->ChangeContext();
564   //
565   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
566   BOPTools_CArray1OfVSInterference& aVFs=pIP->VSInterferences();
567   BOPTools_CArray1OfESInterference& aEFs=pIP->ESInterferences();
568   const NMTTools_IndexedDataMapOfIndexedMapOfInteger& aMAV=pPF->AloneVertices();
569   //
570   Standard_Boolean bHasImage; 
571   Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag; 
572   Standard_Integer aNbVFs, aNbAVF, aNbEFs, aNbVC, aNbE, aNbV;
573   Standard_Real aU1, aU2, aTol;
574   NMTTools_IndexedDataMapOfIndexedMapOfInteger aMFMV;
575   TopTools_MapOfShape aMFence;
576   TopTools_ListIteratorOfListOfShape aIt, aItV;
577   BRep_Builder aBB;
578   //
579   // 1. Collect face-vertex candidates [aMFMV]
580   //
581   // 1.1. VFs
582   aNbVFs=aVFs.Extent();
583   for (i=1; i<=aNbVFs; ++i) {
584     const BOPTools_VSInterference& aVS=aVFs(i);
585     aVS.Indices(n1, n2);
586     nF=n2;
587     nV=n1;
588     if (aDS.Shape(n1).ShapeType()==TopAbs_FACE) {
589       nF=n1;
590       nV=n2;
591     }
592     nVSD=pPF->FindSDVertex(nV);
593     if (nVSD) {
594       nV=nVSD;
595     }
596     //
597     UpdateCandidates(nF, nV, aMFMV);
598   }
599   //
600   // 1.2 EFs
601   aNbEFs=aEFs.Extent();
602   for (i=1; i<=aNbEFs; ++i) {
603     const BOPTools_ESInterference& aEF=aEFs(i);
604     aEF.Indices(n1, n2);
605     nV=aEF.NewShape();
606     if (!nV) {
607       continue;
608     }
609     const TopoDS_Shape& aSnew=aDS.Shape(nV);
610     if (aSnew.ShapeType()!=TopAbs_VERTEX) {
611       continue;
612     }
613     //
614     nF=(aDS.Shape(n1).ShapeType()==TopAbs_FACE) ? n1 : n2;
615     nVSD=pPF->FindSDVertex(nV);
616     if (nVSD) {
617       nV=nVSD;
618     }
619     UpdateCandidates(nF, nV, aMFMV);
620   }
621   //
622   aNbS=aDS.NumberOfShapesOfTheObject();
623   for (nF=1; nF<=aNbS; ++nF) {
624     const TopoDS_Shape& aF=aDS.Shape(nF);
625     //
626     if (aF.ShapeType()!=TopAbs_FACE) {
627       continue;
628     }
629     if (!aMFence.Add(aF)) {
630       continue;
631     }
632     //
633     const TopoDS_Face& aFF=TopoDS::Face(aF);
634     aTol=BRep_Tool::Tolerance(aFF);
635     //
636     // 1.3 FFs
637     if (aMAV.Contains(nF)) {
638       const TColStd_IndexedMapOfInteger& aMAVF=aMAV.FindFromKey(nF);
639       aNbAVF=aMAVF.Extent();
640       for (j=1; j<=aNbAVF; ++j) {
641         nV=aMAVF(j); 
642         nVSD=pPF->FindSDVertex(nV);
643         if (nVSD) {
644           nV=nVSD;
645         }
646         //
647         UpdateCandidates(nF, nV, aMFMV);
648       }
649     }
650     //
651     // 1.4 Internal vertices of the face nF
652     BooleanOperations_OnceExplorer aExp(aDS);
653     aExp.Init(nF, TopAbs_VERTEX);
654     for (; aExp.More(); aExp.Next()) {
655       nV=aExp.Current();
656       const TopoDS_Shape& aV=aDS.Shape(nV);
657       if (aV.Orientation()==TopAbs_INTERNAL) {
658         nVSD=pPF->FindSDVertex(nV);
659         if (nVSD) {
660           nV=nVSD;
661         }
662         //
663         UpdateCandidates(nF, nV, aMFMV);
664       }
665     }
666     //
667     // 2. Process face nF
668     if (!aMFMV.Contains(nF)) {
669       continue;
670     }
671     //
672     const TColStd_IndexedMapOfInteger& aMVC=aMFMV.FindFromKey(nF);
673     aNbVC=aMVC.Extent();
674     if (!aNbVC) {
675       continue;
676     }
677     //
678     // 2.1 Refine candidates
679     TopTools_IndexedDataMapOfShapeListOfShape aMVE;
680     TopTools_ListOfShape aLV;
681     //
682     bHasImage=myImages.HasImage(aF);
683     if (bHasImage) {
684       const TopTools_ListOfShape& aLFx=myImages.Image(aF);
685       aIt.Initialize(aLFx);
686       for (; aIt.More(); aIt.Next()) {
687         const TopoDS_Shape& aFx=aIt.Value();
688         TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
689       }
690     }
691     else {      
692       Standard_Boolean bFaceToProcess;
693       //
694       TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
695       bFaceToProcess=Standard_False;
696       for (j=1; j<=aNbVC; ++j) {
697         nV=aMVC(j);
698         const TopoDS_Shape& aV=aDS.Shape(nV);
699         if (!aMVE.Contains(aV)) {
700           bFaceToProcess=!bFaceToProcess;
701           break;
702         }
703       }
704       if (!bFaceToProcess) {
705         continue;
706       }
707     }// else
708     //
709     for (j=1; j<=aNbVC; ++j) {
710       nV=aMVC(j);
711       const TopoDS_Shape& aV=aDS.Shape(nV);
712       if (aMVE.Contains(aV)) {
713         const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
714         aNbE=aLE.Extent();
715         if (aNbE) {
716           continue;
717         }
718       }
719       aLV.Append(aV);
720     }
721     //
722     aNbV=aLV.Extent();
723     if (aNbV) {
724       //  3. Try to put vertices into the face(s)
725       aItV.Initialize(aLV);
726       for (; aItV.More(); aItV.Next()) {
727         TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value());
728         aV.Orientation(TopAbs_INTERNAL);
729         //
730         bHasImage=myImages.HasImage(aF);
731         if (bHasImage) {
732           const TopTools_ListOfShape& aLFx=myImages.Image(aF);
733           aIt.Initialize(aLFx);
734           for (; aIt.More(); aIt.Next()) {
735             TopoDS_Face aFx=TopoDS::Face(aIt.Value());
736             // update classifier
737             IntTools_FClass2d& aClsf=aCtx.FClass2d(aFx);
738             aClsf.Init(aFx, aTol);
739             //
740             iFlag=aCtx.ComputeVS (aV, aFx, aU1, aU2);
741             if (!iFlag) {
742               aBB.Add(aFx, aV);
743               break;
744             }
745           }
746         }
747         else {  
748           const TopoDS_Face& aFx=TopoDS::Face(aF);
749           // update classifier
750           IntTools_FClass2d& aClsf=aCtx.FClass2d(aFx);
751           aClsf.Init(aFx, aTol);
752           //
753           iFlag=aCtx.ComputeVS (aV, aFx, aU1, aU2);
754           if (!iFlag) {
755             TopoDS_Face aFz;
756             //
757             GEOMAlgo_Tools3D::CopyFace(aFx, aFz); 
758             aBB.Add(aFz, aV);
759             myImages.Bind(aF, aFz);
760           }
761         }
762       }// for (; aItV.More(); aItV.Next()) {
763     }// if (aNbV) {
764   }// for (nF=1; nF<=aNb; ++nF) {
765 }
766 //=======================================================================
767 // function: UpdateCandidates
768 // purpose: 
769 //=======================================================================
770 void UpdateCandidates(const Standard_Integer theNF,
771                       const Standard_Integer theNV,
772                        NMTTools_IndexedDataMapOfIndexedMapOfInteger& theMFMV)
773 {
774   if (theMFMV.Contains(theNF)) {
775     TColStd_IndexedMapOfInteger& aMV=theMFMV.ChangeFromKey(theNF);
776     aMV.Add(theNV);
777   }
778   else {
779     TColStd_IndexedMapOfInteger aMV;
780     aMV.Add(theNV);
781     theMFMV.Add(theNF, aMV);
782   }
783 }