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