2005-12-05 21:23:52 +05:00
|
|
|
// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2.1 of the License.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
//
|
|
|
|
// See http://www.salome-platform.org/
|
|
|
|
//
|
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);
|
|
|
|
}
|
|
|
|
}
|