]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTTools/NMTTools_PaveFiller_4.cxx
Salome HOME
Mantis issue 0021191: GlueEdges and GlueFaces problem with tolerance 1. A fix by...
[modules/geom.git] / src / NMTTools / NMTTools_PaveFiller_4.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_4.cxx
23 //  Created:     Mon Dec  8 17:08:58 2003
24 //  Author:      Peter KURNEV
25
26 #include <NMTTools_PaveFiller.ixx>
27
28 #include <Basics_OCCTVersion.hxx>
29
30 #include <stdio.h>
31 #include <Precision.hxx>
32
33 #include <gp_XYZ.hxx>
34 #include <gp_Pnt.hxx>
35 #include <Bnd_Box.hxx>
36
37 #include <GeomAPI_ProjectPointOnCurve.hxx>
38
39 #include <TColStd_MapOfInteger.hxx>
40 #include <TColStd_IndexedMapOfInteger.hxx>
41 #include <TColStd_ListIteratorOfListOfInteger.hxx>
42 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
43
44 #include <TopoDS.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopoDS_Compound.hxx>
48
49 #include <TopTools_IndexedMapOfShape.hxx>
50 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <TopTools_DataMapOfShapeListOfShape.hxx>
53 #include <TopTools_ListOfShape.hxx>
54 #include <TopTools_DataMapOfShapeShape.hxx>
55
56 #include <BRep_Tool.hxx>
57 #include <BRep_Builder.hxx>
58 #include <BRepBndLib.hxx>
59
60 #include <BOPTColStd_Dump.hxx>
61 #include <BOPTColStd_Failure.hxx>
62
63 #include <IntTools_ShrunkRange.hxx>
64 #include <IntTools_Range.hxx>
65 #include <IntTools_CommonPrt.hxx>
66 #include <IntTools_SequenceOfRanges.hxx>
67 #include <IntTools_EdgeEdge.hxx>
68 #include <IntTools_SequenceOfCommonPrts.hxx>
69 #include <IntTools_Tools.hxx>
70
71 #include <BOPTools_Pave.hxx>
72 #include <BOPTools_PaveSet.hxx>
73 #include <BOPTools_PaveBlockIterator.hxx>
74 #include <BOPTools_PaveBlock.hxx>
75 #include <BOPTools_CArray1OfEEInterference.hxx>
76 #include <BOPTools_EEInterference.hxx>
77 #include <BOPTools_ListOfPaveBlock.hxx>
78 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
79 #include <BOPTools_CArray1OfVVInterference.hxx>
80 #include <BOPTools_VVInterference.hxx>
81 #include <BOPTools_CArray1OfEEInterference.hxx>
82 #include <BOPTools_Tools.hxx>
83 #include <BOPTools_IDMapOfPaveBlockIMapOfPaveBlock.hxx>
84 #include <BOPTools_IMapOfPaveBlock.hxx>
85 #include <BOPTools_ListIteratorOfListOfPave.hxx>
86 #include <BOPTools_SequenceOfPaveBlock.hxx>
87
88 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
89 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
90 #include <BooleanOperations_KindOfInterference.hxx>
91
92 #include <NMTDS_Iterator.hxx>
93 #include <NMTDS_ShapesDataStructure.hxx>
94 #include <NMTDS_IndexedDataMapOfIntegerShape.hxx>
95 #include <NMTDS_IndexedDataMapOfShapeBox.hxx>
96 #include <NMTDS_BoxBndTree.hxx>
97 #include <NCollection_UBTreeFiller.hxx>
98 #include <NMTDS_InterfPool.hxx>
99
100 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
101 #include <NMTTools_ListOfCommonBlock.hxx>
102 #include <NMTTools_CommonBlock.hxx>
103 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
104
105 #include <TColStd_ListOfInteger.hxx>
106 #include <TColStd_ListIteratorOfListOfInteger.hxx>
107 #include <BRepBndLib.hxx>
108 #include <BOPTools_CArray1OfVSInterference.hxx>
109 #include <BOPTools_VSInterference.hxx>
110 #include <TColStd_MapOfInteger.hxx>
111 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
112
113 static
114   void TreatNewVertices(const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI,
115                         TopTools_DataMapOfShapeListOfShape& myImages,
116                         TopTools_DataMapOfShapeShape& myOrigins);
117
118 static
119   void MakeNewVertex(const TopTools_ListOfShape& aLV,
120                      TopoDS_Vertex& aNewVertex);
121
122 static
123   void VertexParameters(const IntTools_CommonPrt& aCPart,
124                         Standard_Real& aT1,
125                         Standard_Real& aT2);
126
127 static
128   Standard_Boolean IsOnPave(const Standard_Real& aT1,
129                             const IntTools_Range& aRange,
130                             const Standard_Real& aTolerance);
131
132 // static
133 //   void EECommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB);
134
135 static
136   void ProcessBlock(const BOPTools_PaveBlock& aPB,
137                     const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
138                     BOPTools_IMapOfPaveBlock& aProcessedBlocks,
139                     BOPTools_IMapOfPaveBlock& aChain);
140
141 static
142   void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
143                   NMTTools_ListOfCommonBlock& aLCB);
144
145 //=======================================================================
146 // function: PerformEE
147 // purpose:
148 //=======================================================================
149 void NMTTools_PaveFiller::PerformEE()
150 {
151   myIsDone=Standard_False;
152   //
153   Standard_Boolean bJustAdd;
154   Standard_Integer n1, n2, anIndexIn, nE1, nE2, aNbVEs, aBlockLength;
155   Standard_Integer aTmp, aWhat, aWith, i, aNbCPrts, aDiscretize=30;
156   Standard_Integer aNbLPB1, aNbLPB2;
157   Standard_Real aTolE1, aTolE2, aDeflection=0.01;
158   BOPTools_ListIteratorOfListOfPaveBlock anIt1, anIt2;
159   TopoDS_Edge aEWhat, aEWith;
160   TopoDS_Vertex aNewVertex;
161   BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
162   BOPTools_IDMapOfPaveBlockIMapOfPaveBlock aMapCB;
163   //
164   BOPTools_CArray1OfEEInterference& aEEs=myIP->EEInterferences();
165   //
166   myDSIt->Initialize(TopAbs_EDGE, TopAbs_EDGE);
167   //
168   // BlockLength correction
169   aNbVEs=myDSIt->BlockLength();
170   aBlockLength=aEEs.BlockLength();
171   if (aNbVEs > aBlockLength) {
172     aEEs.SetBlockLength(aNbVEs);
173   }
174   //
175   for (; myDSIt->More(); myDSIt->Next()) {
176     myDSIt->Current(n1, n2, bJustAdd);
177     anIndexIn = 0;
178     nE1=n1;
179     nE2=n2;
180     //
181     if(bJustAdd) {
182       continue;
183     }
184     //
185     const TopoDS_Edge aE1=TopoDS::Edge(myDS->Shape(nE1));//mpv
186     const TopoDS_Edge aE2=TopoDS::Edge(myDS->Shape(nE2));//mpv
187     //
188     if (BRep_Tool::Degenerated(aE1) || BRep_Tool::Degenerated(aE2)){
189       continue;
190     }
191     //
192     aTolE1=BRep_Tool::Tolerance(aE1);
193     aTolE2=BRep_Tool::Tolerance(aE2);
194     //
195     BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
196     BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
197     //
198     // Modified  Thu Sep 14 14:35:18 2006
199     // Contribution of Samtech www.samcef.com BEGIN
200     aNbLPB1=aLPB1.Extent();
201     aNbLPB2=aLPB2.Extent();
202     //
203     //if (aE1.IsSame(aE2) && aNbLPB1==1 && aNbLPB2==1) {
204     //  continue;
205     //}
206     // Contribution of Samtech www.samcef.com END
207     //
208     for (anIt1.Initialize(aLPB1); anIt1.More(); anIt1.Next()) {
209       BOPTools_PaveBlock& aPB1=anIt1.Value();
210       const IntTools_ShrunkRange& aShrunkRange1=aPB1.ShrunkRange();
211       //
212       const IntTools_Range& aSR1=aShrunkRange1.ShrunkRange();
213       const Bnd_Box&        aBB1=aShrunkRange1.BndBox();
214       //
215       for (anIt2.Initialize(aLPB2); anIt2.More(); anIt2.Next()) {
216         BOPTools_PaveBlock& aPB2=anIt2.Value();
217         const IntTools_ShrunkRange& aShrunkRange2=aPB2.ShrunkRange();
218         //
219         const IntTools_Range& aSR2=aShrunkRange2.ShrunkRange();
220         const Bnd_Box&        aBB2=aShrunkRange2.BndBox();
221         //
222         if (aBB1.IsOut (aBB2)) {
223           continue;
224         }
225         //
226         // EE
227         IntTools_EdgeEdge aEE;
228         aEE.SetEdge1 (aE1);
229         aEE.SetEdge2 (aE2);
230         aEE.SetTolerance1 (aTolE1);
231         aEE.SetTolerance2 (aTolE2);
232         aEE.SetDiscretize (aDiscretize);
233         aEE.SetDeflection (aDeflection);
234         //
235         IntTools_Range anewSR1 = aSR1;
236         IntTools_Range anewSR2 = aSR2;
237         //
238         BOPTools_Tools::CorrectRange (aE1, aE2, aSR1, anewSR1);
239         BOPTools_Tools::CorrectRange (aE2, aE1, aSR2, anewSR2);
240         //
241         aEE.SetRange1(anewSR1);
242         aEE.SetRange2(anewSR2);
243         //
244         aEE.Perform();
245         //
246         anIndexIn=0;
247         //
248         if (aEE.IsDone()) {
249           // reverse order if it is necessary
250           aEWhat=aE1;
251           aEWith=aE2;
252           aWhat=nE1;
253           aWith=nE2;
254           if (aEE.Order()) {
255             aTmp=aWhat;
256             aWhat=aWith;
257             aWith=aTmp;
258             aEWhat=aE2;
259             aEWith=aE1;
260           }
261           //
262           const IntTools_SequenceOfCommonPrts& aCPrts=aEE.CommonParts();
263           aNbCPrts=aCPrts.Length();
264           for (i=1; i<=aNbCPrts; i++) {
265             const IntTools_CommonPrt& aCPart=aCPrts(i);
266             const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
267             //
268             anIndexIn=0;
269             //
270             TopAbs_ShapeEnum aType=aCPart.Type();
271             switch (aType) {
272               case TopAbs_VERTEX:  {
273                 Standard_Real aT1, aT2, aTol=Precision::PConfusion();
274                 Standard_Boolean bIsOnPave1, bIsOnPave2;
275                 IntTools_Range aR1, aR2;
276                 //
277                 VertexParameters(aCPart, aT1, aT2);
278                 //
279                 //decide to keep the pave or not
280                 aR1 = (aEE.Order()) ? anewSR2 : anewSR1;
281                 aR2 = (aEE.Order()) ? anewSR1 : anewSR2;
282                 //
283                 aTol=0.8*aTol;
284                 bIsOnPave1=IsOnPave(aT1, aR1, aTol);
285                 bIsOnPave2=IsOnPave(aT2, aR2, aTol);
286                 //
287                 if(bIsOnPave1 || bIsOnPave2) {
288                    continue;
289                 }
290                 //
291                 BOPTools_Tools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aNewVertex);
292                 //
293                 {
294                   Standard_Integer nV11, nV12, nV21, nV22, nVS[2], k, j, iFound;
295                   Standard_Real aTolVx, aTolVnew, aD2, aDT2;
296                   TColStd_MapOfInteger aMV;
297                   gp_Pnt aPnew, aPx;
298                   //
299                   iFound=0;
300                   j=-1;
301                   nV11=aPB1.Pave1().Index();
302                   nV12=aPB1.Pave2().Index();
303                   nV21=aPB2.Pave1().Index();
304                   nV22=aPB2.Pave2().Index();
305                   aMV.Add(nV11);
306                   aMV.Add(nV12);
307                   //
308                   if (aMV.Contains(nV21)) {
309                     ++j;
310                     nVS[j]=nV21;
311                   }
312                   if (aMV.Contains(nV22)) {
313                     ++j;
314                     nVS[j]=nV22;
315                   }
316                   //
317                   aTolVnew=BRep_Tool::Tolerance(aNewVertex);
318                   aPnew=BRep_Tool::Pnt(aNewVertex);
319                   //
320                   for (k=0; k<=j; ++k) {
321                     const TopoDS_Vertex& aVx=TopoDS::Vertex(myDS->Shape(nVS[k]));
322                     aTolVx=BRep_Tool::Tolerance(aVx);
323                     aPx=BRep_Tool::Pnt(aVx);
324                     aD2=aPnew.SquareDistance(aPx);
325                     //
326                     aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx);
327                     //
328                     if (aD2<aDT2) {
329                       iFound=1;
330                       break;
331                     }
332                   }
333                   //
334                   if (iFound) {
335                     continue;
336                   }
337                 }
338                 //
339                 // Add Interference to the Pool
340                 BOPTools_EEInterference anInterf (aWhat, aWith, aCPart);
341                 //
342                 anIndexIn=aEEs.Append(anInterf);
343                 // qqf
344                 {
345                   myIP->Add(aWhat, aWith, Standard_True, NMTDS_TI_EE);
346                 }
347                 // qqt
348                 //
349                 // Collect
350                 aMapVI.Add(aNewVertex, anIndexIn);
351               }
352                 break;
353
354               case TopAbs_EDGE: {
355                 Standard_Integer aNbComPrt2;
356                 Standard_Boolean aCoinsideFlag;
357                 //
358                 aNbComPrt2=aRanges2.Length();
359                 aCoinsideFlag=IsBlocksCoinside(aPB1, aPB2);
360                 //
361                 if (aNbComPrt2>1 || !aCoinsideFlag) {
362                   break;
363                 }
364                 //
365                 // Fill aMapCB
366                 if (aMapCB.Contains(aPB1)) {
367                   BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB1);
368                   aMapPB.Add(aPB1);
369                   aMapPB.Add(aPB2);
370                 }
371                 else {
372                   BOPTools_IMapOfPaveBlock aMapPB;
373                   aMapPB.Add(aPB1);
374                   aMapPB.Add(aPB2);
375                   aMapCB.Add(aPB1, aMapPB);
376                 }
377                 //
378                 if (aMapCB.Contains(aPB2)) {
379                   BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB2);
380                   aMapPB.Add(aPB1);
381                   aMapPB.Add(aPB2);
382                 }
383                 else {
384                   BOPTools_IMapOfPaveBlock aMapPB;
385                   aMapPB.Add(aPB1);
386                   aMapPB.Add(aPB2);
387                   aMapCB.Add(aPB2, aMapPB);
388                 }
389                 // qqf
390                 {
391                   myIP->Add(aWhat, aWith, Standard_True, NMTDS_TI_EE);
392                 }
393                 // qqt
394               }
395                 break;
396             default:
397               break;
398             } // switch (aType)
399           } // for (i=1; i<=aNbCPrts; i++)
400         }// if (aEE.IsDone())
401       } // for (; anIt2.More(); anIt2.Next())
402     } // for (; anIt1.More(); anIt1.Next())
403   }// for (; myDSIt.More(); myDSIt.Next())
404   //
405   {
406     NMTTools_ListOfCommonBlock aLCB;
407     //
408     FindChains(aMapCB, aLCB);
409     EENewVertices (aMapVI);
410     //TreatPaveBlocks(*this, aLCB);
411     TreatPaveBlocks(aLCB);
412     ReplaceCommonBlocks(aLCB);
413   }
414   //
415   PerformVF1();
416   //
417   myIsDone=Standard_True;
418 }
419
420 //=======================================================================
421 // function:TreatPaveBlocks
422 // purpose:
423 //=======================================================================
424 void NMTTools_PaveFiller::TreatPaveBlocks (NMTTools_ListOfCommonBlock& theLCB)
425 {
426   Standard_Boolean bFound;
427   Standard_Integer nE, nV, nVp, iFlag;
428   Standard_Real aT;
429   TColStd_MapOfInteger aMI;
430   TColStd_MapIteratorOfMapOfInteger aItMI;
431   NMTTools_ListIteratorOfListOfCommonBlock aItLCB;
432   BOPTools_ListIteratorOfListOfPaveBlock aItLPB;
433   BOPTools_ListIteratorOfListOfPave aItLP;
434   //
435   aItLCB.Initialize(theLCB);
436   for (; aItLCB.More(); aItLCB.Next()) {
437     const NMTTools_CommonBlock& aCB=aItLCB.Value();
438     //
439     aMI.Clear();
440     const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
441     //
442     // 1 -> aMI
443     aItLPB.Initialize(aLPB);
444     for (; aItLPB.More(); aItLPB.Next()) {
445       const BOPTools_PaveBlock& aPB=aItLPB.Value();
446       nE=aPB.OriginalEdge();
447       BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
448       BOPTools_ListOfPave& aLP=aPaveSet.ChangeSet();
449       //
450       aItLP.Initialize(aLP);
451       for (; aItLP.More(); aItLP.Next()) {
452         const BOPTools_Pave& aPave=aItLP.Value();
453         nV=aPave.Index();
454         aMI.Add(nV);
455       }
456     }//for (; anItLPB.More(); anItLPB.Next()) {
457     //
458     // 2
459     aItLPB.Initialize(aLPB);
460     for (; aItLPB.More(); aItLPB.Next()) {
461       const BOPTools_PaveBlock& aPB=aItLPB.Value();
462       nE=aPB.OriginalEdge();
463       BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
464       BOPTools_ListOfPave& aLP=aPaveSet.ChangeSet();
465       //
466       aItMI.Initialize(aMI);
467       for (; aItMI.More(); aItMI.Next()) {
468         nV=aItMI.Key();
469         bFound=Standard_False;
470         aItLP.Initialize(aLP);
471         for (; aItLP.More(); aItLP.Next()) {
472           const BOPTools_Pave& aPave=aItLP.Value();
473           nVp=aPave.Index();
474           if (nVp==nV) {
475             bFound=!bFound;
476             break;
477           }
478         }
479         //
480         if (!bFound) {
481           // Append Pave of nV to rhe edge nE
482           const TopoDS_Edge& aE=*(TopoDS_Edge*)(&myDS->Shape(nE));
483           const TopoDS_Vertex& aV= *(TopoDS_Vertex*)(&myDS->Shape(nV));
484 #if OCC_VERSION_LARGE > 0x06050200
485           iFlag=myContext->ComputeVE (aV, aE, aT);
486 #else
487           iFlag=myContext.ComputeVE (aV, aE, aT);
488 #endif
489           if (!iFlag) {
490             BOPTools_Pave aPave;
491             //
492             aPave.SetInterference(-1);
493             aPave.SetType (BooleanOperations_EdgeEdge);
494             aPave.SetIndex(nV);
495             aPave.SetParam(aT);
496             aPaveSet.Append(aPave);
497           }
498         }
499       }//for (; aItMI.More(); aItMI.Next()) {
500     }//for (; anItLPB.More(); anItLPB.Next()) {
501   }
502 }
503
504 //=======================================================================
505 // function:EECommonBlocks
506 // purpose:
507 //=======================================================================
508 void NMTTools_PaveFiller::EECommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB)
509 {
510   NMTTools_ListOfCommonBlock aLCB;
511   //
512   FindChains(aMapCB, aLCB);
513   ReplaceCommonBlocks(aLCB);
514 }
515
516 //=======================================================================
517 // function:EENewVertices
518 // purpose:
519 //=======================================================================
520 void NMTTools_PaveFiller::EENewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
521 {
522   Standard_Integer aNb, aNbVSD, nVnew, nIEE, nE[2], j, iFlag;
523   Standard_Real aT;
524   TopoDS_Edge aE;
525   TopTools_DataMapOfShapeListOfShape myImages;
526   TopTools_DataMapOfShapeShape myOrigins;
527   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
528   TopTools_ListIteratorOfListOfShape aIt;
529   BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
530   TColStd_MapOfInteger aMFence;
531   BOPTools_Pave aPave;
532   //
533   BOPTools_CArray1OfEEInterference& aEEs=myIP->EEInterferences();
534   //
535   aNb=aMapVI.Extent();
536   if (!aNb) { // no new vertices, no new problems
537     return;
538   }
539   //
540   // 0.
541   if (aNb==1) {
542     TopoDS_Vertex aV1=TopoDS::Vertex(aMapVI.FindKey(1));
543     EENewVertices(aV1, aMapVI);
544     return;
545   }
546   //
547   // 1.
548   TreatNewVertices(aMapVI, myImages, myOrigins);
549   //
550   aItIm.Initialize(myImages);
551   for (; aItIm.More(); aItIm.Next()) {
552     const TopoDS_Vertex& aVnew=TopoDS::Vertex(aItIm.Key());
553     const TopTools_ListOfShape& aLVSD=aItIm.Value();
554     //
555     aNbVSD=aLVSD.Extent();
556     if (aNbVSD==1) {// simple case aVnew=aVold
557       EENewVertices(aVnew, aMapVI);
558       continue;
559     }
560     //
561     // aNbVSD>1
562     myDS->InsertShapeAndAncestorsSuccessors(aVnew, anASSeq);
563     nVnew=myDS->NumberOfInsertedShapes();
564     myDS->SetState(nVnew, BooleanOperations_ON);
565     //
566     aMFence.Clear();
567     aIt.Initialize(aLVSD);
568     for (; aIt.More(); aIt.Next()) {
569       const TopoDS_Vertex& aVold=TopoDS::Vertex(aIt.Value());
570       nIEE=aMapVI.FindFromKey(aVold);
571       BOPTools_EEInterference& aEE=aEEs(nIEE);
572       aEE.Indices(nE[0], nE[1]);
573       aEE.SetNewShape(nVnew);
574       //
575       for (j=0; j<2; ++j) {
576         if (aMFence.Add(nE[j])) {
577           aE=TopoDS::Edge(myDS->Shape(nE[j]));
578 #if OCC_VERSION_LARGE > 0x06050200
579           iFlag=myContext->ComputeVE (aVnew, aE, aT);
580 #else
581           iFlag=myContext.ComputeVE (aVnew, aE, aT);
582 #endif
583           if (!iFlag) {
584             aPave.SetInterference(-1);
585             aPave.SetType (BooleanOperations_EdgeEdge);
586             aPave.SetIndex(nVnew);
587             aPave.SetParam(aT);
588             //
589             BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE[j]));
590             aPaveSet.Append(aPave);
591           }
592         }// if (aMFence.Add(nE[j])) {
593       }// for (j=0; j<2; ++j) {
594     }//for (; aIt.More(); aIt.Next()) {
595   }// for (; aItIm.More(); aItIm.Next())
596 }
597 //
598 // case: use_02
599 // completely rewritten
600 //=======================================================================
601 //function : TreatNewVertices
602 //purpose  :
603 //=======================================================================
604 void TreatNewVertices(const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI,
605                       TopTools_DataMapOfShapeListOfShape& myImages,
606                       TopTools_DataMapOfShapeShape& myOrigins)
607 {
608   Standard_Integer j, i, aNbV, aNbVSD;
609   Standard_Real aTol;
610   TColStd_ListIteratorOfListOfInteger aIt;
611   TopoDS_Shape aSTmp, aVF;
612   TopoDS_Vertex aVnew;
613   TopTools_IndexedMapOfShape aMV, aMVProcessed;
614   TopTools_ListIteratorOfListOfShape aItS;
615   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
616   TopTools_DataMapOfShapeListOfShape aMVV;
617   NMTDS_IndexedDataMapOfIntegerShape aMIS;
618   NMTDS_IndexedDataMapOfShapeBox aMSB;
619   //
620   NMTDS_BoxBndTreeSelector aSelector;
621   NMTDS_BoxBndTree aBBTree;
622   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
623   //
624   myImages.Clear();
625   myOrigins.Clear();
626   //
627   aNbV=aMapVI.Extent();
628   for (i=1; i<=aNbV; ++i) {
629     const TopoDS_Shape& aV=aMapVI.FindKey(i);
630     aMV.Add(aV);
631   }
632   //
633   for (i=1; i<=aNbV; ++i) {
634     const TopoDS_Shape& aV=aMV(i);
635     Bnd_Box aBox;
636     //
637     aTol=BRep_Tool::Tolerance(TopoDS::Vertex(aV));
638     aBox.SetGap(aTol);
639     BRepBndLib::Add(aV, aBox);
640     //
641     aTreeFiller.Add(i, aBox);
642     //
643     aMIS.Add(i, aV);
644     aMSB.Add(aV, aBox);
645   }
646   //
647   aTreeFiller.Fill();
648   //
649   // Chains
650   for (i=1; i<=aNbV; ++i) {
651     const TopoDS_Shape& aV=aMV(i);
652     //
653     if (aMVProcessed.Contains(aV)) {
654       continue;
655     }
656     //
657     Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
658     TopTools_ListOfShape aLVSD;
659     TColStd_MapOfInteger aMIP, aMIP1, aMIPC;
660     TColStd_MapIteratorOfMapOfInteger aIt1;
661     //
662     aMIP.Add(i);
663     while(1) {
664       aNbIP=aMIP.Extent();
665       aIt1.Initialize(aMIP);
666       for(; aIt1.More(); aIt1.Next()) {
667         aIP=aIt1.Key();
668         if (aMIPC.Contains(aIP)) {
669           continue;
670         }
671         //
672         const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
673         const Bnd_Box& aBoxVP=aMSB.FindFromKey(aVP);
674         //
675         aSelector.Clear();
676         aSelector.SetBox(aBoxVP);
677         //
678         aNbVSD=aBBTree.Select(aSelector);
679         if (!aNbVSD) {
680           continue;  // it must not be
681         }
682         //
683         const TColStd_ListOfInteger& aLI=aSelector.Indices();
684         aIt.Initialize(aLI);
685         for (; aIt.More(); aIt.Next()) {
686           aIP1=aIt.Value();
687           if (aMIP.Contains(aIP1)) {
688             continue;
689           }
690           aMIP1.Add(aIP1);
691         } //for (; aIt.More(); aIt.Next()) {
692       }//for(; aIt1.More(); aIt1.Next()) {
693       //
694       aNbIP1=aMIP1.Extent();
695       if (!aNbIP1) {
696         break; // from while(1)
697       }
698       //
699       aIt1.Initialize(aMIP);
700       for(; aIt1.More(); aIt1.Next()) {
701         aIP=aIt1.Key();
702         aMIPC.Add(aIP);
703       }
704       //
705       aMIP.Clear();
706       aIt1.Initialize(aMIP1);
707       for(; aIt1.More(); aIt1.Next()) {
708         aIP=aIt1.Key();
709         aMIP.Add(aIP);
710       }
711       aMIP1.Clear();
712     }// while(1)
713     //...
714     aNbIP=aMIPC.Extent();
715     if (!aNbIP) {
716       aMIPC.Add(i);
717     }
718     //
719     aIt1.Initialize(aMIPC);
720     for(j=0; aIt1.More(); aIt1.Next(), ++j) {
721       aIP=aIt1.Key();
722       const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
723       if (!j) {
724         aVF=aVP;
725       }
726       aLVSD.Append(aVP);
727       aMVProcessed.Add(aVP);
728     }
729     myImages.Bind(aVF, aLVSD);
730   }// for (i=1; i<=aNbV; ++i) {
731   //------------------------------
732   //
733   // Make new vertices
734   aMV.Clear();
735   aItIm.Initialize(myImages);
736   for (; aItIm.More(); aItIm.Next()) {
737     const TopoDS_Shape& aV=aItIm.Key();
738     const TopTools_ListOfShape& aLVSD=aItIm.Value();
739     aNbVSD=aLVSD.Extent();
740     if (aNbVSD>1) {
741       aMV.Add(aV);
742       MakeNewVertex(aLVSD, aVnew);
743       aMVV.Bind(aVnew, aLVSD);
744     }
745   }
746   //
747   // UnBind old vertices
748   aNbV=aMV.Extent();
749   for (i=1; i<=aNbV; ++i) {
750     const TopoDS_Shape& aV=aMV(i);
751     myImages.UnBind(aV);
752   }
753   //
754   // Bind new vertices
755   aItIm.Initialize(aMVV);
756   for (; aItIm.More(); aItIm.Next()) {
757     const TopoDS_Shape& aV=aItIm.Key();
758     const TopTools_ListOfShape& aLVSD=aItIm.Value();
759     myImages.Bind(aV, aLVSD);
760   }
761   //
762   // Origins
763   aItIm.Initialize(myImages);
764   for (; aItIm.More(); aItIm.Next()) {
765     const TopoDS_Shape& aV=aItIm.Key();
766     const TopTools_ListOfShape& aLVSD=aItIm.Value();
767     //
768     aItS.Initialize(aLVSD);
769     for (; aItS.More(); aItS.Next()) {
770       const TopoDS_Shape& aVSD=aItS.Value();
771       if (!myOrigins.IsBound(aVSD)) {
772         myOrigins.Bind(aVSD, aV);
773       }
774     }
775   }
776 }
777
778 //=======================================================================
779 //function : MakeNewVertex
780 //purpose  :
781 //=======================================================================
782 void MakeNewVertex(const TopTools_ListOfShape& aLV,
783                    TopoDS_Vertex& aNewVertex)
784 {
785   Standard_Integer aNbV;
786   Standard_Real aTolV, aD, aDmax;
787   gp_XYZ aGC;
788   gp_Pnt aP3D, aPGC;
789   TopoDS_Vertex aVx;
790   BRep_Builder aBB;
791   TopTools_ListIteratorOfListOfShape aIt;
792   //
793   aNbV=aLV.Extent();
794   if (!aNbV) {
795     return;
796   }
797   //
798   // center of gravity
799   aGC.SetCoord(0.,0.,0.);
800   aIt.Initialize(aLV);
801   for (; aIt.More(); aIt.Next()) {
802     aVx=TopoDS::Vertex(aIt.Value());
803     aP3D=BRep_Tool::Pnt(aVx);
804     aGC+=aP3D.XYZ();
805   }
806   aGC/=(Standard_Real)aNbV;
807   aPGC.SetXYZ(aGC);
808   //
809   // tolerance value
810   aDmax=-1.;
811   aIt.Initialize(aLV);
812   for (; aIt.More(); aIt.Next()) {
813     aVx=TopoDS::Vertex(aIt.Value());
814     aP3D=BRep_Tool::Pnt(aVx);
815     aTolV=BRep_Tool::Tolerance(aVx);
816     aD=aPGC.Distance(aP3D)+aTolV;
817     if (aD>aDmax) {
818       aDmax=aD;
819     }
820   }
821   //
822   aBB.MakeVertex (aNewVertex, aPGC, aDmax);
823 }
824
825 //=======================================================================
826 // function:EENewVertices
827 // purpose:
828 //=======================================================================
829 void NMTTools_PaveFiller::EENewVertices (const TopoDS_Vertex& aNewVertex,
830                                          const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
831 {
832   Standard_Integer  i, aNewShape, nE1, nE2;
833   Standard_Real  aT1, aT2;
834   BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
835   BOPTools_Pave aPave;
836   //
837   BOPTools_CArray1OfEEInterference& aEEs=myIP->EEInterferences();
838   //
839   // one new vertex case is treated in usual way
840   //
841   // Insert New Vertex in DS;
842   myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
843   aNewShape=myDS->NumberOfInsertedShapes();
844   myDS->SetState (aNewShape, BooleanOperations_ON);
845   // Insert New Vertex in EE Interference
846   i=aMapVI.FindFromKey(aNewVertex);
847   BOPTools_EEInterference& aEEInterf= aEEs(i);
848   aEEInterf.SetNewShape(aNewShape);
849   // Extact interference info
850   aEEInterf.Indices(nE1, nE2);
851   const IntTools_CommonPrt& aCPart=aEEInterf.CommonPrt();
852   VertexParameters(aCPart, aT1, aT2);
853   //
854   // Add Paves to the myPavePoolNew
855   aPave.SetInterference(i);
856   aPave.SetType (BooleanOperations_EdgeEdge);
857   aPave.SetIndex(aNewShape);
858   // Pave for edge nE1
859   aPave.SetParam(aT1);
860   BOPTools_PaveSet& aPaveSet1=myPavePoolNew(myDS->RefEdge(nE1));
861   aPaveSet1.Append(aPave);
862   // Pave for edge nE2
863   aPave.SetParam(aT2);
864   BOPTools_PaveSet& aPaveSet2=myPavePoolNew(myDS->RefEdge(nE2));
865   aPaveSet2.Append(aPave);
866 }
867
868 //=======================================================================
869 // function: RefinePavePool
870 // purpose:
871 //=======================================================================
872 void NMTTools_PaveFiller::RefinePavePool()
873 {
874   Standard_Integer  i, aNbNew;
875
876   for (i=1; i<=myNbSources; i++) {
877
878     if ((myDS->GetShape(i)).ShapeType()==TopAbs_EDGE) {
879       BOPTools_PaveSet& aPS= myPavePool(myDS->RefEdge(i));
880       //
881       BOPTools_PaveSet& aNewPS= myPavePoolNew(myDS->RefEdge(i));
882       BOPTools_ListOfPave& aNewLP=aNewPS.ChangeSet();
883       //
884       aNbNew=aNewLP.Extent();
885       if (aNbNew) {
886         BOPTools_ListIteratorOfListOfPave anIt(aNewLP);
887         for (; anIt.More(); anIt.Next()) {
888           const BOPTools_Pave& aPave=anIt.Value();
889           aPS.Append(aPave);
890         }
891         // Clear the ListOfPaveBlock
892         BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(i));
893         aLPB.Clear();
894         // Prepare the paveBlocks for that egde again
895         PreparePaveBlocks(i);
896       }
897       aNewLP.Clear();
898     }
899   }
900 }
901
902 //=======================================================================
903 // function: PreparePaveBlocks
904 // purpose:
905 //=======================================================================
906 void NMTTools_PaveFiller::PreparePaveBlocks(const TopAbs_ShapeEnum aType1,
907                                             const TopAbs_ShapeEnum aType2)
908 {
909   myIsDone=Standard_False;
910   //
911   Standard_Boolean bOk1, bOk2, bOk3, bFlag;
912   Standard_Integer i, aNb, nE[2], n1, n2, aNbSplits;
913   TColStd_MapOfInteger aMap;
914   //
915   bOk1= (aType1==TopAbs_VERTEX) &&  (aType2==TopAbs_EDGE) ;
916   bOk2= (aType1==TopAbs_EDGE)   &&  (aType2==TopAbs_EDGE) ;
917   bOk3= (aType1==TopAbs_EDGE)   &&  (aType2==TopAbs_FACE) ;
918   if (!bOk1 && !bOk2 && !bOk3) {// error: Type mismatch
919     return;
920   }
921   //
922   aNb=bOk2 ? 2 : 1;
923   //
924   myDSIt->Initialize(aType1, aType2);
925   for (; myDSIt->More(); myDSIt->Next()) {
926     myDSIt->Current(n1, n2, bFlag);
927     //
928     nE[0]=n1;
929     nE[1]=n2;
930     if (myDS->GetShapeType(n1)!=TopAbs_EDGE) {
931       nE[0]=n2;
932       nE[1]=n1;
933     }
934     //
935     for (i=0; i<aNb; ++i) {
936       BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE[i]));
937       aNbSplits=aLPB.Extent();
938       if (!aNbSplits) {
939         if (aMap.Add(nE[i])) {
940           PreparePaveBlocks(nE[i]);
941           if (!myIsDone) {
942             return;
943           }
944         }
945       }
946     }
947   }// for (; myDSIt.More(); myDSIt.Next())
948   myIsDone=Standard_True;
949 }
950
951 //=======================================================================
952 // function: PreparePaveBlocks
953 // purpose:
954 //=======================================================================
955 void NMTTools_PaveFiller::PreparePaveBlocks(const Standard_Integer nE)
956 {
957   myIsDone=Standard_False;
958   //
959   char buf[512];
960   Standard_Integer nV1, nV2, iErr;
961   TopoDS_Edge aE;
962   TopoDS_Vertex aV1, aV2;
963   //
964   BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
965   // Edge
966   aE=TopoDS::Edge(myDS->Shape(nE));
967   if (BRep_Tool::Degenerated(aE)) {
968     myIsDone=Standard_True;
969     return;
970   }
971   //
972   BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE));
973   //
974   BOPTools_PaveBlockIterator aPBIt(nE, aPS);
975   for (; aPBIt.More(); aPBIt.Next()) {
976     BOPTools_PaveBlock& aPB=aPBIt.Value();
977     const IntTools_Range& aRange=aPB.Range();
978     //
979     const BOPTools_Pave& aPave1=aPB.Pave1();
980     nV1=aPave1.Index();
981     aV1=TopoDS::Vertex(myDS->GetShape(nV1));
982     //
983     const BOPTools_Pave& aPave2=aPB.Pave2();
984     nV2=aPave2.Index();
985     aV2=TopoDS::Vertex(myDS->GetShape(nV2));
986     //
987     // ShrunkRange
988     IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext);
989     iErr=aSR.ErrorStatus();
990     if (!aSR.IsDone()) {
991       sprintf (buf, "Can not obtain ShrunkRange for Edge %d\n", nE);
992       BOPTColStd_Dump::PrintMessage(buf);
993       sprintf (buf, "Can not obtain ShrunkRange for Edge %d", nE);
994       throw
995         BOPTColStd_Failure(buf) ;
996     }
997     //
998     if (iErr==6) {
999       sprintf(buf,
1000               "Warning: [PreparePaveBlocks()] Max.Dummy Shrunk Range for Edge %d\n", nE);
1001       BOPTColStd_Dump::PrintMessage(buf);
1002     }
1003     else {
1004       // Check left paves and correct ShrunkRange if it is necessary
1005       CorrectShrunkRanges (0, aPave1, aSR);
1006       CorrectShrunkRanges (1, aPave2, aSR);
1007     }
1008     //
1009     aPB.SetShrunkRange(aSR);
1010     aLPB.Append(aPB);
1011   } //for (; aPBIt.More(); aPBIt.Next())
1012   myIsDone=Standard_True;
1013 }
1014
1015 //=======================================================================
1016 // function: CorrectShrunkRanges
1017 // purpose:
1018 //=======================================================================
1019 void NMTTools_PaveFiller::CorrectShrunkRanges(const Standard_Integer aSide,
1020                                               const BOPTools_Pave& aPave,
1021                                               IntTools_ShrunkRange& aShrunkRange)
1022 {
1023   BooleanOperations_KindOfInterference aType;
1024   Standard_Integer anIndexInterf ;
1025   //
1026   aType=aPave.Type();
1027   if (aType!=BooleanOperations_EdgeEdge) {
1028     return;
1029   }
1030   //
1031   anIndexInterf=aPave.Interference();
1032   if (anIndexInterf<0) {
1033     // it can be EE interf between E and (e1,e2,..en) -> vertex
1034     // so we can't decide which aEE.CommonPrt() we should take.
1035     return;
1036   }
1037
1038   BOPTools_CArray1OfEEInterference& aEEs=myIP->EEInterferences();
1039   const BOPTools_EEInterference& aEE=aEEs(anIndexInterf);
1040   const IntTools_CommonPrt& aCP=aEE.CommonPrt();
1041   const TopoDS_Edge& aE1=aCP.Edge1();
1042   const TopoDS_Edge& aE2=aCP.Edge2();
1043
1044   const IntTools_Range& aSR=aShrunkRange.ShrunkRange();
1045   const TopoDS_Edge& aE=aShrunkRange.Edge();
1046
1047   IntTools_Range aNewRange;
1048   IntTools_Range aCPRange;
1049
1050   if (aE1.IsSame(aE)) {
1051     const IntTools_Range& aR1=aCP.Range1();
1052     aCPRange=aR1;
1053   }
1054   if (aE2.IsSame(aE)) {
1055     const IntTools_SequenceOfRanges& aSeqR=aCP.Ranges2();
1056     const IntTools_Range& aR2=aSeqR(1);
1057      aCPRange=aR2;
1058   }
1059   //
1060   Standard_Real aCoeff=1.05, tV, tNV;
1061   tV=aPave.Param();
1062   if (aSide==0) { // Left
1063     if (aCPRange.Last() > aSR.First()) {
1064       tNV=aCPRange.Last();
1065       tNV=tV+aCoeff*(tNV-tV);
1066       aNewRange.SetFirst(tNV);
1067       aNewRange.SetLast (aSR.Last());
1068       if(aNewRange.First() < aNewRange.Last()) {
1069         aShrunkRange.SetShrunkRange(aNewRange);
1070       }
1071     }
1072   }
1073   else { // Right
1074     if (aCPRange.First() < aSR.Last()) {
1075       tNV=aCPRange.First();
1076       tNV=tV-aCoeff*(tV-tNV);
1077       aNewRange.SetFirst(aSR.First());
1078       aNewRange.SetLast (tNV);
1079
1080       if(aNewRange.First() < aNewRange.Last()) {
1081         aShrunkRange.SetShrunkRange(aNewRange);
1082       }
1083     }
1084   }
1085 }
1086
1087 //=======================================================================
1088 // function:  IsBlocksCoinside
1089 // purpose:
1090 //=======================================================================
1091 Standard_Boolean NMTTools_PaveFiller::IsBlocksCoinside(const BOPTools_PaveBlock& aPB1,
1092                                                        const BOPTools_PaveBlock& aPB2) const
1093 {
1094   Standard_Boolean bRetFlag=Standard_True;
1095   Standard_Real aTolV11, aTolV12, aTolV21, aTolV22;
1096   Standard_Real d1121, d1122, d1222, d1221, aTolSum, aCoeff=1.05;
1097   gp_Pnt aP11, aP12, aP21, aP22;
1098
1099   const TopoDS_Vertex aV11=TopoDS::Vertex(myDS->Shape(aPB1.Pave1().Index()));//mpv
1100   const TopoDS_Vertex aV12=TopoDS::Vertex(myDS->Shape(aPB1.Pave2().Index()));//mpv
1101   const TopoDS_Vertex aV21=TopoDS::Vertex(myDS->Shape(aPB2.Pave1().Index()));//mpv
1102   const TopoDS_Vertex aV22=TopoDS::Vertex(myDS->Shape(aPB2.Pave2().Index()));//mpv
1103
1104   aTolV11=BRep_Tool::Tolerance(aV11);
1105   aTolV12=BRep_Tool::Tolerance(aV12);
1106   aTolV21=BRep_Tool::Tolerance(aV21);
1107   aTolV22=BRep_Tool::Tolerance(aV22);
1108
1109   aP11=BRep_Tool::Pnt(aV11);
1110   aP12=BRep_Tool::Pnt(aV12);
1111   aP21=BRep_Tool::Pnt(aV21);
1112   aP22=BRep_Tool::Pnt(aV22);
1113
1114   d1121=aP11.Distance(aP21);
1115   aTolSum=aCoeff*(aTolV11+aTolV21);
1116   if (d1121<aTolSum) {
1117     d1222=aP12.Distance(aP22);
1118     aTolSum=aCoeff*(aTolV12+aTolV22);
1119     if (d1222<aTolSum) {
1120       return bRetFlag;
1121     }
1122   }
1123   //
1124   d1122=aP11.Distance(aP22);
1125   aTolSum=aCoeff*(aTolV11+aTolV22);
1126   if (d1122<aTolSum) {
1127     d1221=aP12.Distance(aP21);
1128     aTolSum=aCoeff*(aTolV12+aTolV21);
1129     if (d1221<aTolSum) {
1130       return bRetFlag;
1131     }
1132   }
1133   return !bRetFlag;
1134 }
1135
1136 //=======================================================================
1137 // function: ReplaceCommonBlocks
1138 // purpose:
1139 //=======================================================================
1140 void NMTTools_PaveFiller::ReplaceCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
1141 {
1142   RemoveCommonBlocks(aLCB);
1143   SplitCommonBlocks(aLCB);
1144 }
1145
1146 //=======================================================================
1147 // function: SplitCommonBlocks
1148 // purpose:
1149 //=======================================================================
1150 void NMTTools_PaveFiller::SplitCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
1151 {
1152   Standard_Integer nE;
1153   NMTTools_ListOfCommonBlock aLCBx;
1154   NMTTools_ListIteratorOfListOfCommonBlock anIt, anItCBx;
1155   BOPTools_ListIteratorOfListOfPaveBlock anItLPE;
1156   //
1157   anIt.Initialize(aLCB);
1158   for (; anIt.More(); anIt.Next()) {
1159     const NMTTools_CommonBlock& aCB=anIt.Value();
1160     //
1161     //XXX
1162     aLCBx.Clear();
1163     //XXX
1164     SplitCommonBlock(aCB, aLCBx);
1165     //
1166     anItCBx.Initialize(aLCBx);
1167     for (; anItCBx.More(); anItCBx.Next()) {
1168       const NMTTools_CommonBlock& aCBx=anItCBx.Value();
1169       const BOPTools_ListOfPaveBlock& aLPBx=aCBx.PaveBlocks();
1170       //
1171       anItLPE.Initialize(aLPBx);
1172       for (; anItLPE.More(); anItLPE.Next()) {
1173         const BOPTools_PaveBlock& aPBx=anItLPE.Value();
1174         nE=aPBx.OriginalEdge();
1175         NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
1176         aLCBE.Append(aCBx);
1177       }
1178     }
1179   }
1180   // Modified to provide the order of edges
1181   // in common block where the edge with max
1182   // tolerance value will be the first
1183   //  Thu Sep 14 14:35:18 2006
1184   // Contribution of Samtech www.samcef.com BEGIN
1185   Standard_Integer i, iMax, aNb, aNbCB, nSp;
1186   Standard_Real aTolSp, aTolMax;
1187   BOPTools_ListOfPaveBlock *pLPBE;
1188   //
1189   aNb=myDS->NumberOfShapesOfTheObject();
1190   for (nE=1; nE<=aNb; ++nE) {
1191     const TopoDS_Shape& aE=myDS->Shape(nE);
1192     if (aE.ShapeType()!=TopAbs_EDGE) {
1193       continue;
1194     }
1195     //
1196     NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
1197     aNbCB=aLCBE.Extent();
1198     if (!aNbCB) {
1199       continue;
1200     }
1201     //
1202     anIt.Initialize(aLCBE);
1203     for (; anIt.More(); anIt.Next()) {
1204       NMTTools_CommonBlock& aCBE=anIt.Value();
1205       const BOPTools_ListOfPaveBlock& aLPBE=aCBE.PaveBlocks();
1206       //
1207       aTolMax=-1.;
1208       anItLPE.Initialize(aLPBE);
1209       for (i=0; anItLPE.More(); anItLPE.Next(), ++i) {
1210         const BOPTools_PaveBlock& aPB=anItLPE.Value();
1211         nSp=aPB.OriginalEdge();
1212         const TopoDS_Edge& aSp=TopoDS::Edge(myDS->Shape(nSp));
1213         aTolSp=BRep_Tool::Tolerance(aSp);
1214         if (aTolSp>aTolMax) {
1215           iMax=i;
1216           aTolSp=aTolMax;
1217         }
1218       }
1219       //
1220       BOPTools_ListOfPaveBlock aLPBx;
1221       //
1222       anItLPE.Initialize(aLPBE);
1223       for (i=0; anItLPE.More(); anItLPE.Next(), ++i) {
1224         const BOPTools_PaveBlock& aPB=anItLPE.Value();
1225         if (i==iMax) {
1226           aLPBx.Prepend(aPB);
1227         }
1228         else {
1229           aLPBx.Append(aPB);
1230         }
1231       }
1232       //
1233       pLPBE=(BOPTools_ListOfPaveBlock *)&aLPBE;
1234       pLPBE->Clear();
1235       pLPBE->Append(aLPBx);
1236     }//for (; anIt.More(); anIt.Next()) {
1237   }//for (nE=1; nE<=aNb; ++nE) {
1238   // Contribution of Samtech www.samcef.com END
1239 }
1240
1241 //=======================================================================
1242 // function: RemoveCommonBlocks
1243 // purpose:
1244 //=======================================================================
1245 void NMTTools_PaveFiller::RemoveCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
1246 {
1247   Standard_Integer nE;
1248   NMTTools_ListOfCommonBlock aLCBx;
1249   NMTTools_ListIteratorOfListOfCommonBlock anItCB, anItCBE;
1250   BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
1251   //
1252   anItCB.Initialize(aLCB);
1253   for (; anItCB.More(); anItCB.Next()) {
1254     const NMTTools_CommonBlock& aCB=anItCB.Value();
1255     const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
1256     //
1257     // Remove aCB from each edge
1258     anItLPB.Initialize(aLPB);
1259     for (; anItLPB.More(); anItLPB.Next()) {
1260       const BOPTools_PaveBlock& aPB=anItLPB.Value();
1261       nE=aPB.OriginalEdge();
1262       //
1263       NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
1264       anItCBE.Initialize(aLCBE);
1265       for (; anItCBE.More(); anItCBE.Next()) {
1266         const NMTTools_CommonBlock& aCBE=anItCBE.Value();
1267         if (aCBE.IsEqual(aCB)) {
1268           aLCBE.Remove(anItCBE);
1269           break;
1270         }
1271       }
1272     }
1273   }
1274 }
1275
1276 //=======================================================================
1277 // function: SplitCommonBlock
1278 // purpose:
1279 //=======================================================================
1280 void NMTTools_PaveFiller::SplitCommonBlock(const NMTTools_CommonBlock& aCB,
1281                                            NMTTools_ListOfCommonBlock& aLCBx)
1282 {
1283   Standard_Boolean bIsCoincided;
1284   Standard_Integer i, j,nE, aNbE, aNbSPBx, aNbPB, k;
1285   BOPTools_SequenceOfPaveBlock aSPBx;
1286   BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
1287   BOPTools_ListIteratorOfListOfPave anIt;
1288   BOPTools_PaveBlockIterator anPBIt;
1289   //
1290   const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
1291   aNbE=aLPB.Extent();
1292   //
1293   // 1. Checking: Whether we realy need to split the common block ?
1294   anItLPB.Initialize(aLPB);
1295   for (; anItLPB.More(); anItLPB.Next()) {
1296     const BOPTools_PaveBlock& aPB=anItLPB.Value();
1297     nE=aPB.OriginalEdge();
1298     BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
1299     aPSE.SortSet();
1300     //
1301     BOPTools_PaveSet aPSx;
1302     //
1303     const BOPTools_ListOfPave& aLPE=aPSE.Set();
1304     anIt.Initialize(aLPE);
1305     for (; anIt.More(); anIt.Next()) {
1306       const BOPTools_Pave& aPx=anIt.Value();
1307       if (aPB.IsInBlock(aPx)) {
1308         aPSx.Append(aPx);
1309       }
1310     }
1311     aNbPB=aPSx.Set().Extent();
1312     break;
1313   }
1314   //
1315   if (!aNbPB) {
1316     // we need not split it
1317     aLCBx.Append(aCB);
1318     return;
1319   }
1320   //
1321   // 2. Get sequence of pave Blocks containing all new pave blocks
1322   // for each edges's source pave Block
1323   anItLPB.Initialize(aLPB);
1324   for (; anItLPB.More(); anItLPB.Next()) {
1325     const BOPTools_PaveBlock& aPB=anItLPB.Value();
1326     const BOPTools_Pave& aPave1=aPB.Pave1();
1327     const BOPTools_Pave& aPave2=aPB.Pave2();
1328     nE=aPB.OriginalEdge();
1329     //
1330     BOPTools_PaveSet aPSx;
1331     //
1332     // the set aPsx will contain bounadry paves aPave1, aPave2 and
1333     // all paves of the edge nE that are inside block aPB
1334     aPSx.Append(aPave1);
1335     aPSx.Append(aPave2);
1336     //
1337     BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
1338     aPSE.SortSet();
1339     //
1340     const BOPTools_ListOfPave& aLPE=aPSE.Set();
1341     anIt.Initialize(aLPE);
1342     for (; anIt.More(); anIt.Next()) {
1343       const BOPTools_Pave& aPx=anIt.Value();
1344       if (aPB.IsInBlock(aPx)) {
1345         aPSx.Append(aPx);
1346       }
1347     }
1348     //
1349     // Form pave blocks from aPSx and collect them in aSPBx
1350     anPBIt.Initialize(nE, aPSx);
1351     for (; anPBIt.More(); anPBIt.Next()) {
1352       const BOPTools_PaveBlock& aPBx=anPBIt.Value();
1353       aSPBx.Append(aPBx);
1354     }
1355   }
1356   //
1357   // 3. Do new common blocks
1358   //
1359   const TColStd_ListOfInteger& aLF=aCB.Faces();
1360   aNbSPBx=aSPBx.Length();
1361   aNbPB=aNbSPBx/aNbE;
1362   //
1363   Standard_Integer k1, k2, n11, n12, n21, n22;
1364   //
1365   for (i=1; i<=aNbPB; ++i) {
1366     NMTTools_CommonBlock aCBx;
1367     //
1368     aCBx.AddFaces(aLF);
1369     //
1370     const BOPTools_PaveBlock& aPB1=aSPBx(i);
1371     n11=aPB1.Pave1().Index();
1372     n12=aPB1.Pave2().Index();
1373     //
1374     aCBx.AddPaveBlock(aPB1);
1375     //
1376     for (j=2; j<=aNbE; ++j) {
1377       k1=(j-1)*aNbPB+1;
1378       k2=k1+aNbPB-1;
1379       for(k=k1; k<=k2; ++k) {
1380         const BOPTools_PaveBlock& aPB2=aSPBx(k);
1381         n21=aPB2.Pave1().Index();
1382         n22=aPB2.Pave2().Index();
1383         if ((n21==n11 && n22==n12) || (n21==n12 && n22==n11)) {
1384           //modified by NIZNHY-PKV Thu Nov 11 08:13:24 2010f
1385           bIsCoincided=CheckCoincidence(aPB2, aPB1);
1386           if (bIsCoincided) {
1387             aCBx.AddPaveBlock(aPB2);
1388             break;
1389           }
1390           //aCBx.AddPaveBlock(aPB2);
1391           //break;
1392           //modified by NIZNHY-PKV Thu Nov 11 08:13:31 2010t
1393         }
1394       }
1395     }
1396     aLCBx.Append(aCBx);
1397   }
1398 }
1399
1400 //=======================================================================
1401 // function: VertexParameters
1402 // purpose:
1403 //=======================================================================
1404 void VertexParameters(const IntTools_CommonPrt& aCPart,
1405                       Standard_Real& aT1,
1406                       Standard_Real& aT2)
1407 {
1408   const IntTools_Range& aR1=aCPart.Range1();
1409   aT1=0.5*(aR1.First()+aR1.Last());
1410   //
1411   if((aCPart.VertexParameter1() >= aR1.First()) &&
1412      (aCPart.VertexParameter1() <= aR1.Last())) {
1413     aT1 = aCPart.VertexParameter1();
1414   }
1415   //
1416   const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
1417   const IntTools_Range& aR2=aRanges2(1);
1418   aT2=0.5*(aR2.First()+aR2.Last());
1419   //
1420   if((aCPart.VertexParameter2() >= aR2.First()) &&
1421      (aCPart.VertexParameter2() <= aR2.Last())) {
1422     aT2 = aCPart.VertexParameter2();
1423   }
1424 }
1425
1426 //=======================================================================
1427 // function: KeepPave
1428 // purpose:
1429 //=======================================================================
1430 Standard_Boolean IsOnPave(const Standard_Real& aT1,
1431                           const IntTools_Range& aRange,
1432                           const Standard_Real& aTolerance)
1433 {
1434   Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave;
1435   //
1436   firstisonpave1  = (Abs(aRange.First() - aT1) < aTolerance);
1437   firstisonpave2  = (Abs(aRange.Last()  - aT1) < aTolerance);
1438   bIsOnPave=(firstisonpave1 || firstisonpave2);
1439   return bIsOnPave;
1440 }
1441
1442 //=======================================================================
1443 // function:FindChains
1444 // purpose:
1445 //=======================================================================
1446 void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
1447                 NMTTools_ListOfCommonBlock& aLCB)
1448 {
1449   Standard_Integer  i, j, aNbCB, aNbPB;
1450   BOPTools_IMapOfPaveBlock aProcessedBlocks, aChain;
1451   //
1452   aNbCB=aMapCB.Extent();
1453   for (i=1; i<=aNbCB; ++i) {
1454     const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
1455     if (aProcessedBlocks.Contains(aPB)) {
1456       continue;
1457     }
1458     //
1459     aProcessedBlocks.Add(aPB);
1460     aChain.Add(aPB);
1461     //
1462     const BOPTools_IMapOfPaveBlock& aMapPB=aMapCB(i);
1463     aNbPB=aMapPB.Extent();
1464     for (j=1; j<=aNbPB; ++j) {
1465       const BOPTools_PaveBlock& aPBx=aMapPB(j);
1466       ProcessBlock(aPBx, aMapCB, aProcessedBlocks, aChain);
1467     }
1468     //
1469     NMTTools_CommonBlock aCB;
1470     //
1471     aNbPB=aChain.Extent();
1472     for (j=1; j<=aNbPB; ++j) {
1473       const BOPTools_PaveBlock& aPBx=aChain(j);
1474       aCB.AddPaveBlock(aPBx);
1475     }
1476     aLCB.Append(aCB);
1477     aChain.Clear();
1478   }
1479 }
1480
1481 //=======================================================================
1482 // function:ProcessBlock
1483 // purpose:
1484 //=======================================================================
1485 void ProcessBlock(const BOPTools_PaveBlock& aPB,
1486                   const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
1487                   BOPTools_IMapOfPaveBlock& aProcessedBlocks,
1488                   BOPTools_IMapOfPaveBlock& aChain)
1489 {
1490   Standard_Integer j, aNbPB;
1491   //
1492   if (aProcessedBlocks.Contains(aPB)) {
1493     return;
1494   }
1495   aProcessedBlocks.Add(aPB);
1496   aChain.Add(aPB);
1497   //
1498   const BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.FindFromKey(aPB);
1499   aNbPB=aMapPB.Extent();
1500   for (j=1; j<=aNbPB; ++j) {
1501     const BOPTools_PaveBlock& aPBx=aMapPB(j);
1502     ProcessBlock(aPBx, aMapCB, aProcessedBlocks, aChain);
1503   }
1504 }
1505 // Modified  to provide VS interference between
1506 // vertex as result of EE and a Face of argument
1507 // Thu Sep 14 14:35:18 2006
1508 // Contribution of Samtech www.samcef.com BEGIN
1509 //=======================================================================
1510 // function: PerformVF1
1511 // purpose:
1512 //=======================================================================
1513   void NMTTools_PaveFiller::PerformVF1()
1514 {
1515   Standard_Integer i, aNbEE, n1, n2, nNewShape, aNbS, nF;
1516   Standard_Integer anIndexIn, aFlag;
1517   Standard_Real aU, aV;
1518   TColStd_ListOfInteger aLFI;
1519   TColStd_ListIteratorOfListOfInteger aItLFI;
1520   //
1521   BOPTools_CArray1OfVSInterference& aVSs=myIP->VSInterferences();
1522   BOPTools_CArray1OfEEInterference& aEEs=myIP->EEInterferences();
1523   //
1524   aNbS=myDS->NumberOfShapesOfTheObject();
1525   for (i=1; i<=aNbS; ++i) {
1526     const TopoDS_Shape& aF=myDS->Shape(i);
1527     if (aF.ShapeType()==TopAbs_FACE) {
1528       aLFI.Append(i);
1529     }
1530   }
1531   if (!aLFI.Extent()) {
1532     return;
1533   }
1534   //
1535   aNbEE=aEEs.Extent();
1536   for (i=1; i<=aNbEE; ++i) {
1537     BOPTools_EEInterference& aEE=aEEs(i);
1538     aEE.Indices(n1, n2);
1539     nNewShape=aEE.NewShape();
1540     if (!nNewShape) {
1541       continue;
1542     }
1543     //
1544     const TopoDS_Shape& aSnew=myDS->Shape(nNewShape);
1545     if (aSnew.ShapeType()!=TopAbs_VERTEX) {
1546       continue;
1547     }
1548     //
1549     const TopoDS_Vertex& aVnew=TopoDS::Vertex(aSnew);
1550     //
1551     Bnd_Box aBV;
1552     //
1553     BRepBndLib::Add(aVnew, aBV);
1554     //
1555     aItLFI.Initialize(aLFI);
1556     for (; aItLFI.More(); aItLFI.Next()) {
1557       nF=aItLFI.Value();
1558       //
1559       const TopoDS_Face& aF=TopoDS::Face(myDS->Shape(nF));
1560       const Bnd_Box& aBF=myDS->GetBoundingBox(nF);
1561       if (aBF.IsOut(aBV)) {
1562         continue;
1563       }
1564       //
1565       anIndexIn=0;
1566 #if OCC_VERSION_LARGE > 0x06050200
1567       aFlag=myContext->ComputeVS (aVnew, aF, aU, aV);
1568 #else
1569       aFlag=myContext.ComputeVS (aVnew, aF, aU, aV);
1570 #endif
1571       if (!aFlag) {
1572         BOPTools_VSInterference anInterf (nNewShape, nF, aU, aV);
1573         //
1574         anIndexIn=aVSs.Append(anInterf);
1575         BOPTools_VSInterference& aVS=aVSs(anIndexIn);
1576         aVS.SetNewShape(nNewShape);//->
1577       }
1578     }
1579   }
1580 }
1581 // Contribution of Samtech www.samcef.com END
1582 //modified by NIZNHY-PKV Thu Nov 11 08:13:48 2010f
1583 //=======================================================================
1584 // function: CheckCoincidence
1585 // purpose:
1586 //=======================================================================
1587 Standard_Boolean NMTTools_PaveFiller::CheckCoincidence(const BOPTools_PaveBlock& aPB1,
1588                                                        const BOPTools_PaveBlock& aPB2)
1589 {
1590   Standard_Boolean bRet;
1591   Standard_Integer nE1, nE2, aNbPoints;
1592   Standard_Real aT11, aT12, aT21, aT22, aT1m, aD, aTol, aT2x;
1593   gp_Pnt aP1m;
1594   //
1595   bRet=Standard_False;
1596   //
1597   aT11=aPB1.Pave1().Param();
1598   aT12=aPB1.Pave2().Param();
1599   aT1m=IntTools_Tools::IntermediatePoint (aT11, aT12);
1600   nE1=aPB1.OriginalEdge();
1601   const TopoDS_Edge& aE1=(*(TopoDS_Edge*)(&myDS->Shape(nE1)));
1602   BOPTools_Tools::PointOnEdge(aE1, aT1m, aP1m);
1603   //
1604   aT21=aPB2.Pave1().Param();
1605   aT22=aPB2.Pave2().Param();
1606   nE2=aPB2.OriginalEdge();
1607   const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&myDS->Shape(nE2)));
1608   //
1609 #if OCC_VERSION_LARGE > 0x06050200
1610   GeomAPI_ProjectPointOnCurve& aPPC=myContext->ProjPC(aE2);
1611 #else
1612   GeomAPI_ProjectPointOnCurve& aPPC=myContext.ProjPC(aE2);
1613 #endif
1614   aPPC.Perform(aP1m);
1615   aNbPoints=aPPC.NbPoints();
1616   if (aNbPoints) {
1617     aD=aPPC.LowerDistance();
1618     //
1619     aTol=BRep_Tool::Tolerance(aE1);
1620     aTol=aTol+BRep_Tool::Tolerance(aE2);
1621     if (aD<aTol) {
1622       aT2x=aPPC.LowerDistanceParameter();
1623       if (aT2x>aT21 && aT2x<aT22) {
1624         return !bRet;
1625       }
1626     }
1627   }
1628   return bRet;
1629 }
1630 //modified by NIZNHY-PKV Thu Nov 11 08:13:55 2010t