return;
}
//
+ UpdateInterfsWithSDVertices();
RefineFaceInfoOn();
//
MakePCurves();
//! Treatment of section edges.
Standard_EXPORT Standard_Integer PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
- BOPCol_DataMapOfShapeInteger& theMVI,
BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
BOPCol_DataMapOfIntegerInteger& theDMNewSD,
const BOPCol_IndexedMapOfShape& theMicroEdges,
Standard_EXPORT void UpdateCommonBlocksWithSDVertices();
Standard_EXPORT void UpdateBlocksWithSharedVertices();
-
+
+ Standard_EXPORT void UpdateInterfsWithSDVertices();
+
Standard_EXPORT Standard_Boolean EstimatePaveOnCurve(const Standard_Integer nV,
const BOPDS_Curve& theNC,
const Standard_Real theTolR3D);
}
UpdatePaveBlocksWithSDVertices();
}
+
+namespace
+{
+ //=======================================================================
+ //function : UpdateInterfsWithSDVertices
+ //purpose :
+ //=======================================================================
+ template <class InterfType>
+ void UpdateIntfsWithSDVertices(BOPDS_PDS theDS, BOPCol_NCVector<InterfType>& theInterfs)
+ {
+ for (Standard_Integer i = 0; i < theInterfs.Length(); i++)
+ {
+ InterfType& anIntf = theInterfs(i);
+ Standard_Integer anInd;
+ if (anIntf.HasIndexNew(anInd))
+ {
+ Standard_Integer anIndSD;
+ if (theDS->HasShapeSD(anInd, anIndSD))
+ {
+ anIntf.SetIndexNew(anIndSD);
+ }
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : UpdateInterfsWithSDVertices
+//purpose :
+//=======================================================================
+void BOPAlgo_PaveFiller::UpdateInterfsWithSDVertices()
+{
+ UpdateIntfsWithSDVertices(myDS, myDS->InterfVV());
+ UpdateIntfsWithSDVertices(myDS, myDS->InterfVE());
+ UpdateIntfsWithSDVertices(myDS, myDS->InterfVF());
+ UpdateIntfsWithSDVertices(myDS, myDS->InterfEE());
+ UpdateIntfsWithSDVertices(myDS, myDS->InterfEF());
+}
}
}
if (bFlag) {
+ BOPDS_InterfEE& aEE = aEEs.Append1();
+ aEE.SetIndices(nE1, nE2);
+ aEE.SetCommonPart(aCPart);
continue;
}
//
//
// post treatment
MakeSDVerticesFF(aDMVLV, aDMNewSD);
- myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
+ myErrorStatus=PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
if (myErrorStatus) {
return;
}
//=======================================================================
Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
(BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
- BOPCol_DataMapOfShapeInteger& aMVI,
BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
BOPCol_DataMapOfIntegerInteger& aDMNewSD,
const BOPCol_IndexedMapOfShape& theMicroEdges,
}
//
// 1 prepare arguments
+ BOPCol_MapOfShape anAddedSD;
for (k=1; k<=aNbS; ++k) {
const TopoDS_Shape& aS=theMSCPB.FindKey(k);
aLS.Append(aS);
+ // add vertices-candidates for SD from the map aDMNewSD,
+ // so that they took part in fuse operation.
+ TopoDS_Iterator itV(aS);
+ for (; itV.More(); itV.Next())
+ {
+ const TopoDS_Shape& aVer = itV.Value();
+ Standard_Integer iVer = myDS->Index(aVer);
+ const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
+ if (pSD)
+ {
+ const TopoDS_Shape& aVSD = myDS->Shape(*pSD);
+ if (anAddedSD.Add(aVSD))
+ aLS.Append(aVSD);
+ }
+ }
}
//
// The section edges considered as a micro should be
aV=aSx;
}
// index of new vertex in theDS -> iV
- if (!aMVI.IsBound(aV)) {
+ iV = myDS->Index(aV);
+ if (iV < 0) {
aSI.SetShapeType(aType);
aSI.SetShape(aV);
iV=myDS->Append(aSI);
- //
- aMVI.Bind(aV, iV);
- }
- else {
- iV=aMVI.Find(aV);
}
//
if (!bIntersectionPoint) {
// save SD connection
- nSx = aMVI.Find(aSx);
+ nSx = myDS->Index(aSx);
aDMNewSD.Bind(nSx, iV);
myDS->AddShapeSD(nSx, iV);
}
else {
- // update FF interference
- const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
- iX=aCPB.IndexInterf();
- iP=aCPB.Index();
- BOPDS_InterfFF& aFF=aFFs(iX);
- BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
- BOPDS_Point& aNP=aVNP(iP);
- aNP.SetIndex(iV);
+ // update FF interference
+ const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
+ iX=aCPB.IndexInterf();
+ iP=aCPB.Index();
+ BOPDS_InterfFF& aFF=aFFs(iX);
+ BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
+ BOPDS_Point& aNP=aVNP(iP);
+ aNP.SetIndex(iV);
}
}//if (aType==TopAbs_VERTEX) {
//
if (!aNbLPBx) {
aE=aSx;
//
- if (!aMVI.IsBound(aE)) {
+ iE = myDS->Index(aE);
+ if (iE < 0) {
aSI.SetShapeType(aType);
aSI.SetShape(aE);
iE=myDS->Append(aSI);
- aMVI.Bind(aE, iE);
- }
- else {
- iE=aMVI.Find(aE);
}
// append new PaveBlock to aLPBC
aPB1->SetEdge(iE);
const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
//
// update vertices of paves
- aPave[0]=aPBx->Pave1();
- aPave[1]=aPBx->Pave2();
+ aPave[0] = aPBx->Pave1();
+ aPave[1] = aPBx->Pave2();
for (j=0; j<2; ++j) {
nV = aPave[j].Index();
aV = aPDS->Shape(nV);
- //
- if (!aMVI.IsBound(aV)) {
- // index of new vertex in theDS -> iV
+ // index of new vertex in myDS -> iV
+ iV = myDS->Index(aV);
+ if (iV < 0) {
aSI.SetShapeType(TopAbs_VERTEX);
aSI.SetShape(aV);
iV = myDS->Append(aSI);
- aMVI.Bind(aV, iV);
- }
- else {
- iV = aMVI.Find(aV);
}
const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
if (aP1.Parameter() == aPave[j].Parameter() &&
//
// add edge
aE=aPDS->Shape(aPBRx->Edge());
+ iE = myDS->Index(aE);
//
- if (!aMVI.IsBound(aE)) {
+ if (iE < 0) {
aSI.SetShapeType(aType);
aSI.SetShape(aE);
iE=myDS->Append(aSI);
- aMVI.Bind(aE, iE);
// update real edge tolerance according to distances in common block if any
- if (aPDS->IsCommonBlock(aPBx)) {
- const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBx);
+ if (aPDS->IsCommonBlock(aPBRx)) {
+ const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
if (aFF.TolReal() < aTol) {
aFF.SetTolReal(aTol);
}
}
}
- else {
- iE=aMVI.Find(aE);
- }
// append new PaveBlock to aLPBC
Handle(BOPDS_PaveBlock) aPBC=new BOPDS_PaveBlock();
+ BOPDS_Pave aPaveR1, aPaveR2;
+ aPaveR1 = aPBRx->Pave1();
+ aPaveR2 = aPBRx->Pave2();
+ aPaveR1.SetIndex(myDS->Index(aPDS->Shape(aPaveR1.Index())));
+ aPaveR2.SetIndex(myDS->Index(aPDS->Shape(aPaveR2.Index())));
//
- aPBC->SetPave1(aPave[0]);
- aPBC->SetPave2(aPave[1]);
+ aPBC->SetPave1(aPaveR1);
+ aPBC->SetPave2(aPaveR2);
aPBC->SetEdge(iE);
if (bOld) {
aPBC->SetOriginalEdge(aPB1->OriginalEdge());
}
}//else if (aType==TopAbs_EDGE)
}//for (; aItLS.More(); aItLS.Next()) {
+
+ // Update SD for vertices that did not participate in operation
+ BOPCol_DataMapOfIntegerInteger::Iterator itDM(aDMNewSD);
+ for (; itDM.More(); itDM.Next())
+ {
+ const Standard_Integer* pSD = aDMNewSD.Seek(itDM.Value());
+ if (pSD)
+ {
+ itDM.ChangeValue() = *pSD;
+ myDS->AddShapeSD(itDM.Key(), *pSD);
+ }
+ }
return iRet;
}
aDTol = 1.e-12;
//
GeomAdaptor_Curve aGAC(aIC.Curve());
- aPTol = aGAC.Resolution(aTolR3D);
+ aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
//
bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
if (bExist) {
BOPDS_MapOfPaveBlock aMPB;
BOPCol_MapOfInteger aMicroEdges;
//
+ BOPDS_ListOfPaveBlock anAllPBs;
+
+ // Get pave blocks of section edges
+ BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
+ Standard_Integer aNbFF = aFFs.Extent();
+ for (i = 0; i < aNbFF; ++i)
+ {
+ const BOPDS_InterfFF& aFF = aFFs(i);
+ const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
+ Standard_Integer aNbC = aVNC.Extent();
+ for (j = 0; j < aNbC; ++j)
+ {
+ const BOPDS_Curve& aNC = aVNC(j);
+ const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
+ aItPB.Initialize(aLPBC);
+ for (; aItPB.More(); aItPB.Next())
+ anAllPBs.Append(aItPB.Value());
+ }
+ }
+
+ // Get pave blocks from the pool
BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
aNbPBP = aPBP.Extent();
for (i = 0; i < aNbPBP; ++i) {
BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
- //
aItPB.Initialize(aLPB);
- for (; aItPB.More(); aItPB.Next()) {
- Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
- const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
- bCB = !aCB.IsNull();
- if (bCB) {
- aPB = aCB->PaveBlock1();
- }
+ for (; aItPB.More(); aItPB.Next())
+ anAllPBs.Append(aItPB.Value());
+ }
+
+ // Process all pave blocks
+ aItPB.Initialize(anAllPBs);
+ for (; aItPB.More(); aItPB.Next())
+ {
+ Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
+ const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
+ bCB = !aCB.IsNull();
+ if (bCB) {
+ aPB = aCB->PaveBlock1();
+ }
+ //
+ if (aMPB.Add(aPB)) {
+ bRebuild = Standard_False;
+ aPB->Indices(nV[0], nV[1]);
+ aPB->Range(aT[0], aT[1]);
+ // remember the fact if the edge had different vertices before substitution
+ Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
//
- if (aMPB.Add(aPB)) {
- bRebuild = Standard_False;
- aPB->Indices(nV[0], nV[1]);
- aPB->Range(aT[0], aT[1]);
- // remember the fact if the edge had different vertices before substitution
- Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
- //
- for (j = 0; j < 2; ++j) {
- if (aDMNewSD.IsBound(nV[j])) {
- BOPDS_Pave aPave;
- //
- nV[j] = aDMNewSD.Find(nV[j]);
- aPave.SetIndex(nV[j]);
- aPave.SetParameter(aT[j]);
- //
- bRebuild = Standard_True;
- if (!j) {
- aPB->SetPave1(aPave);
- }
- else {
- aPB->SetPave2(aPave);
- }
- }
- }
- //
- if (bRebuild) {
- Standard_Boolean isDegEdge = myDS->ShapeInfo(aPB->Edge()).HasFlag();
- if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
- // now edge has the same vertex on both ends;
- // check if it is not a regular closed curve.
- const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
- const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
- Standard_Real aLength = IntTools::Length(aE);
- Standard_Real aTolV = BRep_Tool::Tolerance(aV);
- if (aLength <= aTolV * 2.) {
- // micro edge, so mark it for removal
- aMicroEdges.Add(aPB->Edge());
- continue;
- }
- }
- nSp = SplitEdge(aPB->OriginalEdge(), nV[0], aT[0], nV[1], aT[1]);
- if (bCB) {
- aCB->SetEdge(nSp);
+ for (j = 0; j < 2; ++j) {
+ if (aDMNewSD.IsBound(nV[j])) {
+ BOPDS_Pave aPave;
+ //
+ nV[j] = aDMNewSD.Find(nV[j]);
+ aPave.SetIndex(nV[j]);
+ aPave.SetParameter(aT[j]);
+ //
+ bRebuild = Standard_True;
+ if (!j) {
+ aPB->SetPave1(aPave);
}
else {
- aPB->SetEdge(nSp);
+ aPB->SetPave2(aPave);
+ }
+ }
+ }
+ //
+ if (bRebuild) {
+ Standard_Boolean isDegEdge = myDS->ShapeInfo(aPB->Edge()).HasFlag();
+ if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
+ // now edge has the same vertex on both ends;
+ // check if it is not a regular closed curve.
+ const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
+ const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
+ Standard_Real aLength = IntTools::Length(aE);
+ Standard_Real aTolV = BRep_Tool::Tolerance(aV);
+ if (aLength <= aTolV * 2.) {
+ // micro edge, so mark it for removal
+ aMicroEdges.Add(aPB->Edge());
+ continue;
}
- }// if (bRebuild) {
- }// if (aMPB.Add(aPB)) {
- }// for (; aItPB.More(); aItPB.Next()) {
- }// for (i=0; i<aNbPBP; ++i) {
+ }
+ nSp = SplitEdge(aPB->Edge(), nV[0], aT[0], nV[1], aT[1]);
+ if (bCB)
+ aCB->SetEdge(nSp);
+ else
+ aPB->SetEdge(nSp);
+ }// if (bRebuild) {
+ }// if (aMPB.Add(aPB)) {
+ }// for (; aItPB.More(); aItPB.Next()) {
aMPB.Clear();
if (aMicroEdges.Extent())
Standard_Real aTolR3D = aFF.TolR3D();
Standard_Real aTolReal = aFF.TolReal();
Standard_Boolean bToReduce = aTolReal < aTolR3D;
- // tolerance of intersection has been increased, so process this intersection
+ // tolerance of intersection has been increased, so process this intersection
BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
- Standard_Integer aNbC = aVNC.Extent(), k;
- for (k = 0; k < aNbC; ++k) {
+ Standard_Integer aNbC = aVNC.Extent(), k;
+ for (k = 0; k < aNbC; ++k) {
BOPDS_Curve& aNC = aVNC(k);
BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
- BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
for (; aItLPB.More(); ) {
- const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
- Standard_Integer nE;
+ const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+ Standard_Integer nE;
if (!aPB->HasEdge(nE)) {
aLPB.Remove(aItLPB);
- continue;
- }
+ continue;
+ }
//
Standard_Boolean bIsReduced = Standard_False;
if (bToReduce && (aPB->OriginalEdge() < 0)) {
}
}
//
- // fill in the map vertex index - pave blocks
- for (Standard_Integer j=0; j < 2; j++) {
+ // fill in the map vertex index - pave blocks
+ for (Standard_Integer j=0; j < 2; j++) {
Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
- BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
- if (!pPBList) {
- pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
- }
+ BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
+ if (!pPBList) {
+ pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
+ }
pPBList->Append(aPB);
if (bIsReduced) {
aMVIToReduce.Add(nV);
const TopoDS_Face& ,
const Standard_Real ,
const Standard_Real ,
+ const Standard_Real,
Standard_Real& ,
const Handle(IntTools_Context)& );
aTol2D2 = aTol2D * aTol2D;
//
bIsClosed = aVertMap.Find(aVb);
- //
- aNb=aLS.Length();
- if (aNb>0) {
- //
+ {
BOPCol_ListOfShape aBuf;
//
- for (i=aNb; i>0; --i) {
+ aNb = aLS.Length();
+ for (i = aNb; i>0; --i) {
const TopoDS_Shape& aVPrev=aVertVa(i);
const gp_Pnt2d& aPaPrev=aCoordVa(i);
const TopoDS_Shape& aEPrev=aLS(i);
anAngleIn = AngleIn(aEOuta, aLEInfo);
aMinAngle = 100.;
anIsFound = Standard_False;
+ Standard_Integer iCnt = NbWaysOut(aLEInfo);
Standard_Integer aCurIndexE = 0;
anIt.Initialize(aLEInfo);
for (; anIt.More(); anIt.Next()) {
//
// Is there one way to go out of the vertex
// we have to use it only.
- Standard_Integer iCnt;
- iCnt=NbWaysOut (aLEInfo);
//
if (!iCnt) {
// no way to go . (Error)
BOPCol_DataMapOfShapeReal aDMSR;
BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
//
- aA1=0.;
- aA2=0.;
+ aA1=0.; // angle of outgoing edge
+ aA2=0.; // angle of incoming edge
iCntBnd=0;
iCntInt=0;
aItLEI.Initialize(aLEI);
aA1=aA;
}
else {
- aA2=aA+M_PI;
+ aA2=aA;
}
}
else {
return;
}
//
+ Standard_Real aDelta = ClockWiseAngle(aA2, aA1);
aItLEI.Initialize(aLEI);
for (; aItLEI.More(); aItLEI.Next()) {
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
}
//
aA=aEI.Angle();
- if (aA>aA1 && aA<aA2) {
- continue;
+ Standard_Real aDA = ClockWiseAngle(aA2, aA);
+ if (aDA < aDelta) {
+ continue; // already inside
}
//
- bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aA, theContext);
+ bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aDelta, aA, theContext);
if (bRefined) {
aDMSR.Bind(aE, aA);
}
const TopoDS_Face& myFace,
const Standard_Real aA1,
const Standard_Real aA2,
+ const Standard_Real aDelta,
Standard_Real& aA,
const Handle(IntTools_Context)& theContext)
{
//
aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
//
+ const Standard_Real MaxDT = 0.3 * (aT2 - aT1);
aGAC1.D0(aT1, aP1);
aGAC1.D0(aT2, aP2);
aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
//
for (i=0; i<2; ++i) {
- aAi=(!i) ? aA1 : aA2;
+ aAi=(!i) ? aA1 : (aA2 + M_PI);
aXi=cos(aAi);
aYi=sin(aAi);
gp_Dir2d aDiri(aXi, aYi);
continue;
}
//
- aNbP=aGInter.NbPoints();
- if (aNbP<2) {
- continue;
- }
- //
- aT1max=aTV;
- aT2max=-1.;
- for (j=1; j<=aNbP; ++j) {
- const IntRes2d_IntersectionPoint& aIPj=aGInter.Point(j);
- aT1j=aIPj.ParamOnFirst();
- aT2j=aIPj.ParamOnSecond();
+ aNbP = aGInter.NbPoints();
+ aT1max = aTV;
+ aT2max = -1.;
+ for (j = 1; j <= aNbP; ++j) {
+ const IntRes2d_IntersectionPoint& aIPj = aGInter.Point(j);
+ aT1j = aIPj.ParamOnFirst();
+ aT2j = aIPj.ParamOnSecond();
//
- if (aT2j > aT2max) {
- aT2max=aT2j;
- aT1max=aT1j;
+ if (aT2j > aT2max && Abs(aT1j - aTV) < MaxDT) {
+ aT2max = aT2j;
+ aT1max = aT1j;
}
}
//
- dT = aTOp - aT1max;
- if (Abs(dT) < aTolInt) {
- continue;
- }
- //
- aT=aT1max + aCf*dT;
- aGAC1.D0(aT, aP);
- gp_Vec2d aV2D(aPV, aP);
- gp_Dir2d aDir2D(aV2D);
- //
- aAngle=Angle(aDir2D);
- if (aAngle>aA1 && aAngle<aA2) {
- aA=aAngle;
- return bRet;
+ if (aT2max > 0) {
+ dT = aTOp - aT1max;
+ if (Abs(dT) < aTolInt) {
+ continue;
+ }
+ //
+ aT = aT1max + aCf*dT;
+ aGAC1.D0(aT, aP);
+ gp_Vec2d aV2D(aPV, aP);
+ gp_Dir2d aDir2D(aV2D);
+ //
+ aAngle = Angle(aDir2D);
+ Standard_Real aDA = ClockWiseAngle(aA2, aAngle);
+ if (aDA < aDelta) {
+ aA = aAngle;
+ return bRet;
+ }
}
}// for (i=0; i<2; ++i) {
return !bRet;
-}
+}
\ No newline at end of file
//
myLines.Append1()=theSI;
iX=myLines.Extent()-1;
+ myMapShapeIndex.Bind(theSI.Shape(), iX);
//
return iX;
}
//
myLines.Append1().SetShape(theS);
iX=myLines.Extent()-1;
+ myMapShapeIndex.Bind(theS, iX);
return iX;
}
//=======================================================================
aAllocator=
NCollection_BaseAllocator::CommonBaseAllocator();
//
- BOPCol_DataMapOfShapeInteger& aMSI=myMapShapeIndex;
//
i1=0;
i2=0;
aIt.Initialize(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS=aIt.Value();
- if (aMSI.IsBound(aS)) {
+ if (myMapShapeIndex.IsBound(aS)) {
continue;
}
aI=Append(aS);
- aMSI.Bind(aS, aI);
//
- InitShape(aI, aS, aAllocator, aMSI);
+ InitShape(aI, aS);
//
i2=NbShapes()-1;
aR.SetIndices(i1, i2);
//=======================================================================
void BOPDS_DS::InitShape
(const Standard_Integer aI,
- const TopoDS_Shape& aS,
- const Handle(NCollection_BaseAllocator)& theAllocator,
- BOPCol_DataMapOfShapeInteger& aMSI)
+ const TopoDS_Shape& aS)
{
Standard_Integer aIx;
TopoDS_Iterator aIt;
aSI.SetShapeType(aS.ShapeType());
BOPCol_ListOfInteger& aLI=aSI.ChangeSubShapes();
//
- BOPCol_MapOfInteger aM(100, theAllocator);
+ BOPCol_MapOfInteger aM;
//
aIt1.Initialize(aLI);
for (; aIt1.More(); aIt1.Next()) {
aIt.Initialize(aS);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSx=aIt.Value();
- if (aMSI.IsBound(aSx)) {
- aIx=aMSI.Find(aSx);
- }
- else {
- aIx=Append(aSx);
- aMSI.Bind(aSx, aIx);
- }
+ const Standard_Integer* pIx = myMapShapeIndex.Seek(aSx);
+ aIx = (pIx ? *pIx : Append(aSx));
//
- InitShape(aIx, aSx, theAllocator, aMSI);
+ InitShape(aIx, aSx);
//
if (aM.Add(aIx)) {
aLI.Append(aIx);
//! Initializes the state of face with index theIndex
Standard_EXPORT void InitFaceInfo (const Standard_Integer theIndex);
- Standard_EXPORT void InitShape (const Standard_Integer theIndex, const TopoDS_Shape& theS, const BOPCol_BaseAllocator& theAllocator, BOPCol_DataMapOfShapeInteger& theMSI);
+ Standard_EXPORT void InitShape (const Standard_Integer theIndex, const TopoDS_Shape& theS);
Standard_EXPORT Standard_Boolean CheckCoincidence (const Handle(BOPDS_PaveBlock)& thePB1,
const Handle(BOPDS_PaveBlock)& thePB2,
di << " Index: " << ind << "\n";
}
else {
- Standard_Integer i1, i2;
- //
- i1 = pDS->NbSourceShapes();
- i2 = pDS->NbShapes();
- for (ind = i1; ind < i2; ++ind) {
- const TopoDS_Shape& aSx = pDS->Shape(ind);
- if (aSx.IsSame(aS)) {
- di << " Index: " << ind << "\n";
- bFound = Standard_True;
- break;
- }
- }
- }
- //
- if (!bFound) {
di << " DS does not contain the shape\n";
}
//
#include <BRep_Tool.hxx>
#include <BRep_TVertex.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepAdaptor_Curve.hxx>
#include <BRepLib_CheckCurveOnSurface.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <Extrema_LocateExtPC.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomProjLib.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <IntRes2d_Domain.hxx>
const TopoDS_Face& theF,
const Handle(Geom_Surface)& theS,
const TopoDS_Edge& theE1,
- const TopoDS_Edge& theE2);
+ const TopoDS_Edge& theE2,
+ NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen);
//=======================================================================
//class : BOPTools_CPC
TopAbs_VERTEX,
TopAbs_EDGE,
aMVE);
+ NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
aNbV=aMVE.Extent();
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
continue;
}
//
- aD2 = IntersectCurves2d(aV, aF, aS, aE1, aE2);
+ aD2 = IntersectCurves2d(aV, aF, aS, aE1, aE2, aMapEdgeLen);
if (aD2 > aD2max) {
aD2max = aD2;
}
}// for (i=1; i<=aNbV; ++i) {
}
+//=======================================================================
+// Function : MapEdgeLength
+// purpose : Compute edge length and cache it in the map
+//=======================================================================
+static Standard_Real MapEdgeLength(const TopoDS_Edge& theEdge,
+ NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
+{
+ const Standard_Real* pLen = theMapEdgeLen.Seek(theEdge);
+ if (!pLen)
+ {
+ Standard_Real aLen = 0.;
+ if (!BRep_Tool::Degenerated(theEdge))
+ {
+ BRepAdaptor_Curve aCurve(theEdge);
+ aLen = GCPnts_AbscissaPoint::Length(aCurve);
+ }
+ pLen = theMapEdgeLen.Bound(theEdge, aLen);
+ }
+ return *pLen;
+}
//=======================================================================
// Function : IntersectCurves2d
// purpose : Intersect 2d curves of edges
const TopoDS_Face& theF,
const Handle(Geom_Surface)& theS,
const TopoDS_Edge& theE1,
- const TopoDS_Edge& theE2)
+ const TopoDS_Edge& theE2,
+ NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
{
Standard_Real aT11, aT12, aT21, aT22, aTol2d, aMaxDist;
Geom2dInt_GInter anInter;
aC2D2->Value(aT22), aT22, aTol2d);
//
anInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
- if (!anInter.IsDone()) {
+ if (!anInter.IsDone() || (!anInter.NbSegments() && !anInter.NbPoints())) {
return aMaxDist;
}
//
aLP.Append(aPnt);
}
//
+ // evaluate the length of the smallest edge, so that not to return too large distance
+ Standard_Real aLen1 = MapEdgeLength(theE1, theMapEdgeLen);
+ Standard_Real aLen2 = MapEdgeLength(theE2, theMapEdgeLen);
+ const Standard_Real MaxEdgePartCoveredByVertex = 0.3;
+ Standard_Real aMaxThresDist = Min(aLen1, aLen2) * MaxEdgePartCoveredByVertex;
+ aMaxThresDist *= aMaxThresDist;
aItLP.Initialize(aLP);
for (; aItLP.More(); aItLP.Next()) {
const IntRes2d_IntersectionPoint& aPnt = aItLP.Value();
aP2d = aPnt.Value();
theS->D0(aP2d.X(), aP2d.Y(), aP);
aDist = aPV.SquareDistance(aP);
- if (aDist > aMaxDist) {
+ if (aDist > aMaxDist && aDist < aMaxThresDist) {
aMaxDist = aDist;
}
}
aProjector.Perform(aP1);
aNbProj=aProjector.NbPoints();
- if (!aNbProj) {
- return -3;
+ if (aNbProj)
+ {
+ // point falls on the curve
+ aDist = aProjector.LowerDistance();
+ //
+ aTolE2 = BRep_Tool::Tolerance(aE2);
+ aTolSum = aTolP1 + aTolE2 + Precision::Confusion();
+ //
+ aT = aProjector.LowerDistanceParameter();
+ if (aDist > aTolSum) {
+ return -4;
+ }
}
- //
- aDist=aProjector.LowerDistance();
- //
- aTolE2=BRep_Tool::Tolerance(aE2);
- aTolSum = aTolP1 + aTolE2 + Precision::Confusion();
- //
- aT=aProjector.LowerDistanceParameter();
- if (aDist > aTolSum) {
- return -4;
+ else
+ {
+ // point falls out of the curve, check distance to vertices
+ TopoDS_Edge aEFwd = TopoDS::Edge(aE2.Oriented(TopAbs_FORWARD));
+ TopoDS_Iterator itV(aEFwd);
+ aDist = RealLast();
+ for (; itV.More(); itV.Next())
+ {
+ const TopoDS_Vertex& aV = TopoDS::Vertex(itV.Value());
+ if (aV.Orientation() == TopAbs_FORWARD || aV.Orientation() == TopAbs_REVERSED)
+ {
+ gp_Pnt aPV = BRep_Tool::Pnt(aV);
+ aTolSum = aTolP1 + BRep_Tool::Tolerance(aV) + Precision::Confusion();
+ Standard_Real aDist1 = aP1.SquareDistance(aPV);
+ if (aDist1 < aDist && aDist1 < Square(aTolSum))
+ {
+ aDist = aDist1;
+ aT = BRep_Tool::Parameter(aV, aEFwd);
+ }
+ }
+ }
+ if (Precision::IsInfinite(aDist)) {
+ return -3;
+ }
}
return 0;
}
--- /dev/null
+puts "========"
+puts "OCC28017"
+puts "========"
+puts ""
+#################################################
+# Unexpected result of General Fuse operation
+#################################################
+
+restore [locate_data_file bug28017_shape.brep] a
+
+explode a
+bclearobjects
+bcleartools
+baddobjects a_1
+baddtools a_2
+bfillds
+bbuild r
+
+checkmaxtol r -min_tol 0.51
+explode r So
+checknbshapes r -solid 2
+checkshape r_1
+checkshape r_2
+bopcheck r_1
+bopcheck r_2
+don r_1 r_2
+smallview; fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
-puts "TODO OCC23748 ALL: Faulty shapes in variables faulty_1 to faulty_"
-puts "TODO OCC23748 ALL: Error : The volume of result shape is"
+puts "TODO OCC23748 ALL: ERROR. offsetperform operation not done."
+puts "TODO OCC23748 ALL: Error: The command cannot be built"
+puts "TODO OCC23748 ALL: Error : The offset cannot be built."
psphere s 15 270
OFFSETSHAPE 1 {s_2} $calcul $type