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