]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTTools/NMTTools_PaveFiller_4.cxx
Salome HOME
Remove useless and dangerous static function declaration
[modules/geom.git] / src / NMTTools / NMTTools_PaveFiller_4.cxx
1 // File:        NMTTools_PaveFiller_4.cxx
2 // Created:     Mon Dec  8 17:08:58 2003
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <NMTTools_PaveFiller.ixx>
8 //
9 #include <stdio.h>
10 #include <Precision.hxx>
11
12 #include <TColStd_MapOfInteger.hxx>
13 #include <TColStd_IndexedMapOfInteger.hxx>
14
15 #include <TopoDS.hxx>
16 #include <TopoDS_Edge.hxx>
17 #include <TopoDS_Vertex.hxx>
18 #include <TopoDS_Compound.hxx>
19
20 #include <TopTools_IndexedMapOfShape.hxx>
21
22 #include <BRep_Tool.hxx>
23 #include <BRep_Builder.hxx>
24
25 #include <Bnd_Box.hxx>
26
27 #include <IntTools_ShrunkRange.hxx>
28 #include <IntTools_Range.hxx>
29 #include <IntTools_CommonPrt.hxx>
30 #include <IntTools_SequenceOfRanges.hxx>
31 #include <IntTools_EdgeEdge.hxx>
32 #include <IntTools_SequenceOfCommonPrts.hxx>
33
34 #include <BOPTools_Pave.hxx>
35 #include <BOPTools_PaveSet.hxx>
36 #include <BOPTools_PaveBlockIterator.hxx>
37 #include <BOPTools_PaveBlock.hxx>
38 #include <BOPTools_CArray1OfEEInterference.hxx>
39 #include <BOPTools_EEInterference.hxx>
40 #include <BOPTools_ListOfPaveBlock.hxx>
41 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
42 #include <BOPTools_CArray1OfVVInterference.hxx>
43 #include <BOPTools_VVInterference.hxx>
44 #include <BOPTools_CArray1OfEEInterference.hxx>
45 #include <BOPTools_Tools.hxx>
46 #include <BOPTools_IDMapOfPaveBlockIMapOfPaveBlock.hxx>
47 #include <BOPTools_IMapOfPaveBlock.hxx>
48 #include <BOPTools_ListIteratorOfListOfPave.hxx>
49 #include <BOPTools_SequenceOfPaveBlock.hxx>
50
51 #include <BOPTColStd_Dump.hxx>
52 #include <BOPTColStd_Failure.hxx>
53
54 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
55 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
56 #include <BooleanOperations_KindOfInterference.hxx>
57
58 #include <NMTDS_ShapesDataStructure.hxx>
59
60 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
61 #include <NMTTools_ListOfCommonBlock.hxx>
62 #include <NMTTools_CommonBlock.hxx>
63 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
64
65 //
66 static 
67   void VertexParameters(const IntTools_CommonPrt& aCPart,
68                         Standard_Real& aT1, 
69                         Standard_Real& aT2);
70 static
71   Standard_Boolean IsOnPave(const Standard_Real& aT1,
72                             const IntTools_Range& aRange,
73                             const Standard_Real& aTolerance);
74 static
75   void ProcessBlock(const BOPTools_PaveBlock& aPB,
76                     const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
77                     BOPTools_IMapOfPaveBlock& aProcessedBlocks,
78                     BOPTools_IMapOfPaveBlock& aChain);
79 static
80   void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
81                   NMTTools_ListOfCommonBlock& aLCB);
82
83 //=======================================================================
84 // function: PerformEE
85 // purpose: 
86 //=======================================================================
87   void NMTTools_PaveFiller::PerformEE() 
88 {
89   myIsDone=Standard_False;
90   //
91   Standard_Boolean bJustAdd;
92   Standard_Integer n1, n2, anIndexIn, nE1, nE2, aNbVEs, aBlockLength;
93   Standard_Integer aTmp, aWhat, aWith, i, aNbCPrts, aDiscretize=30;
94   Standard_Real aTolE1, aTolE2, aDeflection=0.01;
95   BOPTools_ListIteratorOfListOfPaveBlock anIt1, anIt2;
96   TopoDS_Edge aEWhat, aEWith; 
97   TopoDS_Vertex aNewVertex;
98   BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
99   BOPTools_IDMapOfPaveBlockIMapOfPaveBlock aMapCB;
100   //
101   BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
102   //
103   // BlockLength correction
104   aNbVEs=ExpectedPoolLength();
105   aBlockLength=aEEs.BlockLength();
106   if (aNbVEs > aBlockLength) {
107     aEEs.SetBlockLength(aNbVEs);
108   }
109   //
110   myDSIt.Initialize(TopAbs_EDGE, TopAbs_EDGE);
111   //
112   for (; myDSIt.More(); myDSIt.Next()) {
113     myDSIt.Current(n1, n2, bJustAdd);
114     anIndexIn = 0;
115     //
116     if (myIntrPool->IsComputed(n1, n2)) {
117       continue;
118     }
119     //
120     nE1=n1; 
121     nE2=n2; 
122     SortTypes(nE1, nE2);
123     //
124     if(bJustAdd) {
125       myIntrPool->AddInterference (nE1, nE2, BooleanOperations_EdgeEdge, anIndexIn);
126       continue;
127     }
128     //
129     const TopoDS_Edge& aE1=TopoDS::Edge(myDS->Shape(nE1));
130     const TopoDS_Edge& aE2=TopoDS::Edge(myDS->Shape(nE2));
131     //
132     if (BRep_Tool::Degenerated(aE1) || BRep_Tool::Degenerated(aE2)){
133       continue;
134     }
135     //
136     aTolE1=BRep_Tool::Tolerance(aE1);
137     aTolE2=BRep_Tool::Tolerance(aE2);
138     //
139     BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
140     //
141     for (anIt1.Initialize(aLPB1); anIt1.More(); anIt1.Next()) {
142       BOPTools_PaveBlock& aPB1=anIt1.Value();
143       const IntTools_ShrunkRange& aShrunkRange1=aPB1.ShrunkRange();
144       //
145       const IntTools_Range& aSR1=aShrunkRange1.ShrunkRange();
146       const Bnd_Box&        aBB1=aShrunkRange1.BndBox();
147       //
148       BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
149       //
150       for (anIt2.Initialize(aLPB2); anIt2.More(); anIt2.Next()) {
151         BOPTools_PaveBlock& aPB2=anIt2.Value();
152         const IntTools_ShrunkRange& aShrunkRange2=aPB2.ShrunkRange();
153       
154         const IntTools_Range& aSR2=aShrunkRange2.ShrunkRange();
155         const Bnd_Box&        aBB2=aShrunkRange2.BndBox();
156         //
157         if (aBB1.IsOut (aBB2)) {
158           continue;
159         }
160         // 
161         // EE
162         IntTools_EdgeEdge aEE;
163         aEE.SetEdge1 (aE1);
164         aEE.SetEdge2 (aE2);
165         aEE.SetTolerance1 (aTolE1);
166         aEE.SetTolerance2 (aTolE2);
167         aEE.SetDiscretize (aDiscretize);
168         aEE.SetDeflection (aDeflection);
169         //
170         IntTools_Range anewSR1 = aSR1;
171         IntTools_Range anewSR2 = aSR2;
172         //
173         BOPTools_Tools::CorrectRange (aE1, aE2, aSR1, anewSR1);
174         BOPTools_Tools::CorrectRange (aE2, aE1, aSR2, anewSR2);
175         //
176         aEE.SetRange1(anewSR1);
177         aEE.SetRange2(anewSR2);
178           
179         aEE.Perform();
180         //
181         anIndexIn=0;
182         //
183         if (aEE.IsDone()) {
184           // reverse order if it is necessary
185           aEWhat=aE1;
186           aEWith=aE2;
187           aWhat=nE1;
188           aWith=nE2;
189           if (aEE.Order()) {
190             aTmp=aWhat;
191             aWhat=aWith;
192             aWith=aTmp;
193             aEWhat=aE2;
194             aEWith=aE1;
195           }
196           //
197           const IntTools_SequenceOfCommonPrts& aCPrts=aEE.CommonParts();
198           aNbCPrts=aCPrts.Length();
199           for (i=1; i<=aNbCPrts; i++) {
200             const IntTools_CommonPrt& aCPart=aCPrts(i);
201             const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
202             //
203             anIndexIn=0;
204             //
205             TopAbs_ShapeEnum aType=aCPart.Type();
206             switch (aType) {
207               case TopAbs_VERTEX:  {
208                 Standard_Real aT1, aT2, aTol=Precision::PConfusion();
209                 Standard_Boolean bIsOnPave1, bIsOnPave2;
210                 IntTools_Range aR1, aR2;
211                 //
212                 VertexParameters(aCPart, aT1, aT2);
213                 // 
214                 //decide to keep the pave or not
215                 aR1 = (aEE.Order()) ? anewSR2 : anewSR1;
216                 aR2 = (aEE.Order()) ? anewSR1 : anewSR2;
217                 //
218                 bIsOnPave1=IsOnPave(aT1, aR1, aTol);
219                 bIsOnPave2=IsOnPave(aT2, aR2, aTol);
220                 //
221                 if(bIsOnPave1 || bIsOnPave2) {
222                   myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
223                   continue;
224                 }
225                 //
226                 BOPTools_Tools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aNewVertex);
227                 //
228                 // Add Interference to the Pool
229                 BOPTools_EEInterference anInterf (aWhat, aWith, aCPart);
230                 //
231                 anIndexIn=aEEs.Append(anInterf);
232                 myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
233                 //
234                 // Collect
235                 aMapVI.Add(aNewVertex, anIndexIn);
236               }
237                 break;
238                 
239               case TopAbs_EDGE: {
240                 Standard_Integer aNbComPrt2;
241                 Standard_Boolean aCoinsideFlag;
242                 //
243                 aNbComPrt2=aRanges2.Length();
244                 aCoinsideFlag=IsBlocksCoinside(aPB1, aPB2);
245                 //
246                 if (aNbComPrt2>1 || !aCoinsideFlag) {
247                   myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
248                   break;
249                 }
250                 //
251                 // Fill aMapCB
252                 if (aMapCB.Contains(aPB1)) {
253                   BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB1);
254                   aMapPB.Add(aPB1); 
255                   aMapPB.Add(aPB2); 
256                 }
257                 else {
258                   BOPTools_IMapOfPaveBlock aMapPB;
259                   aMapPB.Add(aPB1); 
260                   aMapPB.Add(aPB2); 
261                   aMapCB.Add(aPB1, aMapPB);
262                 }
263                 //
264                 if (aMapCB.Contains(aPB2)) {
265                   BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB2);
266                   aMapPB.Add(aPB1); 
267                   aMapPB.Add(aPB2); 
268                 }
269                 else {
270                   BOPTools_IMapOfPaveBlock aMapPB;
271                   aMapPB.Add(aPB1); 
272                   aMapPB.Add(aPB2); 
273                   aMapCB.Add(aPB2, aMapPB);
274                 }
275               }
276                 break;
277             default:
278               break;
279             } // switch (aType) 
280           } // for (i=1; i<=aNbCPrts; i++) 
281         }// if (aEE.IsDone())
282       } // for (; anIt2.More(); anIt2.Next()) 
283     } // for (; anIt1.More(); anIt1.Next()) 
284   }// for (; myDSIt.More(); myDSIt.Next()) 
285   //
286   EENewVertices (aMapVI);
287   EECommonBlocks(aMapCB);
288   //
289   myIsDone=Standard_True;
290 }
291 //=======================================================================
292 // function:EECommonBlocks
293 // purpose: 
294 //=======================================================================
295   void NMTTools_PaveFiller::EECommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB)
296 {
297   NMTTools_ListOfCommonBlock aLCB;
298   //
299   FindChains(aMapCB, aLCB);
300   ReplaceCommonBlocks(aLCB);
301 }
302 //=======================================================================
303 // function:EENewVertices
304 // purpose: 
305 //=======================================================================
306   void NMTTools_PaveFiller::EENewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI) 
307 {
308   Standard_Integer aNb, i, j, aNewShape, aNbEdges, aNbIEE, aNbVV, aNbSimple;
309   Standard_Integer aWhat, aWith, i1, i2, nE1, nE2, nE, nV, aFlag;
310   Standard_Real aT;
311   TopoDS_Compound aCompound;
312   BRep_Builder aBB;
313   NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEE;
314   BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;       
315   BOPTools_Pave aPave;
316   TopoDS_Vertex aNewVertex;
317   TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
318   //
319   BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
320   //
321   aNb=aMapVI.Extent();
322   //
323   if (!aNb) { // no new vertices, no new problems 
324     return;
325   }
326   //
327   // 0. 
328   if (aNb==1) {
329     aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
330     EENewVertices(aNewVertex, aMapVI);
331     return;
332   }
333   //
334   // 1. Make compound from new vertices
335   aBB.MakeCompound(aCompound);
336   for (i=1; i<=aNb; ++i) {
337     const TopoDS_Shape& aV=aMapVI.FindKey(i);
338     aBB.Add(aCompound, aV);
339   }
340   //
341   // 2. VV intersection between these vertices 
342   //       using the auxiliary Filler
343   NMTDS_ShapesDataStructure tDS;
344   //
345   tDS.SetCompositeShape(aCompound);
346   tDS.Init();
347   //
348   BOPTools_InterferencePool tInterfPool(tDS);
349   NMTTools_PaveFiller tPaveFiller(tInterfPool);
350   //
351   tPaveFiller.Init();
352   //
353   tPaveFiller.PerformVV();
354   tPaveFiller.PerformNewVertices();
355   //
356   const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
357   //
358   // 3. Separate Comlex and Simple new vertices
359   aNbVV=aVVInterfs.Extent();
360   for (i=1; i<=aNbVV; ++i) {
361     const BOPTools_VVInterference& aVV=aVVInterfs(i);
362     aVV.Indices(aWhat, aWith);
363     const TopoDS_Shape& aV1=tDS.Shape(aWhat);
364     const TopoDS_Shape& aV2=tDS.Shape(aWith);
365     aMNVComplex.Add(aV1);
366     aMNVComplex.Add(aV2);
367   }
368   //
369   for (i=1; i<=aNb; ++i) {
370     const TopoDS_Shape& aV=aMapVI.FindKey(i);
371     if (!aMNVComplex.Contains(aV)) {
372       aMNVSimple.Add(aV);
373     }
374   }
375   //
376   // 4. Treat Simple new Vertices
377   aNbSimple=aMNVSimple.Extent();
378   for (i=1; i<=aNbSimple; ++i) {
379     const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
380     EENewVertices(aV, aMapVI);
381   }
382   //
383   // 3. Fill Maps : NewVertex-edges (aMNVE) 
384   //                NewVertex-interferences (aMNVIEE)
385   for (i=1; i<=aNbVV; ++i) {
386     const BOPTools_VVInterference& aVV=aVVInterfs(i);
387     aNewShape=aVV.NewShape();
388     if (!aNewShape) {
389       continue;
390     }
391     //
392     if (!aMNVE.Contains(aNewShape)) {
393       TColStd_IndexedMapOfInteger aMx;
394       aMNVE.Add(aNewShape, aMx);
395     }
396     if (!aMNVIEE.Contains(aNewShape)) {
397       TColStd_IndexedMapOfInteger aMx;
398       aMNVIEE.Add(aNewShape, aMx);
399     }
400     //
401     TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
402     TColStd_IndexedMapOfInteger& aMIEE=aMNVIEE.ChangeFromKey(aNewShape);
403     //
404     aVV.Indices(aWhat, aWith);
405     //aWhat
406     const TopoDS_Shape& aV1=tDS.Shape(aWhat);
407     i1=aMapVI.FindFromKey(aV1);
408     const BOPTools_EEInterference& aEE1=aEEs(i1);
409     aEE1.Indices(nE1, nE2);
410     aME.Add(nE1);
411     aME.Add(nE2);
412     aMIEE.Add(i1);
413     //aWith
414     const TopoDS_Shape& aV2=tDS.Shape(aWith);
415     i2=aMapVI.FindFromKey(aV2);
416     const BOPTools_EEInterference& aEE2=aEEs(i2);
417     aEE2.Indices(nE1, nE2);
418     aME.Add(nE1);
419     aME.Add(nE2);
420     aMIEE.Add(i2);
421     //
422     //printf(" VV: (%d, %d) -> %d\n", aWhat, aWith, aNewShape);
423   }
424   //
425   // 4. Process new vertices
426   aNb=aMNVE.Extent();
427   for (i=1; i<=aNb; ++i) { // xx
428     //
429     //  new Vertex
430     nV=aMNVE.FindKey(i);
431     aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
432     //
433     // Insert New Vertex in DS;
434     myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
435     aNewShape=myDS->NumberOfInsertedShapes();
436     myDS->SetState (aNewShape, BooleanOperations_ON);
437     //
438     // Update index of NewShape in EE interferences
439     const TColStd_IndexedMapOfInteger& aMIEE=aMNVIEE.FindFromKey(nV);//(i);
440     aNbIEE=aMIEE.Extent();
441     for (j=1; j<=aNbIEE; ++j) {
442       i1=aMIEE(j);
443       BOPTools_EEInterference& aEE1=aEEs(i1);
444       aEE1.SetNewShape(aNewShape);
445     }
446     // 
447     // Update Paves on edges
448     const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
449     aNbEdges=aME.Extent();
450     for (j=1; j<=aNbEdges; ++j) {
451       nE=aME(j);
452       const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
453       //
454       aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
455       //
456       if (!aFlag) {
457         aPave.SetInterference(-1);
458         aPave.SetType (BooleanOperations_EdgeEdge);
459         aPave.SetIndex(aNewShape);
460         aPave.SetParam(aT);
461         //
462         BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
463         aPaveSet.Append(aPave);
464       }
465     }
466   }// for (i=1; i<=aNb; ++i) {// xx
467 }
468 //=======================================================================
469 // function:EENewVertices
470 // purpose: 
471 //=======================================================================
472   void NMTTools_PaveFiller::EENewVertices (const TopoDS_Vertex& aNewVertex,
473                                            const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI) 
474 {
475   Standard_Integer  i, aNewShape, nE1, nE2;
476   Standard_Real  aT1, aT2;
477   BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;       
478   BOPTools_Pave aPave;
479   //
480   BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
481   //
482   // one new vertex case is treated in usual way
483   //
484   // Insert New Vertex in DS;
485   myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
486   aNewShape=myDS->NumberOfInsertedShapes();
487   myDS->SetState (aNewShape, BooleanOperations_ON);
488   // Insert New Vertex in EE Interference
489   i=aMapVI.FindFromKey(aNewVertex);
490   BOPTools_EEInterference& aEEInterf= aEEs(i);
491   aEEInterf.SetNewShape(aNewShape);
492   // Extact interference info
493   aEEInterf.Indices(nE1, nE2);
494   const IntTools_CommonPrt& aCPart=aEEInterf.CommonPrt();
495   VertexParameters(aCPart, aT1, aT2);
496   //
497   // Add Paves to the myPavePoolNew
498   aPave.SetInterference(i);
499   aPave.SetType (BooleanOperations_EdgeEdge);
500   aPave.SetIndex(aNewShape);
501   // Pave for edge nE1
502   aPave.SetParam(aT1);
503   BOPTools_PaveSet& aPaveSet1=myPavePoolNew(myDS->RefEdge(nE1));
504   aPaveSet1.Append(aPave);
505   // Pave for edge nE2
506   aPave.SetParam(aT2);
507   BOPTools_PaveSet& aPaveSet2=myPavePoolNew(myDS->RefEdge(nE2));
508   aPaveSet2.Append(aPave);
509 }
510 //=======================================================================
511 // function: RefinePavePool
512 // purpose: 
513 //=======================================================================
514   void NMTTools_PaveFiller::RefinePavePool()
515 {
516   Standard_Integer  i, aNbNew;
517
518   for (i=1; i<=myNbSources; i++) {
519
520     if ((myDS->GetShape(i)).ShapeType()==TopAbs_EDGE) {
521       BOPTools_PaveSet& aPS= myPavePool(myDS->RefEdge(i));
522       //
523       BOPTools_PaveSet& aNewPS= myPavePoolNew(myDS->RefEdge(i));
524       BOPTools_ListOfPave& aNewLP=aNewPS.ChangeSet();
525       //
526       aNbNew=aNewLP.Extent();
527       if (aNbNew) {
528         BOPTools_ListIteratorOfListOfPave anIt(aNewLP);
529         for (; anIt.More(); anIt.Next()) {
530           const BOPTools_Pave& aPave=anIt.Value();
531           aPS.Append(aPave);
532         }
533         // Clear the ListOfPaveBlock
534         BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(i));
535         aLPB.Clear();
536         // Prepare the paveBlocks for that egde again
537         PreparePaveBlocks(i);
538       }
539       aNewLP.Clear();
540     }
541   }
542 }
543 //=======================================================================
544 // function: PreparePaveBlocks
545 // purpose: 
546 //=======================================================================
547   void NMTTools_PaveFiller::PreparePaveBlocks(const TopAbs_ShapeEnum aType1, 
548                                               const TopAbs_ShapeEnum aType2)
549 {
550   myIsDone=Standard_False;
551   //
552   Standard_Boolean Ok1, Ok2, Ok3;
553   Ok1= (aType1==TopAbs_VERTEX) &&  (aType2==TopAbs_EDGE) ;
554   Ok2= (aType1==TopAbs_EDGE)   &&  (aType2==TopAbs_EDGE) ;
555   Ok3= (aType1==TopAbs_EDGE)   &&  (aType2==TopAbs_FACE) ;
556   if (!Ok1 && !Ok2 && !Ok3) {
557     // error: Type mismatch
558     return;
559   }
560   //
561   Standard_Boolean aFlag = Standard_False;
562   Standard_Integer n1, n2, nE1, nE2, aNbSplits;
563   TColStd_MapOfInteger aMap;
564   //
565   myDSIt.Initialize(aType1, aType2);
566   //
567   for (; myDSIt.More(); myDSIt.Next()) {
568     myDSIt.Current(n1, n2, aFlag);
569     nE1=n1; 
570     nE2=n2; 
571     SortTypes(nE1, nE2);
572     //
573     if (aType1==TopAbs_EDGE) {
574       BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
575       aNbSplits=aLPB1.Extent();
576       if (!aNbSplits) {
577         if (!aMap.Contains(nE1)) { 
578           aMap.Add(nE1);
579           PreparePaveBlocks(nE1);
580           //
581           if (!myIsDone) {
582             return;
583           }
584         }
585       }
586     }
587     //
588     if (aType2==TopAbs_EDGE) {
589       BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
590       aNbSplits=aLPB2.Extent();
591       if (!aNbSplits) {
592         if (!aMap.Contains(nE2)) { 
593           aMap.Add(nE2);
594           PreparePaveBlocks(nE2);
595           //
596           if (!myIsDone) {
597             return;
598           }
599         }
600       }
601     }// if (aType2==TopAbs_EDGE)
602   }// for (; myDSIt.More(); myDSIt.Next()) 
603
604   myIsDone=Standard_True;
605 }
606 //=======================================================================
607 // function: PreparePaveBlocks
608 // purpose: 
609 //=======================================================================
610   void NMTTools_PaveFiller::PreparePaveBlocks(const Standard_Integer nE)
611 {
612   myIsDone=Standard_False;
613   
614   Standard_Integer nV1, nV2;
615
616   TopoDS_Edge aE;
617   TopoDS_Vertex aV1, aV2;
618     
619   // SplitShapesPool
620   BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
621   // Edge 
622   aE=TopoDS::Edge(myDS->Shape(nE));
623   //
624   if (!BRep_Tool::Degenerated(aE)){
625     //
626     BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE));
627     
628     BOPTools_PaveBlockIterator aPBIt(nE, aPS);
629     for (; aPBIt.More(); aPBIt.Next()) {
630       BOPTools_PaveBlock& aPB=aPBIt.Value();
631       
632       const IntTools_Range& aRange=aPB.Range();
633       
634       const BOPTools_Pave& aPave1=aPB.Pave1();
635       nV1=aPave1.Index();
636       aV1=TopoDS::Vertex(myDS->GetShape(nV1));
637       
638       const BOPTools_Pave& aPave2=aPB.Pave2();
639       nV2=aPave2.Index();
640       aV2=TopoDS::Vertex(myDS->GetShape(nV2));
641       //
642       // ShrunkRange
643       IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext);
644       //
645       Standard_Integer anErrorStatus;
646       anErrorStatus=aSR.ErrorStatus();
647
648       char buf[512];
649       if (!aSR.IsDone()) {
650         sprintf (buf, "Can not obtain ShrunkRange for Edge %d\n", nE);
651         BOPTColStd_Dump::PrintMessage(buf);
652         sprintf (buf, "Can not obtain ShrunkRange for Edge %d", nE);
653         throw 
654           BOPTColStd_Failure(buf) ;
655       }
656       //
657       if (anErrorStatus==6) {
658         sprintf(buf,
659                 "Warning: [PreparePaveBlocks()] Max.Dummy Shrunk Range for Edge %d\n", nE);
660         BOPTColStd_Dump::PrintMessage(buf);
661       }
662       else {
663         // Check left paves and correct ShrunkRange if it is necessary
664         CorrectShrunkRanges (0, aPave1, aSR);
665         CorrectShrunkRanges (1, aPave2, aSR);
666       }
667       //
668       aPB.SetShrunkRange(aSR);
669       aLPB.Append(aPB);
670     } //for (; aPBIt1.More(); aPBIt1.Next()) 
671   }
672   myIsDone=Standard_True;
673 }
674 //=======================================================================
675 // function: CorrectShrunkRanges
676 // purpose: 
677 //=======================================================================
678   void NMTTools_PaveFiller::CorrectShrunkRanges(const Standard_Integer aSide,
679                                                 const BOPTools_Pave& aPave,
680                                                 IntTools_ShrunkRange& aShrunkRange)
681 {
682   BooleanOperations_KindOfInterference aType;
683   Standard_Integer anIndexInterf ;
684   //
685   aType=aPave.Type();
686   if (aType!=BooleanOperations_EdgeEdge) {
687     return;
688   }
689   //
690   anIndexInterf=aPave.Interference();
691   if (anIndexInterf<0) {
692     // it can be EE interf between E and (e1,e2,..en) -> vertex
693     // so we can't decide which aEE.CommonPrt() we should take.
694     return;
695   }
696
697   BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
698   const BOPTools_EEInterference& aEE=aEEs(anIndexInterf);
699   const IntTools_CommonPrt& aCP=aEE.CommonPrt();
700   const TopoDS_Edge& aE1=aCP.Edge1();
701   const TopoDS_Edge& aE2=aCP.Edge2();
702
703   const IntTools_Range& aSR=aShrunkRange.ShrunkRange();
704   const TopoDS_Edge& aE=aShrunkRange.Edge();
705  
706   IntTools_Range aNewRange;
707   IntTools_Range aCPRange;
708
709   if (aE1.IsSame(aE)) {
710     const IntTools_Range& aR1=aCP.Range1();
711     aCPRange=aR1;
712   }
713   if (aE2.IsSame(aE)) {
714     const IntTools_SequenceOfRanges& aSeqR=aCP.Ranges2();
715     const IntTools_Range& aR2=aSeqR(1);
716      aCPRange=aR2;
717   }
718   //
719   Standard_Real aCoeff=1.05, tV, tNV;
720   tV=aPave.Param();
721   if (aSide==0) { // Left
722     if (aCPRange.Last() > aSR.First()) {
723       tNV=aCPRange.Last();
724       tNV=tV+aCoeff*(tNV-tV);
725       aNewRange.SetFirst(tNV);
726       aNewRange.SetLast (aSR.Last());
727
728       if(aNewRange.First() > aNewRange.Last()) {
729         aShrunkRange.SetShrunkRange(aNewRange);
730       }
731     }
732   }
733   else { // Right
734     if (aCPRange.First() < aSR.Last()) {
735       tNV=aCPRange.First();
736       tNV=tV-aCoeff*(tV-tNV);
737       aNewRange.SetFirst(aSR.First());
738       aNewRange.SetLast (tNV);
739
740       if(aNewRange.First() < aNewRange.Last()) {
741         aShrunkRange.SetShrunkRange(aNewRange);
742       }
743     }
744   }
745 }
746 //=======================================================================
747 // function:  IsBlocksCoinside
748 // purpose: 
749 //=======================================================================
750   Standard_Boolean 
751     NMTTools_PaveFiller::IsBlocksCoinside(const BOPTools_PaveBlock& aPB1,
752                                           const BOPTools_PaveBlock& aPB2) const
753 {
754   Standard_Boolean bRetFlag=Standard_True;
755   Standard_Real aTolV11, aTolV12, aTolV21, aTolV22;
756   Standard_Real d1121, d1122, d1222, d1221, aTolSum, aCoeff=1.05;
757   gp_Pnt aP11, aP12, aP21, aP22;
758
759   const TopoDS_Vertex& aV11=TopoDS::Vertex(myDS->Shape(aPB1.Pave1().Index()));
760   const TopoDS_Vertex& aV12=TopoDS::Vertex(myDS->Shape(aPB1.Pave2().Index()));
761   const TopoDS_Vertex& aV21=TopoDS::Vertex(myDS->Shape(aPB2.Pave1().Index()));
762   const TopoDS_Vertex& aV22=TopoDS::Vertex(myDS->Shape(aPB2.Pave2().Index()));
763
764   aTolV11=BRep_Tool::Tolerance(aV11);
765   aTolV12=BRep_Tool::Tolerance(aV12);
766   aTolV21=BRep_Tool::Tolerance(aV21);
767   aTolV22=BRep_Tool::Tolerance(aV22);
768   
769   aP11=BRep_Tool::Pnt(aV11);
770   aP12=BRep_Tool::Pnt(aV12);
771   aP21=BRep_Tool::Pnt(aV21);
772   aP22=BRep_Tool::Pnt(aV22);
773
774   d1121=aP11.Distance(aP21);
775   aTolSum=aCoeff*(aTolV11+aTolV21);
776   if (d1121<aTolSum) {
777     d1222=aP12.Distance(aP22);
778     aTolSum=aCoeff*(aTolV12+aTolV22);
779     if (d1222<aTolSum) {
780       return bRetFlag;
781     }
782   }
783   //
784   d1122=aP11.Distance(aP22);
785   aTolSum=aCoeff*(aTolV11+aTolV22);
786   if (d1122<aTolSum) {
787     d1221=aP12.Distance(aP21);
788     aTolSum=aCoeff*(aTolV12+aTolV21);
789     if (d1221<aTolSum) {
790       return bRetFlag;
791     }
792   }
793   return !bRetFlag;
794 }
795 //=======================================================================
796 // function: ReplaceCommonBlocks
797 // purpose: 
798 //=======================================================================
799   void NMTTools_PaveFiller::ReplaceCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
800 {
801   RemoveCommonBlocks(aLCB);
802   SplitCommonBlocks(aLCB);
803 }
804 //=======================================================================
805 // function: SplitCommonBlocks
806 // purpose: 
807 //=======================================================================
808   void NMTTools_PaveFiller::SplitCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
809 {
810   Standard_Integer nE;
811   NMTTools_ListOfCommonBlock aLCBx;
812   NMTTools_ListIteratorOfListOfCommonBlock anIt, anItCBx;
813   BOPTools_ListIteratorOfListOfPaveBlock anItLPE;
814   //
815   anIt.Initialize(aLCB);
816   for (; anIt.More(); anIt.Next()) {
817     const NMTTools_CommonBlock& aCB=anIt.Value();
818     //
819     //XXX
820     aLCBx.Clear();
821     //XXX
822     SplitCommonBlock(aCB, aLCBx);
823     //
824     anItCBx.Initialize(aLCBx);
825     for (; anItCBx.More(); anItCBx.Next()) {
826       const NMTTools_CommonBlock& aCBx=anItCBx.Value();
827       const BOPTools_ListOfPaveBlock& aLPBx=aCBx.PaveBlocks();
828       //
829       anItLPE.Initialize(aLPBx);
830       for (; anItLPE.More(); anItLPE.Next()) {
831         const BOPTools_PaveBlock& aPBx=anItLPE.Value();
832         nE=aPBx.OriginalEdge();
833         NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
834         aLCBE.Append(aCBx);
835       }
836     }
837   }
838 }
839 //=======================================================================
840 // function: RemoveCommonBlocks
841 // purpose: 
842 //=======================================================================
843   void NMTTools_PaveFiller::RemoveCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
844 {
845   Standard_Integer nE;
846   NMTTools_ListOfCommonBlock aLCBx;
847   NMTTools_ListIteratorOfListOfCommonBlock anItCB, anItCBE;
848   BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
849   //
850   anItCB.Initialize(aLCB);
851   for (; anItCB.More(); anItCB.Next()) {
852     const NMTTools_CommonBlock& aCB=anItCB.Value();
853     const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
854     //
855     // Remove aCB from each edge 
856     anItLPB.Initialize(aLPB);
857     for (; anItLPB.More(); anItLPB.Next()) {
858       const BOPTools_PaveBlock& aPB=anItLPB.Value();
859       nE=aPB.OriginalEdge();
860       //
861       NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
862       anItCBE.Initialize(aLCBE);
863       for (; anItCBE.More(); anItCBE.Next()) {
864         const NMTTools_CommonBlock& aCBE=anItCBE.Value();
865         if (aCBE.IsEqual(aCB)) {
866           aLCBE.Remove(anItCBE);
867           break;
868         }
869       }
870     }
871   }
872 }
873 //=======================================================================
874 // function: SplitCommonBlock
875 // purpose: 
876 //=======================================================================
877   void NMTTools_PaveFiller::SplitCommonBlock(const NMTTools_CommonBlock& aCB,
878                                              NMTTools_ListOfCommonBlock& aLCBx)
879 {
880   Standard_Integer i, j, k, nE, aNbE, aNbSPBx, aNbPB; 
881   BOPTools_SequenceOfPaveBlock aSPBx;
882   BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
883   BOPTools_ListIteratorOfListOfPave anIt;
884   
885   BOPTools_PaveBlockIterator anPBIt; 
886   //
887   const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
888   aNbE=aLPB.Extent();
889   //
890   // 1. Whether we realy need to split the common block ?
891   anItLPB.Initialize(aLPB);
892   for (; anItLPB.More(); anItLPB.Next()) {
893     const BOPTools_PaveBlock& aPB=anItLPB.Value();
894     nE=aPB.OriginalEdge();
895     BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
896     aPSE.SortSet();
897     //
898     BOPTools_PaveSet aPSx;
899     //
900     const BOPTools_ListOfPave& aLPE=aPSE.Set();
901     anIt.Initialize(aLPE);
902     for (; anIt.More(); anIt.Next()) {
903       const BOPTools_Pave& aPx=anIt.Value();
904       if (aPB.IsInBlock(aPx)) {
905         aPSx.Append(aPx);
906       }
907     }
908     aNbPB=aPSx.Set().Extent();
909     break;
910   }
911   //
912   if (!aNbPB) {
913     // we need not split it
914     aLCBx.Append(aCB);
915     return;
916   }
917   //
918   // 2. Get sequence of pave Blocks containing all new pave blocks
919   // for each edges's source pave Block
920   anItLPB.Initialize(aLPB);
921   for (; anItLPB.More(); anItLPB.Next()) {
922     const BOPTools_PaveBlock& aPB=anItLPB.Value();
923     const BOPTools_Pave& aPave1=aPB.Pave1();
924     const BOPTools_Pave& aPave2=aPB.Pave2();
925     nE=aPB.OriginalEdge();
926     //
927     BOPTools_PaveSet aPSx;
928     //
929     // the set aPsx will contain bounadry paves aPave1, aPave2 and
930     // all paves of the edge nE that are inside block aPB
931     aPSx.Append(aPave1);
932     aPSx.Append(aPave2);
933     //
934     BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
935     aPSE.SortSet();
936     //
937     const BOPTools_ListOfPave& aLPE=aPSE.Set();
938     anIt.Initialize(aLPE);
939     for (; anIt.More(); anIt.Next()) {
940       const BOPTools_Pave& aPx=anIt.Value();
941       if (aPB.IsInBlock(aPx)) {
942         aPSx.Append(aPx);
943       }
944     }
945     //
946     // Form pave blocks from aPSx and collect them in aSPBx
947     anPBIt.Initialize(nE, aPSx);
948     for (; anPBIt.More(); anPBIt.Next()) {
949       const BOPTools_PaveBlock& aPBx=anPBIt.Value();
950       aSPBx.Append(aPBx);
951     }
952   }
953   //
954   // 3. Do new common blocks 
955   //
956   const TColStd_ListOfInteger& aLF=aCB.Faces();
957   aNbSPBx=aSPBx.Length();
958   aNbPB=aNbSPBx/aNbE;
959   //
960   for (i=1; i<=aNbPB; ++i) {
961     NMTTools_CommonBlock aCBx;
962     //
963     aCBx.AddFaces(aLF);
964     //
965     for (j=1; j<=aNbE; ++j) {
966       k=i+(j-1)*aNbPB;
967       const BOPTools_PaveBlock& aPB=aSPBx(k);
968       aCBx.AddPaveBlock(aPB);
969     }
970     aLCBx.Append(aCBx);
971   }
972 }
973
974 //=======================================================================
975 // function: VertexParameters
976 // purpose: 
977 //=======================================================================
978 void VertexParameters(const IntTools_CommonPrt& aCPart,
979                       Standard_Real& aT1, 
980                       Standard_Real& aT2)
981 {
982   const IntTools_Range& aR1=aCPart.Range1();
983   aT1=0.5*(aR1.First()+aR1.Last());
984   //
985   if((aCPart.VertexParameter1() >= aR1.First()) &&
986      (aCPart.VertexParameter1() <= aR1.Last())) {
987     aT1 = aCPart.VertexParameter1();
988   }
989   //
990   const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
991   const IntTools_Range& aR2=aRanges2(1);
992   aT2=0.5*(aR2.First()+aR2.Last());
993   //
994   if((aCPart.VertexParameter2() >= aR2.First()) &&
995      (aCPart.VertexParameter2() <= aR2.Last())) {
996     aT2 = aCPart.VertexParameter2();
997   }
998 }
999 //=======================================================================
1000 // function: KeepPave
1001 // purpose: 
1002 //=======================================================================
1003 Standard_Boolean IsOnPave(const Standard_Real& aT1,
1004                           const IntTools_Range& aRange,
1005                           const Standard_Real& aTolerance)
1006 {
1007   Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave;
1008   //
1009   firstisonpave1  = (Abs(aRange.First() - aT1) < aTolerance);
1010   firstisonpave2  = (Abs(aRange.Last()  - aT1) < aTolerance);
1011   bIsOnPave=(firstisonpave1 || firstisonpave2);
1012   return bIsOnPave;
1013 }
1014
1015 //=======================================================================
1016 // function:FindChains
1017 // purpose: 
1018 //=======================================================================
1019 void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
1020                 NMTTools_ListOfCommonBlock& aLCB)
1021 {
1022   Standard_Integer  i, j, aNbCB, aNbPB;
1023   BOPTools_IMapOfPaveBlock aProcessedBlocks, aChain;
1024   //
1025   aNbCB=aMapCB.Extent();
1026   for (i=1; i<=aNbCB; ++i) {
1027     const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
1028     if (aProcessedBlocks.Contains(aPB)) {
1029       continue;
1030     }
1031     //
1032     aProcessedBlocks.Add(aPB);
1033     aChain.Add(aPB);
1034     //
1035     const BOPTools_IMapOfPaveBlock& aMapPB=aMapCB(i);
1036     aNbPB=aMapPB.Extent();
1037     for (j=1; j<=aNbPB; ++j) {
1038       const BOPTools_PaveBlock& aPBx=aMapPB(j);
1039       ProcessBlock(aPBx, aMapCB, aProcessedBlocks, aChain);
1040     }
1041     //
1042     NMTTools_CommonBlock aCB;
1043     //
1044     aNbPB=aChain.Extent();
1045     for (j=1; j<=aNbPB; ++j) {
1046       const BOPTools_PaveBlock& aPBx=aChain(j);
1047       aCB.AddPaveBlock(aPBx);
1048     }
1049     aLCB.Append(aCB);
1050     aChain.Clear();
1051   }
1052 }
1053 //=======================================================================
1054 // function:ProcessBlock
1055 // purpose: 
1056 //=======================================================================
1057 void ProcessBlock(const BOPTools_PaveBlock& aPB,
1058                   const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
1059                   BOPTools_IMapOfPaveBlock& aProcessedBlocks,
1060                   BOPTools_IMapOfPaveBlock& aChain)
1061 {
1062   Standard_Integer j, aNbPB;
1063   //
1064   if (aProcessedBlocks.Contains(aPB)) {
1065     return;
1066   }
1067   aProcessedBlocks.Add(aPB);
1068   aChain.Add(aPB);
1069   //
1070   const BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.FindFromKey(aPB);
1071   aNbPB=aMapPB.Extent();
1072   for (j=1; j<=aNbPB; ++j) {
1073     const BOPTools_PaveBlock& aPBx=aMapPB(j);
1074     ProcessBlock(aPBx, aMapCB, aProcessedBlocks, aChain);
1075   }
1076 }