// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <IntTools_FaceFace.ixx>
+#include <IntTools_FaceFace.hxx>
#include <Precision.hxx>
#include <Geom2dAPI_InterCurveCurve.hxx>
#include <Geom2dInt_GInter.hxx>
+#include <Geom2dAdaptor.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <IntTools_PntOn2Faces.hxx>
#include <IntTools_Context.hxx>
#include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
+#include <GeomInt.hxx>
+
+#include <Approx_CurveOnSurface.hxx>
+#include <GeomAdaptor.hxx>
+#include <GeomInt_IntSS.hxx>
static
void RefineVector(gp_Vec2d& aV2D);
-#ifdef DEB_DUMPWLINE
+#ifdef OCCT_DEBUG_DUMPWLINE
static
void DumpWLine(const Handle(IntPatch_WLine)& aWLine);
#endif
Standard_Real&,
Standard_Real&);
-static
- void BuildPCurves (Standard_Real f,Standard_Real l,Standard_Real& Tol,
- const Handle (Geom_Surface)& S,
- const Handle (Geom_Curve)& C,
- Handle (Geom2d_Curve)& C2d);
-
static
void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
const Standard_Real theTolerance,
Standard_Real& theumax,
Standard_Real& thevmin,
Standard_Real& thevmax);
+
static
Standard_Boolean NotUseSurfacesForApprox
(const TopoDS_Face& aF1,
const Standard_Integer ilprm);
static
- Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
+ Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine,
+ const Handle(GeomAdaptor_HSurface) &theS1,
+ const Handle(GeomAdaptor_HSurface) &theS2);
static
Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
const Handle(GeomAdaptor_HSurface)& theSurface2,
const TopoDS_Face& theFace1,
const TopoDS_Face& theFace2,
- const IntTools_LineConstructor& theLConstructor,
+ const GeomInt_LineConstructor& theLConstructor,
const Standard_Boolean theAvoidLConstructor,
IntPatch_SequenceOfLine& theNewLines,
Standard_Real& theReachedTol3d,
Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
//
-static
- Standard_Real MaxSquareDistance (const Standard_Real aT,
- const Handle(Geom_Curve)& aC3D,
- const Handle(Geom2d_Curve)& aC2D1,
- const Handle(Geom2d_Curve)& aC2D2,
- const Handle(GeomAdaptor_HSurface) myHS1,
- const Handle(GeomAdaptor_HSurface) myHS2,
- const TopoDS_Face& aF1,
- const TopoDS_Face& aF2,
- const Handle(IntTools_Context)& aCtx);
-
static
Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
const TopoDS_Face& aFace);
-//
static
- Standard_Real FindMaxSquareDistance (const Standard_Real aA,
- const Standard_Real aB,
- const Standard_Real aEps,
- const Handle(Geom_Curve)& aC3D,
- const Handle(Geom2d_Curve)& aC2D1,
- const Handle(Geom2d_Curve)& aC2D2,
- const Handle(GeomAdaptor_HSurface)& myHS1,
- const Handle(GeomAdaptor_HSurface)& myHS2,
- const TopoDS_Face& aF1,
- const TopoDS_Face& aF2,
- const Handle(IntTools_Context)& aCtx);
+ Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
+ const Standard_Real aT,
+ GeomAPI_ProjectPointOnSurf& theProjPS);
+
+static
+ Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ GeomAPI_ProjectPointOnSurf& theProjPS,
+ const Standard_Real theEps);
+
+static
+ Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ const TopoDS_Face& theFace,
+ const Handle(IntTools_Context)& theContext);
+
+static
+ void CorrectPlaneBoundaries(Standard_Real& aUmin,
+ Standard_Real& aUmax,
+ Standard_Real& aVmin,
+ Standard_Real& aVmax);
//=======================================================================
//function :
//function : Perform
//purpose : intersect surfaces of the faces
//=======================================================================
- void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
+void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
const TopoDS_Face& aF2)
{
Standard_Boolean RestrictLine = Standard_False, hasCone = Standard_False;
if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
Standard_Real umin, umax, vmin, vmax;
- Standard_Real dU, dV;
//
BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
- dU=0.1*(umax-umin);
- dV=0.1*(vmax-vmin);
- umin=umin-dU;
- umax=umax+dU;
- vmin=vmin-dV;
- vmax=vmax+dV;
+ CorrectPlaneBoundaries(umin, umax, vmin, vmax);
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
//
BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
- dU=0.1*(umax-umin);
- dV=0.1*(vmax-vmin);
- umin=umin-dU;
- umax=umax+dU;
- vmin=vmin-dV;
- vmax=vmax+dV;
+ CorrectPlaneBoundaries(umin, umax, vmin, vmax);
myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
//
Standard_Real TolAng = 1.e-8;
if ((aType1==GeomAbs_Plane) && isFace2Quad)
{
- Standard_Real dU, dV;
-
- // F1
Standard_Real umin, umax, vmin, vmax;
- BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
-
- dU=0.1*(umax-umin);
- dV=0.1*(vmax-vmin);
- umin=umin-dU;
- umax=umax+dU;
- vmin=vmin-dV;
- vmax=vmax+dV;
+ // F1
+ BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
+ CorrectPlaneBoundaries(umin, umax, vmin, vmax);
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
// F2
BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
}
else if ((aType2==GeomAbs_Plane) && isFace1Quad)
{
- Standard_Real dU, dV;
-
- //F1
Standard_Real umin, umax, vmin, vmax;
+ //F1
BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
// F2
BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
- dU=0.1*(umax-umin);
- dV=0.1*(vmax-vmin);
- umin=umin-dU;
- umax=umax+dU;
- vmin=vmin-dV;
- vmax=vmax+dV;
+ CorrectPlaneBoundaries(umin, umax, vmin, vmax);
myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
//
if( aType1==GeomAbs_Cone ) {
{
const Standard_Real UVMaxStep = 0.001;
const Standard_Real Deflection = (hasCone) ? 0.085 : 0.1;
- myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
+ myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
}
if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
}
// Points
+ Standard_Boolean bValid2D1, bValid2D2;
Standard_Real U1,V1,U2,V2;
IntTools_PntOnFace aPntOnF1, aPntOnF2;
IntTools_PntOn2Faces aPntOn2Faces;
const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
const gp_Pnt& aPnt=aISPnt.Value();
aISPnt.Parameters(U1,V1,U2,V2);
+ //
+ // check the validity of the intersection point for the faces
+ bValid2D1 = myContext->IsPointInOnFace(myFace1, gp_Pnt2d(U1, V1));
+ if (!bValid2D1) {
+ continue;
+ }
+ //
+ bValid2D2 = myContext->IsPointInOnFace(myFace2, gp_Pnt2d(U2, V2));
+ if (!bValid2D2) {
+ continue;
+ }
+ //
+ // add the intersection point
aPntOnF1.Init(myFace1, aPnt, U1, V1);
aPntOnF2.Init(myFace2, aPnt, U2, V2);
//
}
}
+//=======================================================================
+//function : ComputeTolerance
+//purpose :
+//=======================================================================
+Standard_Real IntTools_FaceFace::ComputeTolerance()
+{
+ Standard_Integer i, j, aNbLin;
+ Standard_Real aFirst, aLast, aD, aDMax, aT;
+ Handle(Geom_Surface) aS1, aS2;
+ //
+ aDMax = 0;
+ aNbLin = mySeqOfCurve.Length();
+ //
+ aS1 = myHS1->ChangeSurface().Surface();
+ aS2 = myHS2->ChangeSurface().Surface();
+ //
+ for (i = 1; i <= aNbLin; ++i)
+ {
+ const IntTools_Curve& aIC = mySeqOfCurve(i);
+ const Handle(Geom_Curve)& aC3D = aIC.Curve();
+ if (aC3D.IsNull())
+ {
+ continue;
+ }
+ //
+ aFirst = aC3D->FirstParameter();
+ aLast = aC3D->LastParameter();
+ //
+ const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
+ const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
+ //
+ for (j = 0; j < 2; ++j)
+ {
+ const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
+ const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
+ //
+ if (!aC2D.IsNull())
+ {
+ if (IntTools_Tools::ComputeTolerance
+ (aC3D, aC2D, aS, aFirst, aLast, aD, aT))
+ {
+ if (aD > aDMax)
+ {
+ aDMax = aD;
+ }
+ }
+ }
+ else
+ {
+ const TopoDS_Face& aF = !j ? myFace1 : myFace2;
+ aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
+ if (aD > aDMax)
+ {
+ aDMax = aD;
+ }
+ }
+ }
+ }
+ //
+ return aDMax;
+}
+
//=======================================================================
//function :ComputeTolReached3d
//purpose :
//=======================================================================
void IntTools_FaceFace::ComputeTolReached3d()
{
- Standard_Boolean bCase1;
- Standard_Integer aNbLin, i;
+ Standard_Integer aNbLin;
GeomAbs_SurfaceType aType1, aType2;
//
aNbLin=myIntersector.NbLines();
aType1=myHS1->Surface().GetType();
aType2=myHS2->Surface().GetType();
//
- bCase1=((aType1==GeomAbs_Plane && aType2==GeomAbs_SurfaceOfExtrusion) ||
- (aType2==GeomAbs_Plane && aType1==GeomAbs_SurfaceOfExtrusion));
- //
- if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
- if (aNbLin==2){
+ if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder)
+ {
+ if (aNbLin==2)
+ {
Handle(IntPatch_Line) aIL1, aIL2;
IntPatch_IType aTL1, aTL2;
//
aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
aD=aL1.Distance(aL2);
aD=0.5*aD;
- if (aD<aDTresh) {
+ if (aD<aDTresh)
+ {//In order to avoid creation too thin face
myTolReached3d=aD+dTol;
}
- return;
}
}
- //ZZ
- if (aNbLin) {// Check the distances
- Standard_Integer aNbP, j ;
- Standard_Real aT1, aT2, dT, aD2, aD2Max, aEps, aT11, aT12;
- //
- aD2Max=0.;
- aNbP=10;
- aNbLin=mySeqOfCurve.Length();
- //
- for (i=1; i<=aNbLin; ++i) {
- const IntTools_Curve& aIC=mySeqOfCurve(i);
- const Handle(Geom_Curve)& aC3D=aIC.Curve();
- const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
- const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
- //
- if (aC3D.IsNull()) {
- continue;
- }
- const Handle(Geom_BSplineCurve)& aBC=
- Handle(Geom_BSplineCurve)::DownCast(aC3D);
- if (aBC.IsNull()) {
- continue;
- }
- //
- aT1=aBC->FirstParameter();
- aT2=aBC->LastParameter();
- //
- aEps=0.01*(aT2-aT1);
- dT=(aT2-aT1)/aNbP;
- for (j=1; j<aNbP; ++j) {
- aT11=aT1+j*dT;
- aT12=aT11+dT;
- aD2=FindMaxSquareDistance(aT11, aT12, aEps, aC3D, aC2D1, aC2D2,
- myHS1, myHS2, myFace1, myFace2, myContext);
- if (aD2>aD2Max) {
- aD2Max=aD2;
- }
- }
- }//for (i=1; i<=aNbLin; ++i) {
- //
- myTolReached3d=sqrt(aD2Max);
- }// if (aNbLin)
}// if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
//
- //904/G3 f
- else if (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
- Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
- //
- aTolTresh=1.e-7;
- //
- aTolF1 = BRep_Tool::Tolerance(myFace1);
- aTolF2 = BRep_Tool::Tolerance(myFace2);
- aTolFMax=Max(aTolF1, aTolF2);
- //
- if (aTolFMax>aTolTresh) {
- myTolReached3d=aTolFMax;
- }
- }//if (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
- //t
- //IFV Bug OCC20297
- else if((aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane) ||
- (aType2 == GeomAbs_Cylinder && aType1 == GeomAbs_Plane)) {
- if(aNbLin == 1) {
- const Handle(IntPatch_Line)& aIL1 = myIntersector.Line(1);
- if(aIL1->ArcType() == IntPatch_Circle) {
- gp_Circ aCir = Handle(IntPatch_GLine)::DownCast(aIL1)->Circle();
- gp_XYZ aCirDir = aCir.Axis().Direction().XYZ();
- gp_XYZ aPlDir;
- gp_Pln aPln;
- if(aType1 == GeomAbs_Plane) {
- aPln = myHS1->Surface().Plane();
- }
- else {
- aPln = myHS2->Surface().Plane();
- }
- aPlDir = aPln.Axis().Direction().XYZ();
- Standard_Real cs = aCirDir*aPlDir;
- if(cs < 0.) aPlDir.Reverse();
- Standard_Real eps = 1.e-14;
- if(!aPlDir.IsEqual(aCirDir, eps)) {
- Standard_Integer aNbP = 11;
- Standard_Real dt = 2.*M_PI / (aNbP - 1), t;
- for(t = 0.; t < 2.*M_PI; t += dt) {
- Standard_Real d = aPln.Distance(ElCLib::Value(t, aCir));
- if(myTolReached3d < d) myTolReached3d = d;
- }
- myTolReached3d *= 1.1;
- }
- } //aIL1->ArcType() == IntPatch_Circle
- } //aNbLin == 1
- } // aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane)
- //End IFV Bug OCC20297
- //
- else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
- (aType2==GeomAbs_Plane && aType1==GeomAbs_Torus)) {
- aNbLin=mySeqOfCurve.Length();
- if (aNbLin!=1) {
- return;
- }
- //
- Standard_Integer aNbP;
- Standard_Real aT, aT1, aT2, dT, aUT, aVT, aUP, aVP;
- Standard_Real aDP, aDT, aDmax;
- gp_Pln aPln;
- gp_Torus aTorus;
- gp_Pnt aP, aPP, aPT;
- //
- const IntTools_Curve& aIC=mySeqOfCurve(1);
- const Handle(Geom_Curve)& aC3D=aIC.Curve();
- const Handle(Geom_BSplineCurve)& aBS=
- Handle(Geom_BSplineCurve)::DownCast(aC3D);
- if (aBS.IsNull()) {
- return;
- }
- //
- aT1=aBS->FirstParameter();
- aT2=aBS->LastParameter();
- //
- aPln =(aType1==GeomAbs_Plane) ? myHS1->Plane() : myHS2->Plane();
- aTorus=(aType1==GeomAbs_Plane) ? myHS2->Torus() : myHS1->Torus();
- //
- aDmax=-1.;
- aNbP=11;
- dT=(aT2-aT1)/(aNbP-1);
- for (i=0; i<aNbP; ++i) {
- aT=aT1+i*dT;
- if (i==aNbP-1) {
- aT=aT2;
- }
- //
- aC3D->D0(aT, aP);
- //
- ElSLib::Parameters(aPln, aP, aUP, aVP);
- aPP=ElSLib::Value(aUP, aVP, aPln);
- aDP=aP.SquareDistance(aPP);
- if (aDP>aDmax) {
- aDmax=aDP;
- }
- //
- ElSLib::Parameters(aTorus, aP, aUT, aVT);
- aPT=ElSLib::Value(aUT, aVT, aTorus);
- aDT=aP.SquareDistance(aPT);
- if (aDT>aDmax) {
- aDmax=aDT;
- }
- }
- //
- if (aDmax > myTolReached3d*myTolReached3d) {
- myTolReached3d=sqrt(aDmax);
- myTolReached3d=1.1*myTolReached3d;
- }
- }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
- //
- else if ((aType1==GeomAbs_SurfaceOfRevolution && aType2==GeomAbs_Cylinder) ||
- (aType2==GeomAbs_SurfaceOfRevolution && aType1==GeomAbs_Cylinder)) {
- Standard_Integer j, aNbP;
- Standard_Real aT, aT1, aT2, dT, aD2max, aD2;
- //
- aNbLin=mySeqOfCurve.Length();
- aD2max=0.;
- aNbP=11;
- //
- for (i=1; i<=aNbLin; ++i) {
- const IntTools_Curve& aIC=mySeqOfCurve(i);
- const Handle(Geom_Curve)& aC3D=aIC.Curve();
- const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
- const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
- //
- if (aC3D.IsNull()) {
- continue;
- }
- const Handle(Geom_BSplineCurve)& aBC=
- Handle(Geom_BSplineCurve)::DownCast(aC3D);
- if (aBC.IsNull()) {
- return;
- }
- //
- aT1=aBC->FirstParameter();
- aT2=aBC->LastParameter();
- //
- dT=(aT2-aT1)/(aNbP-1);
- for (j=0; j<aNbP; ++j) {
- aT=aT1+j*dT;
- if (j==aNbP-1) {
- aT=aT2;
- }
- //
- aD2=MaxSquareDistance(aT, aC3D, aC2D1, aC2D2,
- myHS1, myHS2, myFace1, myFace2, myContext);
- if (aD2>aD2max) {
- aD2max=aD2;
- }
- }//for (j=0; j<aNbP; ++j) {
-
- }//for (i=1; i<=aNbLin; ++i) {
- //
- aD2=myTolReached3d*myTolReached3d;
- if (aD2max > aD2) {
- myTolReached3d=sqrt(aD2max);
- }
- }//if((aType1==GeomAbs_SurfaceOfRevolution ...
- else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Sphere) ||
- (aType2==GeomAbs_Plane && aType1==GeomAbs_Sphere)) {
- Standard_Integer j, aNbP;
- Standard_Real aT1, aT2, dT, aD2max, aD2, aEps, aT11, aT12;
- //
- aNbLin=mySeqOfCurve.Length();
- aD2max=0.;
- aNbP=10;
- //
- for (i=1; i<=aNbLin; ++i) {
- const IntTools_Curve& aIC=mySeqOfCurve(i);
- const Handle(Geom_Curve)& aC3D=aIC.Curve();
- const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
- const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
- //
- const Handle(Geom2d_BSplineCurve)& aBC2D1=
- Handle(Geom2d_BSplineCurve)::DownCast(aC2D1);
- const Handle(Geom2d_BSplineCurve)& aBC2D2=
- Handle(Geom2d_BSplineCurve)::DownCast(aC2D2);
- //
- if (aBC2D1.IsNull() && aBC2D2.IsNull()) {
- return;
- }
- //
- if (!aBC2D1.IsNull()) {
- aT1=aBC2D1->FirstParameter();
- aT2=aBC2D1->LastParameter();
- }
- else {
- aT1=aBC2D2->FirstParameter();
- aT2=aBC2D2->LastParameter();
- }
- //
- aEps=0.01*(aT2-aT1);
- dT=(aT2-aT1)/aNbP;
- for (j=0; j<aNbP; ++j) {
- aT11=aT1+j*dT;
- aT12=aT11+dT;
- if (j==aNbP-1) {
- aT12=aT2;
- }
- //
- aD2=FindMaxSquareDistance(aT11, aT12, aEps, aC3D, aC2D1, aC2D2,
- myHS1, myHS2, myFace1, myFace2, myContext);
- if (aD2>aD2max) {
- aD2max=aD2;
- }
- }//for (j=0; j<aNbP; ++j) {
-
- }//for (i=1; i<=aNbLin; ++i) {
- //
- aD2=myTolReached3d*myTolReached3d;
- if (aD2max > aD2) {
- myTolReached3d=sqrt(aD2max);
+
+ Standard_Real aDMax = ComputeTolerance();
+ if (aDMax > myTolReached3d)
+ {
+ myTolReached3d = aDMax;
}
- }//else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Sphere) ...
- else if (!myApprox || bCase1) {
- //else if (!myApprox) {
- Standard_Integer aNbP, j;
- Standard_Real aT1, aT2, dT, aD2, aD2Max, aEps, aT11, aT12;
- //
- aD2Max=0.;
- aNbLin=mySeqOfCurve.Length();
- //
- for (i=1; i<=aNbLin; ++i) {
- const IntTools_Curve& aIC=mySeqOfCurve(i);
- const Handle(Geom_Curve)& aC3D=aIC.Curve();
- const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
- const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
- //
- if (aC3D.IsNull()) {
- continue;
-}
- const Handle(Geom_BSplineCurve)& aBC=
- Handle(Geom_BSplineCurve)::DownCast(aC3D);
- if (aBC.IsNull()) {
- continue;
- }
- //
- aT1=aBC->FirstParameter();
- aT2=aBC->LastParameter();
- //
- aEps=0.0001*(aT2-aT1);
- aNbP=11;
- dT=(aT2-aT1)/aNbP;
- for (j=1; j<aNbP-1; ++j) {
- aT11=aT1+j*dT;
- aT12=aT11+dT;
- aD2=FindMaxSquareDistance(aT11, aT12, aEps, aC3D, aC2D1, aC2D2,
- myHS1, myHS2, myFace1, myFace2, myContext);
- if (aD2>aD2Max) {
- aD2Max=aD2;
- }
- }
- }//for (i=1; i<=aNbLin; ++i) {
- myTolReached3d=sqrt(aD2Max);
}
-}
+
//=======================================================================
//function : MakeCurve
//purpose :
if(typl==IntPatch_Walking) {
Handle(IntPatch_Line) anewL;
//
- const Handle(IntPatch_WLine)& aWLine=
- Handle(IntPatch_WLine)::DownCast(L);
- //DumpWLine(aWLine);
-
- anewL = ComputePurgedWLine(aWLine);
+ Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
+ anewL = ComputePurgedWLine(aWLine, myHS1, myHS2);
if(anewL.IsNull()) {
return;
}
L = anewL;
-
- //const Handle(IntPatch_WLine)& aWLineX = Handle(IntPatch_WLine)::DownCast(L);
+
+ //Handle(IntPatch_WLine) aWLineX (Handle(IntPatch_WLine)::DownCast(L));
//DumpWLine(aWLineX);
//
bAvoidLineConstructor = Standard_False;
}
}
+
+ typl=L->ArcType();
+
//
// Line Constructor
if(!bAvoidLineConstructor) {
myLConstruct.Perform(L);
//
bDone=myLConstruct.IsDone();
- aNbParts=myLConstruct.NbParts();
- if (!bDone|| !aNbParts) {
+ if(!bDone)
+ {
return;
}
+
+ if(typl != IntPatch_Restriction)
+ {
+ aNbParts=myLConstruct.NbParts();
+ if (aNbParts <= 0)
+ {
+ return;
+ }
+ }
}
// Do the Curve
- typl=L->ArcType();
switch (typl) {
//########################################
// Line, Parabola, Hyperbola
//
aNbParts=myLConstruct.NbParts();
for (i=1; i<=aNbParts; i++) {
+ Standard_Boolean bFNIt, bLPIt;
+ //
myLConstruct.Part(i, fprm, lprm);
-
- if (!Precision::IsNegativeInfinite(fprm) &&
- !Precision::IsPositiveInfinite(lprm)) {
+ //
+ bFNIt=Precision::IsNegativeInfinite(fprm);
+ bLPIt=Precision::IsPositiveInfinite(lprm);
+ //
+ if (!bFNIt && !bLPIt) {
//
IntTools_Curve aCurve;
//
aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
if(myApprox1) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
+ myHS1->ChangeSurface().Surface(), newc, C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0.) {
myTolReached2d=Tolpc;
}
//
aCurve.SetFirstCurve2d(H1);
}
-
+ //
if(myApprox2) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
+ myHS2->ChangeSurface().Surface(), newc, C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0.) {
myTolReached2d=Tolpc;
}
aCurve.SetSecondCurve2d(H1);
}
mySeqOfCurve.Append(aCurve);
- } // end of if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
+ } //if (!bFNIt && !bLPIt) {
else {
// on regarde si on garde
//
- Standard_Boolean bFNIt, bLPIt;
Standard_Real aTestPrm, dT=100.;
-
- bFNIt=Precision::IsNegativeInfinite(fprm);
- bLPIt=Precision::IsPositiveInfinite(lprm);
-
+ //
aTestPrm=0.;
-
if (bFNIt && !bLPIt) {
aTestPrm=lprm-dT;
}
else if (!bFNIt && bLPIt) {
aTestPrm=fprm+dT;
}
-
+ else {
+ // i.e, if (bFNIt && bLPIt)
+ aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
+ }
+ //
gp_Pnt ptref(newc->Value(aTestPrm));
//
GeomAbs_SurfaceType typS1 = myHS1->GetType();
typS1 == GeomAbs_SurfaceOfRevolution ||
typS2 == GeomAbs_SurfaceOfExtrusion ||
typS2 == GeomAbs_OffsetSurface ||
- typS2 == GeomAbs_SurfaceOfRevolution)
- {
+ typS2 == GeomAbs_SurfaceOfRevolution) {
Handle(Geom2d_BSplineCurve) H1;
mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
continue;
mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
}
}
- }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
+ }// for (i=1; i<=aNbParts; i++) {
}// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
break;
if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
if(myApprox1) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
+ myHS1->ChangeSurface().Surface(), newc, C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0) {
myTolReached2d=Tolpc;
}
if(myApprox2) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
+ GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
+ myHS2->ChangeSurface().Surface(),newc,C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0) {
myTolReached2d=Tolpc;
}
if(myApprox1) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
+ GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
+ myHS1->ChangeSurface().Surface(),newc,C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0) {
myTolReached2d=Tolpc;
}
if(myApprox2) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
+ GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
+ myHS2->ChangeSurface().Surface(),newc,C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0) {
myTolReached2d=Tolpc;
}
if(myApprox1) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
+ myHS1->ChangeSurface().Surface(), newc, C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0) {
myTolReached2d=Tolpc;
}
if(myApprox2) {
Handle (Geom2d_Curve) C2d;
- BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
+ myHS2->ChangeSurface().Surface(), newc, C2d);
if(Tolpc>myTolReached2d || myTolReached2d==0) {
myTolReached2d=Tolpc;
}
case IntPatch_Walking:{
Handle(IntPatch_WLine) WL =
Handle(IntPatch_WLine)::DownCast(L);
+
+#ifdef OCCT_DEBUG
+ //WL->Dump(0);
+#endif
+
//
Standard_Integer ifprm, ilprm;
//
}
//
mySeqOfCurve.Append(aCurve);
+
}//if(typs1 == GeomAbs_Plane) {
- else if(typs2 == GeomAbs_Plane) {
+ else if(typs2 == GeomAbs_Plane)
+ {
const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
nbpoles = mbspc.NbPoles();
} else {
mySeqOfCurve.Append(aCurve);
}
+
}// else if(typs2 == GeomAbs_Plane)
//
else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
Handle(Geom2d_Curve) C2d;
Standard_Real aTol = myTolApprox;
- BuildPCurves(fprm, lprm, aTol, myHS1->ChangeSurface().Surface(), BS, C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
+ myHS1->ChangeSurface().Surface(), BS, C2d);
BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
aCurve.SetFirstCurve2d(BS1);
}
Handle(Geom2d_Curve) C2d;
Standard_Real aTol = myTolApprox;
- BuildPCurves(fprm, lprm, aTol, myHS2->ChangeSurface().Surface(), BS, C2d);
+ GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
+ myHS2->ChangeSurface().Surface(), BS, C2d);
BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
aCurve.SetSecondCurve2d(BS2);
}
break;
case IntPatch_Restriction:
- break;
- default:
- break;
+ {
+ Handle(IntPatch_RLine) RL =
+ Handle(IntPatch_RLine)::DownCast(L);
+ Handle(Geom_Curve) aC3d;
+ Handle(Geom2d_Curve) aC2d1, aC2d2;
+ Standard_Real aTolReached;
+ GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
+ aC2d1, aC2d2, aTolReached);
+
+ if(aC3d.IsNull())
+ break;
- }
-}
+ Bnd_Box2d aBox1, aBox2;
-//=======================================================================
-//function : BuildPCurves
-//purpose :
-//=======================================================================
-void BuildPCurves (Standard_Real f,
- Standard_Real l,
- Standard_Real& Tol,
- const Handle (Geom_Surface)& S,
- const Handle (Geom_Curve)& C,
- Handle (Geom2d_Curve)& C2d)
-{
- if (!C2d.IsNull()) {
- return;
- }
- //
- Standard_Real umin,umax,vmin,vmax;
- //
- S->Bounds(umin, umax, vmin, vmax);
- // in class ProjLib_Function the range of parameters is shrank by 1.e-09
- if((l - f) > 2.e-09) {
- C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
- //
- if (C2d.IsNull()) {
- // proj. a circle that goes through the pole on a sphere to the sphere
- Tol += Precision::Confusion();
- C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
- }
- }
- else {
- if((l - f) > Epsilon(Abs(f))) {
- GeomAPI_ProjectPointOnSurf aProjector1, aProjector2;
- gp_Pnt P1 = C->Value(f);
- gp_Pnt P2 = C->Value(l);
- aProjector1.Init(P1, S);
- aProjector2.Init(P2, S);
-
- if(aProjector1.IsDone() && aProjector2.IsDone()) {
- Standard_Real U=0., V=0.;
- aProjector1.LowerDistanceParameters(U, V);
- gp_Pnt2d p1(U, V);
-
- aProjector2.LowerDistanceParameters(U, V);
- gp_Pnt2d p2(U, V);
+ const Standard_Real aU1f = myHS1->FirstUParameter(),
+ aV1f = myHS1->FirstVParameter(),
+ aU1l = myHS1->LastUParameter(),
+ aV1l = myHS1->LastVParameter();
+ const Standard_Real aU2f = myHS2->FirstUParameter(),
+ aV2f = myHS2->FirstVParameter(),
+ aU2l = myHS2->LastUParameter(),
+ aV2l = myHS2->LastVParameter();
+
+ aBox1.Add(gp_Pnt2d(aU1f, aV1f));
+ aBox1.Add(gp_Pnt2d(aU1l, aV1l));
+ aBox2.Add(gp_Pnt2d(aU2f, aV2f));
+ aBox2.Add(gp_Pnt2d(aU2l, aV2l));
+
+ GeomInt_VectorOfReal anArrayOfParameters;
- if(p1.Distance(p2) > gp::Resolution()) {
- TColgp_Array1OfPnt2d poles(1,2);
- TColStd_Array1OfReal knots(1,2);
- TColStd_Array1OfInteger mults(1,2);
- poles(1) = p1;
- poles(2) = p2;
- knots(1) = f;
- knots(2) = l;
- mults(1) = mults(2) = 2;
-
- C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
-
- // compute reached tolerance.begin
- gp_Pnt PMid = C->Value((f + l) * 0.5);
- aProjector1.Perform(PMid);
-
- if(aProjector1.IsDone()) {
- aProjector1.LowerDistanceParameters(U, V);
- gp_Pnt2d pmidproj(U, V);
- gp_Pnt2d pmidcurve2d = C2d->Value((f + l) * 0.5);
- Standard_Real adist = pmidcurve2d.Distance(pmidproj);
- Tol = (adist > Tol) ? adist : Tol;
- }
- // compute reached tolerance.end
+ //We consider here that the intersection line is same-parameter-line
+ anArrayOfParameters.Append(aC3d->FirstParameter());
+ anArrayOfParameters.Append(aC3d->LastParameter());
+
+ GeomInt_IntSS::
+ TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
+
+ const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
+
+ //Trim RLine found.
+ for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
+ {
+ const Standard_Real aParF = anArrayOfParameters(anInd),
+ aParL = anArrayOfParameters(anInd+1);
+
+ if((aParL - aParF) <= Precision::PConfusion())
+ continue;
+
+ const Standard_Real aPar = 0.5*(aParF + aParL);
+ gp_Pnt2d aPt;
+
+ Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
+ if(!aC2d1.IsNull())
+ {
+ aC2d1->D0(aPar, aPt);
+
+ if(aBox1.IsOut(aPt))
+ continue;
+
+ if(myApprox1)
+ aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
+ }
+
+ if(!aC2d2.IsNull())
+ {
+ aC2d2->D0(aPar, aPt);
+
+ if(aBox2.IsOut(aPt))
+ continue;
+
+ if(myApprox2)
+ aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
}
+
+ Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
+
+ IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
+ mySeqOfCurve.Append(aIC);
}
}
- }
- //
- if (S->IsUPeriodic() && !C2d.IsNull()) {
- // Recadre dans le domaine UV de la face
- Standard_Real aTm, U0, aEps, period, du, U0x;
- Standard_Boolean bAdjust;
- //
- aEps = Precision::PConfusion();
- period = S->UPeriod();
- //
- aTm = .5*(f + l);
- gp_Pnt2d pm = C2d->Value(aTm);
- U0 = pm.X();
- //
- bAdjust =
- IntTools_Tools::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
- if (bAdjust) {
- gp_Vec2d T1(du, 0.);
- C2d->Translate(T1);
- }
+ break;
+ default:
+ break;
+
}
}
//
if(!isuperiodic && enlarge) {
- if((theumin - uinf) > delta )
+ if(!Precision::IsInfinite(theumin) &&
+ ((theumin - uinf) > delta))
theumin -= delta;
else {
theumin = uinf;
}
- if((usup - theumax) > delta )
+ if(!Precision::IsInfinite(theumax) &&
+ ((usup - theumax) > delta))
theumax += delta;
else
theumax = usup;
}
//
if(!isvperiodic && enlarge) {
- if((thevmin - vinf) > delta ) {
+ if(!Precision::IsInfinite(thevmin) &&
+ ((thevmin - vinf) > delta)) {
thevmin -= delta;
}
else {
thevmin = vinf;
}
- if((vsup - thevmax) > delta ) {
+ if(!Precision::IsInfinite(thevmax) &&
+ ((vsup - thevmax) > delta)) {
thevmax += delta;
}
else {
return !bFlag;
}
+// Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec.
+// In 2d space.
+static Standard_Boolean IsInsideIn2d(const gp_Pnt2d& aBasePnt,
+ const gp_Vec2d& aBaseVec,
+ const gp_Pnt2d& aNextPnt,
+ const Standard_Real aSquareMaxDist)
+{
+ gp_Vec2d aVec2d(aBasePnt, aNextPnt);
+
+ //d*d = (basevec^(nextpnt-basepnt))**2 / basevec**2
+ Standard_Real aCross = aVec2d.Crossed(aBaseVec);
+ Standard_Real aSquareDist = aCross * aCross
+ / aBaseVec.SquareMagnitude();
+
+ return (aSquareDist <= aSquareMaxDist);
+}
+
+// Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec.
+// In 3d space.
+static Standard_Boolean IsInsideIn3d(const gp_Pnt& aBasePnt,
+ const gp_Vec& aBaseVec,
+ const gp_Pnt& aNextPnt,
+ const Standard_Real aSquareMaxDist)
+{
+ gp_Vec aVec(aBasePnt, aNextPnt);
+
+ //d*d = (basevec^(nextpnt-basepnt))**2 / basevec**2
+ Standard_Real aSquareDist = aVec.CrossSquareMagnitude(aBaseVec)
+ / aBaseVec.SquareMagnitude();
+
+ return (aSquareDist <= aSquareMaxDist);
+}
+
//=========================================================================
// static function : ComputePurgedWLine
// purpose : Removes equal points (leave one of equal points) from theWLine
// and recompute vertex parameters.
+// Removes exceed points using tube criteria:
+// delete 7D point if it lies near to expected lines in 2d and 3d.
+// Each task (2d, 2d, 3d) have its own tolerance and checked separately.
// Returns new WLine or null WLine if the number
// of the points is less than 2.
//=========================================================================
-Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) {
-
+Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine,
+ const Handle(GeomAdaptor_HSurface) &theS1,
+ const Handle(GeomAdaptor_HSurface) &theS2)
+{
Standard_Integer i, k, v, nb, nbvtx;
Handle(IntPatch_WLine) aResult;
nbvtx = theWLine->NbVertex();
for(v = 1; v <= nbvtx; v++) {
aLocalWLine->AddVertex(theWLine->Vertex(v));
}
-
for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
Standard_Integer aStartIndex = i + 1;
Standard_Integer anEndIndex = i + 5;
IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
- if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
+ Standard_Real UV[8];
+ p1.Parameters(UV[0], UV[1], UV[2], UV[3]);
+ p2.Parameters(UV[4], UV[5], UV[6], UV[7]);
+
+ Standard_Real aMax = Abs(UV[0]);
+ for(Standard_Integer anIdx = 1; anIdx < 8; anIdx++)
+ {
+ if (aMax < Abs(UV[anIdx]))
+ aMax = Abs(UV[anIdx]);
+ }
+
+ if(p1.Value().IsEqual(p2.Value(), gp::Resolution()) ||
+ Abs(UV[0] - UV[4]) + Abs(UV[1] - UV[5]) < 1.0e-16 * aMax ||
+ Abs(UV[2] - UV[6]) + Abs(UV[3] - UV[7]) < 1.0e-16 * aMax )
+ {
aTmpWLine = aLocalWLine;
aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
-
+
for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
IntPatch_Point aVertex = aTmpWLine->Vertex(v);
Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
}
}
- if(aLineOn2S->NbPoints() > 1) {
+ if (aLineOn2S->NbPoints() <= 2)
+ {
+ if (aLineOn2S->NbPoints() == 2)
+ return aLocalWLine;
+ else
+ return aResult;
+ }
+
+ const Standard_Integer aMinNbBadDistr = 15;
+ const Standard_Integer aNbSingleBezier = 30;
+ // Avoid purge in case of C0 continuity:
+ // Intersection approximator may produce invalid curve after purge, example:
+ // bugs modalg_5 bug24731,
+ // Do not run purger when base number of points is too small.
+ if (theS1->UContinuity() == GeomAbs_C0 ||
+ theS1->VContinuity() == GeomAbs_C0 ||
+ theS2->UContinuity() == GeomAbs_C0 ||
+ theS2->VContinuity() == GeomAbs_C0 ||
+ nb < aNbSingleBezier)
+ {
+ return aLocalWLine;
+ }
+
+ // 1 - Delete point.
+ // 0 - Store point.
+ // -1 - Vertex point (not delete).
+ NCollection_Array1<Standard_Integer> aNewPointsHash(1, aLineOn2S->NbPoints());
+ for(i = 1; i <= aLineOn2S->NbPoints(); i++)
+ aNewPointsHash.SetValue(i, 0);
+
+ for(v = 1; v <= aLocalWLine->NbVertex(); v++)
+ {
+ IntPatch_Point aVertex = aLocalWLine->Vertex(v);
+ Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
+ aNewPointsHash.SetValue(avertexindex, -1);
+ }
+
+ // Workaround to handle case of small amount points after purge.
+ // Test "boolean boptuc_complex B5" and similar.
+ Standard_Integer aNbPnt = 0;
+
+ // Inital computations.
+ Standard_Real UonS1[3], VonS1[3], UonS2[3], VonS2[3];
+ aLineOn2S->Value(1).ParametersOnS1(UonS1[0], VonS1[0]);
+ aLineOn2S->Value(2).ParametersOnS1(UonS1[1], VonS1[1]);
+ aLineOn2S->Value(1).ParametersOnS2(UonS2[0], VonS2[0]);
+ aLineOn2S->Value(2).ParametersOnS2(UonS2[1], VonS2[1]);
+
+ gp_Pnt2d aBase2dPnt1(UonS1[0], VonS1[0]);
+ gp_Pnt2d aBase2dPnt2(UonS2[0], VonS2[0]);
+ gp_Vec2d aBase2dVec1(UonS1[1] - UonS1[0], VonS1[1] - VonS1[0]);
+ gp_Vec2d aBase2dVec2(UonS2[1] - UonS2[0], VonS2[1] - VonS2[0]);
+ gp_Pnt aBase3dPnt = aLineOn2S->Value(1).Value();
+ gp_Vec aBase3dVec(aLineOn2S->Value(1).Value(), aLineOn2S->Value(2).Value());
+
+ // Choose base tolerance and scale it to pipe algorithm.
+ const Standard_Real aBaseTolerance = Precision::Approximation();
+ Standard_Real aResS1Tol = Min(theS1->UResolution(aBaseTolerance),
+ theS1->VResolution(aBaseTolerance));
+ Standard_Real aResS2Tol = Min(theS2->UResolution(aBaseTolerance),
+ theS2->VResolution(aBaseTolerance));
+ Standard_Real aTol1 = aResS1Tol * aResS1Tol;
+ Standard_Real aTol2 = aResS2Tol * aResS2Tol;
+ Standard_Real aTol3d = aBaseTolerance * aBaseTolerance;
+
+ const Standard_Real aLimitCoeff = 0.99 * 0.99;
+ for(i = 3; i <= aLineOn2S->NbPoints(); i++)
+ {
+ Standard_Boolean isDeleteState = Standard_False;
+
+ aLineOn2S->Value(i).ParametersOnS1(UonS1[2], VonS1[2]);
+ aLineOn2S->Value(i).ParametersOnS2(UonS2[2], VonS2[2]);
+ gp_Pnt2d aPnt2dOnS1(UonS1[2], VonS1[2]);
+ gp_Pnt2d aPnt2dOnS2(UonS2[2], VonS2[2]);
+ const gp_Pnt& aPnt3d = aLineOn2S->Value(i).Value();
+
+ if (aNewPointsHash(i - 1) != - 1 &&
+ IsInsideIn2d(aBase2dPnt1, aBase2dVec1, aPnt2dOnS1, aTol1) &&
+ IsInsideIn2d(aBase2dPnt2, aBase2dVec2, aPnt2dOnS2, aTol2) &&
+ IsInsideIn3d(aBase3dPnt, aBase3dVec, aPnt3d, aTol3d) )
+ {
+ // Handle possible uneven parametrization on one of 2d subspaces.
+ // Delete point only when expected lengths are close to each other (aLimitCoeff).
+ // Example:
+ // c2d1 - line
+ // c3d - line
+ // c2d2 - geometrically line, but have uneven parametrization -> c2d2 is bspline.
+ gp_XY aPntOnS1[2]= { gp_XY(UonS1[1] - UonS1[0], VonS1[1] - VonS1[0])
+ , gp_XY(UonS1[2] - UonS1[1], VonS1[2] - VonS1[1])};
+ gp_XY aPntOnS2[2]= { gp_XY(UonS2[1] - UonS2[0], VonS2[1] - VonS2[0])
+ , gp_XY(UonS2[2] - UonS2[1], VonS2[2] - VonS2[1])};
+
+ Standard_Real aStepOnS1 = aPntOnS1[0].SquareModulus() / aPntOnS1[1].SquareModulus();
+ Standard_Real aStepOnS2 = aPntOnS2[0].SquareModulus() / aPntOnS2[1].SquareModulus();
+
+ Standard_Real aStepCoeff = Min(aStepOnS1, aStepOnS2) / Max(aStepOnS1, aStepOnS2);
+
+ if (aStepCoeff > aLimitCoeff)
+ {
+ // Set hash flag to "Delete" state.
+ isDeleteState = Standard_True;
+ aNewPointsHash.SetValue(i - 1, 1);
+
+ // Change middle point.
+ UonS1[1] = UonS1[2];
+ UonS2[1] = UonS2[2];
+ VonS1[1] = VonS1[2];
+ VonS2[1] = VonS2[2];
+ }
+ }
+
+ if (!isDeleteState)
+ {
+ // Compute new pipe parameters.
+ UonS1[0] = UonS1[1];
+ VonS1[0] = VonS1[1];
+ UonS2[0] = UonS2[1];
+ VonS2[0] = VonS2[1];
+
+ UonS1[1] = UonS1[2];
+ VonS1[1] = VonS1[2];
+ UonS2[1] = UonS2[2];
+ VonS2[1] = VonS2[2];
+
+ aBase2dPnt1.SetCoord(UonS1[0], VonS1[0]);
+ aBase2dPnt2.SetCoord(UonS2[0], VonS2[0]);
+ aBase2dVec1.SetCoord(UonS1[1] - UonS1[0], VonS1[1] - VonS1[0]);
+ aBase2dVec2.SetCoord(UonS2[1] - UonS2[0], VonS2[1] - VonS2[0]);
+ aBase3dPnt = aLineOn2S->Value(i - 1).Value();
+ aBase3dVec = gp_Vec(aLineOn2S->Value(i - 1).Value(), aLineOn2S->Value(i).Value());
+
+ aNbPnt++;
+ }
+ }
+
+ // Workaround to handle case of small amount of points after purge.
+ // Test "boolean boptuc_complex B5" and similar.
+ // This is possible since there are at least two points.
+ if (aNewPointsHash(1) == -1 &&
+ aNewPointsHash(2) == -1 &&
+ aNbPnt <= 3)
+ {
+ // Delete first.
+ aNewPointsHash(1) = 1;
+ }
+ if (aNewPointsHash(aLineOn2S->NbPoints() - 1) == -1 &&
+ aNewPointsHash(aLineOn2S->NbPoints() ) == -1 &&
+ aNbPnt <= 3)
+ {
+ // Delete last.
+ aNewPointsHash(aLineOn2S->NbPoints() ) = 1;
+ }
+
+ // Purgre when too small amount of points left.
+ if (aNbPnt <= 2)
+ {
+ for(i = aNewPointsHash.Lower(); i <= aNewPointsHash.Upper(); i++)
+ {
+ if (aNewPointsHash(i) != -1)
+ {
+ aNewPointsHash(i) = 1;
+ }
+ }
+ }
+
+ // Handle possible bad distribution of points,
+ // which are will converted into one single bezier curve (less than 30 points).
+ // Make distribution more even:
+ // max step will be nearly to 0.1 of param distance.
+ if (aNbPnt + 2 > aMinNbBadDistr &&
+ aNbPnt + 2 < aNbSingleBezier )
+ {
+ for(Standard_Integer anIdx = 1; anIdx <= 8; anIdx++)
+ {
+ Standard_Integer aHashIdx =
+ Standard_Integer(anIdx * aLineOn2S->NbPoints() / 9);
+
+ //Store this point.
+ aNewPointsHash(aHashIdx) = 0;
+ }
+ }
+
+ aTmpWLine = aLocalWLine;
+ Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S();
+ aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False);
+ Standard_Integer anOldLineIdx = 1, aVertexIdx = 1;
+ for(i = 1; i <= aNewPointsHash.Upper(); i++)
+ {
+ if (aNewPointsHash(i) == 0)
+ {
+ // Store this point.
+ aPurgedLineOn2S->Add(aLineOn2S->Value(i));
+ anOldLineIdx++;
+ }
+ else if (aNewPointsHash(i) == -1)
+ {
+ // Add vertex.
+ IntPatch_Point aVertex = aTmpWLine->Vertex(aVertexIdx++);
+ aVertex.SetParameter(anOldLineIdx++);
+ aLocalWLine->AddVertex(aVertex);
+ aPurgedLineOn2S->Add(aLineOn2S->Value(i));
+ }
+ }
+
+ if(aPurgedLineOn2S->NbPoints() > 1) {
aResult = aLocalWLine;
}
return aResult;
const Handle(GeomAdaptor_HSurface)& theSurface2,
const TopoDS_Face& theFace1,
const TopoDS_Face& theFace2,
- const IntTools_LineConstructor& theLConstructor,
+ const GeomInt_LineConstructor& theLConstructor,
const Standard_Boolean theAvoidLConstructor,
IntPatch_SequenceOfLine& theNewLines,
Standard_Real& theReachedTol3d,
aParameter=V;
}
- IntTools_Tools::AdjustPeriodic(aParameter,
+ GeomInt::AdjustPeriodic(aParameter,
alowerboundary,
aupperboundary,
aPeriod,
else {
Standard_Real aPeriod = (parit == 0) ? aGASurface->UPeriod() : aGASurface->VPeriod();
Standard_Real anoffset, anAdjustPar;
- IntTools_Tools::AdjustPeriodic(aParameter, alowerboundary, aupperboundary,
+ GeomInt::AdjustPeriodic(aParameter, alowerboundary, aupperboundary,
aPeriod, anAdjustPar, anoffset);
bIsPointOnBoundary=
Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
Standard_Real aParameter = (bIsUBoundary) ? U : V;
Standard_Real anoffset, anAdjustPar;
- IntTools_Tools::AdjustPeriodic(aParameter, alowerboundary, aupperboundary,
+ GeomInt::AdjustPeriodic(aParameter, alowerboundary, aupperboundary,
aPeriod, anAdjustPar, anoffset);
Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
bCheckAngle1 = Standard_True;
aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
- if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
+ if(aNewVec.SquareMagnitude() < gp::Resolution()) {
aNewP.SetValue((surfit == 0), anewU, anewV);
bCheckAngle1 = Standard_False;
}
bCheckAngle2 = Standard_True;
aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
- if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
+ if(aNewVec.SquareMagnitude() < gp::Resolution()) {
bCheckAngle2 = Standard_False;
}
}
aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
- if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
+ if(aVecOld.SquareMagnitude() <= gp::Resolution()) {
continue;
}
else {
ap2.SetX(nU2);
ap2.SetY(nV2);
- if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
+ if(ap1.SquareDistance(ap2) > gp::Resolution()) {
break;
}
}
}
return aIndex;
}
-#ifdef DEB_DUMPWLINE
+#ifdef OCCT_DEBUG_DUMPWLINE
//=======================================================================
//function : DumpWLine
//purpose :
}
aV2D.SetCoord(aC[0], aC[1]);
}
+
//=======================================================================
-//function : FindMaxSquareDistance
-//purpose :
+// Function : FindMaxDistance
+// purpose :
//=======================================================================
-Standard_Real FindMaxSquareDistance (const Standard_Real aT1,
- const Standard_Real aT2,
- const Standard_Real aEps,
- const Handle(Geom_Curve)& aC3D,
- const Handle(Geom2d_Curve)& aC2D1,
- const Handle(Geom2d_Curve)& aC2D2,
- const Handle(GeomAdaptor_HSurface)& myHS1,
- const Handle(GeomAdaptor_HSurface)& myHS2,
- const TopoDS_Face& myFace1,
- const TopoDS_Face& myFace2,
- const Handle(IntTools_Context)& myContext)
+Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ const TopoDS_Face& theFace,
+ const Handle(IntTools_Context)& theContext)
{
- Standard_Real aA, aB, aCf, aX1, aX2, aF1, aF2, aX, aF;
+ Standard_Integer aNbS;
+ Standard_Real aT1, aT2, aDt, aD, aDMax, anEps;
//
- aCf=1.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.));
- aA=aT1;
- aB=aT2;
- aX1=aB-(aB-aA)/aCf;
- aF1=MaxSquareDistance(aX1,
- aC3D, aC2D1, aC2D2, myHS1, myHS2, myFace1, myFace2, myContext);
- aX2=aA+(aB-aA)/aCf;
- aF2=MaxSquareDistance(aX2,
- aC3D, aC2D1, aC2D2, myHS1, myHS2, myFace1, myFace2, myContext);
+ aNbS = 11;
+ aDt = (theLast - theFirst) / aNbS;
+ aDMax = 0.;
+ anEps = 1.e-4 * aDt;
//
- for(;;) {
+ GeomAPI_ProjectPointOnSurf& aProjPS = theContext->ProjPS(theFace);
+ aT2 = theFirst;
+ for (;;) {
+ aT1 = aT2;
+ aT2 += aDt;
//
- if (fabs(aA-aB)<aEps) {
- aX=0.5*(aA+aB);
- aF=MaxSquareDistance(aX,
- aC3D, aC2D1, aC2D2, myHS1, myHS2, myFace1, myFace2, myContext);
+ if (aT2 > theLast) {
break;
}
- if (aF1<aF2){
- aA=aX1;
- aX1=aX2;
- aF1=aF2;
- aX2=aA+(aB-aA)/aCf;
- aF2=MaxSquareDistance(aX2,
- aC3D, aC2D1, aC2D2, myHS1, myHS2, myFace1, myFace2, myContext);
-
- }
- else {
- aB=aX2;
- aX2=aX1;
- aF2=aF1;
- aX1=aB-(aB-aA)/aCf;
- aF1=MaxSquareDistance(aX1,
- aC3D, aC2D1, aC2D2, myHS1, myHS2, myFace1, myFace2, myContext);
+ //
+ aD = FindMaxDistance(theCurve, aT1, aT2, aProjPS, anEps);
+ if (aD > aDMax) {
+ aDMax = aD;
}
}
- return aF;
+ //
+ return aDMax;
}
+
//=======================================================================
-//function : MaxSquareDistance
-//purpose :
+// Function : FindMaxDistance
+// purpose :
//=======================================================================
-Standard_Real MaxSquareDistance (const Standard_Real aT,
- const Handle(Geom_Curve)& aC3D,
- const Handle(Geom2d_Curve)& aC2D1,
- const Handle(Geom2d_Curve)& aC2D2,
- const Handle(GeomAdaptor_HSurface) myHS1,
- const Handle(GeomAdaptor_HSurface) myHS2,
- const TopoDS_Face& aF1,
- const TopoDS_Face& aF2,
- const Handle(IntTools_Context)& aCtx)
+Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ GeomAPI_ProjectPointOnSurf& theProjPS,
+ const Standard_Real theEps)
{
- Standard_Boolean bIsDone;
- Standard_Integer i;
- Standard_Real aU, aV, aD2Max, aD2;
- gp_Pnt2d aP2D;
- gp_Pnt aP, aPS;
+ Standard_Real aA, aB, aCf, aX, aX1, aX2, aF1, aF2, aF;
//
- aD2Max=0.;
+ aCf = 0.61803398874989484820458683436564;//(sqrt(5.)-1)/2.;
+ aA = theFirst;
+ aB = theLast;
//
- aC3D->D0(aT, aP);
- if (aC3D.IsNull()) {
- return aD2Max;
- }
+ aX1 = aB - aCf * (aB - aA);
+ aF1 = MaxDistance(theC, aX1, theProjPS);
+ aX2 = aA + aCf * (aB - aA);
+ aF2 = MaxDistance(theC, aX2, theProjPS);
//
- for (i=0; i<2; ++i) {
- const Handle(GeomAdaptor_HSurface)& aGHS=(!i) ? myHS1 : myHS2;
- const TopoDS_Face &aF=(!i) ? aF1 : aF2;
- const Handle(Geom2d_Curve)& aC2D=(!i) ? aC2D1 : aC2D2;
- //
- if (!aC2D.IsNull()) {
- aC2D->D0(aT, aP2D);
- aP2D.Coord(aU, aV);
- aGHS->D0(aU, aV, aPS);
- aD2=aP.SquareDistance(aPS);
- if (aD2>aD2Max) {
- aD2Max=aD2;
- }
+ for (;;) {
+ if ((aB - aA) < theEps) {
+ break;
}
//
- GeomAPI_ProjectPointOnSurf& aProjector=aCtx->ProjPS(aF);
- //
- aProjector.Perform(aP);
- bIsDone=aProjector.IsDone();
- if (bIsDone) {
- aProjector.LowerDistanceParameters(aU, aV);
- aGHS->D0(aU, aV, aPS);
- aD2=aP.SquareDistance(aPS);
- if (aD2>aD2Max) {
- aD2Max=aD2;
- }
+ if (aF1 > aF2) {
+ aB = aX2;
+ aX2 = aX1;
+ aF2 = aF1;
+ aX1 = aB - aCf * (aB - aA);
+ aF1 = MaxDistance(theC, aX1, theProjPS);
+ }
+ else {
+ aA = aX1;
+ aX1 = aX2;
+ aF1 = aF2;
+ aX2 = aA + aCf * (aB - aA);
+ aF2 = MaxDistance(theC, aX2, theProjPS);
}
}
//
- return aD2Max;
+ aX = 0.5 * (aA + aB);
+ aF = MaxDistance(theC, aX, theProjPS);
+ //
+ if (aF1 > aF) {
+ aF = aF1;
+ }
+ //
+ if (aF2 > aF) {
+ aF = aF2;
+ }
+ //
+ return aF;
+}
+
+//=======================================================================
+// Function : MaxDistance
+// purpose :
+//=======================================================================
+Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
+ const Standard_Real aT,
+ GeomAPI_ProjectPointOnSurf& theProjPS)
+{
+ Standard_Real aD;
+ gp_Pnt aP;
+ //
+ theC->D0(aT, aP);
+ theProjPS.Perform(aP);
+ aD = theProjPS.NbPoints() ? theProjPS.LowerDistance() : 0.;
+ //
+ return aD;
}
//=======================================================================
}
return !bRet;
}
+//=======================================================================
+//function : CorrectPlaneBoundaries
+//purpose :
+//=======================================================================
+ void CorrectPlaneBoundaries(Standard_Real& aUmin,
+ Standard_Real& aUmax,
+ Standard_Real& aVmin,
+ Standard_Real& aVmax)
+{
+ if (!(Precision::IsInfinite(aUmin) ||
+ Precision::IsInfinite(aUmax))) {
+ Standard_Real dU;
+ //
+ dU=0.1*(aUmax-aUmin);
+ aUmin=aUmin-dU;
+ aUmax=aUmax+dU;
+ }
+ if (!(Precision::IsInfinite(aVmin) ||
+ Precision::IsInfinite(aVmax))) {
+ Standard_Real dV;
+ //
+ dV=0.1*(aVmax-aVmin);
+ aVmin=aVmin-dV;
+ aVmax=aVmax+dV;
+ }
+}