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