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