1 // File: NMTTools_PaveFiller_4.cxx
2 // Created: Mon Dec 8 17:08:58 2003
3 // Author: Peter KURNEV
7 #include <NMTTools_PaveFiller.ixx>
10 #include <Precision.hxx>
12 #include <TColStd_MapOfInteger.hxx>
13 #include <TColStd_IndexedMapOfInteger.hxx>
16 #include <TopoDS_Edge.hxx>
17 #include <TopoDS_Vertex.hxx>
18 #include <TopoDS_Compound.hxx>
20 #include <TopTools_IndexedMapOfShape.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRep_Builder.hxx>
25 #include <Bnd_Box.hxx>
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>
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>
51 #include <BOPTColStd_Dump.hxx>
52 #include <BOPTColStd_Failure.hxx>
54 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
55 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
56 #include <BooleanOperations_KindOfInterference.hxx>
58 #include <NMTDS_ShapesDataStructure.hxx>
60 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
61 #include <NMTTools_ListOfCommonBlock.hxx>
62 #include <NMTTools_CommonBlock.hxx>
63 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
67 void VertexParameters(const IntTools_CommonPrt& aCPart,
71 Standard_Boolean IsOnPave(const Standard_Real& aT1,
72 const IntTools_Range& aRange,
73 const Standard_Real& aTolerance);
75 void ProcessBlock(const BOPTools_PaveBlock& aPB,
76 const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
77 BOPTools_IMapOfPaveBlock& aProcessedBlocks,
78 BOPTools_IMapOfPaveBlock& aChain);
80 void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
81 NMTTools_ListOfCommonBlock& aLCB);
83 //=======================================================================
84 // function: PerformEE
86 //=======================================================================
87 void NMTTools_PaveFiller::PerformEE()
89 myIsDone=Standard_False;
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;
101 BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
103 // BlockLength correction
104 aNbVEs=ExpectedPoolLength();
105 aBlockLength=aEEs.BlockLength();
106 if (aNbVEs > aBlockLength) {
107 aEEs.SetBlockLength(aNbVEs);
110 myDSIt.Initialize(TopAbs_EDGE, TopAbs_EDGE);
112 for (; myDSIt.More(); myDSIt.Next()) {
113 myDSIt.Current(n1, n2, bJustAdd);
116 if (myIntrPool->IsComputed(n1, n2)) {
125 myIntrPool->AddInterference (nE1, nE2, BooleanOperations_EdgeEdge, anIndexIn);
129 const TopoDS_Edge& aE1=TopoDS::Edge(myDS->Shape(nE1));
130 const TopoDS_Edge& aE2=TopoDS::Edge(myDS->Shape(nE2));
132 if (BRep_Tool::Degenerated(aE1) || BRep_Tool::Degenerated(aE2)){
136 aTolE1=BRep_Tool::Tolerance(aE1);
137 aTolE2=BRep_Tool::Tolerance(aE2);
139 BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
141 for (anIt1.Initialize(aLPB1); anIt1.More(); anIt1.Next()) {
142 BOPTools_PaveBlock& aPB1=anIt1.Value();
143 const IntTools_ShrunkRange& aShrunkRange1=aPB1.ShrunkRange();
145 const IntTools_Range& aSR1=aShrunkRange1.ShrunkRange();
146 const Bnd_Box& aBB1=aShrunkRange1.BndBox();
148 BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
150 for (anIt2.Initialize(aLPB2); anIt2.More(); anIt2.Next()) {
151 BOPTools_PaveBlock& aPB2=anIt2.Value();
152 const IntTools_ShrunkRange& aShrunkRange2=aPB2.ShrunkRange();
154 const IntTools_Range& aSR2=aShrunkRange2.ShrunkRange();
155 const Bnd_Box& aBB2=aShrunkRange2.BndBox();
157 if (aBB1.IsOut (aBB2)) {
162 IntTools_EdgeEdge aEE;
165 aEE.SetTolerance1 (aTolE1);
166 aEE.SetTolerance2 (aTolE2);
167 aEE.SetDiscretize (aDiscretize);
168 aEE.SetDeflection (aDeflection);
170 IntTools_Range anewSR1 = aSR1;
171 IntTools_Range anewSR2 = aSR2;
173 BOPTools_Tools::CorrectRange (aE1, aE2, aSR1, anewSR1);
174 BOPTools_Tools::CorrectRange (aE2, aE1, aSR2, anewSR2);
176 aEE.SetRange1(anewSR1);
177 aEE.SetRange2(anewSR2);
184 // reverse order if it is necessary
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();
205 TopAbs_ShapeEnum aType=aCPart.Type();
207 case TopAbs_VERTEX: {
208 Standard_Real aT1, aT2, aTol=Precision::PConfusion();
209 Standard_Boolean bIsOnPave1, bIsOnPave2;
210 IntTools_Range aR1, aR2;
212 VertexParameters(aCPart, aT1, aT2);
214 //decide to keep the pave or not
215 aR1 = (aEE.Order()) ? anewSR2 : anewSR1;
216 aR2 = (aEE.Order()) ? anewSR1 : anewSR2;
218 bIsOnPave1=IsOnPave(aT1, aR1, aTol);
219 bIsOnPave2=IsOnPave(aT2, aR2, aTol);
221 if(bIsOnPave1 || bIsOnPave2) {
222 myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
226 BOPTools_Tools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aNewVertex);
228 // Add Interference to the Pool
229 BOPTools_EEInterference anInterf (aWhat, aWith, aCPart);
231 anIndexIn=aEEs.Append(anInterf);
232 myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
235 aMapVI.Add(aNewVertex, anIndexIn);
240 Standard_Integer aNbComPrt2;
241 Standard_Boolean aCoinsideFlag;
243 aNbComPrt2=aRanges2.Length();
244 aCoinsideFlag=IsBlocksCoinside(aPB1, aPB2);
246 if (aNbComPrt2>1 || !aCoinsideFlag) {
247 myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
252 if (aMapCB.Contains(aPB1)) {
253 BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB1);
258 BOPTools_IMapOfPaveBlock aMapPB;
261 aMapCB.Add(aPB1, aMapPB);
264 if (aMapCB.Contains(aPB2)) {
265 BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB2);
270 BOPTools_IMapOfPaveBlock aMapPB;
273 aMapCB.Add(aPB2, aMapPB);
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())
286 EENewVertices (aMapVI);
287 EECommonBlocks(aMapCB);
289 myIsDone=Standard_True;
291 //=======================================================================
292 // function:EECommonBlocks
294 //=======================================================================
295 void NMTTools_PaveFiller::EECommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB)
297 NMTTools_ListOfCommonBlock aLCB;
299 FindChains(aMapCB, aLCB);
300 ReplaceCommonBlocks(aLCB);
302 //=======================================================================
303 // function:EENewVertices
305 //=======================================================================
306 void NMTTools_PaveFiller::EENewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
308 Standard_Integer aNb, i, j, aNewShape, aNbEdges, aNbIEE, aNbVV, aNbSimple;
309 Standard_Integer aWhat, aWith, i1, i2, nE1, nE2, nE, nV, aFlag;
311 TopoDS_Compound aCompound;
313 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEE;
314 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
316 TopoDS_Vertex aNewVertex;
317 TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
319 BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
323 if (!aNb) { // no new vertices, no new problems
329 aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
330 EENewVertices(aNewVertex, aMapVI);
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);
341 // 2. VV intersection between these vertices
342 // using the auxiliary Filler
343 NMTDS_ShapesDataStructure tDS;
345 tDS.SetCompositeShape(aCompound);
348 BOPTools_InterferencePool tInterfPool(tDS);
349 NMTTools_PaveFiller tPaveFiller(tInterfPool);
353 tPaveFiller.PerformVV();
354 tPaveFiller.PerformNewVertices();
356 const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
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);
369 for (i=1; i<=aNb; ++i) {
370 const TopoDS_Shape& aV=aMapVI.FindKey(i);
371 if (!aMNVComplex.Contains(aV)) {
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);
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();
392 if (!aMNVE.Contains(aNewShape)) {
393 TColStd_IndexedMapOfInteger aMx;
394 aMNVE.Add(aNewShape, aMx);
396 if (!aMNVIEE.Contains(aNewShape)) {
397 TColStd_IndexedMapOfInteger aMx;
398 aMNVIEE.Add(aNewShape, aMx);
401 TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
402 TColStd_IndexedMapOfInteger& aMIEE=aMNVIEE.ChangeFromKey(aNewShape);
404 aVV.Indices(aWhat, aWith);
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);
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);
422 //printf(" VV: (%d, %d) -> %d\n", aWhat, aWith, aNewShape);
425 // 4. Process new vertices
427 for (i=1; i<=aNb; ++i) { // xx
431 aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
433 // Insert New Vertex in DS;
434 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
435 aNewShape=myDS->NumberOfInsertedShapes();
436 myDS->SetState (aNewShape, BooleanOperations_ON);
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) {
443 BOPTools_EEInterference& aEE1=aEEs(i1);
444 aEE1.SetNewShape(aNewShape);
447 // Update Paves on edges
448 const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
449 aNbEdges=aME.Extent();
450 for (j=1; j<=aNbEdges; ++j) {
452 const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
454 aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
457 aPave.SetInterference(-1);
458 aPave.SetType (BooleanOperations_EdgeEdge);
459 aPave.SetIndex(aNewShape);
462 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
463 aPaveSet.Append(aPave);
466 }// for (i=1; i<=aNb; ++i) {// xx
468 //=======================================================================
469 // function:EENewVertices
471 //=======================================================================
472 void NMTTools_PaveFiller::EENewVertices (const TopoDS_Vertex& aNewVertex,
473 const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
475 Standard_Integer i, aNewShape, nE1, nE2;
476 Standard_Real aT1, aT2;
477 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
480 BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
482 // one new vertex case is treated in usual way
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);
497 // Add Paves to the myPavePoolNew
498 aPave.SetInterference(i);
499 aPave.SetType (BooleanOperations_EdgeEdge);
500 aPave.SetIndex(aNewShape);
503 BOPTools_PaveSet& aPaveSet1=myPavePoolNew(myDS->RefEdge(nE1));
504 aPaveSet1.Append(aPave);
507 BOPTools_PaveSet& aPaveSet2=myPavePoolNew(myDS->RefEdge(nE2));
508 aPaveSet2.Append(aPave);
510 //=======================================================================
511 // function: RefinePavePool
513 //=======================================================================
514 void NMTTools_PaveFiller::RefinePavePool()
516 Standard_Integer i, aNbNew;
518 for (i=1; i<=myNbSources; i++) {
520 if ((myDS->GetShape(i)).ShapeType()==TopAbs_EDGE) {
521 BOPTools_PaveSet& aPS= myPavePool(myDS->RefEdge(i));
523 BOPTools_PaveSet& aNewPS= myPavePoolNew(myDS->RefEdge(i));
524 BOPTools_ListOfPave& aNewLP=aNewPS.ChangeSet();
526 aNbNew=aNewLP.Extent();
528 BOPTools_ListIteratorOfListOfPave anIt(aNewLP);
529 for (; anIt.More(); anIt.Next()) {
530 const BOPTools_Pave& aPave=anIt.Value();
533 // Clear the ListOfPaveBlock
534 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(i));
536 // Prepare the paveBlocks for that egde again
537 PreparePaveBlocks(i);
543 //=======================================================================
544 // function: PreparePaveBlocks
546 //=======================================================================
547 void NMTTools_PaveFiller::PreparePaveBlocks(const TopAbs_ShapeEnum aType1,
548 const TopAbs_ShapeEnum aType2)
550 myIsDone=Standard_False;
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
561 Standard_Boolean aFlag = Standard_False;
562 Standard_Integer n1, n2, nE1, nE2, aNbSplits;
563 TColStd_MapOfInteger aMap;
565 myDSIt.Initialize(aType1, aType2);
567 for (; myDSIt.More(); myDSIt.Next()) {
568 myDSIt.Current(n1, n2, aFlag);
573 if (aType1==TopAbs_EDGE) {
574 BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
575 aNbSplits=aLPB1.Extent();
577 if (!aMap.Contains(nE1)) {
579 PreparePaveBlocks(nE1);
588 if (aType2==TopAbs_EDGE) {
589 BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
590 aNbSplits=aLPB2.Extent();
592 if (!aMap.Contains(nE2)) {
594 PreparePaveBlocks(nE2);
601 }// if (aType2==TopAbs_EDGE)
602 }// for (; myDSIt.More(); myDSIt.Next())
604 myIsDone=Standard_True;
606 //=======================================================================
607 // function: PreparePaveBlocks
609 //=======================================================================
610 void NMTTools_PaveFiller::PreparePaveBlocks(const Standard_Integer nE)
612 myIsDone=Standard_False;
614 Standard_Integer nV1, nV2;
617 TopoDS_Vertex aV1, aV2;
620 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
622 aE=TopoDS::Edge(myDS->Shape(nE));
624 if (!BRep_Tool::Degenerated(aE)){
626 BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE));
628 BOPTools_PaveBlockIterator aPBIt(nE, aPS);
629 for (; aPBIt.More(); aPBIt.Next()) {
630 BOPTools_PaveBlock& aPB=aPBIt.Value();
632 const IntTools_Range& aRange=aPB.Range();
634 const BOPTools_Pave& aPave1=aPB.Pave1();
636 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
638 const BOPTools_Pave& aPave2=aPB.Pave2();
640 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
643 IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext);
645 Standard_Integer anErrorStatus;
646 anErrorStatus=aSR.ErrorStatus();
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);
654 BOPTColStd_Failure(buf) ;
657 if (anErrorStatus==6) {
659 "Warning: [PreparePaveBlocks()] Max.Dummy Shrunk Range for Edge %d\n", nE);
660 BOPTColStd_Dump::PrintMessage(buf);
663 // Check left paves and correct ShrunkRange if it is necessary
664 CorrectShrunkRanges (0, aPave1, aSR);
665 CorrectShrunkRanges (1, aPave2, aSR);
668 aPB.SetShrunkRange(aSR);
670 } //for (; aPBIt1.More(); aPBIt1.Next())
672 myIsDone=Standard_True;
674 //=======================================================================
675 // function: CorrectShrunkRanges
677 //=======================================================================
678 void NMTTools_PaveFiller::CorrectShrunkRanges(const Standard_Integer aSide,
679 const BOPTools_Pave& aPave,
680 IntTools_ShrunkRange& aShrunkRange)
682 BooleanOperations_KindOfInterference aType;
683 Standard_Integer anIndexInterf ;
686 if (aType!=BooleanOperations_EdgeEdge) {
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.
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();
703 const IntTools_Range& aSR=aShrunkRange.ShrunkRange();
704 const TopoDS_Edge& aE=aShrunkRange.Edge();
706 IntTools_Range aNewRange;
707 IntTools_Range aCPRange;
709 if (aE1.IsSame(aE)) {
710 const IntTools_Range& aR1=aCP.Range1();
713 if (aE2.IsSame(aE)) {
714 const IntTools_SequenceOfRanges& aSeqR=aCP.Ranges2();
715 const IntTools_Range& aR2=aSeqR(1);
719 Standard_Real aCoeff=1.05, tV, tNV;
721 if (aSide==0) { // Left
722 if (aCPRange.Last() > aSR.First()) {
724 tNV=tV+aCoeff*(tNV-tV);
725 aNewRange.SetFirst(tNV);
726 aNewRange.SetLast (aSR.Last());
728 if(aNewRange.First() > aNewRange.Last()) {
729 aShrunkRange.SetShrunkRange(aNewRange);
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);
740 if(aNewRange.First() < aNewRange.Last()) {
741 aShrunkRange.SetShrunkRange(aNewRange);
746 //=======================================================================
747 // function: IsBlocksCoinside
749 //=======================================================================
751 NMTTools_PaveFiller::IsBlocksCoinside(const BOPTools_PaveBlock& aPB1,
752 const BOPTools_PaveBlock& aPB2) const
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;
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()));
764 aTolV11=BRep_Tool::Tolerance(aV11);
765 aTolV12=BRep_Tool::Tolerance(aV12);
766 aTolV21=BRep_Tool::Tolerance(aV21);
767 aTolV22=BRep_Tool::Tolerance(aV22);
769 aP11=BRep_Tool::Pnt(aV11);
770 aP12=BRep_Tool::Pnt(aV12);
771 aP21=BRep_Tool::Pnt(aV21);
772 aP22=BRep_Tool::Pnt(aV22);
774 d1121=aP11.Distance(aP21);
775 aTolSum=aCoeff*(aTolV11+aTolV21);
777 d1222=aP12.Distance(aP22);
778 aTolSum=aCoeff*(aTolV12+aTolV22);
784 d1122=aP11.Distance(aP22);
785 aTolSum=aCoeff*(aTolV11+aTolV22);
787 d1221=aP12.Distance(aP21);
788 aTolSum=aCoeff*(aTolV12+aTolV21);
795 //=======================================================================
796 // function: ReplaceCommonBlocks
798 //=======================================================================
799 void NMTTools_PaveFiller::ReplaceCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
801 RemoveCommonBlocks(aLCB);
802 SplitCommonBlocks(aLCB);
804 //=======================================================================
805 // function: SplitCommonBlocks
807 //=======================================================================
808 void NMTTools_PaveFiller::SplitCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
811 NMTTools_ListOfCommonBlock aLCBx;
812 NMTTools_ListIteratorOfListOfCommonBlock anIt, anItCBx;
813 BOPTools_ListIteratorOfListOfPaveBlock anItLPE;
815 anIt.Initialize(aLCB);
816 for (; anIt.More(); anIt.Next()) {
817 const NMTTools_CommonBlock& aCB=anIt.Value();
822 SplitCommonBlock(aCB, aLCBx);
824 anItCBx.Initialize(aLCBx);
825 for (; anItCBx.More(); anItCBx.Next()) {
826 const NMTTools_CommonBlock& aCBx=anItCBx.Value();
827 const BOPTools_ListOfPaveBlock& aLPBx=aCBx.PaveBlocks();
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));
839 //=======================================================================
840 // function: RemoveCommonBlocks
842 //=======================================================================
843 void NMTTools_PaveFiller::RemoveCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
846 NMTTools_ListOfCommonBlock aLCBx;
847 NMTTools_ListIteratorOfListOfCommonBlock anItCB, anItCBE;
848 BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
850 anItCB.Initialize(aLCB);
851 for (; anItCB.More(); anItCB.Next()) {
852 const NMTTools_CommonBlock& aCB=anItCB.Value();
853 const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
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();
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);
873 //=======================================================================
874 // function: SplitCommonBlock
876 //=======================================================================
877 void NMTTools_PaveFiller::SplitCommonBlock(const NMTTools_CommonBlock& aCB,
878 NMTTools_ListOfCommonBlock& aLCBx)
880 Standard_Integer i, j, k, nE, aNbE, aNbSPBx, aNbPB;
881 BOPTools_SequenceOfPaveBlock aSPBx;
882 BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
883 BOPTools_ListIteratorOfListOfPave anIt;
885 BOPTools_PaveBlockIterator anPBIt;
887 const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
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));
898 BOPTools_PaveSet aPSx;
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)) {
908 aNbPB=aPSx.Set().Extent();
913 // we need not split it
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();
927 BOPTools_PaveSet aPSx;
929 // the set aPsx will contain bounadry paves aPave1, aPave2 and
930 // all paves of the edge nE that are inside block aPB
934 BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
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)) {
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();
954 // 3. Do new common blocks
956 const TColStd_ListOfInteger& aLF=aCB.Faces();
957 aNbSPBx=aSPBx.Length();
960 for (i=1; i<=aNbPB; ++i) {
961 NMTTools_CommonBlock aCBx;
965 for (j=1; j<=aNbE; ++j) {
967 const BOPTools_PaveBlock& aPB=aSPBx(k);
968 aCBx.AddPaveBlock(aPB);
974 //=======================================================================
975 // function: VertexParameters
977 //=======================================================================
978 void VertexParameters(const IntTools_CommonPrt& aCPart,
982 const IntTools_Range& aR1=aCPart.Range1();
983 aT1=0.5*(aR1.First()+aR1.Last());
985 if((aCPart.VertexParameter1() >= aR1.First()) &&
986 (aCPart.VertexParameter1() <= aR1.Last())) {
987 aT1 = aCPart.VertexParameter1();
990 const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
991 const IntTools_Range& aR2=aRanges2(1);
992 aT2=0.5*(aR2.First()+aR2.Last());
994 if((aCPart.VertexParameter2() >= aR2.First()) &&
995 (aCPart.VertexParameter2() <= aR2.Last())) {
996 aT2 = aCPart.VertexParameter2();
999 //=======================================================================
1000 // function: KeepPave
1002 //=======================================================================
1003 Standard_Boolean IsOnPave(const Standard_Real& aT1,
1004 const IntTools_Range& aRange,
1005 const Standard_Real& aTolerance)
1007 Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave;
1009 firstisonpave1 = (Abs(aRange.First() - aT1) < aTolerance);
1010 firstisonpave2 = (Abs(aRange.Last() - aT1) < aTolerance);
1011 bIsOnPave=(firstisonpave1 || firstisonpave2);
1015 //=======================================================================
1016 // function:FindChains
1018 //=======================================================================
1019 void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
1020 NMTTools_ListOfCommonBlock& aLCB)
1022 Standard_Integer i, j, aNbCB, aNbPB;
1023 BOPTools_IMapOfPaveBlock aProcessedBlocks, aChain;
1025 aNbCB=aMapCB.Extent();
1026 for (i=1; i<=aNbCB; ++i) {
1027 const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
1028 if (aProcessedBlocks.Contains(aPB)) {
1032 aProcessedBlocks.Add(aPB);
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);
1042 NMTTools_CommonBlock aCB;
1044 aNbPB=aChain.Extent();
1045 for (j=1; j<=aNbPB; ++j) {
1046 const BOPTools_PaveBlock& aPBx=aChain(j);
1047 aCB.AddPaveBlock(aPBx);
1053 //=======================================================================
1054 // function:ProcessBlock
1056 //=======================================================================
1057 void ProcessBlock(const BOPTools_PaveBlock& aPB,
1058 const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
1059 BOPTools_IMapOfPaveBlock& aProcessedBlocks,
1060 BOPTools_IMapOfPaveBlock& aChain)
1062 Standard_Integer j, aNbPB;
1064 if (aProcessedBlocks.Contains(aPB)) {
1067 aProcessedBlocks.Add(aPB);
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);