]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTTools/NMTTools_PaveFiller_7.cxx
Salome HOME
0021434: Boolean operations generate a shape with big vertex tolerance.
[modules/geom.git] / src / NMTTools / NMTTools_PaveFiller_7.cxx
1 // Copyright (C) 2007-2011  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:        NMTTools_PaveFiller_7.cxx
23 // Author:      Peter KURNEV
24
25 #include <NMTTools_PaveFiller.ixx>
26
27 #include <Basics_OCCTVersion.hxx>
28
29 #include <Bnd_HArray1OfBox.hxx>
30 #include <Bnd_BoundSortBox.hxx>
31 #include <Bnd_Box.hxx>
32 #include <BRepBndLib.hxx>
33
34 #include <TColStd_MapOfInteger.hxx>
35 #include <TColStd_ListOfInteger.hxx>
36 #include <TColStd_IndexedMapOfInteger.hxx>
37 #include <TColStd_ListIteratorOfListOfInteger.hxx>
38
39 #include <GeomAPI_ProjectPointOnCurve.hxx>
40
41 #include <TopAbs_Orientation.hxx>
42
43 #include <TopoDS.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopoDS_Compound.hxx>
48
49 #include <TopTools_DataMapOfIntegerShape.hxx>
50 #include <TopTools_DataMapOfShapeInteger.hxx>
51 #include <TopTools_DataMapOfShapeShape.hxx>
52 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
53 #include <TopTools_DataMapIteratorOfDataMapOfIntegerShape.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
55 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger.hxx>
56
57 #include <BRep_Builder.hxx>
58 #include <BRep_Tool.hxx>
59
60 #include <TopExp_Explorer.hxx>
61 #include <TopExp.hxx>
62
63 #include <IntTools_SequenceOfPntOn2Faces.hxx>
64 #include <IntTools_PntOnFace.hxx>
65 #include <IntTools_PntOn2Faces.hxx>
66
67 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
68
69 #include <BOPTools_SSInterference.hxx>
70 #include <BOPTools_CArray1OfSSInterference.hxx>
71 #include <BOPTools_CArray1OfVVInterference.hxx>
72 #include <BOPTools_VVInterference.hxx>
73 #include <BOPTools_Tools.hxx>
74 #include <BOPTools_ListOfPaveBlock.hxx>
75 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
76 #include <BOPTools_PaveBlock.hxx>
77 #include <BOPTools_Pave.hxx>
78 #include <BOPTools_Tools.hxx>
79
80 #include <NMTDS_Iterator.hxx>
81 #include <NMTDS_ShapesDataStructure.hxx>
82 #include <NMTDS_InterfPool.hxx>
83
84 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
85 #include <NMTTools_MapOfPaveBlock.hxx>
86
87
88 //=======================================================================
89 // function: MakeSplitEdges
90 // purpose:
91 //=======================================================================
92 void NMTTools_PaveFiller::MakeSplitEdges()
93 {
94   myIsDone=Standard_False;
95   //
96   Standard_Boolean bIsNewVertex1, bIsNewVertex2;
97   Standard_Integer i, aNbS, nV1, nV2, aNbPaveBlocks, aNewShapeIndex;
98   Standard_Real    t1, t2;
99   TopAbs_Orientation anOri;
100   TopoDS_Edge aE, aESplit;
101   TopoDS_Vertex aV1, aV2;
102   //
103   aNbS=myDS->NumberOfShapesOfTheObject();
104   for (i=1; i<=aNbS; ++i) {
105     if (myDS->GetShapeType(i) != TopAbs_EDGE)
106       continue;
107     //
108     // Original Edge
109     aE=TopoDS::Edge(myDS->Shape(i));
110     if (BRep_Tool::Degenerated(aE)){
111       continue;
112     }
113     //
114     anOri=aE.Orientation();
115     aE.Orientation(TopAbs_FORWARD);
116     //
117     // Making Split Edges
118     //
119     // Split Set for the Original Edge i
120     BOPTools_ListOfPaveBlock& aSplitEdges=mySplitShapesPool(myDS->RefEdge(i));
121     BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
122     //
123     aNbPaveBlocks=aSplitEdges.Extent();
124
125     for (; aPBIt.More(); aPBIt.Next()) {
126       BOPTools_PaveBlock& aPB=aPBIt.Value();
127       // aPave1
128       const BOPTools_Pave& aPave1=aPB.Pave1();
129       nV1=aPave1.Index();
130       t1=aPave1.Param();
131       aV1=TopoDS::Vertex(myDS->GetShape(nV1));
132       aV1.Orientation(TopAbs_FORWARD);
133       // aPave2
134       const BOPTools_Pave& aPave2=aPB.Pave2();
135       nV2=aPave2.Index();
136       t2=aPave2.Param();
137       aV2=TopoDS::Vertex(myDS->GetShape(nV2));
138       aV2.Orientation(TopAbs_REVERSED);
139       //xx
140       if (aNbPaveBlocks==1) {
141         bIsNewVertex1=myDS->IsNewShape (nV1);
142         bIsNewVertex2=myDS->IsNewShape (nV2);
143         if (!bIsNewVertex1 && !bIsNewVertex2) {
144           aPB.SetEdge(i);
145           continue;
146         }
147       }
148       //xx
149       BOPTools_Tools::MakeSplitEdge(aE, aV1, t1, aV2, t2, aESplit);
150       //
151       // Add Split Part of the Original Edge to the DS
152       BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
153
154       anASSeq.SetNewSuccessor(nV1);
155       anASSeq.SetNewOrientation(aV1.Orientation());
156
157       anASSeq.SetNewSuccessor(nV2);
158       anASSeq.SetNewOrientation(aV2.Orientation());
159       //
160       if (anOri==TopAbs_INTERNAL) {
161         anASSeq.SetNewAncestor(i);
162         aESplit.Orientation(anOri);
163       }
164       //
165       myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
166       aNewShapeIndex=myDS->NumberOfInsertedShapes();
167       myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
168       //
169       // Fill Split Set for the Original Edge
170       aPB.SetEdge(aNewShapeIndex);
171       //
172     }
173   }
174   myIsDone=Standard_True;
175 }
176 //=======================================================================
177 // function: UpdateCommonBlocks
178 // purpose:
179 //=======================================================================
180 void NMTTools_PaveFiller::UpdateCommonBlocks(const Standard_Integer)
181 {
182   Standard_Integer nE, aNbS,  nEx, nEMax, j, aNbPoints, aNbLCB, nF;
183   Standard_Real aTolEx, aTolExMax, aTSRMax[2], aTx[2], aTmp;
184   TColStd_ListIteratorOfListOfInteger aItLI;
185   gp_Pnt aPMax[2];
186   TopoDS_Edge aEMax;
187   BOPTools_ListIteratorOfListOfPaveBlock aItLPB, aItLPBS;
188   NMTTools_ListIteratorOfListOfCommonBlock aItLCB;
189   NMTTools_MapOfPaveBlock aMPB;
190   //
191   myIsDone=Standard_False;
192   //
193   aNbS=myDS->NumberOfShapesOfTheObject();
194   for (nE=1; nE<=aNbS; ++nE) {
195     if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
196       continue;
197     }
198     //
199     const TopoDS_Edge& aE=*((TopoDS_Edge*)&myDS->Shape(nE));
200     if (BRep_Tool::Degenerated(aE)){
201       continue;
202     }
203     //
204     NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
205     //modified by NIZNHY-PKV Thu Jan 19 09:03:19 2012f
206     aNbLCB=aLCB.Extent();
207     if (!aNbLCB) {
208       continue;
209     }
210     // 0
211     NMTTools_ListOfCommonBlock aLCBx;
212     //
213     aItLCB.Initialize(aLCB);
214     for (; aItLCB.More(); aItLCB.Next()) {
215       NMTTools_CommonBlock aCBx;
216       //
217       NMTTools_CommonBlock& aCB=aItLCB.Value();
218       const BOPTools_ListOfPaveBlock &aLPB=aCB.PaveBlocks();
219       aItLPB.Initialize(aLPB);
220       for (; aItLPB.More(); aItLPB.Next()) {
221         const BOPTools_PaveBlock& aPBx=aItLPB.Value();
222         nEx=aPBx.OriginalEdge();
223         BOPTools_ListOfPaveBlock& aLPBS=mySplitShapesPool(myDS->RefEdge(nEx));
224         aItLPBS.Initialize(aLPBS);
225         for (; aItLPBS.More(); aItLPBS.Next()) {
226           const BOPTools_PaveBlock& aPBSx=aItLPBS.Value();
227           if (aPBSx.IsEqual(aPBx)) {
228             aCBx.AddPaveBlock(aPBSx);
229             break;
230           }
231         }// for (; aItLPBS.More(); aItLPBS.Next()) {
232       }// for (; aItLPB.More(); aItLPB.Next()) {
233       //
234       const TColStd_ListOfInteger& aLI=aCB.Faces();
235       aItLI.Initialize(aLI);
236       for (; aItLI.More(); aItLI.Next()) {
237         nF=aItLI.Value();
238         aCBx.AddFace(nF);
239       }
240       //
241       aLCBx.Append(aCBx);
242     }//for (; aItLCB.More(); aItLCB.Next()) {
243     //
244     aLCB.Clear();
245     //
246     aItLCB.Initialize(aLCBx);
247     for (; aItLCB.More(); aItLCB.Next()) {
248       NMTTools_CommonBlock& aCBx=aItLCB.Value();
249       aLCB.Append(aCBx);
250     }
251     //modified by NIZNHY-PKV Thu Jan 19 09:03:30 2012t
252     // 1
253     aItLCB.Initialize(aLCB);
254     for (; aItLCB.More(); aItLCB.Next()) {
255       NMTTools_CommonBlock& aCB=aItLCB.Value();
256       //
257       BOPTools_PaveBlock aPBMax;
258       aTolExMax=-1.;
259       const BOPTools_ListOfPaveBlock &aLPB=aCB.PaveBlocks();
260       aItLPB.Initialize(aLPB);
261       for (; aItLPB.More(); aItLPB.Next()) {
262         const BOPTools_PaveBlock& aPBx=aItLPB.Value();
263         nEx=aPBx.OriginalEdge();
264         const TopoDS_Edge& aEx=*((TopoDS_Edge*)&myDS->Shape(nEx));
265         aTolEx=BRep_Tool::Tolerance(aEx);
266         if (aTolEx>aTolExMax) {
267           aTolExMax=aTolEx;
268           aEMax=aEx;
269           aPBMax=aPBx;
270         }
271       }
272       //
273       // 2
274       if (aMPB.Contains(aPBMax)) {
275         continue;
276       }
277       aMPB.Add(aPBMax);
278       //
279       nEMax=aPBMax.OriginalEdge();
280       const IntTools_ShrunkRange& aISRMax=aPBMax.ShrunkRange();
281       const IntTools_Range& aSRMax=aISRMax.ShrunkRange();
282       const Bnd_Box& aBoxMax=aISRMax.BndBox();
283       aSRMax.Range(aTSRMax[0], aTSRMax[1]);
284       for (j=0; j<2; ++j) {
285         BOPTools_Tools::PointOnEdge(aEMax, aTSRMax[j], aPMax[j]);
286       }
287       //
288       // 3
289       aItLPB.Initialize(aLPB);
290       for (; aItLPB.More(); aItLPB.Next()) {
291         const BOPTools_PaveBlock& aPBx=aItLPB.Value();
292         nEx=aPBx.OriginalEdge();
293         if (nEx==nEMax) {
294           continue;
295         }
296         //
297         const TopoDS_Edge& aEx=*((TopoDS_Edge*)&myDS->Shape(nEx));
298 #if OCC_VERSION_LARGE > 0x06050200
299         GeomAPI_ProjectPointOnCurve& aPPCx=myContext->ProjPC(aEx);
300 #else
301         GeomAPI_ProjectPointOnCurve& aPPCx=myContext.ProjPC(aEx);
302 #endif
303         //
304         for (j=0; j<2; ++j) {
305           aPPCx.Perform(aPMax[j]);
306           aNbPoints=aPPCx.NbPoints();
307           if (!aNbPoints) {
308             break;
309           }
310           aTx[j]=aPPCx.LowerDistanceParameter();
311         }
312         if (!aNbPoints) {
313           // correction the range is impossible due to
314           // a projection problem
315           continue;
316         }
317         //
318         if (aTx[0]>aTx[1]){
319           aTmp=aTx[0];
320           aTx[0]=aTx[1];
321           aTx[1]=aTmp;
322         }
323         //
324         // 4 Correction
325         // 4.1 aPBx
326         {
327           const IntTools_ShrunkRange& aISRx=aPBx.ShrunkRange();
328           IntTools_Range *pSRx=(IntTools_Range *)(&aISRx.ShrunkRange());
329           Bnd_Box *pBoxx=(Bnd_Box *)(&aISRx.BndBox());
330           //
331           pSRx->SetFirst(aTx[0]);
332           pSRx->SetLast(aTx[1]);
333           *pBoxx=aBoxMax;
334         }
335         //
336         // 4.2 aPBSx
337         BOPTools_ListOfPaveBlock& aLPBSx=mySplitShapesPool(myDS->RefEdge(nEx));
338         aItLPBS.Initialize(aLPBSx);
339         for (; aItLPBS.More(); aItLPBS.Next()) {
340           const BOPTools_PaveBlock& aPBSx=aItLPBS.Value();
341           if (!aPBSx.IsEqual(aPBx)) {
342             continue;
343           }
344           //
345           const IntTools_ShrunkRange& aISRx=aPBSx.ShrunkRange();
346           IntTools_Range *pSRx=(IntTools_Range *)(&aISRx.ShrunkRange());
347           Bnd_Box *pBoxx=(Bnd_Box *)(&aISRx.BndBox());
348           //
349           pSRx->SetFirst(aTx[0]);
350           pSRx->SetLast(aTx[1]);
351           *pBoxx=aBoxMax;
352         }
353         //
354         //
355       }//for (; aItLPB.More(); aItLPB.Next()) {
356     }//for (; aItLCB.More(); aItLCB.Next()) {
357   }//for (nE=1; nE<=aNbS; ++nE) {
358 }
359 //=======================================================================
360 // function: UpdateCommonBlocks
361 // purpose:
362 //=======================================================================
363 void NMTTools_PaveFiller::UpdateCommonBlocks()
364 {
365   myIsDone=Standard_False;
366   //
367   Standard_Integer nE, aNbS,  nSp, nEx, nSpx;
368   NMTTools_ListIteratorOfListOfCommonBlock aCBIt;
369   BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
370   //
371   aNbS=myDS->NumberOfShapesOfTheObject();
372   //
373   for (nE=1; nE<=aNbS; ++nE) {
374     if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
375       continue;
376     }
377     if (BRep_Tool::Degenerated(TopoDS::Edge(myDS->Shape(nE)))){
378       continue;
379     }
380     //
381     NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
382     /*BOPTools_ListOfPaveBlock& aLPB=*/mySplitShapesPool  (myDS->RefEdge(nE));
383     //
384     aCBIt.Initialize(aLCB);
385     for (; aCBIt.More(); aCBIt.Next()) {
386       NMTTools_CommonBlock& aCB=aCBIt.Value();
387       //
388       // Among all PBs of aCB the first PB will be one
389       // that have max tolerance value
390       {
391         Standard_Real aTolEx, aTolExMax;
392         BOPTools_ListOfPaveBlock *pLPB, aLPBx;
393         //
394         aTolExMax=-1.;
395         pLPB=(BOPTools_ListOfPaveBlock *)&aCB.PaveBlocks();
396         aPBIt.Initialize(*pLPB);
397         for (; aPBIt.More(); aPBIt.Next()) {
398           const BOPTools_PaveBlock& aPBx=aPBIt.Value();
399           nEx=aPBx.OriginalEdge();
400           const TopoDS_Edge& aEx=TopoDS::Edge(myDS->Shape(nEx));
401           aTolEx=BRep_Tool::Tolerance(aEx);
402           if (aTolEx>aTolExMax) {
403             aTolExMax=aTolEx;
404             aLPBx.Prepend(aPBx);
405           }
406           else{
407             aLPBx.Append(aPBx);
408           }
409         }
410         //
411         pLPB->Clear();
412         *pLPB=aLPBx;
413       }
414       //
415       BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
416       nSp=SplitIndex(aPB);
417       aPB.SetEdge(nSp);
418       //
419       const BOPTools_ListOfPaveBlock& aCBLPB=aCB.PaveBlocks();
420       aPBIt.Initialize(aCBLPB);
421       for (; aPBIt.More(); aPBIt.Next()) {
422         BOPTools_PaveBlock& aPBx=aPBIt.Value();
423         nEx=aPBx.OriginalEdge();
424         if (nEx==nE) {
425           continue;
426         }
427         //
428         nSpx=SplitIndex(aPBx);
429         aPBx.SetEdge(nSpx);
430       }
431       //
432     }
433   }
434 }
435 //=======================================================================
436 // function: SplitIndex
437 // purpose:
438 //=======================================================================
439 Standard_Integer NMTTools_PaveFiller::SplitIndex
440   (const BOPTools_PaveBlock& aPBx) const
441 {
442   Standard_Integer anOriginalEdge, anEdgeIndex=0;
443
444   anOriginalEdge=aPBx.OriginalEdge();
445
446   const BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(anOriginalEdge));
447   //
448   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
449   for (; anIt.More(); anIt.Next()) {
450     BOPTools_PaveBlock& aPB=anIt.Value();
451     if (aPB.IsEqual(aPBx)) {
452       anEdgeIndex=aPB.Edge();
453       return anEdgeIndex;
454     }
455   }
456   return anEdgeIndex;
457 }
458
459 //=======================================================================
460 // function: UpdatePaveBlocks
461 // purpose:
462 //=======================================================================
463 void NMTTools_PaveFiller::UpdatePaveBlocks()
464 {
465   myIsDone=Standard_False;
466   //
467   Standard_Integer i, aNbFFs, nF1, nF2, aNbF, nF, iRankF, nE, nV1, nV2, aNbPB;
468   Standard_Real aT1, aT2;
469   TColStd_IndexedMapOfInteger aMF, aME;
470   TopExp_Explorer aExp;
471   TopoDS_Vertex aV1, aV2;
472   TopoDS_Edge aE;
473   BOPTools_Pave aPave1, aPave2;
474   BOPTools_PaveBlock aPB;
475   //
476   BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
477   //
478   aNbFFs=aFFs.Extent();
479   for (i=1; i<=aNbFFs; ++i) {
480     BOPTools_SSInterference& aFFi=aFFs(i);
481     aFFi.Indices(nF1, nF2);
482     aMF.Add(nF1);
483     aMF.Add(nF2);
484   }
485   //
486   aNbF=aMF.Extent();
487   for(i=1; i<=aNbF; ++i) {
488     nF=aMF(i);
489     iRankF=myDS->Rank(nF);
490     const TopoDS_Shape aF=myDS->Shape(nF);//mpv
491     aExp.Init(aF, TopAbs_EDGE);
492     for(; aExp.More();  aExp.Next()) {
493       aE=TopoDS::Edge(aExp.Current());
494       //
495       if (BRep_Tool::Degenerated(aE)) {
496         continue;
497       }
498       //
499       nE=myDS->ShapeIndex(aE, iRankF);
500       //
501       if (aME.Contains(nE)) {
502         continue;
503       }
504       aME.Add(nE);
505       //
506       BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
507       aNbPB=aLPB.Extent();
508       if (aNbPB) {
509         continue;
510       }
511       TopExp::Vertices(aE, aV1, aV2);
512       //
513       nV1=myDS->ShapeIndex(aV1, iRankF);
514       aT1=BRep_Tool::Parameter(aV1, aE);
515       aPave1.SetIndex(nV1);
516       aPave1.SetParam(aT1);
517       //
518       nV2=myDS->ShapeIndex(aV2, iRankF);
519       aT2=BRep_Tool::Parameter(aV2, aE);
520       aPave2.SetIndex(nV2);
521       aPave2.SetParam(aT2);
522       //
523       aPB.SetEdge(nE);
524       aPB.SetOriginalEdge(nE);
525       aPB.SetPave1(aPave1);
526       aPB.SetPave2(aPave2);
527       //
528       aLPB.Append(aPB);
529     }
530   }
531 }
532
533 //=======================================================================
534 // function: MakeAloneVertices
535 // purpose:
536 //=======================================================================
537 void NMTTools_PaveFiller::MakeAloneVertices()
538 {
539   Standard_Integer i, aNbFFs, nF1, nF2, j, aNbPnts, nFx, aNbV;
540   Standard_Real aTolF1, aTolF2, aTolSum, aTolV;
541   TColStd_ListIteratorOfListOfInteger aIt;
542   TColStd_ListOfInteger aLI;
543   TopoDS_Vertex aV;
544   TopoDS_Compound aCompound;
545   BRep_Builder aBB;
546   TopTools_DataMapOfShapeListOfInteger aDMVFF, aDMVFF1;
547   TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger aItDMVFF;
548   TopTools_DataMapOfShapeShape aDMVV;
549   TopTools_DataMapOfIntegerShape aDMIV;
550   TopTools_DataMapOfShapeInteger aDMVI;
551   TopTools_DataMapIteratorOfDataMapOfShapeInteger aItDMVI;
552   TopTools_DataMapIteratorOfDataMapOfIntegerShape aItDMIV;
553   //
554   aBB.MakeCompound(aCompound);
555   //
556   myAloneVertices.Clear();
557   //
558   BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
559   //
560   // 1. Collect alone vertices from FFs
561   aNbV=0;
562   aNbFFs=aFFs.Extent();
563   for (i=1; i<=aNbFFs; ++i) {
564     BOPTools_SSInterference& aFFi=aFFs(i);
565     aFFi.Indices(nF1, nF2);
566     //
567     const TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));//mpv
568     const TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));//mpv
569     //
570     aTolF1=BRep_Tool::Tolerance(aF1);
571     aTolF2=BRep_Tool::Tolerance(aF2);
572     aTolSum=aTolF1+aTolF2;
573     //
574     aLI.Clear();
575     aLI.Append(nF1);
576     aLI.Append(nF2);
577     //
578     const IntTools_SequenceOfPntOn2Faces& aSeqAlonePnts=aFFi.AlonePnts();
579     aNbPnts=aSeqAlonePnts.Length();
580     for (j=1; j<=aNbPnts; ++j) {
581       const gp_Pnt& aP=aSeqAlonePnts(j).P1().Pnt();
582       BOPTools_Tools::MakeNewVertex(aP, aTolSum, aV);
583       aDMVFF.Bind(aV, aLI);
584       aBB.Add(aCompound, aV);
585       ++aNbV;
586     }
587   }
588   if (!aNbV) {
589     return;
590   }
591   //
592   // 2. Try to fuse alone vertices themselves;
593   FuseVertices(aCompound, aDMVV);
594   //
595   // if some are fused, replace them by new ones
596   aItDMVFF.Initialize(aDMVFF);
597   for (;  aItDMVFF.More(); aItDMVFF.Next()) {
598     const TopoDS_Shape& aVx=aItDMVFF.Key();
599     const TColStd_ListOfInteger& aLIx=aItDMVFF.Value();
600     //
601     if (!aDMVV.IsBound(aVx)) {
602       aDMVFF1.Bind(aVx, aLIx);
603     }
604     else {
605       const TopoDS_Shape& aVy=aDMVV.Find(aVx);
606
607       if (aDMVFF1.IsBound(aVy)) {
608         TColStd_ListOfInteger& aLIy=aDMVFF1.ChangeFind(aVy);
609         aIt.Initialize(aLIx);
610         for(; aIt.More(); aIt.Next()) {
611           nFx=aIt.Value();
612           aLIy.Append(nFx);
613         }
614       }
615       else {
616         aDMVFF1.Bind(aVy, aLIx);
617       }
618     }
619   }
620   aDMVFF.Clear();
621   //
622   // refine lists of faces in aDMVFF1;
623   aItDMVFF.Initialize(aDMVFF1);
624   for (;  aItDMVFF.More(); aItDMVFF.Next()) {
625     TColStd_MapOfInteger aMIy;
626     TColStd_ListOfInteger aLIy;
627     //
628     const TopoDS_Shape& aVx=aItDMVFF.Key();
629     TColStd_ListOfInteger& aLIx=aDMVFF1.ChangeFind(aVx);
630     aIt.Initialize(aLIx);
631     for(; aIt.More(); aIt.Next()) {
632       nFx=aIt.Value();
633       if (aMIy.Add(nFx)) {
634         aLIy.Append(nFx);
635       }
636     }
637     aLIx.Clear();
638     aLIx.Append(aLIy);
639   }
640   //==================================
641   //
642   // 3. Collect vertices from DS
643   Standard_Integer aNbS, nV, nVSD, aNbVDS, i1, i2, aNbVSD;
644   //
645   aNbS=myDS->NumberOfShapesOfTheObject();
646   // old shapes
647   for (i=1; i<=aNbS; ++i) {
648     const TopoDS_Shape& aS=myDS->Shape(i);
649     if (aS.ShapeType() != TopAbs_VERTEX){
650       continue;
651     }
652     //
653     nVSD=FindSDVertex(i);
654     nV=(nVSD) ? nVSD : i;
655     const TopoDS_Shape& aVx=myDS->Shape(nV);
656     if (!aDMVI.IsBound(aVx)) {
657       aDMVI.Bind(aVx, nV);
658     }
659   }
660   // new shapes
661   i1=myDS->NumberOfSourceShapes()+1;
662   i2=myDS->NumberOfInsertedShapes();
663   for (i=i1; i<=i2; ++i) {
664     const TopoDS_Shape aS=myDS->Shape(i);//mpv
665     if (aS.ShapeType() != TopAbs_VERTEX){
666       continue;
667     }
668     if (!aDMVI.IsBound(aS)) {
669       aDMVI.Bind(aS, i);
670     }
671   }
672   //
673   // 4. Initialize BoundSortBox on aDMVI
674   //
675   Handle(Bnd_HArray1OfBox) aHAB;
676   Bnd_BoundSortBox aBSB;
677   //
678   aNbVDS=aDMVI.Extent();
679   aHAB=new Bnd_HArray1OfBox(1, aNbVDS);
680   //
681   aItDMVI.Initialize(aDMVI);
682   for (i=1; aItDMVI.More(); aItDMVI.Next(), ++i) {
683     Bnd_Box aBox;
684     //
685     nV=aItDMVI.Value();
686     aV=TopoDS::Vertex(aItDMVI.Key());
687     aTolV=BRep_Tool::Tolerance(aV);
688     aBox.SetGap(aTolV);
689     BRepBndLib::Add(aV, aBox);
690     aHAB->SetValue(i, aBox);
691     //
692     aDMIV.Bind(i, aV);
693   }
694   aBSB.Initialize(aHAB);
695   //
696   // 5. Compare
697   aItDMVFF.Initialize(aDMVFF1);
698   for (;  aItDMVFF.More(); aItDMVFF.Next()) {
699     Bnd_Box aBoxV;
700     //
701     const TColStd_ListOfInteger& aLIFF=aItDMVFF.Value();
702     aV=TopoDS::Vertex(aItDMVFF.Key());
703     //
704     aTolV=BRep_Tool::Tolerance(aV);
705     aBoxV.SetGap(aTolV);
706     BRepBndLib::Add(aV, aBoxV);
707     //
708     const TColStd_ListOfInteger& aLIVSD=aBSB.Compare(aBoxV);
709     aNbVSD=aLIVSD.Extent();
710     if (aNbVSD==0) {
711       // add new vertex in DS and update map myAloneVertices
712       BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
713       //
714       myDS->InsertShapeAndAncestorsSuccessors(aV, anASSeq);
715       nV=myDS->NumberOfInsertedShapes();
716       //
717       aIt.Initialize(aLIFF);
718       for (; aIt.More(); aIt.Next()) {
719         nFx=aIt.Value();
720         if (myAloneVertices.Contains(nFx)) {
721           TColStd_IndexedMapOfInteger& aMVx=myAloneVertices.ChangeFromKey(nFx);
722           aMVx.Add(nV);
723         }
724         else {
725           TColStd_IndexedMapOfInteger aMVx;
726           aMVx.Add(nV);
727           myAloneVertices.Add(nFx, aMVx);
728         }
729       }
730     }
731   }
732   // qqf
733   {
734     Standard_Integer aNbF, aNbAV, nF, k;
735     NMTTools_IndexedDataMapOfIndexedMapOfInteger aMAVF;
736     //
737     aNbF=myAloneVertices.Extent();
738     if (aNbF<2) {
739       return;
740     }
741     //
742     // 1. fill map Alone Vertex/Face ->  aMAVF
743     for (i=1; i<=aNbF; ++i) {
744       nF=myAloneVertices.FindKey(i);
745       const TColStd_IndexedMapOfInteger& aMAV=myAloneVertices(i);
746       aNbAV=aMAV.Extent();
747       for(j=1; j<=aNbAV; ++j) {
748         nV=aMAV(j);
749         if (aMAVF.Contains(nV)) {
750           TColStd_IndexedMapOfInteger& aMF=aMAVF.ChangeFromKey(nV);
751           aMF.Add(nF);
752         }
753         else{
754           TColStd_IndexedMapOfInteger aMF;
755           aMF.Add(nF);
756           aMAVF.Add(nV, aMF);
757         }
758       }
759     }
760     //
761     // 2 Obtain pairs of faces
762     aNbAV=aMAVF.Extent();
763     for (i=1; i<=aNbAV; ++i) {
764       const TColStd_IndexedMapOfInteger& aMF=aMAVF(i);
765       aNbF=aMF.Extent();
766       for(j=1; j<aNbF; ++j) {
767         nF1=aMF(j);
768         for(k=j+1; k<=aNbF; ++k) {
769           nF2=aMF(k);
770           myIP->Add(nF1, nF2, Standard_True, NMTDS_TI_FF);
771         }
772       }
773     }
774   }
775   // qqt
776 }
777 //=======================================================================
778 // function: AloneVertices
779 // purpose:
780 //=======================================================================
781 const NMTTools_IndexedDataMapOfIndexedMapOfInteger&
782   NMTTools_PaveFiller::AloneVertices()const
783 {
784   return myAloneVertices;
785 }
786 //=======================================================================
787 // function: FuseVertices
788 // purpose:
789 //=======================================================================
790 void NMTTools_PaveFiller::FuseVertices
791   (const TopoDS_Shape& aCompound,
792    TopTools_DataMapOfShapeShape& aDMVV)const
793 {
794   Standard_Integer i, aNbVV, n1, n2, nX;
795   NMTTools_PaveFiller tPF;
796   //
797   tPF.SetCompositeShape(aCompound);
798   //
799   tPF.Init();
800   //
801   tPF.PerformVV();
802   //tPF.PerformNewVertices(); //qq
803   //
804   NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
805   NMTDS_InterfPool& tInterfPool=*(tPF.IP());
806   BOPTools_CArray1OfVVInterference& aVVt=tInterfPool.VVInterferences();
807   //
808   aNbVV=aVVt.Extent();
809   for (i=1; i<=aNbVV; ++i) {
810     const BOPTools_VVInterference& aVV=aVVt(i);
811     aVV.Indices(n1, n2);
812     nX=aVV.NewShape();
813     if (nX) {
814       const TopoDS_Shape& aV1=tDS.Shape(n1);
815       const TopoDS_Shape& aV2=tDS.Shape(n2);
816       const TopoDS_Shape& aVx=tDS.Shape(nX);
817       aDMVV.Bind(aV1, aVx);
818       aDMVV.Bind(aV2, aVx);
819     }
820   }
821 }