diff --git a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx index 3dd243a5ad..2730cfc17f 100644 --- a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx +++ b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx @@ -735,28 +735,12 @@ 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); - + // + IntTools_EdgeEdge aEE(aE1, aE2); + // aEE.Perform(); - if (aEE.IsDone()) { const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts(); Standard_Integer ii = 0; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx index fb439eddd7..62fe9aae26 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx @@ -69,17 +69,14 @@ //======================================================================= 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; // @@ -96,9 +93,6 @@ void BOPAlgo_PaveFiller::PerformEE() 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); @@ -122,9 +116,6 @@ void BOPAlgo_PaveFiller::PerformEE() 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); // @@ -158,75 +149,23 @@ void BOPAlgo_PaveFiller::PerformEE() 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); @@ -237,18 +176,25 @@ void BOPAlgo_PaveFiller::PerformEE() 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])) { @@ -259,7 +205,7 @@ void BOPAlgo_PaveFiller::PerformEE() 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; @@ -269,7 +215,7 @@ void BOPAlgo_PaveFiller::PerformEE() continue; } // - BOPTools_AlgoTools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aVnew); + BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew); // <-LXBR { Standard_Integer nVS[2], iFound, k; @@ -312,14 +258,14 @@ void BOPAlgo_PaveFiller::PerformEE() 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; // @@ -342,10 +288,10 @@ void BOPAlgo_PaveFiller::PerformEE() // 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 diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index 1e6cec0edf..d4d9552173 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -1399,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_CompatibleWires.cxx b/src/BRepFill/BRepFill_CompatibleWires.cxx index 12f6770c2c..7c4ae5a0b3 100644 --- a/src/BRepFill/BRepFill_CompatibleWires.cxx +++ b/src/BRepFill/BRepFill_CompatibleWires.cxx @@ -157,6 +157,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 = BRep_Tool::Curve(Edge, first, last); if (wClosed) { GeomAdaptor_Curve AdC; diff --git a/src/BRepFill/BRepFill_Evolved.cxx b/src/BRepFill/BRepFill_Evolved.cxx index 5e5205ed22..5699d256e1 100644 --- a/src/BRepFill/BRepFill_Evolved.cxx +++ b/src/BRepFill/BRepFill_Evolved.cxx @@ -1700,7 +1700,7 @@ const for (TopoDS_Iterator IteW(IteF.Value()); IteW.More(); IteW.Next()) { - TopoDS_Edge E = TopoDS::Edge(IteW.Value()); + const TopoDS_Edge& E = TopoDS::Edge(IteW.Value()); EdgeVertices(E,V1,V2); MapSpine.Bind(V1,V1); MapSpine.Bind(V2,V2); 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 19a8501903..5400775f9e 100644 --- a/src/BRepFill/BRepFill_PipeShell.cxx +++ b/src/BRepFill/BRepFill_PipeShell.cxx @@ -214,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), @@ -226,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; @@ -414,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 @@ -742,7 +764,8 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) theContinuity = GeomAbs_C0; TopTools_MapOfShape Dummy; BRepFill_DataMapOfShapeHArray2OfShape Dummy2; - MkSw.Build(Dummy, Dummy2, myTransition, theContinuity); + MkSw.Build(Dummy, Dummy2, myTransition, theContinuity, + GeomFill_Location, myMaxDegree, myMaxSegments); myStatus = myLocation->GetStatus(); Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); 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/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 a4e710014f..0000000000 --- a/src/IntTools/IntTools_BeanBeanIntersector.cxx +++ /dev/null @@ -1,1391 +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 +void IntTools_EdgeEdge::Perform() { - 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; + //1. Check data + CheckData(); + if (myErrorStatus) { + return; } // - 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); + //2. Prepare Data + Prepare(); // - // 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); + //3.1. Check Line/Line case + if (myCurve1.GetType() == GeomAbs_Line && + myCurve2.GetType() == GeomAbs_Line) { + ComputeLineLine(); + return; } // - // - Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2; - Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, 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 - 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) -{ + //3.2. Find solutions + IntTools_SequenceOfRanges aRanges1, aRanges2, aSegments1; Standard_Integer i, aNb; - 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; - } + //3.2.1 Find rough ranges + FindRoughRanges(myRange1, myRange2, aSegments1); + aNb = aSegments1.Length(); + //3.2.2. Find exact solutions and ranges + for (i = 1; i <= aNb; ++i) { + const IntTools_Range& aR1 = aSegments1(i); + FindSolutions(aR1, myRange2, aRanges1, aRanges2); } // - 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; - // - aCirc1=myCFrom.Circle(); - aCirc2=myCTo.Circle(); - // - 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; - 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(); - // - 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; - gp_Circ aCirc; - gp_Lin aLine; - gp_Pnt aPCenter, aPOnLine; - - aTFrom=myCFrom.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; + BOPCol_BoxBndTreeSelector aSelector; + BOPCol_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 48d69c60d0..0000000000 --- a/src/IntTools/IntTools_EdgeEdge_1.cxx +++ /dev/null @@ -1,916 +0,0 @@ -// Created on: 2012-11-29 -// Created by: Peter KURNEV -// Copyright (c) 2012-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_Real aA, aB, aCf, aX1, aX2, aF1, aF2, aX, aF; - // - myErrorStatus=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; }