-// Created on: 2000-10-26
-// Created by: Peter KURNEV
-// Copyright (c) 2000-2012 OPEN CASCADE SAS
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License 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.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
-#include <IntTools_EdgeEdge.ixx>
-
-#include <Precision.hxx>
-
-#include <TColStd_SequenceOfReal.hxx>
-
-#include <gp_Circ.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Lin.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
+#include <Bnd_Box.hxx>
+#include <BndLib_Add3dCurve.hxx>
+#include <BOPCol_MapOfInteger.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
#include <ElCLib.hxx>
-#include <Geom_Curve.hxx>
-
+#include <Geom_BezierCurve.hxx>
#include <Geom_BSplineCurve.hxx>
-#include <GeomAdaptor_Curve.hxx>
-
-#include <CPnts_AbscissaPoint.hxx>
-
+#include <Geom_Line.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_OffsetCurve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
-
-#include <Extrema_ExtElC.hxx>
-#include <Extrema_POnCurv.hxx>
-#include <Extrema_ExtCC.hxx>
-
-#include <TopoDS_Iterator.hxx>
-#include <BRep_Tool.hxx>
-
-#include <IntTools.hxx>
-#include <IntTools_Range.hxx>
-#include <IntTools_CArray1OfReal.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Lin.hxx>
#include <IntTools_CommonPrt.hxx>
-#include <IntTools_SequenceOfRanges.hxx>
+#include <IntTools_EdgeEdge.hxx>
+#include <IntTools_Range.hxx>
#include <IntTools_Tools.hxx>
-#include <IntTools_BeanBeanIntersector.hxx>
-
-
-//=======================================================================
-//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());
-}
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
-//=======================================================================
-//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;
-}
+static
+ void BndBuildBox(const BRepAdaptor_Curve& theBAC,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ Bnd_Box& theBox);
+static
+ Standard_Real PointBoxDistance(const Bnd_Box& aB,
+ const gp_Pnt& aP);
+static
+ Standard_Integer SplitRangeOnSegments(const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theResolution,
+ const Standard_Integer theNbSeg,
+ 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_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange);
+static
+ Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
+ const GeomAbs_CurveType theCurveType,
+ const Standard_Real theResCoeff,
+ const Standard_Real theR3D);
+static
+ Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange);
+static
+ Standard_Boolean IsClosed(const Handle(Geom_Curve)& theCurve,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ const Standard_Real theRes);
+static
+ Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType);
//=======================================================================
-//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
+//function : Prepare
//purpose :
//=======================================================================
- void IntTools_EdgeEdge::Perform()
+void IntTools_EdgeEdge::Prepare()
{
- Standard_Boolean bIsSameCurves;
- Standard_Integer i, pri, aNbCommonPrts, aNbRange;
- Standard_Real aT1, aT2, aPC;
- IntTools_CommonPrt aCommonPrt;
- GeomAbs_CurveType aCTFrom, aCTTo;
+ GeomAbs_CurveType aCT1, aCT2;
+ Standard_Integer iCT1, iCT2;
//
- myIsDone=Standard_False;
- myErrorStatus=0;
+ myCurve1.Initialize(myEdge1);
+ myCurve2.Initialize(myEdge2);
//
- CheckData();
- if (myErrorStatus)
- return;
+ if (myRange1.First() == 0. && myRange1.Last() == 0.) {
+ myRange1.SetFirst(myCurve1.FirstParameter());
+ myRange1.SetLast (myCurve1.LastParameter());
+ }
//
- Prepare();
-
- if (myErrorStatus) {
- return;
+ if (myRange2.First() == 0. && myRange2.Last() == 0.) {
+ myRange2.SetFirst(myCurve2.FirstParameter());
+ myRange2.SetLast (myCurve2.LastParameter());
}
//
- aCTFrom = myCFrom.GetType();
- aCTTo = myCTo.GetType();
+ aCT1 = myCurve1.GetType();
+ aCT2 = myCurve2.GetType();
//
- if(aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Line) {
- ComputeLineLine();
- if (myOrder) {
- TopoDS_Edge aTmp;
- aTmp=myEdge1;
- myEdge1=myEdge2;
- myEdge2=aTmp;
+ iCT1 = TypeToInteger(aCT1);
+ iCT2 = TypeToInteger(aCT2);
+ //
+ if (iCT1 == iCT2) {
+ if (iCT1 != 0) {
+ //compute deflection
+ Standard_Real aC1, aC2;
+ //
+ aC2 = CurveDeflection(myCurve2, myRange2);
+ aC1 = (aC2 > Precision::Confusion()) ?
+ CurveDeflection(myCurve1, myRange1) : 1.;
+ //
+ if (aC1 < aC2) {
+ --iCT1;
+ }
}
- return;
}
//
- bIsSameCurves=IsSameCurves();
- if (bIsSameCurves) {
- aCommonPrt.SetType(TopAbs_EDGE);
- aCommonPrt.SetRange1 (myTminFrom, myTmaxFrom);
- aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
- mySeqOfCommonPrts.Append(aCommonPrt);
- myIsDone=Standard_True;
- return;
+ if (iCT1 < iCT2) {
+ TopoDS_Edge tmpE = myEdge1;
+ myEdge1 = myEdge2;
+ myEdge2 = tmpE;
+ //
+ BRepAdaptor_Curve tmpC = myCurve1;
+ myCurve1 = myCurve2;
+ myCurve2 = tmpC;
+ //
+ IntTools_Range tmpR = myRange1;
+ myRange1 = myRange2;
+ myRange2 = tmpR;
+ //
+ mySwap = Standard_True;
}
//
- IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo);
- anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom);
- anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo);
+ Standard_Real aTolAdd = Precision::Confusion() / 2.;
+ myTol1 = myCurve1.Tolerance() + aTolAdd;
+ myTol2 = myCurve2.Tolerance() + aTolAdd;
+ myTol = myTol1 + myTol2;
//
- anIntersector.Perform();
- if(!anIntersector.IsDone()) {
- myIsDone = Standard_False;
+ if (iCT1 != 0 || iCT2 != 0) {
+ Standard_Real f, l, aTM;
+ //
+ myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
+ myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
+ //
+ myResCoeff1 = ResolutionCoeff(myCurve1, myRange1);
+ myResCoeff2 = ResolutionCoeff(myCurve2, myRange2);
+ //
+ myRes1 = Resolution(myCurve1.Curve().Curve(), myCurve1.GetType(), myResCoeff1, myTol1);
+ myRes2 = Resolution(myCurve2.Curve().Curve(), myCurve2.GetType(), myResCoeff2, myTol2);
+ //
+ myPTol1 = 5.e-13;
+ aTM = Max(fabs(myRange1.First()), fabs(myRange1.Last()));
+ if (aTM > 999.) {
+ myPTol1 = 5.e-16 * aTM;
+ }
+ //
+ myPTol2 = 5.e-13;
+ aTM = Max(fabs(myRange2.First()), fabs(myRange2.Last()));
+ if (aTM > 999.) {
+ myPTol2 = 5.e-16 * aTM;
+ }
+ }
+}
+
+//=======================================================================
+//function : Perform
+//purpose :
+//=======================================================================
+void IntTools_EdgeEdge::Perform()
+{
+ //1. Check data
+ CheckData();
+ if (myErrorStatus) {
return;
}
//
- aPC=Precision::PConfusion();
- aCommonPrt.SetEdge1(myCFrom.Edge());
- aCommonPrt.SetEdge2(myCTo.Edge());
+ //2. Prepare Data
+ Prepare();
//
- 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)<aPC) && ((myTmaxFrom - aT2)<aPC)) {
- aCommonPrt.SetAllNullFlag(Standard_True);
- }
- mySeqOfCommonPrts.Append(aCommonPrt);
- }
+ //3.1. Check Line/Line case
+ if (myCurve1.GetType() == GeomAbs_Line &&
+ myCurve2.GetType() == GeomAbs_Line) {
+ ComputeLineLine();
+ return;
}
//
- aNbCommonPrts=mySeqOfCommonPrts.Length();
- for (i=1; i<=aNbCommonPrts; ++i) {
- IntTools_CommonPrt& aCmnPrt=mySeqOfCommonPrts.ChangeValue(i);
- pri=FindRangeOnCurve2 (aCmnPrt);
- if (pri) {
- myErrorStatus=10;
+ if (myQuickCoincidenceCheck) {
+ if (IsCoincident()) {
+ Standard_Real aT11, aT12, aT21, aT22;
+ //
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ AddSolution(aT11, aT12, aT21, aT22, TopAbs_EDGE);
return;
}
}
//
- // Line Circle's Common Parts treatement
- if ((aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Circle) ||
- (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Line) ||
- (aCTFrom==GeomAbs_Ellipse && aCTTo==GeomAbs_Ellipse) ||
- (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Circle)) {
- for (i=1; i<=aNbCommonPrts; i++) {
- IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
- TopAbs_ShapeEnum aType=aCP.Type();
- Standard_Boolean bIsTouch;
- Standard_Real aTx1, aTx2;
- //
- if ((aType==TopAbs_EDGE) && !aCommonPrt.AllNullFlag()) {
- bIsTouch=CheckTouch (aCP, aTx1, aTx2);
- if (bIsTouch) {
- aCP.SetType(TopAbs_VERTEX);
- aCP.SetVertexParameter1(aTx1);
- aCP.SetRange1 (aTx1, aTx1);
- IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
- aRange2.SetFirst(aTx2);
- aRange2.SetLast (aTx2);
- }
- }
- //
- if (aType==TopAbs_VERTEX) {
- if(aCTFrom==GeomAbs_Line || aCTTo==GeomAbs_Line) {
- bIsTouch=CheckTouchVertex (aCP, aTx1, aTx2);
- if (bIsTouch) {
- aCP.SetVertexParameter1(aTx1);
- aCP.SetRange1 (aTx1, aTx1);
- IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
- aRange2.SetFirst(aTx2);
- aRange2.SetLast (aTx2);
- }
- }
- }
- }
- }
+ IntTools_SequenceOfRanges aRanges1, aRanges2;
//
- if (myOrder) {
- TopoDS_Edge aTmp;
- aTmp=myEdge1;
- myEdge1=myEdge2;
- myEdge2=aTmp;
- }
+ //3.2. Find ranges containig solutions
+ Standard_Boolean bSplit2;
+ FindSolutions(aRanges1, aRanges2, bSplit2);
//
- myIsDone=Standard_True;
-}
+ //4. Merge solutions and save common parts
+ MergeSolutions(aRanges1, aRanges2, bSplit2);
+}
//=======================================================================
-//function : CheckData
+//function : IsCoincident
//purpose :
//=======================================================================
- void IntTools_EdgeEdge::CheckData()
+Standard_Boolean IntTools_EdgeEdge::IsCoincident()
{
- if (BRep_Tool::Degenerated(myEdge1)) {
- myErrorStatus=2;
- }
- if (!BRep_Tool::IsGeometric(myEdge1)) {
- myErrorStatus=3;
- }
- if (BRep_Tool::Degenerated(myEdge2)) {
- myErrorStatus=4;
+ Standard_Integer i, iCnt, aNbSeg, aNbP2;
+ Standard_Real dT, aT1, aCoeff, aTresh, aD;
+ Standard_Real aT11, aT12, aT21, aT22;
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ gp_Pnt aP1;
+ //
+ aTresh=0.5;
+ aNbSeg=23;
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ //
+ aProjPC.Init(myGeom2, aT21, aT22);
+ //
+ dT=(aT12-aT11)/aNbSeg;
+ //
+ iCnt=0;
+ for(i=0; i <= aNbSeg; ++i) {
+ aT1 = aT11+i*dT;
+ myGeom1->D0(aT1, aP1);
+ //
+ aProjPC.Perform(aP1);
+ aNbP2=aProjPC.NbPoints();
+ if (!aNbP2) {
+ continue;
+ }
+ //
+ aD=aProjPC.LowerDistance();
+ if(aD < myTol) {
+ ++iCnt;
+ }
}
- if (!BRep_Tool::IsGeometric(myEdge2)) {
- myErrorStatus=5;
- }
+ //
+ aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
+ return aCoeff > aTresh;
}
//=======================================================================
-//function : Prepare
+//function : FindSolutions
//purpose :
//=======================================================================
- void IntTools_EdgeEdge::Prepare()
+void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
+ IntTools_SequenceOfRanges& theRanges2,
+ Standard_Boolean& bSplit2)
{
- Standard_Real aLE1, aLE2, aT1, aT2, aTol1, aTol2;
- GeomAdaptor_Curve aGAC;
- GeomAbs_CurveType aCT1, aCT2;
+ Standard_Boolean bIsClosed2;
+ Standard_Real aT11, aT12, aT21, aT22;
+ Bnd_Box aB2;
//
- // 1.Prepare Curves' data
- const Handle(Geom_Curve)& aC1=BRep_Tool::Curve (myEdge1, aT1, aT2);
- aT1=myRange1.First();
- aT2=myRange1.Last();
- aGAC.Load(aC1, myRange1.First(), myRange1.Last());
- aLE1=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
- //
- const Handle(Geom_Curve)& aC2=BRep_Tool::Curve (myEdge2, aT1, aT2);
- aT1=myRange2.First();
- aT2=myRange2.Last();
- aGAC.Load(aC2, aT1, aT2);
- aLE2=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
- //
- myOrder=Standard_False;
- if (aLE1 <= aLE2) {
- myCFrom.Initialize(myEdge1);
- myCTo .Initialize(myEdge2);
- myTolFrom=myTol1;
- myTolTo=myTol2;
- myTminFrom=myRange1.First();
- myTmaxFrom=myRange1.Last ();
- myTminTo =myRange2.First();
- myTmaxTo =myRange2.Last ();
- }
- else {
- myCFrom.Initialize(myEdge2);
- myCTo .Initialize(myEdge1);
- myTolFrom=myTol2;
- myTolTo=myTol1;
- myTminFrom=myRange2.First();
- myTmaxFrom=myRange2.Last ();
- myTminTo =myRange1.First();
- myTmaxTo =myRange1.Last ();
+ bSplit2 = Standard_False;
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ //
+ bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
+ //
+ if (bIsClosed2) {
+ Bnd_Box aB1;
+ BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
//
- myOrder=Standard_True; // revesed order
+ gp_Pnt aP = myGeom2->Value(aT21);
+ bIsClosed2 = !aB1.IsOut(aP);
}
//
- // 2.Prepare myCriteria
- aCT1=myCFrom.GetType();
- aCT2=myCTo.GetType();
- //
- aTol1=myTol1;
- if(aCT1==GeomAbs_BSplineCurve|| aCT1==GeomAbs_BezierCurve){
- aTol1=1.2*myTol1;
+ if (!bIsClosed2) {
+ BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+ FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
+ return;
}
- aTol2=myTol2;
- if(aCT2==GeomAbs_BSplineCurve|| aCT2==GeomAbs_BezierCurve){
- aTol2=1.2*myTol2;
+ //
+ if (!CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1)) {
+ theRanges1.Append(myRange1);
+ theRanges2.Append(myRange2);
+ return;
}
- myCriteria=aTol1+aTol2;
-}
-//=======================================================================
-//function : IsProjectable
-//purpose :
-//=======================================================================
- Standard_Integer IntTools_EdgeEdge::IsProjectable(const Standard_Real t) const
-{
- Standard_Integer aNbProj;
- Standard_Real f, l;
- gp_Pnt aPFrom;
-
- GeomAPI_ProjectPointOnCurve aProjector;
- const TopoDS_Edge& aEFrom=myCFrom.Edge();
- Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
- aCurveFrom->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;
+ //
+ Standard_Integer i, j, aNb1, aNb2;
+ IntTools_SequenceOfRanges aSegments1, aSegments2;
+ //
+ aNb1 = IsClosed(myGeom1, aT11, aT12, myTol1, myRes1) ? 2 : 1;
+ aNb2 = 2;
+ //
+ aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, aNb1, aSegments1);
+ aNb2 = SplitRangeOnSegments(aT21, aT22, myRes2, aNb2, aSegments2);
+ //
+ for (i = 1; i <= aNb1; ++i) {
+ const IntTools_Range& aR1 = aSegments1(i);
+ for (j = 1; j <= aNb2; ++j) {
+ const IntTools_Range& aR2 = aSegments2(j);
+ BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
+ FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
}
}
- return aNbProj;
+ //
+ bSplit2 = aNb2 > 1;
}
//=======================================================================
-//function : DistanceFunction
+//function : FindSolutions
//purpose :
//=======================================================================
- Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const
+void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
+ const IntTools_Range& theR2,
+ const Bnd_Box& theBox2,
+ IntTools_SequenceOfRanges& theRanges1,
+ IntTools_SequenceOfRanges& theRanges2)
{
- 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;
+ Standard_Boolean bOut, bStop, bThin;
+ Standard_Real aT11, aT12, aT21, aT22;
+ Standard_Real aTB11, aTB12, aTB21, aTB22;
+ Standard_Real aSmallStep1, aSmallStep2;
+ Standard_Integer iCom;
+ Bnd_Box aB1, aB2;
+ //
+ theR1.Range(aT11, aT12);
+ theR2.Range(aT21, aT22);
+ //
+ aB2 = theBox2;
+ //
+ bThin = Standard_False;
+ bStop = Standard_False;
+ iCom = 1;
+ //
+ do {
+ aTB11 = aT11;
+ aTB12 = aT12;
+ aTB21 = aT21;
+ aTB22 = aT22;
+ //
+ //1. Build box for first edge and find parameters
+ // of the second one in that box
+ BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
+ bOut = aB1.IsOut(aB2);
+ if (bOut) {
+ break;
+ }
+ //
+ bThin = ((aT12 - aT11) < myRes1) ||
+ (aB1.IsXThin(myTol) && aB1.IsYThin(myTol) && aB1.IsZThin(myTol));
+ //
+ bOut = !FindParameters(myCurve2, aTB21, aTB22, myTol2, myRes2, myPTol2,
+ myResCoeff2, aB1, aT21, aT22);
+ if (bOut || bThin) {
+ break;
+ }
+ //
+ //2. Build box for second edge and find parameters
+ // of the first one in that box
+ BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+ bOut = aB1.IsOut(aB2);
+ if (bOut) {
+ break;
+ }
+ //
+ bThin = ((aT22 - aT21) < myRes2) ||
+ (aB2.IsXThin(myTol) && aB2.IsYThin(myTol) && aB2.IsZThin(myTol));
+ //
+ bOut = !FindParameters(myCurve1, aTB11, aTB12, myTol1, myRes1, myPTol1,
+ myResCoeff1, aB2, aT11, aT12);
+ //
+ if (bOut || bThin) {
+ break;
+ }
+ //
+ //3. Check if it makes sense to continue
+ aSmallStep1 = (aTB12 - aTB11) / 250.;
+ aSmallStep2 = (aTB22 - aTB21) / 250.;
+ //
+ if (aSmallStep1 < myRes1) {
+ aSmallStep1 = myRes1;
+ }
+ if (aSmallStep2 < myRes2) {
+ aSmallStep2 = myRes2;
+ }
+ //
+ if (((aT11 - aTB11) < aSmallStep1) && ((aTB12 - aT12) < aSmallStep1) &&
+ ((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
+ bStop = Standard_True;
+ }
+ //
+ } while (!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;
}
}
-
- 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;
+ //
+ if (bThin) {
+ if (iCom != 0) {
+ //check intermediate points
+ Standard_Boolean bSol;
+ Standard_Real aT1;
+ gp_Pnt aP1;
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ //
+ aT1 = (aT11 + aT12) * .5;
+ myGeom1->D0(aT1, aP1);
+ //
+ aProjPC.Init(myGeom2, aT21, aT22);
+ aProjPC.Perform(aP1);
+ //
+ if (aProjPC.NbPoints()) {
+ bSol = aProjPC.LowerDistance() <= myTol;
+ }
+ else {
+ Standard_Real aT2;
+ gp_Pnt aP2;
+ //
+ aT2 = (aT21 + aT22) * .5;
+ myGeom2->D0(aT2, aP2);
+ //
+ bSol = aP1.IsEqual(aP2, myTol);
}
-
- aCurveFrom->D0 (tt, aPFrom);
- aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
- aProjector.Perform(aPFrom);
- aNbPoints=aProjector.NbPoints();
- if (aNbPoints) {
- break;
+ //
+ if (!bSol) {
+ return;
}
}
+ //add common part
+ IntTools_Range aR1(aT11, aT12), aR2(aT21, aT22);
+ //
+ theRanges1.Append(aR1);
+ theRanges2.Append(aR2);
+ return;
}
-
-
- if (!aNbPoints) {
- // Can't find projection.
- myErrorStatus=11;
- aD=100.;
- return aD;
+ //
+ if (!IsIntersection(aT11, aT12, aT21, aT22)) {
+ return;
}
-
- aD=aProjector.LowerDistance();
//
- aD=aD-myCriteria;
- return aD;
+ //split ranges on segments and repeat
+ Standard_Integer i, aNb1;
+ IntTools_SequenceOfRanges aSegments1;
+ //
+ IntTools_Range aR2(aT21, aT22);
+ BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+ //
+ aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
+ for (i = 1; i <= aNb1; ++i) {
+ const IntTools_Range& aR1 = aSegments1(i);
+ FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
+ }
}
//=======================================================================
-//function : DerivativeFunction
+//function : FindParameters
//purpose :
//=======================================================================
- Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2)
+Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ const Standard_Real theRes,
+ const Standard_Real thePTol,
+ const Standard_Real theResCoeff,
+ const Bnd_Box& theCBox,
+ Standard_Real& aTB1,
+ Standard_Real& aTB2)
{
- 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;
+ Standard_Boolean bRet;
+ Standard_Integer aC, i, k;
+ Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
+ Standard_Real aDist, aDistP, aDistTol;
+ gp_Pnt aP;
+ Bnd_Box aCBx;
+ //
+ bRet = Standard_False;
+ aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
+ aDt = theRes;
+ aDistP = 0.;
+ aDistTol = 1e-9;
+ aCBx = theCBox;
+ aCBx.Enlarge(theTol);
+ //
+ const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
+ const GeomAbs_CurveType aCurveType = theBAC.GetType();
+ //
+ 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) {
+ theBAC.D0(aTB, aP);
+ aDist = PointBoxDistance(theCBox, aP);
+ if (aDist > theTol) {
+ if (fabs(aDist - aDistP) < aDistTol) {
+ aDt = Resolution(aCurve, aCurveType, theResCoeff, (++k)*aDist);
+ } else {
+ k = 0;
+ aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist);
+ }
+ aTB += aC*aDt;
+ } else {
+ bRet = Standard_True;
+ break;
+ }
+ aDistP = aDist;
+ }
+ //
+ if (!bRet) {
+ if (!i) {
+ //edge is out of the box;
+ return bRet;
+ } else {
+ bRet = !bRet;
+ aTB = aTB1;
+ aDt = aT2 - aTB1;
+ }
+ }
+ //
+ 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) > thePTol) {
+ aTB = aTOut + aDiff*aCf;
+ theBAC.D0(aTB, aP);
+ if (aCBx.IsOut(aP)) {
+ aTOut = aTB;
+ } else {
+ aTIn = aTB;
+ }
+ aDiff = aTIn - aTOut;
+ }
+ }
+ if (!i) {
+ aTB1 = aTB;
+ } else {
+ aTB2 = aTB;
+ }
+ }
+ return bRet;
}
-
//=======================================================================
-//function : FindSimpleRoot
-//purpose : [private]
+//function : MergeSolutions
+//purpose :
//=======================================================================
- Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP,
- const Standard_Real tA,
- const Standard_Real tB,
- const Standard_Real fA)
+void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1,
+ const IntTools_SequenceOfRanges& theRanges2,
+ const Standard_Boolean bSplit2)
{
- 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));
-
- while (1) {
- 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;
+ Standard_Integer aNbCP = theRanges1.Length();
+ if (aNbCP == 0) {
+ return;
+ }
+ //
+ IntTools_Range aRi1, aRi2, aRj1, aRj2;
+ Standard_Boolean bCond;
+ Standard_Integer i, j;
+ TopAbs_ShapeEnum aType;
+ Standard_Real aT11, aT12, aT21, aT22;
+ Standard_Real aTi11, aTi12, aTi21, aTi22;
+ Standard_Real aTj11, aTj12, aTj21, aTj22;
+ Standard_Real aRes1, aRes2, dTR1, dTR2;
+ BOPCol_MapOfInteger aMI;
+ //
+ aRes1 = Resolution(myCurve1.Curve().Curve(),
+ myCurve1.GetType(), myResCoeff1, myTol);
+ aRes2 = Resolution(myCurve2.Curve().Curve(),
+ myCurve2.GetType(), myResCoeff2, myTol);
+ //
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ dTR1 = 20*aRes1;
+ dTR2 = 20*aRes2;
+ aType = TopAbs_VERTEX;
+ //
+ for (i = 1; i <= aNbCP;) {
+ if (aMI.Contains(i)) {
+ ++i;
+ continue;
}
-
- if( step == stepcheck ) {
- if( Abs(value - y) <= 1.e-9 ) {
- return x0;
+ //
+ aRi1 = theRanges1(i);
+ aRi2 = theRanges2(i);
+ //
+ aRi1.Range(aTi11, aTi12);
+ aRi2.Range(aTi21, aTi22);
+ //
+ aMI.Add(i);
+ //
+ for (j = i+1; j <= aNbCP; ++j) {
+ if (aMI.Contains(j)) {
+ continue;
}
- else {
- value = y;
- step = 1;
+ //
+ aRj1 = theRanges1(j);
+ aRj2 = theRanges2(j);
+ //
+ aRj1.Range(aTj11, aTj12);
+ aRj2.Range(aTj21, aTj22);
+ //
+ bCond = (fabs(aTi12 - aTj11) < dTR1) ||
+ (bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
+ if (bCond && bSplit2) {
+ bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) -
+ ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
+ }
+ //
+ if (bCond) {
+ aTi11 = Min(aTi11, aTj11);
+ aTi12 = Max(aTi12, aTj12);
+ aTi21 = Min(aTi21, aTj21);
+ aTi22 = Max(aTi22, aTj22);
+ aMI.Add(j);
+ }
+ else if (!bSplit2) {
+ i = j;
+ break;
}
}
-
- if( step == steplimit ) {
- return x0;
+ //
+ if (((fabs(aT11 - aTi11) < myRes1) && (fabs(aT12 - aTi12) < myRes1)) ||
+ ((fabs(aT21 - aTi21) < myRes2) && (fabs(aT22 - aTi22) < myRes2))) {
+ aType = TopAbs_EDGE;
+ myCommonParts.Clear();
}
-
- s=y*r;
-
- if (s<0.) {
- b=x0;
- continue;
+ //
+ AddSolution(aTi11, aTi12, aTi21, aTi22, aType);
+ if (aType == TopAbs_EDGE) {
+ break;
}
-
- if (s>0.) {
- a=x0; r=y;
+ //
+ if (bSplit2) {
+ ++i;
}
-
- step++;
-
}
}
//=======================================================================
-//function : FindRangeOnCurve2
+//function : AddSolution
//purpose :
//=======================================================================
-Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt& aCommonPrt)
+void IntTools_EdgeEdge::AddSolution(const Standard_Real aT11,
+ const Standard_Real aT12,
+ const Standard_Real aT21,
+ const Standard_Real aT22,
+ const TopAbs_ShapeEnum theType)
{
- Standard_Integer pri;
+ IntTools_CommonPrt aCPart;
//
- pri=0;
- if (aCommonPrt.AllNullFlag()) {
- aCommonPrt.SetType(TopAbs_EDGE);
- aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
- return pri;
+ 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);
}
//
- 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);
+ 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);
+}
- const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
- Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
+//=======================================================================
+//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_Integer i, aNbS, iErr;
+ Standard_Real aDMin, aD, aRes1, aSolCriteria, aTouchCriteria;
+ Standard_Real aT1A, aT1B, aT1Min, aT2Min;
+ Standard_Real aT1Im, aT2Im, aT1Touch;
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ IntTools_SequenceOfRanges aRanges;
+ Standard_Boolean bTouch;
//
- // af2, aPf2
- aCurveFrom->D0 (af1, aPf1);
- pri=GetParameterOnCurve2 (af1, af2);
- if (pri) {
- return 1;
- }
- aCurveTo->D0(af2, aPf2);
+ aDMin = Precision::Infinite();
+ aSolCriteria = 5.e-16;
+ aTouchCriteria = 5.e-13;
+ bTouch = Standard_False;
+ aT1Touch = aT11;
//
- // al2, aPl2
- aCurveFrom->D0 (al1, aPl1);
- pri=GetParameterOnCurve2 (al1, al2);
- if (pri) {
- return 1;
- }
- aCurveTo->D0(al2, aPl2);
+ aRes1 = Resolution(myCurve1.Curve().Curve(),
+ myCurve1.GetType(), myResCoeff1, myTol);
+ aNbS = 10;
+ aNbS = SplitRangeOnSegments(aT11, aT12, 3*aRes1, aNbS, aRanges);
//
- // am2, aPm2
- aCurveFrom->D0 (am1, aPm1);
- pri=GetParameterOnCurve2 (am1, am2);
- if (pri) {
- return 1;
+ aProjPC.Init(myGeom2, aT21, aT22);
+ //
+ aT1 = (aT11 + aT12) * 0.5;
+ iErr = DistPC(aT1, myGeom1, aSolCriteria, aProjPC, aD, aT2, -1);
+ if (iErr == 1) {
+ aT2 = (aT21 + aT22) * 0.5;
}
- 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;
+ aT1Im = aT1;
+ aT2Im = aT2;
+ //
+ for (i = 1; i <= aNbS; ++i) {
+ const IntTools_Range& aR1 = aRanges(i);
+ aR1.Range(aT1A, aT1B);
+ //
+ aD = myTol;
+ iErr = FindDistPC(aT1A, aT1B, myGeom1, aSolCriteria, myPTol1,
+ aProjPC, aD, aT1Min, aT2Min, Standard_False);
+ if (iErr != 1) {
+ if (aD < aDMin) {
+ aT1 = aT1Min;
+ aT2 = aT2Min;
+ aDMin = aD;
+ }
+ //
+ if (aD < aTouchCriteria) {
+ if (bTouch) {
+ aT1A = (aT1Touch + aT1Min) * 0.5;
+ iErr = DistPC(aT1A, myGeom1, aTouchCriteria,
+ aProjPC, aD, aT2Min, -1);
+ if (aD > aTouchCriteria) {
+ aT1 = aT1Im;
+ aT2 = aT2Im;
+ break;
+ }
+ }
+ else {
+ aT1Touch = aT1Min;
+ bTouch = Standard_True;
+ }
+ }
+ }
}
+}
- if((Abs(af2 - myTminTo) < Precision::PConfusion()) &&
- (Abs(al2 - myTmaxTo) < Precision::PConfusion())) {
- aCommonPrt.SetAllNullFlag(Standard_True);
- }
+//=======================================================================
+//function : ComputeLineLine
+//purpose :
+//=======================================================================
+void IntTools_EdgeEdge::ComputeLineLine()
+{
+ Standard_Boolean IsParallel, IsCoincide;
+ 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;
+ 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);
//
- Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2;
- Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1m1, dm1l1, df1l1;
- Standard_Real tV1, tV2;
+ aCommonPrt.SetEdge1(myEdge1);
+ aCommonPrt.SetEdge2(myEdge2);
//
- // parametric differences for C2
- Df2m2=fabs(af2-am2);
- Dm2l2=fabs(am2-al2);
- Df2l2=fabs(af2-al2);
+ aCos = aD1.Dot(aD2);
+ aAng = (aCos >= 0.) ? 2.*(1. - aCos) : 2.*(1. + aCos);
//
- // geometric distances for C2
- df2m2=aPf2.Distance(aPm2);
- dm2l2=aPm2.Distance(aPl2);
- df2l2=aPf2.Distance(aPl2);
-
- aVFlag1=(Df2m2<myEpsT && Dm2l2<myEpsT);
- aVFlag2=(df2m2 < myCriteria && dm2l2 < myCriteria);
-
+ if(aAng <= Precision::Angular()) {
+ IsParallel = Standard_True;
+ if(aL1.SquareDistance(aL2.Location()) <= aTol) {
+ IsCoincide = Standard_True;
+ aP11 = ElCLib::Value(aT11, aL1);
+ aP12 = ElCLib::Value(aT12, aL1);
+ }
+ }
+ else {
+ aP11 = ElCLib::Value(aT11, aL1);
+ aP12 = ElCLib::Value(aT12, aL1);
+ if(aL2.SquareDistance(aP11) <= aTol && aL2.SquareDistance(aP12) <= aTol) {
+ IsCoincide = Standard_True;
+ }
+ }
//
- // Two perpendicular lines => 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);
+ if (IsCoincide) {
+ Standard_Real t21, t22;
+ //
+ 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;
+ }
+ //
+ if(t21 >= aT21) {
+ if(t22 <= aT22) {
+ aCommonPrt.SetRange1(aT11, aT12);
+ aCommonPrt.SetAllNullFlag(Standard_True);
+ aCommonPrt.AppendRange2(t21, t22);
+ }
+ else {
+ aCommonPrt.SetRange1(aT11, aT12 - (t22 - aT22));
+ aCommonPrt.AppendRange2(t21, aT22);
+ }
+ }
+ else {
+ aCommonPrt.SetRange1(aT11 + (aT21 - t21), aT12);
+ aCommonPrt.AppendRange2(aT21, t22);
}
- return 0;
+ aCommonPrt.SetType(TopAbs_EDGE);
+ myCommonParts.Append(aCommonPrt);
+ return;
}
//
- // geometric distances for C1
- df1m1=aPf1.Distance(aPm1);
- dm1l1=aPm1.Distance(aPl1);
- df1l1=aPf1.Distance(aPl1);
- //
- // if geometric distances between boundaries is less than myCriteria
- // we have VERTEX
- aGeomFlag1=(df1l1 < myCriteria);
- aGeomFlag2=(df2l2 < myCriteria);
- if (aGeomFlag1 && aGeomFlag2) {
- aCommonPrt.SetType(TopAbs_VERTEX);
-
- tV2=.5*(af2+al2);
- aCommonPrt.SetVertexParameter2(tV2);
- aCommonPrt.AppendRange2 (af2, al2);
-
- tV1=.5*(af1+al1);
- aCommonPrt.SetVertexParameter1(tV1);
- aCommonPrt.SetRange1 (af1, al1);
- return 0;
+ if (IsParallel) {
+ return;
}
//
- // ???
- 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;
+ {
+ TopoDS_Iterator aIt1, aIt2;
+ aIt1.Initialize(myEdge1);
+ for (; aIt1.More(); aIt1.Next()) {
+ const TopoDS_Shape& aV1 = aIt1.Value();
+ aIt2.Initialize(myEdge2);
+ for (; aIt2.More(); aIt2.Next()) {
+ const TopoDS_Shape& aV2 = aIt2.Value();
+ if (aV2.IsSame(aV1)) {
+ return;
+ }
+ }
}
}
//
- 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;
- }
+ 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;
}
- else {
- // Passed through 0
- aCommonPrt.SetType(TopAbs_EDGE);
- aCommonPrt.AppendRange2 (myTminTo, af2);
- aCommonPrt.AppendRange2 (al2, myTmaxTo);
- return 0;
+ //
+ gp_Pnt aP2(ElCLib::Value(aT2, aL2));
+ aT1 = (gp_Vec(O1, aP2)).Dot(aD1);
+ //
+ if(aT1 < aT11 || aT1 > aT12) {
+ return;
}
-
- 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;
+ //
+ gp_Pnt aP1(ElCLib::Value(aT1, aL1));
+ Standard_Real aDist = aP1.SquareDistance(aP2);
+ //
+ if (aDist > aTol) {
+ return;
}
-
-
-
- aCommonPrt.SetType(TopAbs_EDGE);
- aCommonPrt.AppendRange2 (af2, al2);
- return 0;
+ //
+ // compute correct range on the edges
+ Standard_Real anAngle, aDt1, aDt2;
+ //
+ anAngle = aD1.Angle(aD2);
+ //
+ aDt1 = IntTools_Tools::ComputeIntRange(myTol1, myTol2, anAngle);
+ aDt2 = IntTools_Tools::ComputeIntRange(myTol2, myTol1, anAngle);
+ //
+ aCommonPrt.SetRange1(aT1 - aDt1, aT1 + aDt1);
+ aCommonPrt.AppendRange2(aT2 - aDt2, aT2 + aDt2);
+ aCommonPrt.SetType(TopAbs_VERTEX);
+ aCommonPrt.SetVertexParameter1(aT1);
+ aCommonPrt.SetVertexParameter2(aT2);
+ myCommonParts.Append(aCommonPrt);
}
-
+
//=======================================================================
//function : IsIntersection
//purpose :
//=======================================================================
- void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta,
- const Standard_Real tb)
+Standard_Boolean IntTools_EdgeEdge::IsIntersection(const Standard_Real aT11,
+ const Standard_Real aT12,
+ const Standard_Real aT21,
+ const Standard_Real aT22)
{
- Standard_Integer i, aNb, pri;
- Standard_Real t, f;
- GeomAbs_CurveType aCT1, aCT2;
- IntTools_CArray1OfReal anArgs, aFunc;
- //
- aCT1=myCFrom.GetType();
- aCT2=myCTo.GetType();
- if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) {
- const Handle(Geom_Curve)& Curve1=BRep_Tool::Curve (myCFrom.Edge(), t, f);
- const Handle(Geom_Curve)& Curve2=BRep_Tool::Curve (myCTo.Edge() , t, f);
-
- GeomAdaptor_Curve TheCurve1 (Curve1);
- GeomAdaptor_Curve TheCurve2 (Curve2);
- Extrema_ExtCC anExtrema (TheCurve1, TheCurve2);
-
- if(anExtrema.IsDone() && anExtrema.IsParallel()) {
- myParallel = Standard_True;
- return;
+ 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;
//
- 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();
+ 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;
+ }
//
- Extrema_ExtElC aExtElC(aCirc1, aCirc2);
+ Standard_Real anAngleCriteria;
+ Standard_Real anAngle1, anAngle2;
//
- 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 (aD2<aCriteria2) {
- aExtElC.Points(i, aPC1, aPC2);
- aT1=aPC1.Parameter();
- if (aT1>ta && aT1<tb) {
- myPar1=aT1;
- myParallel=Standard_False;
- return;
- }
- }
- }
- }
+ 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);
}
- }
- //
- // Prepare values of arguments for the interval [ta, tb]
- pri=IntTools::PrepareArgs (myCFrom, tb, ta, myDiscret, myDeflection, anArgs);
- aNb=anArgs.Length();
-
- aFunc.Resize(aNb);
- for (i=0; i<aNb; i++) {
- t=anArgs(i);
- f=DistanceFunction(t);
- if (fabs(f) < myEpsNull) {
- f=0.;
+ //
+ if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) ||
+ ((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) {
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ Standard_Integer iErr;
+ Standard_Real aD, aT1Min, aT2Min;
+ //
+ aD = Precision::Infinite();
+ aProjPC.Init(myGeom2, aT21, aT22);
+ iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1,
+ aProjPC, aD, aT1Min, aT2Min, Standard_False);
+ bRet = (iErr == 2);
}
- aFunc(i)=f;
}
- FindDerivativeRoot(anArgs, aFunc);
- return ;
+ return bRet;
}
//=======================================================================
-//function : FindDerivativeRoot
+//function : CheckCoincidence
//purpose :
//=======================================================================
- void IntTools_EdgeEdge::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
- const IntTools_CArray1OfReal& f)
+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 theCurveRes1)
{
- Standard_Integer i, n, k;
- Standard_Real fr, tr, anEpsNull;
- IntTools_CArray1OfReal fd;
- TColStd_SequenceOfReal aTSeq, aFSeq;
-
- anEpsNull=100.*myEpsNull;
- myPar1=0.;
- myParallel=Standard_True;
-
- n=t.Length();
- fd.Resize(n+1);
- //
- // Table of derivatives
- fd(0)=(f(1)-f(0))/(t(1)-t(0));
- if (fabs(fd(0)) < anEpsNull) {
- fd(0)=0.;
- }
- k=n-1;
- for (i=1; i<k; i++) {
- fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
- if (fabs(fd(i)) < anEpsNull) {
- fd(i)=0.;
+ Standard_Integer iErr, aNb, aNb1, i;
+ Standard_Real aT1A, aT1B, aT1max, aT2max, aDmax;
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ IntTools_SequenceOfRanges aRanges;
+ //
+ iErr = 0;
+ aDmax = -1.;
+ aProjPC.Init(myGeom2, aT21, aT22);
+ //
+ // 1. Express evaluation
+ aNb = 10; // Number of intervals on the curve #1
+ aNb1 = SplitRangeOnSegments(aT11, aT12, theCurveRes1, aNb, aRanges);
+ for (i = 1; i < aNb1; ++i) {
+ const IntTools_Range& aR1 = aRanges(i);
+ aR1.Range(aT1A, aT1B);
+ //
+ iErr = DistPC(aT1B, myGeom1, theCriteria, aProjPC, aDmax, aT2max);
+ if (iErr) {
+ return iErr;
}
}
- fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
- if (fabs(fd(n-1)) < anEpsNull) {
- fd(n-1)=0.;
+ //
+ // if the ranges in aRanges are less than theCurveRes1,
+ // there is no need to do step 2 (deep evaluation)
+ if (aNb1 < aNb) {
+ return iErr;
}
//
- // Finding the range where the derivatives have different signs
- // for neighbouring points
- for (i=1; i<n; i++) {
- Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
- Standard_Boolean bF1, bF2;
- t1 =t(i-1);
- t2 =t(i);
- fd1=fd(i-1);
- fd2=fd(i);
-
- fabsfd1=fabs(fd1);
- bF1=fabsfd1 < myEpsNull;
-
- fabsfd2=fabs(fd2);
- bF2=fabsfd2 < myEpsNull;
-
- //aa
- if (fd1*fd2 < 0.) {
- tr=FindSimpleRoot(2, t1, t2, fd1);
- fr=DistanceFunction(tr);
- myPar1=tr;
- myParallel=Standard_False;
- break;
- }
-
- if (!bF1 && bF2) {
- tr=t2;
- fr=fd2;
- myPar1=tr;
- myParallel=Standard_False;
- break;
- }
-
- if (bF1 && !bF2) {
- tr=t1;
- fr=fd1;
- myPar1=tr;
- myParallel=Standard_False;
- break;
+ // 2. Deep evaluation
+ for (i = 2; i < aNb1; ++i) {
+ const IntTools_Range& aR1 = aRanges(i);
+ aR1.Range(aT1A, aT1B);
+ //
+ iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveRes1,
+ 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 : GetParameterOnCurve2
+//function : FindDistPC
//purpose :
//=======================================================================
- Standard_Integer IntTools_EdgeEdge::GetParameterOnCurve2(const Standard_Real aT1,
- Standard_Real& aT2) const
+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_Real f, l;
- Standard_Integer j, found, aNbPoints;
- const TopoDS_Edge& anEdgeTo=myCTo.Edge();
- const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
-
- Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
- Handle(Geom_Curve)aCurveTo =BRep_Tool::Curve (anEdgeTo, f, l);
-
- gp_Pnt aP1;
- aCurveFrom->D0 (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;
+ Standard_Integer iErr, iC;
+ Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L;
+ //
+ iC = bMaxDist ? 1 : -1;
+ iErr = 0;
+ aT1max = aT2max = 0.; // silence GCC warning
+ //
+ 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;
}
-
- for (j=1; j<=aNbPoints; j++) {
- aT2=aProjector.Parameter(j);
- f=aProjector.Distance(j);
+ //
+ iErr = DistPC(aB, theC1, theCriteria, theProjPC,
+ aYL, aT2L, aDmax, aT1max, aT2max, iC);
+ if (iErr == 2) {
+ return iErr;
}
-
- aT2=aProjector.LowerDistanceParameter();
- if (aT2 < myTminTo) {
- aT2=myTminTo;
+ //
+ 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;
}
- if (aT2 > myTmaxTo) {
- aT2=myTmaxTo;
+ //
+ iErr = DistPC(aXL, theC1, theCriteria, theProjPC,
+ aYL, aT2L, aDmax, aT1max, aT2max, iC);
+ if (iErr) {
+ return iErr;
}
- return 0;
+ //
+ 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);
+ }
+ 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) {
+ if ((iErr == 2) && !bMaxDist) {
+ aXP = (aA + aB) * 0.5;
+ DistPC(aXP, theC1, theCriteria, theProjPC,
+ aYP, aT2P, aDmax, aT1max, aT2max, iC);
+ }
+ return iErr;
+ }
+ //
+ if ((aB - aA) < theEps) {
+ break;
+ }
+ }// for (;;) {
+ //
+ return iErr;
}
-
//=======================================================================
-//function : TreatVertexType
+//function : DistPC
//purpose :
//=======================================================================
- Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1,
- const Standard_Real am2,
- IntTools_CommonPrt& aCommonPrt)
+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_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;
-
+ Standard_Integer iErr;
//
- if (aCurveFrom->IsPeriodic()) {
- aPeriod=aCurveFrom->Period();
- if (tf1<f1 || tf1>l1) {
- tf1=tf1+aPeriod;
- }
- if (tl1<f1 || tl1>l1) {
- tl1=tl1+aPeriod;
- }
+ iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC);
+ if (iErr == 1) {
+ return iErr;
}
//
- // 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;
- //
+ if (iC*(aD - aDmax) > 0) {
+ aDmax = aD;
+ aT1max = aT1;
+ aT2max = aT2;
}
- return 0;
+ //
+ return iErr;
}
-
-
-//
-//
-// 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
+//function : DistPC
+//purpose :
//=======================================================================
- Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
- Standard_Real& aTx1,
- Standard_Real& aTx2) const
+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_Boolean bFlag;
- Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
- Standard_Real aTL1, aTL2, aTC1, aTC2;
- Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx;
- GeomAbs_CurveType aTFrom, aTTo;
- gp_Circ aCirc;
- gp_Lin aLine;
- gp_Pnt aPC, aPLx, aPCx;
- //
- bFlag=Standard_False;
- aCP.Range1(aTFR1, aTLR1);
- (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
- //
- aTFrom=myCFrom.GetType();
- aTTo =myCTo.GetType();
- //
- aTL1=aTFR1;
- aTL2=aTLR1;
- aTC1=aTFR2;
- aTC2=aTLR2;
- if (aTFrom==GeomAbs_Circle) {
- aCirc=myCFrom.Circle();
- aLine=myCTo.Line();
- aTL1=aTFR2;
- aTL2=aTLR2;
- aTC1=aTFR1;
- aTC2=aTLR1;
- }
- else {
- aCirc=myCTo.Circle();
- aLine=myCFrom.Line();
- }
+ Standard_Integer iErr, aNbP2;
+ gp_Pnt aP1;
//
- aPC=aCirc.Location();
- aRC=aCirc.Radius();
+ iErr = 0;
+ theC1->D0(aT1, aP1);
//
- aDLC=aLine.Distance(aPC);
- if (fabs(aDLC-aRC)>myCriteria) {
- return bFlag;
+ theProjPC.Perform(aP1);
+ aNbP2 = theProjPC.NbPoints();
+ if (!aNbP2) {
+ iErr = 1;// the point from aC1 can not be projected on aC2
+ return iErr;
}
//
- 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;
+ aD = theProjPC.LowerDistance();
+ aT2 = theProjPC.LowerDistanceParameter();
+ if (iC*(aD - theCriteria) > 0) {
+ iErr = 2;// the distance is too big or small
}
//
- if (aTLx<aTL1 || aTLx>aTL2) {
- return bFlag;
+ return iErr;
+}
+
+//=======================================================================
+//function : SplitRangeOnSegments
+//purpose :
+//=======================================================================
+Standard_Integer SplitRangeOnSegments(const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theResolution,
+ const Standard_Integer theNbSeg,
+ IntTools_SequenceOfRanges& theSegments)
+{
+ Standard_Real aDiff = aT2 - aT1;
+ if (aDiff < theResolution || theNbSeg == 1) {
+ theSegments.Append(IntTools_Range(aT1, aT2));
+ return 1;
}
- if (aTCx<aTC1 || aTCx>aTC2) {
- return bFlag;
+ //
+ Standard_Real aDt, aT1x, aT2x, aSeg;
+ Standard_Integer aNbSegments, i;
+ //
+ aNbSegments = theNbSeg;
+ aDt = aDiff / aNbSegments;
+ if (aDt < theResolution) {
+ aSeg = aDiff / theResolution;
+ aNbSegments = Standard_Integer(aSeg) + 1;
+ aDt = aDiff / aNbSegments;
}
//
- aTx1=aTLx;
- aTx2=aTCx;
- if (aTFrom==GeomAbs_Circle) {
- aTx1=aTCx;
- aTx2=aTLx;
+ aT1x = aT1;
+ for (i = 1; i < aNbSegments; ++i) {
+ aT2x = aT1x + aDt;
+ //
+ IntTools_Range aR(aT1x, aT2x);
+ theSegments.Append(aR);
+ //
+ aT1x = aT2x;
}
//
- return !bFlag;
+ IntTools_Range aR(aT1x, aT2);
+ theSegments.Append(aR);
+ //
+ return aNbSegments;
}
+
//=======================================================================
-//function : CheckTouch
+//function : BndBuildBox
//purpose :
//=======================================================================
- Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP,
- Standard_Real& aTx1,
- Standard_Real& aTx2)
+void BndBuildBox(const BRepAdaptor_Curve& theBAC,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ Bnd_Box& theBox)
{
- 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;
- }
-
- 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;
- }
- }
- }
-
- 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;
+ Bnd_Box aB;
+ BndLib_Add3dCurve::Add(theBAC, aT1, aT2, theTol, aB);
+ theBox = aB;
+}
- iLower=1;
- aMinDist2=1.e100;
- for (i=1; i<=aNbExt; ++i) {
- aDist2=anExtrema.SquareDistance(i);
- if (aDist2 < aMinDist2) {
- aMinDist2=aDist2;
- iLower=i;
+//=======================================================================
+//function : PointBoxDistance
+//purpose :
+//=======================================================================
+Standard_Real PointBoxDistance(const Bnd_Box& aB,
+ const gp_Pnt& aP)
+{
+ Standard_Real aPCoord[3];
+ Standard_Real aBMinCoord[3], aBMaxCoord[3];
+ Standard_Real aDist, aR1, aR2;
+ Standard_Integer i;
+ //
+ aP.Coord(aPCoord[0], aPCoord[1], aPCoord[2]);
+ aB.Get(aBMinCoord[0], aBMinCoord[1], aBMinCoord[2],
+ aBMaxCoord[0], aBMaxCoord[1], aBMaxCoord[2]);
+ //
+ aDist = 0.;
+ for (i = 0; i < 3; ++i) {
+ aR1 = aBMinCoord[i] - aPCoord[i];
+ if (aR1 > 0.) {
+ aDist += aR1*aR1;
+ continue;
}
-
- 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;
- }
- }
- avalidindex = i;
+ //
+ aR2 = aPCoord[i] - aBMaxCoord[i];
+ if (aR2 > 0.) {
+ aDist += aR2*aR2;
}
}
+ //
+ aDist = Sqrt(aDist);
+ return aDist;
+}
- aDist2=anExtrema.SquareDistance(iLower);
- if (aDist2 > myCriteria * myCriteria) {
- return theflag;
- }
-
- Extrema_POnCurv aPOnC1, aPOnC2;
- anExtrema.Points(iLower, aPOnC1, aPOnC2);
-
- aTx1=aPOnC1.Parameter();
- aTx2=aPOnC2.Parameter();
-
- if((myCFrom.GetType() == GeomAbs_Line && myCTo.GetType() == GeomAbs_Circle) ||
- (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line))
- {
- Standard_Real aRadius;
- GeomAbs_CurveType aTFrom, aTTo;
- gp_Circ aCirc;
- gp_Lin aLine;
- gp_Pnt aPCenter, aPOnLine;
+//=======================================================================
+//function : TypeToInteger
+//purpose :
+//=======================================================================
+Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType)
+{
+ Standard_Integer iRet;
+ //
+ switch(theCType) {
+ case GeomAbs_Line:
+ iRet=0;
+ break;
+ case GeomAbs_Hyperbola:
+ case GeomAbs_Parabola:
+ iRet=1;
+ break;
+ case GeomAbs_Circle:
+ case GeomAbs_Ellipse:
+ iRet=2;
+ break;
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ iRet=3;
+ break;
+ default:
+ iRet=4;
+ break;
+ }
+ return iRet;
+}
- aTFrom=myCFrom.GetType();
- aTTo =myCTo.GetType();
-
- if (aTFrom==GeomAbs_Circle) {
- aCirc=myCFrom.Circle();
- aLine=myCTo.Line();
- Curve2->D0(aTx2, aPOnLine);
+//=======================================================================
+//function : ResolutionCoeff
+//purpose :
+//=======================================================================
+Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange)
+{
+ Standard_Real aResCoeff = 0.;
+ //
+ const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
+ const GeomAbs_CurveType aCurveType = theBAC.GetType();
+ //
+ switch (aCurveType) {
+ case GeomAbs_Circle :
+ aResCoeff = 1. / (2 * Handle(Geom_Circle)::DownCast (aCurve)->Circ().Radius());
+ break;
+ case GeomAbs_Ellipse :
+ aResCoeff = 1. / Handle(Geom_Ellipse)::DownCast (aCurve)->MajorRadius();
+ break;
+ case GeomAbs_OffsetCurve : {
+ const Handle(Geom_OffsetCurve)& anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(aCurve);
+ const Handle(Geom_Curve)& aBasisCurve = anOffsetCurve->BasisCurve();
+ const GeomAbs_CurveType aBCType = GeomAdaptor_Curve(aBasisCurve).GetType();
+ if (aBCType == GeomAbs_Line) {
+ break;
}
-
- else {
- aCirc=myCTo.Circle();
- aLine=myCFrom.Line();
- Curve1->D0(aTx1, aPOnLine);
+ else if (aBCType == GeomAbs_Circle) {
+ aResCoeff = 1. / (2 * (anOffsetCurve->Offset() +
+ Handle(Geom_Circle)::DownCast (aBasisCurve)->Circ().Radius()));
+ break;
}
-
-
- aPCenter=aCirc.Location();
- aRadius =aCirc.Radius();
-
- aDist2=aPOnLine.SquareDistance(aPCenter);
- aDist2=fabs (sqrt(aDist2)-aRadius);
- aDist2 *= aDist2;
- if (aDist2 < Tol * Tol) {
- return !theflag;
+ else if (aBCType == GeomAbs_Ellipse) {
+ aResCoeff = 1. / (anOffsetCurve->Offset() +
+ Handle(Geom_Ellipse)::DownCast (aBasisCurve)->MajorRadius());
+ break;
}
}
-
- 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();
+ case GeomAbs_Hyperbola :
+ case GeomAbs_Parabola :
+ case GeomAbs_OtherCurve :{
+ Standard_Real k, kMin, aDist, aDt, aT1, aT2, aT;
+ Standard_Integer aNbP, i;
+ gp_Pnt aP1, aP2;
+ //
+ aNbP = 30;
+ theRange.Range(aT1, aT2);
+ aDt = (aT2 - aT1) / aNbP;
+ aT = aT1;
+ kMin = 10.;
+ //
+ theBAC.D0(aT1, aP1);
+ for (i = 1; i <= aNbP; ++i) {
+ aT += aDt;
+ theBAC.D0(aT, aP2);
+ aDist = aP1.Distance(aP2);
+ k = aDt / aDist;
+ if (k < kMin) {
+ kMin = k;
+ }
+ aP1 = aP2;
}
+ //
+ aResCoeff = kMin;
+ break;
}
-
- if (fabs (aTx1-aTF1) < Tol) {
- return !theflag;
- }
-
- if (fabs (aTx1-aTL1) < Tol) {
- return !theflag;
- }
-
- if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
- return !theflag;
+ default:
+ break;
}
-
- return theflag;
+ //
+ return aResCoeff;
}
//=======================================================================
-//function : ComputeLineLine
+//function : Resolution
//purpose :
//=======================================================================
- void IntTools_EdgeEdge::ComputeLineLine()
+Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
+ const GeomAbs_CurveType theCurveType,
+ const Standard_Real theResCoeff,
+ const Standard_Real theR3D)
{
- Standard_Boolean IsParallel, IsCoincide;
- Standard_Real Tolang2, Tol2;
- gp_Pnt P11, P12, P21, P22;
+ Standard_Real aRes;
//
- myIsDone = Standard_True;
- //
- IsParallel = Standard_False;
- IsCoincide = Standard_False;
- Tolang2 = 1.e-16;
- Tol2 = myCriteria*myCriteria;
- //
- 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) {
- IsParallel = Standard_True;
- if(C2.SquareDistance(C1.Location()) <= Tol2) {
- IsCoincide = Standard_True;
- P11 = ElCLib::Value(myTminFrom, C1);
- P12 = ElCLib::Value(myTmaxFrom, C1);
+ switch (theCurveType) {
+ case GeomAbs_Line :
+ aRes = theR3D;
+ break;
+ case GeomAbs_Circle: {
+ Standard_Real aDt = theResCoeff * theR3D;
+ aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
+ break;
+ }
+ case GeomAbs_BezierCurve:
+ Handle(Geom_BezierCurve)::DownCast (theCurve)->Resolution(theR3D, aRes);
+ break;
+ case GeomAbs_BSplineCurve:
+ Handle(Geom_BSplineCurve)::DownCast (theCurve)->Resolution(theR3D, aRes);
+ break;
+ case GeomAbs_OffsetCurve: {
+ const Handle(Geom_Curve)& aBasisCurve =
+ Handle(Geom_OffsetCurve)::DownCast(theCurve)->BasisCurve();
+ const GeomAbs_CurveType aBCType = GeomAdaptor_Curve(aBasisCurve).GetType();
+ if (aBCType == GeomAbs_Line) {
+ aRes = theR3D;
+ break;
}
- }
- 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) {
- IsCoincide = Standard_True;
+ else if (aBCType == GeomAbs_Circle) {
+ Standard_Real aDt = theResCoeff * theR3D;
+ aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
+ break;
}
}
-
- 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)) {
- 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);
- }
- else {
- aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo));
- aCommonPrt.AppendRange2(t21, myTmaxTo);
- }
- }
- else {
- aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom);
- aCommonPrt.AppendRange2(myTminTo, t22);
- }
- aCommonPrt.SetType(TopAbs_EDGE);
- mySeqOfCommonPrts.Append(aCommonPrt);
- return;
-
+ default:
+ aRes = theResCoeff * theR3D;
+ break;
}
+ //
+ return aRes;
+}
- if(IsParallel) {
- return;
- }
+//=======================================================================
+//function : CurveDeflection
+//purpose :
+//=======================================================================
+Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange)
+{
+ Standard_Real aDt, aT, aT1, aT2, aDefl;
+ Standard_Integer i, aNbP;
+ gp_Vec aV1, aV2;
+ gp_Pnt aP;
//
- {
- TopoDS_Iterator aIt1, aIt2;
- //
- aIt1.Initialize(myEdge1);
- for (; aIt1.More(); aIt1.Next()) {
- 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;
- }
- }
+ aDefl = 0;
+ aNbP = 10;
+ theRange.Range(aT1, aT2);
+ aDt = (aT2 - aT1) / aNbP;
+ aT = aT1;
+ //
+ theBAC.D1(aT1, aP, aV1);
+ for (i = 1; i <= aNbP; ++i) {
+ aT += aDt;
+ theBAC.D1(aT, aP, aV2);
+ if (aV1.Magnitude() > gp::Resolution() &&
+ aV2.Magnitude() > gp::Resolution()) {
+ gp_Dir aD1(aV1), aD2(aV2);
+ aDefl += aD1.Angle(aD2);
}
+ aV1 = aV2;
}
//
- 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);
+ return aDefl;
+}
- if(d2 > Tol2) {
- return;
+//=======================================================================
+//function : IsClosed
+//purpose :
+//=======================================================================
+Standard_Boolean IsClosed(const Handle(Geom_Curve)& theCurve,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ const Standard_Real theRes)
+{
+ if (Abs(aT1 - aT2) < theRes)
+ {
+ return Standard_False;
}
+
+ gp_Pnt aP1, aP2;
+ theCurve->D0(aT1, aP1);
+ theCurve->D0(aT2, aP2);
//
- IntTools_CommonPrt aCommonPrt;
- aCommonPrt.SetEdge1(myCFrom.Edge());
- aCommonPrt.SetEdge2(myCTo.Edge());
- aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria);
- aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria);
- aCommonPrt.SetType(TopAbs_VERTEX);
- aCommonPrt.SetVertexParameter1(U1);
- aCommonPrt.SetVertexParameter2(U2);
- mySeqOfCommonPrts.Append(aCommonPrt);
-
+ Standard_Real aD = aP1.Distance(aP2);
+ return aD < theTol;
}