geom/src/NMTTools/NMTTools_PaveFiller_4.cxx

1077 lines
31 KiB
C++
Raw Normal View History

2004-12-01 15:39:14 +05:00
// File: NMTTools_PaveFiller_4.cxx
// Created: Mon Dec 8 17:08:58 2003
// Author: Peter KURNEV
// <pkv@irinox>
#include <NMTTools_PaveFiller.ixx>
//
#include <stdio.h>
#include <Precision.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Compound.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <Bnd_Box.hxx>
#include <IntTools_ShrunkRange.hxx>
#include <IntTools_Range.hxx>
#include <IntTools_CommonPrt.hxx>
#include <IntTools_SequenceOfRanges.hxx>
#include <IntTools_EdgeEdge.hxx>
#include <IntTools_SequenceOfCommonPrts.hxx>
#include <BOPTools_Pave.hxx>
#include <BOPTools_PaveSet.hxx>
#include <BOPTools_PaveBlockIterator.hxx>
#include <BOPTools_PaveBlock.hxx>
#include <BOPTools_CArray1OfEEInterference.hxx>
#include <BOPTools_EEInterference.hxx>
#include <BOPTools_ListOfPaveBlock.hxx>
#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
#include <BOPTools_CArray1OfVVInterference.hxx>
#include <BOPTools_VVInterference.hxx>
#include <BOPTools_CArray1OfEEInterference.hxx>
#include <BOPTools_Tools.hxx>
#include <BOPTools_IDMapOfPaveBlockIMapOfPaveBlock.hxx>
#include <BOPTools_IMapOfPaveBlock.hxx>
#include <BOPTools_ListIteratorOfListOfPave.hxx>
#include <BOPTools_SequenceOfPaveBlock.hxx>
#include <BOPTColStd_Dump.hxx>
#include <BOPTColStd_Failure.hxx>
#include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
#include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
#include <BooleanOperations_KindOfInterference.hxx>
#include <NMTDS_ShapesDataStructure.hxx>
#include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
#include <NMTTools_ListOfCommonBlock.hxx>
#include <NMTTools_CommonBlock.hxx>
#include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
//
static
void VertexParameters(const IntTools_CommonPrt& aCPart,
Standard_Real& aT1,
Standard_Real& aT2);
static
Standard_Boolean IsOnPave(const Standard_Real& aT1,
const IntTools_Range& aRange,
const Standard_Real& aTolerance);
static
void ProcessBlock(const BOPTools_PaveBlock& aPB,
const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
BOPTools_IMapOfPaveBlock& aProcessedBlocks,
BOPTools_IMapOfPaveBlock& aChain);
static
void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
NMTTools_ListOfCommonBlock& aLCB);
//=======================================================================
// function: PerformEE
// purpose:
//=======================================================================
void NMTTools_PaveFiller::PerformEE()
{
myIsDone=Standard_False;
//
Standard_Boolean bJustAdd;
Standard_Integer n1, n2, anIndexIn, nE1, nE2, aNbVEs, aBlockLength;
Standard_Integer aTmp, aWhat, aWith, i, aNbCPrts, aDiscretize=30;
Standard_Real aTolE1, aTolE2, aDeflection=0.01;
BOPTools_ListIteratorOfListOfPaveBlock anIt1, anIt2;
TopoDS_Edge aEWhat, aEWith;
TopoDS_Vertex aNewVertex;
BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
BOPTools_IDMapOfPaveBlockIMapOfPaveBlock aMapCB;
//
BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
//
// BlockLength correction
aNbVEs=ExpectedPoolLength();
aBlockLength=aEEs.BlockLength();
if (aNbVEs > aBlockLength) {
aEEs.SetBlockLength(aNbVEs);
}
//
myDSIt.Initialize(TopAbs_EDGE, TopAbs_EDGE);
//
for (; myDSIt.More(); myDSIt.Next()) {
myDSIt.Current(n1, n2, bJustAdd);
anIndexIn = 0;
//
if (myIntrPool->IsComputed(n1, n2)) {
continue;
}
//
nE1=n1;
nE2=n2;
SortTypes(nE1, nE2);
//
if(bJustAdd) {
myIntrPool->AddInterference (nE1, nE2, BooleanOperations_EdgeEdge, anIndexIn);
continue;
}
//
const TopoDS_Edge& aE1=TopoDS::Edge(myDS->Shape(nE1));
const TopoDS_Edge& aE2=TopoDS::Edge(myDS->Shape(nE2));
//
if (BRep_Tool::Degenerated(aE1) || BRep_Tool::Degenerated(aE2)){
continue;
}
//
aTolE1=BRep_Tool::Tolerance(aE1);
aTolE2=BRep_Tool::Tolerance(aE2);
//
BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
//
for (anIt1.Initialize(aLPB1); anIt1.More(); anIt1.Next()) {
BOPTools_PaveBlock& aPB1=anIt1.Value();
const IntTools_ShrunkRange& aShrunkRange1=aPB1.ShrunkRange();
//
const IntTools_Range& aSR1=aShrunkRange1.ShrunkRange();
const Bnd_Box& aBB1=aShrunkRange1.BndBox();
//
BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
//
for (anIt2.Initialize(aLPB2); anIt2.More(); anIt2.Next()) {
BOPTools_PaveBlock& aPB2=anIt2.Value();
const IntTools_ShrunkRange& aShrunkRange2=aPB2.ShrunkRange();
const IntTools_Range& aSR2=aShrunkRange2.ShrunkRange();
const Bnd_Box& aBB2=aShrunkRange2.BndBox();
//
if (aBB1.IsOut (aBB2)) {
continue;
}
//
// EE
IntTools_EdgeEdge aEE;
aEE.SetEdge1 (aE1);
aEE.SetEdge2 (aE2);
aEE.SetTolerance1 (aTolE1);
aEE.SetTolerance2 (aTolE2);
aEE.SetDiscretize (aDiscretize);
aEE.SetDeflection (aDeflection);
//
IntTools_Range anewSR1 = aSR1;
IntTools_Range anewSR2 = aSR2;
//
BOPTools_Tools::CorrectRange (aE1, aE2, aSR1, anewSR1);
BOPTools_Tools::CorrectRange (aE2, aE1, aSR2, anewSR2);
//
aEE.SetRange1(anewSR1);
aEE.SetRange2(anewSR2);
aEE.Perform();
//
anIndexIn=0;
//
if (aEE.IsDone()) {
// reverse order if it is necessary
aEWhat=aE1;
aEWith=aE2;
aWhat=nE1;
aWith=nE2;
if (aEE.Order()) {
aTmp=aWhat;
aWhat=aWith;
aWith=aTmp;
aEWhat=aE2;
aEWith=aE1;
}
//
const IntTools_SequenceOfCommonPrts& aCPrts=aEE.CommonParts();
aNbCPrts=aCPrts.Length();
for (i=1; i<=aNbCPrts; i++) {
const IntTools_CommonPrt& aCPart=aCPrts(i);
const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
//
anIndexIn=0;
//
TopAbs_ShapeEnum aType=aCPart.Type();
switch (aType) {
case TopAbs_VERTEX: {
Standard_Real aT1, aT2, aTol=Precision::PConfusion();
Standard_Boolean bIsOnPave1, bIsOnPave2;
IntTools_Range aR1, aR2;
//
VertexParameters(aCPart, aT1, aT2);
//
//decide to keep the pave or not
aR1 = (aEE.Order()) ? anewSR2 : anewSR1;
aR2 = (aEE.Order()) ? anewSR1 : anewSR2;
//
bIsOnPave1=IsOnPave(aT1, aR1, aTol);
bIsOnPave2=IsOnPave(aT2, aR2, aTol);
//
if(bIsOnPave1 || bIsOnPave2) {
myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
continue;
}
//
BOPTools_Tools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aNewVertex);
//
// Add Interference to the Pool
BOPTools_EEInterference anInterf (aWhat, aWith, aCPart);
//
anIndexIn=aEEs.Append(anInterf);
myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
//
// Collect
aMapVI.Add(aNewVertex, anIndexIn);
}
break;
case TopAbs_EDGE: {
Standard_Integer aNbComPrt2;
Standard_Boolean aCoinsideFlag;
//
aNbComPrt2=aRanges2.Length();
aCoinsideFlag=IsBlocksCoinside(aPB1, aPB2);
//
if (aNbComPrt2>1 || !aCoinsideFlag) {
myIntrPool->AddInterference (aWhat, aWith, BooleanOperations_EdgeEdge, anIndexIn);
break;
}
//
// Fill aMapCB
if (aMapCB.Contains(aPB1)) {
BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB1);
aMapPB.Add(aPB1);
aMapPB.Add(aPB2);
}
else {
BOPTools_IMapOfPaveBlock aMapPB;
aMapPB.Add(aPB1);
aMapPB.Add(aPB2);
aMapCB.Add(aPB1, aMapPB);
}
//
if (aMapCB.Contains(aPB2)) {
BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.ChangeFromKey(aPB2);
aMapPB.Add(aPB1);
aMapPB.Add(aPB2);
}
else {
BOPTools_IMapOfPaveBlock aMapPB;
aMapPB.Add(aPB1);
aMapPB.Add(aPB2);
aMapCB.Add(aPB2, aMapPB);
}
}
break;
default:
break;
} // switch (aType)
} // for (i=1; i<=aNbCPrts; i++)
}// if (aEE.IsDone())
} // for (; anIt2.More(); anIt2.Next())
} // for (; anIt1.More(); anIt1.Next())
}// for (; myDSIt.More(); myDSIt.Next())
//
EENewVertices (aMapVI);
EECommonBlocks(aMapCB);
//
myIsDone=Standard_True;
}
//=======================================================================
// function:EECommonBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::EECommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB)
{
NMTTools_ListOfCommonBlock aLCB;
//
FindChains(aMapCB, aLCB);
ReplaceCommonBlocks(aLCB);
}
//=======================================================================
// function:EENewVertices
// purpose:
//=======================================================================
void NMTTools_PaveFiller::EENewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
{
Standard_Integer aNb, i, j, aNewShape, aNbEdges, aNbIEE, aNbVV, aNbSimple;
Standard_Integer aWhat, aWith, i1, i2, nE1, nE2, nE, nV, aFlag;
Standard_Real aT;
TopoDS_Compound aCompound;
BRep_Builder aBB;
NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEE;
BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
BOPTools_Pave aPave;
TopoDS_Vertex aNewVertex;
TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
//
BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
//
aNb=aMapVI.Extent();
//
if (!aNb) { // no new vertices, no new problems
return;
}
//
// 0.
if (aNb==1) {
aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
EENewVertices(aNewVertex, aMapVI);
return;
}
//
// 1. Make compound from new vertices
aBB.MakeCompound(aCompound);
for (i=1; i<=aNb; ++i) {
const TopoDS_Shape& aV=aMapVI.FindKey(i);
aBB.Add(aCompound, aV);
}
//
// 2. VV intersection between these vertices
// using the auxiliary Filler
NMTDS_ShapesDataStructure tDS;
//
tDS.SetCompositeShape(aCompound);
tDS.Init();
//
BOPTools_InterferencePool tInterfPool(tDS);
NMTTools_PaveFiller tPaveFiller(tInterfPool);
//
tPaveFiller.Init();
//
tPaveFiller.PerformVV();
tPaveFiller.PerformNewVertices();
//
const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
//
// 3. Separate Comlex and Simple new vertices
aNbVV=aVVInterfs.Extent();
for (i=1; i<=aNbVV; ++i) {
const BOPTools_VVInterference& aVV=aVVInterfs(i);
aVV.Indices(aWhat, aWith);
const TopoDS_Shape& aV1=tDS.Shape(aWhat);
const TopoDS_Shape& aV2=tDS.Shape(aWith);
aMNVComplex.Add(aV1);
aMNVComplex.Add(aV2);
}
//
for (i=1; i<=aNb; ++i) {
const TopoDS_Shape& aV=aMapVI.FindKey(i);
if (!aMNVComplex.Contains(aV)) {
aMNVSimple.Add(aV);
}
}
//
// 4. Treat Simple new Vertices
aNbSimple=aMNVSimple.Extent();
for (i=1; i<=aNbSimple; ++i) {
const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
EENewVertices(aV, aMapVI);
}
//
// 3. Fill Maps : NewVertex-edges (aMNVE)
// NewVertex-interferences (aMNVIEE)
for (i=1; i<=aNbVV; ++i) {
const BOPTools_VVInterference& aVV=aVVInterfs(i);
aNewShape=aVV.NewShape();
if (!aNewShape) {
continue;
}
//
if (!aMNVE.Contains(aNewShape)) {
TColStd_IndexedMapOfInteger aMx;
aMNVE.Add(aNewShape, aMx);
}
if (!aMNVIEE.Contains(aNewShape)) {
TColStd_IndexedMapOfInteger aMx;
aMNVIEE.Add(aNewShape, aMx);
}
//
TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
TColStd_IndexedMapOfInteger& aMIEE=aMNVIEE.ChangeFromKey(aNewShape);
//
aVV.Indices(aWhat, aWith);
//aWhat
const TopoDS_Shape& aV1=tDS.Shape(aWhat);
i1=aMapVI.FindFromKey(aV1);
const BOPTools_EEInterference& aEE1=aEEs(i1);
aEE1.Indices(nE1, nE2);
aME.Add(nE1);
aME.Add(nE2);
aMIEE.Add(i1);
//aWith
const TopoDS_Shape& aV2=tDS.Shape(aWith);
i2=aMapVI.FindFromKey(aV2);
const BOPTools_EEInterference& aEE2=aEEs(i2);
aEE2.Indices(nE1, nE2);
aME.Add(nE1);
aME.Add(nE2);
aMIEE.Add(i2);
//
//printf(" VV: (%d, %d) -> %d\n", aWhat, aWith, aNewShape);
}
//
// 4. Process new vertices
aNb=aMNVE.Extent();
for (i=1; i<=aNb; ++i) { // xx
//
// new Vertex
nV=aMNVE.FindKey(i);
aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
//
// Insert New Vertex in DS;
myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
aNewShape=myDS->NumberOfInsertedShapes();
myDS->SetState (aNewShape, BooleanOperations_ON);
//
// Update index of NewShape in EE interferences
const TColStd_IndexedMapOfInteger& aMIEE=aMNVIEE.FindFromKey(nV);//(i);
aNbIEE=aMIEE.Extent();
for (j=1; j<=aNbIEE; ++j) {
i1=aMIEE(j);
BOPTools_EEInterference& aEE1=aEEs(i1);
aEE1.SetNewShape(aNewShape);
}
//
// Update Paves on edges
const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
aNbEdges=aME.Extent();
for (j=1; j<=aNbEdges; ++j) {
nE=aME(j);
const TopoDS_Edge& aE=TopoDS::Edge(myDS->Shape(nE));
//
aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
//
if (!aFlag) {
aPave.SetInterference(-1);
aPave.SetType (BooleanOperations_EdgeEdge);
aPave.SetIndex(aNewShape);
aPave.SetParam(aT);
//
BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
aPaveSet.Append(aPave);
}
}
}// for (i=1; i<=aNb; ++i) {// xx
}
//=======================================================================
// function:EENewVertices
// purpose:
//=======================================================================
void NMTTools_PaveFiller::EENewVertices (const TopoDS_Vertex& aNewVertex,
const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
{
Standard_Integer i, aNewShape, nE1, nE2;
Standard_Real aT1, aT2;
BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
BOPTools_Pave aPave;
//
BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
//
// one new vertex case is treated in usual way
//
// Insert New Vertex in DS;
myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
aNewShape=myDS->NumberOfInsertedShapes();
myDS->SetState (aNewShape, BooleanOperations_ON);
// Insert New Vertex in EE Interference
i=aMapVI.FindFromKey(aNewVertex);
BOPTools_EEInterference& aEEInterf= aEEs(i);
aEEInterf.SetNewShape(aNewShape);
// Extact interference info
aEEInterf.Indices(nE1, nE2);
const IntTools_CommonPrt& aCPart=aEEInterf.CommonPrt();
VertexParameters(aCPart, aT1, aT2);
//
// Add Paves to the myPavePoolNew
aPave.SetInterference(i);
aPave.SetType (BooleanOperations_EdgeEdge);
aPave.SetIndex(aNewShape);
// Pave for edge nE1
aPave.SetParam(aT1);
BOPTools_PaveSet& aPaveSet1=myPavePoolNew(myDS->RefEdge(nE1));
aPaveSet1.Append(aPave);
// Pave for edge nE2
aPave.SetParam(aT2);
BOPTools_PaveSet& aPaveSet2=myPavePoolNew(myDS->RefEdge(nE2));
aPaveSet2.Append(aPave);
}
//=======================================================================
// function: RefinePavePool
// purpose:
//=======================================================================
void NMTTools_PaveFiller::RefinePavePool()
{
Standard_Integer i, aNbNew;
for (i=1; i<=myNbSources; i++) {
if ((myDS->GetShape(i)).ShapeType()==TopAbs_EDGE) {
BOPTools_PaveSet& aPS= myPavePool(myDS->RefEdge(i));
//
BOPTools_PaveSet& aNewPS= myPavePoolNew(myDS->RefEdge(i));
BOPTools_ListOfPave& aNewLP=aNewPS.ChangeSet();
//
aNbNew=aNewLP.Extent();
if (aNbNew) {
BOPTools_ListIteratorOfListOfPave anIt(aNewLP);
for (; anIt.More(); anIt.Next()) {
const BOPTools_Pave& aPave=anIt.Value();
aPS.Append(aPave);
}
// Clear the ListOfPaveBlock
BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(i));
aLPB.Clear();
// Prepare the paveBlocks for that egde again
PreparePaveBlocks(i);
}
aNewLP.Clear();
}
}
}
//=======================================================================
// function: PreparePaveBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::PreparePaveBlocks(const TopAbs_ShapeEnum aType1,
const TopAbs_ShapeEnum aType2)
{
myIsDone=Standard_False;
//
Standard_Boolean Ok1, Ok2, Ok3;
Ok1= (aType1==TopAbs_VERTEX) && (aType2==TopAbs_EDGE) ;
Ok2= (aType1==TopAbs_EDGE) && (aType2==TopAbs_EDGE) ;
Ok3= (aType1==TopAbs_EDGE) && (aType2==TopAbs_FACE) ;
if (!Ok1 && !Ok2 && !Ok3) {
// error: Type mismatch
return;
}
//
Standard_Boolean aFlag = Standard_False;
Standard_Integer n1, n2, nE1, nE2, aNbSplits;
TColStd_MapOfInteger aMap;
//
myDSIt.Initialize(aType1, aType2);
//
for (; myDSIt.More(); myDSIt.Next()) {
myDSIt.Current(n1, n2, aFlag);
nE1=n1;
nE2=n2;
SortTypes(nE1, nE2);
//
if (aType1==TopAbs_EDGE) {
BOPTools_ListOfPaveBlock& aLPB1=mySplitShapesPool(myDS->RefEdge(nE1));
aNbSplits=aLPB1.Extent();
if (!aNbSplits) {
if (!aMap.Contains(nE1)) {
aMap.Add(nE1);
PreparePaveBlocks(nE1);
//
if (!myIsDone) {
return;
}
}
}
}
//
if (aType2==TopAbs_EDGE) {
BOPTools_ListOfPaveBlock& aLPB2=mySplitShapesPool(myDS->RefEdge(nE2));
aNbSplits=aLPB2.Extent();
if (!aNbSplits) {
if (!aMap.Contains(nE2)) {
aMap.Add(nE2);
PreparePaveBlocks(nE2);
//
if (!myIsDone) {
return;
}
}
}
}// if (aType2==TopAbs_EDGE)
}// for (; myDSIt.More(); myDSIt.Next())
myIsDone=Standard_True;
}
//=======================================================================
// function: PreparePaveBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::PreparePaveBlocks(const Standard_Integer nE)
{
myIsDone=Standard_False;
Standard_Integer nV1, nV2;
TopoDS_Edge aE;
TopoDS_Vertex aV1, aV2;
// SplitShapesPool
BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
// Edge
aE=TopoDS::Edge(myDS->Shape(nE));
//
if (!BRep_Tool::Degenerated(aE)){
//
BOPTools_PaveSet& aPS=myPavePool(myDS->RefEdge(nE));
BOPTools_PaveBlockIterator aPBIt(nE, aPS);
for (; aPBIt.More(); aPBIt.Next()) {
BOPTools_PaveBlock& aPB=aPBIt.Value();
const IntTools_Range& aRange=aPB.Range();
const BOPTools_Pave& aPave1=aPB.Pave1();
nV1=aPave1.Index();
aV1=TopoDS::Vertex(myDS->GetShape(nV1));
const BOPTools_Pave& aPave2=aPB.Pave2();
nV2=aPave2.Index();
aV2=TopoDS::Vertex(myDS->GetShape(nV2));
//
// ShrunkRange
IntTools_ShrunkRange aSR (aE, aV1, aV2, aRange, myContext);
//
Standard_Integer anErrorStatus;
anErrorStatus=aSR.ErrorStatus();
char buf[512];
if (!aSR.IsDone()) {
sprintf (buf, "Can not obtain ShrunkRange for Edge %d\n", nE);
BOPTColStd_Dump::PrintMessage(buf);
sprintf (buf, "Can not obtain ShrunkRange for Edge %d", nE);
throw
BOPTColStd_Failure(buf) ;
}
//
if (anErrorStatus==6) {
sprintf(buf,
"Warning: [PreparePaveBlocks()] Max.Dummy Shrunk Range for Edge %d\n", nE);
BOPTColStd_Dump::PrintMessage(buf);
}
else {
// Check left paves and correct ShrunkRange if it is necessary
CorrectShrunkRanges (0, aPave1, aSR);
CorrectShrunkRanges (1, aPave2, aSR);
}
//
aPB.SetShrunkRange(aSR);
aLPB.Append(aPB);
} //for (; aPBIt1.More(); aPBIt1.Next())
}
myIsDone=Standard_True;
}
//=======================================================================
// function: CorrectShrunkRanges
// purpose:
//=======================================================================
void NMTTools_PaveFiller::CorrectShrunkRanges(const Standard_Integer aSide,
const BOPTools_Pave& aPave,
IntTools_ShrunkRange& aShrunkRange)
{
BooleanOperations_KindOfInterference aType;
Standard_Integer anIndexInterf ;
//
aType=aPave.Type();
if (aType!=BooleanOperations_EdgeEdge) {
return;
}
//
anIndexInterf=aPave.Interference();
if (anIndexInterf<0) {
// it can be EE interf between E and (e1,e2,..en) -> vertex
// so we can't decide which aEE.CommonPrt() we should take.
return;
}
BOPTools_CArray1OfEEInterference& aEEs=myIntrPool->EEInterferences();
const BOPTools_EEInterference& aEE=aEEs(anIndexInterf);
const IntTools_CommonPrt& aCP=aEE.CommonPrt();
const TopoDS_Edge& aE1=aCP.Edge1();
const TopoDS_Edge& aE2=aCP.Edge2();
const IntTools_Range& aSR=aShrunkRange.ShrunkRange();
const TopoDS_Edge& aE=aShrunkRange.Edge();
IntTools_Range aNewRange;
IntTools_Range aCPRange;
if (aE1.IsSame(aE)) {
const IntTools_Range& aR1=aCP.Range1();
aCPRange=aR1;
}
if (aE2.IsSame(aE)) {
const IntTools_SequenceOfRanges& aSeqR=aCP.Ranges2();
const IntTools_Range& aR2=aSeqR(1);
aCPRange=aR2;
}
//
Standard_Real aCoeff=1.05, tV, tNV;
tV=aPave.Param();
if (aSide==0) { // Left
if (aCPRange.Last() > aSR.First()) {
tNV=aCPRange.Last();
tNV=tV+aCoeff*(tNV-tV);
aNewRange.SetFirst(tNV);
aNewRange.SetLast (aSR.Last());
if(aNewRange.First() > aNewRange.Last()) {
aShrunkRange.SetShrunkRange(aNewRange);
}
}
}
else { // Right
if (aCPRange.First() < aSR.Last()) {
tNV=aCPRange.First();
tNV=tV-aCoeff*(tV-tNV);
aNewRange.SetFirst(aSR.First());
aNewRange.SetLast (tNV);
if(aNewRange.First() < aNewRange.Last()) {
aShrunkRange.SetShrunkRange(aNewRange);
}
}
}
}
//=======================================================================
// function: IsBlocksCoinside
// purpose:
//=======================================================================
Standard_Boolean
NMTTools_PaveFiller::IsBlocksCoinside(const BOPTools_PaveBlock& aPB1,
const BOPTools_PaveBlock& aPB2) const
{
Standard_Boolean bRetFlag=Standard_True;
Standard_Real aTolV11, aTolV12, aTolV21, aTolV22;
Standard_Real d1121, d1122, d1222, d1221, aTolSum, aCoeff=1.05;
gp_Pnt aP11, aP12, aP21, aP22;
const TopoDS_Vertex& aV11=TopoDS::Vertex(myDS->Shape(aPB1.Pave1().Index()));
const TopoDS_Vertex& aV12=TopoDS::Vertex(myDS->Shape(aPB1.Pave2().Index()));
const TopoDS_Vertex& aV21=TopoDS::Vertex(myDS->Shape(aPB2.Pave1().Index()));
const TopoDS_Vertex& aV22=TopoDS::Vertex(myDS->Shape(aPB2.Pave2().Index()));
aTolV11=BRep_Tool::Tolerance(aV11);
aTolV12=BRep_Tool::Tolerance(aV12);
aTolV21=BRep_Tool::Tolerance(aV21);
aTolV22=BRep_Tool::Tolerance(aV22);
aP11=BRep_Tool::Pnt(aV11);
aP12=BRep_Tool::Pnt(aV12);
aP21=BRep_Tool::Pnt(aV21);
aP22=BRep_Tool::Pnt(aV22);
d1121=aP11.Distance(aP21);
aTolSum=aCoeff*(aTolV11+aTolV21);
if (d1121<aTolSum) {
d1222=aP12.Distance(aP22);
aTolSum=aCoeff*(aTolV12+aTolV22);
if (d1222<aTolSum) {
return bRetFlag;
}
}
//
d1122=aP11.Distance(aP22);
aTolSum=aCoeff*(aTolV11+aTolV22);
if (d1122<aTolSum) {
d1221=aP12.Distance(aP21);
aTolSum=aCoeff*(aTolV12+aTolV21);
if (d1221<aTolSum) {
return bRetFlag;
}
}
return !bRetFlag;
}
//=======================================================================
// function: ReplaceCommonBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::ReplaceCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
{
RemoveCommonBlocks(aLCB);
SplitCommonBlocks(aLCB);
}
//=======================================================================
// function: SplitCommonBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::SplitCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
{
Standard_Integer nE;
NMTTools_ListOfCommonBlock aLCBx;
NMTTools_ListIteratorOfListOfCommonBlock anIt, anItCBx;
BOPTools_ListIteratorOfListOfPaveBlock anItLPE;
//
anIt.Initialize(aLCB);
for (; anIt.More(); anIt.Next()) {
const NMTTools_CommonBlock& aCB=anIt.Value();
//
//XXX
aLCBx.Clear();
//XXX
SplitCommonBlock(aCB, aLCBx);
//
anItCBx.Initialize(aLCBx);
for (; anItCBx.More(); anItCBx.Next()) {
const NMTTools_CommonBlock& aCBx=anItCBx.Value();
const BOPTools_ListOfPaveBlock& aLPBx=aCBx.PaveBlocks();
//
anItLPE.Initialize(aLPBx);
for (; anItLPE.More(); anItLPE.Next()) {
const BOPTools_PaveBlock& aPBx=anItLPE.Value();
nE=aPBx.OriginalEdge();
NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
aLCBE.Append(aCBx);
}
}
}
}
//=======================================================================
// function: RemoveCommonBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::RemoveCommonBlocks(const NMTTools_ListOfCommonBlock& aLCB)
{
Standard_Integer nE;
NMTTools_ListOfCommonBlock aLCBx;
NMTTools_ListIteratorOfListOfCommonBlock anItCB, anItCBE;
BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
//
anItCB.Initialize(aLCB);
for (; anItCB.More(); anItCB.Next()) {
const NMTTools_CommonBlock& aCB=anItCB.Value();
const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
//
// Remove aCB from each edge
anItLPB.Initialize(aLPB);
for (; anItLPB.More(); anItLPB.Next()) {
const BOPTools_PaveBlock& aPB=anItLPB.Value();
nE=aPB.OriginalEdge();
//
NMTTools_ListOfCommonBlock& aLCBE=myCommonBlockPool(myDS->RefEdge(nE));
anItCBE.Initialize(aLCBE);
for (; anItCBE.More(); anItCBE.Next()) {
const NMTTools_CommonBlock& aCBE=anItCBE.Value();
if (aCBE.IsEqual(aCB)) {
aLCBE.Remove(anItCBE);
break;
}
}
}
}
}
//=======================================================================
// function: SplitCommonBlock
// purpose:
//=======================================================================
void NMTTools_PaveFiller::SplitCommonBlock(const NMTTools_CommonBlock& aCB,
NMTTools_ListOfCommonBlock& aLCBx)
{
Standard_Integer i, j, k, nE, aNbE, aNbSPBx, aNbPB;
BOPTools_SequenceOfPaveBlock aSPBx;
BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
BOPTools_ListIteratorOfListOfPave anIt;
BOPTools_PaveBlockIterator anPBIt;
//
const BOPTools_ListOfPaveBlock& aLPB=aCB.PaveBlocks();
aNbE=aLPB.Extent();
//
// 1. Whether we realy need to split the common block ?
anItLPB.Initialize(aLPB);
for (; anItLPB.More(); anItLPB.Next()) {
const BOPTools_PaveBlock& aPB=anItLPB.Value();
nE=aPB.OriginalEdge();
BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
aPSE.SortSet();
//
BOPTools_PaveSet aPSx;
//
const BOPTools_ListOfPave& aLPE=aPSE.Set();
anIt.Initialize(aLPE);
for (; anIt.More(); anIt.Next()) {
const BOPTools_Pave& aPx=anIt.Value();
if (aPB.IsInBlock(aPx)) {
aPSx.Append(aPx);
}
}
aNbPB=aPSx.Set().Extent();
break;
}
//
if (!aNbPB) {
// we need not split it
aLCBx.Append(aCB);
return;
}
//
// 2. Get sequence of pave Blocks containing all new pave blocks
// for each edges's source pave Block
anItLPB.Initialize(aLPB);
for (; anItLPB.More(); anItLPB.Next()) {
const BOPTools_PaveBlock& aPB=anItLPB.Value();
const BOPTools_Pave& aPave1=aPB.Pave1();
const BOPTools_Pave& aPave2=aPB.Pave2();
nE=aPB.OriginalEdge();
//
BOPTools_PaveSet aPSx;
//
// the set aPsx will contain bounadry paves aPave1, aPave2 and
// all paves of the edge nE that are inside block aPB
aPSx.Append(aPave1);
aPSx.Append(aPave2);
//
BOPTools_PaveSet& aPSE=myPavePoolNew(myDS->RefEdge(nE));
aPSE.SortSet();
//
const BOPTools_ListOfPave& aLPE=aPSE.Set();
anIt.Initialize(aLPE);
for (; anIt.More(); anIt.Next()) {
const BOPTools_Pave& aPx=anIt.Value();
if (aPB.IsInBlock(aPx)) {
aPSx.Append(aPx);
}
}
//
// Form pave blocks from aPSx and collect them in aSPBx
anPBIt.Initialize(nE, aPSx);
for (; anPBIt.More(); anPBIt.Next()) {
const BOPTools_PaveBlock& aPBx=anPBIt.Value();
aSPBx.Append(aPBx);
}
}
//
// 3. Do new common blocks
//
const TColStd_ListOfInteger& aLF=aCB.Faces();
aNbSPBx=aSPBx.Length();
aNbPB=aNbSPBx/aNbE;
//
for (i=1; i<=aNbPB; ++i) {
NMTTools_CommonBlock aCBx;
//
aCBx.AddFaces(aLF);
//
for (j=1; j<=aNbE; ++j) {
k=i+(j-1)*aNbPB;
const BOPTools_PaveBlock& aPB=aSPBx(k);
aCBx.AddPaveBlock(aPB);
}
aLCBx.Append(aCBx);
}
}
//=======================================================================
// function: VertexParameters
// purpose:
//=======================================================================
void VertexParameters(const IntTools_CommonPrt& aCPart,
Standard_Real& aT1,
Standard_Real& aT2)
{
const IntTools_Range& aR1=aCPart.Range1();
aT1=0.5*(aR1.First()+aR1.Last());
//
if((aCPart.VertexParameter1() >= aR1.First()) &&
(aCPart.VertexParameter1() <= aR1.Last())) {
aT1 = aCPart.VertexParameter1();
}
//
const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
const IntTools_Range& aR2=aRanges2(1);
aT2=0.5*(aR2.First()+aR2.Last());
//
if((aCPart.VertexParameter2() >= aR2.First()) &&
(aCPart.VertexParameter2() <= aR2.Last())) {
aT2 = aCPart.VertexParameter2();
}
}
//=======================================================================
// function: KeepPave
// purpose:
//=======================================================================
Standard_Boolean IsOnPave(const Standard_Real& aT1,
const IntTools_Range& aRange,
const Standard_Real& aTolerance)
{
Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave;
//
firstisonpave1 = (Abs(aRange.First() - aT1) < aTolerance);
firstisonpave2 = (Abs(aRange.Last() - aT1) < aTolerance);
bIsOnPave=(firstisonpave1 || firstisonpave2);
return bIsOnPave;
}
//=======================================================================
// function:FindChains
// purpose:
//=======================================================================
void FindChains(const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
NMTTools_ListOfCommonBlock& aLCB)
{
Standard_Integer i, j, aNbCB, aNbPB;
BOPTools_IMapOfPaveBlock aProcessedBlocks, aChain;
//
aNbCB=aMapCB.Extent();
for (i=1; i<=aNbCB; ++i) {
const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
if (aProcessedBlocks.Contains(aPB)) {
continue;
}
//
aProcessedBlocks.Add(aPB);
aChain.Add(aPB);
//
const BOPTools_IMapOfPaveBlock& aMapPB=aMapCB(i);
aNbPB=aMapPB.Extent();
for (j=1; j<=aNbPB; ++j) {
const BOPTools_PaveBlock& aPBx=aMapPB(j);
ProcessBlock(aPBx, aMapCB, aProcessedBlocks, aChain);
}
//
NMTTools_CommonBlock aCB;
//
aNbPB=aChain.Extent();
for (j=1; j<=aNbPB; ++j) {
const BOPTools_PaveBlock& aPBx=aChain(j);
aCB.AddPaveBlock(aPBx);
}
aLCB.Append(aCB);
aChain.Clear();
}
}
//=======================================================================
// function:ProcessBlock
// purpose:
//=======================================================================
void ProcessBlock(const BOPTools_PaveBlock& aPB,
const BOPTools_IDMapOfPaveBlockIMapOfPaveBlock& aMapCB,
BOPTools_IMapOfPaveBlock& aProcessedBlocks,
BOPTools_IMapOfPaveBlock& aChain)
{
Standard_Integer j, aNbPB;
//
if (aProcessedBlocks.Contains(aPB)) {
return;
}
aProcessedBlocks.Add(aPB);
aChain.Add(aPB);
//
const BOPTools_IMapOfPaveBlock& aMapPB=aMapCB.FindFromKey(aPB);
aNbPB=aMapPB.Extent();
for (j=1; j<=aNbPB; ++j) {
const BOPTools_PaveBlock& aPBx=aMapPB(j);
ProcessBlock(aPBx, aMapCB, aProcessedBlocks, aChain);
}
}