diff --git a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx index c715e05984..752ff41836 100644 --- a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx +++ b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx @@ -699,28 +699,11 @@ void BOPAlgo_ArgumentAnalyzer::TestTangent() } } else if(theType == TopAbs_EDGE) { - Standard_Integer aDiscretize = 30; - Standard_Real aDeflection = 0.01; const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&(aS1); const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&(aS2); - - IntTools_EdgeEdge aEE; - aEE.SetEdge1 (aE1); - aEE.SetEdge2 (aE2); - aEE.SetTolerance1 (BRep_Tool::Tolerance(aE1)); - aEE.SetTolerance2 (BRep_Tool::Tolerance(aE2)); - aEE.SetDiscretize (aDiscretize); - aEE.SetDeflection (aDeflection); - - Standard_Real f = 0., l = 0.; - BRep_Tool::Range(aE1, f, l); - aEE.SetRange1(f, l); - - BRep_Tool::Range(aE2, f, l); - aEE.SetRange2(f, l); - - aEE.Perform(); - + // + IntTools_EdgeEdge aEE(aE1, aE2); + // if (aEE.IsDone()) { const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts(); Standard_Integer ii = 0; diff --git a/src/BOPAlgo/BOPAlgo_BOP.cdl b/src/BOPAlgo/BOPAlgo_BOP.cdl index 3f2e37ad54..064e36883d 100644 --- a/src/BOPAlgo/BOPAlgo_BOP.cdl +++ b/src/BOPAlgo/BOPAlgo_BOP.cdl @@ -20,6 +20,7 @@ uses Shape from TopoDS, BaseAllocator from BOPCol, ListOfShape from BOPCol, + ListOfShape from TopTools, MapOfShape from BOPCol, IndexedDataMapOfShapeListOfShape from BOPCol, Operation from BOPAlgo, @@ -97,6 +98,14 @@ is returns Boolean from Standard is protected; + Generated (me:out; + theS : Shape from TopoDS) + ---Purpose: Returns the list of shapes generated from the + -- shape theS. + returns ListOfShape from TopTools + is redefined; + ---C++: return const & + fields myNbArgs : Integer from Standard is protected; myOperation : Operation from BOPAlgo is protected; diff --git a/src/BOPAlgo/BOPAlgo_BOP_1.cxx b/src/BOPAlgo/BOPAlgo_BOP_1.cxx index 6dd627f07e..6ce06ed151 100644 --- a/src/BOPAlgo/BOPAlgo_BOP_1.cxx +++ b/src/BOPAlgo/BOPAlgo_BOP_1.cxx @@ -136,3 +136,45 @@ // myShape=aRC; } + +//======================================================================= +//function : Generated +//purpose : +//======================================================================= +const TopTools_ListOfShape& BOPAlgo_BOP::Generated(const TopoDS_Shape& theS) +{ + myHistShapes.Clear(); + if (theS.IsNull() || (myOperation != BOPAlgo_SECTION)) { + return myHistShapes; + } + // + TopAbs_ShapeEnum aType = theS.ShapeType(); + if (aType != TopAbs_FACE) { + return myHistShapes; + } + // + Standard_Integer nS = myDS->Index(theS); + if (nS < 0) { + return myHistShapes; + } + // + if (!myDS->HasFaceInfo(nS)) { + return myHistShapes; + } + // + //collect section edges of the face theS + Standard_Integer i, aNb, nSp; + // + const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nS); + const BOPDS_IndexedMapOfPaveBlock& aMPBSc = aFI.PaveBlocksSc(); + aNb = aMPBSc.Extent(); + for (i = 1; i <= aNb; ++i) { + const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i); + nSp = aPB->Edge(); + const TopoDS_Shape& aSp = myDS->Shape(nSp); + myHistShapes.Append(aSp); + } + // + return myHistShapes; +} + diff --git a/src/BOPAlgo/BOPAlgo_Builder_4.cxx b/src/BOPAlgo/BOPAlgo_Builder_4.cxx index f22482b300..ca706f2204 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_4.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_4.cxx @@ -29,55 +29,9 @@ //function : Generated //purpose : //======================================================================= - const TopTools_ListOfShape& BOPAlgo_Builder::Generated(const TopoDS_Shape& theS) + const TopTools_ListOfShape& BOPAlgo_Builder::Generated(const TopoDS_Shape&) { - Standard_Boolean bHasImage, bToReverse; - TopAbs_ShapeEnum aType; - BOPCol_ListIteratorOfListOfShape aIt; - // myHistShapes.Clear(); - // - if (theS.IsNull()) { - return myHistShapes; - } - // - bHasImage=myImages.IsBound(theS); - if (!bHasImage) { - return myHistShapes; - } - // - aType=theS.ShapeType(); - // - if (!(aType==TopAbs_EDGE || aType==TopAbs_FACE || - aType==TopAbs_VERTEX || aType==TopAbs_SOLID)) { - return myHistShapes; - } - // - //PrepareHistory(); - // - const BOPCol_ListOfShape& aLSp=myImages.Find(theS); - aIt.Initialize(aLSp); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aSp=aIt.Value(); - if (myShapesSD.IsBound(aSp)) { - if (myMapShape.Contains(aSp)) { - TopoDS_Shape aSpR=myShapesSD.Find(aSp); - // - if (aType==TopAbs_VERTEX || aType==TopAbs_SOLID) { - aSpR.Orientation(theS.Orientation()); - } - else { - bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSpR, theS, myContext); - if (bToReverse) { - aSpR.Reverse(); - } - } - // - myHistShapes.Append(aSpR); - } - } - } - // return myHistShapes; } //======================================================================= @@ -114,21 +68,23 @@ aIt.Initialize(aLSp); for (; aIt.More(); aIt.Next()) { TopoDS_Shape aSp=aIt.Value(); - if (!myShapesSD.IsBound(aSp)) { - if (myMapShape.Contains(aSp)) { - // - if (aType==TopAbs_VERTEX || aType==TopAbs_SOLID) { - aSp.Orientation(theS.Orientation()); - } - else { - bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, theS, myContext); - if (bToReverse) { - aSp.Reverse(); - } - } - // - myHistShapes.Append(aSp); + if (myShapesSD.IsBound(aSp)) { + aSp = myShapesSD.Find(aSp); + } + // + if (myMapShape.Contains(aSp)) { + // + if (aType==TopAbs_VERTEX || aType==TopAbs_SOLID) { + aSp.Orientation(theS.Orientation()); } + else { + bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, theS, myContext); + if (bToReverse) { + aSp.Reverse(); + } + } + // + myHistShapes.Append(aSp); } } // @@ -175,13 +131,13 @@ // if (!myShapesSD.IsBound(aSp)) { if (myMapShape.Contains(aSp)) { - return bRet; //false + return bRet; //false } } else { TopoDS_Shape aSpR=myShapesSD.Find(aSp); if (myMapShape.Contains(aSpR)) { - return bRet; //false + return bRet; //false } } } @@ -201,7 +157,7 @@ return; } // - Standard_Boolean bHasImage, bContainsSD; + Standard_Boolean bHasImage; TopAbs_ShapeEnum aType; BOPCol_MapOfShape aMS; BOPCol_ListIteratorOfListOfShape aIt; @@ -232,18 +188,18 @@ BOPCol_ListOfShape aLSx; if (!bHasImage) { if (myMapShape.Contains(aSx)) { - aLSx.Append(aSx); - myImagesResult.Add(aSx, aLSx); + aLSx.Append(aSx); + myImagesResult.Add(aSx, aLSx); } } else { const BOPCol_ListOfShape& aLSp=myImages.Find(aSx); aIt.Initialize(aLSp); for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aSp=aIt.Value(); - if (myMapShape.Contains(aSp)) { - aLSx.Append(aSp); - } + const TopoDS_Shape& aSp=aIt.Value(); + if (myMapShape.Contains(aSp)) { + aLSx.Append(aSp); + } } myImagesResult.Add(aSx, aLSx); } @@ -254,55 +210,19 @@ myHasDeleted=IsDeleted(aSx); } // - if (!myHasGenerated || !myHasModified) { + if (!myHasModified && bHasImage) { if (aType==TopAbs_EDGE || aType==TopAbs_FACE || - aType==TopAbs_VERTEX || aType==TopAbs_SOLID) { - if (bHasImage) { - const BOPCol_ListOfShape& aLSp=myImages.Find(aSx); - aIt.Initialize(aLSp); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aSp=aIt.Value(); - // - if (myMapShape.Contains(aSp)) { - bContainsSD=myShapesSD.IsBound(aSp); - // - if (!myHasGenerated) { - if (bContainsSD) { - myHasGenerated=Standard_True; - } - } - if (!myHasModified) { - if (!bContainsSD) { - myHasModified=Standard_True; - } - } - } // if (myMapShape.Contains(aSp)) - } - } + aType==TopAbs_VERTEX || aType==TopAbs_SOLID) { + myHasModified = Standard_True; } } + // + if (!myHasGenerated) { + if (aType==TopAbs_FACE) { + const TopTools_ListOfShape& aLG = Generated(aSx); + myHasGenerated = aLG.Extent() > 0; + } + } } myFlagHistory=Standard_True; } - -// <- A - /* - BOPCol_ListOfShape aLSx; - if (!bHasImage) { - if (myMapShape.Contains(aSx)) { - aLSx.Append(aSx); - myImagesResult.Add(aSx, aLSx); - } - } - else { - const BOPCol_ListOfShape& aLSp=myImages.Find(aSx); - aIt.Initialize(aLSp); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aSp=aIt.Value(); - if (myMapShape.Contains(aSp)) { - aLSx.Append(aSp); - } - } - myImagesResult.Add(aSx, aLSx); - } - */ diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx index 9143e7205b..1d22a853f6 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx @@ -23,6 +23,8 @@ #include +#include + #include #include #include @@ -42,6 +44,7 @@ #include #include #include +#include // #include #include @@ -56,28 +59,24 @@ #include #include #include -#include - +// #include -#include + //======================================================================= // function: PerformEE // purpose: //======================================================================= - void BOPAlgo_PaveFiller::PerformEE() +void BOPAlgo_PaveFiller::PerformEE() { - Standard_Boolean bJustAdd, bOrder; - Standard_Integer i, iX, iSize, nE1, nE2, aDiscretize; - Standard_Integer aNbCPrts, nWhat, nWith; + Standard_Boolean bJustAdd; + Standard_Integer i, iX, iSize, nE1, nE2; + Standard_Integer aNbCPrts; Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22; - Standard_Real aTolE1, aTolE2, aDeflection; TopAbs_ShapeEnum aType; - TopoDS_Edge aEWhat, aEWith; BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2; Handle(NCollection_IncAllocator) aAllocator; - Handle(BOPDS_PaveBlock) aPBn1, aPBn2; BOPDS_MapOfPaveBlock aMPBToUpdate; BOPDS_MapIteratorOfMapOfPaveBlock aItPB; // @@ -94,9 +93,6 @@ BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator); BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator); // - aDiscretize=30; - aDeflection=0.01; - // BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); aEEs.SetStartSize(iSize); aEEs.SetIncrement(iSize); @@ -120,9 +116,6 @@ const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape())); const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape())); // - aTolE1=BRep_Tool::Tolerance(aE1); - aTolE2=BRep_Tool::Tolerance(aE2); - // BOPDS_ListOfPaveBlock& aLPB1=myDS->ChangePaveBlocks(nE1); BOPDS_ListOfPaveBlock& aLPB2=myDS->ChangePaveBlocks(nE2); // @@ -156,75 +149,23 @@ continue; } // - // -----------f - //DEBft - //printf(" nE1=%d nE2=%d\n", nE1, nE2); - // - IntTools_EdgeEdge aEdgeEdge; - // - aEdgeEdge.SetEdge1 (aE1); - aEdgeEdge.SetEdge2 (aE2); - aEdgeEdge.SetTolerance1 (aTolE1); - aEdgeEdge.SetTolerance2 (aTolE2); - aEdgeEdge.SetDiscretize (aDiscretize); - aEdgeEdge.SetDeflection (aDeflection); - // - IntTools_Range aSR1(aTS11, aTS12); - IntTools_Range aSR2(aTS21, aTS22); - IntTools_Range anewSR1 = aSR1; - IntTools_Range anewSR2 = aSR2; - // - BOPTools_AlgoTools::CorrectRange (aE1, aE2, aSR1, anewSR1); - BOPTools_AlgoTools::CorrectRange (aE2, aE1, aSR2, anewSR2); + IntTools_EdgeEdge anEdgeEdge; // aPB1->Range(aT11, aT12); aPB2->Range(aT21, aT22); - IntTools_Range aPBRange1(aT11, aT12), aPBRange2(aT21, aT22); // - IntTools_Range aPBR1 = aPBRange1; - IntTools_Range aPBR2 = aPBRange2; - BOPTools_AlgoTools::CorrectRange (aE1, aE2, aPBR1, aPBRange1); - BOPTools_AlgoTools::CorrectRange (aE2, aE1, aPBR2, aPBRange2); + anEdgeEdge.SetEdge1(aE1, aT11, aT12); + anEdgeEdge.SetEdge2(aE2, aT21, aT22); // - aEdgeEdge.SetRange1(aPBRange1); - aEdgeEdge.SetRange2(aPBRange2); - // - aEdgeEdge.Perform(); - if (!aEdgeEdge.IsDone()) { + anEdgeEdge.Perform(); + if (!anEdgeEdge.IsDone()) { continue; } // - bOrder=aEdgeEdge.Order(); - if (!bOrder) { - aEWhat=aE1; - aEWith=aE2; - nWhat=nE1; - nWith=nE2; - aSR1=anewSR1; - aSR2=anewSR2; - aPBR1=aPBRange1; - aPBR2=aPBRange2; - aPBn1=aPB1; - aPBn2=aPB2; - } - else { - nWhat=nE2; - nWith=nE1; - aEWhat=aE2; - aEWith=aE1; - aSR1=anewSR2; - aSR2=anewSR1; - aPBR1=aPBRange2; - aPBR2=aPBRange1; - aPBn1=aPB2; - aPBn2=aPB1; - } - // - IntTools_Range aR11(aPBR1.First(), aSR1.First()), aR12(aSR1.Last(), aPBR1.Last()), - aR21(aPBR2.First(), aSR2.First()), aR22(aSR2.Last(), aPBR2.Last()); - // - const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeEdge.CommonParts(); + IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12), + aR21(aT21, aTS21), aR22(aTS22, aT22); // + const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts(); aNbCPrts=aCPrts.Length(); for (i=1; i<=aNbCPrts; ++i) { const IntTools_CommonPrt& aCPart=aCPrts(i); @@ -235,18 +176,25 @@ Standard_Integer nV[4], j; Standard_Real aT1, aT2, aTol; TopoDS_Vertex aVnew; + IntTools_Range aCR1, aCR2; // BOPInt_Tools::VertexParameters(aCPart, aT1, aT2); - aTol=Precision::Confusion(); + aTol = Precision::Confusion(); + aCR1 = aCPart.Range1(); + aCR2 = aCPart.Ranges2()(1); // //decide to keep the pave or not - bIsOnPave[0] = BOPInt_Tools::IsOnPave1(aT1, aR11, aTol); - bIsOnPave[1] = BOPInt_Tools::IsOnPave1(aT1, aR12, aTol); - bIsOnPave[2] = BOPInt_Tools::IsOnPave1(aT2, aR21, aTol); - bIsOnPave[3] = BOPInt_Tools::IsOnPave1(aT2, aR22, aTol); + bIsOnPave[0] = BOPInt_Tools::IsOnPave1(aT1, aR11, aTol) || + BOPInt_Tools::IsOnPave1(aR11.First(), aCR1, aTol); + bIsOnPave[1] = BOPInt_Tools::IsOnPave1(aT1, aR12, aTol) || + BOPInt_Tools::IsOnPave1(aR12.Last(), aCR1, aTol); + bIsOnPave[2] = BOPInt_Tools::IsOnPave1(aT2, aR21, aTol) || + BOPInt_Tools::IsOnPave1(aR21.First(), aCR2, aTol); + bIsOnPave[3] = BOPInt_Tools::IsOnPave1(aT2, aR22, aTol) || + BOPInt_Tools::IsOnPave1(aR22.Last(), aCR2, aTol); // - aPBn1->Indices(nV[0], nV[1]); - aPBn2->Indices(nV[2], nV[3]); + aPB1->Indices(nV[0], nV[1]); + aPB2->Indices(nV[2], nV[3]); // if((bIsOnPave[0] && bIsOnPave[2]) || (bIsOnPave[0] && bIsOnPave[3]) || (bIsOnPave[1] && bIsOnPave[2]) || (bIsOnPave[1] && bIsOnPave[3])) { @@ -257,7 +205,7 @@ for (j = 0; j < 4; ++j) { if (bIsOnPave[j]) { //add interf VE(nV[j], nE) - Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPBn2 : aPBn1; + Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1; ForceInterfVE(nV[j], aPB, aMPBToUpdate); bFlag = Standard_True; break; @@ -267,7 +215,7 @@ continue; } // - BOPTools_AlgoTools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aVnew); + BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew); // <-LXBR { Standard_Integer nVS[2], iFound, k; @@ -310,14 +258,14 @@ continue; } } - + // 1 iX=aEEs.Append()-1; BOPDS_InterfEE& aEE=aEEs(iX); - aEE.SetIndices(nWhat, nWith); + aEE.SetIndices(nE1, nE2); aEE.SetCommonPart(aCPart); // 2 - myDS->AddInterf(nWhat, nWith); + myDS->AddInterf(nE1, nE2); // BOPDS_CoupleOfPaveBlocks aCPB; // @@ -328,14 +276,11 @@ break; // case TopAbs_EDGE: { - Standard_Boolean bHasSameBounds; - Standard_Integer aNbComPrt2; - // - aNbComPrt2=aCPart.Ranges2().Length(); - if (aNbComPrt2>1){ + if (aNbCPrts > 1) { break; } - //// <-LXBR + // + Standard_Boolean bHasSameBounds; bHasSameBounds=aPB1->HasSameBounds(aPB2); if (!bHasSameBounds) { break; @@ -343,10 +288,10 @@ // 1 iX=aEEs.Append()-1; BOPDS_InterfEE& aEE=aEEs(iX); - aEE.SetIndices(nWhat, nWith); + aEE.SetIndices(nE1, nE2); aEE.SetCommonPart(aCPart); // 2 - myDS->AddInterf(nWhat, nWith); + myDS->AddInterf(nE1, nE2); // BOPAlgo_Tools::FillMap(aPB1, aPB2, aMPBLPB, aAllocator); }//case TopAbs_EDGE @@ -388,9 +333,9 @@ //function : PerformVertices //purpose : //======================================================================= - Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE - (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, - Handle(NCollection_BaseAllocator)& theAllocator) +Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE + (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, + Handle(NCollection_BaseAllocator)& theAllocator) { Standard_Integer aNbV, iRet; // @@ -523,9 +468,9 @@ //function : TreatNewVertices //purpose : //======================================================================= - void BOPAlgo_PaveFiller::TreatNewVertices( - const BOPCol_IndexedDataMapOfShapeInteger& aMapVI, - BOPCol_IndexedDataMapOfShapeListOfShape& myImages) +void BOPAlgo_PaveFiller::TreatNewVertices + (const BOPCol_IndexedDataMapOfShapeInteger& aMapVI, + BOPCol_IndexedDataMapOfShapeListOfShape& myImages) { Standard_Integer j, i, aNbV, aNbVSD; Standard_Real aTol; @@ -661,7 +606,7 @@ //function : FillShrunkData //purpose : //======================================================================= - void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB) +void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB) { Standard_Integer nE, nV1, nV2, iErr; Standard_Real aT1, aT2, aTS1, aTS2; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index 2ed55c8b34..d4d9552173 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -271,7 +271,7 @@ void BOPAlgo_PaveFiller::MakeBlocks() Standard_Boolean bExist, bValid2D; Standard_Integer i, nF1, nF2, aNbC, aNbP, j; Standard_Integer nV1, nV2; - Standard_Real aTolR3D, aTolR2D, aT1, aT2, aTol; + Standard_Real aTolR3D, aT1, aT2, aTol; Handle(NCollection_IncAllocator) aAllocator; BOPDS_ListIteratorOfListOfPaveBlock aItLPB; TopoDS_Edge aES; @@ -310,7 +310,6 @@ void BOPAlgo_PaveFiller::MakeBlocks() const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2))); // aTolR3D=aFF.TolR3D(); - aTolR2D=aFF.TolR2D(); // // Update face info if (aMF.Add(nF1)) { @@ -1400,66 +1399,66 @@ Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance(const Standard_Integer nV aType1=aGAS1.GetType(); aType2=aGAS2.GetType(); // - if (aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) { - GeomAbs_CurveType aTypeC; + //if (aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) { + GeomAbs_CurveType aTypeC; + // + const IntTools_Curve& aIC=aNC.Curve(); + aTypeC=aIC.Type(); + //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) { + Handle(Geom2d_Curve) aC2D[2]; + // + aC2D[0]=aIC.FirstCurve2d(); + aC2D[1]=aIC.SecondCurve2d(); + if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) { + Standard_Integer nV, m, n; + Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr; + gp_Pnt aPC[2], aPV; + gp_Dir aDN[2]; + gp_Pnt2d aP2D; + BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1; // - const IntTools_Curve& aIC=aNC.Curve(); - aTypeC=aIC.Type(); - if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) { - Handle(Geom2d_Curve) aC2D[2]; + aDT2=2e-7; // the rich criteria + aDScPr=5.e-9; // the creasing criteria + aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]); + // + aItMI.Initialize(aMV); + for (; aItMI.More(); aItMI.Next()) { + nV = aItMI.Value(); + const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV)); + aPV=BRep_Tool::Pnt(aV); // - aC2D[0]=aIC.FirstCurve2d(); - aC2D[1]=aIC.SecondCurve2d(); - if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) { - Standard_Integer nV, m, n; - Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr; - gp_Pnt aPC[2], aPV; - gp_Dir aDN[2]; - gp_Pnt2d aP2D; - BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1; + for (m=0; m<2; ++m) { + aD2=aPC[m].SquareDistance(aPV); + if (aD2>aDT2) {// no rich + continue; + } // - aDT2=2e-7; // the rich criteria - aDScPr=5.e-9; // the creasing criteria - aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]); + for (n=0; n<2; ++n) { + Handle(Geom_Surface)& aS=(!n)? aS1 : aS2; + aC2D[n]->D0(aTC[m], aP2D); + aP2D.Coord(u, v); + BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]); + } + // + aScPr=aDN[0]*aDN[1]; + if (aScPr<0.) { + aScPr=-aScPr; + } + aScPr=1.-aScPr; // - aItMI.Initialize(aMV); - for (; aItMI.More(); aItMI.Next()) { - nV = aItMI.Value(); - const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV)); - aPV=BRep_Tool::Pnt(aV); - // - for (m=0; m<2; ++m) { - aD2=aPC[m].SquareDistance(aPV); - if (aD2>aDT2) {// no rich - continue; - } - // - for (n=0; n<2; ++n) { - Handle(Geom_Surface)& aS=(!n)? aS1 : aS2; - aC2D[n]->D0(aTC[m], aP2D); - aP2D.Coord(u, v); - BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]); - } - // - aScPr=aDN[0]*aDN[1]; - if (aScPr<0.) { - aScPr=-aScPr; - } - aScPr=1.-aScPr; - // - if (aScPr>aDScPr) { - continue; - } - // - // The intersection curve aIC is vanishing curve (the crease) - aD=sqrt(aD2); - // - PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol); - } - }//for (jVU=1; jVU=aNbVU; ++jVU) { + if (aScPr>aDScPr) { + continue; + } + // + // The intersection curve aIC is vanishing curve (the crease) + aD=sqrt(aD2); + // + PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol); } - }//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) { - }//if(aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) { + }//for (jVU=1; jVU=aNbVU; ++jVU) { + } + //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) { + //}//if(aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) { } //======================================================================= diff --git a/src/BRepFill/BRepFill.cdl b/src/BRepFill/BRepFill.cdl index df96e385e2..14104cc9ef 100644 --- a/src/BRepFill/BRepFill.cdl +++ b/src/BRepFill/BRepFill.cdl @@ -189,6 +189,12 @@ is ListOfShape from TopTools, OrientedShapeMapHasher from TopTools); + class DataMapOfShapeHArray2OfShape instantiates + DataMap from TCollection (Shape from TopoDS, + HArray2OfShape from TopTools, + ShapeMapHasher from TopTools); + + class CurveConstraint ; ---Purpose: same as CurveConstraint from GeomPlate -- with BRepAdaptor_Surface instead of diff --git a/src/BRepFill/BRepFill_CompatibleWires.cxx b/src/BRepFill/BRepFill_CompatibleWires.cxx index 446186b110..7c4ae5a0b3 100644 --- a/src/BRepFill/BRepFill_CompatibleWires.cxx +++ b/src/BRepFill/BRepFill_CompatibleWires.cxx @@ -158,10 +158,7 @@ static Standard_Boolean PlaneOfWire (const TopoDS_Wire& W, gp_Pln& P) TopoDS_Edge Edge = TopoDS::Edge(anExp.Current()); Standard_Real first, last; TopLoc_Location loc; - Handle(Geom_Curve) curv; - curv = BRep_Tool::Curve(Edge, loc, first, last); - curv = - Handle(Geom_Curve)::DownCast(curv->Transformed(loc.Transformation())); + Handle(Geom_Curve) curv = BRep_Tool::Curve(Edge, first, last); if (wClosed) { GeomAdaptor_Curve AdC; AdC.Load(curv); @@ -1455,9 +1452,24 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) Standard_Integer nbs, NbSamples = 0; if (theLength <= 2) NbSamples = 4; + gp_Pln FirstPlane; + PlaneOfWire(TopoDS::Wire(myWork(ideb)), FirstPlane); + gp_Pnt FirstBary = FirstPlane.Location(); + gp_Vec NormalOfFirstPlane = FirstPlane.Axis().Direction(); for (i = ideb+1; i <= ifin; i++) { const TopoDS_Wire& wire = TopoDS::Wire(myWork(i)); + + //Compute offset vector as current bary center projected on first plane + //to first bary center + gp_Pln CurPlane; + PlaneOfWire(wire, CurPlane); + gp_Pnt CurBary = CurPlane.Location(); + gp_Vec aVec(FirstBary, CurBary); + gp_Vec anOffsetProj = (aVec * NormalOfFirstPlane) * NormalOfFirstPlane; + CurBary.Translate(-anOffsetProj); //projected current bary center + gp_Vec Offset(CurBary, FirstBary); + TopoDS_Wire newwire; BRep_Builder BB; BB.MakeWire(newwire); @@ -1481,11 +1493,6 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) else for (j = 1; j <= theLength; j++) { - // get a vector to superpose SeqVertices(j) on PrevSeq(1) - const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(1) ); - const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(j) ); - gp_Vec curToPrevVec( BRep_Tool::Pnt(V), BRep_Tool::Pnt(Vprev) ); - //Forward Standard_Real SumDist = 0.; for (k = j, n = 1; k <= theLength; k++, n++) @@ -1493,7 +1500,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) ); gp_Pnt Pprev = BRep_Tool::Pnt(Vprev); const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) ); - gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + curToPrevVec.XYZ(); + gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ(); SumDist += Pprev.Distance(P); if (NbSamples > 0) { @@ -1512,7 +1519,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) (Ecurve.FirstParameter() + nbs*SampleOnCur) : (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur); gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev); - gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + curToPrevVec.XYZ(); + gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ(); SumDist += PonPrev.Distance(PonCur); } } @@ -1522,7 +1529,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) ); gp_Pnt Pprev = BRep_Tool::Pnt(Vprev); const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) ); - gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + curToPrevVec.XYZ(); + gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ(); SumDist += Pprev.Distance(P); if (NbSamples > 0) { @@ -1541,7 +1548,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) (Ecurve.FirstParameter() + nbs*SampleOnCur) : (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur); gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev); - gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + curToPrevVec.XYZ(); + gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ(); SumDist += PonPrev.Distance(PonCur); } } @@ -1560,7 +1567,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) ); gp_Pnt Pprev = BRep_Tool::Pnt(Vprev); const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) ); - gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + curToPrevVec.XYZ(); + gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ(); SumDist += Pprev.Distance(P); if (NbSamples > 0) { @@ -1582,7 +1589,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) : (Ecurve.FirstParameter() + nbs*SampleOnCur); gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev); - gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + curToPrevVec.XYZ(); + gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ(); SumDist += PonPrev.Distance(PonCur); } } @@ -1592,7 +1599,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) ); gp_Pnt Pprev = BRep_Tool::Pnt(Vprev); const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) ); - gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + curToPrevVec.XYZ(); + gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ(); SumDist += Pprev.Distance(P); if (NbSamples > 0) { @@ -1611,7 +1618,7 @@ void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ ) (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) : (Ecurve.FirstParameter() + nbs*SampleOnCur); gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev); - gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + curToPrevVec.XYZ(); + gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ(); SumDist += PonPrev.Distance(PonCur); } } diff --git a/src/BRepFill/BRepFill_Draft.cxx b/src/BRepFill/BRepFill_Draft.cxx index e8b7887afb..1607747a30 100644 --- a/src/BRepFill/BRepFill_Draft.cxx +++ b/src/BRepFill/BRepFill_Draft.cxx @@ -14,11 +14,13 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. + #include #include #include #include +#include #include #include @@ -519,7 +521,9 @@ static Standard_Boolean GoodOrientation(const Bnd_Box& B, BRepFill_Sweep Sweep(mySec, myLoc, Standard_True); Sweep.SetTolerance(myTol); Sweep.SetAngularControl(angmin, angmax); - Sweep.Build(myStyle, myCont); + TopTools_MapOfShape Dummy; + BRepFill_DataMapOfShapeHArray2OfShape Dummy2; + Sweep.Build(Dummy, Dummy2, myStyle, myCont); if (Sweep.IsDone()) { myShape = Sweep.Shape(); myShell = TopoDS::Shell(myShape); diff --git a/src/BRepFill/BRepFill_Evolved.cxx b/src/BRepFill/BRepFill_Evolved.cxx index 9dad6d397c..5699d256e1 100644 --- a/src/BRepFill/BRepFill_Evolved.cxx +++ b/src/BRepFill/BRepFill_Evolved.cxx @@ -14,6 +14,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. + #include @@ -2220,8 +2221,8 @@ void BRepFill_Evolved::MakePipe(const TopoDS_Edge& SE, } #endif -// BRepFill_Pipe Pipe(BRepLib_MakeWire(SE),GenProf); - BRepFill_Pipe Pipe = BRepFill_Pipe(BRepLib_MakeWire(SE),GenProf); + BRepFill_Pipe Pipe(BRepLib_MakeWire(SE), GenProf); + //BRepFill_Pipe Pipe = BRepFill_Pipe(BRepLib_MakeWire(SE),GenProf); #ifdef DRAW if (AffichGeom) { diff --git a/src/BRepFill/BRepFill_LocationLaw.cxx b/src/BRepFill/BRepFill_LocationLaw.cxx index c86fec3c79..35352f577d 100644 --- a/src/BRepFill/BRepFill_LocationLaw.cxx +++ b/src/BRepFill/BRepFill_LocationLaw.cxx @@ -14,6 +14,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. + #include #include @@ -36,6 +37,7 @@ #include #include #include +#include //======================================================================= @@ -608,8 +610,10 @@ void BRepFill_LocationLaw::CurvilinearBounds(const Standard_Integer Index, M(2,1), M(2,2), M(2,3), V.Y(), M(3,1), M(3,2), M(3,3), V.Z(), 1.e-12, 1.e-14); - TopLoc_Location Loc(fila); - W.Location(Loc.Multiplied(W.Location())); + //TopLoc_Location Loc(fila); + //W.Location(Loc.Multiplied(W.Location())); + W = BRepBuilderAPI_Transform(W, fila, Standard_True); //copy + /////////////////////////////////////////// } else { W.Nullify(); diff --git a/src/BRepFill/BRepFill_Pipe.cdl b/src/BRepFill/BRepFill_Pipe.cdl index e8319b393c..170f06016f 100644 --- a/src/BRepFill/BRepFill_Pipe.cdl +++ b/src/BRepFill/BRepFill_Pipe.cdl @@ -14,6 +14,7 @@ -- Alternatively, this file may be used under the terms of Open CASCADE -- commercial license or contractual agreement. + class Pipe from BRepFill ---Purpose: Create a shape by sweeping a shape (the profile) @@ -26,6 +27,8 @@ class Pipe from BRepFill uses HArray2OfShape from TopTools, + MapOfShape from TopTools, + DataMapOfShapeHArray2OfShape from BRepFill, LocationLaw from BRepFill, Shape from TopoDS, Face from TopoDS, @@ -108,7 +111,7 @@ is is static; - PipeLine(me; Point : Pnt from gp) + PipeLine(me : in out; Point : Pnt from gp) ---Purpose: Create a Wire by sweeping the Point along the returns Wire from TopoDS raises @@ -145,6 +148,10 @@ is DefineRealSegmax(me : in out) is static private; + RebuildTopOrBottomFace(me; aFace: Shape from TopoDS; + IsTop: Boolean from Standard) + is static private; + ShareFaces(me: in out; theShape: Shape from TopoDS; theInitialFacesLen: Integer; theInitialEdgesLen: Integer; @@ -164,7 +171,10 @@ fields myLoc : LocationLaw from BRepFill; mySections: HArray2OfShape from TopTools; myFaces : HArray2OfShape from TopTools; - myEdges : HArray2OfShape from TopTools; + myEdges : HArray2OfShape from TopTools; + myReversedEdges : MapOfShape from TopTools; + myTapes : DataMapOfShapeHArray2OfShape from BRepFill; + myCurIndexOfSectionEdge : Integer from Standard; myFirst : Shape from TopoDS; myLast : Shape from TopoDS; diff --git a/src/BRepFill/BRepFill_Pipe.cxx b/src/BRepFill/BRepFill_Pipe.cxx index 5c4f57944d..034fcf247a 100644 --- a/src/BRepFill/BRepFill_Pipe.cxx +++ b/src/BRepFill/BRepFill_Pipe.cxx @@ -52,12 +52,65 @@ #include #include #include +#include +#include +#include + +#include +#include +#include #ifdef DRAW #include static Standard_Boolean Affich = 0; #endif + +static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace, + TopoDS_Edge& anEdge) +{ + Standard_Real fpar, lpar; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar); + if (aPCurve.IsNull()) + return; + + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar); + if (aCurve.IsNull()) + return; + + Handle(Geom2dAdaptor_HCurve) GAHC2d = new Geom2dAdaptor_HCurve(aPCurve, fpar, lpar); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aSurf); + Adaptor3d_CurveOnSurface ConS(GAHC2d, GAHS); + + Standard_Real Tol = BRep_Tool::Tolerance(anEdge); + Standard_Real InitTol = Tol; + Standard_Real TolTol = Tol*Tol; + const Standard_Integer NCONTROL = 22; + Standard_Real delta = (lpar - fpar)/NCONTROL; + for (Standard_Integer i = 0; i <= NCONTROL; i++) + { + Standard_Real par = fpar + i*delta; + gp_Pnt pnt = aCurve->Value(par); + gp_Pnt prj = ConS.Value(par); + Standard_Real sqdist = pnt.SquareDistance(prj); + if (sqdist > TolTol) + TolTol = sqdist; + } + Tol = 1.00005 * Sqrt(TolTol); + if (Tol >= InitTol) + { + BRep_Builder BB; + BB.UpdateEdge(anEdge, Tol); + TopoDS_Iterator itv(anEdge); + for (; itv.More(); itv.Next()) + { + TopoDS_Vertex aVertex = TopoDS::Vertex(itv.Value()); + BB.UpdateVertex(aVertex, Tol); + } + } +} + //======================================================================= //function : BRepFill_Pipe //purpose : @@ -70,6 +123,8 @@ BRepFill_Pipe::BRepFill_Pipe() myContinuity = GeomAbs_C2; myMode = GeomFill_IsCorrectedFrenet; myForceApproxC1 = Standard_False; + + myCurIndexOfSectionEdge = 1; } @@ -99,6 +154,9 @@ BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine, myContinuity = GeomAbs_C0; myForceApproxC1 = ForceApproxC1; + + myCurIndexOfSectionEdge = 1; + Perform(Spine, Profile, KPart); } @@ -175,7 +233,8 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine, TopLoc_Location LocFirst(fila); myFirst = myProfile; if ( ! LocFirst.IsIdentity()) { - myFirst.Location( LocFirst.Multiplied(myProfile.Location()) ); + //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) ); + myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy } myLoc->Law(myLoc->NbLaw())->GetDomain(first, last); @@ -190,7 +249,8 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine, if (! myLoc->IsClosed() || LocFirst != LocLast) { myLast = myProfile; if ( ! LocLast.IsIdentity()) { - myLast.Location(LocLast.Multiplied(myProfile.Location()) ); + //myLast.Location(LocLast.Multiplied(myProfile.Location()) ); + myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy } } else { @@ -379,7 +439,7 @@ TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const //purpose : Construct a wire by sweeping of a point //======================================================================= -TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const +TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) { // Postioning gp_Pnt P; @@ -393,7 +453,8 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const // Sweeping BRepFill_Sweep MkSw(Section, myLoc, Standard_True); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); + MkSw.Build( myReversedEdges, myTapes, + BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); TopoDS_Shape aLocalShape = MkSw.Shape(); return TopoDS::Wire(aLocalShape); // return TopoDS::Wire(MkSw.Shape()); @@ -480,7 +541,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, case TopAbs_SOLID : case TopAbs_COMPSOLID : - Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID"); + Standard_DomainError::Raise("BRepFill_Pipe::profile contains solids"); break; case TopAbs_COMPOUND : @@ -519,7 +580,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS)); BRepFill_Sweep MkSw(Section, myLoc, Standard_True); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); + MkSw.Build( myReversedEdges, myTapes, + BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); result = MkSw.Shape(); } @@ -530,7 +592,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, MkSw.SetBounds(TopoDS::Wire(TheFirst), TopoDS::Wire(TheLast)); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); + MkSw.Build( myReversedEdges, myTapes, + BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); result = MkSw.Shape(); // Labeling of elements @@ -543,9 +606,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, Handle(TopTools_HArray2OfShape) Aux, Somme; Standard_Integer length; Standard_Integer ii, jj, kk; - const Standard_Integer aNbFaces = myFaces->ColLength(); - const Standard_Integer aNbEdges = myEdges->ColLength(); - const Standard_Integer aNbSections = mySections->ColLength(); Aux = MkSw.SubShape(); length = Aux->ColLength() + myFaces->ColLength(); @@ -568,7 +628,9 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, for (jj=1; jj<=mySections->RowLength(); jj++) { for (ii=1; ii<=mySections->ColLength(); ii++) Somme->SetValue(ii, jj, mySections->Value(ii, jj)); - + + myCurIndexOfSectionEdge = mySections->ColLength()+1; + for (kk=1, ii=mySections->ColLength()+1; kk <=Aux->ColLength(); kk++, ii++) Somme->SetValue(ii, jj, Aux->Value(kk, jj)); @@ -589,15 +651,20 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, } myEdges = Somme; - - // Perform sharing faces - result = ShareFaces(result, aNbFaces, aNbEdges, aNbSections); } } } if ( TheS.ShapeType() == TopAbs_FACE ) { Standard_Integer ii, jj; + //jgv + TopExp_Explorer Explo(result, TopAbs_FACE); + for (; Explo.More(); Explo.Next()) + { + TopoDS_Shape aFace = Explo.Current(); + RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed + } + ///// TopoDS_Face F; for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) { for (jj=1; jj<=myFaces->RowLength(); jj++) { @@ -609,6 +676,10 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, if ( !mySpine.Closed()) { // if Spine is not closed // add the last face of the solid + + //jgv + RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face + ///// B.Add(result, TopoDS::Face(TheLast)); } @@ -805,280 +876,46 @@ void BRepFill_Pipe::DefineRealSegmax() } //======================================================================= -//function : ShareFaces -//purpose : +//function : RebuildTopOrBottomFace +//purpose : Correct orientation of v-iso edges +// according to new 3d and 2d curves taken from swept surfaces //======================================================================= -TopoDS_Shape BRepFill_Pipe::ShareFaces - (const TopoDS_Shape &theShape, - const Standard_Integer theInitialFacesLen, - const Standard_Integer theInitialEdgesLen, - const Standard_Integer theInitialSectionsLen) +void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace, + const Standard_Boolean IsTop) const { - TopoDS_Shape aResult = theShape; - // Check if there are shapes to be shared. - TopTools_DataMapOfShapeInteger aMapBndEdgeIndex; - TColStd_DataMapOfIntegerInteger aMapNewOldFIndex; - TColStd_DataMapOfIntegerInteger aMapNewOldEIndex; - TopTools_MapOfShape aMapUsedVtx; - TopExp_Explorer anExp; - Standard_Integer i; + Standard_Integer IndexOfSection = + (IsTop)? 1 : mySections->RowLength(); + Standard_Integer ii; - Standard_Integer jj; - BRep_Builder aBuilder; - - // Check the first and last J index of myFaces. - for (i = 1; i <= 2; i++) { - // Compute jj index of faces. - if (i == 1) { - jj = 1; - } else { - jj = myFaces->RowLength(); - - if (jj == 1) { - break; - } - } - - // Fill the map of boundary edges on initial faces. - for (ii = 1; ii <= theInitialFacesLen; ii++) { - anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE); - - for (; anExp.More(); anExp.Next()) { - aMapBndEdgeIndex.Bind(anExp.Current(), ii); - } - } - - // Check if edges of newly created faces are shared with old ones. - for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) { - anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE); - - for (; anExp.More(); anExp.Next()) { - if (aMapBndEdgeIndex.IsBound(anExp.Current())) { - // This row should be replaced. - Standard_Integer anOldIndex = aMapBndEdgeIndex.Find(anExp.Current()); - - aMapNewOldFIndex.Bind(ii, anOldIndex); - - // Find corresponding new and old edges indices. - TopoDS_Vertex aV[2]; - TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV[0], aV[1]); - Standard_Integer ie; - - // Compute jj index of edges. - Standard_Integer je = (i == 1 ? 1 : myEdges->RowLength()); - - for (Standard_Integer j = 0; j < 2; j++) { - if (aMapUsedVtx.Contains(aV[j])) { - // This vertex is treated. - continue; - } - - // Find old index. - Standard_Integer iEOld = -1; - TopoDS_Vertex aVE[2]; - - for (ie = 1; ie <= theInitialEdgesLen; ie++) { - const TopoDS_Shape &anEdge = myEdges->Value(ie, je); - - TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]); - - if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) { - iEOld = ie; - break; - } - } - - if (iEOld > 0) { - // Find new index. - for (ie = theInitialEdgesLen+1; ie <= myEdges->ColLength(); ie++) { - const TopoDS_Shape &anEdge = myEdges->Value(ie, je); - - TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]); - - if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) { - // This row should be replaced. - aMapNewOldEIndex.Bind(ie, iEOld); - aMapUsedVtx.Add(aV[j]); - break; - } - } - } - } - + BRep_Builder BB; + TopoDS_Iterator itf(aFace); + for (; itf.More(); itf.Next()) + { + TopoDS_Shape aWire = itf.Value(); + TopTools_SequenceOfShape InitEdges; + TopTools_SequenceOfShape ResEdges; + TopoDS_Iterator itw(aWire); + for (; itw.More(); itw.Next()) + { + TopoDS_Shape anEdge = itw.Value(); + for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++) + { + TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection); + if (anEdge.IsSame(aVisoEdge)) + { + InitEdges.Append(anEdge); + ResEdges.Append(aVisoEdge); break; } } } - } - - if (!aMapNewOldFIndex.IsEmpty()) { - TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIter(aMapNewOldFIndex); - TopTools_ListOfShape aListShape; - BRepTools_Substitution aSubstitute; - - for (; anIter.More(); anIter.Next()) { - const Standard_Integer aNewIndex = anIter.Key(); - const Standard_Integer anOldIndex = anIter.Value(); - - // Change new faces by old ones. - for (jj = 1; jj <= myFaces->RowLength(); jj++) { - const TopoDS_Shape &aNewFace = myFaces->Value(aNewIndex, jj); - const TopoDS_Shape &anOldFace = myFaces->Value(anOldIndex, jj); - - if (!aSubstitute.IsCopied(aNewFace)) { - aListShape.Append(anOldFace.Oriented(TopAbs_REVERSED)); - aSubstitute.Substitute(aNewFace, aListShape); - aListShape.Clear(); - } - } - } - - // Change new edges by old ones. - for (anIter.Initialize(aMapNewOldEIndex); anIter.More(); anIter.Next()) { - const Standard_Integer aNewIndex = anIter.Key(); - const Standard_Integer anOldIndex = anIter.Value(); - - for (jj = 1; jj <= myEdges->RowLength(); jj++) { - const TopoDS_Shape &aNewEdge = myEdges->Value(aNewIndex, jj); - const TopoDS_Shape &anOldEdge = myEdges->Value(anOldIndex, jj); - - if (!aSubstitute.IsCopied(aNewEdge)) { - aListShape.Append(anOldEdge.Oriented(TopAbs_FORWARD)); - aSubstitute.Substitute(aNewEdge, aListShape); - aListShape.Clear(); - - // Change new vertices by old ones. - TopoDS_Iterator aNewIt(aNewEdge); - TopoDS_Iterator anOldIt(anOldEdge); - - for (; aNewIt.More() && anOldIt.More(); - aNewIt.Next(), anOldIt.Next()) { - if (!aNewIt.Value().IsSame(anOldIt.Value())) { - if (!aSubstitute.IsCopied(aNewIt.Value())) { - aListShape.Append(anOldIt.Value().Oriented(TopAbs_FORWARD)); - aSubstitute.Substitute(aNewIt.Value(), aListShape); - aListShape.Clear(); - } - } - } - } - } - } - - // Perform substitution. - aSubstitute.Build(aResult); - - if (aSubstitute.IsCopied(aResult)) { - // Get copied shape. - const TopTools_ListOfShape& listSh = aSubstitute.Copy(aResult); - - aResult = listSh.First(); - - // Update original faces with copied ones. - for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) { - for (jj = 1; jj <= myFaces->RowLength(); jj++) { - TopoDS_Shape anOldFace = myFaces->Value(ii, jj); // Copy - - if (aSubstitute.IsCopied(anOldFace)) { - const TopTools_ListOfShape& aList = aSubstitute.Copy(anOldFace); - - if(!aList.IsEmpty()) { - // Store copied face. - const TopoDS_Shape &aCopyFace = aList.First(); - TopAbs_Orientation anOri = anOldFace.Orientation(); - const Standard_Boolean isShared = aMapNewOldFIndex.IsBound(ii); - - if (isShared) { - // Reverse the orientation for shared face. - anOri = TopAbs::Reverse(anOri); - } - - myFaces->SetValue(ii, jj, aCopyFace.Oriented(anOri)); - - // Check if it is necessary to update PCurves on this face. - if (!isShared) { - TopoDS_Face anOldF = TopoDS::Face(anOldFace); - TopoDS_Face aCopyF = TopoDS::Face(aCopyFace); - - anOldF.Orientation(TopAbs_FORWARD); - anExp.Init(anOldF, TopAbs_EDGE); - - for (; anExp.More(); anExp.Next()) { - const TopoDS_Shape &anOldEdge = anExp.Current(); - - if (aSubstitute.IsCopied(anOldEdge)) { - const TopTools_ListOfShape& aListE = - aSubstitute.Copy(anOldEdge); - - if(!aListE.IsEmpty()) { - // This edge is copied. Check if there is a PCurve - // on the face. - TopoDS_Edge aCopyE = TopoDS::Edge(aListE.First()); - Standard_Real aFirst; - Standard_Real aLast; - Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface - (aCopyE, aCopyF, aFirst, aLast); - - if (aPCurve.IsNull()) { - // There is no pcurve copy it from the old edge. - TopoDS_Edge anOldE = TopoDS::Edge(anOldEdge); - - aPCurve = BRep_Tool::CurveOnSurface - (anOldE, anOldF, aFirst, aLast); - - if (aPCurve.IsNull() == Standard_False) { - // Update the shared edge with PCurve from new Face. - Standard_Real aTol = Max(BRep_Tool::Tolerance(anOldE), - BRep_Tool::Tolerance(aCopyE)); - - aBuilder.UpdateEdge(aCopyE, aPCurve, aCopyF, aTol); - } - } - } - } - } - } - } - } - } - } - - // Update new edges with shared ones. - for (ii = theInitialEdgesLen + 1; ii <= myEdges->ColLength(); ii++) { - for (jj = 1; jj <= myEdges->RowLength(); jj++) { - const TopoDS_Shape &aLocalShape = myEdges->Value(ii, jj); - - if (aSubstitute.IsCopied(aLocalShape)) { - const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); - - if(!aList.IsEmpty()) { - const TopAbs_Orientation anOri = TopAbs_FORWARD; - - myEdges->SetValue(ii, jj, aList.First().Oriented(anOri)); - } - } - } - } - - // Update new sections with shared ones. - for (ii = theInitialSectionsLen+1; ii <= mySections->ColLength(); ii++) { - for (jj = 1; jj <= mySections->RowLength(); jj++) { - const TopoDS_Shape &aLocalShape = mySections->Value(ii, jj); - - if (aSubstitute.IsCopied(aLocalShape)) { - const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); - - if(!aList.IsEmpty()) { - const TopAbs_Orientation anOri = TopAbs_FORWARD; - - mySections->SetValue(ii, jj, aList.First().Oriented(anOri)); - } - } - } - } + aWire.Free(Standard_True); + for (ii = 1; ii <= InitEdges.Length(); ii++) + { + BB.Remove(aWire, InitEdges(ii)); + UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii))); + BB.Add(aWire, ResEdges(ii)); } } - - return aResult; } diff --git a/src/BRepFill/BRepFill_PipeShell.cdl b/src/BRepFill/BRepFill_PipeShell.cdl index 26e9d49308..8eabe7e3c0 100644 --- a/src/BRepFill/BRepFill_PipeShell.cdl +++ b/src/BRepFill/BRepFill_PipeShell.cdl @@ -106,6 +106,19 @@ is ---Level: Public + +-- ============================================ +-- Methods to set parameters for approximation +-- ============================================ + SetMaxDegree(me : mutable; + NewMaxDegree : Integer from Standard); + ---Purpose: Define the maximum V degree of resulting surface + + SetMaxSegments(me : mutable; + NewMaxSegments : Integer from Standard); + ---Purpose: Define the maximum number of spans in V-direction + -- on resulting surface + SetForceApproxC1(me : mutable; ForceApproxC1 : Boolean from Standard); ---Purpose: Set the flag that indicates attempt to approximate @@ -280,6 +293,8 @@ fields myBoundTol : Real; myTolAngular : Real; angmin, angmax : Real; + myMaxDegree : Integer; + myMaxSegments : Integer; myForceApproxC1 : Boolean; myLaw : Function from Law; diff --git a/src/BRepFill/BRepFill_PipeShell.cxx b/src/BRepFill/BRepFill_PipeShell.cxx index 3b48a9c153..5400775f9e 100644 --- a/src/BRepFill/BRepFill_PipeShell.cxx +++ b/src/BRepFill/BRepFill_PipeShell.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,7 @@ #include #include +#include #include #include @@ -212,7 +214,7 @@ static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace, //purpose : //======================================================================= BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine) - : mySpine(Spine), + : mySpine(Spine), myForceApproxC1(Standard_False), myIsAutomaticLaw(Standard_False), myTrihedron(GeomFill_IsCorrectedFrenet), @@ -224,6 +226,9 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine) myLaw.Nullify(); SetTolerance(); + myMaxDegree = 11; + myMaxSegments = 30; + // Attention to closed non-declared wire ! if (!mySpine.Closed()) { TopoDS_Vertex Vf, Vl; @@ -412,6 +417,25 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine) mySection.Nullify(); //It is required to relocalize the sections. } + +//======================================================================= +//function : SetMaxDegree +//purpose : +//======================================================================= +void BRepFill_PipeShell::SetMaxDegree(const Standard_Integer NewMaxDegree) +{ + myMaxDegree = NewMaxDegree; +} + +//======================================================================= +//function : SetMaxSegments +//purpose : +//======================================================================= +void BRepFill_PipeShell::SetMaxSegments(const Standard_Integer NewMaxSegments) +{ + myMaxSegments = NewMaxSegments; +} + //======================================================================= //function : SetForceApproxC1 //purpose : Set the flag that indicates attempt to approximate @@ -738,7 +762,10 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) GeomAbs_Shape theContinuity = GeomAbs_C2; if (myTrihedron == GeomFill_IsDiscreteTrihedron) theContinuity = GeomAbs_C0; - MkSw.Build(myTransition, theContinuity); + TopTools_MapOfShape Dummy; + BRepFill_DataMapOfShapeHArray2OfShape Dummy2; + MkSw.Build(Dummy, Dummy2, myTransition, theContinuity, + GeomFill_Location, myMaxDegree, myMaxSegments); myStatus = myLocation->GetStatus(); Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); @@ -1118,11 +1145,14 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, Sec.Vertex(), Sec.WithContact(), Sec.WithCorrection()); - W = Sec.Wire(); + TopoDS_Wire TmpWire = Sec.Wire(); aTrsf = Place.Transformation(); - TopLoc_Location Loc2(Place.Transformation()), Loc1; - Loc1 = W.Location(); - W.Location(Loc2.Multiplied(Loc1)); + //TopLoc_Location Loc2(Place.Transformation()), Loc1; + //Loc1 = TmpWire.Location(); + //W.Location(Loc2.Multiplied(Loc1)); + //Transform the copy + W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); + //////////////////////////////////// param = Place.AbscissaOnPath(); } diff --git a/src/BRepFill/BRepFill_Sweep.cdl b/src/BRepFill/BRepFill_Sweep.cdl index a38e957c04..f5ece71bef 100644 --- a/src/BRepFill/BRepFill_Sweep.cdl +++ b/src/BRepFill/BRepFill_Sweep.cdl @@ -14,6 +14,7 @@ -- Alternatively, this file may be used under the terms of Open CASCADE -- commercial license or contractual agreement. + class Sweep from BRepFill ---Purpose: Topological Sweep Algorithm @@ -28,8 +29,11 @@ uses Shape from GeomAbs, HArray2OfShape from TopTools, ListOfShape from TopTools, - DataMapOfShapeShape from TopTools, + DataMapOfShapeShape from TopTools, + MapOfShape from TopTools, + DataMapOfShapeHArray2OfShape from BRepFill, Wire from TopoDS, + Edge from TopoDS, Shape from TopoDS, Trsf from gp @@ -81,7 +85,9 @@ is -- to be C0. - Build(me : in out; + Build(me : in out; + ReversedEdges : in out MapOfShape from TopTools; + Tapes : in out DataMapOfShapeHArray2OfShape from BRepFill; Transition : TransitionStyle = BRepFill_Modified; Continuity : Shape from GeomAbs = GeomAbs_C2; Approx : ApproxStyle = GeomFill_Location; @@ -112,7 +118,9 @@ is BuildShell(me : in out; Transition : TransitionStyle; - Vf, Vl : Integer; + Vf, Vl : Integer; + ReversedEdges : in out MapOfShape from TopTools; + Tapes : in out DataMapOfShapeHArray2OfShape from BRepFill; ExtendFirst : Real = 0.0; ExtendLast : Real = 0.0) returns Boolean is private; @@ -158,6 +166,11 @@ is V : in out Shape from TopoDS) is private; + RebuildTopOrBottomEdge(me; aNewEdge: Edge from TopoDS; + anEdge: in out Edge from TopoDS; + ReversedEdges: in out MapOfShape from TopTools) + is private; + fields isDone : Boolean; KPart : Boolean; diff --git a/src/BRepFill/BRepFill_Sweep.cxx b/src/BRepFill/BRepFill_Sweep.cxx index 93c3d3d01c..09907ffc48 100644 --- a/src/BRepFill/BRepFill_Sweep.cxx +++ b/src/BRepFill/BRepFill_Sweep.cxx @@ -91,6 +91,7 @@ #include #include #include +#include #include #include @@ -99,6 +100,7 @@ #include #include #include +#include #include #include @@ -908,20 +910,16 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF, f2, l2, C3); C2 = C3; - Standard_Boolean pointu_f, pointu_l; // P1 = BT.Pnt(Vf); P1 = BRep_Tool::Pnt(Vf); // P2 = BT.Pnt(V1); P2 = BRep_Tool::Pnt(V1); // pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BT.Tolerance(Vf)); - pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BRep_Tool::Tolerance(Vf)); // P1 = BT.Pnt(Vl); P1 = BRep_Tool::Pnt(Vl); // P2 = BT.Pnt(V2); P2 = BRep_Tool::Pnt(V2); // pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BT.Tolerance(Vl)); - pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BRep_Tool::Tolerance(Vl)); - P2d.SetCoord(0.,f1); L = new (Geom2d_Line) (P2d, gp::DX2d()); @@ -1703,7 +1701,9 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, LastShape = Last; // It is necessary to check the SameRange on its (PRO13551) +#ifdef DEB Standard_Boolean issame = Standard_True; +#endif BRep_Builder B; BRepTools_WireExplorer wexp; if (!FirstShape.IsNull()) { @@ -1711,7 +1711,9 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, if (!BRepLib::CheckSameRange(wexp.Current())) { B.SameRange(wexp.Current(), Standard_False); B.SameParameter(wexp.Current(), Standard_False); +#ifdef DEB issame = Standard_False; +#endif } } } @@ -1721,7 +1723,9 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, if (!BRepLib::CheckSameRange(wexp.Current())) { B.SameRange(wexp.Current(), Standard_False); B.SameParameter(wexp.Current(), Standard_False); +#ifdef DEB issame = Standard_False; +#endif } } } @@ -1933,6 +1937,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, BuildShell(const BRepFill_TransitionStyle /*Transition*/, const Standard_Integer IFirst, const Standard_Integer ILast, + TopTools_MapOfShape& ReversedEdges, + BRepFill_DataMapOfShapeHArray2OfShape& Tapes, const Standard_Real ExtendFirst, const Standard_Real ExtendLast) { @@ -2060,8 +2066,31 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Standard_Boolean exuv, singu, singv; Handle(Geom_Surface) S; + // Preprocessing: correct if the profile is shell + if (!ReversedEdges.IsEmpty()) + { + TopTools_SequenceOfShape EdgesToReverse; + TopoDS_Iterator itw(FirstShape); + for (; itw.More(); itw.Next()) + { + const TopoDS_Shape& anEdge = itw.Value(); + if (ReversedEdges.Contains(anEdge)) + EdgesToReverse.Append(anEdge); + } + FirstShape.Free(Standard_True); + for (Standard_Integer i = 1; i <= EdgesToReverse.Length(); i++) + { + B.Remove(FirstShape, EdgesToReverse(i)); + EdgesToReverse(i).Reverse(); + B.Add(FirstShape, EdgesToReverse(i)); + } + } + // (2.0) return preexisting Edges and vertices TopoDS_Edge E; + TColStd_Array1OfBoolean IsBuilt(1, NbLaw); + IsBuilt.Init(Standard_False); + TopTools_Array1OfShape StartEdges(1, NbLaw); if (! FirstShape.IsNull() && (IFirst==1)) { mySec->Init(FirstShape); for (isec=1; isec<=NbLaw; isec++) { @@ -2073,7 +2102,53 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Vertex(isec+1, 1) = TopExp::LastVertex(E); UpdateVertex(IFirst-1, isec+1, TabErr(isec, 1), Vi(1), Vertex(isec+1, 1)); + + StartEdges(isec) = E; + if (Tapes.IsBound(E)) + { + IsBuilt(isec) = Standard_True; + + //Initialize VEdge, UEdge, Vertex and myFaces + Standard_Integer j; + for (j = 1; j <= NbPath+1; j++) + { + VEdge(isec, j) = Tapes(E)->Value(1, j); + VEdge(isec, j).Reverse(); //direction of round is reversed + } + Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed + for (j = 1; j <= NbPath; j++) + UEdge(ifirst, j) = Tapes(E)->Value(2, j); + for (j = 1; j <= NbPath; j++) + UEdge(ilast, j) = Tapes(E)->Value(3, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(ifirst, j) = Tapes(E)->Value(4, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(ilast, j) = Tapes(E)->Value(5, j); + for (j = 1; j <= NbPath; j++) + myFaces->SetValue(isec, j, Tapes(E)->Value(6, j)); + + if (uclose && isec == 1) + { + for (j = 1; j <= NbPath; j++) + UEdge(NbLaw+1, j) = UEdge(1, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(NbLaw+1, j) = Vertex(1, j); + } + if (uclose && isec == NbLaw) + { + for (j = 1; j <= NbPath; j++) + UEdge(1, j) = UEdge(NbLaw+1, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(1, j) = Vertex(NbLaw+1, j); + } + } + else + { + Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1); + Tapes.Bind(E, EmptyArray); + } } + if (VEdge(1, 1).Orientation() == TopAbs_REVERSED) Vertex(1, 1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1))); else @@ -2081,128 +2156,152 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, UpdateVertex(IFirst-1, 1, TabErr(1, 1), Vi(1), Vertex(1, 1)); } - else { // Otherwise construct vertices - Standard_Real u, v, aux; - Standard_Boolean ureverse; - for (isec=1; isec<=NbLaw+1; isec++) { - // Return data - if (isec >NbLaw) { - S = TabS(NbLaw, 1); - ureverse = UReverse(NbLaw, 1); - exuv = ExchUV(NbLaw, 1); + + Standard_Real u, v, aux; + Standard_Boolean ureverse; + for (isec=1; isec<=NbLaw+1; isec++) { + // Return data + if (isec >NbLaw) { + S = TabS(NbLaw, 1); + ureverse = UReverse(NbLaw, 1); + exuv = ExchUV(NbLaw, 1); + } + else { + S = TabS(isec, 1); + ureverse = UReverse(isec, 1); + exuv = ExchUV(isec, 1); + } + S->Bounds(UFirst, ULast, VFirst, VLast); + + // Choice of parameters + if (ureverse) { + if (exuv) { + aux = VFirst; VFirst = VLast; VLast = aux; } else { - S = TabS(isec, 1); - ureverse = UReverse(isec, 1); - exuv = ExchUV(isec, 1); + aux = UFirst; UFirst = ULast; ULast = aux; } - S->Bounds(UFirst, ULast, VFirst, VLast); - - // Choice of parameters - if (ureverse) { - if (exuv) { - aux = VFirst; VFirst = VLast; VLast = aux; - } - else { - aux = UFirst; UFirst = ULast; ULast = aux; - } - } - if (isec!= NbLaw+1) { + } + if (isec!= NbLaw+1) { + u = UFirst; + v = VFirst; + } + else { + if (exuv) { u = UFirst; + v = VLast; + } + else { + u = ULast; v = VFirst; } - else { - if (exuv) { - u = UFirst; - v = VLast; - } - else { - u = ULast; - v = VFirst; - } - } - - // construction of vertices + } + + // construction of vertices + if (Vertex(isec, 1).IsNull()) B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)), S->Value(u,v), mySec->VertexTol(isec-1,Vi(1))); + else + { + TopLoc_Location Identity; + Vertex(isec, 1).Location(Identity); + B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)), + S->Value(u,v), + mySec->VertexTol(isec-1,Vi(1))); } - } - + } //end of for (isec=1; isec<=NbLaw+1; isec++) + if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) { mySec->Init(LastShape); for (isec=1; isec<=NbLaw; isec++) { E = mySec->CurrentEdge(); - VEdge(isec, NbPath+1) = E; - if (E.Orientation() == TopAbs_REVERSED) - Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(E); - else - Vertex(isec+1, NbPath+1) = TopExp::LastVertex(E); + if (VEdge(isec, NbPath+1).IsNull()) + VEdge(isec, NbPath+1) = E; + + if (Vertex(isec+1, NbPath+1).IsNull()) + { + if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED) + Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1))); + else + Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1))); + } UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath), Vi(NbPath+1), Vertex(isec+1, NbPath+1)); } - if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED) - Vertex(1, NbPath+1) = - TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1))); - else - Vertex(1, NbPath+1) = - TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1))); + + if (Vertex(1, NbPath+1).IsNull()) + { + if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED) + Vertex(1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1))); + else + Vertex(1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1))); + } UpdateVertex(ILast-1, 1, TabErr(1, NbPath), Vi(NbPath+1), Vertex(1, NbPath+1 )); - } - else { - Standard_Real u, v, aux; - Standard_Boolean ureverse; - for (isec=1; isec<=NbLaw+1; isec++) { - // Return data - if (isec >NbLaw) { + } + + for (isec=1; isec<=NbLaw+1; isec++) { + // Return data + if (isec >NbLaw) { S = TabS(NbLaw, NbPath); ureverse = UReverse(NbLaw, NbPath); exuv = ExchUV(NbLaw, NbPath); + } + else { + S = TabS(isec, NbPath); + ureverse = UReverse(isec, NbPath); + exuv = ExchUV(isec, NbPath); + } + S->Bounds(UFirst, ULast, VFirst, VLast); + + // Choice of parametres + if (ureverse) { + if (exuv) { + aux = VFirst; VFirst = VLast; VLast = aux; } else { - S = TabS(isec, NbPath); - ureverse = UReverse(isec, NbPath); - exuv = ExchUV(isec, NbPath); + aux = UFirst; UFirst = ULast; ULast = aux; } - S->Bounds(UFirst, ULast, VFirst, VLast); - - // Choice of parametres - if (ureverse) { - if (exuv) { - aux = VFirst; VFirst = VLast; VLast = aux; - } - else { - aux = UFirst; UFirst = ULast; ULast = aux; - } - } - if (isec == NbLaw+1) { + } + if (isec == NbLaw+1) { + u = ULast; + v = VLast; + } + else { + if (exuv) { u = ULast; + v = VFirst; + } + else { + u = UFirst; v = VLast; } - else { - if (exuv) { - u = ULast; - v = VFirst; - } - else { - u = UFirst; - v = VLast; - } - } - - // construction of vertex + } + + // construction of vertex + if (Vertex(isec, NbPath+1).IsNull()) B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), S->Value(u,v), mySec->VertexTol(isec-1, Vi(NbPath+1))); - } - } + else + { + TopLoc_Location Identity; + Vertex(isec, NbPath+1).Location(Identity); + B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), + S->Value(u,v), + mySec->VertexTol(isec-1, Vi(NbPath+1))); + } + } //end of for (isec=1; isec<=NbLaw+1; isec++) // ---------- Creation of Vertex and edge ------------ for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) { for (isec=1; isec <=NbLaw; isec++) { + if (IsBuilt(isec)) + continue; + S = TabS(isec, ipath); exuv = ExchUV(isec, ipath); S->Bounds(UFirst, ULast, VFirst, VLast); @@ -2270,6 +2369,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, TabErr(isec,1) + mySec->VertexTol(isec,Vi(1)), TopoDS::Vertex(Vertex(isec+1, 1)) ); + if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) { VEdge(isec, 1) = NullEdge(Vertex(isec, 1)); } @@ -2339,7 +2439,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, } // (2.2) Iso-u - if (isec == 1) { + if (isec == 1 && UEdge(1, ipath).IsNull()) { if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) { gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath))); gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1))); @@ -2360,18 +2460,29 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, UEdge(isec+1, ipath) = UEdge(1, ipath); } else { - UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, - Vertex(isec+1, ipath), - Vertex(isec+1, ipath+1), - myTol3d); + if (UEdge(isec+1, ipath).IsNull()) + UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, + Vertex(isec+1, ipath), + Vertex(isec+1, ipath+1), + myTol3d); + else + UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast); } // (2.3) Iso-v - if (ipath == 1 && VEdge(isec, ipath).IsNull()) - VEdge(isec, ipath) = BuildEdge(S, exuv, VFirst, - Vertex(isec , 1), - Vertex(isec+1, 1), - myTol3d); + if (ipath == 1) + { + TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst, + Vertex(isec , 1), + Vertex(isec+1, 1), + myTol3d); + if (VEdge(isec, ipath).IsNull()) + VEdge(isec, ipath) = aNewFirstEdge; + else //rebuild first edge + RebuildTopOrBottomEdge(aNewFirstEdge, + TopoDS::Edge(VEdge(isec, ipath)), + ReversedEdges); + } else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)), S, exuv, VFirst); @@ -2386,9 +2497,22 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Vertex(isec , ipath+1), Vertex(isec+1, ipath+1), myTol3d); - else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), - S, exuv, VLast); - + else + { + if (ipath != NbPath || vclose) + UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), + S, exuv, VLast); + else //ipath == NbPath && !vclose => rebuild last edge + { + TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast, + Vertex(isec , ipath+1), + Vertex(isec+1, ipath+1), + myTol3d); + RebuildTopOrBottomEdge(aNewLastEdge, + TopoDS::Edge(VEdge(isec, ipath+1)), + ReversedEdges); + } + } } }// End of construction of edges } @@ -2427,7 +2551,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, else myFaces->SetValue(isec, IPath, VEdge(isec, ipath)); } - else { + else if (myFaces->Value(isec, IPath).IsNull()) { BuildFace(TabS(isec,ipath), TopoDS::Edge(UEdge(isec, ipath)), TopoDS::Edge(VEdge(isec, ipath)), @@ -2442,6 +2566,12 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, } } + // (3.1) Reverse the faces that have been built ealier + for (ipath = 1; ipath <= NbPath; ipath++) + for (isec = 1; isec <= NbLaw; isec++) + if (IsBuilt(isec)) + myFaces->ChangeValue(isec, ipath).Reverse(); + // (4) History and Continuity @@ -2500,6 +2630,28 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, } } } + + // (5) Update Tapes + Standard_Integer j; + if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell + { + for (isec = 1; isec <= NbLaw; isec++) + { + for (j = 1; j <= NbPath+1; j++) + Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j)); + for (j = 1; j <= NbPath; j++) + Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j)); + for (j = 1; j <= NbPath; j++) + Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j)); + for (j = 1; j <= NbPath+1; j++) + Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j)); + for (j = 1; j <= NbPath+1; j++) + Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j)); + for (j = 1; j <= NbPath; j++) + Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j)); + } + } + return Standard_True; } @@ -2507,11 +2659,13 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, //function : Build //purpose : Construt the result of sweeping //====================================================================== - void BRepFill_Sweep::Build(const BRepFill_TransitionStyle Transition, - const GeomAbs_Shape Continuity, - const GeomFill_ApproxStyle Approx, - const Standard_Integer Degmax, - const Standard_Integer Segmax) +void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges, + BRepFill_DataMapOfShapeHArray2OfShape& Tapes, + const BRepFill_TransitionStyle Transition, + const GeomAbs_Shape Continuity, + const GeomFill_ApproxStyle Approx, + const Standard_Integer Degmax, + const Standard_Integer Segmax) { myContinuity = Continuity; myApproxStyle = Approx; @@ -2548,6 +2702,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, if (NbTrous==1) Extend = EvalExtrapol(1, Transition); isDone = BuildShell(Transition, 1, NbPath+1, + ReversedEdges, + Tapes, Extend, Extend); } else { // This is done piece by piece @@ -2558,6 +2714,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, else ILast = Trous->Value(ii); isDone = BuildShell(Transition, IFirst, ILast, + ReversedEdges, + Tapes, EvalExtrapol(IFirst, Transition), EvalExtrapol(ILast, Transition)); if (IFirst>1) { @@ -3100,3 +3258,105 @@ void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath, B.UpdateVertex(TheV, Tol); } } + +//======================================================================= +//function : RebuildTopOrBottomEdge +//purpose : Rebuild v-iso edge of top or bottom section +// inserting new 3d and 2d curves taken from swept surfaces +//====================================================================== +void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge, + TopoDS_Edge& anEdge, + TopTools_MapOfShape& ReversedEdges) const +{ + Standard_Real fpar, lpar; + Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar); + TopLoc_Location Identity; + + Standard_Boolean ToReverse = Standard_False; + Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge); + if (IsDegen) + BRep_Tool::Range(aNewEdge, fpar, lpar); + else + { + TopoDS_Vertex V1, V2, NewV1, NewV2; + TopExp::Vertices(anEdge, V1, V2); + if (!V1.IsSame(V2)) + { + TopExp::Vertices(aNewEdge, NewV1, NewV2); + V1.Location(Identity); + if (!V1.IsSame(NewV1)) + { + if (V1.IsSame(NewV2)) + ToReverse = Standard_True; + else + { + gp_Pnt Pnt1 = BRep_Tool::Pnt(V1); + gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1); + Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1); + if (!Pnt1.IsEqual(NewPnt1, TolSum)) + ToReverse = Standard_True; + } + } + } + else + { + Standard_Real OldFirst, OldLast; + Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast); + gp_Vec OldD1, NewD1; + gp_Pnt MidPnt; + OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1); + aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1); + if (OldD1 * NewD1 < 0.) + ToReverse = Standard_True; + } + } + + anEdge.Location(Identity); + const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape()); + TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge)); + BRep_Builder BB; + BB.Range(anEdge, fpar, lpar); + BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion()); + const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape()); + const BRep_ListOfCurveRepresentation& lcr = TE->Curves(); + BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr); + for (; itrep.More(); itrep.Next()) + { + const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value(); + if (CurveRep->IsCurveOnSurface()) + { + const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&CurveRep); + Handle(Geom2d_Curve) aPCurve = GC->PCurve(); + Handle(Geom_Surface) aSurf = GC->Surface(); + TopLoc_Location aLoc = aNewEdge.Location() * GC->Location(); + BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion()); + } + } + + anEdge.Free(Standard_True); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + + TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD); + + BB.Remove(anEdgeFORWARD, V1); + BB.Remove(anEdgeFORWARD, V2); + + V1.Location(Identity); + V2.Location(Identity); + if (ToReverse) + { + V2.Orientation(TopAbs_FORWARD); + V1.Orientation(TopAbs_REVERSED); + } + BB.Add(anEdgeFORWARD, V1); + BB.Add(anEdgeFORWARD, V2); + + if (ToReverse) + { + anEdge.Reverse(); + ReversedEdges.Add(anEdge); + } + + BB.Degenerated(anEdge, IsDegen); +} diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cdl b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cdl index 5c423f5873..753674cdf5 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cdl +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cdl @@ -212,12 +212,28 @@ is -- - boundary tolerance BoundTol -- - angular tolerance TolAngular. + + +-- ============================================ +-- Methods to set parameters for approximation +-- ============================================ + SetMaxDegree(me : in out; + NewMaxDegree : Integer from Standard); + ---Purpose: Define the maximum V degree of resulting surface + + SetMaxSegments(me : in out; + NewMaxSegments : Integer from Standard); + ---Purpose: Define the maximum number of spans in V-direction + -- on resulting surface + SetForceApproxC1(me : in out; ForceApproxC1 : Boolean from Standard); ---Purpose: Set the flag that indicates attempt to approximate -- a C1-continuous surface if a swept surface proved -- to be C0. + + SetTransitionMode(me : in out; Mode :TransitionMode from BRepBuilderAPI = BRepBuilderAPI_Transformed) ---Purpose: Sets the transition mode to manage discontinuities on diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx index 86231ca848..77731fd8af 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx @@ -200,6 +200,24 @@ void BRepOffsetAPI_MakePipeShell::Delete( const TopoDS_Shape& Profile) myPipe->SetTolerance(Tol3d, BoundTol, TolAngular); } +//======================================================================= +//function : SetMaxDegree +//purpose : +//======================================================================= +void BRepOffsetAPI_MakePipeShell::SetMaxDegree(const Standard_Integer NewMaxDegree) +{ + myPipe->SetMaxDegree(NewMaxDegree); +} + +//======================================================================= +//function : SetMaxSegments +//purpose : +//======================================================================= +void BRepOffsetAPI_MakePipeShell::SetMaxSegments(const Standard_Integer NewMaxSegments) +{ + myPipe->SetMaxSegments(NewMaxSegments); +} + //======================================================================= //function : SetForceApproxC1 //purpose : Set the flag that indicates attempt to approximate diff --git a/src/BRepTools/BRepTools_TrsfModification.cxx b/src/BRepTools/BRepTools_TrsfModification.cxx index 96aa8e40cc..9535326161 100644 --- a/src/BRepTools/BRepTools_TrsfModification.cxx +++ b/src/BRepTools/BRepTools_TrsfModification.cxx @@ -30,6 +30,7 @@ #include #include +#include //======================================================================= //function : BRepTools_TrsfModification @@ -147,6 +148,9 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d Standard_Real scale = myTrsf.ScaleFactor(); Tol *= Abs(scale); const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,loc); + GeomAdaptor_Surface GAsurf(S); + if (GAsurf.GetType() == GeomAbs_Plane) + return Standard_False; Standard_Real f,l; Handle(Geom2d_Curve) NewC = BRep_Tool::CurveOnSurface(E,F,f,l); diff --git a/src/GeomFill/GeomFill_SectionPlacement.cxx b/src/GeomFill/GeomFill_SectionPlacement.cxx index 91f4c103f5..fa41ecbe5a 100644 --- a/src/GeomFill/GeomFill_SectionPlacement.cxx +++ b/src/GeomFill/GeomFill_SectionPlacement.cxx @@ -317,8 +317,8 @@ GeomFill_SectionPlacement(const Handle(GeomFill_LocationLaw)& L, delta = (BC->Knot(i+1) - t) / NbLocalPnts; for (j = 0; j < NbLocalPnts; j++) { - t += delta; Pnts->SetValue( nb++, myAdpSection.Value(t) ); + t += delta; } } if (I3 != I4 && first < BC->Knot(I3)) @@ -327,8 +327,8 @@ GeomFill_SectionPlacement(const Handle(GeomFill_LocationLaw)& L, delta = (last - t) / NbLocalPnts; for (j = 0; j < NbLocalPnts; j++) { - t += delta; Pnts->SetValue( nb++, myAdpSection.Value(t) ); + t += delta; } } if (!myAdpSection.IsClosed()) diff --git a/src/IntTools/FILES b/src/IntTools/FILES deleted file mode 100644 index 05d791b82b..0000000000 --- a/src/IntTools/FILES +++ /dev/null @@ -1 +0,0 @@ -IntTools_EdgeEdge_1.cxx diff --git a/src/IntTools/IntTools.cdl b/src/IntTools/IntTools.cdl index eb0be3f02c..df6c142ba0 100644 --- a/src/IntTools/IntTools.cdl +++ b/src/IntTools/IntTools.cdl @@ -87,10 +87,6 @@ is ---Purpose: class provides computing ranges of parameters --- of edge/face intersection. - class BeanBeanIntersector; - ---Purpose: class provides computing ranges of parameters - --- of edge/edge intersection. - ----- class Curve; ---Purpose: class is a container of diff --git a/src/IntTools/IntTools_BeanBeanIntersector.cdl b/src/IntTools/IntTools_BeanBeanIntersector.cdl deleted file mode 100644 index 0e51ba37d8..0000000000 --- a/src/IntTools/IntTools_BeanBeanIntersector.cdl +++ /dev/null @@ -1,176 +0,0 @@ --- Created on: 2001-07-06 --- Created by: Michael KLOKOV --- Copyright (c) 2001-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and / or modify it --- under the terms of the GNU Lesser General Public version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class BeanBeanIntersector from IntTools - - ---Purpose: The class BeanBeanIntersector computes ranges of parameters on - --- the curve of a first bean (part of edge) that bounds the parts of bean which - --- are on the other bean according to tolerance of edges. - -uses - SequenceOfRoots from IntTools, - MarkedRangeSet from IntTools, - SequenceOfRanges from IntTools, - Range from IntTools, - ExtCC from Extrema, - ProjectPointOnCurve from GeomAPI, - Edge from TopoDS, - Curve from BRepAdaptor, - Curve from Geom - - -is - Create returns BeanBeanIntersector from IntTools; - - Create(theEdge1: Edge from TopoDS; - theEdge2: Edge from TopoDS) - returns BeanBeanIntersector from IntTools; - ---Purpose: - --- Initializes the algorithm - --- - - Create(theCurve1 : Curve from BRepAdaptor; - theCurve2 : Curve from BRepAdaptor; - theBeanTolerance1: Real from Standard; - theBeanTolerance2: Real from Standard) - returns BeanBeanIntersector from IntTools; - ---Purpose: - --- Initializes the algorithm - --- - - Create(theCurve1 : Curve from BRepAdaptor; - theCurve2 : Curve from BRepAdaptor; - theFirstParOnCurve1: Real from Standard; - theLastParOnCurve1 : Real from Standard; - theFirstParOnCurve2: Real from Standard; - theLastParOnCurve2 : Real from Standard; - theBeanTolerance1 : Real from Standard; - theBeanTolerance2 : Real from Standard) - returns BeanBeanIntersector from IntTools; - ---Purpose: - --- Initializes the algorithm - --- - - Init(me: in out;theEdge1: Edge from TopoDS; - theEdge2: Edge from TopoDS); - ---Purpose: - --- Initializes the algorithm - --- - - - - Init(me: in out;theCurve1 : Curve from BRepAdaptor; - theCurve2 : Curve from BRepAdaptor; - theBeanTolerance1: Real from Standard; - theBeanTolerance2: Real from Standard); - ---Purpose: - --- Initializes the algorithm - --- - - Init(me: in out;theCurve1 : Curve from BRepAdaptor; - theCurve2 : Curve from BRepAdaptor; - theFirstParOnCurve1: Real from Standard; - theLastParOnCurve1 : Real from Standard; - theFirstParOnCurve2: Real from Standard; - theLastParOnCurve2 : Real from Standard; - theBeanTolerance1 : Real from Standard; - theBeanTolerance2 : Real from Standard); - ---Purpose: - --- Initializes the algorithm - --- - - SetBeanParameters(me: in out;IsFirstBean : Boolean from Standard; - theFirstParOnCurve: Real from Standard; - theLastParOnCurve : Real from Standard); - ---Purpose: - --- Sets bounding parameters for first bean if IsFirstBean is true - --- and for second bean if IsFirstBean is false - --- - - - Perform(me: in out); - ---Purpose: - --- Launches the algorithm - --- - - IsDone(me) returns Boolean from Standard; - ---C++: inline - ---Purpose: - --- Returns true if the computations was successfull - --- otherwise returns false - - Result(me) - returns SequenceOfRanges from IntTools; - ---C++: return const & - - Result(me; theResults: out SequenceOfRanges from IntTools); - - - -- private - - ComputeRoughIntersection(me: in out) - is private; - - FastComputeIntersection(me: in out) - returns Boolean from Standard is private; - - ComputeUsingExtrema(me: in out; theRange2: Range from IntTools) - is private; - - ComputeNearRangeBoundaries(me: in out; theRange2: Range from IntTools) - is private; - - ComputeRangeFromStartPoint(me: in out; ToIncreaseParameter : Boolean from Standard; - theParameter : Real from Standard; - theIndex : Integer from Standard; - theParameter2 : Real from Standard; - theRange2 : Range from IntTools) - is private; - - Distance(me: in out; theArg : Real from Standard; - theArgOnOtherBean: out Real from Standard) - returns Real from Standard - is private; - -fields - - -- sources - myCurve1 : Curve from BRepAdaptor; - myCurve2 : Curve from BRepAdaptor; - myTrsfCurve1 : Curve from Geom; - myTrsfCurve2 : Curve from Geom; - - myFirstParameter1 : Real from Standard; - myLastParameter1 : Real from Standard; - myFirstParameter2 : Real from Standard; - myLastParameter2 : Real from Standard; - - myBeanTolerance1 : Real from Standard; - myBeanTolerance2 : Real from Standard; - - myCurveResolution1: Real from Standard; - myCriteria : Real from Standard; - - -- tools - myProjector : ProjectPointOnCurve from GeomAPI; - myRangeManager : MarkedRangeSet from IntTools; - myDeflection : Real from Standard; - - -- results - myResults : SequenceOfRanges from IntTools; - - myIsDone : Boolean from Standard; - -end BeanBeanIntersector from IntTools; diff --git a/src/IntTools/IntTools_BeanBeanIntersector.cxx b/src/IntTools/IntTools_BeanBeanIntersector.cxx deleted file mode 100644 index 96bfe98628..0000000000 --- a/src/IntTools/IntTools_BeanBeanIntersector.cxx +++ /dev/null @@ -1,1393 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and / or modify it -// under the terms of the GNU Lesser General Public version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static - void LocalPrepareArgs(BRepAdaptor_Curve& theCurve, - const Standard_Real theFirstParameter, - const Standard_Real theLastParameter, - Standard_Real& theDeflection, - IntTools_CArray1OfReal& theArgs); - -static - Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter, - IntTools_MarkedRangeSet& theMarkedRange); -static - Standard_Integer CheckCoincidence(const Standard_Real aT11, - const Standard_Real aT12, - const Handle(Geom_Curve)& aC1, - const Standard_Real aT21, - const Standard_Real aT22, - const Handle(Geom_Curve)& aC2, - const Standard_Real aCriteria, - const Standard_Real aCurveResolution1, - GeomAPI_ProjectPointOnCurve& aProjector); - - -// ================================================================================== -// function: IntTools_BeanBeanIntersector -// purpose: -// ================================================================================== -IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector() : - -myFirstParameter1(0.), -myLastParameter1(0.), -myFirstParameter2(0.), -myLastParameter2(0.), -myBeanTolerance1(0.), -myBeanTolerance2(0.), -myCurveResolution1(0.), -myCriteria(0.), -myIsDone(Standard_False) -{ -} - -// ================================================================================== -// function: IntTools_BeanBeanIntersector -// purpose: -// ================================================================================== -IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const TopoDS_Edge& theEdge1, - const TopoDS_Edge& theEdge2) : - -myFirstParameter1(0.), -myLastParameter1(0.), -myFirstParameter2(0.), -myLastParameter2(0.), -myBeanTolerance1(0.), -myBeanTolerance2(0.), -myCurveResolution1(0.), -myCriteria(0.), -myIsDone(Standard_False) -{ - Init(theEdge1, theEdge2); -} - -// ================================================================================== -// function: IntTools_BeanBeanIntersector -// purpose: -// ================================================================================== -IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const BRepAdaptor_Curve& theCurve1, - const BRepAdaptor_Curve& theCurve2, - const Standard_Real theBeanTolerance1, - const Standard_Real theBeanTolerance2) : - -myFirstParameter1(0.), -myLastParameter1(0.), -myFirstParameter2(0.), -myLastParameter2(0.), -myBeanTolerance1(0.), -myBeanTolerance2(0.), -myCurveResolution1(0.), -myCriteria(0.), -myIsDone(Standard_False) -{ - Init(theCurve1, theCurve2, theBeanTolerance1, theBeanTolerance2); -} - -// ================================================================================== -// function: IntTools_BeanBeanIntersector -// purpose: -// ================================================================================== -IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const BRepAdaptor_Curve& theCurve1, - const BRepAdaptor_Curve& theCurve2, - const Standard_Real theFirstParOnCurve1, - const Standard_Real theLastParOnCurve1, - const Standard_Real theFirstParOnCurve2, - const Standard_Real theLastParOnCurve2, - const Standard_Real theBeanTolerance1, - const Standard_Real theBeanTolerance2) : - -myFirstParameter1(0.), -myLastParameter1(0.), -myFirstParameter2(0.), -myLastParameter2(0.), -myBeanTolerance1(0.), -myBeanTolerance2(0.), -myCurveResolution1(0.), -myCriteria(0.), -myIsDone(Standard_False) -{ - Init(theCurve1, theCurve2, theFirstParOnCurve1, theLastParOnCurve1, - theFirstParOnCurve2, theLastParOnCurve2, - theBeanTolerance1, theBeanTolerance2); -} - -// ================================================================================== -// function: Init -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::Init(const TopoDS_Edge& theEdge1, - const TopoDS_Edge& theEdge2) -{ - myCurve1.Initialize(theEdge1); - myCurve2.Initialize(theEdge2); - - myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf())); - myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf())); - - SetBeanParameters(Standard_True, myCurve1.FirstParameter(), myCurve1.LastParameter()); - SetBeanParameters(Standard_False, myCurve2.FirstParameter(), myCurve2.LastParameter()); - - myBeanTolerance1 = BRep_Tool::Tolerance(theEdge1); - myBeanTolerance2 = BRep_Tool::Tolerance(theEdge2); - myCriteria = myBeanTolerance1 + myBeanTolerance2; - myCurveResolution1 = myCurve1.Resolution(myCriteria); -} - -// ================================================================================== -// function: Init -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::Init(const BRepAdaptor_Curve& theCurve1, - const BRepAdaptor_Curve& theCurve2, - const Standard_Real theBeanTolerance1, - const Standard_Real theBeanTolerance2) -{ - myCurve1 = theCurve1; - myCurve2 = theCurve2; - - SetBeanParameters(Standard_True, myCurve1.FirstParameter(), myCurve1.LastParameter()); - SetBeanParameters(Standard_False, myCurve2.FirstParameter(), myCurve2.LastParameter()); - - myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf())); - myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf())); - - myBeanTolerance1 = theBeanTolerance1; - myBeanTolerance2 = theBeanTolerance2; - myCriteria = myBeanTolerance1 + myBeanTolerance2; - myCurveResolution1 = myCurve1.Resolution(myCriteria); -} - -// ================================================================================== -// function: Init -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::Init(const BRepAdaptor_Curve& theCurve1, - const BRepAdaptor_Curve& theCurve2, - const Standard_Real theFirstParOnCurve1, - const Standard_Real theLastParOnCurve1, - const Standard_Real theFirstParOnCurve2, - const Standard_Real theLastParOnCurve2, - const Standard_Real theBeanTolerance1, - const Standard_Real theBeanTolerance2) -{ - myCurve1 = theCurve1; - myCurve2 = theCurve2; - - myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf())); - myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf())); - - SetBeanParameters(Standard_True, theFirstParOnCurve1, theLastParOnCurve1); - SetBeanParameters(Standard_False, theFirstParOnCurve2, theLastParOnCurve2); - - myBeanTolerance1 = theBeanTolerance1; - myBeanTolerance2 = theBeanTolerance2; - myCriteria = myBeanTolerance1 + myBeanTolerance2; - myCurveResolution1 = myCurve1.Resolution(myCriteria); -} - -// ================================================================================== -// function: SetBeanParameters -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::SetBeanParameters(const Standard_Boolean IsFirstBean, - const Standard_Real theFirstParOnCurve, - const Standard_Real theLastParOnCurve) -{ - if(IsFirstBean) { - myFirstParameter1 = theFirstParOnCurve; - myLastParameter1 = theLastParOnCurve; - } - else { - myFirstParameter2 = theFirstParOnCurve; - myLastParameter2 = theLastParOnCurve; - } -} -// ================================================================================== -// function: Result -// purpose: -// ================================================================================== -const IntTools_SequenceOfRanges& IntTools_BeanBeanIntersector::Result() const -{ - return myResults; -} - -// ================================================================================== -// function: Result -// purpose: -// ================================================================================== - void IntTools_BeanBeanIntersector::Result(IntTools_SequenceOfRanges& theResults) const -{ - theResults = myResults; -} -// ================================================================================== -// function: Perform -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::Perform() -{ - Standard_Boolean bFastComputed; - Standard_Integer k, i, iFlag, aNbRanges, aNbResults; - Standard_Real aMidParameter, aCoeff, aParamDist, aPPC; - Standard_Real aCriteria2, aD2; - gp_Pnt aPi, aPh; - IntTools_CArray1OfReal aParams; - IntTools_Range aRange2, aRange; - // - myIsDone = Standard_False; - myResults.Clear(); - // - LocalPrepareArgs(myCurve1, myFirstParameter1, myLastParameter1, myDeflection, aParams); - // - myRangeManager.SetRanges(aParams, 0); - // - aNbRanges=myRangeManager.Length(); - if(!aNbRanges) { - return; - } - // - bFastComputed=FastComputeIntersection(); - if(bFastComputed) { - aRange.SetFirst(myFirstParameter1); - aRange.SetLast (myLastParameter1); - myResults.Append(aRange); - myIsDone = Standard_True; - return; - } - // - ComputeRoughIntersection(); - - //Standard_Real aMidParameter = (myFirstParameter2 + myLastParameter2) * 0.5; - aCoeff=0.5753; - aMidParameter = myFirstParameter2+(myLastParameter2-myFirstParameter2)*aCoeff; - // - for(k = 0; k < 2; ++k) { - if(!k) { - aRange2.SetFirst(myFirstParameter2); - aRange2.SetLast(aMidParameter); - } - else { - aRange2.SetFirst(aMidParameter); - aRange2.SetLast(myLastParameter2); - } - - ComputeUsingExtrema(aRange2); - - ComputeNearRangeBoundaries(aRange2); - } - // - // Legend iFlag - // - // 0 - just initialized - // 1 - non-intersected - // 2 - roughly intersected - // 3 - intersection is not done - // 4 - coincided range - // - aPPC=Precision::PConfusion(); - aCriteria2=myCriteria*myCriteria; - aNbRanges=myRangeManager.Length(); - // - for(i=1; i<=aNbRanges; ++i) { - iFlag=myRangeManager.Flag(i); - // - if(iFlag==4) { - aRange=myRangeManager.Range(i); - aNbResults=myResults.Length(); - if(aNbResults>0) { - const IntTools_Range& aLastRange = myResults.Last(); - // - aParamDist = Abs(aRange.First() - aLastRange.Last()); - if(aParamDist > myCurveResolution1) { - myResults.Append(aRange); - } - else { - aPi=myCurve1.Value(aRange.First()); - aPh=myCurve1.Value(aLastRange.Last()); - aD2=aPi.SquareDistance(aPh); - if(aParamDist0) { - else { - myResults.Append(aRange); - } - } //if(iFlag==4) { - } // for(i = 1; i <= myRangeManager.Length(); i++) { - myIsDone = Standard_True; -} -// ================================================================================== -// function: FastComputeIntersection -// purpose: -// ================================================================================== -Standard_Boolean IntTools_BeanBeanIntersector::FastComputeIntersection() -{ - Standard_Boolean aresult; - GeomAbs_CurveType aCT1, aCT2; - // - aresult = Standard_False; - // - aCT1=myCurve1.GetType(); - aCT2=myCurve2.GetType(); - // - if(aCT1 != aCT2) { - return aresult; - } - // - // Line - if(aCT1==GeomAbs_Line) { - Standard_Real par1, par2; - - if((Distance(myFirstParameter1, par1) < myCriteria) && - (Distance(myLastParameter1, par2) < myCriteria)) { - - if((par1 >= myFirstParameter2) && (par1 <= myLastParameter2) && - (par2 >= myFirstParameter2) && (par2 <= myLastParameter2)) { - myRangeManager.InsertRange(myFirstParameter1, myLastParameter1, 4); - aresult = Standard_True; - } - } - return aresult; - } - // - // Circle - if(aCT1==GeomAbs_Circle) { - Standard_Real anAngle, aPA, aDistLoc, aDist, aDiff, aR1, aR2; - gp_Circ aCirc1, aCirc2; - gp_Dir aDir1, aDir2; - // - aCirc1=myCurve1.Circle(); - aCirc2=myCurve2.Circle(); - aR1=aCirc1.Radius(); - aR2=aCirc2.Radius(); - // - aPA=Precision::Angular(); - aDir1 = aCirc1.Axis().Direction(); - aDir2 = aCirc2.Axis().Direction(); - // - anAngle = aDir1.Angle(aDir2); - if(anAngle > aPA) { - return aresult; //-> - } - // - const gp_Pnt& aPLoc1=aCirc1.Location(); - const gp_Pnt& aPLoc2=aCirc2.Location(); - aDistLoc = aPLoc1.Distance(aPLoc2); - aDist=aDistLoc; - aDiff=aR1 - aR2; - aDist+=Abs(aDiff); - if(Abs(aDist) > myCriteria) { - return aresult; //-> - } - // - Standard_Real aSinPA, atmpvalue, aprojectedradius; - // - aSinPA=sin(aPA); - atmpvalue = aR1*aSinPA; - atmpvalue *= atmpvalue; - aprojectedradius = sqrt(aR1*aR1 - atmpvalue); - - aDiff = aprojectedradius - aR2; - aDist = aDistLoc + sqrt((aDiff * aDiff) + atmpvalue); - if(Abs(aDist) > myCriteria) { - return aresult; //-> - } - // - Standard_Boolean newparfound; - Standard_Integer i; - Standard_Real afirstpar, alastpar, par1, par2, apar; - // - afirstpar = myFirstParameter1; - alastpar = myLastParameter1; - - for(i = 0; i < 2; i++) { - if((Distance(afirstpar, par1) < myCriteria) && - (Distance(alastpar , par2) < myCriteria)) { - - if(i || Distance((myFirstParameter1 + myLastParameter2) * 0.5, apar) < myCriteria) { - myRangeManager.InsertRange(afirstpar, alastpar, 4); - - if(!i) { - aresult = Standard_True; - } - } - break; - } - // - if(i) { - break; - } - // i=0 : - newparfound = Standard_False; - - if(Distance((myFirstParameter1 + myLastParameter2) * 0.5, apar) < myCriteria) { - afirstpar = myFirstParameter1 + myCriteria; - alastpar = myLastParameter1 - myCriteria; - newparfound = Standard_True; - - if(alastpar <= afirstpar) { - newparfound = Standard_False; - } - } - // - if(!newparfound) { - break; - } - }// for(i = 0; i < 2; i++) { - } // if(aCT1==GeomAbs_Circle) - //modified by NIZNHY-PKV Mon Oct 08 14:08:19 2012f - if (aCT1==GeomAbs_BSplineCurve || aCT1==GeomAbs_BezierCurve) { - Standard_Integer iFlag; - // - iFlag=CheckCoincidence(myFirstParameter1, - myLastParameter1, - myTrsfCurve1, - myFirstParameter2, - myLastParameter2, - myTrsfCurve2, - myCriteria, - myCurveResolution1, - myProjector); - if (!iFlag) { - aresult=!aresult; - } - } - //modified by NIZNHY-PKV Mon Oct 08 14:08:23 2012t - return aresult; -} -// ================================================================================== -// function: Distance -// purpose: -// ================================================================================== -Standard_Real IntTools_BeanBeanIntersector::Distance(const Standard_Real theArg, - Standard_Real& theArgOnOtherBean) -{ - Standard_Real aDistance; - Standard_Integer aNbPoints; - gp_Pnt aPoint; - // - aDistance=RealLast(); - // - aPoint=myCurve1.Value(theArg); - myProjector.Init(myTrsfCurve2, myFirstParameter2, myLastParameter2); - myProjector.Perform(aPoint); - // - aNbPoints=myProjector.NbPoints(); - if(aNbPoints > 0) { - theArgOnOtherBean = myProjector.LowerDistanceParameter(); - aDistance=myProjector.LowerDistance(); - } - // - else { - Standard_Real aDistance1, aDistance2; - // - aDistance1 = aPoint.Distance(myCurve2.Value(myFirstParameter2)); - aDistance2 = aPoint.Distance(myCurve2.Value(myLastParameter2)); - // - theArgOnOtherBean = myLastParameter2; - aDistance=aDistance2; - if(aDistance1 < aDistance2) { - theArgOnOtherBean = myFirstParameter2; - aDistance=aDistance1; - } - } - return aDistance; -} -// ================================================================================== -// function: ComputeRoughIntersection -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::ComputeRoughIntersection() -{ - Standard_Boolean isintersection; - Standard_Integer i, aNbArgs, aNbArgs1, aNbRanges, j, aNbLines, k, pIt, extIt, iFlag; - Standard_Real aDeflection, aGPR, aCurDeflection, aT1, aT2, aD; - Standard_Real aMaxDistance, aDistance, aPPC, aPrm1, aPrm2, aPPA; - GeomAbs_CurveType aCT1, aCT2; - gp_Pnt aPoint1, aPoint2, aMidPOnCurve, aMidPOnLine, aP1, aP2; - IntTools_CArray1OfReal anArgs; - LocalPrepareArgs(myCurve2, myFirstParameter2, myLastParameter2, aDeflection, anArgs); - // - aNbArgs=anArgs.Length(); - if(!aNbArgs) { - return; - } - // - aCT1=myCurve1.GetType(); - aCT2=myCurve2.GetType(); - aGPR=gp::Resolution(); - aPPC=Precision::PConfusion(); - aPPA=Precision::Angular(); - aNbArgs1=aNbArgs-1; - // - Intf_Array1OfLin aLines(1, aNbArgs1); - TColStd_Array1OfInteger aLineFlags(1, aNbArgs1); - TColStd_Array1OfReal aDistances(1, aNbArgs1); - // - aT1=anArgs(0); - aPoint1 = myCurve2.Value(aT1); - for(i=1; i aDeflection) { - aDeflection = aCurDeflection; - } - } - } - aT1=aT2; - aPoint1 = aPoint2; - } - // - aNbLines=aLines.Upper(); - aMaxDistance = myCriteria + myDeflection + aDeflection; - - aT1=myRangeManager.Range(1).First(); - aPoint1 = myCurve1.Value(aT1); - aNbRanges=myRangeManager.Length(); - for(i = 1; i <= aNbRanges; ++i) { - const IntTools_Range& aRange = myRangeManager.Range(i); - aT2=aRange.Last(); - aPoint2 = myCurve1.Value(aT2); - // - iFlag=myRangeManager.Flag(i); - if(iFlag==4) {// coincided - aT1=aT2; - aPoint1 = aPoint2; - continue; - } - // - myRangeManager.SetFlag(i, 1); // not intersected - - Bnd_Box aBox1; - aBox1.Add(aPoint1); - aBox1.Add(aPoint2); - aBox1.Enlarge(myBeanTolerance1 + myDeflection); - - gp_Vec aVec(aPoint1, aPoint2); - - aDistance=aVec.Magnitude(); - if(aDistance <= aGPR) { - myRangeManager.SetFlag(i, 0); - continue; - } - // - gp_Lin aLine(aPoint1, gp_Dir(aVec)); - // - if((aCT1 == GeomAbs_BezierCurve) || - (aCT1 == GeomAbs_BSplineCurve)) { - aMidPOnCurve = myCurve1.Value((aRange.First() + aRange.Last()) * 0.5); - aMidPOnLine = ElCLib::Value((aDistance*0.5), aLine); - aCurDeflection = aMidPOnCurve.Distance(aMidPOnLine); - if(myDeflection < aCurDeflection) { - aMaxDistance += aCurDeflection - myDeflection; - myDeflection = aCurDeflection; - } - } - // - for(j=1; j<=aNbLines; ++j) { - if(!aLineFlags(j)) { - myRangeManager.SetFlag(i, 0); - continue; - } - // - const gp_Lin& aL2=aLines(j); - //Handle(Geom_Line) aC2=new Geom_Line(aL2); // DEB ft - aD=aDistances(j); - aP1=ElCLib::Value(0., aL2); - aP2=ElCLib::Value(aD, aL2); - // - Extrema_ExtElC anExtrema(aLine, aL2, aPPA); - if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) { - isintersection = Standard_False; - - if(anExtrema.IsParallel()) { - isintersection = (anExtrema.SquareDistance(1) < aMaxDistance * aMaxDistance); - } - else { //1 - for(k = 1; !isintersection && k <= anExtrema.NbExt(); ++k) { - if(anExtrema.SquareDistance(k) < aMaxDistance * aMaxDistance) { - Extrema_POnCurv P1, P2; - anExtrema.Points(k, P1, P2); - aPrm1=P1.Parameter(); - aPrm2=P2.Parameter(); - if((aPrm1 >= -aMaxDistance) && (aPrm1 <= aDistance+aMaxDistance) && - (aPrm2 >= -aMaxDistance) && (aPrm2 <= aD+aMaxDistance)) { - isintersection = Standard_True; - } - else { // 2 - Extrema_ExtPElC aPointProjector; - - for(pIt = 0; !isintersection && (pIt < 4); ++pIt) { - switch (pIt) { - case 0: { - aPointProjector = - //Extrema_ExtPElC(aPoint1, aLines(j), aPPC, 0., aDistances(j)); - Extrema_ExtPElC(aPoint1, aL2, aPPC, -aMaxDistance, aD+aMaxDistance); - break; - } - case 1: { - aPointProjector = - //Extrema_ExtPElC(aPoint2, aLines(j), aPPC, 0., aD); - Extrema_ExtPElC(aPoint2, aL2, aPPC, -aMaxDistance, aD+aMaxDistance); - break; - } - case 2: { - aPointProjector = - //Extrema_ExtPElC(ElCLib::Value(0., aLines(j)), aLine, aPPC, 0., aDistance); - Extrema_ExtPElC(aP1, aLine, aPPC, -aMaxDistance, aDistance+aMaxDistance); - break; - } - case 3: { - aPointProjector = - //Extrema_ExtPElC(ElCLib::Value(aDistances(j), aLines(j)), aLine, aPPC, 0., aDistance); - Extrema_ExtPElC(aP2, aLine, aPPC, -aMaxDistance, aDistance+aMaxDistance); - break; - } - default: { - break; - } - } - // - if(aPointProjector.IsDone()) { - Standard_Real aMaxDistance2 = aMaxDistance * aMaxDistance; - for(extIt = 1; extIt <= aPointProjector.NbExt(); extIt++) { - if(aPointProjector.SquareDistance(extIt) < aMaxDistance2) { - isintersection = Standard_True; - } - } - } - } // end for - }// else { // 2 - }//if(anExtrema.Value(k) < aMaxDistance) { - }//for(k = 1; !isintersection && k <= anExtrema.NbExt(); k++) { - }//else { //1 - - if(isintersection) { - myRangeManager.SetFlag(i, 2); // roughly intersected - break; - } - }//if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) { - else { - Bnd_Box aBox2; - aBox2.Add(myCurve2.Value(anArgs(j-1))); - aBox2.Add(myCurve2.Value(anArgs(j))); - aBox2.Enlarge(myBeanTolerance2 + aDeflection); - // - if(!aBox1.IsOut(aBox2)) { - myRangeManager.SetFlag(i, 2); // roughly intersected - break; - } - } - } - aT1=aT2; - aPoint1 = aPoint2; - } -} - -// ================================================================================== -// function: ComputeUsingExtrema -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::ComputeUsingExtrema(const IntTools_Range& theRange2) -{ - //rln Dec 2008. - //Extrema_ExtCC is reused throughout this method to store caches computed on - //theRange2. However it is actually used only in a few calls of - //ComputeUsingExtrema(), so using a default constructor would add unnecessary overhead - //of initialization its internal fields. Since it is not manipulated by Handle then - //we will use a pointer to it and initialize it only when needed. - Extrema_ExtCC *apExtrema = 0; - Handle(GeomAdaptor_HCurve) aHCurve1, aHCurve2; //will be initialized later, only if needed - //handles are used to guard pointers to GeomAdaptor_Curve inside Extrema - Standard_Real aCriteria2 = myCriteria * myCriteria; - for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) { - - if(myRangeManager.Flag(i) == 2 || myRangeManager.Flag(i) == 0) { - const IntTools_Range& aParamRange = myRangeManager.Range(i); - - if(aParamRange.Last() - aParamRange.First() < Precision::PConfusion()) { - - if(((i > 1) && (myRangeManager.Flag(i-1) == 4)) || - ((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 4))) { - myRangeManager.SetFlag(i, 4); - continue; - } - } - if (aHCurve2.IsNull()) { - //initialize only once - apExtrema = new Extrema_ExtCC; - Standard_Real ftmp = theRange2.First() - Precision::PConfusion(); - Standard_Real ltmp = theRange2.Last() + Precision::PConfusion(); - ftmp = (ftmp < myFirstParameter2) ? myFirstParameter2 : ftmp; - ltmp = (ltmp > myLastParameter2) ? myLastParameter2 : ltmp; - aHCurve2 = new GeomAdaptor_HCurve (myTrsfCurve2, ftmp, ltmp); - apExtrema->SetCurve (2, aHCurve2->Curve(), theRange2.First(), theRange2.Last()); - } - Extrema_ExtCC& anExtrema = *apExtrema; - - Standard_Real ftmp = aParamRange.First() - Precision::PConfusion(); - Standard_Real ltmp = aParamRange.Last() + Precision::PConfusion(); - ftmp = (ftmp < myFirstParameter1) ? myFirstParameter1 : ftmp; - ltmp = (ltmp > myLastParameter1) ? myLastParameter1 : ltmp; - aHCurve1 = new GeomAdaptor_HCurve (myTrsfCurve1, ftmp, ltmp); - anExtrema.SetCurve (1, aHCurve1->Curve(), aParamRange.First(), aParamRange.Last()); - - anExtrema.Perform(); - - if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) { - Standard_Integer anOldNbRanges = myRangeManager.Length(); - - if (anExtrema.IsParallel()) { - if(anExtrema.SquareDistance(1) < aCriteria2) { - Standard_Real theParameter1, theParameter2; - Standard_Real adistance1 = Distance(aParamRange.First(), theParameter1); - Standard_Real adistance2 = Distance(aParamRange.Last(), theParameter2); - Standard_Boolean validdistance1 = (adistance1 < myCriteria); - Standard_Boolean validdistance2 = (adistance2 < myCriteria); - - if (validdistance1 && validdistance2) { - myRangeManager.InsertRange(aParamRange.First(), aParamRange.Last(), 4); - continue; - } - else { - if(validdistance1) { - ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), i, theParameter1, theRange2); - } - else { - if(validdistance2) { - ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), i, theParameter2, theRange2); - } - else { - Standard_Real a = aParamRange.First(); - Standard_Real b = aParamRange.Last(); - Standard_Real da = adistance1; - Standard_Real db = adistance2; - Standard_Real asolution = a; - Standard_Boolean found = Standard_False; - - while(((b - a) > myCurveResolution1) && !found) { - asolution = (a+b)*0.5; - Standard_Real adist = Distance(asolution, theParameter1); - - if(adist < myCriteria) { - found = Standard_True; - } - else { - if(da < db) { - b = asolution; - db = adist; - } - else { - a = asolution; - da = adist; - } - } - } // end while - - if(found) { - ComputeRangeFromStartPoint(Standard_False, asolution, i, theParameter1, theRange2); - ComputeRangeFromStartPoint(Standard_True, asolution, i, theParameter1, theRange2); - } - else { - myRangeManager.SetFlag(i, 2); - } - } - } - } - } - } - else { - - for(Standard_Integer j = 1 ; j <= anExtrema.NbExt(); j++) { - if(anExtrema.SquareDistance(j) < aCriteria2) { - Extrema_POnCurv p1, p2; - anExtrema.Points(j, p1, p2); - - Standard_Integer aNbRanges = myRangeManager.Length(); - - Standard_Integer anIndex = myRangeManager.GetIndex(p1.Parameter(), Standard_False); - if(anIndex > 0) { - ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), anIndex, p2.Parameter(), theRange2); - } - - anIndex = myRangeManager.GetIndex(p1.Parameter(), Standard_True); - - if(anIndex > 0) { - ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), anIndex, p2.Parameter(), theRange2); - } - - if(aNbRanges == myRangeManager.Length()) { - SetEmptyResultRange(p1.Parameter(), myRangeManager); - } - } - } // end for - } - Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges; - - if(adifference > 0) { - i+=adifference; - } - } - else { - myRangeManager.SetFlag(i, 3); // intersection not done. - } - } - } - if (apExtrema) delete apExtrema; -} - -// ================================================================================== -// function: ComputeNearRangeBoundaries -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::ComputeNearRangeBoundaries(const IntTools_Range& theRange2) -{ - Standard_Real theParameter = theRange2.First(); - - for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) { - if(myRangeManager.Flag(i) != 3) - continue; - - if((i > 1) && ((myRangeManager.Flag(i-1) == 1) || (myRangeManager.Flag(i-1) == 4))) { - myRangeManager.SetFlag(i, 2); - continue; - } - - const IntTools_Range& aParamRange = myRangeManager.Range(i); - - if(Distance(aParamRange.First(), theParameter) < myCriteria) { - Standard_Integer aNbRanges = myRangeManager.Length(); - - if(i > 1) { - ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), i-1, theParameter, theRange2); - } - ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), i + (myRangeManager.Length() - aNbRanges), theParameter, theRange2); - - if(aNbRanges == myRangeManager.Length()) { - SetEmptyResultRange(aParamRange.First(), myRangeManager); - } - } - else { - myRangeManager.SetFlag(i, 2); - } - } - - if((myRangeManager.Flag(myRangeManager.Length()) == 3) || - (myRangeManager.Flag(myRangeManager.Length()) == 2)) { - const IntTools_Range& aParamRange = myRangeManager.Range(myRangeManager.Length()); - - if(Distance(aParamRange.Last(), theParameter) < myCriteria) { - Standard_Integer aNbRanges = myRangeManager.Length(); - myRangeManager.SetFlag(myRangeManager.Length(), 2); - - ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), myRangeManager.Length(), theParameter, theRange2); - - if(aNbRanges == myRangeManager.Length()) { - SetEmptyResultRange(aParamRange.Last(), myRangeManager); - } - } - else { - myRangeManager.SetFlag(myRangeManager.Length(), 2); - } - } -} - -// ================================================================================== -// function: ComputeRangeFromStartPoint -// purpose: -// ================================================================================== -void IntTools_BeanBeanIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter, - const Standard_Real theParameter, - const Standard_Integer theIndex, - const Standard_Real theParameter2, - const IntTools_Range& theRange2) -{ - - if(myRangeManager.Flag(theIndex) == 4 || - myRangeManager.Flag(theIndex) == 1) - return; - - Standard_Integer aValidIndex = theIndex; - Standard_Real aMinDelta = myCurveResolution1 * 0.5; - Standard_Real aDeltaRestrictor = myLastParameter1 - myFirstParameter1; - - if(Abs(aDeltaRestrictor) < Precision::PConfusion()) { - return; - } - - if(aMinDelta > aDeltaRestrictor) { - aMinDelta = aDeltaRestrictor; - } - Standard_Real tenOfMinDelta = aMinDelta * 10.; - Standard_Real aDelta = myCurveResolution1; - Standard_Real aCurPar = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta); - Standard_Real aPrevPar = theParameter; - IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex); - - Standard_Boolean BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First()); - - if(BoundaryCondition) { - aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First(); - BoundaryCondition = Standard_False; - } - - Standard_Integer loopcounter = 0; // neccesary to have no infinite loop - Standard_Real aParameter = theParameter2; - Standard_Boolean anotherSolutionFound = Standard_False; - - Standard_Boolean isboundaryindex = Standard_False; - Standard_Boolean isvalidindex = Standard_True; - - Standard_Real aCriteria2 = myCriteria * myCriteria; - - while((aDelta >= aMinDelta) && (loopcounter <= 10)) { - Standard_Boolean pointfound = Standard_False; - - gp_Pnt aPoint = myCurve1.Value(aCurPar); - GeomAdaptor_Curve aCurve2(myTrsfCurve2, theRange2.First(), theRange2.Last()); - - Extrema_LocateExtPC anExtrema(aPoint, aCurve2, aParameter, theRange2.First(), theRange2.Last(), 1.e-10); - - if(anExtrema.IsDone()) { - if(anExtrema.SquareDistance() < aCriteria2) { - Extrema_POnCurv aPOnCurv = anExtrema.Point(); - aParameter = aPOnCurv.Parameter(); - pointfound = Standard_True; - } - } - else { - // pointfound = (Distance(aCurPar, aParameter) < myCriteria); - Standard_Real afoundparam = aParameter; - - if(Distance(aCurPar, afoundparam) < myCriteria) { - aParameter = afoundparam; - pointfound = Standard_True; - } - } - - if(pointfound) { - aPrevPar = aCurPar; - anotherSolutionFound = Standard_True; - - if(BoundaryCondition && (isboundaryindex || !isvalidindex)) - break; - } - else { - aDeltaRestrictor = aDelta; - } - - // if pointfound decide to increase aDelta using derivative of distance function - // - - aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5); - aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor; - aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta); - - BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First()); - - isboundaryindex = Standard_False; - isvalidindex = Standard_True; - - if(BoundaryCondition) { - isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) || - (ToIncreaseParameter && (aValidIndex == myRangeManager.Length()))); - - if(!isboundaryindex) { - if(pointfound) { - Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1); - - if(aFlag != 1 && aFlag != 4) { - aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1); - aCurrentRange = myRangeManager.Range(aValidIndex); - - if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) || - (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) { - aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5; - aDelta*=0.5; - } - } - else { - isvalidindex = Standard_False; - aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First(); - } - } - } - else { - aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First(); - } - - if(aDelta < tenOfMinDelta) { - loopcounter++; - } - else { - loopcounter = 0; - } - } // end if(BoundaryCondition) - } - - if(anotherSolutionFound) { - if(ToIncreaseParameter) - myRangeManager.InsertRange(theParameter, aPrevPar, 4); - else - myRangeManager.InsertRange(aPrevPar, theParameter, 4); - } -} - -// --------------------------------------------------------------------------------- -// static function: LocalPrepareArgs -// purpose: -// --------------------------------------------------------------------------------- -static void LocalPrepareArgs(BRepAdaptor_Curve& theCurve, - const Standard_Real theFirstParameter, - const Standard_Real theLastParameter, - Standard_Real& theDeflection, - IntTools_CArray1OfReal& theArgs) { - Standard_Integer aDiscretization = 30; - Standard_Real aRelativeDeflection = 0.01; - theDeflection = aRelativeDeflection; - Standard_Boolean prepareargs = Standard_True; - - switch(theCurve.GetType()) { - case GeomAbs_Line: { - prepareargs = Standard_False; - aDiscretization = 3; - theArgs.Append(theFirstParameter); - - if((theLastParameter - theFirstParameter) > Precision::PConfusion()) { - theArgs.Append((theFirstParameter + theLastParameter)*0.5); - } - theArgs.Append(theLastParameter); - theDeflection = Precision::Confusion(); - break; - } - case GeomAbs_Circle: { - aDiscretization = 23; - theDeflection = aRelativeDeflection * theCurve.Circle().Radius(); - break; - } - case GeomAbs_Ellipse: { - aDiscretization = 40; - theDeflection = 2 * aRelativeDeflection * theCurve.Ellipse().MajorRadius(); - break; - } - case GeomAbs_Hyperbola: - case GeomAbs_Parabola: { - aDiscretization = 40; - theDeflection = aRelativeDeflection; - break; - } - case GeomAbs_BezierCurve: { - aDiscretization = 30; - theDeflection = aRelativeDeflection; - break; - } - case GeomAbs_BSplineCurve: { - aDiscretization = 30; - theDeflection = aRelativeDeflection; - break; - } - default: { - aDiscretization = 30; - theDeflection = aRelativeDeflection; - } - } - - if(prepareargs) { - IntTools::PrepareArgs(theCurve, theLastParameter, theFirstParameter, aDiscretization, aRelativeDeflection, theArgs); - } -} -// --------------------------------------------------------------------------------- -// static function: SetEmptyResultRange -// purpose: -// --------------------------------------------------------------------------------- -static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter, - IntTools_MarkedRangeSet& theMarkedRange) { - - const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter); - Standard_Boolean add = (anIndices.Length() > 0); - - for(Standard_Integer k = 1; k <= anIndices.Length(); k++) { - if(theMarkedRange.Flag(anIndices(k)) == 4) { - add = Standard_False; - break; - } - } - - if(add) { - theMarkedRange.InsertRange(theParameter, theParameter, 4); - } - - return add; -} -//modified by NIZNHY-PKV Fri Oct 12 09:34:10 2012f -static - Standard_Integer DistPC(const Standard_Real aT1, - const Handle(Geom_Curve)& aC1, - const Standard_Real aCriteria, - GeomAPI_ProjectPointOnCurve& aProjector, - Standard_Real& aD, - Standard_Real& aT2); - - -static - Standard_Integer DistPC(const Standard_Real aT1, - const Handle(Geom_Curve)& aC1, - const Standard_Real aCriteria, - GeomAPI_ProjectPointOnCurve& aProjector, - Standard_Real& aD, - Standard_Real& aT2, - Standard_Real& aDmax, - Standard_Real& aTmax); - -static - Standard_Integer FindMaxDistPC(const Standard_Real aT1A, - const Standard_Real aT1B, - const Handle(Geom_Curve)& aC1, - const Standard_Real aCriteria, - const Standard_Real aEps1, - GeomAPI_ProjectPointOnCurve& aProjector, - Standard_Real& aDmax, - Standard_Real& aT1max); - -//======================================================================= -//function : CheckCoincidence -//purpose : -//======================================================================= -Standard_Integer CheckCoincidence(const Standard_Real aT11, - const Standard_Real aT12, - const Handle(Geom_Curve)& aC1, - const Standard_Real aT21, - const Standard_Real aT22, - const Handle(Geom_Curve)& aC2, - const Standard_Real aCriteria, - const Standard_Real aEps1, - GeomAPI_ProjectPointOnCurve& aProjector) -{ - Standard_Integer iErr, aNb1, i, aNbX; - Standard_Real dT1, aT1, aT2, aD, aDmax, aTmax; - Standard_Real aT1A, aT1B, aD1max,aT1max; - // - iErr=0; // the patches are coincided - // - // - aProjector.Init(aC2, aT21, aT22); - // - aDmax=-1.; - // - // 1. Express evaluation - // - aNb1=10; // Number of intervals on the curve #1 - dT1=(aT12-aT11)/aNb1; - for (i=1; iaCriteria) { - iErr=2; // the distance is too big - return iErr; - } - } - // - // 2. Deep evaluation - aD1max=aDmax; - // - aNbX=aNb1-1; - for (i=1; iaYL) { - aA=aXL; - aXL=aXP; - aYL=aYP; - aXP=aA+(aB-aA)*aGS; - iErr=DistPC(aXP, aC1, aCriteria, aProjector, aYP, aT2P, aDmax, aT1max); - if(iErr){ - return iErr; - } - } - else { - aB=aXP; - aXP=aXL; - aYP=aYL; - aXL=aB-(aB-aA)*aGS; - iErr=DistPC(aXL, aC1, aCriteria, aProjector, aYL, aT2L, aDmax, aT1max); - if(iErr){ - return iErr; - } - } - // - if ((aB-aA)aDmax) { - aDmax=aD; - aTmax=aT2; - } - // - return iErr; -} -//======================================================================= -//function : DistPC -//purpose : -//======================================================================= -Standard_Integer DistPC(const Standard_Real aT1, - const Handle(Geom_Curve)& aC1, - const Standard_Real aCriteria, - GeomAPI_ProjectPointOnCurve& aProjector, - Standard_Real& aD, - Standard_Real& aT2) -{ - Standard_Integer iErr, aNbP2; - gp_Pnt aP1; - // - iErr=0; - aC1->D0(aT1, aP1); - // - aProjector.Perform(aP1); - aNbP2=aProjector.NbPoints(); - if (!aNbP2) { - iErr=1;// the point from aC1 can not be projected on aC2 - return iErr; - } - // - aD=aProjector.LowerDistance(); - aT2=aProjector.LowerDistanceParameter(); - if (aD>aCriteria) { - iErr=2;// the distance is too big - } - // - return iErr; -} -//modified by NIZNHY-PKV Fri Oct 12 09:34:12 2012t diff --git a/src/IntTools/IntTools_BeanBeanIntersector.lxx b/src/IntTools/IntTools_BeanBeanIntersector.lxx deleted file mode 100644 index 4db8bdf080..0000000000 --- a/src/IntTools/IntTools_BeanBeanIntersector.lxx +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and / or modify it -// under the terms of the GNU Lesser General Public version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -inline Standard_Boolean IntTools_BeanBeanIntersector::IsDone() const -{ - return myIsDone; -} - - diff --git a/src/IntTools/IntTools_EdgeEdge.cdl b/src/IntTools/IntTools_EdgeEdge.cdl index 0cca697f62..f29a59184b 100644 --- a/src/IntTools/IntTools_EdgeEdge.cdl +++ b/src/IntTools/IntTools_EdgeEdge.cdl @@ -1,6 +1,5 @@ --- Created on: 2000-10-26 --- Created by: Peter KURNEV --- Copyright (c) 2000-2014 OPEN CASCADE SAS +-- Created by: Eugeny MALTCHIKOV +-- Copyright (c) 2014 OPEN CASCADE SAS -- -- This file is part of Open CASCADE Technology software library. -- @@ -14,298 +13,221 @@ -- commercial license or contractual agreement. class EdgeEdge from IntTools + ---Purpose: + -- The class provides Edge/Edge intersection algorithm + -- based on the intersection between edges bounding boxes. - ---Purpose: The class provides Edge/Edge algorithm to determine - -- common parts between two edges in 3-d space. - -- Common parts can be : Vertices or Edges. - --- -uses - Edge from TopoDS, - Curve from BRepAdaptor, - SequenceOfRoots from IntTools, - SequenceOfRanges from IntTools, - CArray1OfReal from IntTools, - CommonPrt from IntTools, - SequenceOfCommonPrts from IntTools, - Range from IntTools ---raises - -is - Create - returns EdgeEdge from IntTools; - ---Purpose: - --- Empty constructor - --- - - SetEdge1 (me:out; - anEdge:Edge from TopoDS); - ---Purpose: - --- Sets the first edge - --- - - SetTolerance1 (me:out; - aTolEdge1:Real from Standard); - ---Purpose: - --- Sets the value of tolerance pipe for the first edge - --- +uses + Real from Standard, + Box from Bnd, + Range from IntTools, + Edge from TopoDS, + Curve from Geom, + Curve from BRepAdaptor, + ShapeEnum from TopAbs, + SequenceOfRanges from IntTools, + SequenceOfCommonPrts from IntTools - SetEdge2 (me:out; - anEdge:Edge from TopoDS); - ---Purpose: - --- Sets the second edge - --- +is + + Create + returns EdgeEdge from IntTools; + ---C++: alias "~IntTools_EdgeEdge();" + ---C++: inline + ---Purpose: + -- Empty contructor - SetTolerance2 (me:out; - aTolEdge2:Real from Standard); - ---Purpose: - --- Sets the value of tolerance pipe for the first edge - --- - - SetDiscretize (me:out; - aDiscret:Integer from Standard); - ---Purpose: - --- Sets the number of division for the shortest - --- edge among the two. The deflection is not taken - --- into account - --- - - SetDeflection (me:out; - aDeflection:Real from Standard); - ---Purpose: - --- Sets the value of maximum reative deflection between - --- the two nearest points on a curve. - --- - - SetEpsilonT (me:out; - anEpsT:Real from Standard); - ---Purpose: - --- Sets the criteria of equality of two arguments, - --- i.e. |t2-t1| +#include -#include +#include -#include - -#include -#include -#include #include -#include +#include #include -#include -#include -#include +#include -#include +#include +#include #include -#include -#include -#include - -#include #include +#include + +#include +#include -#include -#include -#include -#include -#include #include -#include +#include +static + Standard_Boolean BndCommon(const Bnd_Box& theB1, + const Bnd_Box& theB2, + Bnd_Box& theBOut); +static + void BndBuildBox(const BRepAdaptor_Curve& theBAC, + const Standard_Real aT1, + const Standard_Real aT2, + const Standard_Real theTol, + Bnd_Box& theBox); +static + void SplitRangeOnSegments(const Standard_Real aT1, + const Standard_Real aT2, + const Standard_Real theResolution, + const Standard_Integer theNbSeg, + IntTools_SequenceOfRanges& theSegments); +static + void SplitRangeOnTwo(const Standard_Real aT1, + const Standard_Real aT2, + IntTools_SequenceOfRanges& theSegments); +static + Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& theC1, + const Standard_Real theCriteria, + GeomAPI_ProjectPointOnCurve& theProjector, + Standard_Real& aD, + Standard_Real& aT2, + const Standard_Integer iC = 1); +static + Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& theC1, + const Standard_Real theCriteria, + GeomAPI_ProjectPointOnCurve& theProjector, + Standard_Real& aD, + Standard_Real& aT2, + Standard_Real& aDmax, + Standard_Real& aT1max, + Standard_Real& aT2max, + const Standard_Integer iC = 1); +static + Standard_Integer FindDistPC(const Standard_Real aT1A, + const Standard_Real aT1B, + const Handle(Geom_Curve)& theC1, + const Standard_Real theCriteria, + const Standard_Real theEps, + GeomAPI_ProjectPointOnCurve& theProjector, + Standard_Real& aDmax, + Standard_Real& aT1max, + Standard_Real& aT2max, + const Standard_Boolean bMaxDist = Standard_True); +static + Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType); -//======================================================================= -//function : IntTools_EdgeEdge::IntTools_EdgeEdge -//purpose : -//======================================================================= -IntTools_EdgeEdge::IntTools_EdgeEdge() -{ - myTol1=1.e-7; - myTol2=1.e-7; - myDiscret=30; - myEpsT=1e-12; - myEpsNull=1e-12; - myDeflection=0.01; - myIsDone=Standard_False; - myErrorStatus=1; - myOrder=Standard_False; - - myPar1=0.; - myParallel=Standard_False; -} - -//======================================================================= -//function : SetEdge1 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& anEdge) -{ - myEdge1=anEdge; -} -//======================================================================= -//function : SetEdge2 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& anEdge) -{ - myEdge2=anEdge; -} - -//======================================================================= -//function : SetTolerance1 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetTolerance1(const Standard_Real aTol) -{ - myTol1=aTol; -} -//======================================================================= -//function : SetTolerance2 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetTolerance2(const Standard_Real aTol) -{ - myTol2=aTol; -} - -//======================================================================= -//function : SetDiscretize -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetDiscretize(const Standard_Integer aDiscret) -{ - myDiscret=aDiscret; -} -//======================================================================= -//function : SetDeflection -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetDeflection(const Standard_Real aDefl) -{ - myDeflection=aDefl; -} -//======================================================================= -//function : SetEpsilonT -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetEpsilonT(const Standard_Real anEpsT) -{ - myEpsT=anEpsT; -} -//======================================================================= -//function : SetEpsilonNull -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetEpsilonNull(const Standard_Real anEpsNull) -{ - myEpsNull=anEpsNull; -} - -//======================================================================= -//function : SetRange1 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetRange1(const Standard_Real aFirst, - const Standard_Real aLast) -{ - myRange1.SetFirst (aFirst); - myRange1.SetLast (aLast); -} -//======================================================================= -//function : SetRange2 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetRange2(const Standard_Real aFirst, - const Standard_Real aLast) -{ - myRange2.SetFirst (aFirst); - myRange2.SetLast (aLast); -} - -//======================================================================= -//function : SetRange1 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetRange1(const IntTools_Range& aRange) -{ - myRange1.SetFirst (aRange.First()); - myRange1.SetLast (aRange.Last()); -} -//======================================================================= -//function : SetRange2 -//purpose : -//======================================================================= - void IntTools_EdgeEdge::SetRange2(const IntTools_Range& aRange) -{ - myRange2.SetFirst (aRange.First()); - myRange2.SetLast (aRange.Last()); -} - -//======================================================================= -//function : Order -//purpose : -//======================================================================= - Standard_Boolean IntTools_EdgeEdge::Order()const -{ - return myOrder; -} -//======================================================================= -//function : IsDone -//purpose : -//======================================================================= - Standard_Boolean IntTools_EdgeEdge::IsDone()const -{ - return myIsDone; -} -//======================================================================= -//function : ErrorStatus -//purpose : -//======================================================================= - Standard_Integer IntTools_EdgeEdge::ErrorStatus()const -{ - return myErrorStatus; -} - -//======================================================================= -//function : CommonParts -//purpose : -//======================================================================= - const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const -{ - return mySeqOfCommonPrts; -} -//======================================================================= -//function : Range1 -//purpose : -//======================================================================= - const IntTools_Range& IntTools_EdgeEdge::Range1() const -{ - return myRange1; -} -//======================================================================= -//function : Range2 -//purpose : -//======================================================================= - const IntTools_Range& IntTools_EdgeEdge::Range2() const -{ - return myRange2; -} -//======================================================================= -//function : Perform -//purpose : -//======================================================================= - void IntTools_EdgeEdge::Perform() -{ - Standard_Boolean bIsSameCurves; - Standard_Integer i, pri, aNbCommonPrts, aNbRange; - Standard_Real aT1, aT2, aPC; - IntTools_CommonPrt aCommonPrt; - GeomAbs_CurveType aCTFrom, aCTTo; - // - myIsDone=Standard_False; - myErrorStatus=0; - // - CheckData(); - if (myErrorStatus) - return; - // - Prepare(); - - if (myErrorStatus) { - return; - } - // - aCTFrom = myCFrom.GetType(); - aCTTo = myCTo.GetType(); - // - if(aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Line) { - ComputeLineLine(); - if (myOrder) { - TopoDS_Edge aTmp; - aTmp=myEdge1; - myEdge1=myEdge2; - myEdge2=aTmp; - } - return; - } - // - bIsSameCurves=IsSameCurves(); - if (bIsSameCurves) { - aCommonPrt.SetType(TopAbs_EDGE); - aCommonPrt.SetRange1 (myTminFrom, myTmaxFrom); - aCommonPrt.AppendRange2 (myTminTo, myTmaxTo); - mySeqOfCommonPrts.Append(aCommonPrt); - myIsDone=Standard_True; - return; - } - // - IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo); - anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom); - anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo); - // - anIntersector.Perform(); - if(!anIntersector.IsDone()) { - myIsDone = Standard_False; - return; - } - // - aPC=Precision::PConfusion(); - aCommonPrt.SetEdge1(myCFrom.Edge()); - aCommonPrt.SetEdge2(myCTo.Edge()); - // - const IntTools_SequenceOfRanges& aSR=anIntersector.Result(); - aNbRange=aSR.Length(); - for(i=1; i <=aNbRange; ++i) { - const IntTools_Range& aRange =aSR.Value(i); - aT1=aRange.First(); - aT2=aRange.Last(); - // - if(IsProjectable(IntTools_Tools::IntermediatePoint(aT1, aT2))) { - aCommonPrt.SetRange1(aT1, aT2); - // - if(((aT1 - myTminFrom)D0(t, aPFrom); - - Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (myCTo.Edge(), f, l); - aProjector.Init(aCurveTo, myTminTo, myTmaxTo); - aProjector.Perform(aPFrom); - aNbProj=aProjector.NbPoints(); - // - if (myCTo.GetType()==GeomAbs_Circle) { - gp_Circ aCirc=myCTo.Circle(); - const gp_Pnt& aCenter=aCirc.Location(); - if (aCenter.SquareDistance(aPFrom) < 1.e-7) { - aNbProj=1; - } - } - return aNbProj; -} - -//======================================================================= -//function : DistanceFunction -//purpose : -//======================================================================= - Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const -{ - Standard_Real aD, f, l; - GeomAPI_ProjectPointOnCurve aProjector; - gp_Pnt aPFrom; //ZZ , aPTo; - - const TopoDS_Edge& aEFrom=myCFrom.Edge(); - const TopoDS_Edge& aETo =myCTo.Edge(); - - Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l); - aCurveFrom->D0 (t, aPFrom); - Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (aETo, f, l); - - if (myCTo.GetType()==GeomAbs_Circle) { - gp_Circ aCirc=myCTo.Circle(); - const gp_Pnt& aCenter=aCirc.Location(); - const gp_Ax1& anAx1 =aCirc.Axis(); - const gp_Dir& aDir =anAx1.Direction(); - gp_Lin aLin(aCenter, aDir); - Standard_Real dPFromLin=aLin.Distance(aPFrom); - if (dPFromLin < 1.e-7) { - gp_Pnt anAnyPTo; - aCurveTo->D0 (myTminTo, anAnyPTo); - aD=aPFrom.Distance(anAnyPTo); - - aD=aD-myCriteria; - return aD; - } - } - - aProjector.Init(aCurveTo, myTminTo, myTmaxTo); - aProjector.Perform(aPFrom); - // - Standard_Integer j, aNbPoints; - // - aNbPoints =aProjector.NbPoints(); - if (!aNbPoints) { - for (j=0; j<=1; j++) { - Standard_Real tt; - tt=t+myEpsT; - if (j) { - tt=t-myEpsT; - } - - aCurveFrom->D0 (tt, aPFrom); - aProjector.Init(aCurveTo, myTminTo, myTmaxTo); - aProjector.Perform(aPFrom); - aNbPoints=aProjector.NbPoints(); - if (aNbPoints) { - break; - } - } - } - - - if (!aNbPoints) { - // Can't find projection. - myErrorStatus=11; - aD=100.; - return aD; - } - - aD=aProjector.LowerDistance(); - // - aD=aD-myCriteria; - return aD; -} - -//======================================================================= -//function : DerivativeFunction -//purpose : -//======================================================================= - Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2) -{ - Standard_Real t1, t3, aD1, aD2, aD3; - Standard_Real dt=1.e-7; - t1=t2-dt; - aD1=DistanceFunction(t1); - t3=t2+dt; - aD3=DistanceFunction(t3); - - aD2=.5*(aD3-aD1)/dt; - return aD2; -} - - -//======================================================================= -//function : FindSimpleRoot -//purpose : [private] -//======================================================================= - Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP, - const Standard_Real tA, - const Standard_Real tB, - const Standard_Real fA) -{ - Standard_Real r, a, b, y, x0, s; - - a=tA; b=tB; r=fA; - - Standard_Integer step = 1, stepcheck = 1000, steplimit = 100000; - Standard_Real value = (IP==1) ? DistanceFunction(0.5*(a+b)) : DerivativeFunction(0.5*(a+b)); - - for(;;) { - x0=.5*(a+b); - - if (IP==1) - y=DistanceFunction(x0); - else - y=DerivativeFunction(x0); - - Standard_Real aMaxAB100 = 100.*Max(a, b); - Standard_Real anEps = Epsilon(aMaxAB100); - Standard_Real anEpsT = Max(anEps, myEpsT); -// if (fabs(b-a) < myEpsT || y==0.) { - if (fabs(b-a) < anEpsT || y==0.) { - return x0; - } - - if( step == stepcheck ) { - if( Abs(value - y) <= 1.e-9 ) { - return x0; - } - else { - value = y; - step = 1; - } - } - - if( step == steplimit ) { - return x0; - } - - s=y*r; - - if (s<0.) { - b=x0; - continue; - } - - if (s>0.) { - a=x0; r=y; - } - - step++; - - } -} - -//======================================================================= -//function : FindRangeOnCurve2 -//purpose : -//======================================================================= -Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt& aCommonPrt) -{ - Standard_Integer pri; - // - pri=0; - if (aCommonPrt.AllNullFlag()) { - aCommonPrt.SetType(TopAbs_EDGE); - aCommonPrt.AppendRange2 (myTminTo, myTmaxTo); - return pri; - } - // - Standard_Real ttmp, f, l, af1, al1, am1, af2, al2, am2; - gp_Pnt aPf1, aPl1, aPm1, aPf2, aPl2, aPm2; - GeomAPI_ProjectPointOnCurve aProjector; - - aCommonPrt.Range1(af1, al1); - am1=.5*(af1+al1); - - const TopoDS_Edge& anEdgeTo=myCTo.Edge(); - Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f, l); - - const TopoDS_Edge& anEdgeFrom=myCFrom.Edge(); - Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l); - // - // af2, aPf2 - aCurveFrom->D0 (af1, aPf1); - pri=GetParameterOnCurve2 (af1, af2); - if (pri) { - return 1; - } - aCurveTo->D0(af2, aPf2); - // - // al2, aPl2 - aCurveFrom->D0 (al1, aPl1); - pri=GetParameterOnCurve2 (al1, al2); - if (pri) { - return 1; - } - aCurveTo->D0(al2, aPl2); - // - // am2, aPm2 - aCurveFrom->D0 (am1, aPm1); - pri=GetParameterOnCurve2 (am1, am2); - if (pri) { - return 1; - } - aCurveTo->D0(am2, aPm2); - // - // Reverse C2 points if it is necessary - Standard_Boolean reverse = (af2 > al2); - - if (reverse) { - ttmp=af2; - af2=al2; - al2=ttmp; - gp_Pnt aPTmp; - aPTmp=aPf2; - aPf2=aPl2; - aPl2=aPTmp; - } - - if((Abs(af2 - myTminTo) < Precision::PConfusion()) && - (Abs(al2 - myTmaxTo) < Precision::PConfusion())) { - aCommonPrt.SetAllNullFlag(Standard_True); - } - // - // - Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2; - Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1m1, dm1l1, df1l1; - Standard_Real tV1, tV2; - // - // parametric differences for C2 - Df2m2=fabs(af2-am2); - Dm2l2=fabs(am2-al2); - Df2l2=fabs(af2-al2); - // - // geometric distances for C2 - df2m2=aPf2.Distance(aPm2); - dm2l2=aPm2.Distance(aPl2); - df2l2=aPf2.Distance(aPl2); - - aVFlag1=(Df2m2 VERTEX - if ( aVFlag1 && aVFlag2) { - // V e r t e x - aCommonPrt.SetType(TopAbs_VERTEX); - pri=TreatVertexType(am1, am2, aCommonPrt); - - if (pri) { - tV2=.5*(af2+al2); - aCommonPrt.SetVertexParameter2(tV2); - aCommonPrt.AppendRange2 (af2, al2); - - tV1=.5*(af1+al1); - aCommonPrt.SetVertexParameter1(tV1); - aCommonPrt.SetRange1 (af1, al1); - } - return 0; - } - // - // geometric distances for C1 - df1m1=aPf1.Distance(aPm1); - dm1l1=aPm1.Distance(aPl1); - df1l1=aPf1.Distance(aPl1); - // - // if geometric distances between boundaries is less than myCriteria - // we have VERTEX - aGeomFlag1=(df1l1 < myCriteria); - aGeomFlag2=(df2l2 < myCriteria); - if (aGeomFlag1 && aGeomFlag2) { - aCommonPrt.SetType(TopAbs_VERTEX); - - tV2=.5*(af2+al2); - aCommonPrt.SetVertexParameter2(tV2); - aCommonPrt.AppendRange2 (af2, al2); - - tV1=.5*(af1+al1); - aCommonPrt.SetVertexParameter1(tV1); - aCommonPrt.SetRange1 (af1, al1); - return 0; - } - // - // ??? - if (Df2l2 < myEpsT && !aVFlag1) { - if (aPf1.Distance(aPl1) < myCriteria && aPf2.Distance(aPl2) < myCriteria) { - af1=myTminTo; - al2=myTmaxTo; - aCommonPrt.AppendRange2 (af1, al2); - aCommonPrt.SetType(TopAbs_EDGE); - return 0; - } - } - // - aProjector.Init(aCurveFrom, myTminFrom, myTmaxFrom); - aProjector.Perform(aPm2); - Standard_Integer aNbPoints=aProjector.NbPoints(); - if (aNbPoints) { - Standard_Real aDD=aProjector.LowerDistance(); - if (aDD > myCriteria) { - // Passed through 0 - aCommonPrt.SetType(TopAbs_EDGE); - aCommonPrt.AppendRange2 (myTminTo, af2); - aCommonPrt.AppendRange2 (al2, myTmaxTo); - return 0; - } - } - else { - // Passed through 0 - aCommonPrt.SetType(TopAbs_EDGE); - aCommonPrt.AppendRange2 (myTminTo, af2); - aCommonPrt.AppendRange2 (al2, myTmaxTo); - return 0; - } - - IsIntersection (af1, al1); - if (!myParallel && !aCommonPrt.AllNullFlag()) { - Standard_Real aPar2; - GetParameterOnCurve2 (myPar1, aPar2); - aCommonPrt.SetType(TopAbs_VERTEX); - - Standard_Boolean IsmyPar1 = Standard_True; - - if(Abs(af1-myTminFrom) < Precision::PConfusion()) { - IsmyPar1 = Standard_False; - aCommonPrt.SetVertexParameter1(af1); - if(reverse) - aCommonPrt.SetVertexParameter2(al2); - else - aCommonPrt.SetVertexParameter2(af2); - } - - if(Abs(al1-myTmaxFrom) < Precision::PConfusion()) { - IsmyPar1 = Standard_False; - aCommonPrt.SetVertexParameter1(al1); - - if(reverse) - aCommonPrt.SetVertexParameter2(af2); - else - aCommonPrt.SetVertexParameter2(al2); - } - - if(Abs(af2-myTminTo) < Precision::PConfusion()) { - IsmyPar1 = Standard_False; - aCommonPrt.SetVertexParameter2(af2); - - if(reverse) - aCommonPrt.SetVertexParameter1(al1); - else - aCommonPrt.SetVertexParameter1(af1); - } - - if(Abs(al2-myTmaxTo) < Precision::PConfusion()) { - IsmyPar1 = Standard_False; - aCommonPrt.SetVertexParameter2(al2); - - if(reverse) - aCommonPrt.SetVertexParameter1(af1); - else - aCommonPrt.SetVertexParameter1(al1); - } - // aCommonPrt.SetVertexParameter1(myPar1); - // aCommonPrt.SetRange1 (af1, al1); - - // aCommonPrt.SetVertexParameter2(aPar2); - if(IsmyPar1) { - aCommonPrt.SetVertexParameter1(myPar1); - aCommonPrt.SetRange1 (af1, al1); - - aCommonPrt.SetVertexParameter2(aPar2); - } - aCommonPrt.AppendRange2 (af2, al2); - return 0; - } - - - - aCommonPrt.SetType(TopAbs_EDGE); - aCommonPrt.AppendRange2 (af2, al2); - return 0; -} - -//======================================================================= -//function : IsIntersection -//purpose : -//======================================================================= - void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta, - const Standard_Real tb) -{ - Standard_Integer i, aNb, pri; - Standard_Real t, f; - GeomAbs_CurveType aCT1, aCT2; - IntTools_CArray1OfReal anArgs, aFunc; - // - aCT1=myCFrom.GetType(); - aCT2=myCTo.GetType(); - if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) { - const Handle(Geom_Curve)& Curve1=BRep_Tool::Curve (myCFrom.Edge(), t, f); - const Handle(Geom_Curve)& Curve2=BRep_Tool::Curve (myCTo.Edge() , t, f); - - GeomAdaptor_Curve TheCurve1 (Curve1); - GeomAdaptor_Curve TheCurve2 (Curve2); - Extrema_ExtCC anExtrema (TheCurve1, TheCurve2); - - if(anExtrema.IsDone() && anExtrema.IsParallel()) { - myParallel = Standard_True; - return; - } - } - // - if (aCT1==GeomAbs_Circle && aCT2==GeomAbs_Circle) { - Standard_Boolean bIsDone, bIsParallel; - Standard_Integer aNbExt; - Standard_Real aD2, aCriteria2, aT1; - gp_Circ aCirc1, aCirc2; - Extrema_POnCurv aPC1, aPC2; + BRepAdaptor_Curve tmpC = myCurve1; + myCurve1 = myCurve2; + myCurve2 = tmpC; // - aCirc1=myCFrom.Circle(); - aCirc2=myCTo.Circle(); + IntTools_Range tmpR = myRange1; + myRange1 = myRange2; + myRange2 = tmpR; // - Extrema_ExtElC aExtElC(aCirc1, aCirc2); - // - bIsDone=aExtElC.IsDone(); - if (bIsDone) { - bIsParallel=aExtElC.IsParallel(); - if (!bIsParallel) { - aCriteria2=myCriteria*myCriteria; - aNbExt=aExtElC.NbExt(); - for (i=1; i<=aNbExt; ++i) { - aD2=aExtElC.SquareDistance(i); - if (aD2ta && aT1D0 (aT1, aP1); - GeomAPI_ProjectPointOnCurve aProjector; - aProjector.Init(aCurveTo, myTminTo, myTmaxTo); - aProjector.Perform(aP1); - aNbPoints=aProjector.NbPoints(); - found=1; - if (!aNbPoints) { - found=0; - for (j=0; j<=1; j++) { - Standard_Real tt; - tt=aT1+myEpsT; - if (j) { - tt=aT1-myEpsT; - } - aCurveFrom->D0 (tt, aP1); - aProjector.Init(aCurveTo, myTminTo, myTmaxTo); - aProjector.Perform(aP1); - aNbPoints=aProjector.NbPoints(); - if (aNbPoints) { - found=1; - break; - } - } - } - - if (!found) { - aCurveFrom->D0 (aT1, aP1); - Standard_Real aDistance = RealLast(); - - for(Standard_Integer pIt=0; pIt < 2; pIt++) { - Standard_Real adist = aDistance; - if(pIt) - adist = aP1.Distance(aCurveTo->Value(myTminTo)); - else - adist = aP1.Distance(aCurveTo->Value(myTmaxTo)); - - if(adist < myCriteria) { - found = Standard_True; - - if(adist < aDistance) { - aT2 = (pIt) ? myTminTo : myTmaxTo; - aDistance = adist; - } - } - } - if(found) - return 0; - } - - if (!found) { - aT2=0.; - return 1; - } - - for (j=1; j<=aNbPoints; j++) { - aT2=aProjector.Parameter(j); - f=aProjector.Distance(j); - } - - aT2=aProjector.LowerDistanceParameter(); - if (aT2 < myTminTo) { - aT2=myTminTo; - } - if (aT2 > myTmaxTo) { - aT2=myTmaxTo; - } - return 0; -} - -//======================================================================= -//function : TreatVertexType -//purpose : -//======================================================================= - Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1, - const Standard_Real am2, - IntTools_CommonPrt& aCommonPrt) -{ - Standard_Real f1, l1, f2, l2, Alfa , aPeriod; - gp_Pnt aPm1, aPm2, aP; - gp_Vec aVm1, aVm2; - - - const TopoDS_Edge& anEdgeFrom=myCFrom.Edge(); - Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f1, l1); - aCurveFrom->D1 (am1, aPm1, aVm1); - aVm1.Normalize(); - - const TopoDS_Edge& anEdgeTo=myCTo.Edge(); - Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f2, l2); - aCurveTo->D1 (am2, aPm2, aVm2); - aVm2.Normalize(); - - Alfa=aVm1.Angle(aVm2); - - if (Alfa < Precision::Angular()) { - return 1; - } - - Standard_Real sinAlfa, cosAlfa, dd, tf1, tl1, tf2, tl2, aL1, aL2; - Standard_Integer ip; - - sinAlfa=sin(Alfa); - cosAlfa=cos(Alfa); - - dd=aPm1.Distance(aPm2); - // aL2 - if (dd>myCriteria) { - return 1; - } - aL2=(myTolTo*cosAlfa+myTolFrom)/sinAlfa; - // left point - aP.SetXYZ(aPm2.XYZ()-aVm2.XYZ()*aL2); - ip=IntTools::Parameter (aP, aCurveTo, tf2); - if (ip){ - return ip; - } - // - if(aP.Distance(aCurveTo->Value(tf2)) > myTolTo) - return 1; - - // right point - aP.SetXYZ(aPm2.XYZ()+aVm2.XYZ()*aL2); - ip=IntTools::Parameter (aP, aCurveTo, tl2); - if (ip){ - return ip; - } - - if(aP.Distance(aCurveTo->Value(tl2)) > myTolTo) - return 1; - - // aL1 - if (dd>myCriteria) { - return 1; - } - - aL1=(myTolFrom*cosAlfa+myTolTo)/sinAlfa; - // left point - aP.SetXYZ(aPm1.XYZ()-aVm1.XYZ()*aL1); - ip=IntTools::Parameter (aP, aCurveFrom, tf1); - if (ip){ - return ip; - } - - if(aP.Distance(aCurveFrom->Value(tf1)) > myTolFrom) - return 1; - - // right point - aP.SetXYZ(aPm1.XYZ()+aVm1.XYZ()*aL1); - ip=IntTools::Parameter (aP, aCurveFrom, tl1); - if (ip){ - return ip; - } - - if(aP.Distance(aCurveFrom->Value(tl1)) > myTolFrom) - return 1; - - // - if (aCurveFrom->IsPeriodic()) { - aPeriod=aCurveFrom->Period(); - if (tf1l1) { - tf1=tf1+aPeriod; - } - if (tl1l1) { - tl1=tl1+aPeriod; - } - } - // - // First range - aCommonPrt.SetRange1 (tf1, tl1); - aCommonPrt.SetVertexParameter1((tf1 + tl1) * 0.5); - // - // Second Range(s) - if (aCurveTo->IsPeriodic() && tf2 > tl2) { - // aCurveTo is periodic curve and we pass through 0. - - aPeriod=aCurveTo->Period(); - aCommonPrt.AppendRange2 (tf2, aPeriod); - aCommonPrt.AppendRange2 (0., tl2); - aCommonPrt.SetVertexParameter2((tf2 + aPeriod) * 0.5); - } - else { - // usual cases - return 1; // + bThin = (aTB22 - aTB21) < myRes2; + if (bThin) { + bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, aB1, aTB11, aTB12); + if (bOut) { + break; + } + } else { + BndBuildBox(myCurve2, aTB21, aTB22, myTol2, aB2); + BndCommon(aB1, aB2, aB2); + // + bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, aB2, aTB11, aTB12); + if (bOut) { + break; + } + // + bThin = ((aTB12 - aTB11) < myRes1) || + (aB2.IsXThin(aTol) && aB2.IsYThin(aTol) && aB2.IsZThin(aTol)); + // + if (!bThin) { + aSmallStep1 = (aT12 - aT11) / 250.; + aSmallStep2 = (aT22 - aT21) / 250.; + // + if (aSmallStep1 < myRes1) { + aSmallStep1 = myRes1; + } + if (aSmallStep2 < myRes2) { + aSmallStep2 = myRes2; + } + // + if (((aTB11 - aT11) < aSmallStep1) && ((aT12 - aTB12) < aSmallStep1) && + ((aTB21 - aT21) < aSmallStep2) && ((aT22 - aTB22) < aSmallStep2)) { + bStop = Standard_True; + } else { + BndBuildBox(myCurve1, aTB11, aTB12, myTol1, aB1); + bOut = !BndCommon(aB1, aB2, aB1); + if (bOut) { + break; + } + } + } + } + // + aT11 = aTB11; + aT12 = aTB12; + aT21 = aTB21; + aT22 = aTB22; + } while (!bThin && !bStop); + // + if (bOut) { + //no intersection; + return; + } + // + if (!bThin) { + //check curves for coincidence on the ranges + iCom = CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1); + if (!iCom) { + bThin = Standard_True; + } + } + // + if (bThin) { + if (iCom != 0) { + //check intermediate points + Standard_Real aT1, aT2, aDist; + gp_Pnt aP1, aP2; + // + aT1 = IntTools_Tools::IntermediatePoint(aT11, aT12); + aT2 = IntTools_Tools::IntermediatePoint(aT21, aT22); + // + aP1 = myGeom1->Value(aT1); + aP2 = myGeom2->Value(aT2); + // + aDist = aP1.Distance(aP2); + if (aDist > myTol) { + return; + } + } + //add common part + IntTools_Range aR1(aT11, aT12), aR2(aT21, aT22); + // + theRanges1.Append(aR1); + theRanges2.Append(aR2); + return; + } + // + if (!IsIntersection(aT11, aT12, aT21, aT22)) { + return; + } + // + //split ranges on segments and repeat + Standard_Integer i, aNb1; + IntTools_SequenceOfRanges aSegments1; + // + IntTools_Range aR2(aT21, aT22); + SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1); + aNb1 = aSegments1.Length(); + for (i = 1; i <= aNb1; ++i) { + const IntTools_Range& aR1 = aSegments1(i); + FindSolutions(aR1, aR2, theRanges1, theRanges2); } - return 0; } - - -// -// -// Print block - -// myErrorStatus -// 1 - the method Perform() is not invoked -// 2,3,4,5 -the method CheckData() fails -// 6 - PrepareArgs() problems -// 7 - No Projectable ranges -// 8,9 - PrepareArgs() problems occured inside projectable Ranges -// 10 - problems in FindRange2 -// 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays: -// possible reason is that no points on myCFrom that could be projected -// on myCTo -// - //======================================================================= -//function : CheckTouchVertex -//purpose : line/Circle refinement -//======================================================================= - Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP, - Standard_Real& aTx1, - Standard_Real& aTx2) const -{ - Standard_Boolean bFlag; - Standard_Real aTFR1, aTLR1, aTFR2, aTLR2; - Standard_Real aTL1, aTL2, aTC1, aTC2; - Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx; - GeomAbs_CurveType aTFrom, aTTo; - gp_Circ aCirc; - gp_Lin aLine; - gp_Pnt aPC, aPLx, aPCx; - // - bFlag=Standard_False; - aCP.Range1(aTFR1, aTLR1); - (aCP.Ranges2())(1).Range(aTFR2, aTLR2); - // - aTFrom=myCFrom.GetType(); - aTTo =myCTo.GetType(); - // - aTL1=aTFR1; - aTL2=aTLR1; - aTC1=aTFR2; - aTC2=aTLR2; - if (aTFrom==GeomAbs_Circle) { - aCirc=myCFrom.Circle(); - aLine=myCTo.Line(); - aTL1=aTFR2; - aTL2=aTLR2; - aTC1=aTFR1; - aTC2=aTLR1; - } - else { - aCirc=myCTo.Circle(); - aLine=myCFrom.Line(); - } - // - aPC=aCirc.Location(); - aRC=aCirc.Radius(); - // - aDLC=aLine.Distance(aPC); - if (fabs(aDLC-aRC)>myCriteria) { - return bFlag; - } - // - aTLx=ElCLib::Parameter(aLine, aPC); - aPLx=ElCLib::Value(aTLx, aLine); - aTCx=ElCLib::Parameter(aCirc, aPLx); - aPCx=ElCLib::Value(aTCx, aCirc); - aD2=aPLx.SquareDistance(aPCx); - aC2=myCriteria*myCriteria; - if (aD2>aC2) { - return bFlag; - } - // - if (aTLxaTL2) { - return bFlag; - } - if (aTCxaTC2) { - return bFlag; - } - // - aTx1=aTLx; - aTx2=aTCx; - if (aTFrom==GeomAbs_Circle) { - aTx1=aTCx; - aTx2=aTLx; - } - // - return !bFlag; -} -//======================================================================= -//function : CheckTouch +//function : FindParameters //purpose : //======================================================================= - Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP, - Standard_Real& aTx1, - Standard_Real& aTx2) +Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC, + const Standard_Real aT1, + const Standard_Real aT2, + const Standard_Real theRes, + const Bnd_Box& theCBox, + Standard_Real& aTB1, + Standard_Real& aTB2) { - Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al,aDist2, aMinDist2; - Standard_Boolean theflag=Standard_False; - Standard_Integer aNbExt, i, iLower; - - aCP.Range1(aTF1, aTL1); - (aCP.Ranges2())(1).Range(aTF2, aTL2); - - Tol = Precision::PConfusion(); - - const Handle(Geom_Curve)& Curve1 =BRep_Tool::Curve (myCFrom.Edge(), af, al); - const Handle(Geom_Curve)& Curve2 =BRep_Tool::Curve (myCTo.Edge() , af, al); - - GeomAdaptor_Curve TheCurve1 (Curve1, aTF1, aTL1); - GeomAdaptor_Curve TheCurve2 (Curve2, aTF2, aTL2); - - { - Standard_Real aTol1 = TheCurve1.Resolution(myCriteria); - aTol1 = (Tol < aTol1) ? Tol : aTol1; - - Standard_Boolean isfirst = (Abs(myTminFrom - aTF1) < aTol1); - Standard_Boolean islast = (Abs(myTmaxFrom - aTL1) < aTol1); - - if(!isfirst || !islast) { - if(isfirst) { - aTx1 = aTF1; - GeomAPI_ProjectPointOnCurve aProjector; - aProjector.Init(Curve2, aTF2, aTL2); - aProjector.Perform(Curve1->Value(aTx1)); - // - if(aProjector.NbPoints() > 0) - aTx2 = aProjector.LowerDistanceParameter(); - else { - if(Curve1->Value(aTx1).Distance(Curve2->Value(aTF2)) < myCriteria) - aTx2 = aTF2; - else - aTx2 = aTL2; - } - return !theflag; + Standard_Boolean bRet; + Standard_Integer aC, i, k; + Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn, aPTol, aTol, + aDist, aDistP; + gp_Pnt aP; + Bnd_Box aCBx; + // + bRet = Standard_False; + aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.; + aDt = theRes; + aPTol = theRes * 0.001; + aTol = theBAC.Tolerance(); + aDistP = 0.; + aCBx = theCBox; + aCBx.Enlarge(aTol); + // + for (i = 0; i < 2; ++i) { + aTB = !i ? aT1 : aT2; + aT = !i ? aT2 : aTB1; + aC = !i ? 1 : -1; + bRet = Standard_False; + k = 0; + //looking for the point on the edge which is in the box; + while (aC*(aT-aTB) >= 0) { + aP = theBAC.Value(aTB); + Bnd_Box aBP; + aBP.Add(aP); + aDist = aBP.Distance(theCBox); + k = (fabs(aDist - aDistP) < Precision::PConfusion()) ? k+1 : 0; + if (aDist > aTol) { + aDt = theBAC.Resolution(aDist*Max(k, 1)); + aTB += aC*aDt; + } else { + bRet = Standard_True; + break; } - - if(islast) { - aTx1 = aTL1; - GeomAPI_ProjectPointOnCurve aProjector; - aProjector.Init(Curve2, aTF2, aTL2); - aProjector.Perform(Curve1->Value(aTx1)); - if(aProjector.NbPoints() > 0) - aTx2 = aProjector.LowerDistanceParameter(); - else { - if(Curve1->Value(aTx1).Distance(Curve2->Value(aTL2)) < myCriteria) - aTx2 = aTL2; - else - aTx2 = aTF2; - } - return !theflag; + aDistP = aDist; + } + // + if (!bRet) { + if (!i) { + //edge is out of the box; + return bRet; + } else { + bRet = !bRet; + aTB = aTB1; + aDt = aT2 - aTB1; } } - } - - Extrema_ExtCC anExtrema (TheCurve1, TheCurve2, aTF1-Tol, aTL1+Tol, aTF2-Tol, aTL2+Tol, Tol, Tol); - - if(!anExtrema.IsDone()) { - return theflag; - } - if (anExtrema.IsParallel()) { - return theflag; - } - - aNbExt=anExtrema.NbExt() ; - if (!aNbExt) { - return theflag; - } - - Standard_Boolean istouch = Standard_True; - Standard_Integer avalidindex = 0; - - iLower=1; - aMinDist2=1.e100; - for (i=1; i<=aNbExt; ++i) { - aDist2=anExtrema.SquareDistance(i); - if (aDist2 < aMinDist2) { - aMinDist2=aDist2; - iLower=i; - } - - if(aDist2 < myCriteria * myCriteria) { - if(avalidindex) { - Extrema_POnCurv aPOnC1, aPOnC2; - anExtrema.Points(i, aPOnC1, aPOnC2); - Standard_Real aPar1 = aPOnC1.Parameter(); - anExtrema.Points(avalidindex, aPOnC1, aPOnC2); - Standard_Real aPar2 = aPOnC1.Parameter(); - - if(Abs(aPar1 - aPar2) > Precision::PConfusion()) { - istouch = Standard_False; - } + // + aT = !i ? aT1 : aT2; + if (aTB != aT) { + //one point IN, one point OUT; looking for the bounding point; + aTIn = aTB; + aTOut = aTB - aC*aDt; + aDiff = aTIn - aTOut; + while (fabs(aDiff) > aPTol) { + aTB = aTOut + aDiff*aCf; + aP = theBAC.Value(aTB); + if (aCBx.IsOut(aP)) { + aTOut = aTB; + } else { + aTIn = aTB; + } + aDiff = aTIn - aTOut; } - avalidindex = i; + } + if (!i) { + aTB1 = aTB; + } else { + aTB2 = aTB; } } - - aDist2=anExtrema.SquareDistance(iLower); - if (aDist2 > myCriteria * myCriteria) { - return theflag; - } - - Extrema_POnCurv aPOnC1, aPOnC2; - anExtrema.Points(iLower, aPOnC1, aPOnC2); - - aTx1=aPOnC1.Parameter(); - aTx2=aPOnC2.Parameter(); - - if((myCFrom.GetType() == GeomAbs_Line && myCTo.GetType() == GeomAbs_Circle) || - (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line)) - { - Standard_Real aRadius; - GeomAbs_CurveType aTFrom, aTTo; - gp_Circ aCirc; - gp_Lin aLine; - gp_Pnt aPCenter, aPOnLine; - - aTFrom=myCFrom.GetType(); - aTTo =myCTo.GetType(); - - if (aTFrom==GeomAbs_Circle) { - aCirc=myCFrom.Circle(); - aLine=myCTo.Line(); - Curve2->D0(aTx2, aPOnLine); - } - - else { - aCirc=myCTo.Circle(); - aLine=myCFrom.Line(); - Curve1->D0(aTx1, aPOnLine); - } - - - aPCenter=aCirc.Location(); - aRadius =aCirc.Radius(); - - aDist2=aPOnLine.SquareDistance(aPCenter); - aDist2=fabs (sqrt(aDist2)-aRadius); - aDist2 *= aDist2; - if (aDist2 < Tol * Tol) { - return !theflag; - } - } - - GeomAPI_ProjectPointOnCurve aProjector; - Standard_Real aMidPar, aMidDist; - aMidPar = (aTF1 + aTL1) * 0.5; - aProjector.Init(Curve2, aTF2, aTL2); - aProjector.Perform(Curve1->Value(aMidPar)); - if(aProjector.NbPoints() > 0) { - aMidDist=aProjector.LowerDistance(); - if(aMidDist * aMidDist < aDist2 || !istouch) { - aTx1 = aMidPar; - aTx2 = aProjector.LowerDistanceParameter(); - } - } - - if (fabs (aTx1-aTF1) < Tol) { - return !theflag; - } - - if (fabs (aTx1-aTL1) < Tol) { - return !theflag; - } - - if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) { - return !theflag; - } - - return theflag; + return bRet; } //======================================================================= -//function : ComputeLineLine +//function : MergeSolutions //purpose : //======================================================================= - void IntTools_EdgeEdge::ComputeLineLine() +void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1, + const IntTools_SequenceOfRanges& theRanges2) +{ + IntTools_Range aRi1, aRi2, aRj1, aRj2; + Standard_Integer aNbCP, i, j; + TopAbs_ShapeEnum aType; + Standard_Real aTi11, aTi12, aTi21, aTi22, + aTj11, aTj12, aTj21, aTj22; + // + aNbCP = theRanges1.Length(); + aType = TopAbs_VERTEX; + // + for (i = 1; i <= aNbCP; ) { + aRi1 = theRanges1(i); + aRi2 = theRanges2(i); + // + aRi1.Range(aTi11, aTi12); + aRi2.Range(aTi21, aTi22); + // + for (j = i+1; j <= aNbCP; ++j) { + aRj1 = theRanges1(j); + aRj2 = theRanges2(j); + // + aRj1.Range(aTj11, aTj12); + aRj2.Range(aTj21, aTj22); + if (fabs(aTi12 - aTj11) < 10*myRes1 || + fabs(aTi22 - aTj21) < 10*myRes2) { + aTi11 = Min(aTi11, aTj11); + aTi12 = Max(aTi12, aTj12); + aTi21 = Min(aTi21, aTj21); + aTi22 = Max(aTi22, aTj22); + } else { + break; + } + } + i = j; + // + if (aTi11 == myRange1.First() && aTi12 == myRange1.Last() && + aTi21 == myRange2.First() && aTi22 == myRange2.Last()) { + aType = TopAbs_EDGE; + } + // + AddSolution(aTi11, aTi12, aTi21, aTi22, aType); + } +} + +//======================================================================= +//function : AddSolution +//purpose : +//======================================================================= +void IntTools_EdgeEdge::AddSolution(const Standard_Real aT11, + const Standard_Real aT12, + const Standard_Real aT21, + const Standard_Real aT22, + const TopAbs_ShapeEnum theType) +{ + IntTools_CommonPrt aCPart; + // + aCPart.SetType(theType); + if (!mySwap) { + aCPart.SetEdge1(myEdge1); + aCPart.SetEdge2(myEdge2); + aCPart.SetRange1(aT11, aT12); + aCPart.AppendRange2(aT21, aT22); + } else { + aCPart.SetEdge1(myEdge2); + aCPart.SetEdge2(myEdge1); + aCPart.SetRange1(aT21, aT22); + aCPart.AppendRange2(aT11, aT12); + } + // + if (theType == TopAbs_VERTEX) { + Standard_Real aT1, aT2; + // + FindBestSolution(aT11, aT12, aT21, aT22, aT1, aT2); + // + if (!mySwap) { + aCPart.SetVertexParameter1(aT1); + aCPart.SetVertexParameter2(aT2); + } else { + aCPart.SetVertexParameter1(aT2); + aCPart.SetVertexParameter2(aT1); + } + } + myCommonParts.Append(aCPart); +} + +//======================================================================= +//function : FindBestSolution +//purpose : +//======================================================================= +void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11, + const Standard_Real aT12, + const Standard_Real aT21, + const Standard_Real aT22, + Standard_Real& aT1, + Standard_Real& aT2) +{ + Standard_Real aD, aDMin, aDt, aT1x, aT2x, aT1p, aT2p, aMinStep, aTMax; + Standard_Integer i, aNbP, iErr; + GeomAPI_ProjectPointOnCurve aProj; + gp_Pnt aP; + // + aNbP = 10; + aT1 = IntTools_Tools::IntermediatePoint(aT11, aT12); + aT2 = IntTools_Tools::IntermediatePoint(aT21, aT22); + aDMin = 100.; + aD = 100.; + aDt = (aT12 - aT11) / aNbP; + aMinStep = 5.e-13; + aTMax = Max(fabs(aT11), fabs(aT12)); + if (aTMax > 999.) { + aMinStep = 5.e-16 * aTMax; + } + // + aProj.Init(myGeom2, aT21, aT22); + for (i = 0; i < aNbP; ++i) { + aT1x = aT11 + i*aDt; + aT2x = aT1x + aDt; + iErr = FindDistPC(aT1x, aT2x, myGeom1, 0., aMinStep, aProj, aD, aT1p, aT2p, Standard_False); + if (iErr != 1 && aD < aDMin) { + aT1 = aT1p; + aT2 = aT2p; + aDMin = aD; + if (aDMin == 0.) { + break; + } + } + } +} + +//======================================================================= +//function : ComputeLineLine +//purpose : +//======================================================================= +void IntTools_EdgeEdge::ComputeLineLine() { Standard_Boolean IsParallel, IsCoincide; - Standard_Real Tolang2, Tol2; - gp_Pnt P11, P12, P21, P22; - // - myIsDone = Standard_True; + Standard_Real aSin, aCos, aAng, aTol; + Standard_Real aT1, aT2, aT11, aT12, aT21, aT22; + gp_Pnt aP11, aP12; + gp_Lin aL1, aL2; + gp_Dir aD1, aD2; + IntTools_CommonPrt aCommonPrt; // IsParallel = Standard_False; IsCoincide = Standard_False; - Tolang2 = Precision::Angular(); - Tol2 = myCriteria*myCriteria; + aTol = myTol*myTol; + aL1 = myCurve1.Line(); + aL2 = myCurve2.Line(); + aD1 = aL1.Position().Direction(); + aD2 = aL2.Position().Direction(); + myRange1.Range(aT11, aT12); + myRange2.Range(aT21, aT22); // - gp_Lin C1 = myCFrom.Line(); - gp_Lin C2 = myCTo.Line(); - const gp_Dir& D1 = C1.Position().Direction(); - const gp_Dir& D2 = C2.Position().Direction(); - Standard_Real aCos = D1.Dot(D2); - Standard_Real Ang2; - - if(aCos >= 0. ) { - Ang2 = 2.*(1. - aCos); - } - else { - Ang2 = 2.*(1. + aCos); - } - - if(Ang2 <= Tolang2) { + aCommonPrt.SetEdge1(myEdge1); + aCommonPrt.SetEdge2(myEdge2); + // + aCos = aD1.Dot(aD2); + aAng = (aCos >= 0.) ? 2.*(1. - aCos) : 2.*(1. + aCos); + // + if(aAng <= Precision::Angular()) { IsParallel = Standard_True; - if(C2.SquareDistance(C1.Location()) <= Tol2) { + if(aL1.SquareDistance(aL2.Location()) <= aTol) { IsCoincide = Standard_True; - P11 = ElCLib::Value(myTminFrom, C1); - P12 = ElCLib::Value(myTmaxFrom, C1); + aP11 = ElCLib::Value(aT11, aL1); + aP12 = ElCLib::Value(aT12, aL1); } } else { - //Check coincidence of extremity points; - //Check only shortest line - P11 = ElCLib::Value(myTminFrom, C1); - P12 = ElCLib::Value(myTmaxFrom, C1); - if(C2.SquareDistance(P11) <= Tol2 && C2.SquareDistance(P12) <= Tol2) { + aP11 = ElCLib::Value(aT11, aL1); + aP12 = ElCLib::Value(aT12, aL1); + if(aL2.SquareDistance(aP11) <= aTol && aL2.SquareDistance(aP12) <= aTol) { IsCoincide = Standard_True; } } - - if(IsCoincide) { + // + if (IsCoincide) { Standard_Real t21, t22; - t21 = ElCLib::Parameter(C2, P11); - t22 = ElCLib::Parameter(C2, P12); - - if((t21 > myTmaxTo && t22 > myTmaxTo) || (t21 < myTminTo && t22 < myTminTo)) { + // + t21 = ElCLib::Parameter(aL2, aP11); + t22 = ElCLib::Parameter(aL2, aP12); + if((t21 > aT22 && t22 > aT22) || (t21 < aT21 && t22 < aT21)) { return; } - + // Standard_Real temp; if(t21 > t22) { temp = t21; t21 = t22; t22 = temp; } - - IntTools_CommonPrt aCommonPrt; - aCommonPrt.SetEdge1(myCFrom.Edge()); - aCommonPrt.SetEdge2(myCTo.Edge()); - if(t21 >= myTminTo) { - if(t22 <= myTmaxTo) { - aCommonPrt.SetRange1(myTminFrom, myTmaxFrom); - aCommonPrt.SetAllNullFlag(Standard_True); - aCommonPrt.AppendRange2(t21, t22); + // + if(t21 >= aT21) { + if(t22 <= aT22) { + aCommonPrt.SetRange1(aT11, aT12); + aCommonPrt.SetAllNullFlag(Standard_True); + aCommonPrt.AppendRange2(t21, t22); } else { - aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo)); - aCommonPrt.AppendRange2(t21, myTmaxTo); + aCommonPrt.SetRange1(aT11, aT12 - (t22 - aT22)); + aCommonPrt.AppendRange2(t21, aT22); } } else { - aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom); - aCommonPrt.AppendRange2(myTminTo, t22); + aCommonPrt.SetRange1(aT11 + (aT21 - t21), aT12); + aCommonPrt.AppendRange2(aT21, t22); } aCommonPrt.SetType(TopAbs_EDGE); - mySeqOfCommonPrts.Append(aCommonPrt); + myCommonParts.Append(aCommonPrt); return; - } - - if(IsParallel) { + // + if (IsParallel) { return; } // { TopoDS_Iterator aIt1, aIt2; - // aIt1.Initialize(myEdge1); for (; aIt1.More(); aIt1.Next()) { - const TopoDS_Shape& aV1=aIt1.Value(); + const TopoDS_Shape& aV1 = aIt1.Value(); aIt2.Initialize(myEdge2); for (; aIt2.More(); aIt2.Next()) { - const TopoDS_Shape& aV2=aIt2.Value(); - if (aV2.IsSame(aV1)) { - // the two straight lines have commpn vertex - return; - } + const TopoDS_Shape& aV2 = aIt2.Value(); + if (aV2.IsSame(aV1)) { + return; + } } } } // - Standard_Real aSin2 = 1. - aCos*aCos; - gp_Pnt O1 = C1.Location(); - gp_Pnt O2 = C2.Location(); - gp_Vec O1O2 (O1,O2); - Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ()); - U2 /= aSin2; - if(U2 < myTminTo || U2 > myTmaxTo) { - return; - } - - gp_Pnt P2(ElCLib::Value(U2,C2)); - Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1); - if(U1 < myTminFrom || U1 > myTmaxFrom) { - return; - } - - gp_Pnt P1(ElCLib::Value(U1,C1)); - Standard_Real d2 = P1.SquareDistance(P2); - - if(d2 > Tol2) { + aSin = 1. - aCos*aCos; + gp_Pnt O1 = aL1.Location(); + gp_Pnt O2 = aL2.Location(); + gp_Vec O1O2 (O1, O2); + // + aT2 = (aD1.XYZ()*(O1O2.Dot(aD1))-(O1O2.XYZ())).Dot(aD2.XYZ()); + aT2 /= aSin; + // + if(aT2 < aT21 || aT2 > aT22) { return; } // - IntTools_CommonPrt aCommonPrt; - aCommonPrt.SetEdge1(myCFrom.Edge()); - aCommonPrt.SetEdge2(myCTo.Edge()); - aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria); - aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria); + gp_Pnt aP2(ElCLib::Value(aT2, aL2)); + aT1 = (gp_Vec(O1, aP2)).Dot(aD1); + // + if(aT1 < aT11 || aT1 > aT12) { + return; + } + // + gp_Pnt aP1(ElCLib::Value(aT1, aL1)); + Standard_Real aDist = aP1.SquareDistance(aP2); + // + if (aDist > aTol) { + return; + } + // + aCommonPrt.SetRange1(aT1 - myTol, aT1 + myTol); + aCommonPrt.AppendRange2(aT2 - myTol, aT2 + myTol); aCommonPrt.SetType(TopAbs_VERTEX); - aCommonPrt.SetVertexParameter1(U1); - aCommonPrt.SetVertexParameter2(U2); - mySeqOfCommonPrts.Append(aCommonPrt); - + aCommonPrt.SetVertexParameter1(aT1); + aCommonPrt.SetVertexParameter2(aT2); + myCommonParts.Append(aCommonPrt); } + +//======================================================================= +//function : FindRoughRanges +//purpose : +//======================================================================= +Standard_Integer IntTools_EdgeEdge::FindRoughRanges(const IntTools_Range& theR1, + const IntTools_Range& theR2, + IntTools_SequenceOfRanges& theSegments1) +{ + Standard_Integer iRet, i, j, aNbi, aNbj, aNbSD; + Standard_Real aTi1, aTi2, aTj1, aTj2, aDi, aDj; + IntTools_SequenceOfRanges aSi, aSj, aNewSi, aNewSj; + BOPCol_MapOfInteger aMj; + BOPCol_ListIteratorOfListOfInteger aItLI; + Bnd_Box aBi, aBj; + BOPDS_BoxBndTreeSelector aSelector; + BOPDS_BoxBndTree aBBTree; + NCollection_UBTreeFiller aTreeFiller(aBBTree); + // + theR1.Range(aTi1, aTi2); + theR2.Range(aTj1, aTj2); + aDi = (aTi2 - aTi1) / 2.; + aDj = (aTj2 - aTj1) / 2.; + aNbi = 2; + aNbj = 2; + // + SplitRangeOnTwo(aTi1, aTi2, aSi); + SplitRangeOnTwo(aTj1, aTj2, aSj); + // + while (aDi > myRes1 || aDj > myRes2) { + aDi /= 2.; + aDj /= 2.; + // + aBBTree.Clear(); + aTreeFiller.Reset(); + for (j = 1; j <= aNbj; ++j) { + const IntTools_Range& aRj = aSj(j); + aRj.Range(aTj1, aTj2); + // + BndBuildBox(myCurve2, aTj1, aTj2, myTol2, aBj); + // + aTreeFiller.Add(j, aBj); + } + // + aTreeFiller.Fill(); + // + for (i = 1; i <= aNbi; ++i) { + const IntTools_Range& aRi = aSi(i); + aRi.Range(aTi1, aTi2); + // + BndBuildBox(myCurve1, aTi1, aTi2, myTol1, aBi); + // + aSelector.Clear(); + aSelector.SetBox(aBi); + // + aNbSD = aBBTree.Select(aSelector); + if (!aNbSD){ + continue; + } + // + SplitRangeOnTwo(aTi1, aTi2, aNewSi); + // + const BOPCol_ListOfInteger& aLI = aSelector.Indices(); + aItLI.Initialize(aLI); + for (; aItLI.More(); aItLI.Next()) { + j = aItLI.Value(); + if (aMj.Add(j)) { + const IntTools_Range& aRj = aSj(j); + aRj.Range(aTj1, aTj2); + SplitRangeOnTwo(aTj1, aTj2, aNewSj); + } + } + } + // + aSi.Assign(aNewSi); + aSj.Assign(aNewSj); + aNbi = aSi.Length(); + aNbj = aSj.Length(); + // + if ((aNbi == 0) || (aNbj == 0) || (aNbi > 500) || (aNbj > 500)) { + break; + } + // + aNewSi.Clear(); + aNewSj.Clear(); + aMj.Clear(); + } + // + iRet = (aNbi && aNbj) ? 1 : 0; + if (iRet) { + //collect ranges + IntTools_Range aRi1 = aSi(1), aRi2; + Standard_Real aT1 = aRi1.First(); + for (i = 2; i <= aNbi; ++i) { + aRi2 = aSi(i); + if ((aRi2.First() - aRi1.Last()) > myRes1) { + theSegments1.Append(IntTools_Range(aT1, aRi1.Last())); + aT1 = aRi2.First(); + } + aRi1 = aRi2; + } + theSegments1.Append(IntTools_Range(aT1, aRi2.Last())); + } + // + return iRet; +} + +//======================================================================= +//function : IsIntersection +//purpose : +//======================================================================= +Standard_Boolean IntTools_EdgeEdge::IsIntersection(const Standard_Real aT11, + const Standard_Real aT12, + const Standard_Real aT21, + const Standard_Real aT22) +{ + Standard_Boolean bRet; + gp_Pnt aP11, aP12, aP21, aP22; + gp_Vec aV11, aV12, aV21, aV22; + Standard_Real aD11_21, aD11_22, aD12_21, aD12_22, aCriteria, aCoef; + Standard_Boolean bSmall_11_21, bSmall_11_22, bSmall_12_21, bSmall_12_22; + // + bRet = Standard_True; + aCoef = 1.e+5; + if (((aT12 - aT11) > aCoef*myRes1) && ((aT22 - aT21) > aCoef*myRes2)) { + aCoef = 5000; + } else { + Standard_Real aTRMin = Min((aT12 - aT11)/myRes1, (aT22 - aT21)/myRes2); + aCoef = aTRMin / 100.; + if (aCoef < 1.) { + aCoef = 1.; + } + } + aCriteria = aCoef * myTol; + aCriteria *= aCriteria; + // + myGeom1->D1(aT11, aP11, aV11); + myGeom1->D1(aT12, aP12, aV12); + myGeom2->D1(aT21, aP21, aV21); + myGeom2->D1(aT22, aP22, aV22); + // + aD11_21 = aP11.SquareDistance(aP21); + aD11_22 = aP11.SquareDistance(aP22); + aD12_21 = aP12.SquareDistance(aP21); + aD12_22 = aP12.SquareDistance(aP22); + // + bSmall_11_21 = aD11_21 < aCriteria; + bSmall_11_22 = aD11_22 < aCriteria; + bSmall_12_21 = aD12_21 < aCriteria; + bSmall_12_22 = aD12_22 < aCriteria; + // + if ((bSmall_11_21 && bSmall_12_22) || + (bSmall_11_22 && bSmall_12_21)) { + if (aCoef == 1.) { + return bRet; + } + // + Standard_Real anAngleCriteria; + Standard_Real anAngle1, anAngle2; + // + anAngleCriteria = 5.e-3; + if (bSmall_11_21 && bSmall_12_22) { + anAngle1 = aV11.Angle(aV21); + anAngle2 = aV12.Angle(aV22); + } else { + anAngle1 = aV11.Angle(aV22); + anAngle2 = aV12.Angle(aV21); + } + // + if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) || + ((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) { + GeomAPI_ProjectPointOnCurve aProj; + Standard_Integer iErr; + Standard_Real aD, aT1p, aT2p; + // + aD = 100.; + aProj.Init(myGeom2, aT21, aT22); + iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1, aProj, aD, aT1p, aT2p, Standard_False); + bRet = (iErr == 2); + } + } + return bRet; +} + +//======================================================================= +//function : CheckCoincidence +//purpose : +//======================================================================= +Standard_Integer IntTools_EdgeEdge::CheckCoincidence(const Standard_Real aT11, + const Standard_Real aT12, + const Standard_Real aT21, + const Standard_Real aT22, + const Standard_Real theCriteria, + const Standard_Real theCurveResolution1) +{ + Standard_Integer iErr, aNb, i; + Standard_Real dT1, aT1, aT2, aD, aDmax; + Standard_Real aT1A, aT1B, aT1max, aT2max; + GeomAPI_ProjectPointOnCurve aProjPC; + // + iErr = 0; + aDmax = -1.; + aProjPC.Init(myGeom2, aT21, aT22); + // + // 1. Express evaluation + aNb = 10; // Number of intervals on the curve #1 + dT1 = (aT12 - aT11) / aNb; + for (i = 1; i < aNb; ++i) { + aT1 = aT11 + i*dT1; + // + iErr = DistPC(aT1, myGeom1, theCriteria, aProjPC, aD, aT2); + if (iErr) { + return iErr; + } + } + // + // 2. Deep evaluation + aNb -= 1; + for (i = 1; i < aNb; ++i) { + aT1A = aT11 + i*dT1; + aT1B = aT1A + dT1; + // + iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveResolution1, + aProjPC, aDmax, aT1max, aT2max); + if (iErr) { + return iErr; + } + } + // Possible values: + // iErr == 0 - the patches are coincided + // iErr == 1 - a point from aC1 can not be projected on aC2 + // iErr == 2 - the distance is too big + return iErr; +} + +//======================================================================= +//function : FindDistPC +//purpose : +//======================================================================= +Standard_Integer FindDistPC(const Standard_Real aT1A, + const Standard_Real aT1B, + const Handle(Geom_Curve)& theC1, + const Standard_Real theCriteria, + const Standard_Real theEps, + GeomAPI_ProjectPointOnCurve& theProjPC, + Standard_Real& aDmax, + Standard_Real& aT1max, + Standard_Real& aT2max, + const Standard_Boolean bMaxDist) +{ + Standard_Integer iErr, iC; + Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L; + // + iC = bMaxDist ? 1 : -1; + iErr = 0; + // + aGS = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.; + aA = aT1A; + aB = aT1B; + // + // check bounds + iErr = DistPC(aA, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC); + if (iErr == 2) { + return iErr; + } + // + iErr = DistPC(aB, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC); + if (iErr == 2) { + return iErr; + } + // + aXP = aA + (aB - aA)*aGS; + aXL = aB - (aB - aA)*aGS; + // + iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC); + if (iErr) { + return iErr; + } + // + iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC); + if (iErr) { + return iErr; + } + // + for (;;) { + if (iC*(aYP - aYL) > 0) { + aA = aXL; + aXL = aXP; + aYL = aYP; + aXP = aA + (aB - aA)*aGS; + iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC); + if (iErr) { + return iErr; + } + } + else { + aB = aXP; + aXP = aXL; + aYP = aYL; + aXL = aB - (aB - aA)*aGS; + iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC); + if (iErr) { + return iErr; + } + } + // + if ((aB - aA) < theEps) { + break; + } + }// for (;;) { + // + return iErr; +} +//======================================================================= +//function : DistPC +//purpose : +//======================================================================= +Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& theC1, + const Standard_Real theCriteria, + GeomAPI_ProjectPointOnCurve& theProjPC, + Standard_Real& aD, + Standard_Real& aT2, + Standard_Real& aDmax, + Standard_Real& aT1max, + Standard_Real& aT2max, + const Standard_Integer iC) +{ + Standard_Integer iErr; + // + iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC); + if (iErr) { + return iErr; + } + // + if (iC*(aD - aDmax) > 0) { + aDmax = aD; + aT1max = aT1; + aT2max = aT2; + } + // + return iErr; +} +//======================================================================= +//function : DistPC +//purpose : +//======================================================================= +Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& theC1, + const Standard_Real theCriteria, + GeomAPI_ProjectPointOnCurve& theProjPC, + Standard_Real& aD, + Standard_Real& aT2, + const Standard_Integer iC) +{ + Standard_Integer iErr, aNbP2; + gp_Pnt aP1; + // + iErr = 0; + theC1->D0(aT1, aP1); + // + theProjPC.Perform(aP1); + aNbP2 = theProjPC.NbPoints(); + if (!aNbP2) { + iErr = 1;// the point from aC1 can not be projected on aC2 + return iErr; + } + // + aD = theProjPC.LowerDistance(); + aT2 = theProjPC.LowerDistanceParameter(); + if (iC*(aD - theCriteria) > 0) { + iErr = 2;// the distance is too big or small + } + // + return iErr; +} + +//======================================================================= +//function : SplitRangeOnSegments +//purpose : +//======================================================================= +void SplitRangeOnSegments(const Standard_Real aT1, + const Standard_Real aT2, + const Standard_Real theResolution, + const Standard_Integer theNbSeg, + IntTools_SequenceOfRanges& theSegments) +{ + Standard_Real aDt, aT1x, aT2x, aSeg; + Standard_Integer aNbSegments, i; + // + aNbSegments = theNbSeg; + aDt = aT2 - aT1; + if (aDt < theResolution) { + aNbSegments = 1; + } else if (aDt < Precision::Confusion()) { + aSeg = aDt / theResolution; + if (aSeg < theNbSeg) { + aNbSegments = Standard_Integer(aSeg) + 1; + } + } + // + aDt /= aNbSegments; + aT1x = aT1; + for (i = 1; i <= aNbSegments; ++i) { + aT2x = aT1x + aDt; + if (i==aNbSegments) { + aT2x = aT2; + } + // + IntTools_Range aR(aT1x, aT2x); + theSegments.Append(aR); + // + aT1x = aT2x; + } +} + +//======================================================================= +//function : SplitRangeOnTwo +//purpose : +//======================================================================= +void SplitRangeOnTwo(const Standard_Real aT1, + const Standard_Real aT2, + IntTools_SequenceOfRanges& theSegments) +{ + Standard_Real aCf, aT; + // + aCf=0.5; + aT = aT1 + (aT2-aT1)*aCf; + // + IntTools_Range aR1(aT1, aT), aR2(aT, aT2); + // + theSegments.Append(aR1); + theSegments.Append(aR2); +} + +//======================================================================= +//function : BndCommon +//purpose : +//======================================================================= +Standard_Boolean BndCommon(const Bnd_Box& theB1, + const Bnd_Box& theB2, + Bnd_Box& theBOut) +{ + Standard_Boolean bRet; + // + bRet = !theB1.IsOut(theB2); + if (bRet) { + Standard_Real aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1, + aXmin2, aYmin2, aZmin2, aXmax2, aYmax2, aZmax2; + Bnd_Box aBCom; + // + theB1.Get(aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1); + theB2.Get(aXmin2, aYmin2, aZmin2, aXmax2, aYmax2, aZmax2); + // + aBCom.Update(Max(aXmin1, aXmin2), Max(aYmin1, aYmin2), Max(aZmin1, aZmin2), + Min(aXmax1, aXmax2), Min(aYmax1, aYmax2), Min(aZmax1, aZmax2)); + // + aBCom.Get(aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1); + theBOut = aBCom; + } + return bRet; +} + +//======================================================================= +//function : BndBuildBox +//purpose : +//======================================================================= +void BndBuildBox(const BRepAdaptor_Curve& theBAC, + const Standard_Real aT1, + const Standard_Real aT2, + const Standard_Real theTol, + Bnd_Box& theBox) +{ + Bnd_Box aB; + BndLib_Add3dCurve::Add(theBAC, aT1, aT2, theTol, aB); + theBox = aB; +} + +//======================================================================= +//function : TypeToInteger +//purpose : +//======================================================================= +Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType) +{ + Standard_Integer iRet; + // + switch(theCType) { + case GeomAbs_Line: + iRet=0; + break; + case GeomAbs_Circle: + iRet=1; + break; + case GeomAbs_Ellipse: + case GeomAbs_Hyperbola: + case GeomAbs_Parabola: + iRet=2; + break; + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: + iRet=3; + break; + default: + iRet=4; + break; + } + return iRet; +} + diff --git a/src/IntTools/IntTools_EdgeEdge.lxx b/src/IntTools/IntTools_EdgeEdge.lxx new file mode 100644 index 0000000000..64ae16b860 --- /dev/null +++ b/src/IntTools/IntTools_EdgeEdge.lxx @@ -0,0 +1,197 @@ +// Created by: Eugeny MALTCHIKOV +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +//======================================================================= +//function : IntTools_EdgeEdge +//purpose : +//======================================================================= +inline IntTools_EdgeEdge::IntTools_EdgeEdge() +: + myTol1(0.), + myTol2(0.), + myTol(0.), + myRes1(0.), + myRes2(0.), + myRange1(0., 0.), + myRange2(0., 0.), + mySwap(Standard_False), + myErrorStatus(0) +{ +} +//======================================================================= +//function : IntTools_EdgeEdge +//purpose : +//======================================================================= +inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge& theEdge1, + const TopoDS_Edge& theEdge2) +: + myEdge1(theEdge1), + myEdge2(theEdge2), + myTol1(0.), + myTol2(0.), + myTol(0.), + myRes1(0.), + myRes2(0.), + myRange1(0., 0.), + myRange2(0., 0.), + mySwap(Standard_False), + myErrorStatus(0) +{ +} +//======================================================================= +//function : IntTools_EdgeEdge +//purpose : +//======================================================================= +inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge& theEdge1, + const Standard_Real aT11, + const Standard_Real aT12, + const TopoDS_Edge& theEdge2, + const Standard_Real aT21, + const Standard_Real aT22) +: + myEdge1(theEdge1), + myEdge2(theEdge2), + myTol1(0.), + myTol2(0.), + myTol(0.), + myRes1(0.), + myRes2(0.), + myRange1(aT11, aT12), + myRange2(aT21, aT22), + mySwap(Standard_False), + myErrorStatus(0) +{ +} +//======================================================================= +//function : IntTools_EdgeEdge +//purpose : +//======================================================================= +inline IntTools_EdgeEdge::~IntTools_EdgeEdge() +{ +} +//======================================================================= +//function : SetEdge1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& theEdge) +{ + myEdge1 = theEdge; +} +//======================================================================= +//function : SetRange1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetRange1(const IntTools_Range& theRange) +{ + myRange1 = theRange; +} +//======================================================================= +//function : SetRange1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetRange1(const Standard_Real aT1, + const Standard_Real aT2) +{ + myRange1.SetFirst(aT1); + myRange1.SetLast(aT2); +} +//======================================================================= +//function : SetEdge1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& theEdge, + const Standard_Real aT1, + const Standard_Real aT2) +{ + SetEdge1(theEdge); + SetRange1(aT1, aT2); +} +//======================================================================= +//function : SetEdge2 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& theEdge) +{ + myEdge2 = theEdge; +} +//======================================================================= +//function : SetRange1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetRange2(const IntTools_Range& theRange) +{ + myRange2 = theRange; +} +//======================================================================= +//function : SetRange1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetRange2(const Standard_Real aT1, + const Standard_Real aT2) +{ + myRange2.SetFirst(aT1); + myRange2.SetLast(aT2); +} +//======================================================================= +//function : SetEdge1 +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& theEdge, + const Standard_Real aT1, + const Standard_Real aT2) +{ + SetEdge2(theEdge); + SetRange2(aT1, aT2); +} +//======================================================================= +//function : CommonParts +//purpose : +//======================================================================= +inline const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const +{ + return myCommonParts; +} +//======================================================================= +//function : IsDone +//purpose : +//======================================================================= +inline Standard_Boolean IntTools_EdgeEdge::IsDone() const +{ + return (myErrorStatus == 0); +} +//======================================================================= +//function : CheckData +//purpose : +//======================================================================= +inline void IntTools_EdgeEdge::CheckData() +{ + if (myEdge1.IsNull() || myEdge2.IsNull()) { + myErrorStatus = 1; + return; + } + // + if (BRep_Tool::Degenerated(myEdge1) || BRep_Tool::Degenerated(myEdge2)) { + myErrorStatus = 2; + return; + } + // + if (!BRep_Tool::IsGeometric(myEdge1) || !BRep_Tool::IsGeometric(myEdge2)) { + myErrorStatus = 3; + return; + } +} + diff --git a/src/IntTools/IntTools_EdgeEdge_1.cxx b/src/IntTools/IntTools_EdgeEdge_1.cxx deleted file mode 100644 index 09421ecb46..0000000000 --- a/src/IntTools/IntTools_EdgeEdge_1.cxx +++ /dev/null @@ -1,918 +0,0 @@ -// Created on: 2014-11-29 -// Created by: Peter KURNEV -// Copyright (c) 2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and / or modify it -// under the terms of the GNU Lesser General Public version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include -#include -#include -#include -#include -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// -#include -// -#include - - -//======================================================================= -//class : IntTools_ComparatorCurve -//purpose : -//======================================================================= -class IntTools_ComparatorCurve { - public: - IntTools_ComparatorCurve() { - myT11=0.; - myT12=0.; - myT21=0.; - myT22=0.; - myIsSame=Standard_False; - }; - // - virtual ~IntTools_ComparatorCurve(){ - }; - // - void SetCurve1(const BRepAdaptor_Curve& aBC3D) { - myBC1=aBC3D; - }; - // - const BRepAdaptor_Curve& Curve1()const { - return myBC1; - }; - // - void SetRange1(const Standard_Real aT1, - const Standard_Real aT2) { - myT11=aT1; - myT12=aT2; - }; - // - void Range1(Standard_Real& aT1, Standard_Real& aT2)const { - aT1=myT11; - aT2=myT12; - }; - // - void SetCurve2(const BRepAdaptor_Curve& aBC3D){ - myBC2=aBC3D; - }; - // - const BRepAdaptor_Curve& Curve2()const{ - return myBC2; - }; - // - void SetRange2(const Standard_Real aT1, - const Standard_Real aT2){ - myT21=aT1; - myT22=aT2; - }; - // - void Range2(Standard_Real& aT1, - Standard_Real& aT2)const { - aT1=myT21; - aT2=myT22; - }; - // - Standard_Boolean IsSame()const { - return myIsSame; - }; - // - void Perform(); - // - //-------------------------------------- - protected: - // - void IsSameElipse(); - // - void IsSameBSplineCurve(); - // - static - Standard_Boolean - IsSameReal(const Standard_Real aR1, - const Standard_Real aR2); - // - static - Standard_Boolean - IsSameAx2(const gp_Ax2& aAx21, - const gp_Ax2& aAx22); - // - static - Standard_Boolean - IsSameAx1(const gp_Ax1& aAx1, - const gp_Ax1& aAx2); - // - static - Standard_Boolean - IsSamePnt(const gp_Pnt& aP1, - const gp_Pnt& aP2); - static - Standard_Boolean - IsSameDir(const gp_Dir& aDir1, - const gp_Dir& aDir2); - // - static - Standard_Boolean - IsSameXYZ(const gp_XYZ& aXYZ1, - const gp_XYZ& aXYZ2); - // - static - void GetCurveBase(const Handle(Geom_Curve)& aC3D, - GeomAbs_CurveType& aTypeBase, - Handle(Geom_Curve)& aCurveBase); - // - static - Standard_Boolean - IsTypeBase(const Handle(Geom_Curve)& aC, - GeomAbs_CurveType& aTypeB); - // - protected: - BRepAdaptor_Curve myBC1; - Standard_Real myT11; - Standard_Real myT12; - // - BRepAdaptor_Curve myBC2; - Standard_Real myT21; - Standard_Real myT22; - // - Standard_Boolean myIsSame; -}; -// -//======================================================================= -//function : Perform -//purpose : -//======================================================================= -void IntTools_ComparatorCurve::Perform() -{ - GeomAbs_CurveType aCurveType1, aCurveType2; - // - myIsSame=Standard_False; - // - aCurveType1=myBC1.GetType(); - aCurveType2=myBC2.GetType(); - // - myIsSame=(aCurveType1==aCurveType2); - if (!myIsSame) { - return; - } - // - myIsSame=IsSameReal(myT11, myT21); - if (!myIsSame) { - return; - } - // - myIsSame=IsSameReal(myT12, myT22); - if (!myIsSame) { - return; - } - // - if (aCurveType1==GeomAbs_Ellipse) { - IsSameElipse(); - return; - } - else if (aCurveType1==GeomAbs_BSplineCurve) { - IsSameBSplineCurve(); - return ; - } - else { - myIsSame=Standard_False; - return; - } -} -//======================================================================= -//function : IsSameBSplineCurve -//purpose : -//======================================================================= -void IntTools_ComparatorCurve::IsSameBSplineCurve() -{ - Standard_Boolean bIsRational, bIsPreiodic; - Standard_Integer iNbPoles, iNbKnots, iDegree; - // - bIsRational=myBC1.IsRational(); - myIsSame=(bIsRational==myBC2.IsRational()); - if (!myIsSame) { - return; - } - // - iNbPoles=myBC1.NbPoles(); - myIsSame=(iNbPoles==myBC2.NbPoles()); - if (!myIsSame) { - return; - } - // - iNbKnots=myBC1.NbKnots(); - myIsSame=(iNbKnots==myBC2.NbKnots()); - if (!myIsSame) { - return; - } - // - iDegree=myBC1.Degree(); - myIsSame=(iDegree==myBC2.Degree()); - if (!myIsSame) { - return; - } - // - bIsPreiodic=myBC1.IsPeriodic(); - myIsSame=(bIsPreiodic==myBC2.IsPeriodic()); - if (!myIsSame) { - return; - } - - //------------------------------------------- - Standard_Integer i, j, aM[2]; - Standard_Real aT1, aT2, aX0[4], aX1[4]; - GeomAbs_CurveType aTypeBase; - gp_Pnt aP; - Handle(Geom_Curve) aC; - Handle(Geom_BSplineCurve) aBSp[2]; - TopoDS_Edge aE1, aE2; - // - aE1=myBC1.Edge(); - aE2=myBC2.Edge(); - // - aC=BRep_Tool::Curve (aE1, aT1, aT2); - GetCurveBase(aC, aTypeBase, aBSp[0]); - // - aC=BRep_Tool::Curve (aE2, aT1, aT2); - GetCurveBase(aC, aTypeBase, aBSp[1]); - // - // Poles / Weights - for(i=1; i<=iNbPoles; ++i) { - aP=aBSp[0]->Pole(i); - aP.Coord(aX0[0], aX0[1], aX0[2]); - aX0[3]=aBSp[0]->Weight(i); - // - aP=aBSp[1]->Pole(i); - aP.Coord(aX1[0], aX1[1], aX1[2]); - aX1[3]=aBSp[1]->Weight(i); - // - for (j=0; j<4; ++j) { - myIsSame=IsSameReal(aX0[j], aX1[j]); - if(!myIsSame) { - return; - } - } - }//for(i=1; iKnot(i); - aX0[1]=aBSp[1]->Knot(i); - myIsSame=IsSameReal(aX0[0], aX0[1]); - if(!myIsSame) { - return; - } - // - aM[0]=aBSp[0]->Multiplicity(i); - aM[1]=aBSp[1]->Multiplicity(i); - myIsSame=(aM[0]==aM[1]); - if(!myIsSame) { - return; - } - } -} -//======================================================================= -//function : GetCurveBase -//purpose : -//======================================================================= -void IntTools_ComparatorCurve::GetCurveBase(const Handle(Geom_Curve)& aC3D, - GeomAbs_CurveType& aTypeBase, - Handle(Geom_Curve)& aCurveBase) -{ - Standard_Boolean bIsTypeBase; - Standard_Integer iTrimmed, iOffset; - Standard_Real aOffsetBase; - GeomAbs_CurveType aTypeB; - Handle(Geom_Curve) aC3DB; - Handle(Geom_TrimmedCurve) aCT3D; - Handle(Geom_OffsetCurve) aCF3D; - // - aTypeBase=GeomAbs_OtherCurve; - aOffsetBase=0.; - // - aC3DB=aC3D; - bIsTypeBase=IsTypeBase(aC3DB, aTypeB); - if (bIsTypeBase) { - aTypeBase=aTypeB; - aCurveBase=aC3D; - return; - } - // - for(;;) { - iTrimmed=0; - iOffset=0; - aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3DB); - if (!aCT3D.IsNull()) { - aC3DB=aCT3D->BasisCurve(); - ++iTrimmed; - } - // - aCF3D=Handle(Geom_OffsetCurve)::DownCast(aC3DB); - if (!aCF3D.IsNull()) { - Standard_Real aOffset; - // - aOffset=aCF3D->Offset(); - aOffsetBase=aOffsetBase+aOffset; - // - aC3DB=aCF3D->BasisCurve(); - ++iOffset; - } - // - if (!(iTrimmed || iOffset)) { - break; - } - // - bIsTypeBase=IsTypeBase(aC3DB, aTypeB); - if (bIsTypeBase) { - aTypeBase=aTypeB; - aCurveBase=aC3DB; - return; - } - } -} -//======================================================================= -//function : IsTypeBase -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsTypeBase(const Handle(Geom_Curve)& aC, - GeomAbs_CurveType& aTypeB) -{ - Standard_Boolean bRet; - Handle(Standard_Type) aType; - // - bRet=Standard_True; - // - aType=aC->DynamicType(); - if (aType==STANDARD_TYPE(Geom_Line)) { - aTypeB=GeomAbs_Line; - } - else if (aType==STANDARD_TYPE(Geom_Circle)) { - aTypeB=GeomAbs_Circle; - } - else if (aType==STANDARD_TYPE(Geom_Ellipse)) { - aTypeB=GeomAbs_Ellipse; - } - else if (aType==STANDARD_TYPE(Geom_Parabola)) { - aTypeB=GeomAbs_Parabola; - } - else if (aType==STANDARD_TYPE(Geom_Hyperbola)) { - aTypeB=GeomAbs_Hyperbola; - } - else if (aType==STANDARD_TYPE(Geom_BezierCurve)) { - aTypeB=GeomAbs_BezierCurve; - } - else if (aType==STANDARD_TYPE(Geom_BSplineCurve)) { - aTypeB=GeomAbs_BSplineCurve; - } - else { - aTypeB=GeomAbs_OtherCurve; - bRet=!bRet; - } - return bRet; -} -//======================================================================= -//function : IsSameElipse -//purpose : -//======================================================================= -void IntTools_ComparatorCurve::IsSameElipse() -{ - Standard_Real aR1, aR2; - gp_Elips aElips1, aElips2; - // - myIsSame=Standard_False; - // - aElips1=myBC1.Ellipse(); - aElips2=myBC2.Ellipse(); - // - aR1=aElips1.MajorRadius(); - aR2=aElips2.MajorRadius(); - myIsSame=IsSameReal(aR1, aR2); - if (!myIsSame) { - return; - } - // - aR1=aElips1.MinorRadius(); - aR2=aElips2.MinorRadius(); - myIsSame=IsSameReal(aR1, aR2); - if (!myIsSame) { - return; - } - // - const gp_Ax2& aAx21=aElips1.Position(); - const gp_Ax2& aAx22=aElips2.Position(); - myIsSame=IsSameAx2(aAx21, aAx22); -} -//======================================================================= -//function : IsSameAx2 -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsSameAx2(const gp_Ax2& aAx21, - const gp_Ax2& aAx22) -{ - Standard_Boolean bRet; - // - const gp_Ax1& aAx1=aAx21.Axis(); - const gp_Ax1& aAx2=aAx22.Axis(); - // - bRet=IsSameAx1(aAx1, aAx2); - if (!bRet) { - return bRet; - } - // - const gp_Dir& aDirX1=aAx21.XDirection(); - const gp_Dir& aDirX2=aAx22.XDirection(); - // - bRet=IsSameDir(aDirX1, aDirX2); - if (!bRet) { - return bRet; - } - // - // - const gp_Dir& aDirY1=aAx21.YDirection(); - const gp_Dir& aDirY2=aAx22.YDirection(); - // - bRet=IsSameDir(aDirY1, aDirY2); - // - return bRet; -} -//======================================================================= -//function : IsSamePnt -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsSamePnt(const gp_Pnt& aP1, - const gp_Pnt& aP2) -{ - const gp_XYZ& aXYZ1=aP1.XYZ(); - const gp_XYZ& aXYZ2=aP2.XYZ(); - return IsSameXYZ(aXYZ1, aXYZ2); -} -//======================================================================= -//function : IsSameAx1 -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsSameAx1(const gp_Ax1& aAx1, - const gp_Ax1& aAx2) -{ - Standard_Boolean bRet; - // - const gp_Pnt& aP1=aAx1.Location(); - const gp_Pnt& aP2=aAx2.Location(); - // - bRet=IsSamePnt(aP1, aP2); - if (!bRet) { - return bRet; - } - // - const gp_Dir& aDir1=aAx1.Direction(); - const gp_Dir& aDir2=aAx2.Direction(); - // - bRet=IsSameDir(aDir1, aDir2); - return bRet; -} -//======================================================================= -//function : IsSameDir -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsSameDir(const gp_Dir& aDir1, - const gp_Dir& aDir2) -{ - const gp_XYZ& aXYZ1=aDir1.XYZ(); - const gp_XYZ& aXYZ2=aDir2.XYZ(); - return IsSameXYZ(aXYZ1, aXYZ2); -} -//======================================================================= -//function : IsSameXYZ -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsSameXYZ(const gp_XYZ& aXYZ1, - const gp_XYZ& aXYZ2) -{ - Standard_Boolean bRet = Standard_False; - Standard_Integer i; - Standard_Real aX1[3], aX2[3]; - - aXYZ1.Coord(aX1[0], aX1[1], aX1[2]); - aXYZ2.Coord(aX2[0], aX2[1], aX2[2]); - // - for (i=0; i<3; ++i) { - bRet=IsSameReal(aX1[i], aX2[i]); - if(!bRet) { - break; - } - } - return bRet; -} -//======================================================================= -//function : IsSameReal -//purpose : -//======================================================================= -Standard_Boolean - IntTools_ComparatorCurve::IsSameReal(const Standard_Real aR1, - const Standard_Real aR2) -{ - Standard_Boolean bRet; - Standard_Real aEpsilon; - // - aEpsilon=Epsilon(aR1); - bRet=(fabs(aR1-aR2)myT12) { - aT2=myT12; - } - } - // - FindMaxLocal(aT1, aT2, aEps, aD, aT); - if (myErrorStatus) { - return ; - } - // - if (aD>aDmax) { - aDmax=aD; - aTmax=aT; - } - } - // - myTx=aTmax; - myDx=aDmax; -} -//======================================================================= -//function : FindMaxLocal -//purpose : Solver: Golden Mean -//======================================================================= -void IntTools_DistCC::FindMaxLocal(const Standard_Real aT11, - const Standard_Real aT12, - const Standard_Real aEps, - Standard_Real& aDx, - Standard_Real& aTx) -{ - Standard_Integer iErr; - Standard_Real aA, aB, aCf, aX1, aX2, aF1, aF2, aX, aF; - // - myErrorStatus=0; - iErr=0; - aDx=0.; - aTx=0.; - // - aCf=1.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.)); - // - aA=aT11; - aB=aT12; - // - aX1=aB-(aB-aA)/aCf; - aF1=Distance(aX1); - if (myErrorStatus) { - return ; - } - // - aX2=aA+(aB-aA)/aCf; - aF2=Distance(aX2); - if (myErrorStatus) { - return; - } - // - for(;;) { - if (fabs(aA-aB)D0(aT, aP1); - myPPC2.Perform(aP1); - // - aNbP2=myPPC2.NbPoints(); - if (!aNbP2) { - myErrorStatus=4; - return aD; - } - // - aD=myPPC2.LowerDistance(); - if (aD>myThreshold) { - myErrorStatus=10; - } - return aD; -} -//modified by NIZNHY-PKV Tue Jan 15 07:44:44 2013t -// -//======================================================================= -//function : IsSameCurves -//purpose : -//======================================================================= -Standard_Boolean IntTools_EdgeEdge::IsSameCurves() -{ - Standard_Boolean bRet, bIsBC; - GeomAbs_CurveType aCT1, aCT2; - IntTools_ComparatorCurve aICC; - // - // 1. Check letter - aICC.SetCurve1(myCFrom); - aICC.SetRange1(myTminFrom, myTmaxFrom); - // - aICC.SetCurve2(myCTo); - aICC.SetRange2(myTminTo, myTmaxTo); - // - aICC.Perform(); - bRet=aICC.IsSame(); - if (bRet) { - return bRet; - } - // - // 2. Check inwards - aCT1=myCFrom.GetType(); - aCT2=myCTo.GetType(); - bIsBC=(aCT1==GeomAbs_BSplineCurve || - aCT1==GeomAbs_BezierCurve || - aCT2==GeomAbs_BSplineCurve || - aCT2==GeomAbs_BezierCurve); - // - if (bIsBC) { - Standard_Integer iErr; - Standard_Real aT11, aT12, aT21, aT22; - Handle(Geom_Curve) aC1, aC2; - IntTools_DistCC aDistCC; - // - const TopoDS_Edge& aE1=myCFrom.Edge(); - aC1=BRep_Tool::Curve(aE1, aT11, aT12); - // - const TopoDS_Edge& aE2=myCTo.Edge(); - aC2=BRep_Tool::Curve(aE2, aT21, aT22); - // - aDistCC.SetCurve1(aC1); - aDistCC.SetRange1(myTminFrom, myTmaxFrom); - aDistCC.SetCurve2(aC2); - aDistCC.SetRange2(myTminTo, myTmaxTo); - aDistCC.SetThreshold(myCriteria); - // - aDistCC.Perform(); - // - iErr=aDistCC.ErrorStatus(); - // - bRet=(!iErr); - // - } - return bRet; -} - diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index 815435c909..e7fa725df0 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -88,7 +88,8 @@ // Returns true if one of original edges dropped static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges, const TopoDS_Shape aShape, - Standard_Integer& anIndex) + Standard_Integer& anIndex, + Handle(ShapeBuild_ReShape)& aContext) { //map of edges TopTools_IndexedMapOfShape aNewEdges; @@ -122,6 +123,7 @@ static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges, aNewEdges.Substitute(aNewEdges.FindIndex(current), LastEdge); ///////////////////////// edges.Remove(i); + aContext->Remove(current); i--; if(!isDropped) { @@ -838,7 +840,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() Standard_Integer dummy; TopTools_SequenceOfShape edges; - AddOrdinaryEdges(edges,aFace,dummy); + AddOrdinaryEdges(edges, aFace, dummy, myContext); TopTools_SequenceOfShape faces; faces.Append(aFace); @@ -878,7 +880,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() B.MakeFace(aMockUpFace,aBaseSurface,aBaseLocation,0.); MovePCurves(aMockUpFace,anCheckedFace); - if (AddOrdinaryEdges(edges,aMockUpFace,dummy)) { + if (AddOrdinaryEdges(edges, aMockUpFace, dummy, myContext)) { // sequence edges is modified i = dummy; }