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