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