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