diff --git a/src/AppDef/AppDef_Compute.hxx b/src/AppDef/AppDef_Compute.hxx index c387e88122..a65bbd343a 100644 --- a/src/AppDef/AppDef_Compute.hxx +++ b/src/AppDef/AppDef_Compute.hxx @@ -116,7 +116,7 @@ public: Standard_EXPORT const AppParCurves_MultiBSpCurve& SplineValue(); //! returns the type of parametrization - Standard_EXPORT void Parametrization (Approx_ParametrizationType& partype) const; + Standard_EXPORT Approx_ParametrizationType Parametrization () const; //! returns the new parameters of the approximation //! corresponding to the points of the multicurve . diff --git a/src/AppParCurves/AppParCurves_LeastSquare.gxx b/src/AppParCurves/AppParCurves_LeastSquare.gxx index d21e2765c5..0915499a13 100644 --- a/src/AppParCurves/AppParCurves_LeastSquare.gxx +++ b/src/AppParCurves/AppParCurves_LeastSquare.gxx @@ -56,6 +56,92 @@ static int FlatLength(const TColStd_Array1OfInteger& Mults) { return sum; } +//======================================================================= +//function : CheckTangents +//purpose : Checks if theArrTg3d and theArrTg2d have direction +// corresponded to the direction between theArrPt1 and theArrPt2. +// If it is not then reverses tangent vectors. +// theArrPt1 (as same as theArrPt2) is sub-set of all 3D-points in +// one multy-point (multy-point is union of sets of 2D- and 3D-points). +// +//ATTENTION!!! +// The property of correlation between Tg3d and Tg2d is used here. +// Therefore, only 3D-coinciding is checked. +//======================================================================= +static void CheckTangents(const TColgp_Array1OfPnt& theArrPt1, + const TColgp_Array1OfPnt& theArrPt2, + TColgp_Array1OfVec& theArrTg3d, + TColgp_Array1OfVec2d& theArrTg2d) +{ + if(theArrPt1.Lower() != theArrPt2.Lower()) + return; + + if(theArrPt1.Upper() != theArrPt2.Upper()) + return; + + if(theArrTg3d.Length() != theArrPt1.Length()) + return; + + Standard_Boolean isToChangeDir = Standard_False; + + for(Standard_Integer i = theArrPt1.Lower(); i <= theArrPt1.Upper(); i++) + { + const gp_Vec aV1(theArrPt1(i), theArrPt2(i)); + const gp_Vec& aV2 = theArrTg3d(i); + + if(aV1.Dot(aV2) < 0.0) + { + isToChangeDir = Standard_True; + break; + } + } + + if(!isToChangeDir) + return; + + //Change directions for every 2D- and 3D-tangents + + for(Standard_Integer i = theArrTg3d.Lower(); i <= theArrTg3d.Upper(); i++) + { + theArrTg3d(i).Reverse(); + } + + for(Standard_Integer i = theArrTg2d.Lower(); i <= theArrTg2d.Upper(); i++) + { + theArrTg2d(i).Reverse(); + } +} + +//======================================================================= +//function : CheckTangents +//purpose : Checks if theArrTg2d have direction +// corresponded to the direction between theArrPt1 and theArrPt2. +// If it is not then reverses tangent vector. +// theArrPt1 (as same as theArrPt2) is sub-set of all 2D-points in +// one multy-point (multy-point is union of sets of 2D- and 3D-points). +//======================================================================= +static void CheckTangents(const TColgp_Array1OfPnt2d& theArrPt1, + const TColgp_Array1OfPnt2d& theArrPt2, + TColgp_Array1OfVec2d& theArrTg2d) +{ + if(theArrPt1.Lower() != theArrPt2.Lower()) + return; + + if(theArrPt1.Upper() != theArrPt2.Upper()) + return; + + for(Standard_Integer i = theArrPt1.Lower(); i <= theArrPt1.Upper(); i++) + { + const gp_Vec2d aV1(theArrPt1(i), theArrPt2(i)); + const gp_Vec2d& aV2 = theArrTg2d(i); + + if(aV1.Dot(aV2) < 0.0) + { + theArrTg2d(i).Reverse(); + } + } +} + AppParCurves_LeastSquare:: AppParCurves_LeastSquare(const MultiLine& SSP, @@ -893,14 +979,20 @@ void AppParCurves_LeastSquare::Perform(const math_Vector& Parameters, - +//======================================================================= +//function : Affect +//purpose : Index is an ID of the point in MultiLine. Every point is set of +// several 3D- and 2D-points. E.g. every points of Walking-line, +// obtained in intersection algorithm, is set of one 3D points +// (nbP == 1) and two 2D-points (nbP2d == 2). +//======================================================================= void AppParCurves_LeastSquare::Affect(const MultiLine& SSP, const Standard_Integer Index, AppParCurves_Constraint& Cons, math_Vector& Vt, math_Vector& Vc) { - // Vt: vecteur tangent, Vc: vecteur courbure. + // Vt: vector of tangent, Vc: vector of curvature. if (Cons >= AppParCurves_TangencyPoint) { Standard_Integer i, i2 = 1; @@ -908,59 +1000,99 @@ void AppParCurves_LeastSquare::Affect(const MultiLine& SSP, Standard_Integer mynbP2d = nbP2d, mynbP = nbP; if (nbP2d == 0) mynbP2d = 1; if (nbP == 0) mynbP = 1; - TColgp_Array1OfPnt TabP(1, mynbP); - TColgp_Array1OfPnt2d TabP2d(1, mynbP2d); TColgp_Array1OfVec TabV(1, mynbP); TColgp_Array1OfVec2d TabV2d(1, mynbP2d); - if (Cons == AppParCurves_CurvaturePoint) { - if (nbP != 0 && nbP2d != 0) { - Ok = ToolLine::Curvature(SSP, Index,TabV,TabV2d); - if (!Ok) { Cons = AppParCurves_TangencyPoint;} + if (Cons == AppParCurves_CurvaturePoint) + { + if (nbP != 0 && nbP2d != 0) + { + Ok = ToolLine::Curvature(SSP, Index,TabV,TabV2d); + if (!Ok) { Cons = AppParCurves_TangencyPoint;} } - else if (nbP2d != 0) { - Ok = ToolLine::Curvature(SSP, Index, TabV2d); - if (!Ok) { Cons = AppParCurves_TangencyPoint;} + else if (nbP2d != 0) + { + Ok = ToolLine::Curvature(SSP, Index, TabV2d); + if (!Ok) { Cons = AppParCurves_TangencyPoint;} } else { - Ok = ToolLine::Curvature(SSP, Index, TabV); - if (!Ok) { Cons = AppParCurves_TangencyPoint;} + Ok = ToolLine::Curvature(SSP, Index, TabV); + if (!Ok) { Cons = AppParCurves_TangencyPoint;} } if (Ok) { - for (i = 1; i <= nbP; i++) { - (TabV(i)).Coord(Vc(i2), Vc(i2+1), Vc(i2+2)); - i2 += 3; - } - for (i = 1; i <= nbP2d; i++) { - (TabV2d(i)).Coord(Vc(i2), Vc(i2+1)); - i2 += 2; - } + for (i = 1; i <= nbP; i++) { + (TabV(i)).Coord(Vc(i2), Vc(i2+1), Vc(i2+2)); + i2 += 3; + } + + for (i = 1; i <= nbP2d; i++) { + (TabV2d(i)).Coord(Vc(i2), Vc(i2+1)); + i2 += 2; + } } } i2 = 1; if (Cons >= AppParCurves_TangencyPoint) { if (nbP != 0 && nbP2d != 0) { - Ok = ToolLine::Tangency(SSP, Index, TabV, TabV2d); - if (!Ok) { Cons = AppParCurves_PassPoint;} + Ok = ToolLine::Tangency(SSP, Index, TabV, TabV2d); + if (!Ok) { Cons = AppParCurves_PassPoint;} } else if (nbP2d != 0) { - Ok = ToolLine::Tangency(SSP, Index, TabV2d); - if (!Ok) { Cons = AppParCurves_PassPoint;} + Ok = ToolLine::Tangency(SSP, Index, TabV2d); + if (!Ok) { Cons = AppParCurves_PassPoint;} } else { - Ok = ToolLine::Tangency(SSP, Index, TabV); - if (!Ok) { Cons = AppParCurves_PassPoint;} + Ok = ToolLine::Tangency(SSP, Index, TabV); + if (!Ok) { Cons = AppParCurves_PassPoint;} } - if (Ok) { - for (i = 1; i <= nbP; i++) { - (TabV(i)).Coord(Vt(i2), Vt(i2+1), Vt(i2+2)); - i2 += 3; - } - for (i = 1; i <= nbP2d; i++) { - (TabV2d(i)).Coord(Vt(i2), Vt(i2+1)); - i2 += 2; - } + + if (Ok) + { + TColgp_Array1OfPnt anArrPts3d1(1, mynbP), anArrPts3d2(1, mynbP); + + if(nbP != 0) + { + if(Index < ToolLine::LastPoint(SSP)) + { + ToolLine::Value(SSP, Index, anArrPts3d1); + ToolLine::Value(SSP, Index+1, anArrPts3d2); + } + else + {// (Index == ToolLine::LastPoint(theML)) + ToolLine::Value(SSP, Index-1, anArrPts3d1); + ToolLine::Value(SSP, Index, anArrPts3d2); + } + + CheckTangents(anArrPts3d1, anArrPts3d2, TabV, TabV2d); + } + else if(nbP2d != 0) + { + TColgp_Array1OfPnt2d anArrPts2d1(1, mynbP2d), anArrPts2d2(1, mynbP2d); + + if(Index < ToolLine::LastPoint(SSP)) + { + ToolLine::Value(SSP, Index, anArrPts3d1, anArrPts2d1); + ToolLine::Value(SSP, Index+1, anArrPts3d2, anArrPts2d2); + } + else + {// (Index == ToolLine::LastPoint(theML)) + ToolLine::Value(SSP, Index-1, anArrPts3d1, anArrPts2d1); + ToolLine::Value(SSP, Index, anArrPts3d2, anArrPts2d2); + } + + CheckTangents(anArrPts2d1, anArrPts2d2, TabV2d); + } + + for (i = 1; i <= nbP; i++) { + (TabV(i)).Coord(Vt(i2), Vt(i2+1), Vt(i2+2)); + i2 += 3; + } + + for (i = 1; i <= nbP2d; i++) { + (TabV2d(i)).Coord(Vt(i2), Vt(i2+1)); + i2 += 2; + } } } } diff --git a/src/Approx/Approx_ComputeLine.gxx b/src/Approx/Approx_ComputeLine.gxx index 94aabbaf47..edc6086e24 100644 --- a/src/Approx/Approx_ComputeLine.gxx +++ b/src/Approx/Approx_ComputeLine.gxx @@ -1274,7 +1274,7 @@ void Approx_ComputeLine::Error(const Standard_Integer Index, tol2d = Tolers2d.Value(Index); } -void Approx_ComputeLine::Parametrization(Approx_ParametrizationType& partype) const +Approx_ParametrizationType Approx_ComputeLine::Parametrization() const { - partype = Par; + return Par; } diff --git a/src/ApproxInt/ApproxInt_Approx.gxx b/src/ApproxInt/ApproxInt_Approx.gxx index 911e90fe75..a59c2cf8e6 100644 --- a/src/ApproxInt/ApproxInt_Approx.gxx +++ b/src/ApproxInt/ApproxInt_Approx.gxx @@ -23,135 +23,68 @@ #include #include -const Standard_Integer LimRajout = 5; -const Standard_Integer NbPntMaxDecoupage = 30; -const Standard_Real RatioTol = 1.5; +// If quantity of points is less than aMinNbPointsForApprox +// then interpolation is used. +const Standard_Integer aMinNbPointsForApprox = 5; -//======================================================================= -//function : MINABS3 -//purpose : Compute minimal absolute distance to 0 from 3 values. -//======================================================================= -static Standard_Real MINABS3(Standard_Real a, Standard_Real b,Standard_Real c) -{ - if(a<0.0) a=-a; - if(b<0.0) b=-b; - if(c<0.0) c=-c; - if(a>c) a=c; - if(a>b) a=b; - return(a); -} - -//======================================================================= -//function : MINABS4 -//purpose : Compute minimal absolute distance to 0 from 4 values. -//======================================================================= -static Standard_Real MINABS4(Standard_Real a, Standard_Real b,Standard_Real c,Standard_Real d) -{ - if(a<0.0) a=-a; - if(b<0.0) b=-b; - if(c<0.0) c=-c; - if(d<0.0) d=-d; - if(a>c) a=c; - if(a>b) a=b; - if(a>d) a=d; - return(a); -} +// This constant should be removed in the future. +const Standard_Real RatioTol = 1.5 ; //======================================================================= //function : ComputeTrsf3d //purpose : //======================================================================= static void ComputeTrsf3d(const Handle(TheWLine)& theline, - Standard_Real& Xo, Standard_Real& Ax, - Standard_Real& Yo, Standard_Real& Ay, - Standard_Real& Zo, Standard_Real& Az) + Standard_Real& theXo, + Standard_Real& theYo, + Standard_Real& theZo) { - Standard_Integer nbp = theline->NbPnts(); - Standard_Real z0,z1,x0,x1,y0,y1; - z0=y0=x0=RealLast(); - z1=y1=x1=RealFirst(); - for(Standard_Integer i=1;i<=nbp;i++) { - const gp_Pnt& P = theline->Point(i).Value(); - Standard_Real X = P.X(); - Standard_Real Y = P.Y(); - Standard_Real Z = P.Z(); - if(Xx1) x1=X; - if(Yy1) y1=Y; - if(Zz1) z1=Z; - } - Standard_Real dx = x1-x0; - Standard_Real dy = y1-y0; - Standard_Real dz = z1-z0; - Standard_Real MaxD = dx; - if(MaxD < dy) MaxD=dy; - if(MaxD < dz) MaxD=dz; - Standard_Real MaxDF = 0.01*MaxD; + const Standard_Integer aNbPnts = theline->NbPnts(); + Standard_Real aXmin = RealLast(), aYmin = RealLast(), aZmin = RealLast(); + for(Standard_Integer i=1;i<=aNbPnts;i++) + { + const gp_Pnt& P = theline->Point(i).Value(); + aXmin = Min(P.X(), aXmin); + aYmin = Min(P.Y(), aYmin); + aZmin = Min(P.Z(), aZmin); + } - if(MaxDF<1e-12) - MaxDF=1.0; - - if(dx > MaxDF) { Ax = 1.0 / dx; Xo = -Ax * x0; } - else { Ax = 1.0/( MaxDF) ; Xo = -Ax*x0; } - if(dy > MaxDF) { Ay = 1.0 / dy; Yo = -Ay * y0; } - else { Ay = 1.0/( MaxDF); Yo = -Ay*y0; } - if(dz > MaxDF) { Az = 1.0 / dz; Zo = -Az * z0; } - else { Az = 1.0/(MaxDF); Zo = -Az*z0; } + theXo = -aXmin; + theYo = -aYmin; + theZo = -aZmin; } //======================================================================= //function : ComputeTrsf2d -//purpose : +//purpose : //======================================================================= static void ComputeTrsf2d(const Handle(TheWLine)& theline, - Standard_Real& Uo, Standard_Real& Au, - Standard_Real& Vo, Standard_Real& Av, const Standard_Boolean onFirst, - const Standard_Real UVResRatio = 1.0) -{ - Standard_Integer nbp = theline->NbPnts(); - Standard_Real u0,u1,v0,v1; - u0 = v0 = RealLast(); - u1 = v1 = RealFirst(); - // pointer to a member-function - void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const; - if (onFirst) - pfunc = &IntSurf_PntOn2S::ParametersOnS1; - else - pfunc = &IntSurf_PntOn2S::ParametersOnS2; - for(Standard_Integer i=1;i<=nbp;i++) { - const IntSurf_PntOn2S& POn2S = theline->Point(i); - Standard_Real U,V; - (POn2S.*pfunc)(U,V); - if(Uu1) u1=U; - if(Vv1) v1=V; - } + Standard_Real& theUo, + Standard_Real& theVo) +{ + const Standard_Integer aNbPnts = theline->NbPnts(); + Standard_Real aUmin = RealLast(), aVmin = RealLast(); - Standard_Real du = (u1-u0); - Standard_Real dv = (v1-v0); + // pointer to a member-function + void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const; - if (UVResRatio > 1.) - du *= UVResRatio; - else if (UVResRatio < 1.) - dv /= UVResRatio; + if (onFirst) + pfunc = &IntSurf_PntOn2S::ParametersOnS1; + else + pfunc = &IntSurf_PntOn2S::ParametersOnS2; + + for(Standard_Integer i=1; i<=aNbPnts; i++) + { + const IntSurf_PntOn2S& POn2S = theline->Point(i); + Standard_Real U,V; + (POn2S.*pfunc)(U,V); + aUmin = Min(U, aUmin); + aVmin = Min(V, aVmin); + } - Standard_Real MaxUV=du; - if(MaxUV MaxUVF) { Au = 1.0 / du; Uo = -Au * u0; } - else { Au = 1.0/(MaxUVF); Uo = -Au*u0; } - if(dv > MaxUVF) { Av = 1.0 / dv; Vo = -Av * v0; } - else { Av = 1.0/(MaxUVF); Vo = -Av*v0; } + theUo = -aUmin; + theVo = -aVmin; } //======================================================================= @@ -219,22 +152,23 @@ static void Parameters(const ApproxInt_TheMultiLine& Line, } //======================================================================= -//function : ApproxInt_Approx -//purpose : Constructor. +//function : Default constructor +//purpose : //======================================================================= -ApproxInt_Approx::ApproxInt_Approx() -: myComputeLine(4, 8, 0.001, 0.001, 5, Standard_True), - myComputeLineBezier(4, 8, 0.001, 0.001, 5, Standard_True) +ApproxInt_Approx::ApproxInt_Approx(): + myComputeLine(4, 8, 0.001, 0.001, 5), + myComputeLineBezier(4, 8, 0.001, 0.001, 5), + myWithTangency(Standard_True), + myTol3d(0.001), + myTol2d(0.001), + myDegMin(4), + myDegMax(8), + myNbIterMax(5), + myTolReached3d(0.0), + myTolReached2d(0.0) { myComputeLine.SetContinuity(2); - myData.myBezierApprox = Standard_True; - - myRelativeTol = Standard_True; - myNbPntMax = NbPntMaxDecoupage; - myData.myMinFactorXYZ = 0.0; - myData.myMinFactorUV = 0.0; - myTolReached3d = myTolReached2d = 0.0; - myUVRes1 = myUVRes2 = 1.0; + //myComputeLineBezier.SetContinuity(2); } //======================================================================= @@ -251,43 +185,35 @@ void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline, // Prepare DS. prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); - Standard_Integer nbpntbez = indicemax-indicemin; - if(nbpntbez < LimRajout) + const Standard_Integer nbpntbez = myData.indicemax - myData.indicemin; + if(nbpntbez < aMinNbPointsForApprox) myData.myBezierApprox = Standard_False; else myData.myBezierApprox = Standard_True; // Fill data structure. - fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2); + fillData(theline); // Build knots. buildKnots(theline, NULL); - - Standard_Boolean cut = Standard_True; - if(myRelativeTol==Standard_False) + if (myKnots.Length() == 2 && + indicemax - indicemin > 2 * myData.myNbPntMax) { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); + // At least 3 knots for BrepApprox. + myKnots.ChangeLast() = (indicemax - indicemin) / 2; + myKnots.Append(indicemax); } + myComputeLine.Init (myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization); + myComputeLineBezier.Init(myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization); + buildCurve(theline, NULL); } //======================================================================= //function : Perform -//purpose : Param-Param perform. +//purpose : Definition of next steps according to surface types +// (i.e. coordination algorithm). //======================================================================= void ApproxInt_Approx::Perform(const ThePSurface& Surf1, const ThePSurface& Surf2, @@ -299,95 +225,26 @@ void ApproxInt_Approx::Perform(const ThePSurface& Surf1, const Standard_Integer indicemax) { - GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1); - GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2); - if ((typeS1 != GeomAbs_Plane && - typeS1 != GeomAbs_Cylinder && - typeS1 != GeomAbs_Sphere && - typeS1 != GeomAbs_Cone) && - (typeS2 != GeomAbs_Plane && - typeS2 != GeomAbs_Cylinder && - typeS2 != GeomAbs_Sphere && - typeS2 != GeomAbs_Cone)) - { - // Prepare DS. - prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); + myTolReached3d = myTolReached2d = 0.; - // Non-analytical case: Param-Param perform. - ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2); + const GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1); + const GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2); - Standard_Integer nbpntbez = indicemax-indicemin; - if(nbpntbez < LimRajout) - myData.myBezierApprox = Standard_False; - else - myData.myBezierApprox = Standard_True; + const Standard_Boolean isQuadric = ((typeS1 == GeomAbs_Plane) || + (typeS1 == GeomAbs_Cylinder) || + (typeS1 == GeomAbs_Sphere) || + (typeS1 == GeomAbs_Cone) || + (typeS2 == GeomAbs_Plane) || + (typeS2 == GeomAbs_Cylinder) || + (typeS2 == GeomAbs_Sphere) || + (typeS2 == GeomAbs_Cone)); - Standard_Boolean cut = Standard_True; - if(nbpntbez < LimRajout) - { - cut = Standard_False; - } - - Standard_Real aS1URes = ThePSurfaceTool::UResolution(Surf1, 1.0), - aS1VRes = ThePSurfaceTool::VResolution(Surf1, 1.0), - aS2URes = ThePSurfaceTool::UResolution(Surf2, 1.0), - aS2VRes = ThePSurfaceTool::VResolution(Surf2, 1.0); - if(ApproxU1V1) - myUVRes1 = aS1URes / aS1VRes; - if(ApproxU2V2) - myUVRes2 = aS2URes / aS2VRes; - - // Fill data structure. - fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2); - - // Build knots. - Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces; - buildKnots(theline, ptrsvsurf); - - if(myRelativeTol==Standard_False) - { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - } - else - { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - cut, - myData.parametrization); - } - - buildCurve(theline, ptrsvsurf); - } - else + if(isQuadric) { IntSurf_Quadric Quad; Standard_Boolean SecondIsImplicit=Standard_False; switch (typeS1) { - case GeomAbs_Plane: Quad.SetValue(ThePSurfaceTool::Plane(Surf1)); break; @@ -427,160 +284,51 @@ void ApproxInt_Approx::Perform(const ThePSurface& Surf1, default: break; - } + }//switch (typeS2) } + break; - } - if(SecondIsImplicit) - { - Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax); - } - else - { - Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax); - } + }//switch (typeS1) + + Perform(Quad, (SecondIsImplicit? Surf1: Surf2), theline, + ApproxXYZ, ApproxU1V1, ApproxU2V2, + indicemin, indicemax, !SecondIsImplicit); + + return; } -} -//======================================================================= -//function : SetParameters -//purpose : -//======================================================================= -void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d, - const Standard_Real Tol2d, - const Standard_Integer DegMin, - const Standard_Integer DegMax, - const Standard_Integer NbIterMax, - const Standard_Boolean ApproxWithTangency, - const Approx_ParametrizationType Parametrization) -{ - myWithTangency = ApproxWithTangency; - myTol3d = Tol3d / RatioTol; - myTol2d = Tol2d / RatioTol; - myDegMin = DegMin; - myDegMax = DegMax; - myNbIterMax = NbIterMax; - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - Standard_True, - Parametrization); + // Here, isQuadric == FALSE. - if(!ApproxWithTangency) { - myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); - } - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - Standard_True, - Parametrization); - if(!ApproxWithTangency) - { - myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); - } - myData.myBezierApprox = Standard_True; -} - -//======================================================================= -//function : SetParameters -//purpose : Set parameters with RelativeTol flag and NbPntMax value. -//======================================================================= -void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d, - const Standard_Real Tol2d, - const Standard_Boolean RelativeTol, - const Standard_Integer DegMin, - const Standard_Integer DegMax, - const Standard_Integer NbIterMax, - const Standard_Integer NbPntMax, - const Standard_Boolean ApproxWithTangency, - const Approx_ParametrizationType Parametrization) -{ - myNbPntMax = NbPntMax ; - myRelativeTol = RelativeTol ; - SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ; -} - -//======================================================================= -//function : Perform -//purpose : Param-Analytic perform. -//======================================================================= -void ApproxInt_Approx::Perform(const ThePSurface& PSurf, - const TheISurface& ISurf, - const Handle(TheWLine)& theline, - const Standard_Boolean ApproxXYZ, - const Standard_Boolean ApproxU1V1, - const Standard_Boolean ApproxU2V2, - const Standard_Integer indicemin, - const Standard_Integer indicemax) -{ // Prepare DS. prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); - // Non-analytical case: Param-Analytic perform. - ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf); + // Non-analytical case: Param-Param perform. + ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2); Standard_Integer nbpntbez = indicemax-indicemin; - if(nbpntbez < LimRajout) - myData.myBezierApprox = Standard_False; - else - myData.myBezierApprox = Standard_True; - Standard_Boolean cut = Standard_True; - if(nbpntbez < LimRajout) + if(nbpntbez < aMinNbPointsForApprox) { - cut = Standard_False; + myData.myBezierApprox = Standard_False; + } + else + { + myData.myBezierApprox = Standard_True; } - - Standard_Real aS1URes = ThePSurfaceTool::UResolution(PSurf, 1.0), - aS1VRes = ThePSurfaceTool::VResolution(PSurf, 1.0); - if(ApproxU1V1) - myUVRes1 = aS1URes / aS1VRes; // Fill data structure. - fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2); + fillData(theline); + + const Standard_Boolean cut = myData.myBezierApprox; + const Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces; // Build knots. - Standard_Address ptrsvsurf = &myImpPrmSvSurfaces; buildKnots(theline, ptrsvsurf); - if(myRelativeTol==Standard_False) - { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - } - else - { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - cut, - myData.parametrization); - } + myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, + myNbIterMax, cut, myData.parametrization); + myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, + myNbIterMax, cut, myData.parametrization); buildCurve(theline, ptrsvsurf); } @@ -596,76 +344,79 @@ void ApproxInt_Approx::Perform(const TheISurface& ISurf, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, - const Standard_Integer indicemax) + const Standard_Integer indicemax, + const Standard_Boolean isTheQuadFirst) { // Prepare DS. prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); // Non-analytical case: Analytic-Param perform. - ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf, PSurf); + ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces = + isTheQuadFirst? ApproxInt_TheImpPrmSvSurfaces(ISurf, PSurf): + ApproxInt_TheImpPrmSvSurfaces(PSurf, ISurf); - Standard_Integer nbpntbez = indicemax-indicemin; - if(nbpntbez < LimRajout) - myData.myBezierApprox = Standard_False; - else - myData.myBezierApprox = Standard_True; - - Standard_Boolean cut = Standard_True; - if(nbpntbez < LimRajout) + const Standard_Integer nbpntbez = indicemax-indicemin; + if(nbpntbez < aMinNbPointsForApprox) { - cut = Standard_False; + myData.myBezierApprox = Standard_False; + } + else + { + myData.myBezierApprox = Standard_True; } - Standard_Real aS2URes = ThePSurfaceTool::UResolution(PSurf, 1.0), - aS2VRes = ThePSurfaceTool::VResolution(PSurf, 1.0); - if(ApproxU2V2) - myUVRes2 = aS2URes / aS2VRes; + const Standard_Boolean cut = myData.myBezierApprox; + const Standard_Address ptrsvsurf = &myImpPrmSvSurfaces; // Fill data structure. - fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2); + fillData(theline); // Build knots. - Standard_Address ptrsvsurf = &myImpPrmSvSurfaces; buildKnots(theline, ptrsvsurf); - if(myRelativeTol==Standard_False) - { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d*myData.myMinFactorXYZ, - myTol2d*myData.myMinFactorUV, - myNbIterMax, - cut, - myData.parametrization); - } - else - { - myComputeLine.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - cut, - myData.parametrization); - myComputeLineBezier.Init(myDegMin, - myDegMax, - myTol3d, - myTol2d, - myNbIterMax, - cut, - myData.parametrization); - } + myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, + myNbIterMax, cut, myData.parametrization); + myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, + myNbIterMax, cut, myData.parametrization); buildCurve(theline, ptrsvsurf); } +//======================================================================= +//function : SetParameters +//purpose : +//======================================================================= +void ApproxInt_Approx::SetParameters( const Standard_Real Tol3d, + const Standard_Real Tol2d, + const Standard_Integer DegMin, + const Standard_Integer DegMax, + const Standard_Integer NbIterMax, + const Standard_Integer NbPntMax, + const Standard_Boolean ApproxWithTangency, + const Approx_ParametrizationType Parametrization) +{ + myData.myNbPntMax = NbPntMax; + myWithTangency = ApproxWithTangency; + myTol3d = Tol3d/RatioTol; + myTol2d = Tol2d/RatioTol; + myDegMin = DegMin; + myDegMax = DegMax; + myNbIterMax = NbIterMax; + + myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, + myNbIterMax, Standard_True, Parametrization); + myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, + myNbIterMax, Standard_True, Parametrization); + + if(!ApproxWithTangency) + { + myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); + myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); + } + + myData.myBezierApprox = Standard_True; +} + //======================================================================= //function : NbMultiCurves //purpose : @@ -683,9 +434,8 @@ void ApproxInt_Approx::UpdateTolReached() { if (myData.myBezierApprox) { - Standard_Integer ICur; - Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves(); - for (ICur = 1 ; ICur <= NbCurves ; ICur++) + const Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ; + for (Standard_Integer ICur = 1 ; ICur <= NbCurves ; ICur++) { Standard_Real Tol3D, Tol2D ; myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ; @@ -705,13 +455,7 @@ void ApproxInt_Approx::UpdateTolReached() //======================================================================= Standard_Real ApproxInt_Approx::TolReached3d() const { - Standard_Real TheTol3D = RatioTol * myTolReached3d ; - - if (myData.myMinFactorXYZ>1.5e-7) - TheTol3D = TheTol3D / myData.myMinFactorXYZ; - - //cout << "Tol 3D: " << TheTol3D << endl; - return TheTol3D ; + return myTolReached3d * RatioTol; } //======================================================================= @@ -720,13 +464,7 @@ Standard_Real ApproxInt_Approx::TolReached3d() const //======================================================================= Standard_Real ApproxInt_Approx::TolReached2d() const { - Standard_Real TheTol2D = RatioTol * myTolReached2d ; - - if (myData.myMinFactorUV>1.5e-7) - TheTol2D = TheTol2D / myData.myMinFactorUV; - - //cout << "Tol 2D: " << TheTol2D << endl; - return TheTol2D ; + return myTolReached2d * RatioTol; } //======================================================================= @@ -738,11 +476,6 @@ Standard_Boolean ApproxInt_Approx::IsDone() const if(myData.myBezierApprox) { return(myComputeLineBezier.NbMultiCurves() > 0); - //-- Lorsque la tolerance n est pas atteinte et qu il - //-- faudrait rajouter des points sur la ligne - //-- les approx sortent avec la meilleure tolerance - //-- atteinte. ( Pas de rajout de points ds cette version) - //-- return(myTolReached); } else { @@ -757,11 +490,11 @@ Standard_Boolean ApproxInt_Approx::IsDone() const const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const { if(myData.myBezierApprox) - { + { return(myBezToBSpl.Value()); } else - { + { return(myComputeLine.Value()); } } @@ -770,52 +503,22 @@ const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer //function : fillData //purpose : Fill ApproxInt data structure. //======================================================================= -void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline, - const Standard_Boolean ApproxXYZ, - const Standard_Boolean ApproxU1V1, - const Standard_Boolean ApproxU2V2) +void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline) { - if(ApproxXYZ) - { - ComputeTrsf3d(theline, myData.Xo, myData.Ax, myData.Yo, myData.Ay, myData.Zo, myData.Az); - } + if(myData.ApproxXYZ) + ComputeTrsf3d(theline, myData.Xo, myData.Yo, myData.Zo); else - { myData.Xo = myData.Yo = myData.Zo = 0.0; - myData.Ax = myData.Ay = myData.Az = 1.0; - } - if(ApproxU1V1) - { - ComputeTrsf2d(theline, myData.U1o, myData.A1u, myData.V1o, myData.A1v,Standard_True, myUVRes1); - } + if(myData.ApproxU1V1) + ComputeTrsf2d(theline, Standard_True, myData.U1o, myData.V1o); else - { myData.U1o = myData.V1o = 0.0; - myData.A1u = myData.A1v = 1.0; - } - if(ApproxU2V2) - { - ComputeTrsf2d(theline, myData.U2o, myData.A2u, myData.V2o, myData.A2v, Standard_False, myUVRes2); - } + if(myData.ApproxU2V2) + ComputeTrsf2d(theline, Standard_False, myData.U2o, myData.V2o); else - { myData.U2o = myData.V2o = 0.0; - myData.A2u = myData.A2v = 1.0; - } - - Standard_Real A3d = MINABS3(myData.Ax, myData.Ay, myData.Az); - if((A3d < myData.myMinFactorXYZ) || (myData.myMinFactorXYZ == 0.0)) - { - myData.myMinFactorXYZ = A3d; - } - - Standard_Real A2d = MINABS4(myData.A1u, myData.A1v, myData.A2u, myData.A2v); - if((A2d < myData.myMinFactorUV) || (myData.myMinFactorUV == 0.0)) - { - myData.myMinFactorUV = A2d; - } } //======================================================================= @@ -828,20 +531,13 @@ void ApproxInt_Approx::prepareDS(const Standard_Boolean theApproxXYZ, const Standard_Integer theIndicemin, const Standard_Integer theIndicemax) { - myData.myMinFactorXYZ = 0.0; - myData.myMinFactorUV = 0.0; myTolReached3d = myTolReached2d = 0.0; - myUVRes1 = myUVRes2 = 1.0; myData.ApproxU1V1 = theApproxU1V1; myData.ApproxU2V2 = theApproxU2V2; myData.ApproxXYZ = theApproxXYZ; myData.indicemin = theIndicemin; myData.indicemax = theIndicemax; - myData.nbpntmax = myNbPntMax; - - Approx_ParametrizationType parametrization; - myComputeLineBezier.Parametrization(parametrization); - myData.parametrization = parametrization; + myData.parametrization = myComputeLineBezier.Parametrization(); } //======================================================================= @@ -852,71 +548,66 @@ void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline, const Standard_Address thePtrSVSurf) { myKnots.Clear(); - if(myData.myBezierApprox) - { - ApproxInt_TheMultiLine aTestLine(theline, - thePtrSVSurf, - ((myData.ApproxXYZ)? 1 : 0), - ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), - myData.Xo, myData.Ax, myData.Yo, myData.Ay, myData.Zo, myData.Az, - myData.U1o, myData.A1u, - myData.V1o, myData.A1v, - myData.U2o, myData.A2u, - myData.V2o ,myData.A2v, - myData.ApproxU1V1, - myData.indicemin, - myData.indicemax); - - Standard_Integer nbp3d = aTestLine.NbP3d(); - Standard_Integer nbp2d = aTestLine.NbP2d(); - TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d)); - TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d)); - TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax); - TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax); - TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax); - Standard_Integer i; - for(i = myData.indicemin; i <= myData.indicemax; ++i) - { - if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d); - else if (nbp2d != 0) aTestLine.Value(i, aTabPnt2d); - else if (nbp3d != 0) aTestLine.Value(i, aTabPnt3d); - // - if(nbp3d > 0) - { - aPntXYZ(i) = aTabPnt3d(1); - } - if(nbp2d > 1) - { - aPntU1V1(i) = aTabPnt2d(1); - aPntU2V2(i) = aTabPnt2d(2); - } - else if(nbp2d > 0) - { - if(myData.ApproxU1V1) - { - aPntU1V1(i) = aTabPnt2d(1); - } - else - { - aPntU2V2(i) = aTabPnt2d(1); - } - } - } - - Standard_Integer aMinNbPnts = myData.nbpntmax; - - // Expected parametrization. - math_Vector aPars(myData.indicemin, myData.indicemax); - Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars); - - ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars, - myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots); - } - else + if(!myData.myBezierApprox) { myKnots.Append(myData.indicemin); myKnots.Append(myData.indicemax); + return; } + + const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf, + ((myData.ApproxXYZ)? 1 : 0), + ((myData.ApproxU1V1)? 1: 0) + + ((myData.ApproxU2V2)? 1: 0), + myData.Xo, myData.Yo, myData.Zo, + myData.U1o, myData.V1o, myData.U2o, myData.V2o, + myData.ApproxU1V1, + myData.indicemin, myData.indicemax); + + const Standard_Integer nbp3d = aTestLine.NbP3d(), + nbp2d = aTestLine.NbP2d(); + TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d)); + TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d)); + TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax); + TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax); + TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax); + + for(Standard_Integer i = myData.indicemin; i <= myData.indicemax; ++i) + { + if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d); + else if (nbp2d != 0) aTestLine.Value(i, aTabPnt2d); + else if (nbp3d != 0) aTestLine.Value(i, aTabPnt3d); + // + if(nbp3d > 0) + { + aPntXYZ(i) = aTabPnt3d(1); + } + if(nbp2d > 1) + { + aPntU1V1(i) = aTabPnt2d(1); + aPntU2V2(i) = aTabPnt2d(2); + } + else if(nbp2d > 0) + { + if(myData.ApproxU1V1) + { + aPntU1V1(i) = aTabPnt2d(1); + } + else + { + aPntU2V2(i) = aTabPnt2d(1); + } + } + } + + Standard_Integer aMinNbPnts = myData.myNbPntMax; + + // Expected parametrization. + math_Vector aPars(myData.indicemin, myData.indicemax); + Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars); + + ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars, + myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots); } //======================================================================= @@ -932,93 +623,74 @@ void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline, } Standard_Integer kind = myKnots.Lower(); - Standard_Integer imin, imax; - myTolReached = Standard_True; + Standard_Integer imin = 0, imax = 0; Standard_Boolean OtherInter = Standard_False; do { // Base cycle: iterate over knots. imin = myKnots(kind); imax = myKnots(kind+1); - ApproxInt_TheMultiLine myMultiLine(theline, - thePtrSVSurf, + ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf, ((myData.ApproxXYZ)? 1 : 0), ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), - myData.Xo, myData.Ax, myData.Yo,myData.Ay, myData.Zo,myData.Az, - myData.U1o, myData.A1u, myData.V1o, myData.A1v, - myData.U2o, myData.A2u, myData.V2o, myData.A2v, - myData.ApproxU1V1, - imin, - imax); + myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o, + myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax); if(myData.myBezierApprox) { myComputeLineBezier.Perform(myMultiLine); if (myComputeLineBezier.NbMultiCurves() == 0) return; - myTolReached&=myComputeLineBezier.IsToleranceReached(); } else { myComputeLine.Perform(myMultiLine); } + UpdateTolReached(); - Standard_Integer indice3d,indice2d1,indice2d2; - indice3d = 1; - indice2d1= 2; - indice2d2= 3; + Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3; if(!myData.ApproxXYZ) { indice2d1--; indice2d2--; } if(!myData.ApproxU1V1) { indice2d2--; } if(myData.ApproxXYZ) { - Standard_Real ax,bx,ay,by,az,bz; - ax = 1.0/myData.Ax; bx = -myData.Xo*ax; - ay = 1.0/myData.Ay; by = -myData.Yo*ay; - az = 1.0/myData.Az; bz = -myData.Zo*az; if(myData.myBezierApprox) { for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { - myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az); + myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0); } } else { - myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az); + myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0); } } if(myData.ApproxU1V1) { - Standard_Real ax,bx,ay,by; - ax = 1.0/myData.A1u; bx = -myData.U1o*ax; - ay = 1.0/myData.A1v; by = -myData.V1o*ay; if(myData.myBezierApprox) { for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { - myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay); + myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0); } } else { - myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay); + myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0); } } if(myData.ApproxU2V2) { - Standard_Real ax,bx,ay,by; - ax = 1.0/myData.A2u; bx = -myData.U2o*ax; - ay = 1.0/myData.A2v; by = -myData.V2o*ay; if(myData.myBezierApprox) { for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { - myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay); + myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0); } } else { - myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay); + myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0); } } diff --git a/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx b/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx index d7e06fb9c0..74eb09d898 100644 --- a/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx +++ b/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx @@ -20,11 +20,310 @@ #include #include -#define ComputeParametersOnImplicitSurface(MyISurf,P,u,v) MyISurf.Parameters(P,u,v) +//======================================================================= +//function : IsSingular +//purpose : Returns TRUE if vectors theDU || theDV or if at least one +// of them has null-magnitude. +// theSqLinTol is square of linear tolerance. +// theAngTol is angular tolerance. +//======================================================================= +static Standard_Boolean IsSingular( const gp_Vec& theDU, + const gp_Vec& theDV, + const Standard_Real theSqLinTol, + const Standard_Real theAngTol) +{ + gp_Vec aDU(theDU), aDV(theDV); -#define Debug(expr) cout<<" expr :"< 0.0 && aSqMagnDV > 0.0 but theDV || theDU. + + const Standard_Real aLenU = sqrt(aSqMagnDU), + aLenV = sqrt(aSqMagnDV); + + //aLenSum > 0.0 definitely + const Standard_Real aLenSum = aLenU + aLenV; + + if(theDV.Dot(theDU) > 0.0) + { + //Vectors theDV and theDU are codirectional. + + if(theIsTo3DTgCompute) + { + theTg2D.SetCoord(1.0/aLenSum, 1.0/aLenSum); + theTg3D = theDU*theTg2D.X() + theDV*theTg2D.Y(); + } + else + { + //theTg3D is already defined. + //Here we check only, if this tangent is parallel to theDU + //(and theDV together). + + if(theDU.Crossed(theTg3D).SquareMagnitude() < + theAngTol*theAngTol*aSqMagnDU*aSQTan) + { + //theTg3D is parallel to theDU + + const Standard_Real aDP = theTg3D.Dot(theDU); + const Standard_Real aLenTg = Sign(sqrt(aSQTan), aDP); + theTg2D.SetCoord(aLenTg/aLenSum, aLenTg/aLenSum); + } + else + { + //theTg3D is not parallel to theDU + //It is abnormal + + return Standard_False; + } + } + } + else + { + //Vectors theDV and theDU are opposite. + + if(theIsTo3DTgCompute) + { + //Here we chose theDU as direction of theTg3D. + //True direction shall be precised later (the algorithm is + //based on array of Walking-points). + + theTg2D.SetCoord(1.0/aLenSum, -1.0/aLenSum); + theTg3D = theDU*theTg2D.X() + theDV*theTg2D.Y(); + } + else + { + //theTg3D is already defined. + //Here we check only, if this tangent is parallel to theDU + //(and theDV together). + + if(theDU.Crossed(theTg3D).SquareMagnitude() < + theAngTol*theAngTol*aSqMagnDU*aSQTan) + { + //theTg3D is parallel to theDU + + const Standard_Real aDP = theTg3D.Dot(theDU); + const Standard_Real aLenTg = Sign(sqrt(aSQTan), aDP); + theTg2D.SetCoord(aLenTg/aLenSum, -aLenTg/aLenSum); + } + else + { + //theTg3D is not parallel to theDU + //It is abnormal + + return Standard_False; + } + } + } + + return Standard_True; +} + +//======================================================================= +//function : NonSingularProcessing +//purpose : Computes 2D-representation (in UV-coordinates) of +// theTg3D vector on the surface in case when +// theDU.Crossed(theDV).Magnitude() > 0.0. Stores result in +// theTg2D variable. +// theDU and theDV are vectors of 1st derivative +// (with respect to U and V variables correspondingly). +// theLinTol is SQUARE of the tolerance. +// +//Algorithm: +// Condition +// Tg=theDU*theTg2D.X()+theDV*theTg2D.Y() +// has to be satisfied strictly. +// More over, vector Tg has always to be NORMALYZED. +//======================================================================= +static Standard_Boolean NonSingularProcessing(const gp_Vec& theDU, + const gp_Vec& theDV, + const gp_Vec& theTg3D, + const Standard_Real theLinTol, + const Standard_Real theAngTol, + gp_Vec2d& theTg2D) +{ + const gp_Vec aNormal = theDU.Crossed(theDV); + const Standard_Real aSQMagn = aNormal.SquareMagnitude(); + + if(IsSingular(theDU, theDV, theLinTol, theAngTol)) + { + gp_Vec aTg(theTg3D); + return + SingularProcessing(theDU, theDV, Standard_False, + theLinTol, theAngTol, aTg, theTg2D); + } + + //If @\vec{T}=\vec{A}*U+\vec{B}*V@ then + + // \left\{\begin{matrix} + // \vec{A} \times \vec{T} = (\vec{A} \times \vec{B})*V + // \vec{B} \times \vec{T} = (\vec{B} \times \vec{A})*U + // \end{matrix}\right. + + //From here, values of U and V can be found very easily + //(if @\left \| \vec{A} \times \vec{B} \right \| > 0.0 @, + //else it is singular case). + + const gp_Vec aTgU(theTg3D.Crossed(theDU)), aTgV(theTg3D.Crossed(theDV)); + const Standard_Real aDeltaU = aTgV.SquareMagnitude()/aSQMagn; + const Standard_Real aDeltaV = aTgU.SquareMagnitude()/aSQMagn; + + theTg2D.SetCoord(Sign(sqrt(aDeltaU), aTgV.Dot(aNormal)), -Sign(sqrt(aDeltaV), aTgU.Dot(aNormal))); + + return Standard_True; +} //-------------------------------------------------------------------------------- ApproxInt_ImpPrmSvSurfaces::ApproxInt_ImpPrmSvSurfaces( const TheISurface& ISurf @@ -111,16 +410,31 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::TangencyOnSurf2(const Standard_Real T=MyTguv2; return(t); } -//-------------------------------------------------------------------------------- -Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 - ,Standard_Real& v1 - ,Standard_Real& u2 - ,Standard_Real& v2 - ,gp_Pnt& P - ,gp_Vec& Tg - ,gp_Vec2d& Tguv1 - ,gp_Vec2d& Tguv2) { - + +//======================================================================= +//function : Compute +//purpose : Computes point on curve, 3D and 2D-tangents of a curve and +// parameters on the surfaces. +//======================================================================= +Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1, + Standard_Real& v1, + Standard_Real& u2, + Standard_Real& v2, + gp_Pnt& P, + gp_Vec& Tg, + gp_Vec2d& Tguv1, + gp_Vec2d& Tguv2) +{ + const IntSurf_Quadric& aQSurf = MyZerImpFunc.ISurface(); + const ThePSurface& aPSurf = MyZerImpFunc.PSurface(); + gp_Vec2d& aQuadTg = MyImplicitFirst ? Tguv1 : Tguv2; + gp_Vec2d& aPrmTg = MyImplicitFirst ? Tguv2 : Tguv1; + + //for square + const Standard_Real aNullValue = Precision::Approximation()* + Precision::Approximation(), + anAngTol = Precision::Angular(); + Standard_Real tu1=u1; Standard_Real tu2=u2; Standard_Real tv1=v1; @@ -175,7 +489,6 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 } } - Standard_Real aBornInf[2],aBornSup[2],aF[1],aX[2],aTolerance[2]; math_Vector BornInf(aBornInf,1,2),BornSup(aBornSup,1,2),F(aF,1,1), X(aX,1,2),Tolerance(aTolerance,1,2); @@ -183,14 +496,14 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 math_Matrix D(aD,1, 1, 1, 2); Standard_Real binfu,bsupu,binfv,bsupv; - binfu = ThePSurfaceTool::FirstUParameter(MyPSurf); - binfv = ThePSurfaceTool::FirstVParameter(MyPSurf); - bsupu = ThePSurfaceTool::LastUParameter(MyPSurf); - bsupv = ThePSurfaceTool::LastVParameter(MyPSurf); + binfu = ThePSurfaceTool::FirstUParameter(aPSurf); + binfv = ThePSurfaceTool::FirstVParameter(aPSurf); + bsupu = ThePSurfaceTool::LastUParameter(aPSurf); + bsupv = ThePSurfaceTool::LastVParameter(aPSurf); BornInf(1) = binfu; BornSup(1) = bsupu; BornInf(2) = binfv; BornSup(2) = bsupv; - //--- ThePSurfaceTool::GetResolution(MyPSurf,Tolerance(1),Tolerance(2)); + //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2)); Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8; Standard_Real TranslationU=0.0; @@ -200,8 +513,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 Rsnld.SetTolerance(Tolerance); if(MyImplicitFirst) { if(u2bsupu+0.0000000001) { - if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { - Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf); + if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf); do { TranslationU-=d; } while(u2+TranslationU > bsupu); } else { @@ -222,8 +535,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 } } if(v2bsupv+0.0000000001) { - if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { - Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf); + if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf); do { TranslationV-=d; } while(v2+TranslationV > bsupv); } else { @@ -248,8 +561,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 } else { if(u1bsupu+0.0000000001) { - if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { - Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf); + if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf); do { TranslationU-=d; } while(u1+TranslationU > bsupu); } else { @@ -270,8 +583,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 } } if(v1bsupv+0.0000000001) { - if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { - Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf); + if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf); do { TranslationV-=d; } while(v1+TranslationV > bsupv); } else { @@ -296,9 +609,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 } //---------------------------------------------------- - //-- Pour eviter de coller le point de depart de la - //-- recherche sur une des bornes (Rsnld -> NotDone) - //-- + //Make a small step from boundaries in order to avoid + //finding "outboundaried" solution (Rsnld -> NotDone). if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001; if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001; if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001; @@ -308,15 +620,6 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1 Standard_Real PourTesterU = X(1); Standard_Real PourTesterV = X(2); - - /* *************************************************************** - cout<<" Envoi a Rsnld : "; Debug(X(1)); Debug(X(2)); - Debug(BornInf(1)); Debug(BornInf(2)); - Debug(BornSup(1)); Debug(BornSup(2)); cout<M_PI) u1-=M_PI+M_PI; - while(tu1-u1>M_PI) u1+=M_PI+M_PI; - } - MyParOnS1.SetCoord(tu1,tv1); - MyParOnS2.SetCoord(tu2,tv2); - ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V); - MyISurf.D1(u1,v1,P,ID1U,ID1V); + MyPnt = P = ThePSurfaceTool::Value(aPSurf, X(1), X(2)); + + if( (DistAvantApresV <= 0.001 ) && + (DistAvantApresU <= 0.001 )) + { + gp_Vec aD1uPrm,aD1vPrm; + gp_Vec aD1uQuad,aD1vQuad; + + if(MyImplicitFirst) + { + u2 = X(1)-TranslationU; + v2 = X(2)-TranslationV; + + if(aQSurf.TypeQuadric() != GeomAbs_Plane) + { + while(u1-tu1>M_PI) u1-=M_PI+M_PI; + while(tu1-u1>M_PI) u1+=M_PI+M_PI; + } + + MyParOnS1.SetCoord(tu1,tv1); + MyParOnS2.SetCoord(tu2,tv2); + + gp_Pnt aP2; + + ThePSurfaceTool::D1(aPSurf, X(1), X(2), P, aD1uPrm, aD1vPrm); + aQSurf.D1(u1,v1, aP2, aD1uQuad, aD1vQuad); + + //Middle-point of P-P2 segment + P.BaryCenter(1.0, aP2, 1.0); } - else { - u1 = X(1)-TranslationU; - v1 = X(2)-TranslationV; - ComputeParametersOnImplicitSurface(MyISurf,P,u2,v2); - if(MyISurf.TypeQuadric() != GeomAbs_Plane) { - while(u2-tu2>M_PI) u2-=M_PI+M_PI; - while(tu2-u2>M_PI) u2+=M_PI+M_PI; - } - MyParOnS1.SetCoord(tu1,tv1); - MyParOnS2.SetCoord(tu2,tu2); - ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V); - MyISurf.D1(u2,v2,P,ID1U,ID1V); - } - - - gp_Vec VNormaleImp = MyISurf.Normale(MyPnt); - gp_Vec VNormalePrm = PD1U.Crossed(PD1V); - if( VNormaleImp.SquareMagnitude() <= gp::Resolution() - || VNormalePrm.SquareMagnitude() <= gp::Resolution()) { - MyIsTangent = Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); - } - - gp_Dir NormaleImp(VNormaleImp); - gp_Dir NormalePrm(VNormalePrm); - - gp_Vec VNImp(NormaleImp); - gp_Vec VNPrm(NormalePrm); - MyTg = VNImp.Crossed(VNPrm); - Standard_Real NmyTg = MyTg.Magnitude(); - if(NmyTg < 0.000001) { - MyIsTangent = Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); - } - MyTg.SetCoord(MyTg.X()/NmyTg,MyTg.Y()/NmyTg,MyTg.Z()/NmyTg); - - - MyTg = NormaleImp.Crossed(NormalePrm); - Tg = MyTg; - - Standard_Real TUTV,TgTU,TgTV,TUTU,TVTV,DIS; - Standard_Real DeltaU,DeltaV; - TUTU = PD1U.Dot(PD1U); - TVTV = PD1V.Dot(PD1V); - TUTV = PD1U.Dot(PD1V); - TgTU = MyTg.Dot(PD1U); - TgTV = MyTg.Dot(PD1V); - DIS = TUTU * TVTV - TUTV * TUTV; - - if(DIS<1e-10 && DIS>-1e-10) { - MyIsTangent = Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); + else + { + u1 = X(1)-TranslationU; + v1 = X(2)-TranslationV; + //aQSurf.Parameters(P, u2, v2); + if(aQSurf.TypeQuadric() != GeomAbs_Plane) + { + while(u2-tu2>M_PI) u2-=M_PI+M_PI; + while(tu2-u2>M_PI) u2+=M_PI+M_PI; + } + + MyParOnS1.SetCoord(tu1,tv1); + MyParOnS2.SetCoord(tu2,tu2); + + gp_Pnt aP2; + ThePSurfaceTool::D1(aPSurf, X(1), X(2), P, aD1uPrm, aD1vPrm); + + aQSurf.D1(u2, v2, aP2, aD1uQuad, aD1vQuad); + + //Middle-point of P-P2 segment + P.BaryCenter(1.0, aP2, 1.0); } + MyPnt = P; - DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ; - DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ; - - if(MyImplicitFirst) { - MyTguv1.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U)) - ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V))); - MyTguv2.SetCoord(DeltaU,DeltaV); - Tguv1 = MyTguv1; - Tguv2 = MyTguv2; + //Normals to the surfaces + gp_Vec aNormalPrm(aD1uPrm.Crossed(aD1vPrm)), + aNormalImp(aQSurf.Normale(MyPnt)); + + const Standard_Real aSQMagnPrm = aNormalPrm.SquareMagnitude(), + aSQMagnImp = aNormalImp.SquareMagnitude(); + + Standard_Boolean isPrmSingular = Standard_False, + isImpSingular = Standard_False; + + if(IsSingular(aD1uPrm, aD1vPrm, aNullValue, anAngTol)) + { + isPrmSingular = Standard_True; + if(!SingularProcessing(aD1uPrm, aD1vPrm, Standard_True, + aNullValue, anAngTol, Tg, aPrmTg)) + { + MyIsTangent = Standard_False; + MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; + return Standard_False; + } + + MyTg = Tg; } - else { - MyTguv1.SetCoord(DeltaU,DeltaV); - MyTguv2.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U)) - ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V))); - Tguv1 = MyTguv1; - Tguv2 = MyTguv2; + else + { + aNormalPrm.Divide(sqrt(aSQMagnPrm)); } + + //Analogicaly for implicit surface + if(aSQMagnImp < aNullValue) + { + isImpSingular = Standard_True; + + if(!SingularProcessing(aD1uQuad, aD1vQuad, !isPrmSingular, + aNullValue, anAngTol, Tg, aQuadTg)) + { + MyIsTangent = Standard_False; + MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; + return Standard_False; + } + + MyTg = Tg; + } + else + { + aNormalImp.Divide(sqrt(aSQMagnImp)); + } + + if(isImpSingular && isPrmSingular) + { + //All is OK. All abnormal cases were processed above. + + MyTguv1 = Tguv1; + MyTguv2 = Tguv2; + + MyIsTangent=Standard_True; + return MyIsTangent; + } + else if(!(isImpSingular || isPrmSingular)) + { + //Processing pure non-singular case + //(3D- and 2D-tangents are still not defined) + + //Ask to pay attention to the fact that here + //aNormalImp and aNormalPrm are normalyzed. + //Therefore, @ \left \| \vec{Tg} \right \| = 0.0 @ + //if and only if (aNormalImp || aNormalPrm). + Tg = aNormalImp.Crossed(aNormalPrm); + } + + const Standard_Real aSQMagnTg = Tg.SquareMagnitude(); + + if(aSQMagnTg < aNullValue) + { + MyIsTangent = Standard_False; + MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; + return Standard_False; + } + + //Normalyze Tg vector + Tg.Divide(sqrt(aSQMagnTg)); + MyTg = Tg; + + if(!isPrmSingular) + { + //If isPrmSingular==TRUE then aPrmTg has already been computed. + + if(!NonSingularProcessing(aD1uPrm, aD1vPrm, Tg, aNullValue, anAngTol, aPrmTg)) + { + MyIsTangent = Standard_False; + MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; + return Standard_False; + } + } + + if(!isImpSingular) + { + //If isImpSingular==TRUE then aQuadTg has already been computed. + + if(!NonSingularProcessing(aD1uQuad, aD1vQuad, Tg, aNullValue, anAngTol, aQuadTg)) + { + MyIsTangent = Standard_False; + MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; + return Standard_False; + } + } + + MyTguv1 = Tguv1; + MyTguv2 = Tguv2; + MyIsTangent=Standard_True; - return(Standard_True); + +#ifdef OCCT_DEBUG + //cout << "+++++++++++++++++ ApproxInt_ImpPrmSvSurfaces::Compute(...) ++++++++++" << endl; + //printf( "P2d_1(%+10.20f, %+10.20f); P2d_2(%+10.20f, %+10.20f)\n" + // "P(%+10.20f, %+10.20f, %+10.20f);\n" + // "Tg = {%+10.20f, %+10.20f, %+10.20f};\n" + // "Tguv1 = {%+10.20f, %+10.20f};\n" + // "Tguv2 = {%+10.20f, %+10.20f}\n", + // u1, v1, u2, v2, + // P.X(), P.Y(), P.Z(), + // Tg.X(), Tg.Y(), Tg.Z(), + // Tguv1.X(), Tguv1.Y(), Tguv2.X(), Tguv2.Y()); + //cout << "-----------------------------------------------------------------------" << endl; +#endif + + return Standard_True; } else { - //-- cout<<" ApproxInt_ImpImpSvSurfaces.gxx : Distance apres recadrage Trop Grande "<& th Standard_Integer anIdx = i + 1; for( ; anIdx <= theInds.Length(); ++anIdx) { - if (theInds(anIdx) - anIndsPrev > theMinNbPnts) + if (theInds(anIdx) - anIndsPrev >= theMinNbPnts) break; } anIdx--; @@ -379,10 +360,36 @@ void ApproxInt_KnotTools::FilterKnots(NCollection_Sequence& th aMidIdx - theInds(anIdx) < theMinNbPnts && theInds(anIdx) - anIndsPrev >= aMinNbStep) { - // Bad distribution points merge into one knot interval. - theLKnots.Append(theInds(anIdx)); - anIndsPrev = theInds(anIdx); - i = anIdx; + if (theInds(anIdx) - anIndsPrev > 2 * theMinNbPnts) + { + // Bad distribution points merge into one knot interval. + theLKnots.Append(anIndsPrev + theMinNbPnts); + anIndsPrev = anIndsPrev + theMinNbPnts; + i = anIdx - 1; + } + else + { + if (theInds(anIdx - 1) - anIndsPrev >= theMinNbPnts / 2) + { + // Bad distribution points merge into one knot interval. + theLKnots.Append(theInds(anIdx - 1)); + anIndsPrev = theInds(anIdx - 1); + i = anIdx - 1; + if (theInds(anIdx) - theInds(anIdx - 1) <= theMinNbPnts / 2) + { + theLKnots.SetValue(theLKnots.Upper(), theInds(anIdx)); + anIndsPrev = theInds(anIdx ); + i = anIdx; + } + } + else + { + // Bad distribution points merge into one knot interval. + theLKnots.Append(theInds(anIdx)); + anIndsPrev = theInds(anIdx); + i = anIdx; + } + } } else if (anIdx == theInds.Upper() && // Last point obtained. theLKnots.Length() >= 2) // It is possible to modify last item. diff --git a/src/ApproxInt/ApproxInt_MultiLine.gxx b/src/ApproxInt/ApproxInt_MultiLine.gxx index c6ee083657..d6f2e64e36 100644 --- a/src/ApproxInt/ApproxInt_MultiLine.gxx +++ b/src/ApproxInt/ApproxInt_MultiLine.gxx @@ -14,101 +14,85 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#define DEBUG 0 - - #include -#include #include #include #include #include +#include -ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line, - const Standard_Address svsurf, - const Standard_Integer NbP3d, - const Standard_Integer NbP2d, - const Standard_Real xo, - const Standard_Real ax, - const Standard_Real yo, - const Standard_Real ay, - const Standard_Real zo, - const Standard_Real az, - const Standard_Real u1o, - const Standard_Real a1u, - const Standard_Real v1o, - const Standard_Real a1v, - const Standard_Real u2o, - const Standard_Real a2u, - const Standard_Real v2o, - const Standard_Real a2v, - const Standard_Boolean P2DOnFirst, - const Standard_Integer IndMin, - const Standard_Integer IndMax): +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +ApproxInt_MultiLine:: + ApproxInt_MultiLine(const Handle_TheLine& line, + const Standard_Address svsurf, + const Standard_Integer NbP3d, + const Standard_Integer NbP2d, + const Standard_Real xo, + const Standard_Real yo, + const Standard_Real zo, + const Standard_Real u1o, + const Standard_Real v1o, + const Standard_Real u2o, + const Standard_Real v2o, + const Standard_Boolean P2DOnFirst, + const Standard_Integer IndMin, + const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf), + myLine(line), + indicemin(Min(IndMin, IndMax)), + indicemax(Max(IndMin, IndMax)), + nbp3d(NbP3d), nbp2d(NbP2d), + p2donfirst(P2DOnFirst), + Xo(xo), Yo(yo), Zo(zo), + U1o(u1o), V1o(v1o), + U2o(u2o), V2o(v2o) - PtrOnmySvSurfaces(svsurf), - myLine(line), - indicemin(IndMin), - indicemax(IndMax), - nbp3d(NbP3d), - nbp2d(NbP2d), - p2donfirst(P2DOnFirst), - Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az), - U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v), - U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v) { -#if DEBUG - if(indicemin>=indicemax) { - cout<<"\n********************************************"; - cout<<"\n***** ApproxInt_MultiLine ********"; - cout<<"\n***** indicemin = indicemax = "<=indicemax) { -#if DEBUG - cout<<"\n********************************************"; - cout<<"\n***** ApproxInt_MultiLine ********"; - cout<<"\n***** indicemin = indicemax = "<Point(Index)); - Standard_Real X = POn2S.Value().X(); - Standard_Real Y = POn2S.Value().Y(); - Standard_Real Z = POn2S.Value().Z(); - TabPnt(1) = gp_Pnt(X*Ax + Xo, Y*Ay + Yo, Z*Az + Zo); + const gp_Pnt& aP = myLine->Point(Index).Value(); + TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo); } -//-------------------------------------------------------------------------------- -void ApproxInt_MultiLine::Value( const Standard_Integer Index - ,TColgp_Array1OfPnt2d& TabPnt2d) const + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +void ApproxInt_MultiLine::Value(const Standard_Integer Index, + TColgp_Array1OfPnt2d& TabPnt2d) const { IntSurf_PntOn2S POn2S(myLine->Point(Index)); - Standard_Real u1,u2,v1,v2; - POn2S.Parameters(u1,v1,u2,v2); - if(nbp2d==1) { - if(p2donfirst) { - TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); + Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0; + POn2S.Parameters(u1, v1, u2, v2); + if(nbp2d==1) + { + if(p2donfirst) + { + TabPnt2d(1).SetCoord(u1+U1o, v1+V1o); } - else { - TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); + else + { + TabPnt2d(1).SetCoord(u2+U2o, v2+V2o); } } - else { - TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); - if(TabPnt2d.Length()>=2) { - TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); + else + { + TabPnt2d(1).SetCoord(u1+U1o, v1+V1o); + if(TabPnt2d.Length() >= 2) + { + TabPnt2d(2).SetCoord(u2+U2o, v2+V2o); } } } -//-------------------------------------------------------------------------------- -void ApproxInt_MultiLine::Value( const Standard_Integer Index - ,TColgp_Array1OfPnt& TabPnt - ,TColgp_Array1OfPnt2d& TabPnt2d) const + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +void ApproxInt_MultiLine::Value(const Standard_Integer Index, + TColgp_Array1OfPnt& TabPnt, + TColgp_Array1OfPnt2d& TabPnt2d) const { - IntSurf_PntOn2S POn2S(myLine->Point(Index)); - Standard_Real u1,u2,v1,v2; - POn2S.Parameters(u1,v1,u2,v2); - if(nbp2d==1) { - if(p2donfirst) { - TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); - } - else { - TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); - } - } - else { - TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); - if(TabPnt2d.Length()>=2) { - TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); - } - } - Standard_Real X = POn2S.Value().X(); - Standard_Real Y = POn2S.Value().Y(); - Standard_Real Z = POn2S.Value().Z(); - TabPnt(1) = gp_Pnt(X * Ax + Xo, Y * Ay + Yo, Z * Az + Zo); + Value(Index, TabPnt); + Value(Index, TabPnt2d); } -//-------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------- -Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index - ,TColgp_Array1OfVec& TabVec) const -{ + +//======================================================================= +//function : Tangency +//purpose : +//======================================================================= +Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index, + TColgp_Array1OfVec& TabVec) const +{ if(PtrOnmySvSurfaces==NULL) - return(Standard_False); + return Standard_False; - IntSurf_PntOn2S POn2S(myLine->Point(Index)); - Standard_Real u1,u2,v1,v2; - gp_Vec Tg; + const IntSurf_PntOn2S& POn2S = myLine->Point(Index); + Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0; POn2S.Parameters(u1,v1,u2,v2); - Standard_Boolean ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg); - if(ret) { - Standard_Real X = Tg.X(); - Standard_Real Y = Tg.Y(); - Standard_Real Z = Tg.Z(); - TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az); + + Standard_Boolean ret= + ((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1)); + if(!ret) + { + TabVec(1).SetCoord(0.0, 0.0, 0.0); } - else - TabVec(1) = gp_Vec(0.0,0.0,0.0); - return(ret); + + return ret; } -//-------------------------------------------------------------------------------- -Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index - ,TColgp_Array1OfVec2d& TabVec2d) const -{ + +//======================================================================= +//function : Tangency +//purpose : +//======================================================================= +Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index, + TColgp_Array1OfVec2d& TabVec2d) const +{ if(PtrOnmySvSurfaces==NULL) - return(Standard_False); + return Standard_False; - IntSurf_PntOn2S POn2S(myLine->Point(Index)); - Standard_Real u1,u2,v1,v2,U,V; - gp_Vec2d Tg2d; - Standard_Boolean ret; + const IntSurf_PntOn2S& POn2S = myLine->Point(Index); + Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0; POn2S.Parameters(u1,v1,u2,v2); - if(nbp2d==1) { - Standard_Real Au = A1u; - Standard_Real Av = A1v; - if(p2donfirst) { - ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); + + Standard_Boolean ret = Standard_False; + if(nbp2d==1) + { + if(p2donfirst) + { + ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1)); } - else { - ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); - Au = A2u; - Av = A2v; + else + { + ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1)); } - if(ret) { - U = Tg2d.X(); - V = Tg2d.Y(); - TabVec2d(1) = gp_Vec2d(U * Au, V * Av); - } - else { - TabVec2d(1) = gp_Vec2d(0.0,0.0); - } } - else { - ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); - if(ret) { - U = Tg2d.X(); - V = Tg2d.Y(); - TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v); - - if(TabVec2d.Length()>=2) { - ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); - U = Tg2d.X(); - V = Tg2d.Y(); - TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v); - } - else { - TabVec2d(1) = gp_Vec2d(0.0,0.0); - if(TabVec2d.Length()>=2) { - TabVec2d(2) = gp_Vec2d(0.0,0.0); - } + else + { + ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1)); + if(ret) + { + if(TabVec2d.Length()>=2) + { + ret = + (ret && + ((TheSvSurfaces *)PtrOnmySvSurfaces)-> + TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2))); } } } - return(ret); + + if(!ret) + { + TabVec2d(1) = gp_Vec2d(0.0, 0.0); + if(TabVec2d.Length() >= 2) + { + TabVec2d(2) = gp_Vec2d(0.0,0.0); + } + } + + return ret; } -//-------------------------------------------------------------------------------- -Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index - ,TColgp_Array1OfVec& TabVec - ,TColgp_Array1OfVec2d& TabVec2d) const + +//======================================================================= +//function : Tangency +//purpose : +//======================================================================= +Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index, + TColgp_Array1OfVec& TabVec, + TColgp_Array1OfVec2d& TabVec2d) const { - if(PtrOnmySvSurfaces==NULL) - return(Standard_False); - - IntSurf_PntOn2S POn2S(myLine->Point(Index)); - Standard_Real u1,u2,v1,v2,U,V; - gp_Vec2d Tg2d; - gp_Vec Tg; - Standard_Boolean ret; - POn2S.Parameters(u1,v1,u2,v2); - if(nbp2d==1) { - Standard_Real Au = A1u; - Standard_Real Av = A1v; - if(p2donfirst) { - ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); - } - else { - ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); - Au = A2u; - Av = A2v; - } - if(ret) { - U = Tg2d.X(); - V = Tg2d.Y(); - TabVec2d(1) = gp_Vec2d(U * Au, V * Av); - } - else { - TabVec2d(1) = gp_Vec2d(0.0,0.0); - } - } - else { - ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); - if(ret) { - U = Tg2d.X(); - V = Tg2d.Y(); - TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v); - if(TabVec2d.Length()>=2) { - ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); - U = Tg2d.X(); - V = Tg2d.Y(); - TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v); - } - } - else { - TabVec2d(1) = gp_Vec2d(0.0,0.0); - if(TabVec2d.Length()>=2) { - TabVec2d(2) = gp_Vec2d(0.0,0.0); - } - } - } - if(ret) { - ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg); - Standard_Real X = Tg.X(); - Standard_Real Y = Tg.Y(); - Standard_Real Z = Tg.Z(); - TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az); - } - else { - TabVec(1) = gp_Vec(0.0,0.0,0.0); - } - return(ret); + return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d)); } -//-------------------------------------------------------------------------------- - - -//================================================================================ -ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween(const Standard_Integer Low, - const Standard_Integer High, - const Standard_Integer aNbPntsToInsert) -const { +//======================================================================= +//function : MakeMLBetween +//purpose : +//======================================================================= +ApproxInt_MultiLine + ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low, + const Standard_Integer High, + const Standard_Integer aNbPntsToInsert) const +{ if(PtrOnmySvSurfaces==NULL) { //-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<Point(i).Parameters(u1,v1,u2,v2); U1(i) = u1; @@ -422,20 +340,17 @@ const { V1(i) = v1; U2(i) = u2; V2(i) = v2; - AC(i) = AC(i-1) - + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value()); + AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value()); } #endif //------------------------------------------------------------- //-- Creation des structures contenant les resultats - Handle(IntSurf_LineOn2S) ResultPntOn2SLine - = new IntSurf_LineOn2S(); + Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S(); IntSurf_PntOn2S StartPOn2S; - TColStd_Array1OfReal StartParams(1,4); - + TColStd_Array1OfReal StartParams(1,4); ds = AC(High) / (NbPnts-1); Standard_Integer Indice = Low; @@ -450,8 +365,11 @@ const { //-- s s -- //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) -- //---------------------------------------------------------- - while(AC(Indice+1) <= s) { - if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice)); + while(AC(Indice+1) <= s) + { + if(!HasBeenInserted) + ResultPntOn2SLine->Add(myLine->Point(Indice)); + HasBeenInserted = Standard_False; Indice++; if (Indice == High) @@ -461,10 +379,12 @@ const { if (Indice == High) break; - if(!HasBeenInserted && AC(Indice) <= s) { + if(!HasBeenInserted && AC(Indice) <= s) + { ResultPntOn2SLine->Add(myLine->Point(Indice)); HasBeenInserted = Standard_True; } + Standard_Real a = s - AC(Indice); Standard_Real b = AC(Indice+1) - s; Standard_Real nab = 1.0/(a+b); @@ -474,48 +394,57 @@ const { //-- Si Dist au precedent point < dsmin -- //-- -- //---------------------------------------------------------- - if((a>dsmin) && (b>dsmin)) { - + if((a>dsmin) && (b>dsmin)) + { u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab; v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab; u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab; v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab; - - - if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) { - StartPOn2S.SetValue(P,u1,v1,u2,v2); - //-- cout<<" Insertion du point calcule : "<Add(StartPOn2S); + + if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) + { + StartPOn2S.SetValue(P,u1,v1,u2,v2); + //-- cout<<" Insertion du point calcule : "<Add(StartPOn2S); } - else { - //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<Add(myLine->Point(Indice)); - //-- cout<<" Insertion du point :"<Add(myLine->Point(Indice)); + + //-- cout<<" Insertion du point :"<Add(myLine->Point(Indice)); - HasBeenInserted = Standard_True; - } + + if(!HasBeenInserted && AC(Indice) <= s) + { + ResultPntOn2SLine->Add(myLine->Point(Indice)); + HasBeenInserted = Standard_True; + } } - else { - s+=dsmin - ds; + else + { + s+= (dsmin - ds); } } } @@ -538,7 +467,8 @@ const { Standard_Integer CodeErreur=0; - for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) { + for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) + { Standard_Real d,du,dv,duv2; temp->Point(i).Parameters(u1,v1,u2,v2); //-- Virage P1A P1B P1C @@ -551,11 +481,13 @@ const { du = P1C.X() - u1; dv = P1C.Y() - v1; d = du*du+dv*dv; - if(d>duv2) { + if(d>duv2) + { CodeErreur = 1; CodeErreur = 1; break; } + //-- Virage P2A P2B P2C P2C.SetCoord(u2,v2); du = P2B.X()-P2A.X(); @@ -566,63 +498,80 @@ const { du = P2C.X() - u2; dv = P2C.Y() - v2; d = du*du+dv*dv; - if(d>duv2) { + if(d>duv2) + { CodeErreur = 2; break; } + P1A=P1B; P2A=P2B; P1B=P1C; P2B=P2C; } -#if DEBUG - if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) { - cout<<" *** Pas assez de points entre :"< "<NbPnts()<NbPnts() < NbPntsToInsert + High - Low + 1) + //{ + // cout<<" *** Pas assez de points entre :"<< + // Low<<" et "< "<NbPnts()<NbPnts() >= NbPntsToInsert + High - Low + 1) - && (CodeErreur==0)) { - return(ApproxInt_MultiLine(temp, - (High-Low>10)? PtrOnmySvSurfaces : NULL, - nbp3d, - nbp2d, - Xo,Ax,Yo,Ay,Zo,Az, - U1o,A1u,V1o,A1v, - U2o,A2u,V2o,A2v, - p2donfirst, - 1,ResultPntOn2SLine->NbPoints())); + + if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0)) + { + return(ApproxInt_MultiLine( temp, + (High-Low>10)? PtrOnmySvSurfaces : NULL, + nbp3d, + nbp2d, + Xo,Yo,Zo, + U1o,V1o, + U2o,V2o, + p2donfirst, + 1,ResultPntOn2SLine->NbPoints())); } - else { + else + { //-- cout<<" ApproxInt_MultiLine "<ChangeBuildTool(); TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool(); GTofBTofBuilder.SetNbPntMax(myApproxNbPntMax); - GTofBTofBuilder.SetTolerances (myApproxTol3D, myApproxTol2D, myApproxRelativeTol) ; + GTofBTofBuilder.SetTolerances (myApproxTol3D, myApproxTol2D) ; Handle(TopOpeBRepBuild_HBuilder)& HB = myDSA.myHB; Handle(TopOpeBRepDS_HDataStructure)& HDS = myDSA.ChangeDS(); HB->Perform(HDS,myS1,myS2); diff --git a/src/BRepAlgo/BRepAlgo_BooleanOperations.hxx b/src/BRepAlgo/BRepAlgo_BooleanOperations.hxx index a00b4f7cb9..6975d3ffe2 100644 --- a/src/BRepAlgo/BRepAlgo_BooleanOperations.hxx +++ b/src/BRepAlgo/BRepAlgo_BooleanOperations.hxx @@ -58,7 +58,7 @@ public: //! the same time in one curve. //! Tol3D, Tol2D : Tolerances to be reached by the approximation. //! RelativeTol : The given tolerances are relative. - Standard_EXPORT void SetApproxParameters (const Standard_Integer NbPntMax, const Standard_Real Tol3D, const Standard_Real Tol2D, const Standard_Boolean RelativeTol); + Standard_EXPORT void SetApproxParameters (const Standard_Integer NbPntMax, const Standard_Real Tol3D, const Standard_Real Tol2D); Standard_EXPORT void Define (const TopoDS_Shape& S1, const TopoDS_Shape& S2, Handle(TopOpeBRepDS_HDataStructure)& HDS); @@ -129,9 +129,6 @@ private: Standard_Integer myApproxNbPntMax; Standard_Real myApproxTol3D; Standard_Real myApproxTol2D; - Standard_Boolean myApproxRelativeTol; - - }; diff --git a/src/BRepApprox/BRepApprox_Approx.hxx b/src/BRepApprox/BRepApprox_Approx.hxx index c00efbe5bd..ed037318f4 100644 --- a/src/BRepApprox/BRepApprox_Approx.hxx +++ b/src/BRepApprox/BRepApprox_Approx.hxx @@ -51,22 +51,24 @@ class AppParCurves_MultiBSpCurve; struct Approx_Data { - Approx_Data() + Approx_Data() : myBezierApprox(Standard_True), + Xo(0.0), Yo(0.0), Zo(0.0), + U1o(0.0), V1o(0.0), U2o(0.0), V2o(0.0), + ApproxXYZ(Standard_True), + ApproxU1V1(Standard_True), + ApproxU2V2(Standard_True), + indicemin(0), indicemax(0), + myNbPntMax(30), parametrization(Approx_ChordLength) { - myMinFactorXYZ = 0.0; - myMinFactorUV = 0.0; } Standard_Boolean myBezierApprox; - Standard_Real Xo, Ax, Yo, Ay, Zo, Az, - U1o, A1u, V1o, A1v, U2o, A2u, V2o, A2v; + Standard_Real Xo, Yo, Zo, U1o, V1o, U2o, V2o; Standard_Boolean ApproxXYZ, ApproxU1V1, ApproxU2V2; - Standard_Integer indicemin, indicemax, nbpntmax; + Standard_Integer indicemin, indicemax, myNbPntMax; Approx_ParametrizationType parametrization; - Standard_Real myMinFactorXYZ, myMinFactorUV; }; - class BRepApprox_Approx { public: @@ -80,10 +82,16 @@ public: Standard_EXPORT void Perform (const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ = Standard_True, const Standard_Boolean ApproxU1V1 = Standard_True, const Standard_Boolean ApproxU2V2 = Standard_True, const Standard_Integer indicemin = 0, const Standard_Integer indicemax = 0); - Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength); - - Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Boolean RelativeTol, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Integer NbPntMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength); - + Standard_EXPORT + void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, + const Standard_Integer DegMin, + const Standard_Integer DegMax, + const Standard_Integer NbIterMax, + const Standard_Integer NbPntMax = 30, + const Standard_Boolean ApproxWithTangency = Standard_True, + const Approx_ParametrizationType + Parametrization = Approx_ChordLength); + Standard_EXPORT void Perform(); Standard_EXPORT Standard_Real TolReached3d() const; @@ -106,22 +114,12 @@ protected: private: - - Standard_EXPORT Standard_Integer CorrectFinishIdx(const Standard_Integer theMinIdx, - const Standard_Integer theMaxIdx, - const Handle(BRepApprox_ApproxLine)& theline); - - Standard_EXPORT void Perform (const BRepAdaptor_Surface& Surf1, const IntSurf_Quadric& Surf2, const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax); - - Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const BRepAdaptor_Surface& Surf2, const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax); + Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const BRepAdaptor_Surface& Surf2, const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax, const Standard_Boolean isTheQuadFirst); Standard_EXPORT void UpdateTolReached(); //! Fill data structure for intersection approximation. - Standard_EXPORT void fillData(const Handle(BRepApprox_ApproxLine)& theLine, - const Standard_Boolean theApproxXYZ, - const Standard_Boolean theApproxU1V1, - const Standard_Boolean theApproxU2V2); + Standard_EXPORT void fillData(const Handle(BRepApprox_ApproxLine)& theLine); //! Prepare data structure for further computations. Standard_EXPORT void prepareDS(const Standard_Boolean theApproxXYZ, @@ -141,19 +139,15 @@ private: BRepApprox_TheComputeLineOfApprox myComputeLine; BRepApprox_TheComputeLineBezierOfApprox myComputeLineBezier; Approx_MCurvesToBSpCurve myBezToBSpl; - Standard_Boolean myTolReached; Standard_Boolean myWithTangency; Standard_Real myTol3d; Standard_Real myTol2d; - Standard_Boolean myRelativeTol; Standard_Integer myDegMin; Standard_Integer myDegMax; - Standard_Integer myNbPntMax; Standard_Integer myNbIterMax; Standard_Real myTolReached3d; Standard_Real myTolReached2d; Approx_Data myData; - Standard_Real myUVRes1, myUVRes2; NCollection_Vector myKnots; }; diff --git a/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx b/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx index 331323eb04..1e7f39c54e 100644 --- a/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx @@ -116,15 +116,12 @@ public: Standard_EXPORT const AppParCurves_MultiBSpCurve& SplineValue(); //! returns the type of parametrization - Standard_EXPORT void Parametrization (Approx_ParametrizationType& partype) const; + Standard_EXPORT Approx_ParametrizationType Parametrization () const; //! returns the new parameters of the approximation //! corresponding to the points of the multicurve . Standard_EXPORT const TColStd_Array1OfReal& Parameters (const Standard_Integer Index = 1) const; - - - protected: diff --git a/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx b/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx index 8df99ddb03..40d91b079c 100644 --- a/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx @@ -40,56 +40,71 @@ class BRepApprox_TheMultiLineOfApprox public: DEFINE_STANDARD_ALLOC - - //! The class SvSurfaces is used when the - //! approximation algorithm needs some extra points on - //! the line . A New line is then created which - //! shares the same surfaces and functions. - //! - //! SvSurfaces is a deferred class which allows - //! several implementations of this algorithm with - //! different surfaces (bi-parametric ones, or + //! The class SvSurfaces is used when the approximation algorithm + //! needs some extra points on the line . + //! A New line is then created which shares the same surfaces and functions. + //! SvSurfaces is a deferred class which allows several implementations of + //! this algorithm with different surfaces (bi-parametric ones, or //! implicit and biparametric ones) - Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, const Standard_Address PtrSvSurfaces, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0); - + Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, + const Standard_Address PtrSvSurfaces, + const Standard_Integer NbP3d, + const Standard_Integer NbP2d, + const Standard_Real xo, + const Standard_Real yo, + const Standard_Real zo, + const Standard_Real u1o, + const Standard_Real v1o, + const Standard_Real u2o, + const Standard_Real v2o, + const Standard_Boolean P2DOnFirst, + const Standard_Integer IndMin = 0, + const Standard_Integer IndMax = 0); + //! No Extra points will be added on the current line - Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0); - + Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, + const Standard_Integer NbP3d, + const Standard_Integer NbP2d, + const Standard_Real xo, + const Standard_Real yo, + const Standard_Real zo, + const Standard_Real u1o, + const Standard_Real v1o, + const Standard_Real u2o, + const Standard_Real v2o, + const Standard_Boolean P2DOnFirst, + const Standard_Integer IndMin = 0, + const Standard_Integer IndMax = 0); + Standard_EXPORT Standard_Integer FirstPoint() const; Standard_EXPORT Standard_Integer LastPoint() const; - + //! Returns the number of 2d points of a TheLine. Standard_EXPORT Standard_Integer NbP2d() const; - + //! Returns the number of 3d points of a TheLine. Standard_EXPORT Standard_Integer NbP3d() const; - + Standard_EXPORT Approx_Status WhatStatus() const; - //! returns the 3d points of the multipoint - //! when only 3d points exist. + //! Returns the 3d points of the multipoint when only 3d points exist. Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt) const; - - //! returns the 2d points of the multipoint - //! when only 2d points exist. + + //! Returns the 2d points of the multipoint when only 2d points exist. Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt2d& tabPt2d) const; - - //! returns the 3d and 2d points of the multipoint - //! . + + //! Returns the 3d and 2d points of the multipoint . Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt, TColgp_Array1OfPnt2d& tabPt2d) const; - - //! returns the 3d points of the multipoint - //! when only 3d points exist. + + //! Returns the 3d tangency points of the multipoint only when 3d points exist. Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV) const; - //! returns the 2d tangency points of the multipoint - //! only when 2d points exist. + //! Returns the 2d tangency points of the multipoint only when 2d points exist. Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec2d& tabV2d) const; - //! returns the 3d and 2d points of the multipoint - //! . + //! Returns the 3d and 2d points of the multipoint . Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const; Standard_EXPORT BRepApprox_TheMultiLineOfApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const; @@ -97,48 +112,25 @@ public: //! Dump of the current multi-line. Standard_EXPORT void Dump() const; - - - protected: - - - - + BRepApprox_TheMultiLineOfApprox operator=(BRepApprox_TheMultiLineOfApprox&); private: - - - - Standard_Address PtrOnmySvSurfaces; - Handle(BRepApprox_ApproxLine) myLine; - Standard_Integer indicemin; - Standard_Integer indicemax; - Standard_Integer nbp3d; - Standard_Integer nbp2d; - Standard_Boolean p2donfirst; - Standard_Real Xo; - Standard_Real Ax; - Standard_Real Yo; - Standard_Real Ay; - Standard_Real Zo; - Standard_Real Az; - Standard_Real U1o; - Standard_Real A1u; - Standard_Real V1o; - Standard_Real A1v; - Standard_Real U2o; - Standard_Real A2u; - Standard_Real V2o; - Standard_Real A2v; - + const Standard_Address PtrOnmySvSurfaces; + const Handle(BRepApprox_ApproxLine) myLine; + const Standard_Integer indicemin; + const Standard_Integer indicemax; + const Standard_Integer nbp3d; + const Standard_Integer nbp2d; + const Standard_Boolean p2donfirst; + const Standard_Real Xo; + const Standard_Real Yo; + const Standard_Real Zo; + const Standard_Real U1o; + const Standard_Real V1o; + const Standard_Real U2o; + const Standard_Real V2o; }; - - - - - - #endif // _BRepApprox_TheMultiLineOfApprox_HeaderFile diff --git a/src/BRepLib/BRepLib.cxx b/src/BRepLib/BRepLib.cxx index 98e3e0c005..b60055fd91 100644 --- a/src/BRepLib/BRepLib.cxx +++ b/src/BRepLib/BRepLib.cxx @@ -1259,7 +1259,20 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, else GCurve->PCurve2(curPC); } } - else IsSameP = 0; + else + { + //Approx_SameParameter has failed. + //Consequently, the situation might be, + //when 3D and 2D-curve do not have same-range. + GeomLib::SameRange( Tol2d, PC[i], + GCurve->First(), GCurve->Last(), + f3d,l3d,curPC); + + if (i == 0) GCurve->PCurve(curPC); + else GCurve->PCurve2(curPC); + + IsSameP = 0; + } } else IsSameP = 0; diff --git a/src/BSplCLib/BSplCLib_2.cxx b/src/BSplCLib/BSplCLib_2.cxx index 53f1675c4c..575753d1f8 100644 --- a/src/BSplCLib/BSplCLib_2.cxx +++ b/src/BSplCLib/BSplCLib_2.cxx @@ -31,6 +31,8 @@ #include +static const Standard_Integer aGlobalMaxDegree = 25; + //======================================================================= //struct : BSplCLib_DataContainer //purpose: Auxiliary structure providing buffers for poles and knots used in @@ -43,7 +45,7 @@ struct BSplCLib_DataContainer { (void)Degree; // avoid compiler warning Standard_OutOfRange_Raise_if (Degree > BSplCLib::MaxDegree() || - BSplCLib::MaxDegree() > 25, + BSplCLib::MaxDegree() > aGlobalMaxDegree, "BSplCLib: bspline degree is greater than maximum supported"); } @@ -324,7 +326,7 @@ BSplCLib::BuildBSpMatrix(const TColStd_Array1OfReal& Parameters, ReturnCode = 0, FirstNonZeroBsplineIndex, BandWidth, - MaxOrder = 21, + MaxOrder = aGlobalMaxDegree+1, Order ; math_Matrix BSplineBasis(1, MaxOrder, diff --git a/src/ChFi3d/ChFi3d_Builder_0.cxx b/src/ChFi3d/ChFi3d_Builder_0.cxx index 9dc4e638e8..9ba0cf32f2 100644 --- a/src/ChFi3d/ChFi3d_Builder_0.cxx +++ b/src/ChFi3d/ChFi3d_Builder_0.cxx @@ -3039,8 +3039,6 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)& S1, Standard_Real& tolreached, const Standard_Boolean wholeCurv) { - Standard_Real Step = 0.1; - gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2)); gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2)); gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4)); @@ -3267,7 +3265,8 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)& S1, else Ul = Uok; } else { // both projected, but where? - if (Uf == Ul) continue; + if (Abs(Uf - Ul) < Precision::PConfusion()) + continue; } ptestdeb = C3d->Value(Uf); ptestfin = C3d->Value(Ul); @@ -3323,7 +3322,8 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)& S1, // At this stage : // classic intersections have failed, the path is approached in vain. - // Standard_Real Step = 0.1; + + Standard_Real Step = 0.1; for(;;) { //Attention the parameters of arrow for the path and //the tolerance for the approximation can't be taken as those of the @@ -3451,8 +3451,12 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)& S1, // Handle(IntPatch_WLine) WL = new IntPatch_WLine(L2S,Standard_False); +#ifdef OCCT_DEBUG + //WL->Dump(0); +#endif + GeomInt_WLApprox approx; - approx.SetParameters(tolap,tol2d,4,8,0,1); + approx.SetParameters(tolap, tol2d, 4, 8, 0, 30, Standard_True); // manage here the approximations that are not useful on planes! approx.Perform(S1,S2,WL, Standard_True,Standard_True,Standard_True, diff --git a/src/Draft/Draft_Modification_1.cxx b/src/Draft/Draft_Modification_1.cxx index 57b0d8e065..47c00b581e 100644 --- a/src/Draft/Draft_Modification_1.cxx +++ b/src/Draft/Draft_Modification_1.cxx @@ -946,13 +946,14 @@ void Draft_Modification::Perform () return; } - Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast(); + Standard_Real Glob2Min = RealLast(); GeomAdaptor_Curve TheCurve; Standard_Integer i,j; //,jmin; if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve)) { + Standard_Real Dist2Min = RealLast(); imin = 0; for (i=1; i<= i2s.NbLines(); i++) { TheCurve.Load(i2s.Line(i)); @@ -1041,7 +1042,7 @@ void Draft_Modification::Perform () Dist2Min = myExtPC.SquareDistance(1); locpmin = myExtPC.Point(1).Parameter(); for (j=2; j<=myExtPC.NbExt(); j++) { - Dist2 = myExtPC.SquareDistance(j); + const Standard_Real Dist2 = myExtPC.SquareDistance(j); if (Dist2 < Dist2Min) { Dist2Min = Dist2; locpmin = myExtPC.Point(j).Parameter(); @@ -1142,15 +1143,15 @@ void Draft_Modification::Perform () Handle( Geom_Curve ) FirstCurve; if (Candidates.Length() > 1) { - Dist2Min = RealLast(); + Standard_Real DistMin = Precision::Infinite(); for (i = 1; i <= Candidates.Length(); i++) { Handle( Geom_Curve ) aCurve = Candidates(i); gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() ); - Dist2 = Pnt.SquareDistance( pfv ); - if (Dist2 < Dist2Min) + const Standard_Real Dist = Pnt.Distance( pfv ); + if (Dist - DistMin < -Precision::Confusion()) { - Dist2Min = Dist2; + DistMin = Dist; FirstCurve = aCurve; } } @@ -1210,12 +1211,12 @@ void Draft_Modification::Perform () TheCurve.Load( newC ); Extrema_ExtPC myExtPC( pfv, TheCurve ); - Dist2Min = RealLast(); + Standard_Real Dist2Min = RealLast(); for (i = 1; i <= myExtPC.NbExt(); i++) { if (myExtPC.IsMin(i)) { - Dist2 = myExtPC.SquareDistance(i); + const Standard_Real Dist2 = myExtPC.SquareDistance(i); if (Dist2 < Dist2Min) { Dist2Min = Dist2; diff --git a/src/GeomInt/GeomInt_IntSS.hxx b/src/GeomInt/GeomInt_IntSS.hxx index af993374cf..40ed65331b 100644 --- a/src/GeomInt/GeomInt_IntSS.hxx +++ b/src/GeomInt/GeomInt_IntSS.hxx @@ -40,6 +40,7 @@ class gp_Pnt2d; class IntPatch_RLine; class Bnd_Box2d; class Adaptor3d_TopolTool; +class IntPatch_WLine; @@ -110,7 +111,9 @@ public: //! of the source surface. Standard_EXPORT static void TrimILineOnSurfBoundaries (const Handle(Geom2d_Curve)& theC2d1, const Handle(Geom2d_Curve)& theC2d2, const Bnd_Box2d& theBound1, const Bnd_Box2d& theBound2, GeomInt_VectorOfReal& theArrayOfParameters); + Standard_EXPORT static Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL, const Standard_Integer ideb, const Standard_Integer ifin); + Standard_EXPORT static Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine, const Standard_Integer ideb, const Standard_Integer ifin, const Standard_Boolean onFirst); protected: diff --git a/src/GeomInt/GeomInt_IntSS.lxx b/src/GeomInt/GeomInt_IntSS.lxx index 24ed10cb45..95455a6897 100644 --- a/src/GeomInt/GeomInt_IntSS.lxx +++ b/src/GeomInt/GeomInt_IntSS.lxx @@ -15,6 +15,7 @@ // commercial license or contractual agreement. #include +#include //======================================================================= diff --git a/src/GeomInt/GeomInt_IntSS_1.cxx b/src/GeomInt/GeomInt_IntSS_1.cxx index 91832c5e04..76e1e88e9f 100644 --- a/src/GeomInt/GeomInt_IntSS_1.cxx +++ b/src/GeomInt/GeomInt_IntSS_1.cxx @@ -14,232 +14,227 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include +#include -#include #include -#include #include -#include #include #include -#include -#include -#include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include #include -#include +#include #include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include #include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -static - void Parameters(const Handle(GeomAdaptor_HSurface)& HS1, - const Handle(GeomAdaptor_HSurface)& HS2, - const gp_Pnt& Ptref, - Standard_Real& U1, - Standard_Real& V1, - Standard_Real& U2, - Standard_Real& V2); - -static - Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL, - const Standard_Integer ideb, - const Standard_Integer ifin); - -static - Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine, - const Standard_Integer ideb, - const Standard_Integer ifin, - const Standard_Boolean onFirst); - -static - Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine); - - -static - Standard_Boolean DecompositionOfWLine (const Handle(IntPatch_WLine)& theWLine, - const Handle(GeomAdaptor_HSurface)& theSurface1, - const Handle(GeomAdaptor_HSurface)& theSurface2, - const Standard_Real aTolSum, - const GeomInt_LineConstructor& theLConstructor, - IntPatch_SequenceOfLine& theNewLines); - -static - Standard_Real AdjustPeriodic(const Standard_Real theParameter, - const Standard_Real parmin, - const Standard_Real parmax, - const Standard_Real thePeriod, - Standard_Real& theOffset) ; -static - Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter, - const Standard_Real theFirstBoundary, - const Standard_Real theSecondBoundary, - const Standard_Real theResolution, - Standard_Boolean& IsOnFirstBoundary); - -static - Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint, - const gp_Pnt2d& theLastPoint, - const Standard_Real theUmin, - const Standard_Real theUmax, - const Standard_Real theVmin, - const Standard_Real theVmax, - gp_Pnt2d& theNewPoint); - - -static - void AdjustUPeriodic (const Handle(Geom_Surface)& aS, - const Handle(Geom2d_Curve)& aC2D); -static - void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, - IntSurf_Quadric& quad1); - -class ProjectPointOnSurf -{ - public: - ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {} - void Init(const Handle(Geom_Surface)& Surface, - const Standard_Real Umin, - const Standard_Real Usup, - const Standard_Real Vmin, - const Standard_Real Vsup); - void Init (); - void Perform(const gp_Pnt& P); - Standard_Boolean IsDone () const { return myIsDone; } - void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const; - Standard_Real LowerDistance() const; - protected: - Standard_Boolean myIsDone; - Standard_Integer myIndex; - Extrema_ExtPS myExtPS; - GeomAdaptor_Surface myGeomAdaptor; -}; +#include +#include //======================================================================= -//function : Init +//function : AdjustUPeriodic //purpose : //======================================================================= - void ProjectPointOnSurf::Init (const Handle(Geom_Surface)& Surface, - const Standard_Real Umin, - const Standard_Real Usup, - const Standard_Real Vmin, - const Standard_Real Vsup ) + static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D) { - const Standard_Real Tolerance = Precision::PConfusion(); + if (aC2D.IsNull() || !aS->IsUPeriodic()) + return; // - myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup); - myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance); - myIsDone = Standard_False; + const Standard_Real aEps=Precision::PConfusion();//1.e-9 + const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15 + // + Standard_Real umin,umax,vmin,vmax; + aS->Bounds(umin,umax,vmin,vmax); + const Standard_Real aPeriod = aS->UPeriod(); + + const Standard_Real aT1=aC2D->FirstParameter(); + const Standard_Real aT2=aC2D->LastParameter(); + const Standard_Real aTx=aT1+0.467*(aT2-aT1); + const gp_Pnt2d aPx=aC2D->Value(aTx); + // + Standard_Real aUx=aPx.X(); + if (fabs(aUx)(umax+aEps)) { + aUx-=aPeriod; + dU-=aPeriod; + } + // + if (dU!=0.) { + gp_Vec2d aV2D(dU, 0.); + aC2D->Translate(aV2D); + } } -//======================================================================= -//function : Init + + //======================================================================= +//function : GetQuadric //purpose : //======================================================================= - void ProjectPointOnSurf::Init () + static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1) { - myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0); - if (myIsDone) { - // evaluate the lower distance and its index; - Standard_Real Dist2Min = myExtPS.SquareDistance(1); - myIndex = 1; - for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++) + switch (HS1->Surface().GetType()) + { + case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break; + case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break; + case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break; + case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break; + case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break; + default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve"); + } +} + +//======================================================================= +//function : Parameters +//purpose : +//======================================================================= + static void Parameters( const Handle(GeomAdaptor_HSurface)& HS1, + const Handle(GeomAdaptor_HSurface)& HS2, + const gp_Pnt& Ptref, + Standard_Real& U1, + Standard_Real& V1, + Standard_Real& U2, + Standard_Real& V2) +{ + IntSurf_Quadric quad1,quad2; + // + GetQuadric(HS1, quad1); + GetQuadric(HS2, quad2); + // + quad1.Parameters(Ptref,U1,V1); + quad2.Parameters(Ptref,U2,V2); +} + +//======================================================================= +//function : ParametersOfNearestPointOnSurface +//purpose : +//======================================================================= +static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr, + Standard_Real& theU, + Standard_Real& theV) +{ + if(!theExtr.IsDone() || !theExtr.NbExt()) + return Standard_False; + + Standard_Integer anIndex = 1; + Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex); + for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++) + { + Standard_Real aSQD = theExtr.SquareDistance(i); + if (aSQD < aMinSQDist) { - const Standard_Real Dist2 = myExtPS.SquareDistance(i); - if (Dist2 < Dist2Min) { - Dist2Min = Dist2; - myIndex = i; - } + aMinSQDist = aSQD; + anIndex = i; + } + } + + theExtr.Point(anIndex).Parameter(theU, theV); + + return Standard_True; +} + +//======================================================================= +//function : GetSegmentBoundary +//purpose : +//======================================================================= +static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm, + const Handle(Geom2d_Curve)& theCurve, + GeomInt_VectorOfReal& theArrayOfParameters) +{ + Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter(); + + if(theSegm.HasFirstPoint()) + { + const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint(); + aU1 = anIPF.ParamOnFirst(); + } + + if(theSegm.HasLastPoint()) + { + const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint(); + aU2 = anIPL.ParamOnFirst(); + } + + theArrayOfParameters.Append(aU1); + theArrayOfParameters.Append(aU2); +} + +//======================================================================= +//function : IntersectCurveAndBoundary +//purpose : +//======================================================================= +static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d, + const Handle(Geom2d_Curve)* const theArrBounds, + const Standard_Integer theNumberOfCurves, + const Standard_Real theTol, + GeomInt_VectorOfReal& theArrayOfParameters) +{ + if(theC2d.IsNull()) + return; + + Geom2dAdaptor_Curve anAC1(theC2d); + for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++) + { + if(theArrBounds[aCurID].IsNull()) + continue; + + Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]); + Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol); + + if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty()) + continue; + + for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++) + { + const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst(); + theArrayOfParameters.Append(aParam); + } + + for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++) + { + GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters); } } } -//======================================================================= -//function : Perform -//purpose : -//======================================================================= -void ProjectPointOnSurf::Perform(const gp_Pnt& P) -{ - myExtPS.Perform(P); - Init (); -} -//======================================================================= -//function : LowerDistanceParameters -//purpose : -//======================================================================= -void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U, - Standard_Real& V ) const -{ - StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters"); - (myExtPS.Point(myIndex)).Parameter(U,V); -} -//======================================================================= -//function : LowerDistance -//purpose : -//======================================================================= -Standard_Real ProjectPointOnSurf::LowerDistance() const -{ - StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance"); - return sqrt(myExtPS.SquareDistance(myIndex)); -} -// //======================================================================= //function : MakeCurve //purpose : //======================================================================= void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, - const Handle(Adaptor3d_TopolTool) & dom1, - const Handle(Adaptor3d_TopolTool) & dom2, - const Standard_Real Tol, - const Standard_Boolean Approx, - const Standard_Boolean ApproxS1, - const Standard_Boolean ApproxS2) + const Handle(Adaptor3d_TopolTool) & dom1, + const Handle(Adaptor3d_TopolTool) & dom2, + const Standard_Real Tol, + const Standard_Boolean Approx, + const Standard_Boolean ApproxS1, + const Standard_Boolean ApproxS2) { Standard_Boolean myApprox1, myApprox2, myApprox; @@ -261,13 +256,11 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, typl = L->ArcType(); // if(typl==IntPatch_Walking) { - Handle(IntPatch_Line) anewL = - ComputePurgedWLine(Handle(IntPatch_WLine)::DownCast(L)); - // - if(anewL.IsNull()) { + Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L)); + if(aWLine.IsNull()) { return; } - L = anewL; + L = aWLine; } // // Line Constructor @@ -562,7 +555,7 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, GeomInt_WLApprox theapp3d; Standard_Real tol2d = myTolApprox; // - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True); aNbParts=myLConstruct.NbParts(); for (i=1; i<=aNbParts; i++) { @@ -658,12 +651,17 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, }// case IntPatch_Analytic: break; - //######################################## - // Walking - //######################################## + //######################################## + // Walking + //######################################## case IntPatch_Walking:{ Handle(IntPatch_WLine) WL = Handle(IntPatch_WLine)::DownCast(L); + +#ifdef OCCT_DEBUG + //WL->Dump(0); +#endif + // Standard_Integer ifprm, ilprm; // @@ -700,15 +698,10 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, // tol2d = myTolApprox; aTolSS=2.e-7; - if(myHS1 == myHS2) { - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False); - } - else { - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True); - } + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2); // bIsDecomposited = - DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL); + GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL); // aNbParts=myLConstruct.NbParts(); aNbSeqOfL=aSeqOfL.Length(); @@ -749,7 +742,7 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) && (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) { - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True); //Standard_Boolean bUseSurfaces; //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm); //if (bUseSurfaces) { @@ -1082,1034 +1075,6 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, break; } } -// -//======================================================================= -//function : AdjustUPeriodic -//purpose : -//======================================================================= - static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D) -{ - if (aC2D.IsNull() || !aS->IsUPeriodic()) - return; - // - const Standard_Real aEps=Precision::PConfusion();//1.e-9 - const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15 - // - Standard_Real umin,umax,vmin,vmax; - aS->Bounds(umin,umax,vmin,vmax); - const Standard_Real aPeriod = aS->UPeriod(); - - const Standard_Real aT1=aC2D->FirstParameter(); - const Standard_Real aT2=aC2D->LastParameter(); - const Standard_Real aTx=aT1+0.467*(aT2-aT1); - const gp_Pnt2d aPx=aC2D->Value(aTx); - // - Standard_Real aUx=aPx.X(); - if (fabs(aUx)(umax+aEps)) { - aUx-=aPeriod; - dU-=aPeriod; - } - // - if (dU!=0.) { - gp_Vec2d aV2D(dU, 0.); - aC2D->Translate(aV2D); - } -} -// -// -//======================================================================= -//function : GetQuadric -//purpose : -//======================================================================= - static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1) -{ - switch (HS1->Surface().GetType()) - { - case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break; - case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break; - case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break; - case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break; - case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break; - default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve"); - } -} - -//======================================================================= -//function : Parameters -//purpose : -//======================================================================= - void Parameters(const Handle(GeomAdaptor_HSurface)& HS1, - const Handle(GeomAdaptor_HSurface)& HS2, - const gp_Pnt& Ptref, - Standard_Real& U1, - Standard_Real& V1, - Standard_Real& U2, - Standard_Real& V2) -{ - IntSurf_Quadric quad1,quad2; - // - GetQuadric(HS1, quad1); - GetQuadric(HS2, quad2); - // - quad1.Parameters(Ptref,U1,V1); - quad2.Parameters(Ptref,U2,V2); -} - -//======================================================================= -//function : MakeBSpline -//purpose : -//======================================================================= -Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL, - const Standard_Integer ideb, - const Standard_Integer ifin) -{ - const Standard_Integer nbpnt = ifin-ideb+1; - TColgp_Array1OfPnt poles(1,nbpnt); - TColStd_Array1OfReal knots(1,nbpnt); - TColStd_Array1OfInteger mults(1,nbpnt); - Standard_Integer i = 1, ipidebm1 = ideb; - for(; i<=nbpnt; ipidebm1++, i++) - { - poles(i) = WL->Point(ipidebm1).Value(); - mults(i) = 1; - knots(i) = i-1; - } - mults(1) = mults(nbpnt) = 2; - return new Geom_BSplineCurve(poles,knots,mults,1); -} - -//======================================================================= -//function : MakeBSpline2d -//purpose : -//======================================================================= -Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine, - const Standard_Integer ideb, - const Standard_Integer ifin, - const Standard_Boolean onFirst) -{ - const Standard_Integer nbpnt = ifin-ideb+1; - TColgp_Array1OfPnt2d poles(1,nbpnt); - TColStd_Array1OfReal knots(1,nbpnt); - TColStd_Array1OfInteger mults(1,nbpnt); - Standard_Integer i = 1, ipidebm1 = ideb; - for(; i <= nbpnt; ipidebm1++, i++) - { - Standard_Real U, V; - if(onFirst) - theWLine->Point(ipidebm1).ParametersOnS1(U, V); - else - theWLine->Point(ipidebm1).ParametersOnS2(U, V); - poles(i).SetCoord(U, V); - mults(i) = 1; - knots(i) = i-1; - } - mults(1) = mults(nbpnt) = 2; - return new Geom2d_BSplineCurve(poles,knots,mults,1); -} - -//========================================================================= -// static function : ComputePurgedWLine -// purpose : Removes equal points (leave one of equal points) from theWLine -// and recompute vertex parameters. -// 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) aResult; - Handle(IntPatch_WLine) aLocalWLine; - Handle(IntPatch_WLine) aTmpWLine = theWLine; - - Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); - aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False); - Standard_Integer i, k, v, nb, nbvtx; - nbvtx = theWLine->NbVertex(); - nb = theWLine->NbPnts(); - - for(i = 1; i <= nb; i++) { - aLineOn2S->Add(theWLine->Point(i)); - } - - 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; - nb = aLineOn2S->NbPoints(); - anEndIndex = (anEndIndex > nb) ? nb : anEndIndex; - - if((aStartIndex >= nb) || (anEndIndex <= 1)) { - continue; - } - k = aStartIndex; - - while(k <= anEndIndex) { - - if(i != k) { - IntSurf_PntOn2S p1 = aLineOn2S->Value(i); - IntSurf_PntOn2S p2 = aLineOn2S->Value(k); - - if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) { - 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(avertexindex >= k) { - aVertex.SetParameter(aVertex.ParameterOnLine() - 1.); - } - aLocalWLine->AddVertex(aVertex); - } - aLineOn2S->RemovePoint(k); - anEndIndex--; - continue; - } - } - k++; - } - } - - if(aLineOn2S->NbPoints() > 1) { - aResult = aLocalWLine; - } - return aResult; -} -//======================================================================= -//function : DecompositionOfWLine -//purpose : -//======================================================================= -Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine, - const Handle(GeomAdaptor_HSurface)& theSurface1, - const Handle(GeomAdaptor_HSurface)& theSurface2, - const Standard_Real aTolSum, - const GeomInt_LineConstructor& theLConstructor, - IntPatch_SequenceOfLine& theNewLines) -{ - typedef NCollection_List ListOfInteger; - //have to use std::vector, not NCollection_Vector in order to use copy constructor of - //ListOfInteger which will be created with specific allocator instance - typedef std::vector > ArrayOfListOfInteger; - - Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary; - Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex; - Standard_Real aTol, umin, umax, vmin, vmax; - - //an inc allocator, it will contain wasted space (upon list's Clear()) but it should - //still be faster than the standard allocator, and wasted memory should not be - //significant and will be limited by time span of this function; - //this is a separate allocator from the anIncAlloc below what provides better data - //locality in the latter (by avoiding wastes which will only be in anIdxAlloc) - Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator(); - ListOfInteger aListOfPointIndex (anIdxAlloc); - - //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2; - ProjectPointOnSurf aPrj1, aPrj2; - Handle(Geom_Surface) aSurf1, aSurf2; - // - aNbParts=theLConstructor.NbParts(); - aNbPnts=theWLine->NbPnts(); - // - if((!aNbPnts) || (!aNbParts)){ - return Standard_False; - } - // - Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator(); - NCollection_StdAllocator anAlloc (anIncAlloc); - const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from - ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc); - - NCollection_LocalArray anArrayOfLineTypeArr (aNbPnts + 1); - Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr; - // - nblines = 0; - aTol = Precision::Confusion(); - // - aSurf1 = theSurface1->ChangeSurface().Surface(); - aSurf1->Bounds(umin, umax, vmin, vmax); - aPrj1.Init(aSurf1, umin, umax, vmin, vmax); - // - aSurf2 = theSurface2->ChangeSurface().Surface(); - aSurf2->Bounds(umin, umax, vmin, vmax); - aPrj2.Init(aSurf2, umin, umax, vmin, vmax); - // - // - bIsPrevPointOnBoundary=Standard_False; - for(pit=1; pit<=aNbPnts; pit++) { - const IntSurf_PntOn2S& aPoint = theWLine->Point(pit); - bIsCurrentPointOnBoundary=Standard_False; - // - // whether aPoint is on boundary or not - // - for(i=0; i<2; i++) {// exploration Surface 1,2 - Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2; - aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax); - // - for(j=0; j<2; j++) {// exploration of coordinate U,V - Standard_Boolean isperiodic; - // - isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic(); - if(!isperiodic) { - continue; - } - // - Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V; - Standard_Real aParameter, anoffset, anAdjustPar; - Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary; - // - aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol); - aPeriod = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod(); - alowerboundary = (!j) ? umin : vmin; - aupperboundary = (!j) ? umax : vmax; - U=0.;V=0.;//? - // - if(!i){ - aPoint.ParametersOnS1(U, V); - } - else{ - aPoint.ParametersOnS2(U, V); - } - // - aParameter = (!j) ? U : V; - anoffset=0.; - anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset); - // - bIsOnFirstBoundary=Standard_True; - // - bIsPointOnBoundary= - IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary); - - if(bIsPointOnBoundary) { - bIsCurrentPointOnBoundary = Standard_True; - break; - } - }// for(j=0; j<2; j++) - - if(bIsCurrentPointOnBoundary){ - break; - } - }// for(i=0; i<2; i++) - // - if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) { - - if(!aListOfPointIndex.IsEmpty()) { - nblines++; - anArrayOfLines[nblines] = aListOfPointIndex; - anArrayOfLineType[nblines] = bIsPrevPointOnBoundary; - aListOfPointIndex.Clear(); - } - bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary; - } - aListOfPointIndex.Append(pit); - } // for(pit=1; pit<=aNbPnts; pit++) - // - aNbListOfPointIndex=aListOfPointIndex.Extent(); - if(aNbListOfPointIndex) { - nblines++; - anArrayOfLines[nblines].Assign (aListOfPointIndex); - anArrayOfLineType[nblines] = bIsPrevPointOnBoundary; - aListOfPointIndex.Clear(); - } - // - if(nblines <= 1){ - return Standard_False; - } - // - // Correct wlines.begin - Standard_Integer aLineType; - TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines); - Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator()); - // - for(i = 1; i <= nblines; i++) { - aLineType=anArrayOfLineType[i]; - if(aLineType) { - continue; - } - // - const ListOfInteger& aListOfIndex = anArrayOfLines[i]; - if(aListOfIndex.Extent() < 2) { - continue; - } - // - TColStd_ListOfInteger aListOfFLIndex; - Standard_Integer aneighbourindex, aLineTypeNeib; - // - for(j = 0; j < 2; j++) {// neighbour line choice - aneighbourindex = (!j) ? (i-1) : (i+1); - if((aneighbourindex < 1) || (aneighbourindex > nblines)){ - continue; - } - // - aLineTypeNeib=anArrayOfLineType[aneighbourindex]; - if(!aLineTypeNeib){ - continue; - } - // - const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex]; - Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First(); - const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex); - // check if need use derivative.begin .end [absence] - // - IntSurf_PntOn2S aNewP = aPoint; - Standard_Integer surfit, parit; - // - for(surfit = 0; surfit < 2; ++surfit) { - - Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2; - - umin = aGASurface->FirstUParameter(); - umax = aGASurface->LastUParameter(); - vmin = aGASurface->FirstVParameter(); - vmax = aGASurface->LastVParameter(); - Standard_Real U=0., V=0.; - - if(!surfit) { - aNewP.ParametersOnS1(U, V); - } - else { - aNewP.ParametersOnS2(U, V); - } - // - Standard_Integer nbboundaries = 0; - Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1 - Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1 - // - for(parit = 0; parit < 2; parit++) { - Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic(); - - Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol); - Standard_Real alowerboundary = (!parit) ? umin : vmin; - Standard_Real aupperboundary = (!parit) ? umax : vmax; - - Standard_Real aParameter = (!parit) ? U : V; - Standard_Boolean bIsOnFirstBoundary = Standard_True; - - if(!isperiodic) { - if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) { - bIsUBoundary = (!parit); - bIsFirstBoundary = bIsOnFirstBoundary; - nbboundaries++; - } - } - else { - Standard_Real aPeriod = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod(); - Standard_Real anoffset = 0.; - Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset); - - if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) { - bIsUBoundary = (parit == 0); - bIsFirstBoundary = bIsOnFirstBoundary; - nbboundaries++; - } - } - } - // - Standard_Boolean bComputeLineEnd = Standard_False; - - if(nbboundaries == 2) { - bComputeLineEnd = Standard_True; - } - else if(nbboundaries == 1) { - Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic(); - - if(isperiodic) { - Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin; - Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax; - Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod(); - Standard_Real aParameter = (bIsUBoundary) ? U : V; - Standard_Real anoffset = 0.; - Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset); - - Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary); - Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist); - anotherPar += anoffset; - Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last(); - const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex); - Standard_Real nU1, nV1; - - if(surfit == 0) - aNeighbourPoint.ParametersOnS1(nU1, nV1); - else - aNeighbourPoint.ParametersOnS2(nU1, nV1); - - Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V); - Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar); - bComputeLineEnd = Standard_True; - Standard_Boolean bCheckAngle1 = Standard_False; - Standard_Boolean bCheckAngle2 = Standard_False; - gp_Vec2d aNewVec; - Standard_Real anewU = (bIsUBoundary) ? anotherPar : U; - Standard_Real anewV = (bIsUBoundary) ? V : anotherPar; - // - if(((adist1 - adist2) > Precision::PConfusion()) && - (adist2 < (aPeriod / 4.))) { - bCheckAngle1 = Standard_True; - aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV)); - - if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) { - aNewP.SetValue((surfit == 0), anewU, anewV); - bCheckAngle1 = Standard_False; - } - } - else if(adist1 < (aPeriod / 4.)) { - bCheckAngle2 = Standard_True; - aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V)); - - if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) { - bCheckAngle2 = Standard_False; - } - } - // - if(bCheckAngle1 || bCheckAngle2) { - // assume there are at least two points in line (see "if" above) - Standard_Integer anindexother = aneighbourpointindex; - - while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) { - anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1); - const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother); - Standard_Real nU2, nV2; - - if(surfit == 0) - aPrevNeighbourPoint.ParametersOnS1(nU2, nV2); - else - aPrevNeighbourPoint.ParametersOnS2(nU2, nV2); - gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1)); - - if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) { - continue; - } - else { - Standard_Real anAngle = aNewVec.Angle(aVecOld); - - if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) { - - if(bCheckAngle1) { - Standard_Real U1, U2, V1, V2; - IntSurf_PntOn2S atmppoint = aNewP; - atmppoint.SetValue((surfit == 0), anewU, anewV); - atmppoint.Parameters(U1, V1, U2, V2); - gp_Pnt P1 = theSurface1->Value(U1, V1); - gp_Pnt P2 = theSurface2->Value(U2, V2); - gp_Pnt P0 = aPoint.Value(); - - if(P0.IsEqual(P1, aTol) && - P0.IsEqual(P2, aTol) && - P1.IsEqual(P2, aTol)) { - bComputeLineEnd = Standard_False; - aNewP.SetValue((surfit == 0), anewU, anewV); - } - } - - if(bCheckAngle2) { - bComputeLineEnd = Standard_False; - } - } - break; - } - } // end while(anindexother...) - } - } - } - // - if(bComputeLineEnd) { - Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last(); - const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1); - Standard_Real nU1, nV1; - - if(surfit == 0) - aNeighbourPoint.ParametersOnS1(nU1, nV1); - else - aNeighbourPoint.ParametersOnS2(nU1, nV1); - gp_Pnt2d ap1(nU1, nV1); - gp_Pnt2d ap2(nU1, nV1); - Standard_Integer aneighbourpointindex2 = aneighbourpointindex1; - - while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) { - aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1); - const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2); - Standard_Real nU2, nV2; - - if(surfit == 0) - aPrevNeighbourPoint.ParametersOnS1(nU2, nV2); - else - aPrevNeighbourPoint.ParametersOnS2(nU2, nV2); - ap2.SetX(nU2); - ap2.SetY(nV2); - - if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) { - break; - } - } - gp_Pnt2d anewpoint; - Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint); - - if(found) { - // check point - Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2); - //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1; - ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1; - Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2; - - gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y()); - aProjector.Perform(aP3d); - - if(aProjector.IsDone()) { - if(aProjector.LowerDistance() < aCriteria) { - Standard_Real foundU = U, foundV = V; - aProjector.LowerDistanceParameters(foundU, foundV); - - if(surfit == 0) - aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV); - else - aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y()); - } - } - } - } - } - aSeqOfPntOn2S->Add(aNewP); - aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints()); - } - anArrayOfLineEnds.SetValue(i, aListOfFLIndex); - } - // Correct wlines.end - - // Split wlines.begin - for(j = 1; j <= theLConstructor.NbParts(); j++) { - Standard_Real fprm = 0., lprm = 0.; - theLConstructor.Part(j, fprm, lprm); - Standard_Integer ifprm = (Standard_Integer)fprm; - Standard_Integer ilprm = (Standard_Integer)lprm; - // - Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); - // - for(i = 1; i <= nblines; i++) { - if(anArrayOfLineType[i] != 0) { - continue; - } - const ListOfInteger& aListOfIndex = anArrayOfLines[i]; - - if(aListOfIndex.Extent() < 2) { - continue; - } - const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i); - Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2); - Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2); - - if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) { - bhasfirstpoint = (i != 1); - } - - if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) { - bhaslastpoint = (i != nblines); - } - Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last())); - Standard_Boolean bIsLastInside = ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last())); - - if(!bIsFirstInside && !bIsLastInside) { - if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) { - // append whole line, and boundaries if neccesary - if(bhasfirstpoint) { - const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First()); - aLineOn2S->Add(aP); - } - ListOfInteger::Iterator anIt(aListOfIndex); - - for(; anIt.More(); anIt.Next()) { - const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); - aLineOn2S->Add(aP); - } - - if(bhaslastpoint) { - const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last()); - aLineOn2S->Add(aP); - } - - // check end of split line (end is almost always) - Standard_Integer aneighbour = i + 1; - Standard_Boolean bIsEndOfLine = Standard_True; - - if(aneighbour <= nblines) { - const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour]; - - if((anArrayOfLineType[aneighbour] != 0) && - (aListOfNeighbourIndex.IsEmpty())) { - bIsEndOfLine = Standard_False; - } - } - - if(bIsEndOfLine) { - if(aLineOn2S->NbPoints() > 1) { - Handle(IntPatch_WLine) aNewWLine = - new IntPatch_WLine(aLineOn2S, Standard_False); - theNewLines.Append(aNewWLine); - } - aLineOn2S = new IntSurf_LineOn2S(); - } - } - continue; - } - // end if(!bIsFirstInside && !bIsLastInside) - - if(bIsFirstInside && bIsLastInside) { - // append inside points between ifprm and ilprm - ListOfInteger::Iterator anIt(aListOfIndex); - - for(; anIt.More(); anIt.Next()) { - if((anIt.Value() < ifprm) || (anIt.Value() > ilprm)) - continue; - const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); - aLineOn2S->Add(aP); - } - } - else { - - if(bIsFirstInside) { - // append points from ifprm to last point + boundary point - ListOfInteger::Iterator anIt(aListOfIndex); - - for(; anIt.More(); anIt.Next()) { - if(anIt.Value() < ifprm) - continue; - const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); - aLineOn2S->Add(aP); - } - - if(bhaslastpoint) { - const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last()); - aLineOn2S->Add(aP); - } - // check end of split line (end is almost always) - Standard_Integer aneighbour = i + 1; - Standard_Boolean bIsEndOfLine = Standard_True; - - if(aneighbour <= nblines) { - const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour]; - - if((anArrayOfLineType[aneighbour] != 0) && - (aListOfNeighbourIndex.IsEmpty())) { - bIsEndOfLine = Standard_False; - } - } - - if(bIsEndOfLine) { - if(aLineOn2S->NbPoints() > 1) { - Handle(IntPatch_WLine) aNewWLine = - new IntPatch_WLine(aLineOn2S, Standard_False); - theNewLines.Append(aNewWLine); - } - aLineOn2S = new IntSurf_LineOn2S(); - } - } - // end if(bIsFirstInside) - - if(bIsLastInside) { - // append points from first boundary point to ilprm - if(bhasfirstpoint) { - const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First()); - aLineOn2S->Add(aP); - } - ListOfInteger::Iterator anIt(aListOfIndex); - - for(; anIt.More(); anIt.Next()) { - if(anIt.Value() > ilprm) - continue; - const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); - aLineOn2S->Add(aP); - } - } - //end if(bIsLastInside) - } - } - - if(aLineOn2S->NbPoints() > 1) { - Handle(IntPatch_WLine) aNewWLine = - new IntPatch_WLine(aLineOn2S, Standard_False); - theNewLines.Append(aNewWLine); - } - } - // Split wlines.end - // - // cda002/I3 - Standard_Real fprm, lprm; - Standard_Integer ifprm, ilprm, aNbPoints, aIndex; - // - aNbParts=theLConstructor.NbParts(); - // - for(j = 1; j <= aNbParts; j++) { - theLConstructor.Part(j, fprm, lprm); - ifprm=(Standard_Integer)fprm; - ilprm=(Standard_Integer)lprm; - // - if ((ilprm-ifprm)==1) { - for(i = 1; i <= nblines; i++) { - aLineType=anArrayOfLineType[i]; - if(aLineType) { - continue; - } - // - const ListOfInteger& aListOfIndex = anArrayOfLines[i]; - aNbPoints=aListOfIndex.Extent(); - if(aNbPoints==1) { - aIndex=aListOfIndex.First(); - if (aIndex==ifprm || aIndex==ilprm) { - Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); - const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm); - const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm); - aLineOn2S->Add(aP1); - aLineOn2S->Add(aP2); - Handle(IntPatch_WLine) aNewWLine = - new IntPatch_WLine(aLineOn2S, Standard_False); - theNewLines.Append(aNewWLine); - } - } - } - } - } - // - return Standard_True; -} - -//======================================================================= -//function : AdjustPeriodic -//purpose : -//======================================================================= -Standard_Real AdjustPeriodic(const Standard_Real theParameter, - const Standard_Real parmin, - const Standard_Real parmax, - const Standard_Real thePeriod, - Standard_Real& theOffset) -{ - Standard_Real aresult = theParameter; - theOffset = 0.; - while(aresult < parmin) { - aresult += thePeriod; - theOffset += thePeriod; - } - while(aresult > parmax) { - aresult -= thePeriod; - theOffset -= thePeriod; - } - return aresult; -} - -//======================================================================= -//function : IsPointOnBoundary -//purpose : -//======================================================================= -Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter, - const Standard_Real theFirstBoundary, - const Standard_Real theSecondBoundary, - const Standard_Real theResolution, - Standard_Boolean& IsOnFirstBoundary) -{ - IsOnFirstBoundary = Standard_True; - if(fabs(theParameter - theFirstBoundary) < theResolution) - return Standard_True; - if(fabs(theParameter - theSecondBoundary) < theResolution) - { - IsOnFirstBoundary = Standard_False; - return Standard_True; - } - return Standard_False; -} -//======================================================================= -//function : FindPoint -//purpose : -//======================================================================= -Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint, - const gp_Pnt2d& theLastPoint, - const Standard_Real theUmin, - const Standard_Real theUmax, - const Standard_Real theVmin, - const Standard_Real theVmax, - gp_Pnt2d& theNewPoint) -{ - gp_Vec2d aVec(theFirstPoint, theLastPoint); - Standard_Integer i = 0, j = 0; - - for(i = 0; i < 4; i++) { - gp_Vec2d anOtherVec; - gp_Vec2d anOtherVecNormal; - gp_Pnt2d aprojpoint = theLastPoint; - - if((i % 2) == 0) { - anOtherVec.SetX(0.); - anOtherVec.SetY(1.); - anOtherVecNormal.SetX(1.); - anOtherVecNormal.SetY(0.); - - if(i < 2) - aprojpoint.SetX(theUmin); - else - aprojpoint.SetX(theUmax); - } - else { - anOtherVec.SetX(1.); - anOtherVec.SetY(0.); - anOtherVecNormal.SetX(0.); - anOtherVecNormal.SetY(1.); - - if(i < 2) - aprojpoint.SetY(theVmin); - else - aprojpoint.SetY(theVmax); - } - gp_Vec2d anormvec = aVec; - anormvec.Normalize(); - Standard_Real adot1 = anormvec.Dot(anOtherVecNormal); - - if(fabs(adot1) < Precision::Angular()) - continue; - Standard_Real adist = 0.; - - if((i % 2) == 0) { - adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax); - } - else { - adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax); - } - Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1; - - for(j = 0; j < 2; j++) { - anoffset = (j == 0) ? anoffset : -anoffset; - gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset)); - gp_Vec2d acurvec(theLastPoint, acurpoint); - - // - Standard_Real aDotX, anAngleX, aPC; - // - aDotX=aVec.Dot(acurvec); - anAngleX=aVec.Angle(acurvec); - aPC=Precision::PConfusion(); - // - if(aDotX > 0. && fabs(anAngleX) < aPC) { - // - if((i % 2) == 0) { - if((acurpoint.Y() >= theVmin) && - (acurpoint.Y() <= theVmax)) { - theNewPoint = acurpoint; - return Standard_True; - } - } - else { - if((acurpoint.X() >= theUmin) && - (acurpoint.X() <= theUmax)) { - theNewPoint = acurpoint; - return Standard_True; - } - } - } - } - } - return Standard_False; -} - -//======================================================================= -//function : ParametersOfNearestPointOnSurface -//purpose : -//======================================================================= -static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr, - Standard_Real& theU, - Standard_Real& theV) -{ - if(!theExtr.IsDone() || !theExtr.NbExt()) - return Standard_False; - - Standard_Integer anIndex = 1; - Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex); - for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++) - { - Standard_Real aSQD = theExtr.SquareDistance(i); - if (aSQD < aMinSQDist) - { - aMinSQDist = aSQD; - anIndex = i; - } - } - - theExtr.Point(anIndex).Parameter(theU, theV); - - return Standard_True; -} - -//======================================================================= -//function : GetSegmentBoundary -//purpose : -//======================================================================= -static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm, - const Handle(Geom2d_Curve)& theCurve, - GeomInt_VectorOfReal& theArrayOfParameters) -{ - Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter(); - - if(theSegm.HasFirstPoint()) - { - const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint(); - aU1 = anIPF.ParamOnFirst(); - } - - if(theSegm.HasLastPoint()) - { - const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint(); - aU2 = anIPL.ParamOnFirst(); - } - - theArrayOfParameters.Append(aU1); - theArrayOfParameters.Append(aU2); -} - -//======================================================================= -//function : IntersectCurveAndBoundary -//purpose : -//======================================================================= -static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d, - const Handle(Geom2d_Curve)* const theArrBounds, - const Standard_Integer theNumberOfCurves, - const Standard_Real theTol, - GeomInt_VectorOfReal& theArrayOfParameters) -{ - if(theC2d.IsNull()) - return; - - Geom2dAdaptor_Curve anAC1(theC2d); - for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++) - { - if(theArrBounds[aCurID].IsNull()) - continue; - - Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]); - Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol); - - if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty()) - continue; - - for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++) - { - const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst(); - theArrayOfParameters.Append(aParam); - } - - for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++) - { - GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters); - } - } -} //======================================================================= //function : TreatRLine @@ -2134,6 +1099,9 @@ void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL, anAHC2d = theRL->ArcOnS1(); theRL->ParamOnS1(tf, tl); theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d()); + tf = Max(tf, theC2d1->FirstParameter()); + tl = Min(tl, theC2d1->LastParameter()); + theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl); } else if (theRL->IsArcOnS2()) { @@ -2141,6 +1109,9 @@ void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL, anAHC2d = theRL->ArcOnS2(); theRL->ParamOnS2(tf, tl); theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d()); + tf = Max(tf, theC2d2->FirstParameter()); + tl = Min(tl, theC2d2->LastParameter()); + theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl); } else { @@ -2386,3 +1357,57 @@ void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end()); } + +//======================================================================= +//function : MakeBSpline +//purpose : +//======================================================================= +Handle(Geom_Curve) GeomInt_IntSS::MakeBSpline (const Handle(IntPatch_WLine)& WL, + const Standard_Integer ideb, + const Standard_Integer ifin) +{ + const Standard_Integer nbpnt = ifin-ideb+1; + TColgp_Array1OfPnt poles(1,nbpnt); + TColStd_Array1OfReal knots(1,nbpnt); + TColStd_Array1OfInteger mults(1,nbpnt); + Standard_Integer i = 1, ipidebm1 = ideb; + for(; i<=nbpnt; ipidebm1++, i++) + { + poles(i) = WL->Point(ipidebm1).Value(); + mults(i) = 1; + knots(i) = i-1; + } + mults(1) = mults(nbpnt) = 2; + return new Geom_BSplineCurve(poles,knots,mults,1); +} + +//======================================================================= +//function : MakeBSpline2d +//purpose : +//======================================================================= +Handle(Geom2d_BSplineCurve) GeomInt_IntSS:: + MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine, + const Standard_Integer ideb, + const Standard_Integer ifin, + const Standard_Boolean onFirst) +{ + const Standard_Integer nbpnt = ifin-ideb+1; + TColgp_Array1OfPnt2d poles(1,nbpnt); + TColStd_Array1OfReal knots(1,nbpnt); + TColStd_Array1OfInteger mults(1,nbpnt); + Standard_Integer i = 1, ipidebm1 = ideb; + for(; i <= nbpnt; ipidebm1++, i++) + { + Standard_Real U, V; + if(onFirst) + theWLine->Point(ipidebm1).ParametersOnS1(U, V); + else + theWLine->Point(ipidebm1).ParametersOnS2(U, V); + poles(i).SetCoord(U, V); + mults(i) = 1; + knots(i) = i-1; + } + + mults(1) = mults(nbpnt) = 2; + return new Geom2d_BSplineCurve(poles,knots,mults,1); +} diff --git a/src/GeomInt/GeomInt_LineTool.cxx b/src/GeomInt/GeomInt_LineTool.cxx index 97b5069b83..5dcf43df40 100644 --- a/src/GeomInt/GeomInt_LineTool.cxx +++ b/src/GeomInt/GeomInt_LineTool.cxx @@ -14,15 +14,250 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - +#include #include + +#include +#include +#include +#include #include #include -#include -#include #include #include -#include +#include +#include +#include +#include +#include + +class ProjectPointOnSurf +{ + public: + ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {} + void Init(const Handle(Geom_Surface)& Surface, + const Standard_Real Umin, + const Standard_Real Usup, + const Standard_Real Vmin, + const Standard_Real Vsup); + void Init (); + void Perform(const gp_Pnt& P); + Standard_Boolean IsDone () const { return myIsDone; } + void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const; + Standard_Real LowerDistance() const; + protected: + Standard_Boolean myIsDone; + Standard_Integer myIndex; + Extrema_ExtPS myExtPS; + GeomAdaptor_Surface myGeomAdaptor; +}; + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void ProjectPointOnSurf::Init ( const Handle(Geom_Surface)& Surface, + const Standard_Real Umin, + const Standard_Real Usup, + const Standard_Real Vmin, + const Standard_Real Vsup ) +{ + const Standard_Real Tolerance = Precision::PConfusion(); + // + myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup); + myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance); + myIsDone = Standard_False; +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void ProjectPointOnSurf::Init () +{ + myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0); + if (myIsDone) { + // evaluate the lower distance and its index; + Standard_Real Dist2Min = myExtPS.SquareDistance(1); + myIndex = 1; + for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++) + { + const Standard_Real Dist2 = myExtPS.SquareDistance(i); + if (Dist2 < Dist2Min) { + Dist2Min = Dist2; + myIndex = i; + } + } + } +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void ProjectPointOnSurf::Perform(const gp_Pnt& P) +{ + myExtPS.Perform(P); + Init (); +} + +//======================================================================= +//function : LowerDistanceParameters +//purpose : +//======================================================================= +void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U, + Standard_Real& V ) const +{ + StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters"); + (myExtPS.Point(myIndex)).Parameter(U,V); +} + +//======================================================================= +//function : LowerDistance +//purpose : +//======================================================================= +Standard_Real ProjectPointOnSurf::LowerDistance() const +{ + StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance"); + return sqrt(myExtPS.SquareDistance(myIndex)); +} + +//======================================================================= +//function : AdjustPeriodic +//purpose : +//======================================================================= +static Standard_Real AdjustPeriodic(const Standard_Real theParameter, + const Standard_Real parmin, + const Standard_Real parmax, + const Standard_Real thePeriod, + Standard_Real& theOffset) +{ + Standard_Real aresult = theParameter; + theOffset = 0.; + while(aresult < parmin) { + aresult += thePeriod; + theOffset += thePeriod; + } + while(aresult > parmax) { + aresult -= thePeriod; + theOffset -= thePeriod; + } + return aresult; +} + +//======================================================================= +//function : IsPointOnBoundary +//purpose : +//======================================================================= +static Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter, + const Standard_Real theFirstBoundary, + const Standard_Real theSecondBoundary, + const Standard_Real theResolution, + Standard_Boolean& IsOnFirstBoundary) +{ + IsOnFirstBoundary = Standard_True; + if(fabs(theParameter - theFirstBoundary) < theResolution) + return Standard_True; + if(fabs(theParameter - theSecondBoundary) < theResolution) + { + IsOnFirstBoundary = Standard_False; + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : FindPoint +//purpose : +//======================================================================= +static Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint, + const gp_Pnt2d& theLastPoint, + const Standard_Real theUmin, + const Standard_Real theUmax, + const Standard_Real theVmin, + const Standard_Real theVmax, + gp_Pnt2d& theNewPoint) +{ + gp_Vec2d aVec(theFirstPoint, theLastPoint); + Standard_Integer i = 0, j = 0; + + for(i = 0; i < 4; i++) { + gp_Vec2d anOtherVec; + gp_Vec2d anOtherVecNormal; + gp_Pnt2d aprojpoint = theLastPoint; + + if((i % 2) == 0) { + anOtherVec.SetX(0.); + anOtherVec.SetY(1.); + anOtherVecNormal.SetX(1.); + anOtherVecNormal.SetY(0.); + + if(i < 2) + aprojpoint.SetX(theUmin); + else + aprojpoint.SetX(theUmax); + } + else { + anOtherVec.SetX(1.); + anOtherVec.SetY(0.); + anOtherVecNormal.SetX(0.); + anOtherVecNormal.SetY(1.); + + if(i < 2) + aprojpoint.SetY(theVmin); + else + aprojpoint.SetY(theVmax); + } + gp_Vec2d anormvec = aVec; + anormvec.Normalize(); + Standard_Real adot1 = anormvec.Dot(anOtherVecNormal); + + if(fabs(adot1) < Precision::Angular()) + continue; + Standard_Real adist = 0.; + + if((i % 2) == 0) { + adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax); + } + else { + adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax); + } + Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1; + + for(j = 0; j < 2; j++) { + anoffset = (j == 0) ? anoffset : -anoffset; + gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset)); + gp_Vec2d acurvec(theLastPoint, acurpoint); + + // + Standard_Real aDotX, anAngleX, aPC; + // + aDotX=aVec.Dot(acurvec); + anAngleX=aVec.Angle(acurvec); + aPC=Precision::PConfusion(); + // + if(aDotX > 0. && fabs(anAngleX) < aPC) { + // + if((i % 2) == 0) { + if((acurpoint.Y() >= theVmin) && + (acurpoint.Y() <= theVmax)) { + theNewPoint = acurpoint; + return Standard_True; + } + } + else { + if((acurpoint.X() >= theUmin) && + (acurpoint.X() <= theUmax)) { + theNewPoint = acurpoint; + return Standard_True; + } + } + } + } + } + return Standard_False; +} + //======================================================================= //function : NbVertex @@ -164,3 +399,600 @@ Standard_Real GeomInt_LineTool::LastParameter (const Handle(IntPatch_Line)& L) } return 0.0; } + +//======================================================================= +//function : DecompositionOfWLine +//purpose : +//======================================================================= +Standard_Boolean GeomInt_LineTool:: + DecompositionOfWLine( const Handle(IntPatch_WLine)& theWLine, + const Handle(GeomAdaptor_HSurface)& theSurface1, + const Handle(GeomAdaptor_HSurface)& theSurface2, + const Standard_Real aTolSum, + const GeomInt_LineConstructor& theLConstructor, + IntPatch_SequenceOfLine& theNewLines) +{ + typedef NCollection_List ListOfInteger; + //have to use std::vector, not NCollection_Vector in order to use copy constructor of + //ListOfInteger which will be created with specific allocator instance + typedef std::vector > ArrayOfListOfInteger; + + Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary; + Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex; + Standard_Real aTol, umin, umax, vmin, vmax; + + //an inc allocator, it will contain wasted space (upon list's Clear()) but it should + //still be faster than the standard allocator, and wasted memory should not be + //significant and will be limited by time span of this function; + //this is a separate allocator from the anIncAlloc below what provides better data + //locality in the latter (by avoiding wastes which will only be in anIdxAlloc) + Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator(); + ListOfInteger aListOfPointIndex (anIdxAlloc); + + //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2; + ProjectPointOnSurf aPrj1, aPrj2; + Handle(Geom_Surface) aSurf1, aSurf2; + // + aNbParts=theLConstructor.NbParts(); + aNbPnts=theWLine->NbPnts(); + // + if((!aNbPnts) || (!aNbParts)){ + return Standard_False; + } + // + Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator(); + NCollection_StdAllocator anAlloc (anIncAlloc); + const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from + ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc); + + NCollection_LocalArray anArrayOfLineTypeArr (aNbPnts + 1); + Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr; + // + nblines = 0; + aTol = Precision::Confusion(); + // + aSurf1 = theSurface1->ChangeSurface().Surface(); + aSurf1->Bounds(umin, umax, vmin, vmax); + aPrj1.Init(aSurf1, umin, umax, vmin, vmax); + // + aSurf2 = theSurface2->ChangeSurface().Surface(); + aSurf2->Bounds(umin, umax, vmin, vmax); + aPrj2.Init(aSurf2, umin, umax, vmin, vmax); + // + // + bIsPrevPointOnBoundary=Standard_False; + for(pit=1; pit<=aNbPnts; pit++) { + const IntSurf_PntOn2S& aPoint = theWLine->Point(pit); + bIsCurrentPointOnBoundary=Standard_False; + // + // whether aPoint is on boundary or not + // + for(i=0; i<2; i++) {// exploration Surface 1,2 + Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2; + aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax); + // + for(j=0; j<2; j++) {// exploration of coordinate U,V + Standard_Boolean isperiodic; + // + isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic(); + if(!isperiodic) { + continue; + } + // + Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V; + Standard_Real aParameter, anoffset, anAdjustPar; + Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary; + // + aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol); + aPeriod = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod(); + alowerboundary = (!j) ? umin : vmin; + aupperboundary = (!j) ? umax : vmax; + U=0.;V=0.;//? + // + if(!i){ + aPoint.ParametersOnS1(U, V); + } + else{ + aPoint.ParametersOnS2(U, V); + } + // + aParameter = (!j) ? U : V; + anoffset=0.; + anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset); + // + bIsOnFirstBoundary=Standard_True; + // + bIsPointOnBoundary= + IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary); + + if(bIsPointOnBoundary) { + bIsCurrentPointOnBoundary = Standard_True; + break; + } + }// for(j=0; j<2; j++) + + if(bIsCurrentPointOnBoundary){ + break; + } + }// for(i=0; i<2; i++) + // + if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) { + + if(!aListOfPointIndex.IsEmpty()) { + nblines++; + anArrayOfLines[nblines] = aListOfPointIndex; + anArrayOfLineType[nblines] = bIsPrevPointOnBoundary; + aListOfPointIndex.Clear(); + } + bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary; + } + aListOfPointIndex.Append(pit); + } // for(pit=1; pit<=aNbPnts; pit++) + // + aNbListOfPointIndex=aListOfPointIndex.Extent(); + if(aNbListOfPointIndex) { + nblines++; + anArrayOfLines[nblines].Assign (aListOfPointIndex); + anArrayOfLineType[nblines] = bIsPrevPointOnBoundary; + aListOfPointIndex.Clear(); + } + // + if(nblines <= 1){ + return Standard_False; + } + // + // Correct wlines.begin + Standard_Integer aLineType; + TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines); + Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator()); + // + for(i = 1; i <= nblines; i++) { + aLineType=anArrayOfLineType[i]; + if(aLineType) { + continue; + } + // + const ListOfInteger& aListOfIndex = anArrayOfLines[i]; + if(aListOfIndex.Extent() < 2) { + continue; + } + // + TColStd_ListOfInteger aListOfFLIndex; + Standard_Integer aneighbourindex, aLineTypeNeib; + // + for(j = 0; j < 2; j++) {// neighbour line choice + aneighbourindex = (!j) ? (i-1) : (i+1); + if((aneighbourindex < 1) || (aneighbourindex > nblines)){ + continue; + } + // + aLineTypeNeib=anArrayOfLineType[aneighbourindex]; + if(!aLineTypeNeib){ + continue; + } + // + const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex]; + Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First(); + const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex); + // check if need use derivative.begin .end [absence] + // + IntSurf_PntOn2S aNewP = aPoint; + Standard_Integer surfit, parit; + // + for(surfit = 0; surfit < 2; ++surfit) { + + Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2; + + umin = aGASurface->FirstUParameter(); + umax = aGASurface->LastUParameter(); + vmin = aGASurface->FirstVParameter(); + vmax = aGASurface->LastVParameter(); + Standard_Real U=0., V=0.; + + if(!surfit) { + aNewP.ParametersOnS1(U, V); + } + else { + aNewP.ParametersOnS2(U, V); + } + // + Standard_Integer nbboundaries = 0; + Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1 + Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1 + // + for(parit = 0; parit < 2; parit++) { + Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic(); + + Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol); + Standard_Real alowerboundary = (!parit) ? umin : vmin; + Standard_Real aupperboundary = (!parit) ? umax : vmax; + + Standard_Real aParameter = (!parit) ? U : V; + Standard_Boolean bIsOnFirstBoundary = Standard_True; + + if(!isperiodic) { + if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) { + bIsUBoundary = (!parit); + bIsFirstBoundary = bIsOnFirstBoundary; + nbboundaries++; + } + } + else { + Standard_Real aPeriod = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod(); + Standard_Real anoffset = 0.; + Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset); + + if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) { + bIsUBoundary = (parit == 0); + bIsFirstBoundary = bIsOnFirstBoundary; + nbboundaries++; + } + } + } + // + Standard_Boolean bComputeLineEnd = Standard_False; + + if(nbboundaries == 2) { + bComputeLineEnd = Standard_True; + } + else if(nbboundaries == 1) { + Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic(); + + if(isperiodic) { + Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin; + Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax; + Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod(); + Standard_Real aParameter = (bIsUBoundary) ? U : V; + Standard_Real anoffset = 0.; + Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset); + + Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary); + Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist); + anotherPar += anoffset; + Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last(); + const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex); + Standard_Real nU1, nV1; + + if(surfit == 0) + aNeighbourPoint.ParametersOnS1(nU1, nV1); + else + aNeighbourPoint.ParametersOnS2(nU1, nV1); + + Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V); + Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar); + bComputeLineEnd = Standard_True; + Standard_Boolean bCheckAngle1 = Standard_False; + Standard_Boolean bCheckAngle2 = Standard_False; + gp_Vec2d aNewVec; + Standard_Real anewU = (bIsUBoundary) ? anotherPar : U; + Standard_Real anewV = (bIsUBoundary) ? V : anotherPar; + // + if(((adist1 - adist2) > Precision::PConfusion()) && + (adist2 < (aPeriod / 4.))) { + bCheckAngle1 = Standard_True; + aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV)); + + if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) { + aNewP.SetValue((surfit == 0), anewU, anewV); + bCheckAngle1 = Standard_False; + } + } + else if(adist1 < (aPeriod / 4.)) { + bCheckAngle2 = Standard_True; + aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V)); + + if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) { + bCheckAngle2 = Standard_False; + } + } + // + if(bCheckAngle1 || bCheckAngle2) { + // assume there are at least two points in line (see "if" above) + Standard_Integer anindexother = aneighbourpointindex; + + while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) { + anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1); + const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother); + Standard_Real nU2, nV2; + + if(surfit == 0) + aPrevNeighbourPoint.ParametersOnS1(nU2, nV2); + else + aPrevNeighbourPoint.ParametersOnS2(nU2, nV2); + gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1)); + + if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) { + continue; + } + else { + Standard_Real anAngle = aNewVec.Angle(aVecOld); + + if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) { + + if(bCheckAngle1) { + Standard_Real U1, U2, V1, V2; + IntSurf_PntOn2S atmppoint = aNewP; + atmppoint.SetValue((surfit == 0), anewU, anewV); + atmppoint.Parameters(U1, V1, U2, V2); + gp_Pnt P1 = theSurface1->Value(U1, V1); + gp_Pnt P2 = theSurface2->Value(U2, V2); + gp_Pnt P0 = aPoint.Value(); + + if(P0.IsEqual(P1, aTol) && + P0.IsEqual(P2, aTol) && + P1.IsEqual(P2, aTol)) { + bComputeLineEnd = Standard_False; + aNewP.SetValue((surfit == 0), anewU, anewV); + } + } + + if(bCheckAngle2) { + bComputeLineEnd = Standard_False; + } + } + break; + } + } // end while(anindexother...) + } + } + } + // + if(bComputeLineEnd) { + Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last(); + const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1); + Standard_Real nU1, nV1; + + if(surfit == 0) + aNeighbourPoint.ParametersOnS1(nU1, nV1); + else + aNeighbourPoint.ParametersOnS2(nU1, nV1); + gp_Pnt2d ap1(nU1, nV1); + gp_Pnt2d ap2(nU1, nV1); + Standard_Integer aneighbourpointindex2 = aneighbourpointindex1; + + while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) { + aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1); + const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2); + Standard_Real nU2, nV2; + + if(surfit == 0) + aPrevNeighbourPoint.ParametersOnS1(nU2, nV2); + else + aPrevNeighbourPoint.ParametersOnS2(nU2, nV2); + ap2.SetX(nU2); + ap2.SetY(nV2); + + if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) { + break; + } + } + gp_Pnt2d anewpoint; + Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint); + + if(found) { + // check point + Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2); + //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1; + ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1; + Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2; + + gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y()); + aProjector.Perform(aP3d); + + if(aProjector.IsDone()) { + if(aProjector.LowerDistance() < aCriteria) { + Standard_Real foundU = U, foundV = V; + aProjector.LowerDistanceParameters(foundU, foundV); + + if(surfit == 0) + aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV); + else + aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y()); + } + } + } + } + } + aSeqOfPntOn2S->Add(aNewP); + aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints()); + } + anArrayOfLineEnds.SetValue(i, aListOfFLIndex); + } + // Correct wlines.end + + // Split wlines.begin + for(j = 1; j <= theLConstructor.NbParts(); j++) { + Standard_Real fprm = 0., lprm = 0.; + theLConstructor.Part(j, fprm, lprm); + Standard_Integer ifprm = (Standard_Integer)fprm; + Standard_Integer ilprm = (Standard_Integer)lprm; + // + Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); + // + for(i = 1; i <= nblines; i++) { + if(anArrayOfLineType[i] != 0) { + continue; + } + const ListOfInteger& aListOfIndex = anArrayOfLines[i]; + + if(aListOfIndex.Extent() < 2) { + continue; + } + const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i); + Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2); + Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2); + + if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) { + bhasfirstpoint = (i != 1); + } + + if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) { + bhaslastpoint = (i != nblines); + } + Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last())); + Standard_Boolean bIsLastInside = ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last())); + + if(!bIsFirstInside && !bIsLastInside) { + if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) { + // append whole line, and boundaries if neccesary + if(bhasfirstpoint) { + const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First()); + aLineOn2S->Add(aP); + } + ListOfInteger::Iterator anIt(aListOfIndex); + + for(; anIt.More(); anIt.Next()) { + const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); + aLineOn2S->Add(aP); + } + + if(bhaslastpoint) { + const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last()); + aLineOn2S->Add(aP); + } + + // check end of split line (end is almost always) + Standard_Integer aneighbour = i + 1; + Standard_Boolean bIsEndOfLine = Standard_True; + + if(aneighbour <= nblines) { + const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour]; + + if((anArrayOfLineType[aneighbour] != 0) && + (aListOfNeighbourIndex.IsEmpty())) { + bIsEndOfLine = Standard_False; + } + } + + if(bIsEndOfLine) { + if(aLineOn2S->NbPoints() > 1) { + Handle(IntPatch_WLine) aNewWLine = + new IntPatch_WLine(aLineOn2S, Standard_False); + theNewLines.Append(aNewWLine); + } + aLineOn2S = new IntSurf_LineOn2S(); + } + } + continue; + } + // end if(!bIsFirstInside && !bIsLastInside) + + if(bIsFirstInside && bIsLastInside) { + // append inside points between ifprm and ilprm + ListOfInteger::Iterator anIt(aListOfIndex); + + for(; anIt.More(); anIt.Next()) { + if((anIt.Value() < ifprm) || (anIt.Value() > ilprm)) + continue; + const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); + aLineOn2S->Add(aP); + } + } + else { + + if(bIsFirstInside) { + // append points from ifprm to last point + boundary point + ListOfInteger::Iterator anIt(aListOfIndex); + + for(; anIt.More(); anIt.Next()) { + if(anIt.Value() < ifprm) + continue; + const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); + aLineOn2S->Add(aP); + } + + if(bhaslastpoint) { + const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last()); + aLineOn2S->Add(aP); + } + // check end of split line (end is almost always) + Standard_Integer aneighbour = i + 1; + Standard_Boolean bIsEndOfLine = Standard_True; + + if(aneighbour <= nblines) { + const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour]; + + if((anArrayOfLineType[aneighbour] != 0) && + (aListOfNeighbourIndex.IsEmpty())) { + bIsEndOfLine = Standard_False; + } + } + + if(bIsEndOfLine) { + if(aLineOn2S->NbPoints() > 1) { + Handle(IntPatch_WLine) aNewWLine = + new IntPatch_WLine(aLineOn2S, Standard_False); + theNewLines.Append(aNewWLine); + } + aLineOn2S = new IntSurf_LineOn2S(); + } + } + // end if(bIsFirstInside) + + if(bIsLastInside) { + // append points from first boundary point to ilprm + if(bhasfirstpoint) { + const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First()); + aLineOn2S->Add(aP); + } + ListOfInteger::Iterator anIt(aListOfIndex); + + for(; anIt.More(); anIt.Next()) { + if(anIt.Value() > ilprm) + continue; + const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value()); + aLineOn2S->Add(aP); + } + } + //end if(bIsLastInside) + } + } + + if(aLineOn2S->NbPoints() > 1) { + Handle(IntPatch_WLine) aNewWLine = + new IntPatch_WLine(aLineOn2S, Standard_False); + theNewLines.Append(aNewWLine); + } + } + // Split wlines.end + // + // cda002/I3 + Standard_Real fprm, lprm; + Standard_Integer ifprm, ilprm, aNbPoints, aIndex; + // + aNbParts=theLConstructor.NbParts(); + // + for(j = 1; j <= aNbParts; j++) { + theLConstructor.Part(j, fprm, lprm); + ifprm=(Standard_Integer)fprm; + ilprm=(Standard_Integer)lprm; + // + if ((ilprm-ifprm)==1) { + for(i = 1; i <= nblines; i++) { + aLineType=anArrayOfLineType[i]; + if(aLineType) { + continue; + } + // + const ListOfInteger& aListOfIndex = anArrayOfLines[i]; + aNbPoints=aListOfIndex.Extent(); + if(aNbPoints==1) { + aIndex=aListOfIndex.First(); + if (aIndex==ifprm || aIndex==ilprm) { + Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); + const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm); + const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm); + aLineOn2S->Add(aP1); + aLineOn2S->Add(aP2); + Handle(IntPatch_WLine) aNewWLine = + new IntPatch_WLine(aLineOn2S, Standard_False); + theNewLines.Append(aNewWLine); + } + } + } + } + } + // + return Standard_True; +} diff --git a/src/GeomInt/GeomInt_LineTool.hxx b/src/GeomInt/GeomInt_LineTool.hxx index 00b26c6a61..e99eb472fb 100644 --- a/src/GeomInt/GeomInt_LineTool.hxx +++ b/src/GeomInt/GeomInt_LineTool.hxx @@ -23,9 +23,12 @@ #include #include +#include +#include class IntPatch_Line; class IntPatch_Point; - +class IntPatch_WLine; +class GeomAdaptor_HSurface; class GeomInt_LineTool @@ -43,7 +46,13 @@ public: Standard_EXPORT static Standard_Real LastParameter (const Handle(IntPatch_Line)& L); - + Standard_EXPORT static Standard_Boolean + DecompositionOfWLine( const Handle(IntPatch_WLine)& theWLine, + const Handle(GeomAdaptor_HSurface)& theSurface1, + const Handle(GeomAdaptor_HSurface)& theSurface2, + const Standard_Real aTolSum, + const GeomInt_LineConstructor& theLConstructor, + IntPatch_SequenceOfLine& theNewLines); protected: diff --git a/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx b/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx index aa296ca796..7de0869ebb 100644 --- a/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx @@ -116,8 +116,8 @@ public: Standard_EXPORT const AppParCurves_MultiBSpCurve& SplineValue(); //! returns the type of parametrization - Standard_EXPORT void Parametrization (Approx_ParametrizationType& partype) const; - + Standard_EXPORT Approx_ParametrizationType Parametrization () const; + //! returns the new parameters of the approximation //! corresponding to the points of the multicurve . Standard_EXPORT const TColStd_Array1OfReal& Parameters (const Standard_Integer Index = 1) const; diff --git a/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx b/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx index 3582728aa1..78095b219b 100644 --- a/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx @@ -41,55 +41,75 @@ public: DEFINE_STANDARD_ALLOC - - //! The class SvSurfaces is used when the - //! approximation algorithm needs some extra points on - //! the line . A New line is then created which - //! shares the same surfaces and functions. - //! - //! SvSurfaces is a deferred class which allows - //! several implementations of this algorithm with - //! different surfaces (bi-parametric ones, or + //! The class SvSurfaces is used when the approximation algorithm + //! needs some extra points on the line . + //! A New line is then created which shares the same surfaces and functions. + //! SvSurfaces is a deferred class which allows several implementations of + //! this algorithm with different surfaces (bi-parametric ones, or //! implicit and biparametric ones) - Standard_EXPORT GeomInt_TheMultiLineOfWLApprox(const Handle(IntPatch_WLine)& line, const Standard_Address PtrSvSurfaces, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0); + Standard_EXPORT GeomInt_TheMultiLineOfWLApprox( const Handle(IntPatch_WLine)& line, + const Standard_Address PtrSvSurfaces, + const Standard_Integer NbP3d, + const Standard_Integer NbP2d, + const Standard_Real xo, + const Standard_Real yo, + const Standard_Real zo, + const Standard_Real u1o, + const Standard_Real v1o, + const Standard_Real u2o, + const Standard_Real v2o, + const Standard_Boolean P2DOnFirst, + const Standard_Integer IndMin = 0, + const Standard_Integer IndMax = 0); //! No Extra points will be added on the current line - Standard_EXPORT GeomInt_TheMultiLineOfWLApprox(const Handle(IntPatch_WLine)& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0); + Standard_EXPORT GeomInt_TheMultiLineOfWLApprox( const Handle(IntPatch_WLine)& line, + const Standard_Integer NbP3d, + const Standard_Integer NbP2d, + const Standard_Real xo, + const Standard_Real yo, + const Standard_Real zo, + const Standard_Real u1o, + const Standard_Real v1o, + const Standard_Real u2o, + const Standard_Real v2o, + const Standard_Boolean P2DOnFirst, + const Standard_Integer IndMin = 0, + const Standard_Integer IndMax = 0); Standard_EXPORT Standard_Integer FirstPoint() const; Standard_EXPORT Standard_Integer LastPoint() const; - + //! Returns the number of 2d points of a TheLine. Standard_EXPORT Standard_Integer NbP2d() const; - + //! Returns the number of 3d points of a TheLine. Standard_EXPORT Standard_Integer NbP3d() const; Standard_EXPORT Approx_Status WhatStatus() const; - //! returns the 3d points of the multipoint - //! when only 3d points exist. + //! Returns the 3d points of the multipoint when only 3d points exist. Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt) const; - //! returns the 2d points of the multipoint - //! when only 2d points exist. - Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt2d& tabPt2d) const; - - //! returns the 3d and 2d points of the multipoint - //! . + //! Returns the 2d points of the multipoint when only 2d points exist. + Standard_EXPORT void Value (const Standard_Integer MPointIndex, + TColgp_Array1OfPnt2d& tabPt2d) const; + + //! returns the 3d and 2d points of the multipoint . Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt, TColgp_Array1OfPnt2d& tabPt2d) const; - //! returns the 3d points of the multipoint - //! when only 3d points exist. - Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV) const; + //! Returns the 3d tangency points of the multipoint only + //! when 3d points exist. + Standard_EXPORT Standard_Boolean Tangency ( const Standard_Integer MPointIndex, + TColgp_Array1OfVec& tabV) const; - //! returns the 2d tangency points of the multipoint - //! only when 2d points exist. - Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec2d& tabV2d) const; + //! Returns the 2d tangency points of the multipoint only + //! when 2d points exist. + Standard_EXPORT Standard_Boolean Tangency ( const Standard_Integer MPointIndex, + TColgp_Array1OfVec2d& tabV2d) const; - //! returns the 3d and 2d points of the multipoint - //! . + //! Returns the 3d and 2d points of the multipoint . Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const; Standard_EXPORT GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const; @@ -101,44 +121,25 @@ public: protected: - - - - + GeomInt_TheMultiLineOfWLApprox operator=(GeomInt_TheMultiLineOfWLApprox&); private: - - - - Standard_Address PtrOnmySvSurfaces; - Handle(IntPatch_WLine) myLine; - Standard_Integer indicemin; - Standard_Integer indicemax; - Standard_Integer nbp3d; - Standard_Integer nbp2d; - Standard_Boolean p2donfirst; - Standard_Real Xo; - Standard_Real Ax; - Standard_Real Yo; - Standard_Real Ay; - Standard_Real Zo; - Standard_Real Az; - Standard_Real U1o; - Standard_Real A1u; - Standard_Real V1o; - Standard_Real A1v; - Standard_Real U2o; - Standard_Real A2u; - Standard_Real V2o; - Standard_Real A2v; + const Standard_Address PtrOnmySvSurfaces; + const Handle(IntPatch_WLine) myLine; + const Standard_Integer indicemin; + const Standard_Integer indicemax; + const Standard_Integer nbp3d; + const Standard_Integer nbp2d; + const Standard_Boolean p2donfirst; + const Standard_Real Xo; + const Standard_Real Yo; + const Standard_Real Zo; + const Standard_Real U1o; + const Standard_Real V1o; + const Standard_Real U2o; + const Standard_Real V2o; }; - - - - - - #endif // _GeomInt_TheMultiLineOfWLApprox_HeaderFile diff --git a/src/GeomInt/GeomInt_WLApprox.hxx b/src/GeomInt/GeomInt_WLApprox.hxx index ba734a4a0e..9e179b826f 100644 --- a/src/GeomInt/GeomInt_WLApprox.hxx +++ b/src/GeomInt/GeomInt_WLApprox.hxx @@ -51,19 +51,22 @@ class AppParCurves_MultiBSpCurve; struct Approx_Data { - Approx_Data() + Approx_Data() : myBezierApprox(Standard_True), + Xo(0.0), Yo(0.0), Zo(0.0), + U1o(0.0), V1o(0.0), U2o(0.0), V2o(0.0), + ApproxXYZ(Standard_True), + ApproxU1V1(Standard_True), + ApproxU2V2(Standard_True), + indicemin(0), indicemax(0), + myNbPntMax(30), parametrization(Approx_ChordLength) { - myMinFactorXYZ = 0.0; - myMinFactorUV = 0.0; } Standard_Boolean myBezierApprox; - Standard_Real Xo, Ax, Yo, Ay, Zo, Az, - U1o, A1u, V1o, A1v, U2o, A2u, V2o, A2v; + Standard_Real Xo, Yo, Zo, U1o, V1o, U2o, V2o; Standard_Boolean ApproxXYZ, ApproxU1V1, ApproxU2V2; - Standard_Integer indicemin, indicemax, nbpntmax; + Standard_Integer indicemin, indicemax, myNbPntMax; Approx_ParametrizationType parametrization; - Standard_Real myMinFactorXYZ, myMinFactorUV; }; @@ -80,10 +83,15 @@ public: Standard_EXPORT void Perform (const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ = Standard_True, const Standard_Boolean ApproxU1V1 = Standard_True, const Standard_Boolean ApproxU2V2 = Standard_True, const Standard_Integer indicemin = 0, const Standard_Integer indicemax = 0); - Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength); - - Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Boolean RelativeTol, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Integer NbPntMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength); - + Standard_EXPORT + void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, + const Standard_Integer DegMin, + const Standard_Integer DegMax, + const Standard_Integer NbIterMax, + const Standard_Integer NbPntMax = 30, + const Standard_Boolean ApproxWithTangency = Standard_True, + const Approx_ParametrizationType + Parametrization = Approx_ChordLength); Standard_EXPORT void Perform(); Standard_EXPORT Standard_Real TolReached3d() const; @@ -106,22 +114,12 @@ protected: private: - - Standard_EXPORT Standard_Integer CorrectFinishIdx(const Standard_Integer theMinIdx, - const Standard_Integer theMaxIdx, - const Handle(IntPatch_WLine)& theline); - - Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& Surf1, const IntSurf_Quadric& Surf2, const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax); - - Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax); + Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax, const Standard_Boolean isTheQuadFirst); Standard_EXPORT void UpdateTolReached(); //! Fill data structure for intersection approximation. - Standard_EXPORT void fillData(const Handle(IntPatch_WLine)& theLine, - const Standard_Boolean theApproxXYZ, - const Standard_Boolean theApproxU1V1, - const Standard_Boolean theApproxU2V2); + Standard_EXPORT void fillData(const Handle(IntPatch_WLine)& theLine); //! Prepare data structure for further computations. Standard_EXPORT void prepareDS(const Standard_Boolean theApproxXYZ, @@ -141,19 +139,15 @@ private: GeomInt_TheComputeLineOfWLApprox myComputeLine; GeomInt_TheComputeLineBezierOfWLApprox myComputeLineBezier; Approx_MCurvesToBSpCurve myBezToBSpl; - Standard_Boolean myTolReached; Standard_Boolean myWithTangency; Standard_Real myTol3d; Standard_Real myTol2d; - Standard_Boolean myRelativeTol; Standard_Integer myDegMin; Standard_Integer myDegMax; - Standard_Integer myNbPntMax; Standard_Integer myNbIterMax; Standard_Real myTolReached3d; Standard_Real myTolReached2d; Approx_Data myData; - Standard_Real myUVRes1, myUVRes2; NCollection_Vector myKnots; }; diff --git a/src/GeomliteTest/GeomliteTest_API2dCommands.cxx b/src/GeomliteTest/GeomliteTest_API2dCommands.cxx index 084c495e97..3effd51944 100644 --- a/src/GeomliteTest/GeomliteTest_API2dCommands.cxx +++ b/src/GeomliteTest/GeomliteTest_API2dCommands.cxx @@ -280,16 +280,14 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const //function : intersect //purpose : //======================================================================= - static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a) { if( n < 2) { -#ifdef OCCT_DEBUG cout<< "2dintersect curve curve [Tol]"<NbPoints(); i++) { - if(i <= Number || i >= (Line->NbPoints()-Number)) { - if(IsReversed) - Line->Value(i).ParametersOnS2(U,V); // S2 - quadric - else - Line->Value(i).ParametersOnS1(U,V); // S1 - quadric - cout << "point p" << i << " " << U << " " << V << endl; - } - } - cout << endl; -} -#endif -// DEBUG FUNCTION !!! - static void SearchVertices(const Handle(IntSurf_LineOn2S)& Line, const Handle(IntSurf_LineOn2S)& Vertices, TColStd_Array1OfInteger& PTypes) @@ -2378,19 +2318,23 @@ static Standard_Boolean SplitOnSegments(Handle(IntPatch_WLine)& WLine, return result; } +//======================================================================= +//function : DecomposeResult +//purpose : Split in the places where it passes through seam edge +// or singularity (apex of cone or pole of sphere). +// This passage is detected by jump of U-parameter +// from point to point. +//======================================================================= static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine, const Standard_Boolean IsReversed, const IntSurf_Quadric& theQuad, const Handle(Adaptor3d_TopolTool)& thePDomain, - const Handle(Adaptor3d_HSurface)& theQSurf, + const Handle(Adaptor3d_HSurface)& theQSurf, //quadric + const Handle(Adaptor3d_HSurface)& thePSurf, //parametric const Standard_Real theArcTol, IntPatch_SequenceOfLine& theLines) { - // Split in the places where it passes through seam edge or singularity - // (apex of cone or pole of sphere). This passage is detected by jump of U-parameter - // from point to point. - - const Standard_Real aDeltaUmax = 0.5*M_PI; + const Standard_Real aDeltaUmax = M_PI_2; const Standard_Real aTOL3D = 1.e-10, aTOL2D = Precision::PConfusion(), aTOL2DS = Precision::PConfusion(); @@ -2437,7 +2381,13 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine, // build WLine parts (if any) Standard_Boolean flNextLine = Standard_True; Standard_Boolean hasBeenDecomposed = Standard_False; - Standard_Boolean PrePointExist = Standard_False; + enum PrePoint_Type + { + PrePoint_NONE, + PrePoint_SEAM, + PrePoint_POLE + }PrePointExist = PrePoint_NONE; + IntSurf_PntOn2S PrePoint; while(flNextLine) { @@ -2449,15 +2399,86 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine, Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S(); //if((Lindex-Findex+1) <= 2 ) - if(aLindex <= aFindex) - return hasBeenDecomposed; + if((aLindex <= aFindex) && (PrePointExist != PrePoint_POLE)) + { + //break of "while(flNextLine)" cycle + break; + } - if (PrePointExist) + if (PrePointExist == PrePoint_SEAM) { sline->Add(PrePoint); - PrePointExist = Standard_False; } - + else if(PrePointExist == PrePoint_POLE) + { + //The last point of the line is the pole of the quadric. + //Therefore, Walking-line has been broken in this point. + //However, new line must start from this point. Here we must + //find its 2D-coordinates. + + //For sphere and cone, some intersection point is satisfied to the system + // \cos(U_{q}) = S_{x}(U_{s},V_{s})/F(V_{q}) + // \sin(U_{q}) = S_{y}(U_{s},V_{s})/F(V_{q}) + + //where + // @S_{x}@, @S_{y}@ are X and Y-coordinates of thePSurf; + // @U_{s}@ and @V_{s}@ are UV-parameters on thePSurf; + // @U_{q}@ and @V_{q}@ are UV-parameters on theQSurf; + // @F(V_{q}) @ is some function, which value independs on @U_{q}@ + // (form of this function depends on the type of the quadric). + + //When we go through the pole, the function @F(V_{q}) @ changes sign. + //Therefore, some cases are possible, when only @\cos(U_{q}) @ or + //only @ \sin(U_{q}) @ change sign. + + //Consequently, when the line goes throug the pole, @U_{q}@ can be + //changed on @\pi /2 @ (but not less). + + const Standard_Real aPeriod = M_PI_2, aHalfPeriod = M_PI_4; + const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aFindex); + + IntSurf_PntOn2S aFirstPoint = PrePoint; + + if(!aFirstPoint.IsSame(aRefPt, Precision::Confusion())) + { + Standard_Real aURef = 0.0, aVRef = 0.0; + Standard_Real aUquad = 0.0, aVquad = 0.0; + + //Take parameters on quadric + if(IsReversed) + { + aFirstPoint.ParametersOnS2(aUquad, aVquad); + aRefPt.ParametersOnS2(aURef, aVRef); + } + else + { + aFirstPoint.ParametersOnS1(aUquad, aVquad); + aRefPt.ParametersOnS1(aURef, aVRef); + } + + { + Standard_Real aDeltaPar = aURef-aUquad; + const Standard_Real anIncr = aPeriod*Sign(1.0, aDeltaPar); + while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod)) + { + aUquad += anIncr; + aDeltaPar = aURef-aUquad; + } + } + + aFirstPoint.SetValue(!IsReversed, aUquad, aVquad); + + sline->Add(aFirstPoint); + } + else + { + //break of "while(flNextLine)" cycle + break; + } + } + + PrePointExist = PrePoint_NONE; + // analyze other points for(Standard_Integer k = aFindex; k <= aLindex; k++) { @@ -2517,7 +2538,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine, Abs(AnU1 - 2*M_PI) <= Precision::PConfusion()) { //Modify - PrePointExist = Standard_True; + PrePointExist = PrePoint_SEAM; Standard_Real theU1, theV1; if (!IsReversed) { @@ -2534,6 +2555,240 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine, theU1, theV1); } } + else + {//Check if WLine goes through pole + const Standard_Real aTol = Precision::Confusion(); + const Standard_Real aPeriod = M_PI+M_PI, aHalfPeriod = M_PI; + const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aBindex-1); + + //Not quadric point + Standard_Real aU0 = 0.0, aV0 = 0.0; + //Quadric point + Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0; + + if(IsReversed) + { + aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef); + } + else + { + aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0); + } + + //Transforms parametric surface in coordinate-system of the quadric + gp_Trsf aTr; + aTr.SetTransformation(theQuad.Sphere().Position()); + + //aPQuad is Pole + gp_Pnt aPQuad; + Standard_Real aUquad = 0.0; + Standard_Real aVquad = 0.0; + + if(theQuad.TypeQuadric() == GeomAbs_Sphere) + { + aVquad = Sign(M_PI_2, aVQuadRef); + } + else if(theQuad.TypeQuadric() == GeomAbs_Cone) + { + const Standard_Real aRadius = theQuad.Cone().RefRadius(); + const Standard_Real aSemiAngle = theQuad.Cone().SemiAngle(); + aVquad = -aRadius/sin(aSemiAngle); + } + else + { + Standard_TypeMismatch::Raise( "IntPatch_ImpPrmIntersection.cxx," + " DecomposeResult(...): " + "Unsupported quadric with Pole"); + } + + theQSurf->D0(aUquad, aVquad, aPQuad); + + Extrema_GenLocateExtPS anExtr(aPQuad, thePSurf->Surface(), aU0, aV0, + Precision::PConfusion(), + Precision::PConfusion()); + + if(!anExtr.IsDone()) + break; + + if(anExtr.SquareDistance() < aTol*aTol) + { //Pole is an intersection point + //(lies in the quadric and the parametric surface) + + anExtr.Point().Parameter(aU0, aV0); + gp_Pnt aP0(anExtr.Point().Value()); + + IntSurf_PntOn2S aNewPoint; + aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), IsReversed, aU0, aV0); + + if(!aNewPoint.IsSame(aRefPt, Precision::Confusion())) + { //Found pole does not exist in the Walking-line + //It must be added there (with correct 2D-parameters) + + //2D-parameters of theparametric surface have already been found (aU0, aV0). + //Let find 2D-parameters on the quadric. + + //The algorithm depends on the type of the quadric. Here we consider a Sphere only. + //Analogical result can be made for another types (e.g. cone, but formulas will + //be different) in case of need. + + //First of all, we need in adjusting thePSurf in the coordinate system of the Sphere + //(in order to make the equation of the sphere maximal simple). However, as it will be + //shown later, thePSurf is used in algorithm in order to get its derivatives. Therefore, + //for improving performance, transformation of these vectors is enough (there is no point + //in transformation of full surface). + + gp_Pnt aPtemp; + gp_Vec aVecDu, aVecDv; + thePSurf->D1(aU0, aV0, aPtemp, aVecDu, aVecDv); + + //Derivatives of transformed thePSurf + aVecDu.Transform(aTr); + aVecDv.Transform(aTr); + + if(theQuad.TypeQuadric() == GeomAbs_Sphere) + { + //The intersection point (including the pole) + //must be satisfied to the following system: + + // \left\{\begin{matrix} + // R*\cos (U_{q})*\cos (V_{q})=S_{x}(U_{s},V_{s}) + // R*\sin (U_{q})*\cos (V_{q})=S_{y}(U_{s},V_{s}) + // R*\sin (V_{q})=S_{z}(U_{s},V_{s}) + // \end{matrix}\right, + //where + // R is the radius of the sphere; + // @S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf; + // @U_{s}@ and @V_{s}@ are equal to aU0 and aV0 corespondingly; + // @U_{q}@ and @V_{q}@ are equal to aUquad and aVquad corespondingly. + + //Consequently (from first two equations), + // \left\{\begin{matrix} + // \cos (U_{q}) = \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})} + // \sin (U_{q}) = \frac{S_{y}(U_{s},V_{s})}{R*\cos (V_{q})} + // \end{matrix}\right. + + //For pole, + // V_{q}=\pm \pi /2 \Rightarrow \cos (V_{q}) = 0 (denominator is equal to 0). + + //Therefore, computation U_{q} directly is impossibly. + // + //Let @V_{q}@ tends to @\pm \pi /2@. + //Then (indeterminate form is evaluated in accordance of L'Hospital rule), + // \cos (U_{q}) = \lim_{V_{q} \to (\pi /2-0)} + // \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}= + // -\lim_{V_{q} \to (\pi /2-0)} + // \frac{\frac{\partial S_{x}} + // {\partial U_{s}}*\frac{\mathrm{d} U_{s}} + // {\mathrm{d} V_{q}}+\frac{\partial S_{x}} + // {\partial V_{s}}*\frac{\mathrm{d} V_{s}} + // {\mathrm{d} V_{q}}}{R*\sin (V_{q})} = + // -\frac{1}{R}*\frac{\mathrm{d} U_{s}} + // {\mathrm{d} V_{q}}*(\frac{\partial S_{x}} + // {\partial U_{s}}+\frac{\partial S_{x}} + // {\partial V_{s}}*\frac{\mathrm{d} V_{s}} + // {\mathrm{d} U_{s}}) = + // -\frac{1}{R}*\frac{\mathrm{d} V_{s}} + // {\mathrm{d} V_{q}}*(\frac{\partial S_{x}} + // {\partial U_{s}}*\frac{\mathrm{d} U_{s}} + // {\mathrm{d} V_{s}}+\frac{\partial S_{x}} + // {\partial V_{s}}). + + //Analogicaly for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@). + + //Let mean, that + // \cos (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \cos (U_{q}) \left | _{V_{q} \to (\pi /2-0)} + // \sin (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \sin (U_{q}) \left | _{V_{q} \to (\pi /2-0)} + + //From the 3rd equation of the system, we obtain + // \frac{\mathrm{d} (R*\sin (V_{q}))}{\mathrm{d} V_{q}} = + // \frac{\mathrm{d} S_{z}(U_{s},V_{s})}{\mathrm{d} V_{q}} + //or + // R*\cos (V_{q}) = \frac{\partial S_{z}}{\partial U_{s}}* + // \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}} + // {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}}. + + //If @V_{q}=\pm \pi /2@, then + // \frac{\partial S_{z}}{\partial U_{s}}* + // \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}} + // {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}} = 0. + + //Consequently, if @\frac{\partial S_{z}}{\partial U_{s}} \neq 0 @ then + // \frac{\mathrm{d} U_{s}}{\mathrm{d} V_{s}} = + // -\frac{\frac{\partial S_{z}}{\partial V_{s}}} + // {\frac{\partial S_{z}}{\partial U_{s}}}. + + //If @ \frac{\partial S_{z}}{\partial V_{s}} \neq 0 @ then + // \frac{\mathrm{d} V_{s}}{\mathrm{d} U_{s}} = + // -\frac{\frac{\partial S_{z}}{\partial U_{s}}} + // {\frac{\partial S_{z}}{\partial V_{s}}} + + //Cases, when @ \frac{\partial S_{z}}{\partial U_{s}} = + //\frac{\partial S_{z}}{\partial V_{s}} = 0 @ are not consider here. + //The reason is written below. + + //Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates. + //Ask to pay attention to the fact that this vector is always normalyzed. + gp_Vec2d aV1; + + if(Abs(aVecDu.Z()) > Abs(aVecDv.Z())) + { + //Example of this exception is intersection a plane with a sphere + //when the plane tangents the sphere in some pole (i.e. only one + //intersection point, not line). In this case, U-coordinate of the + //sphere is undefined (can be realy anything). On the other hand, + //in this case there are not any Walking-line to be decomposited. + Standard_NumericError_Raise_if(Abs(aVecDu.Z()) < Precision::PConfusion(), + "IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): " + "Cannot find UV-coordinate for quadric in the pole"); + const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z(); + + aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(), + aVecDu.Y()*aDusDvs - aVecDv.Y()); + } + else + { + //Example of this exception is intersection a plane with a sphere + //when the plane tangents the sphere in some pole (i.e. only one + //intersection point, not line). In this case, U-coordinate of the + //sphere is undefined (can be realy anything). On the other hand, + //in this case there are not any Walking-line to be decomposited. + Standard_NumericError_Raise_if(Abs(aVecDv.Z()) < Precision::PConfusion(), + "IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): " + "Cannot find UV-coordinate for quadric in the pole"); + + const Standard_Real aDvsDus = aVecDu.Z()/aVecDv.Z(); + aV1.SetCoord( aVecDv.X()*aDvsDus - aVecDu.X(), + aVecDv.Y()*aDvsDus - aVecDu.Y()); + } + + aV1.Normalize(); + + if(Abs(aV1.X()) > Abs(aV1.Y())) + aUquad = Sign(asin(aV1.Y()), aVquad); + else + aUquad = Sign(acos(aV1.X()), aVquad); + } + + { + //Adjust found U-paramter to previous point of the Walking-line + Standard_Real aDeltaPar = aUQuadRef-aUquad; + const Standard_Real anIncr = aPeriod*Sign(1.0, aDeltaPar); + while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod)) + { + aUquad += anIncr; + aDeltaPar = aUQuadRef-aUquad; + } + } + + aNewPoint.SetValue(!IsReversed, aUquad, aVquad); + + sline->Add(aNewPoint); + PrePointExist = PrePoint_POLE; + PrePoint = aNewPoint; + } + } + } + //// break; } @@ -2572,11 +2827,6 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine, } } - if(!hasInternals) - { - ForcedPurgePoints(sline,IsReversed,theQuad); - } - Handle(IntPatch_WLine) wline = new IntPatch_WLine(sline,Standard_False, theLine->TransitionOnS1(),theLine->TransitionOnS2()); diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index 3e4c7db594..dc234e3bc8 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -12,6 +12,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include @@ -20,406 +21,23 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include #include #include +#include #include #define DEBUG 0 static const Standard_Integer aNbPointsInALine = 200; -//======================================================================= -//function : MinMax -//purpose : Replaces theParMIN = MIN(theParMIN, theParMAX), -// theParMAX = MAX(theParMIN, theParMAX). -//======================================================================= -static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX) -{ - if(theParMIN > theParMAX) - { - const Standard_Real aTmp = theParMAX; - theParMAX = theParMIN; - theParMIN = aTmp; - } -} - -//======================================================================= -//function : IsSeam -//purpose : Returns: -// 0 - if interval [theU1, theU2] does not intersect the "seam-edge" -// or if "seam-edge" do not exist; -// 1 - if interval (theU1, theU2) intersect the "seam-edge". -// 2 - if theU1 or/and theU2 lie ON the "seam-edge" -// -//ATTENTION!!! -// If (theU1 == theU2) then this function will return only both 0 or 2. -//======================================================================= -static Standard_Integer IsSeam( const Standard_Real theU1, - const Standard_Real theU2, - const Standard_Real thePeriod) -{ - if(IsEqual(thePeriod, 0.0)) - return 0; - - //If interval [theU1, theU2] intersect seam-edge then there exists an integer - //number N such as - // (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T), - //where T is the period. - //I.e. the inerval [theU1/T, theU2/T] must contain at least one - //integer number. In this case, Floor(theU1/T) and Floor(theU2/T) - //return different values or theU1/T is strictly integer number. - //Examples: - // 1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3. - // 2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2. - - const Standard_Real aVal1 = theU1/thePeriod, - aVal2 = theU2/thePeriod; - const Standard_Integer aPar1 = static_cast(Floor(aVal1)); - const Standard_Integer aPar2 = static_cast(Floor(aVal2)); - if(aPar1 != aPar2) - {//Interval (theU1, theU2] intersects seam-edge - if(IsEqual(aVal2, static_cast(aPar2))) - {//aVal2 is an integer number => theU2 lies ON the "seam-edge" - return 2; - } - - return 1; - } - - //Here, aPar1 == aPar2. - - if(IsEqual(aVal1, static_cast(aPar1))) - {//aVal1 is an integer number => theU1 lies ON the "seam-edge" - return 2; - } - - //If aVal2 is a true integer number then always (aPar1 != aPar2). - - return 0; -} - -//======================================================================= -//function : IsSeamOrBound -//purpose : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge" -// (if it exist) or surface boundaries and both thePtf and thePtl do -// not match "seam-edge" or boundaries. -// Point thePtmid lies in this segment. If thePtmid match -// "seam-edge" or boundaries strictly (without any tolerance) then -// the function will return TRUE. -// See comments in function body for detail information. -//======================================================================= -static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf, - const IntSurf_PntOn2S& thePtl, - const IntSurf_PntOn2S& thePtmid, - const Standard_Real theU1Period, - const Standard_Real theU2Period, - const Standard_Real theV1Period, - const Standard_Real theV2Period, - const Standard_Real theUfSurf1, - const Standard_Real theUlSurf1, - const Standard_Real theVfSurf1, - const Standard_Real theVlSurf1, - const Standard_Real theUfSurf2, - const Standard_Real theUlSurf2, - const Standard_Real theVfSurf2, - const Standard_Real theVlSurf2) -{ - Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0; - Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0; - thePtf.Parameters(aU11, aV11, aU12, aV12); - thePtl.Parameters(aU21, aV21, aU22, aV22); - - MinMax(aU11, aU21); - MinMax(aV11, aV21); - MinMax(aU12, aU22); - MinMax(aV12, aV22); - - if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0) - {//Interval [aU11, aU21] intersects theUfSurf1 - return Standard_True; - } - - if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0) - {//Interval [aU11, aU21] intersects theUlSurf1 - return Standard_True; - } - - if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0) - {//Interval [aV11, aV21] intersects theVfSurf1 - return Standard_True; - } - - if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0) - {//Interval [aV11, aV21] intersects theVlSurf1 - return Standard_True; - } - - if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0) - {//Interval [aU12, aU22] intersects theUfSurf2 - return Standard_True; - } - - if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0) - {//Interval [aU12, aU22] intersects theUlSurf2 - return Standard_True; - } - - if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0) - {//Interval [aV12, aV22] intersects theVfSurf2 - return Standard_True; - } - - if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0) - {//Interval [aV12, aV22] intersects theVlSurf2 - return Standard_True; - } - - if(IsSeam(aU11, aU21, theU1Period)) - return Standard_True; - - if(IsSeam(aV11, aV21, theV1Period)) - return Standard_True; - - if(IsSeam(aU12, aU22, theU2Period)) - return Standard_True; - - if(IsSeam(aV12, aV22, theV2Period)) - return Standard_True; - - /* - The segment [thePtf, thePtl] does not intersect the boundaries and - the seam-edge of the surfaces. - Nevertheless, following situation is possible: - - seam or - bound - | - thePtf * | - | - * thePtmid - thePtl * | - | - - This case must be processed, too. - */ - - Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0; - thePtmid.Parameters(aU1, aV1, aU2, aV2); - - if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1)) - return Standard_True; - - if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2)) - return Standard_True; - - if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1)) - return Standard_True; - - if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2)) - return Standard_True; - - if(IsSeam(aU1, aU1, theU1Period)) - return Standard_True; - - if(IsSeam(aU2, aU2, theU2Period)) - return Standard_True; - - if(IsSeam(aV1, aV1, theV1Period)) - return Standard_True; - - if(IsSeam(aV2, aV2, theV2Period)) - return Standard_True; - - return Standard_False; -} - -//======================================================================= -//function : JoinWLines -//purpose : joins all WLines from theSlin to one if it is possible and -// records the result into theSlin again. -// Lines will be kept to be splitted if: -// a) they are separated (has no common points); -// b) resulted line (after joining) go through -// seam-edges or surface boundaries. -// -// In addition, if points in theSPnt lies at least in one of -// the line in theSlin, this point will be deleted. -//======================================================================= -static void JoinWLines(IntPatch_SequenceOfLine& theSlin, - IntPatch_SequenceOfPoint& theSPnt, - const Standard_Real theTol3D, - const Standard_Real theU1Period, - const Standard_Real theU2Period, - const Standard_Real theV1Period, - const Standard_Real theV2Period, - const Standard_Real theUfSurf1, - const Standard_Real theUlSurf1, - const Standard_Real theVfSurf1, - const Standard_Real theVlSurf1, - const Standard_Real theUfSurf2, - const Standard_Real theUlSurf2, - const Standard_Real theVfSurf2, - const Standard_Real theVlSurf2) -{ - if(theSlin.Length() == 0) - return; - - for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++) - { - Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1))); - - if(aWLine1.IsNull()) - {//We must have failed to join not-point-lines - return; - } - - const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts(); - const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1); - const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1); - - for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++) - { - const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S(); - - if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) || - aPntCur.IsSame(aPntLW1, Precision::Confusion())) - { - theSPnt.Remove(aNPt); - aNPt--; - } - } - - Standard_Boolean hasBeenRemoved = Standard_False; - for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++) - { - Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2))); - - const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts(); - - const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1); - const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1); - - const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1); - const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2); - - if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion())) - { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2); - if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period, - theV1Period, theV2Period, theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2)) - { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) - { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->InsertBefore(1, aPt); - } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; - } - } - - if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion())) - { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1); - if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period, - theV1Period, theV2Period, theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2)) - { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) - { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->InsertBefore(1, aPt); - } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; - } - } - - if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion())) - { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2); - if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period, - theV1Period, theV2Period, theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2)) - { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) - { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->Add(aPt); - } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; - } - } - - if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion())) - { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1); - if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period, - theV1Period, theV2Period, theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2)) - { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) - { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->Add(aPt); - } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; - } - } - } - - if(hasBeenRemoved) - aNumOfLine1--; - } -} - //====================================================================== // function: SequenceOfLine //====================================================================== @@ -1103,7 +721,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Boolean isGeomInt, - const Standard_Boolean theIsReqToKeepRLine) + const Standard_Boolean theIsReqToKeepRLine, + const Standard_Boolean theIsReqToPostWLProc) { myTolArc = TolArc; myTolTang = TolTang; @@ -1336,6 +955,25 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); } + + if(!theIsReqToPostWLProc) + return; + + for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++) + { + Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i)); + + if(aWL.IsNull()) + continue; + + Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2); + + if(aRW.IsNull()) + continue; + + slin.InsertAfter(i, aRW); + slin.Remove(i); + } } //======================================================================= @@ -1350,7 +988,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& ListOfPnts, const Standard_Boolean RestrictLine, - const Standard_Boolean isGeomInt) + const Standard_Boolean isGeomInt, + const Standard_Boolean theIsReqToKeepRLine, + const Standard_Boolean theIsReqToPostWLProc) { myTolArc = TolArc; myTolTang = TolTang; @@ -1547,14 +1187,33 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) { GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, - TolTang, ListOfPnts, RestrictLine, typs1, typs2); + TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine); } else { GeomGeomPerfomTrimSurf(theS1, theD1, theS2, theD2, - TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); + TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine); } } + + if(!theIsReqToPostWLProc) + return; + + for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++) + { + Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i)); + + if(aWL.IsNull()) + continue; + + Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2); + + if(aRW.IsNull()) + continue; + + slin.InsertAfter(i, aRW); + slin.Remove(i); + } } //======================================================================= @@ -1912,15 +1571,19 @@ void IntPatch_Intersection:: spnt.Append(aPoint); } - JoinWLines( slin, spnt, theTolTang, - theS1->IsUPeriodic()? theS1->UPeriod() : 0.0, - theS2->IsUPeriodic()? theS2->UPeriod() : 0.0, - theS1->IsVPeriodic()? theS1->VPeriod() : 0.0, - theS2->IsVPeriodic()? theS2->VPeriod() : 0.0, - theS1->FirstUParameter(), theS1->LastUParameter(), - theS1->FirstVParameter(), theS1->LastVParameter(), - theS2->FirstUParameter(), theS2->LastUParameter(), - theS2->FirstVParameter(), theS2->LastVParameter()); + IntPatch_WLineTool::JoinWLines( slin, spnt, theTolTang, + theS1->IsUPeriodic()? theS1->UPeriod() : 0.0, + theS2->IsUPeriodic()? theS2->UPeriod() : 0.0, + theS1->IsVPeriodic()? theS1->VPeriod() : 0.0, + theS2->IsVPeriodic()? theS2->VPeriod() : 0.0, + theS1->FirstUParameter(), + theS1->LastUParameter(), + theS1->FirstVParameter(), + theS1->LastVParameter(), + theS2->FirstUParameter(), + theS2->LastUParameter(), + theS2->FirstVParameter(), + theS2->LastVParameter()); } } } @@ -2000,31 +1663,35 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, for (; i<=nblm; i++) slin.Append(interpp.Line(i)); } } + + for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++) + { + Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i)); + + if(aWL.IsNull()) + continue; + + Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2); + + if(aRW.IsNull()) + continue; + + slin.InsertAfter(i, aRW); + slin.Remove(i); + } } -//====================================================================== -#include -#include -#include -#include -#define MAXR 200 +#ifdef DUMPOFIntPatch_Intersection -//void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1, -// Handle(Adaptor2d_HCurve2d) *R2, -// int *NR1, -// int *NR2, -// Standard_Integer nbR1, -// Standard_Integer nbR2, -// const IntPatch_Point& VTX) -void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *, +void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1, Handle(Adaptor2d_HCurve2d) *, + int *NR1, int *, - int *, + Standard_Integer nbR1, Standard_Integer , - Standard_Integer , - const IntPatch_Point& ) + const IntPatch_Point& VTX) { - /* + if(VTX.IsOnDomS1()) { //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1()))))); @@ -2038,18 +1705,17 @@ void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *, printf("\n R Pas trouvee (IntPatch)\n"); } - */ } +#endif - -//void IntPatch_Intersection::Dump(const Standard_Integer Mode, -void IntPatch_Intersection::Dump(const Standard_Integer , - const Handle(Adaptor3d_HSurface)& S1, - const Handle(Adaptor3d_TopolTool)& D1, - const Handle(Adaptor3d_HSurface)& S2, - const Handle(Adaptor3d_TopolTool)& D2) const +void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/, + const Handle(Adaptor3d_HSurface)& /*S1*/, + const Handle(Adaptor3d_TopolTool)& /*D1*/, + const Handle(Adaptor3d_HSurface)& /*S2*/, + const Handle(Adaptor3d_TopolTool)& /*D2*/) const { - +#ifdef DUMPOFIntPatch_Intersection + const int MAXR = 200; //-- ---------------------------------------------------------------------- //-- construction de la liste des restrictions & vertex //-- @@ -2061,14 +1727,14 @@ void IntPatch_Intersection::Dump(const Standard_Integer , NR1[nbR1]=0; nbR1++; } - for(D2->Init();D2->More() && nbR2Next()) { + for(D2->Init();D2->More() && nbR2Next()) { R2[nbR2]=D2->Value(); NR2[nbR2]=0; nbR2++; } printf("\nDUMP_INT: ----empt:%2ud tgte:%2ud oppo:%2ud ---------------------------------",empt,tgte,empt); - Standard_Integer i,j,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba; + Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba; nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0; nbl=NbLines(); for(i=1;i<=nbl;i++) { @@ -2151,7 +1817,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer , printf("\nDUMP_LC :vtx :%2d r:%2d :%2d :%2d", nbvw,nbvr,nbva,nbvg); + printf("\n"); - - printf("\n"); +#endif } diff --git a/src/IntPatch/IntPatch_Intersection.hxx b/src/IntPatch/IntPatch_Intersection.hxx index 799c099835..cfe6b037bb 100644 --- a/src/IntPatch/IntPatch_Intersection.hxx +++ b/src/IntPatch/IntPatch_Intersection.hxx @@ -79,14 +79,32 @@ public: //! When intersection result returns IntPatch_RLine and another //! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE) //! will always keep both lines even if they are coincided. - Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False); + //! Flag theIsReqToPostWLProc has been enterred only for + //! compatibility with TopOpeBRep package. It shall be deleted + //! after deleting TopOpeBRep. + //! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line + //! obtained after intersection algorithm directly (wothout any post-processing). + Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True); //! If isGeomInt == Standard_False, then method //! Param-Param intersection will be used. - Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True); + //! Flag theIsReqToKeepRLine has been enterred only for + //! compatibility with TopOpeBRep package. It shall be deleted + //! after deleting TopOpeBRep. + //! When intersection result returns IntPatch_RLine and another + //! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE) + //! will always keep both lines even if they are coincided. + //! Flag theIsReqToPostWLProc has been enterred only for + //! compatibility with TopOpeBRep package. It shall be deleted + //! after deleting TopOpeBRep. + //! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line + //! obtained after intersection algorithm directly (wothout any post-processing). + Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True); + //! Perform with start point Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2, const Standard_Real TolArc, const Standard_Real TolTang); + //! Uses for finding self-intersected surfaces. Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolArc, const Standard_Real TolTang); //! Returns True if the calculus was succesfull. diff --git a/src/IntPatch/IntPatch_WLineTool.cxx b/src/IntPatch/IntPatch_WLineTool.cxx new file mode 100644 index 0000000000..02208c1f68 --- /dev/null +++ b/src/IntPatch/IntPatch_WLineTool.cxx @@ -0,0 +1,953 @@ +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public 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. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +//======================================================================= +//function : MinMax +//purpose : Replaces theParMIN = MIN(theParMIN, theParMAX), +// theParMAX = MAX(theParMIN, theParMAX). +// +// Static subfunction in IsSeamOrBound. +//======================================================================= +static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX) +{ + if(theParMIN > theParMAX) + { + const Standard_Real aTmp = theParMAX; + theParMAX = theParMIN; + theParMIN = aTmp; + } +} + +//========================================================================= +// function : FillPointsHash +// purpose : Fill points hash by input data. +// Static subfunction in ComputePurgedWLine. +//========================================================================= +static void FillPointsHash(const Handle(IntPatch_WLine) &theWLine, + NCollection_Array1 &thePointsHash) +{ + // 1 - Delete point. + // 0 - Store point. + // -1 - Vertex point (not delete). + Standard_Integer i, v; + + for(i = 1; i <= theWLine->NbPnts(); i++) + thePointsHash.SetValue(i, 0); + + for(v = 1; v <= theWLine->NbVertex(); v++) + { + IntPatch_Point aVertex = theWLine->Vertex(v); + Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine(); + thePointsHash.SetValue(avertexindex, -1); + } +} + +//========================================================================= +// function : MakeNewWLine +// purpose : Makes new walking line according to the points hash +// Static subfunction in ComputePurgedWLine and DeleteOuter. +//========================================================================= +static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine) &theWLine, + const NCollection_Array1 &thePointsHash) +{ + Standard_Integer i; + + Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S(); + Handle(IntPatch_WLine) aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False); + Standard_Integer anOldLineIdx = 1, aVertexIdx = 1; + for(i = 1; i <= thePointsHash.Upper(); i++) + { + if (thePointsHash(i) == 0) + { + // Store this point. + aPurgedLineOn2S->Add(theWLine->Point(i)); + anOldLineIdx++; + } + else if (thePointsHash(i) == -1) + { + // Add vertex. + IntPatch_Point aVertex = theWLine->Vertex(aVertexIdx++); + aVertex.SetParameter(anOldLineIdx++); + aLocalWLine->AddVertex(aVertex); + aPurgedLineOn2S->Add(theWLine->Point(i)); + } + } + + return aLocalWLine; +} + +//========================================================================= +// function : MovePoint +// purpose : Move point into surface param space. No interpolation used +// because walking algorithm should care for closeness to the param space. +// Static subfunction in ComputePurgedWLine. +//========================================================================= +static void MovePoint(const Handle(Adaptor3d_HSurface) &theS1, + Standard_Real &U1, Standard_Real &V1) +{ + if (U1 < theS1->FirstUParameter()) + U1 = theS1->FirstUParameter(); + + if (U1 > theS1->LastUParameter()) + U1 = theS1->LastUParameter(); + + if (V1 < theS1->FirstVParameter()) + V1 = theS1->FirstVParameter(); + + if (V1 > theS1->LastVParameter()) + V1 = theS1->LastVParameter(); +} + +//========================================================================= +// function : DeleteOuterPoints +// purpose : Check and delete out of bounds points on walking line. +// Static subfunction in ComputePurgedWLine. +//========================================================================= +static Handle(IntPatch_WLine) + DeleteOuterPoints(const Handle(IntPatch_WLine) &theWLine, + const Handle(Adaptor3d_HSurface) &theS1, + const Handle(Adaptor3d_HSurface) &theS2, + const Handle(Adaptor3d_TopolTool) &theDom1, + const Handle(Adaptor3d_TopolTool) &theDom2) +{ + Standard_Integer i; + + NCollection_Array1 aDelOuterPointsHash(1, theWLine->NbPnts()); + FillPointsHash(theWLine, aDelOuterPointsHash); + + if (theS1->IsUPeriodic() || theS1->IsVPeriodic() || + theS2->IsUPeriodic() || theS2->IsVPeriodic() ) + return theWLine; + + gp_Pnt2d aPntOnF1, aPntOnF2; + Standard_Real aX1, aY1, aX2, aY2; + + // Iterate over points in walking line and delete which are out of bounds. + // Forward. + Standard_Boolean isAllDeleted = Standard_True; + Standard_Boolean aChangedFirst = Standard_False; + Standard_Integer aFirstGeomIdx = 1; + for(i = 1; i <= theWLine->NbPnts(); i++) + { + theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2); + aPntOnF1.SetCoord(aX1, aY1); + aPntOnF2.SetCoord(aX2, aY2); + + TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion()); + TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion()); + + if (aState1 == TopAbs_OUT || + aState2 == TopAbs_OUT ) + { + aDelOuterPointsHash(i) = 1; + aChangedFirst = Standard_True; + } + else + { + isAllDeleted = Standard_False; + + aFirstGeomIdx = Max (i - 1, 1); + if (aDelOuterPointsHash(i) == -1) + aFirstGeomIdx = i; // Use data what lies in (i) point / vertex. + + aDelOuterPointsHash(i) = -1; + break; + } + } + + if (isAllDeleted) + { + // ALL points are out of bounds: + // case boolean bcut_complex F5 and similar. + return theWLine; + } + + // Backward. + Standard_Boolean aChangedLast = Standard_False; + Standard_Integer aLastGeomIdx = theWLine->NbPnts(); + for(i = theWLine->NbPnts(); i >= 1; i--) + { + theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2); + aPntOnF1.SetCoord(aX1, aY1); + aPntOnF2.SetCoord(aX2, aY2); + + TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion()); + TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion()); + + if (aState1 == TopAbs_OUT || + aState2 == TopAbs_OUT ) + { + aDelOuterPointsHash(i) = 1; + aChangedLast = Standard_True; // Move vertex to first good point + } + else + { + aLastGeomIdx = Min (i + 1, theWLine->NbPnts()); + if (aDelOuterPointsHash(i) == -1) + aLastGeomIdx = i; // Use data what lies in (i) point / vertex. + + aDelOuterPointsHash(i) = -1; + break; + } + } + + if (!aChangedFirst && !aChangedLast) + { + // Nothing is done, return input. + return theWLine; + } + + // Build new line and modify geometry of necessary vertexes. + Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash); + + if (aChangedFirst) + { + // Vertex geometry. + IntPatch_Point aVertex = aLocalWLine->Vertex(1); + aVertex.SetValue(theWLine->Point(aFirstGeomIdx).Value()); + Standard_Real aU1, aU2, aV1, aV2; + theWLine->Point(aFirstGeomIdx).Parameters(aU1, aV1, aU2, aV2); + MovePoint(theS1, aU1, aV1); + MovePoint(theS2, aU2, aV2); + aVertex.SetParameters(aU1, aV1, aU2, aV2); + aLocalWLine->Replace(1, aVertex); + // Change point in walking line. + aLocalWLine->SetPoint(1, aVertex); + } + + if (aChangedLast) + { + // Vertex geometry. + IntPatch_Point aVertex = aLocalWLine->Vertex(aLocalWLine->NbVertex()); + aVertex.SetValue(theWLine->Point(aLastGeomIdx).Value()); + Standard_Real aU1, aU2, aV1, aV2; + theWLine->Point(aLastGeomIdx).Parameters(aU1, aV1, aU2, aV2); + MovePoint(theS1, aU1, aV1); + MovePoint(theS2, aU2, aV2); + aVertex.SetParameters(aU1, aV1, aU2, aV2); + aLocalWLine->Replace(aLocalWLine->NbVertex(), aVertex); + // Change point in walking line. + aLocalWLine->SetPoint(aLocalWLine->NbPnts(), aVertex); + } + + + return aLocalWLine; +} + +//========================================================================= +// function : IsInsideIn2d +// purpose : Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec. +// In 2d space. Static subfunction in DeleteByTube. +//========================================================================= +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); +} + +//========================================================================= +// function : IsInsideIn3d +// purpose : Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec. +// In 3d space. Static subfunction in DeleteByTube. +//========================================================================= +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 const Standard_Integer aMinNbBadDistr = 15; +static const Standard_Integer aNbSingleBezier = 30; + +//========================================================================= +// function : DeleteByTube +// purpose : Check and delete points using tube criteria. +// Static subfunction in ComputePurgedWLine. +//========================================================================= +static Handle(IntPatch_WLine) + DeleteByTube(const Handle(IntPatch_WLine) &theWLine, + const Handle(Adaptor3d_HSurface) &theS1, + const Handle(Adaptor3d_HSurface) &theS2) +{ + // III: Check points for tube criteria: + // Workaround to handle case of small amount points after purge. + // Test "boolean boptuc_complex B5" and similar. + Standard_Integer aNbPnt = 0 , i; + + if (theWLine->NbPnts() <= 2) + return theWLine; + + NCollection_Array1 aNewPointsHash(1, theWLine->NbPnts()); + FillPointsHash(theWLine, aNewPointsHash); + + // Inital computations. + Standard_Real UonS1[3], VonS1[3], UonS2[3], VonS2[3]; + theWLine->Point(1).ParametersOnS1(UonS1[0], VonS1[0]); + theWLine->Point(2).ParametersOnS1(UonS1[1], VonS1[1]); + theWLine->Point(1).ParametersOnS2(UonS2[0], VonS2[0]); + theWLine->Point(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 = theWLine->Point(1).Value(); + gp_Vec aBase3dVec(theWLine->Point(1).Value(), theWLine->Point(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 <= theWLine->NbPnts(); i++) + { + Standard_Boolean isDeleteState = Standard_False; + + theWLine->Point(i).ParametersOnS1(UonS1[2], VonS1[2]); + theWLine->Point(i).ParametersOnS2(UonS2[2], VonS2[2]); + gp_Pnt2d aPnt2dOnS1(UonS1[2], VonS1[2]); + gp_Pnt2d aPnt2dOnS2(UonS2[2], VonS2[2]); + const gp_Pnt& aPnt3d = theWLine->Point(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 = theWLine->Point(i - 1).Value(); + aBase3dVec = gp_Vec(theWLine->Point(i - 1).Value(), theWLine->Point(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(theWLine->NbPnts() - 1) == -1 && + aNewPointsHash(theWLine->NbPnts() ) == -1 && + aNbPnt <= 3) + { + // Delete last. + aNewPointsHash(theWLine->NbPnts()) = 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 * theWLine->NbPnts() / 9); + + //Store this point. + aNewPointsHash(aHashIdx) = 0; + } + } + + return MakeNewWLine(theWLine, aNewPointsHash); +} + +//======================================================================= +//function : IsSeam +//purpose : Returns: +// 0 - if interval [theU1, theU2] does not intersect the "seam-edge" +// or if "seam-edge" do not exist; +// 1 - if interval (theU1, theU2) intersect the "seam-edge". +// 2 - if theU1 or/and theU2 lie ON the "seam-edge" +// +//ATTENTION!!! +// If (theU1 == theU2) then this function will return only both 0 or 2. +// +// Static subfunction in IsSeamOrBound. +//======================================================================= +static Standard_Integer IsSeam( const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Real thePeriod) +{ + if(IsEqual(thePeriod, 0.0)) + return 0; + + //If interval [theU1, theU2] intersect seam-edge then there exists an integer + //number N such as + // (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T), + //where T is the period. + //I.e. the inerval [theU1/T, theU2/T] must contain at least one + //integer number. In this case, Floor(theU1/T) and Floor(theU2/T) + //return different values or theU1/T is strictly integer number. + //Examples: + // 1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3. + // 2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2. + + const Standard_Real aVal1 = theU1/thePeriod, + aVal2 = theU2/thePeriod; + const Standard_Integer aPar1 = static_cast(Floor(aVal1)); + const Standard_Integer aPar2 = static_cast(Floor(aVal2)); + if(aPar1 != aPar2) + {//Interval (theU1, theU2] intersects seam-edge + if(IsEqual(aVal2, static_cast(aPar2))) + {//aVal2 is an integer number => theU2 lies ON the "seam-edge" + return 2; + } + + return 1; + } + + //Here, aPar1 == aPar2. + + if(IsEqual(aVal1, static_cast(aPar1))) + {//aVal1 is an integer number => theU1 lies ON the "seam-edge" + return 2; + } + + //If aVal2 is a true integer number then always (aPar1 != aPar2). + + return 0; +} + +//======================================================================= +//function : IsSeamOrBound +//purpose : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge" +// (if it exist) or surface boundaries and both thePtf and thePtl do +// not match "seam-edge" or boundaries. +// Point thePtmid lies in this segment. If thePtmid match +// "seam-edge" or boundaries strictly (without any tolerance) then +// the function will return TRUE. +// See comments in function body for detail information. +// +// Static subfunction in JoinWLines. +//======================================================================= +static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf, + const IntSurf_PntOn2S& thePtl, + const IntSurf_PntOn2S& thePtmid, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + const Standard_Real theUfSurf1, + const Standard_Real theUlSurf1, + const Standard_Real theVfSurf1, + const Standard_Real theVlSurf1, + const Standard_Real theUfSurf2, + const Standard_Real theUlSurf2, + const Standard_Real theVfSurf2, + const Standard_Real theVlSurf2) +{ + Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0; + Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0; + thePtf.Parameters(aU11, aV11, aU12, aV12); + thePtl.Parameters(aU21, aV21, aU22, aV22); + + MinMax(aU11, aU21); + MinMax(aV11, aV21); + MinMax(aU12, aU22); + MinMax(aV12, aV22); + + if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0) + {//Interval [aU11, aU21] intersects theUfSurf1 + return Standard_True; + } + + if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0) + {//Interval [aU11, aU21] intersects theUlSurf1 + return Standard_True; + } + + if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0) + {//Interval [aV11, aV21] intersects theVfSurf1 + return Standard_True; + } + + if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0) + {//Interval [aV11, aV21] intersects theVlSurf1 + return Standard_True; + } + + if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0) + {//Interval [aU12, aU22] intersects theUfSurf2 + return Standard_True; + } + + if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0) + {//Interval [aU12, aU22] intersects theUlSurf2 + return Standard_True; + } + + if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0) + {//Interval [aV12, aV22] intersects theVfSurf2 + return Standard_True; + } + + if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0) + {//Interval [aV12, aV22] intersects theVlSurf2 + return Standard_True; + } + + if(IsSeam(aU11, aU21, theU1Period)) + return Standard_True; + + if(IsSeam(aV11, aV21, theV1Period)) + return Standard_True; + + if(IsSeam(aU12, aU22, theU2Period)) + return Standard_True; + + if(IsSeam(aV12, aV22, theV2Period)) + return Standard_True; + + /* + The segment [thePtf, thePtl] does not intersect the boundaries and + the seam-edge of the surfaces. + Nevertheless, following situation is possible: + + seam or + bound + | + thePtf * | + | + * thePtmid + thePtl * | + | + + This case must be processed, too. + */ + + Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0; + thePtmid.Parameters(aU1, aV1, aU2, aV2); + + if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1)) + return Standard_True; + + if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2)) + return Standard_True; + + if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1)) + return Standard_True; + + if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2)) + return Standard_True; + + if(IsSeam(aU1, aU1, theU1Period)) + return Standard_True; + + if(IsSeam(aU2, aU2, theU2Period)) + return Standard_True; + + if(IsSeam(aV1, aV1, theV1Period)) + return Standard_True; + + if(IsSeam(aV2, aV2, theV2Period)) + return Standard_True; + + return Standard_False; +} + +//========================================================================= +// function : ComputePurgedWLine +// purpose : +//========================================================================= +Handle(IntPatch_WLine) IntPatch_WLineTool:: + ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine, + const Handle(Adaptor3d_HSurface) &theS1, + const Handle(Adaptor3d_HSurface) &theS2, + const Handle(Adaptor3d_TopolTool) &theDom1, + const Handle(Adaptor3d_TopolTool) &theDom2) +{ + Standard_Integer i, k, v, nb, nbvtx; + Handle(IntPatch_WLine) aResult; + nbvtx = theWLine->NbVertex(); + nb = theWLine->NbPnts(); + if (nb==2) + { + const IntSurf_PntOn2S& p1 = theWLine->Point(1); + const IntSurf_PntOn2S& p2 = theWLine->Point(2); + if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) + return aResult; + } + + Handle(IntPatch_WLine) aLocalWLine; + Handle(IntPatch_WLine) aTmpWLine = theWLine; + Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); + aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False); + for(i = 1; i <= nb; i++) + aLineOn2S->Add(theWLine->Point(i)); + + for(v = 1; v <= nbvtx; v++) + aLocalWLine->AddVertex(theWLine->Vertex(v)); + + // I: Delete equal points + for(i = 1; i <= aLineOn2S->NbPoints(); i++) + { + Standard_Integer aStartIndex = i + 1; + Standard_Integer anEndIndex = i + 5; + nb = aLineOn2S->NbPoints(); + anEndIndex = (anEndIndex > nb) ? nb : anEndIndex; + + if((aStartIndex > nb) || (anEndIndex <= 1)) + continue; + + k = aStartIndex; + + while(k <= anEndIndex) + { + if(i != k) + { + IntSurf_PntOn2S p1 = aLineOn2S->Value(i); + IntSurf_PntOn2S p2 = aLineOn2S->Value(k); + + 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(avertexindex >= k) + { + aVertex.SetParameter(aVertex.ParameterOnLine() - 1.); + } + aLocalWLine->AddVertex(aVertex); + } + aLineOn2S->RemovePoint(k); + anEndIndex--; + continue; + } + } + k++; + } + } + + if (aLineOn2S->NbPoints() <= 2) + { + if (aLineOn2S->NbPoints() == 2) + return aLocalWLine; + else + return aResult; + } + + // 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; + } + + // II: Delete out of borders points. + Handle(IntPatch_WLine) aLocalWLineOuter = + DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2); + + // III: Delete points by tube criteria. + Handle(IntPatch_WLine) aLocalWLineTube = + DeleteByTube(aLocalWLineOuter, theS1, theS2); + + if(aLocalWLineTube->NbPnts() > 1) + { + aResult = aLocalWLineTube; + } + return aResult; +} + + +//======================================================================= +//function : JoinWLines +//purpose : +//======================================================================= +void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin, + IntPatch_SequenceOfPoint& theSPnt, + const Standard_Real theTol3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + const Standard_Real theUfSurf1, + const Standard_Real theUlSurf1, + const Standard_Real theVfSurf1, + const Standard_Real theVlSurf1, + const Standard_Real theUfSurf2, + const Standard_Real theUlSurf2, + const Standard_Real theVfSurf2, + const Standard_Real theVlSurf2) +{ + if(theSlin.Length() == 0) + return; + + for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++) + { + Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1))); + + if(aWLine1.IsNull()) + {//We must have failed to join not-point-lines + continue; + } + + const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts(); + const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1); + const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1); + + for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++) + { + const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S(); + + if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) || + aPntCur.IsSame(aPntLW1, Precision::Confusion())) + { + theSPnt.Remove(aNPt); + aNPt--; + } + } + + Standard_Boolean hasBeenRemoved = Standard_False; + for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++) + { + Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2))); + + if(aWLine2.IsNull()) + continue; + + const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts(); + + const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1); + const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1); + + const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1); + const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2); + + if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion())) + { + const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); + const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2); + if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period, + theV1Period, theV2Period, theUfSurf1, theUlSurf1, + theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, + theVfSurf2, theVlSurf2)) + { + aWLine1->ClearVertexes(); + for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->InsertBefore(1, aPt); + } + + aWLine1->ComputeVertexParameters(theTol3D); + + theSlin.Remove(aNumOfLine2); + aNumOfLine2--; + hasBeenRemoved = Standard_True; + + continue; + } + } + + if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion())) + { + const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); + const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1); + if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period, + theV1Period, theV2Period, theUfSurf1, theUlSurf1, + theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, + theVfSurf2, theVlSurf2)) + { + aWLine1->ClearVertexes(); + for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->InsertBefore(1, aPt); + } + + aWLine1->ComputeVertexParameters(theTol3D); + + theSlin.Remove(aNumOfLine2); + aNumOfLine2--; + hasBeenRemoved = Standard_True; + + continue; + } + } + + if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion())) + { + const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1); + const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2); + if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period, + theV1Period, theV2Period, theUfSurf1, theUlSurf1, + theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, + theVfSurf2, theVlSurf2)) + { + aWLine1->ClearVertexes(); + for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->Add(aPt); + } + + aWLine1->ComputeVertexParameters(theTol3D); + + theSlin.Remove(aNumOfLine2); + aNumOfLine2--; + hasBeenRemoved = Standard_True; + + continue; + } + } + + if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion())) + { + const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1); + const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1); + if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period, + theV1Period, theV2Period, theUfSurf1, theUlSurf1, + theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2, + theVfSurf2, theVlSurf2)) + { + aWLine1->ClearVertexes(); + for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->Add(aPt); + } + + aWLine1->ComputeVertexParameters(theTol3D); + + theSlin.Remove(aNumOfLine2); + aNumOfLine2--; + hasBeenRemoved = Standard_True; + + continue; + } + } + } + + if(hasBeenRemoved) + aNumOfLine1--; + } +} \ No newline at end of file diff --git a/src/IntPatch/IntPatch_WLineTool.hxx b/src/IntPatch/IntPatch_WLineTool.hxx new file mode 100644 index 0000000000..210aa89366 --- /dev/null +++ b/src/IntPatch/IntPatch_WLineTool.hxx @@ -0,0 +1,81 @@ +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public 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. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IntPatch_WLineTool_HeaderFile +#define _IntPatch_WLineTool_HeaderFile + +#include +#include +#include +#include +class TopoDS_Face; +class GeomAdaptor_HSurface; +class GeomInt_LineConstructor; +class IntTools_Context; +class Adaptor3d_TopolTool; +class Adaptor3d_HSurface; + +//! IntPatch_WLineTool provides set of static methods related to walking lines. +class IntPatch_WLineTool +{ +public: + + DEFINE_STANDARD_ALLOC + + //! I + //! Removes equal points (leave one of equal points) from theWLine + //! and recompute vertex parameters. + //! + //! II + //! Removes point out of borders in case of non periodic surfaces. + //! + //! III + //! 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. + Standard_EXPORT static + Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine, + const Handle(Adaptor3d_HSurface) &theS1, + const Handle(Adaptor3d_HSurface) &theS2, + const Handle(Adaptor3d_TopolTool) &theDom1, + const Handle(Adaptor3d_TopolTool) &theDom2); + +//! Joins all WLines from theSlin to one if it is possible and records +//! the result into theSlin again. Lines will be kept to be splitted if: +//! a) they are separated (has no common points); +//! b) resulted line (after joining) go through seam-edges or surface boundaries. +//! +//! In addition, if points in theSPnt lies at least in one of the line in theSlin, +//! this point will be deleted. + Standard_EXPORT static void JoinWLines(IntPatch_SequenceOfLine& theSlin, + IntPatch_SequenceOfPoint& theSPnt, + const Standard_Real theTol3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + const Standard_Real theUfSurf1, + const Standard_Real theUlSurf1, + const Standard_Real theVfSurf1, + const Standard_Real theVlSurf1, + const Standard_Real theUfSurf2, + const Standard_Real theUlSurf2, + const Standard_Real theVfSurf2, + const Standard_Real theVlSurf2); + +}; + +#endif \ No newline at end of file diff --git a/src/IntTools/IntTools_Context.cxx b/src/IntTools/IntTools_Context.cxx index 4eaadcb346..7c09b67135 100644 --- a/src/IntTools/IntTools_Context.cxx +++ b/src/IntTools/IntTools_Context.cxx @@ -852,6 +852,33 @@ Standard_Boolean IntTools_Context::IsVertexOnLine (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion())) aT = aFirst; } + else + { + // Local search may fail. Try to use more precise algo. + Extrema_ExtPC anExt(aPv, aGAC, 1.e-10); + Standard_Real aMinDist = RealLast(); + Standard_Integer aMinIdx = -1; + for (Standard_Integer anIdx = 1; anIdx <= anExt.NbExt(); anIdx++) + { + if ( anExt.IsMin(anIdx) && + anExt.SquareDistance(anIdx) < aMinDist ) + { + aMinDist = anExt.SquareDistance(anIdx); + aMinIdx = anIdx; + } + } + if (aMinIdx != -1) + { + const Extrema_POnCurv& aPOncurve = anExt.Point(aMinIdx); + aT = aPOncurve.Parameter(); + + if((aT > (aLast + aFirst) * 0.5) || + (aPv.Distance(aPOncurve.Value()) > aTolSum) || + (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion())) + aT = aFirst; + } + } + } // return Standard_True; @@ -877,6 +904,32 @@ Standard_Boolean IntTools_Context::IsVertexOnLine (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion())) aT = aLast; } + else + { + // Local search may fail. Try to use more precise algo. + Extrema_ExtPC anExt(aPv, aGAC, 1.e-10); + Standard_Real aMinDist = RealLast(); + Standard_Integer aMinIdx = -1; + for (Standard_Integer anIdx = 1; anIdx <= anExt.NbExt(); anIdx++) + { + if ( anExt.IsMin(anIdx) && + anExt.SquareDistance(anIdx) < aMinDist ) + { + aMinDist = anExt.SquareDistance(anIdx); + aMinIdx = anIdx; + } + } + if (aMinIdx != -1) + { + const Extrema_POnCurv& aPOncurve = anExt.Point(aMinIdx); + aT = aPOncurve.Parameter(); + + if((aT < (aLast + aFirst) * 0.5) || + (aPv.Distance(aPOncurve.Value()) > aTolSum) || + (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion())) + aT = aLast; + } + } } // return Standard_True; diff --git a/src/IntTools/IntTools_FaceFace.cxx b/src/IntTools/IntTools_FaceFace.cxx index 349393db33..2ad7420f69 100644 --- a/src/IntTools/IntTools_FaceFace.cxx +++ b/src/IntTools/IntTools_FaceFace.cxx @@ -108,20 +108,17 @@ #include #include #include +#include -#ifdef OCCT_DEBUG_DUMPWLINE -static - void DumpWLine(const Handle(IntPatch_WLine)& aWLine); -#endif -// +//#ifdef OCCT_DEBUG_DUMPWLINE +//static +// void DumpWLine(const Handle(IntPatch_WLine)& aWLine); +//#endif +//// static void TolR3d(const TopoDS_Face& , const TopoDS_Face& , Standard_Real& ); -static - Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)&, - const Standard_Integer, - const Standard_Integer); static void Parameters(const Handle(GeomAdaptor_HSurface)&, @@ -871,17 +868,11 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, typl = L->ArcType(); // if(typl==IntPatch_Walking) { - Handle(IntPatch_Line) anewL; - // Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L)); - anewL = IntTools_WLineTool::ComputePurgedWLine(aWLine, myHS1, myHS2, dom1, dom2); - if(anewL.IsNull()) { + if(aWLine.IsNull()) { return; } - L = anewL; - - //Handle(IntPatch_WLine) aWLineX (Handle(IntPatch_WLine)::DownCast(L)); - //DumpWLine(aWLineX); + L = aWLine; // if(!myListOfPnts.IsEmpty()) { @@ -1378,14 +1369,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, Handle(Geom2d_BSplineCurve) H2; if(myApprox1) { - H1 = IntTools_WLineTool::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True); + H1 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True); } if(myApprox2) { - H2 = IntTools_WLineTool::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False); + H2 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False); } // - mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2)); + mySeqOfCurve.Append(IntTools_Curve(GeomInt_IntSS::MakeBSpline(WL,1,WL->NbPnts()), H1, H2)); } } // if (!myApprox) @@ -1394,7 +1385,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, // Standard_Real tol2d = myTolApprox; // - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True); aNbParts=myLConstruct.NbParts(); for (i=1; i<=aNbParts; i++) { @@ -1410,14 +1401,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, Handle(Geom2d_BSplineCurve) H2; if(myApprox1) { - H1 = IntTools_WLineTool::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True); + H1 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True); } if(myApprox2) { - H2 = IntTools_WLineTool::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False); + H2 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False); } // - mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2)); + mySeqOfCurve.Append(IntTools_Curve(GeomInt_IntSS::MakeBSpline(WL,1,WL->NbPnts()), H1, H2)); } else { @@ -1528,14 +1519,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, } // if(myApprox1) { - H1 = IntTools_WLineTool::MakeBSpline2d(WL, ifprm, ilprm, Standard_True); + H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True); } // if(myApprox2) { - H2 = IntTools_WLineTool::MakeBSpline2d(WL, ifprm, ilprm, Standard_False); + H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False); } // - aBSp=MakeBSpline(WL, ifprm, ilprm); + aBSp=GeomInt_IntSS::MakeBSpline(WL, ifprm, ilprm); IntTools_Curve aIC(aBSp, H1, H2); mySeqOfCurve.Append(aIC); }// for (i=1; i<=aNbParts; ++i) { @@ -1578,17 +1569,18 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, } if(myHS1 == myHS2) { - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType); rejectSurface = Standard_True; } else { if(reApprox && !rejectSurface) - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType); else { Standard_Integer iDegMax, iDegMin, iNbIter; // ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter); - theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType); + theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, + iNbIter, 30, Standard_True, aParType); } } // @@ -1654,7 +1646,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) && (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) { - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True, aParType); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, + Standard_True, aParType); Standard_Boolean bUseSurfaces; bUseSurfaces = IntTools_WLineTool::NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm); @@ -1662,7 +1655,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, // ###### rejectSurface = Standard_True; // ###### - theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType); + theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, + Standard_False, aParType); } } } @@ -1674,14 +1668,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, Handle(Geom2d_BSplineCurve) H1; Handle(Geom2d_BSplineCurve) H2; // - Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm); + Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm); // if(myApprox1) { - H1 = IntTools_WLineTool::MakeBSpline2d(WL, ifprm, ilprm, Standard_True); + H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True); } // if(myApprox2) { - H2 = IntTools_WLineTool::MakeBSpline2d(WL, ifprm, ilprm, Standard_False); + H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False); } // IntTools_Curve aIC(aBSp, H1, H2); @@ -1884,15 +1878,15 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, Handle(Geom2d_BSplineCurve) H1, H2; bPCurvesOk = Standard_True; // - Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm); + Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm); if(myApprox1) { - H1 = IntTools_WLineTool::MakeBSpline2d(WL, ifprm, ilprm, Standard_True); + H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True); bPCurvesOk = CheckPCurve(H1, myFace1); } if(myApprox2) { - H2 = IntTools_WLineTool::MakeBSpline2d(WL, ifprm, ilprm, Standard_False); + H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False); bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2); } // diff --git a/src/IntTools/IntTools_WLineTool.cxx b/src/IntTools/IntTools_WLineTool.cxx index 43b122fb2f..fc6b2f2779 100644 --- a/src/IntTools/IntTools_WLineTool.cxx +++ b/src/IntTools/IntTools_WLineTool.cxx @@ -13,26 +13,25 @@ #include -#include #include #include -#include -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include #include +#include +#include /////////////////////// NotUseSurfacesForApprox ///////////////////////// @@ -228,38 +227,6 @@ Standard_Boolean IntTools_WLineTool::NotUseSurfacesForApprox(const TopoDS_Face& /////////////////////// end of NotUseSurfacesForApprox ////////////////// - -//======================================================================= -//function : MakeBSpline2d -//purpose : -//======================================================================= -Handle(Geom2d_BSplineCurve) IntTools_WLineTool:: - MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine, - const Standard_Integer ideb, - const Standard_Integer ifin, - const Standard_Boolean onFirst) -{ - Standard_Integer i, nbpnt = ifin-ideb+1; - TColgp_Array1OfPnt2d poles(1,nbpnt); - TColStd_Array1OfReal knots(1,nbpnt); - TColStd_Array1OfInteger mults(1,nbpnt); - Standard_Integer ipidebm1; - - for(i = 1, ipidebm1 = i+ideb-1; i <= nbpnt; ipidebm1++, i++) { - Standard_Real U, V; - if(onFirst) - theWLine->Point(ipidebm1).ParametersOnS1(U, V); - else - theWLine->Point(ipidebm1).ParametersOnS2(U, V); - poles(i).SetCoord(U, V); - mults(i) = 1; - knots(i) = i-1; - } - mults(1) = mults(nbpnt) = 2; - - return new Geom2d_BSplineCurve(poles,knots,mults,1); -} - /////////////////////// DecompositionOfWLine //////////////////////////// //======================================================================= @@ -767,7 +734,6 @@ Standard_Boolean IntTools_WLineTool:: Standard_Real& theReachedTol3d, const Handle(IntTools_Context)& aContext) { - Standard_Boolean bRet, bAvoidLineConstructor; Standard_Integer aNbPnts, aNbParts; // @@ -1492,558 +1458,4 @@ Standard_Boolean IntTools_WLineTool:: return Standard_True; } -///////////////////// end of DecompositionOfWLine /////////////////////// - -/////////////////////// ComputePurgedWLine ////////////////////////////// - -//========================================================================= -// function : FillPointsHash -// purpose : Fill points hash by input data. -// Static subfunction in ComputePurgedWLine. -//========================================================================= -static void FillPointsHash(const Handle(IntPatch_WLine) &theWLine, - NCollection_Array1 &thePointsHash) -{ - // 1 - Delete point. - // 0 - Store point. - // -1 - Vertex point (not delete). - Standard_Integer i, v; - - for(i = 1; i <= theWLine->NbPnts(); i++) - thePointsHash.SetValue(i, 0); - - for(v = 1; v <= theWLine->NbVertex(); v++) - { - IntPatch_Point aVertex = theWLine->Vertex(v); - Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine(); - thePointsHash.SetValue(avertexindex, -1); - } -} - -//========================================================================= -// function : MakeNewWLine -// purpose : Makes new walking line according to the points hash -// Static subfunction in ComputePurgedWLine and DeleteOuter. -//========================================================================= -static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine) &theWLine, - const NCollection_Array1 &thePointsHash) -{ - Standard_Integer i; - - Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S(); - Handle(IntPatch_WLine) aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False); - Standard_Integer anOldLineIdx = 1, aVertexIdx = 1; - for(i = 1; i <= thePointsHash.Upper(); i++) - { - if (thePointsHash(i) == 0) - { - // Store this point. - aPurgedLineOn2S->Add(theWLine->Point(i)); - anOldLineIdx++; - } - else if (thePointsHash(i) == -1) - { - // Add vertex. - IntPatch_Point aVertex = theWLine->Vertex(aVertexIdx++); - aVertex.SetParameter(anOldLineIdx++); - aLocalWLine->AddVertex(aVertex); - aPurgedLineOn2S->Add(theWLine->Point(i)); - } - } - - return aLocalWLine; -} - -//========================================================================= -// function : MovePoint -// purpose : Move point into surface param space. No interpolation used -// because walking algorithm should care for closeness to the param space. -// Static subfunction in ComputePurgedWLine. -//========================================================================= -static void MovePoint(const Handle(GeomAdaptor_HSurface) &theS1, - Standard_Real &U1, Standard_Real &V1) -{ - if (U1 < theS1->FirstUParameter()) - U1 = theS1->FirstUParameter(); - - if (U1 > theS1->LastUParameter()) - U1 = theS1->LastUParameter(); - - if (V1 < theS1->FirstVParameter()) - V1 = theS1->FirstVParameter(); - - if (V1 > theS1->LastVParameter()) - V1 = theS1->LastVParameter(); -} - -//========================================================================= -// function : DeleteOuterPoints -// purpose : Check and delete out of bounds points on walking line. -// Static subfunction in ComputePurgedWLine. -//========================================================================= -static Handle(IntPatch_WLine) - DeleteOuterPoints(const Handle(IntPatch_WLine) &theWLine, - const Handle(GeomAdaptor_HSurface) &theS1, - const Handle(GeomAdaptor_HSurface) &theS2, - const Handle(Adaptor3d_TopolTool) &theDom1, - const Handle(Adaptor3d_TopolTool) &theDom2) -{ - Standard_Integer i; - - NCollection_Array1 aDelOuterPointsHash(1, theWLine->NbPnts()); - FillPointsHash(theWLine, aDelOuterPointsHash); - - if (theS1->IsUPeriodic() || theS1->IsVPeriodic() || - theS2->IsUPeriodic() || theS2->IsVPeriodic() ) - return theWLine; - - gp_Pnt2d aPntOnF1, aPntOnF2; - Standard_Real aX1, aY1, aX2, aY2; - - // Iterate over points in walking line and delete which are out of bounds. - // Forward. - Standard_Boolean isAllDeleted = Standard_True; - Standard_Boolean aChangedFirst = Standard_False; - Standard_Integer aFirstGeomIdx = 1; - for(i = 1; i <= theWLine->NbPnts(); i++) - { - theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2); - aPntOnF1.SetCoord(aX1, aY1); - aPntOnF2.SetCoord(aX2, aY2); - - TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion()); - TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion()); - - if (aState1 == TopAbs_OUT || - aState2 == TopAbs_OUT ) - { - aDelOuterPointsHash(i) = 1; - aChangedFirst = Standard_True; - } - else - { - isAllDeleted = Standard_False; - - aFirstGeomIdx = Max (i - 1, 1); - if (aDelOuterPointsHash(i) == -1) - aFirstGeomIdx = i; // Use data what lies in (i) point / vertex. - - aDelOuterPointsHash(i) = -1; - break; - } - } - - if (isAllDeleted) - { - // ALL points are out of bounds: - // case boolean bcut_complex F5 and similar. - return theWLine; - } - - // Backward. - Standard_Boolean aChangedLast = Standard_False; - Standard_Integer aLastGeomIdx = theWLine->NbPnts(); - for(i = theWLine->NbPnts(); i >= 1; i--) - { - theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2); - aPntOnF1.SetCoord(aX1, aY1); - aPntOnF2.SetCoord(aX2, aY2); - - TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion()); - TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion()); - - if (aState1 == TopAbs_OUT || - aState2 == TopAbs_OUT ) - { - aDelOuterPointsHash(i) = 1; - aChangedLast = Standard_True; // Move vertex to first good point - } - else - { - aLastGeomIdx = Min (i + 1, theWLine->NbPnts()); - if (aDelOuterPointsHash(i) == -1) - aLastGeomIdx = i; // Use data what lies in (i) point / vertex. - - aDelOuterPointsHash(i) = -1; - break; - } - } - - if (!aChangedFirst && !aChangedLast) - { - // Nothing is done, return input. - return theWLine; - } - - // Build new line and modify geometry of necessary vertexes. - Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash); - - if (aChangedFirst) - { - // Vertex geometry. - IntPatch_Point aVertex = aLocalWLine->Vertex(1); - aVertex.SetValue(theWLine->Point(aFirstGeomIdx).Value()); - Standard_Real aU1, aU2, aV1, aV2; - theWLine->Point(aFirstGeomIdx).Parameters(aU1, aV1, aU2, aV2); - MovePoint(theS1, aU1, aV1); - MovePoint(theS2, aU2, aV2); - aVertex.SetParameters(aU1, aV1, aU2, aV2); - aLocalWLine->Replace(1, aVertex); - // Change point in walking line. - aLocalWLine->SetPoint(1, aVertex); - } - - if (aChangedLast) - { - // Vertex geometry. - IntPatch_Point aVertex = aLocalWLine->Vertex(aLocalWLine->NbVertex()); - aVertex.SetValue(theWLine->Point(aLastGeomIdx).Value()); - Standard_Real aU1, aU2, aV1, aV2; - theWLine->Point(aLastGeomIdx).Parameters(aU1, aV1, aU2, aV2); - MovePoint(theS1, aU1, aV1); - MovePoint(theS2, aU2, aV2); - aVertex.SetParameters(aU1, aV1, aU2, aV2); - aLocalWLine->Replace(aLocalWLine->NbVertex(), aVertex); - // Change point in walking line. - aLocalWLine->SetPoint(aLocalWLine->NbPnts(), aVertex); - } - - - return aLocalWLine; -} - -//========================================================================= -// function : IsInsideIn2d -// purpose : Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec. -// In 2d space. Static subfunction in DeleteByTube. -//========================================================================= -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); -} - -//========================================================================= -// function : IsInsideIn3d -// purpose : Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec. -// In 3d space. Static subfunction in DeleteByTube. -//========================================================================= -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 const Standard_Integer aMinNbBadDistr = 15; -static const Standard_Integer aNbSingleBezier = 30; - -//========================================================================= -// function : DeleteByTube -// purpose : Check and delete points using tube criteria. -// Static subfunction in ComputePurgedWLine. -//========================================================================= -static Handle(IntPatch_WLine) - DeleteByTube(const Handle(IntPatch_WLine) &theWLine, - const Handle(GeomAdaptor_HSurface) &theS1, - const Handle(GeomAdaptor_HSurface) &theS2) -{ - // III: Check points for tube criteria: - // Workaround to handle case of small amount points after purge. - // Test "boolean boptuc_complex B5" and similar. - Standard_Integer aNbPnt = 0 , i; - - if (theWLine->NbPnts() <= 2) - return theWLine; - - NCollection_Array1 aNewPointsHash(1, theWLine->NbPnts()); - FillPointsHash(theWLine, aNewPointsHash); - - // Inital computations. - Standard_Real UonS1[3], VonS1[3], UonS2[3], VonS2[3]; - theWLine->Point(1).ParametersOnS1(UonS1[0], VonS1[0]); - theWLine->Point(2).ParametersOnS1(UonS1[1], VonS1[1]); - theWLine->Point(1).ParametersOnS2(UonS2[0], VonS2[0]); - theWLine->Point(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 = theWLine->Point(1).Value(); - gp_Vec aBase3dVec(theWLine->Point(1).Value(), theWLine->Point(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 <= theWLine->NbPnts(); i++) - { - Standard_Boolean isDeleteState = Standard_False; - - theWLine->Point(i).ParametersOnS1(UonS1[2], VonS1[2]); - theWLine->Point(i).ParametersOnS2(UonS2[2], VonS2[2]); - gp_Pnt2d aPnt2dOnS1(UonS1[2], VonS1[2]); - gp_Pnt2d aPnt2dOnS2(UonS2[2], VonS2[2]); - const gp_Pnt& aPnt3d = theWLine->Point(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 = theWLine->Point(i - 1).Value(); - aBase3dVec = gp_Vec(theWLine->Point(i - 1).Value(), theWLine->Point(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(theWLine->NbPnts() - 1) == -1 && - aNewPointsHash(theWLine->NbPnts() ) == -1 && - aNbPnt <= 3) - { - // Delete last. - aNewPointsHash(theWLine->NbPnts()) = 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 * theWLine->NbPnts() / 9); - - //Store this point. - aNewPointsHash(aHashIdx) = 0; - } - } - - return MakeNewWLine(theWLine, aNewPointsHash); -} - -//========================================================================= -// function : ComputePurgedWLine -// purpose : -//========================================================================= -Handle(IntPatch_WLine) IntTools_WLineTool:: - ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine, - const Handle(GeomAdaptor_HSurface) &theS1, - const Handle(GeomAdaptor_HSurface) &theS2, - const Handle(Adaptor3d_TopolTool) &theDom1, - const Handle(Adaptor3d_TopolTool) &theDom2) -{ - Standard_Integer i, k, v, nb, nbvtx; - Handle(IntPatch_WLine) aResult; - nbvtx = theWLine->NbVertex(); - nb = theWLine->NbPnts(); - if (nb==2) - { - const IntSurf_PntOn2S& p1 = theWLine->Point(1); - const IntSurf_PntOn2S& p2 = theWLine->Point(2); - if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) - return aResult; - } - - Handle(IntPatch_WLine) aLocalWLine; - Handle(IntPatch_WLine) aTmpWLine = theWLine; - Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); - aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False); - for(i = 1; i <= nb; i++) - aLineOn2S->Add(theWLine->Point(i)); - - for(v = 1; v <= nbvtx; v++) - aLocalWLine->AddVertex(theWLine->Vertex(v)); - - // I: Delete equal points - for(i = 1; i <= aLineOn2S->NbPoints(); i++) - { - Standard_Integer aStartIndex = i + 1; - Standard_Integer anEndIndex = i + 5; - nb = aLineOn2S->NbPoints(); - anEndIndex = (anEndIndex > nb) ? nb : anEndIndex; - - if((aStartIndex > nb) || (anEndIndex <= 1)) - continue; - - k = aStartIndex; - - while(k <= anEndIndex) - { - if(i != k) - { - IntSurf_PntOn2S p1 = aLineOn2S->Value(i); - IntSurf_PntOn2S p2 = aLineOn2S->Value(k); - - 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(avertexindex >= k) - { - aVertex.SetParameter(aVertex.ParameterOnLine() - 1.); - } - aLocalWLine->AddVertex(aVertex); - } - aLineOn2S->RemovePoint(k); - anEndIndex--; - continue; - } - } - k++; - } - } - - if (aLineOn2S->NbPoints() <= 2) - { - if (aLineOn2S->NbPoints() == 2) - return aLocalWLine; - else - return aResult; - } - - // 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; - } - - // II: Delete out of borders points. - Handle(IntPatch_WLine) aLocalWLineOuter = - DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2); - - /// III: Delete points by tube criteria. - Handle(IntPatch_WLine) aLocalWLineTube = - DeleteByTube(aLocalWLineOuter, theS1, theS2); - - if(aLocalWLineTube->NbPnts() > 1) - { - aResult = aLocalWLineTube; - } - return aResult; -} - -/////////////////////// end of ComputePurgedWLine /////////////////////// \ No newline at end of file +///////////////////// end of DecompositionOfWLine /////////////////////// \ No newline at end of file diff --git a/src/IntTools/IntTools_WLineTool.hxx b/src/IntTools/IntTools_WLineTool.hxx index 59a3f886fc..bfb9e69934 100644 --- a/src/IntTools/IntTools_WLineTool.hxx +++ b/src/IntTools/IntTools_WLineTool.hxx @@ -38,33 +38,6 @@ public: const Standard_Integer ifprm, const Standard_Integer ilprm); - //! I - //! Removes equal points (leave one of equal points) from theWLine - //! and recompute vertex parameters. - //! - //! II - //! Removes point out of borders in case of non periodic surfaces. - //! - //! III - //! 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. - Standard_EXPORT static - Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine, - const Handle(GeomAdaptor_HSurface) &theS1, - const Handle(GeomAdaptor_HSurface) &theS2, - const Handle(Adaptor3d_TopolTool) &theDom1, - const Handle(Adaptor3d_TopolTool) &theDom2); - - Standard_EXPORT static - Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine) &theWLine, - const Standard_Integer ideb, - const Standard_Integer ifin, - const Standard_Boolean onFirst); - Standard_EXPORT static Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine, const Handle(GeomAdaptor_HSurface)& theSurface1, diff --git a/src/ProjLib/ProjLib_ComputeApprox.cxx b/src/ProjLib/ProjLib_ComputeApprox.cxx index 5ac8d74ffe..d4c5bebee8 100644 --- a/src/ProjLib/ProjLib_ComputeApprox.cxx +++ b/src/ProjLib/ProjLib_ComputeApprox.cxx @@ -258,23 +258,47 @@ static void Function_SetUVBounds(Standard_Real& myU1, nbp = Max(nbp, 3); Step = (W2 - W1) / (nbp - 1); Standard_Boolean isclandper = (!(myCurve->IsClosed()) && !(myCurve->IsPeriodic())); - for(Standard_Real par = W1 + Step; par <= W2; par += Step) { + Standard_Boolean isFirst = Standard_True; + for(Standard_Real par = W1 + Step; par <= W2; par += Step) + { if(!isclandper) par += Step; P = myCurve->Value(par); ElSLib::Parameters( Cone, P, U, V); U += Delta; d = U - U1; - if(d > M_PI) { + if(d > M_PI) + { if( ( (IsEqual(U,(2*M_PI),1.e-10) && (U1 >= 0. && U1 <= M_PI)) && - (IsEqual(U,Ul,1.e-10) && !IsEqual(Uf,0.,1.e-10)) ) && isclandper ) U = 0.; - else Delta -= 2*M_PI; + (IsEqual(U,Ul,1.e-10) && !IsEqual(Uf,0.,1.e-10)) ) && isclandper ) + U = 0.0; + else + { + // Protection against first-last point on seam. + if (isFirst) + U1 = 2*M_PI; + else if (par + Step >= W2) + U = 0.0; + else + Delta -= 2*M_PI; + } U += Delta; d = U - U1; } - else if(d < -M_PI) { + else if(d < -M_PI) + { if( ( (IsEqual(U,0.,1.e-10) && (U1 >= M_PI && U1 <= (2*M_PI))) && - (IsEqual(U,Ul,1.e-10) && !IsEqual(Uf,(2*M_PI),1.e-10)) ) && isclandper ) U = 2*M_PI; - else Delta += 2*M_PI; + (IsEqual(U,Ul,1.e-10) && !IsEqual(Uf,(2*M_PI),1.e-10)) ) && isclandper ) + U = 2*M_PI; + else + { + // Protection against first-last point on seam. + if (isFirst) + U1 = 0.0; + else if (par + Step >= W2) + U = 2*M_PI; + else + Delta += 2*M_PI; + } U += Delta; d = U - U1; } @@ -282,7 +306,8 @@ static void Function_SetUVBounds(Standard_Real& myU1, if(U < myU1) {myU1 = U; pmin = par;} if(U > myU2) {myU2 = U; pmax = par;} U1 = U; - } + isFirst = Standard_False; + } // for(Standard_Real par = W1 + Step; par <= W2; par += Step) if(!(Abs(pmin - W1) <= Precision::PConfusion() || Abs(pmin - W2) <= Precision::PConfusion()) ) myU1 -= dmax*.5; if(!(Abs(pmax - W1) <= Precision::PConfusion() || Abs(pmax - W2) <= Precision::PConfusion()) ) myU2 += dmax*.5; diff --git a/src/QABugs/FILES b/src/QABugs/FILES index e771130812..319ab4a231 100644 --- a/src/QABugs/FILES +++ b/src/QABugs/FILES @@ -19,6 +19,7 @@ QABugs_16.cxx QABugs_17.cxx QABugs_18.cxx QABugs_19.cxx +QABugs_20.cxx QABugs_MyText.cxx QABugs_MyText.hxx QABugs_PresentableObject.cxx diff --git a/src/QABugs/QABugs.cxx b/src/QABugs/QABugs.cxx index 06807c966c..9449d71000 100644 --- a/src/QABugs/QABugs.cxx +++ b/src/QABugs/QABugs.cxx @@ -35,6 +35,7 @@ void QABugs::Commands(Draw_Interpretor& theCommands) { QABugs::Commands_17(theCommands); QABugs::Commands_18(theCommands); QABugs::Commands_19(theCommands); + QABugs::Commands_20(theCommands); return; } diff --git a/src/QABugs/QABugs.hxx b/src/QABugs/QABugs.hxx index fa3a47a3f5..bfd1a989cb 100644 --- a/src/QABugs/QABugs.hxx +++ b/src/QABugs/QABugs.hxx @@ -73,6 +73,7 @@ public: Standard_EXPORT static void Commands_19 (Draw_Interpretor& DI); + Standard_EXPORT static void Commands_20 (Draw_Interpretor& DI); diff --git a/src/QABugs/QABugs_20.cxx b/src/QABugs/QABugs_20.cxx new file mode 100644 index 0000000000..bcb373a47d --- /dev/null +++ b/src/QABugs/QABugs_20.cxx @@ -0,0 +1,1251 @@ +// Created on: 2015-10-26 +// Created by: Nikolai BUKHALOV +// Copyright (c) 2002-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public 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. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : SurfaceGenOCC26675_1 +//purpose : Generates a surface for intersect (in corresponding +// test case). If we save these surfaces to the disk +// then bug will not be reproduced. Therefore, this generator +// is very important (despite its taking many lines of the code). +//======================================================================= +static Standard_Integer SurfaceGenOCC26675_1( Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + + if(theNArg < 2) + { + theDI << "Use OCC26675_1 result\n"; + return 1; + } + + const gp_Pnt aCircCenter(-112.93397037070100000000, +177.52792379072199000000, +10.63374076104853900000); + const gp_Dir aCircN(+0.00000000000000000000, +1.00000000000000000000, +0.00000000000000000000); + const gp_Dir aCircX(+0.00000000000000000000, -0.00000000000000000000, +1.00000000000000000000); + const gp_Dir anExtrDir(-500.00000000000000000000, -866.02540378443609000000, +0.00000000000000000000); + const gp_Ax2 aCircAxes(aCircCenter, aCircN, aCircX); + const Handle(Geom_Curve) aCurv = new Geom_Circle(aCircAxes, +50.00000000000000000000); + + const Handle(Geom_Surface) aS2 = new Geom_SurfaceOfLinearExtrusion(aCurv, anExtrDir); + + TColgp_Array2OfPnt aPoles(1, 7, 1, 81); + TColStd_Array2OfReal aWeights(1, 7, 1, 81); + TColStd_Array1OfReal aUKnots(1, 2), aVKnots(1, 12); + TColStd_Array1OfInteger aUMult(1, 2), aVMult(1, 12); + const Standard_Integer aUDegree = 6, aVDegree = 8; + + aUKnots(1) = +0.00000000000000000000; + aUKnots(2) = +1.00000000000000000000; + aVKnots(1) = +0.08911853946147080300; + aVKnots(2) = +0.11779167587451674000; + aVKnots(3) = +0.14583467562325506000; + aVKnots(4) = +0.20255081178503931000; + aVKnots(5) = +0.25926694794682359000; + aVKnots(6) = +0.31598308410860781000; + aVKnots(7) = +0.34262437462234741000; + aVKnots(8) = +0.37067364397889985000; + aVKnots(9) = +0.39731552779654306000; + aVKnots(10) = +0.42536420384919182000; + aVKnots(11) = +0.45200329235672548000; + aVKnots(12) = +0.47802918742799144000; + + aUMult(1) = 7; + aUMult(2) = 7; + aVMult(1) = 9; + aVMult(2) = 7; + aVMult(3) = 7; + aVMult(4) = 7; + aVMult(5) = 7; + aVMult(6) = 7; + aVMult(7) = 7; + aVMult(8) = 7; + aVMult(9) = 7; + aVMult(10) = 8; + aVMult(11) = 8; + aVMult(12) = 9; + + //// + { + aWeights.ChangeValue(1, 1) = +1.02986327036737910000; + aPoles.ChangeValue(1, 1) = gp_Pnt(+131.75315905495660000000, +2.88570510351864900000, -66.24709307590461500000); + aWeights.ChangeValue(1, 2) = +1.02989244478761060000; + aPoles.ChangeValue(1, 2) = gp_Pnt(+128.70876344053133000000, +2.88791208181246970000, -67.92914281439198000000); + aWeights.ChangeValue(1, 3) = +1.02991676091113950000; + aPoles.ChangeValue(1, 3) = gp_Pnt(+125.64133203841195000000, +2.88975018186799830000, -69.56968825975690200000); + aWeights.ChangeValue(1, 4) = +1.02993613450133650000; + aPoles.ChangeValue(1, 4) = gp_Pnt(+122.55164101294532000000, +2.89121448973680460000, -71.16831921321855200000); + aWeights.ChangeValue(1, 5) = +1.02995970896170810000; + aPoles.ChangeValue(1, 5) = gp_Pnt(+119.44028474076808000000, +2.89299532863950050000, -72.72471137484106400000); + aWeights.ChangeValue(1, 6) = +1.02998196300928410000; + aPoles.ChangeValue(1, 6) = gp_Pnt(+116.30796917345266000000, +2.89467567823625730000, -74.23853925439507900000); + aWeights.ChangeValue(1, 7) = +1.02999781361772440000; + aPoles.ChangeValue(1, 7) = gp_Pnt(+113.15537818476763000000, +2.89587201010380560000, -75.70949847615843000000); + aWeights.ChangeValue(1, 8) = +1.03001626830283270000; + aPoles.ChangeValue(1, 8) = gp_Pnt(+109.98323502828077000000, +2.89726468512897210000, -77.13723994508107800000); + aWeights.ChangeValue(1, 9) = +1.03004822145815230000; + aPoles.ChangeValue(1, 9) = gp_Pnt(+103.60126699909762000000, +2.89967510685080440000, -79.90571269046952800000); + aWeights.ChangeValue(1, 10) = +1.03006364818936770000; + aPoles.ChangeValue(1, 10) = gp_Pnt(+100.39144092265354000000, +2.90083845616186050000, -81.24644132200651800000); + aWeights.ChangeValue(1, 11) = +1.03007725635592000000; + aPoles.ChangeValue(1, 11) = gp_Pnt(+97.16342330855667300000, +2.90186436688425700000, -82.54338871675531700000); + aWeights.ChangeValue(1, 12) = +1.03009045031501500000; + aPoles.ChangeValue(1, 12) = gp_Pnt(+93.91790293022438600000, +2.90285879918974650000, -83.79626764915399000000); + aWeights.ChangeValue(1, 13) = +1.03010285398183930000; + aPoles.ChangeValue(1, 13) = gp_Pnt(+90.65560197798836800000, +2.90379346029782100000, -85.00479786905465600000); + aWeights.ChangeValue(1, 14) = +1.03011393120350900000; + aPoles.ChangeValue(1, 14) = gp_Pnt(+87.37722618415423900000, +2.90462796925060120000, -86.16871841453435400000); + aWeights.ChangeValue(1, 15) = +1.03012484065787050000; + aPoles.ChangeValue(1, 15) = gp_Pnt(+84.08346762829417300000, +2.90544970249433290000, -87.28777941880029800000); + aWeights.ChangeValue(1, 16) = +1.03015471267321200000; + aPoles.ChangeValue(1, 16) = gp_Pnt(+74.15848807058078800000, +2.90769927244280210000, -90.50962423575197100000); + aWeights.ChangeValue(1, 17) = +1.03017194800922400000; + aPoles.ChangeValue(1, 17) = gp_Pnt(+67.48342008926763900000, +2.90899668032978950000, -92.47701903504494700000); + aWeights.ChangeValue(1, 18) = +1.03018680682765670000; + aPoles.ChangeValue(1, 18) = gp_Pnt(+60.75515833606132100000, +2.91011480947056490000, -94.26204121664201800000); + aWeights.ChangeValue(1, 19) = +1.03019958109549670000; + aPoles.ChangeValue(1, 19) = gp_Pnt(+53.97928154760177200000, +2.91107580930771360000, -95.86305268935117900000); + aWeights.ChangeValue(1, 20) = +1.03021050389503350000; + aPoles.ChangeValue(1, 20) = gp_Pnt(+47.16164692132413400000, +2.91189735380426780000, -97.27865560180262600000); + aWeights.ChangeValue(1, 21) = +1.03021974942385830000; + aPoles.ChangeValue(1, 21) = gp_Pnt(+40.30838837608569500000, +2.91259264267907050000, -98.50769317562559000000); + aWeights.ChangeValue(1, 22) = +1.03022743299486370000; + aPoles.ChangeValue(1, 22) = gp_Pnt(+33.42591476110869300000, +2.91317040233699530000, -99.54925039136011800000); + aWeights.ChangeValue(1, 23) = +1.03023979631718900000; + aPoles.ChangeValue(1, 23) = gp_Pnt(+19.61576136171939000000, +2.91409991934468550000, -101.25602945077115000000); + aWeights.ChangeValue(1, 24) = +1.03024450452679140000; + aPoles.ChangeValue(1, 24) = gp_Pnt(+12.68754355991407800000, +2.91445385083459700000, -101.92122234436175000000); + aWeights.ChangeValue(1, 25) = +1.03024781840890120000; + aPoles.ChangeValue(1, 25) = gp_Pnt(+5.74236948737514120000, +2.91470294045230770000, -102.39751844510502000000); + aWeights.ChangeValue(1, 26) = +1.03024979501192000000; + aPoles.ChangeValue(1, 26) = gp_Pnt(-1.21367831605073050000, +2.91485150371151920000, -102.68442590550356000000); + aWeights.ChangeValue(1, 27) = +1.03025046568879790000; + aPoles.ChangeValue(1, 27) = gp_Pnt(-8.17455041611474620000, +2.91490191238154670000, -102.78167594353056000000); + aWeights.ChangeValue(1, 28) = +1.03024983609703540000; + aPoles.ChangeValue(1, 28) = gp_Pnt(-15.13423127055194300000, +2.91485459458572780000, -102.68922293042964000000); + aWeights.ChangeValue(1, 29) = +1.03024788619868260000; + aPoles.ChangeValue(1, 29) = gp_Pnt(-22.08674002008992700000, +2.91470803482494080000, -102.40724441194320000000); + aWeights.ChangeValue(1, 30) = +1.03024126030624540000; + aPoles.ChangeValue(1, 30) = gp_Pnt(-35.96556766132121700000, +2.91420996731856930000, -101.46503408514069000000); + aWeights.ChangeValue(1, 31) = +1.03023657011944230000; + aPoles.ChangeValue(1, 31) = gp_Pnt(-42.89191729472150200000, +2.91385737699769360000, -100.80479886745856000000); + aWeights.ChangeValue(1, 32) = +1.03023047292900880000; + aPoles.ChangeValue(1, 32) = gp_Pnt(-49.79923779841396900000, +2.91339898565004060000, -99.95583114848535900000); + aWeights.ChangeValue(1, 33) = +1.03022290017099550000; + aPoles.ChangeValue(1, 33) = gp_Pnt(-56.68161614207340900000, +2.91282960709223810000, -98.91875138839027700000); + aWeights.ChangeValue(1, 34) = +1.03021374148842180000; + aPoles.ChangeValue(1, 34) = gp_Pnt(-63.53316994906088400000, +2.91214088593828220000, -97.69440448679608800000); + aWeights.ChangeValue(1, 35) = +1.03020284473128080000; + aPoles.ChangeValue(1, 35) = gp_Pnt(-70.34804877511381000000, +2.91132129711663760000, -96.28385939245710300000); + aWeights.ChangeValue(1, 36) = +1.03019001595653580000; + aPoles.ChangeValue(1, 36) = gp_Pnt(-77.12043535415037400000, +2.91035614521427500000, -94.68840860671046800000); + aWeights.ChangeValue(1, 37) = +1.03016805964614980000; + aPoles.ChangeValue(1, 37) = gp_Pnt(-86.96652166958519100000, +2.90870378328618400000, -92.08365976972685000000); + aWeights.ChangeValue(1, 38) = +1.03016062145972500000; + aPoles.ChangeValue(1, 38) = gp_Pnt(-90.07809790629383400000, +2.90814392820824040000, -91.21821667329717800000); + aWeights.ChangeValue(1, 39) = +1.03015268516758060000; + aPoles.ChangeValue(1, 39) = gp_Pnt(-93.17869710255469300000, +2.90754650188789080000, -90.31338955501080100000); + aWeights.ChangeValue(1, 40) = +1.03014422393874510000; + aPoles.ChangeValue(1, 40) = gp_Pnt(-96.26774201507643600000, +2.90690946644790090000, -89.36934028436292000000); + aWeights.ChangeValue(1, 41) = +1.03013520381253840000; + aPoles.ChangeValue(1, 41) = gp_Pnt(-99.34465666946248100000, +2.90623024256504880000, -88.38624129906430900000); + aWeights.ChangeValue(1, 42) = +1.03012558369857450000; + aPoles.ChangeValue(1, 42) = gp_Pnt(-102.40886646020824000000, +2.90550570939860810000, -87.36427556081821400000); + aWeights.ChangeValue(1, 43) = +1.03011531537676040000; + aPoles.ChangeValue(1, 43) = gp_Pnt(-105.45979824903711000000, +2.90473220450791560000, -86.30363650725728100000); + aWeights.ChangeValue(1, 44) = +1.03009266486593140000; + aPoles.ChangeValue(1, 44) = gp_Pnt(-111.76765655411073000000, +2.90302557752729130000, -84.02084620865503000000); + aWeights.ChangeValue(1, 45) = +1.03007954250893910000; + aPoles.ChangeValue(1, 45) = gp_Pnt(-115.02237879255169000000, +2.90203661863772000000, -82.79254553120374300000); + aWeights.ChangeValue(1, 46) = +1.03006700046846360000; + aPoles.ChangeValue(1, 46) = gp_Pnt(-118.26033551796380000000, +2.90109123094133370000, -81.51987347500843800000); + aWeights.ChangeValue(1, 47) = +1.03005153385518430000; + aPoles.ChangeValue(1, 47) = gp_Pnt(-121.48081153033489000000, +2.89992503429592440000, -80.20310945547186100000); + aWeights.ChangeValue(1, 48) = +1.03003663316288070000; + aPoles.ChangeValue(1, 48) = gp_Pnt(-124.68310204708784000000, +2.89880123910694910000, -78.84252385592422700000); + aWeights.ChangeValue(1, 49) = +1.03002002524051230000; + aPoles.ChangeValue(1, 49) = gp_Pnt(-127.86649232671233000000, +2.89754829341323060000, -77.43842231968982000000); + aWeights.ChangeValue(1, 50) = +1.03000192732161230000; + aPoles.ChangeValue(1, 50) = gp_Pnt(-131.03028254956638000000, +2.89618247462029290000, -75.99111259804850200000); + aWeights.ChangeValue(1, 51) = +1.02996526567113600000; + aPoles.ChangeValue(1, 51) = gp_Pnt(-137.09281139094972000000, +2.89341459629042360000, -73.11712223836046600000); + aWeights.ChangeValue(1, 52) = +1.02994403451589630000; + aPoles.ChangeValue(1, 52) = gp_Pnt(-139.99435839258939000000, +2.89181101472158900000, -71.69634981883045600000); + aWeights.ChangeValue(1, 53) = +1.02992866105538440000; + aPoles.ChangeValue(1, 53) = gp_Pnt(-142.87784656482347000000, +2.89064973421052680000, -70.23882874204873900000); + aWeights.ChangeValue(1, 54) = +1.02989968743283590000; + aPoles.ChangeValue(1, 54) = gp_Pnt(-145.74271824362268000000, +2.88845983550875030000, -68.74489127449217600000); + aWeights.ChangeValue(1, 55) = +1.02988222474524970000; + aPoles.ChangeValue(1, 55) = gp_Pnt(-148.58838121276386000000, +2.88713941077432070000, -67.21475112846350400000); + aWeights.ChangeValue(1, 56) = +1.02985386954408620000; + aPoles.ChangeValue(1, 56) = gp_Pnt(-151.41432118416620000000, +2.88499463682574180000, -65.64875099202183200000); + aWeights.ChangeValue(1, 57) = +1.02982704006090460000; + aPoles.ChangeValue(1, 57) = gp_Pnt(-154.21993049579214000000, +2.88296397171855910000, -64.04717955157212800000); + aWeights.ChangeValue(1, 58) = +1.02976639514278400000; + aPoles.ChangeValue(1, 58) = gp_Pnt(-160.00375832753414000000, +2.87837140815595260000, -60.64735416015690100000); + aWeights.ChangeValue(1, 59) = +1.02972545417711370000; + aPoles.ChangeValue(1, 59) = gp_Pnt(-162.97914403387477000000, +2.87526824819569480000, -58.84445149944087200000); + aWeights.ChangeValue(1, 60) = +1.02970377642253300000; + aPoles.ChangeValue(1, 60) = gp_Pnt(-165.92810584856278000000, +2.87362619373759860000, -56.99783055334398100000); + aWeights.ChangeValue(1, 61) = +1.02963665582001740000; + aPoles.ChangeValue(1, 61) = gp_Pnt(-168.85438185317770000000, +2.86853152516479340000, -55.11698298198095400000); + aWeights.ChangeValue(1, 62) = +1.02961756328192160000; + aPoles.ChangeValue(1, 62) = gp_Pnt(-171.75125340157436000000, +2.86708271055963240000, -53.19057330425229700000); + aWeights.ChangeValue(1, 63) = +1.02954937293527580000; + aPoles.ChangeValue(1, 63) = gp_Pnt(-174.62251681022158000000, +2.86190007017706360000, -51.22700225930964300000); + aWeights.ChangeValue(1, 64) = +1.02950097342691520000; + aPoles.ChangeValue(1, 64) = gp_Pnt(-177.46620192435449000000, +2.85821732043423180000, -49.22415777229338100000); + aWeights.ChangeValue(1, 65) = +1.02943612532291810000; + aPoles.ChangeValue(1, 65) = gp_Pnt(-180.28206426096281000000, +2.85327724467687100000, -47.18300981722491400000); + aWeights.ChangeValue(1, 66) = +1.02937840445786000000; + aPoles.ChangeValue(1, 66) = gp_Pnt(-182.89713737694305000000, +2.84888100315162470000, -45.28741010449485300000); + aWeights.ChangeValue(1, 67) = +1.02929786839840220000; + aPoles.ChangeValue(1, 67) = gp_Pnt(-185.48808576506855000000, +2.84272935508061810000, -43.35897595091199000000); + aWeights.ChangeValue(1, 68) = +1.02927785532845030000; + aPoles.ChangeValue(1, 68) = gp_Pnt(-188.05509745668041000000, +2.84122612975151250000, -41.39706700987362400000); + aWeights.ChangeValue(1, 69) = +1.02909457173363930000; + aPoles.ChangeValue(1, 69) = gp_Pnt(-190.59634219852757000000, +2.82717082550985440000, -39.40453806610211300000); + aWeights.ChangeValue(1, 70) = +1.02915656102508410000; + aPoles.ChangeValue(1, 70) = gp_Pnt(-193.11296933822229000000, +2.83195841118334000000, -37.37763511391345600000); + aWeights.ChangeValue(1, 71) = +1.02891246603941110000; + aPoles.ChangeValue(1, 71) = gp_Pnt(-195.60305999702362000000, +2.81322479805689340000, -35.32107774203857500000); + aWeights.ChangeValue(1, 72) = +1.02884001996307940000; + aPoles.ChangeValue(1, 72) = gp_Pnt(-198.06589030811097000000, +2.80764438138268390000, -33.23208121127716900000); + aWeights.ChangeValue(1, 73) = +1.02870418206103250000; + aPoles.ChangeValue(1, 73) = gp_Pnt(-200.50111697620073000000, +2.79717360924099090000, -31.11182660391394400000); + aWeights.ChangeValue(1, 74) = +1.02860417892814660000; + aPoles.ChangeValue(1, 74) = gp_Pnt(-202.93720652839650000000, +2.78949733525485710000, -28.99085629216911300000); + aWeights.ChangeValue(1, 75) = +1.02826579045547110000; + aPoles.ChangeValue(1, 75) = gp_Pnt(-205.34394850673777000000, +2.76315604312090550000, -26.83940109433629200000); + aWeights.ChangeValue(1, 76) = +1.02871793966742330000; + aPoles.ChangeValue(1, 76) = gp_Pnt(-207.72575255584553000000, +2.79855565223875710000, -24.65500081264426800000); + aWeights.ChangeValue(1, 77) = +1.02728787827176630000; + aPoles.ChangeValue(1, 77) = gp_Pnt(-210.07706367406874000000, +2.68725363743552850000, -22.43634910730148800000); + aWeights.ChangeValue(1, 78) = +1.02767535385809120000; + aPoles.ChangeValue(1, 78) = gp_Pnt(-212.39605978578481000000, +2.71705476277515070000, -20.20562112100595800000); + aWeights.ChangeValue(1, 79) = +1.02745809923169020000; + aPoles.ChangeValue(1, 79) = gp_Pnt(-214.68098626410506000000, +2.69985190382785320000, -17.91605900374278100000); + aWeights.ChangeValue(1, 80) = +1.02725110106359850000; + aPoles.ChangeValue(1, 80) = gp_Pnt(-216.94385389331507000000, +2.68435107488514250000, -15.61289037092123000000); + aWeights.ChangeValue(1, 81) = +1.02619749797986360000; + aPoles.ChangeValue(1, 81) = gp_Pnt(-219.16685583874414000000, +2.59983520096898510000, -13.28583956380401400000); + aWeights.ChangeValue(2, 1) = +1.00955713824395700000; + aPoles.ChangeValue(2, 1) = gp_Pnt(+131.76756408216349000000, +2.10451717388867540000, -66.27316135719137000000); + aWeights.ChangeValue(2, 2) = +1.00956608612165600000; + aPoles.ChangeValue(2, 2) = gp_Pnt(+128.72252404033563000000, +2.10631182699007670000, -67.95492700832653600000); + aWeights.ChangeValue(2, 3) = +1.00957354292813030000; + aPoles.ChangeValue(2, 3) = gp_Pnt(+125.65455798821807000000, +2.10780700070896730000, -69.59522708152212500000); + aWeights.ChangeValue(2, 4) = +1.00957948395970430000; + aPoles.ChangeValue(2, 4) = gp_Pnt(+122.56436007131990000000, +2.10899819276768510000, -71.19369911011085600000); + aWeights.ChangeValue(2, 5) = +1.00958671248272140000; + aPoles.ChangeValue(2, 5) = gp_Pnt(+119.45249930698063000000, +2.11044722765431250000, -72.74983445837314400000); + aWeights.ChangeValue(2, 6) = +1.00959353559448470000; + aPoles.ChangeValue(2, 6) = gp_Pnt(+116.31971419268339000000, +2.11181476538007030000, -74.26341133748536500000); + aWeights.ChangeValue(2, 7) = +1.00959839503054960000; + aPoles.ChangeValue(2, 7) = gp_Pnt(+113.16673272248508000000, +2.11278857229853930000, -75.73421464457315700000); + aWeights.ChangeValue(2, 8) = +1.00960405269294800000; + aPoles.ChangeValue(2, 8) = gp_Pnt(+109.99417142410560000000, +2.11392227976110990000, -77.16175403351917300000); + aWeights.ChangeValue(2, 9) = +1.00961384794963970000; + aPoles.ChangeValue(2, 9) = gp_Pnt(+103.61137952541701000000, +2.11588481923337430000, -79.92991318438167500000); + aWeights.ChangeValue(2, 10) = +1.00961857675621050000; + aPoles.ChangeValue(2, 10) = gp_Pnt(+100.40113044627800000000, +2.11683214779396200000, -81.27049552555527600000); + aWeights.ChangeValue(2, 11) = +1.00962274789480260000; + aPoles.ChangeValue(2, 11) = gp_Pnt(+97.17272090352022900000, +2.11766766635255620000, -82.56731642507010300000); + aWeights.ChangeValue(2, 12) = +1.00962679188946770000; + aPoles.ChangeValue(2, 12) = gp_Pnt(+93.92682593436140300000, +2.11847763961438810000, -83.82006598438695700000); + aWeights.ChangeValue(2, 13) = +1.00963059350869510000; + aPoles.ChangeValue(2, 13) = gp_Pnt(+90.66416580726762200000, +2.11923900414192050000, -85.02847304317147300000); + aWeights.ChangeValue(2, 14) = +1.00963398843777610000; + aPoles.ChangeValue(2, 14) = gp_Pnt(+87.38545325411524800000, +2.11991885797243330000, -86.19228543784532800000); + aWeights.ChangeValue(2, 15) = +1.00963733185346640000; + aPoles.ChangeValue(2, 15) = gp_Pnt(+84.09136475788710600000, +2.12058835416503610000, -87.31123582184922300000); + aWeights.ChangeValue(2, 16) = +1.00964648640037450000; + aPoles.ChangeValue(2, 16) = gp_Pnt(+74.16530685267888100000, +2.12242134451684360000, -90.53282418399284400000); + aWeights.ChangeValue(2, 17) = +1.00965176794147850000; + aPoles.ChangeValue(2, 17) = gp_Pnt(+67.48955141808187400000, +2.12347869023601370000, -92.50007118315201600000); + aWeights.ChangeValue(2, 18) = +1.00965632094816660000; + aPoles.ChangeValue(2, 18) = gp_Pnt(+60.76066172731987800000, +2.12439006790716880000, -94.28495774595940300000); + aWeights.ChangeValue(2, 19) = +1.00966023501695720000; + aPoles.ChangeValue(2, 19) = gp_Pnt(+53.98420072674593900000, +2.12517346720689600000, -95.88584819516199800000); + aWeights.ChangeValue(2, 20) = +1.00966358166845400000; + aPoles.ChangeValue(2, 20) = gp_Pnt(+47.16601123883578600000, +2.12584324589548320000, -97.30134659055448800000); + aWeights.ChangeValue(2, 21) = +1.00966641434734730000; + aPoles.ChangeValue(2, 21) = gp_Pnt(+40.31221541713015500000, +2.12641013013135180000, -98.53029698991525700000); + aWeights.ChangeValue(2, 22) = +1.00966876842241260000; + aPoles.ChangeValue(2, 22) = gp_Pnt(+33.42921418500849000000, +2.12688121470786750000, -99.57178366381829400000); + aWeights.ChangeValue(2, 23) = +1.00967255617655650000; + aPoles.ChangeValue(2, 23) = gp_Pnt(+19.61796125907087400000, +2.12763915883061920000, -101.27845724558523000000); + aWeights.ChangeValue(2, 24) = +1.00967399859793750000; + aPoles.ChangeValue(2, 24) = gp_Pnt(+12.68919279606528900000, +2.12792777824197280000, -101.94361028295506000000); + aWeights.ChangeValue(2, 25) = +1.00967501382968900000; + aPoles.ChangeValue(2, 25) = gp_Pnt(+5.74348853231593990000, +2.12813091177048630000, -102.41987704106546000000); + aWeights.ChangeValue(2, 26) = +1.00967561936957820000; + aPoles.ChangeValue(2, 26) = gp_Pnt(-1.21307744928976070000, +2.12825206894226590000, -102.70676666240287000000); + aWeights.ChangeValue(2, 27) = +1.00967582483410380000; + aPoles.ChangeValue(2, 27) = gp_Pnt(-8.17446448579617170000, +2.12829317854427910000, -102.80401081431219000000); + aWeights.ChangeValue(2, 28) = +1.00967563195849760000; + aPoles.ChangeValue(2, 28) = gp_Pnt(-15.13466558037753100000, +2.12825458864942170000, -102.71156371647888000000); + aWeights.ChangeValue(2, 29) = +1.00967503459672270000; + aPoles.ChangeValue(2, 29) = gp_Pnt(-22.08770764998126900000, +2.12813506662251010000, -102.42960214757312000000); + aWeights.ChangeValue(2, 30) = +1.00967300468446490000; + aPoles.ChangeValue(2, 30) = gp_Pnt(-35.96760988752987500000, +2.12772890088942160000, -101.48744752427969000000); + aWeights.ChangeValue(2, 31) = +1.00967156777535580000; + aPoles.ChangeValue(2, 31) = gp_Pnt(-42.89448004815705000000, +2.12744138030294440000, -100.82725372327035000000); + aWeights.ChangeValue(2, 32) = +1.00966969979090780000; + aPoles.ChangeValue(2, 32) = gp_Pnt(-49.80232400744441900000, +2.12706759457740000000, -99.97834162579670200000); + aWeights.ChangeValue(2, 33) = +1.00966737970297200000; + aPoles.ChangeValue(2, 33) = gp_Pnt(-56.68523628384353000000, +2.12660332632729520000, -98.94133225857957800000); + aWeights.ChangeValue(2, 34) = +1.00966457365849260000; + aPoles.ChangeValue(2, 34) = gp_Pnt(-63.53734456971785200000, +2.12604178346724470000, -97.71706998895581400000); + aWeights.ChangeValue(2, 35) = +1.00966123497950600000; + aPoles.ChangeValue(2, 35) = gp_Pnt(-70.35281013187348300000, +2.12537359908900880000, -96.30662240267085400000); + aWeights.ChangeValue(2, 36) = +1.00965730416314050000; + aPoles.ChangeValue(2, 36) = gp_Pnt(-77.12582820180557500000, +2.12458683129447450000, -94.71128014840769500000); + aWeights.ChangeValue(2, 37) = +1.00965057624220010000; + aPoles.ChangeValue(2, 37) = gp_Pnt(-86.97287762202962800000, +2.12324005462031540000, -92.10671540000876700000); + aWeights.ChangeValue(2, 38) = +1.00964829695753690000; + aPoles.ChangeValue(2, 38) = gp_Pnt(-90.08473551349412400000, +2.12278376932639290000, -91.24134329153459100000); + aWeights.ChangeValue(2, 39) = +1.00964586498084840000; + aPoles.ChangeValue(2, 39) = gp_Pnt(-93.18562459494498300000, +2.12229689243319890000, -90.33659169532975900000); + aWeights.ChangeValue(2, 40) = +1.00964327207694590000; + aPoles.ChangeValue(2, 40) = gp_Pnt(-96.27496896689456200000, +2.12177776971417840000, -89.39262240039663300000); + aWeights.ChangeValue(2, 41) = +1.00964050782222770000; + aPoles.ChangeValue(2, 41) = gp_Pnt(-99.35219429474524600000, +2.12122430736176200000, -88.40960770124299000000); + aWeights.ChangeValue(2, 42) = +1.00963755960468140000; + aPoles.ChangeValue(2, 42) = gp_Pnt(-102.41672784011750000000, +2.12063397196916760000, -87.38773038403248000000); + aWeights.ChangeValue(2, 43) = +1.00963441262388320000; + aPoles.ChangeValue(2, 43) = gp_Pnt(-105.46799849165807000000, +2.12000379050942020000, -86.32718371153289600000); + aWeights.ChangeValue(2, 44) = +1.00962747055142050000; + aPoles.ChangeValue(2, 44) = gp_Pnt(-111.77654530973133000000, +2.11861352771318150000, -84.04460889409097000000); + aWeights.ChangeValue(2, 45) = +1.00962344856326270000; + aPoles.ChangeValue(2, 45) = gp_Pnt(-115.03162075269803000000, +2.11780798556167320000, -82.81644583890866300000); + aWeights.ChangeValue(2, 46) = +1.00961960432211730000; + aPoles.ChangeValue(2, 46) = gp_Pnt(-118.26993104545312000000, +2.11703799459344700000, -81.54389579486141300000); + aWeights.ChangeValue(2, 47) = +1.00961486342011010000; + aPoles.ChangeValue(2, 47) = gp_Pnt(-121.49080060905077000000, +2.11608829135299810000, -80.22729418526657200000); + aWeights.ChangeValue(2, 48) = +1.00961029578343630000; + aPoles.ChangeValue(2, 48) = gp_Pnt(-124.69348951442340000000, +2.11517321690879800000, -78.86685283462101400000); + aWeights.ChangeValue(2, 49) = +1.00960520454014850000; + aPoles.ChangeValue(2, 49) = gp_Pnt(-127.87731027004676000000, +2.11415312105035590000, -77.46291256687052900000); + aWeights.ChangeValue(2, 50) = +1.00959965618773250000; + aPoles.ChangeValue(2, 50) = gp_Pnt(-131.04156234039974000000, +2.11304129636208420000, -76.01577573259778800000); + aWeights.ChangeValue(2, 51) = +1.00958841592243690000; + aPoles.ChangeValue(2, 51) = gp_Pnt(-137.10496896782513000000, +2.11078854745601690000, -73.14215015354327000000); + aWeights.ChangeValue(2, 52) = +1.00958190609540830000; + aPoles.ChangeValue(2, 52) = gp_Pnt(-140.00695092509352000000, +2.10948365684345340000, -71.72161996530125800000); + aWeights.ChangeValue(2, 53) = +1.00957719225994170000; + aPoles.ChangeValue(2, 53) = gp_Pnt(-142.89082065884315000000, +2.10853873486620720000, -70.26423921243410600000); + aWeights.ChangeValue(2, 54) = +1.00956830737110970000; + aPoles.ChangeValue(2, 54) = gp_Pnt(-145.75622246387837000000, +2.10675729535240960000, -68.77065477701791000000); + aWeights.ChangeValue(2, 55) = +1.00956295195561060000; + aPoles.ChangeValue(2, 55) = gp_Pnt(-148.60233584192389000000, +2.10568335609513650000, -67.24065593702246700000); + aWeights.ChangeValue(2, 56) = +1.00955425555818930000; + aPoles.ChangeValue(2, 56) = gp_Pnt(-151.42883073983140000000, +2.10393921590561070000, -65.67497260857376800000); + aWeights.ChangeValue(2, 57) = +1.00954602613011150000; + aPoles.ChangeValue(2, 57) = gp_Pnt(-154.23502547473331000000, +2.10228833319884910000, -64.07366145615235100000); + aWeights.ChangeValue(2, 58) = +1.00952742278729300000; + aPoles.ChangeValue(2, 58) = gp_Pnt(-160.02004322449872000000, +2.09855561509982950000, -60.67448614970191300000); + aWeights.ChangeValue(2, 59) = +1.00951486183164940000; + aPoles.ChangeValue(2, 59) = gp_Pnt(-162.99613088380306000000, +2.09603444654779600000, -58.87207545484513800000); + aWeights.ChangeValue(2, 60) = +1.00950821186194630000; + aPoles.ChangeValue(2, 60) = gp_Pnt(-165.94554723216726000000, +2.09470002788322150000, -57.02566663092176900000); + aWeights.ChangeValue(2, 61) = +1.00948761363819010000; + aPoles.ChangeValue(2, 61) = gp_Pnt(-168.87287521283019000000, +2.09056345777511910000, -55.14566924440539700000); + aWeights.ChangeValue(2, 62) = +1.00948175483840210000; + aPoles.ChangeValue(2, 62) = gp_Pnt(-171.77025983587509000000, +2.08938700649796160000, -53.21936605947655600000); + aWeights.ChangeValue(2, 63) = +1.00946082358399410000; + aPoles.ChangeValue(2, 63) = gp_Pnt(-174.64262250370552000000, +2.08518149324171190000, -51.25662423685646700000); + aWeights.ChangeValue(2, 64) = +1.00944596410269540000; + aPoles.ChangeValue(2, 64) = gp_Pnt(-177.48726621628353000000, +2.08219461660139650000, -49.25423871740036900000); + aWeights.ChangeValue(2, 65) = +1.00942605045267530000; + aPoles.ChangeValue(2, 65) = gp_Pnt(-180.30433731845508000000, +2.07819005191471670000, -47.21374002625280800000); + aWeights.ChangeValue(2, 66) = +1.00940832657289500000; + aPoles.ChangeValue(2, 66) = gp_Pnt(-182.92026834009920000000, +2.07462614892136180000, -45.31887901738367200000); + aWeights.ChangeValue(2, 67) = +1.00938358350026620000; + aPoles.ChangeValue(2, 67) = gp_Pnt(-185.51252638985017000000, +2.06964535925843180000, -43.39137009339865600000); + aWeights.ChangeValue(2, 68) = +1.00937745534293180000; + aPoles.ChangeValue(2, 68) = gp_Pnt(-188.07970214515959000000, +2.06841969296490240000, -41.42984981640538000000); + aWeights.ChangeValue(2, 69) = +1.00932110415642830000; + aPoles.ChangeValue(2, 69) = gp_Pnt(-190.62397551723822000000, +2.05705915800362950000, -39.43932945784815300000); + aWeights.ChangeValue(2, 70) = +1.00934018958961060000; + aPoles.ChangeValue(2, 70) = gp_Pnt(-193.13969442040633000000, +2.06091733419064350000, -37.41169132931209200000); + aWeights.ChangeValue(2, 71) = +1.00926513417552190000; + aPoles.ChangeValue(2, 71) = gp_Pnt(-195.63329272671066000000, +2.04578165519120160000, -35.35822241980492500000); + aWeights.ChangeValue(2, 72) = +1.00924284324010150000; + aPoles.ChangeValue(2, 72) = gp_Pnt(-198.09761820165846000000, +2.04128022217386820000, -33.26975126412686700000); + aWeights.ChangeValue(2, 73) = +1.00920104311988150000; + aPoles.ChangeValue(2, 73) = gp_Pnt(-200.53514329838038000000, +2.03283693524956680000, -31.15087616958502200000); + aWeights.ChangeValue(2, 74) = +1.00917029694372660000; + aPoles.ChangeValue(2, 74) = gp_Pnt(-202.97255799662608000000, +2.02663657044316060000, -29.03126127135719200000); + aWeights.ChangeValue(2, 75) = +1.00906597799637380000; + aPoles.ChangeValue(2, 75) = gp_Pnt(-205.38430250588374000000, +2.00548607046822540000, -26.88375382824776200000); + aWeights.ChangeValue(2, 76) = +1.00920552993214340000; + aPoles.ChangeValue(2, 76) = gp_Pnt(-207.76049754988114000000, +2.03384304897263670000, -24.69318019977189100000); + aWeights.ChangeValue(2, 77) = +1.00876475817298510000; + aPoles.ChangeValue(2, 77) = gp_Pnt(-210.12674832523484000000, +1.94448851661030540000, -22.49703905023471500000); + aWeights.ChangeValue(2, 78) = +1.00888387250469380000; + aPoles.ChangeValue(2, 78) = gp_Pnt(-212.44800842772909000000, +1.96852329008748410000, -20.25405344977475500000); + aWeights.ChangeValue(2, 79) = +1.00881670070680670000; + aPoles.ChangeValue(2, 79) = gp_Pnt(-214.73260668420895000000, +1.95481624964232450000, -17.97008076073228700000); + aWeights.ChangeValue(2, 80) = +1.00875338528797620000; + aPoles.ChangeValue(2, 80) = gp_Pnt(-216.99878954601004000000, +1.94217039944868790000, -15.66960286452947800000); + aWeights.ChangeValue(2, 81) = +1.00842683370719490000; + aPoles.ChangeValue(2, 81) = gp_Pnt(-219.23765241170187000000, +1.87520469423183880000, -13.35291936652889800000); + aWeights.ChangeValue(3, 1) = +0.99802424639217791000; + aPoles.ChangeValue(3, 1) = gp_Pnt(+131.89876890515018000000, +1.35189067474276530000, -66.51059820355672500000); + aWeights.ChangeValue(3, 2) = +0.99802234515929278000; + aPoles.ChangeValue(3, 2) = gp_Pnt(+128.85071311608803000000, +1.35313353595059940000, -68.19368716153405800000); + aWeights.ChangeValue(3, 3) = +0.99802076064203826000; + aPoles.ChangeValue(3, 3) = gp_Pnt(+125.77977143028471000000, +1.35416922698475650000, -69.83529373030198400000); + aWeights.ChangeValue(3, 4) = +0.99801949820651126000; + aPoles.ChangeValue(3, 4) = gp_Pnt(+122.68659332837821000000, +1.35499438550965670000, -71.43508181423516100000); + aWeights.ChangeValue(3, 5) = +0.99801796211084914000; + aPoles.ChangeValue(3, 5) = gp_Pnt(+119.57173533591266000000, +1.35599832254451200000, -72.99244308799212900000); + aWeights.ChangeValue(3, 6) = +0.99801651211145281000; + aPoles.ChangeValue(3, 6) = gp_Pnt(+116.43595392098000000000, +1.35694592285710100000, -74.50721127326711700000); + aWeights.ChangeValue(3, 7) = +0.99801547938002733000; + aPoles.ChangeValue(3, 7) = gp_Pnt(+113.28000153804584000000, +1.35762078417993900000, -75.97921900496575600000); + aWeights.ChangeValue(3, 8) = +0.99801427699595313000; + aPoles.ChangeValue(3, 8) = gp_Pnt(+110.10443724854701000000, +1.35840649430771500000, -77.40790012997213400000); + aWeights.ChangeValue(3, 9) = +0.99801219521191387000; + aPoles.ChangeValue(3, 9) = gp_Pnt(+103.71561277285424000000, +1.35976677896647580000, -80.17831514578958300000); + aWeights.ChangeValue(3, 10) = +0.99801119017200446000; + aPoles.ChangeValue(3, 10) = gp_Pnt(+100.50232486897988000000, +1.36042346207845170000, -81.51999289835789900000); + aWeights.ChangeValue(3, 11) = +0.99801030363459775000; + aPoles.ChangeValue(3, 11) = gp_Pnt(+97.27087733082035500000, +1.36100269005924380000, -82.81788136334564900000); + aWeights.ChangeValue(3, 12) = +0.99800944410125381000; + aPoles.ChangeValue(3, 12) = gp_Pnt(+94.02193936655145000000, +1.36156425167614130000, -84.07165794609035500000); + aWeights.ChangeValue(3, 13) = +0.99800863606857426000; + aPoles.ChangeValue(3, 13) = gp_Pnt(+90.75622955795523700000, +1.36209214789795310000, -85.28105659074749700000); + aWeights.ChangeValue(3, 14) = +0.99800791446328430000; + aPoles.ChangeValue(3, 14) = gp_Pnt(+87.47446474935537700000, +1.36256356235759690000, -86.44582972368263500000); + aWeights.ChangeValue(3, 15) = +0.99800720379689600000; + aPoles.ChangeValue(3, 15) = gp_Pnt(+84.17731596959211500000, +1.36302781837419680000, -87.56569962027794000000); + aWeights.ChangeValue(3, 16) = +0.99800525790220496000; + aPoles.ChangeValue(3, 16) = gp_Pnt(+74.24198734063921300000, +1.36429897306986340000, -90.78996991844945800000); + aWeights.ChangeValue(3, 17) = +0.99800413521623321000; + aPoles.ChangeValue(3, 17) = gp_Pnt(+67.56001809965197000000, +1.36503231983535440000, -92.75885901427626800000); + aWeights.ChangeValue(3, 18) = +0.99800316736440942000; + aPoles.ChangeValue(3, 18) = gp_Pnt(+60.82490109578901600000, +1.36566449260567850000, -94.54523441794054900000); + aWeights.ChangeValue(3, 19) = +0.99800233531441818000; + aPoles.ChangeValue(3, 19) = gp_Pnt(+54.04219505707111900000, +1.36620793936844790000, -96.14746061467829500000); + aWeights.ChangeValue(3, 20) = +0.99800162387306934000; + aPoles.ChangeValue(3, 20) = gp_Pnt(+47.21773986109732800000, +1.36667259642912180000, -97.56414160157402200000); + aWeights.ChangeValue(3, 21) = +0.99800102168630012000; + aPoles.ChangeValue(3, 21) = gp_Pnt(+40.35765665228271400000, +1.36706588836418840000, -98.79412083143951400000); + aWeights.ChangeValue(3, 22) = +0.99800052123917371000; + aPoles.ChangeValue(3, 22) = gp_Pnt(+33.46834796257081700000, +1.36739272798589770000, -99.83648116661171900000); + aWeights.ChangeValue(3, 23) = +0.99799971600020576000; + aPoles.ChangeValue(3, 23) = gp_Pnt(+19.64441706716387900000, +1.36791861440644060000, -101.54459131896159000000); + aWeights.ChangeValue(3, 24) = +0.99799940935225717000; + aPoles.ChangeValue(3, 24) = gp_Pnt(+12.70928858254282900000, +1.36811887624638580000, -102.21030492597274000000); + aWeights.ChangeValue(3, 25) = +0.99799919351964705000; + aPoles.ChangeValue(3, 25) = gp_Pnt(+5.75722078489831280000, +1.36825982711689180000, -102.68697252648171000000); + aWeights.ChangeValue(3, 26) = +0.99799906478455291000; + aPoles.ChangeValue(3, 26) = gp_Pnt(-1.20571159764999210000, +1.36834389755229970000, -102.97410341218257000000); + aWeights.ChangeValue(3, 27) = +0.99799902110371730000; + aPoles.ChangeValue(3, 27) = gp_Pnt(-8.17346746041202720000, +1.36837242333404090000, -103.07142929357101000000); + aWeights.ChangeValue(3, 28) = +0.99799906210844536000; + aPoles.ChangeValue(3, 28) = gp_Pnt(-15.14003926915473600000, +1.36834564548690430000, -102.97890429403182000000); + aWeights.ChangeValue(3, 29) = +0.99799918910460783000; + aPoles.ChangeValue(3, 29) = gp_Pnt(-22.09945300681867100000, +1.36826271027814080000, -102.69670494840925000000); + aWeights.ChangeValue(3, 30) = +0.99799962065035785000; + aPoles.ChangeValue(3, 30) = gp_Pnt(-35.99208002634647800000, +1.36798088374117890000, -101.75375562004130000000); + aWeights.ChangeValue(3, 31) = +0.99799992612548816000; + aPoles.ChangeValue(3, 31) = gp_Pnt(-42.92529183965938000000, +1.36778138671521220000, -101.09300634269859000000); + aWeights.ChangeValue(3, 32) = +0.99800032324181509000; + aPoles.ChangeValue(3, 32) = gp_Pnt(-49.83946240643516700000, +1.36752203923507090000, -100.24338136864999000000); + aWeights.ChangeValue(3, 33) = +0.99800081646744487000; + aPoles.ChangeValue(3, 33) = gp_Pnt(-56.72868525600537000000, +1.36719992054037180000, -99.20550257416397200000); + aWeights.ChangeValue(3, 34) = +0.99800141299480705000; + aPoles.ChangeValue(3, 34) = gp_Pnt(-63.58708851299418500000, +1.36681032802942060000, -97.98021473616272200000); + aWeights.ChangeValue(3, 35) = +0.99800212274065336000; + aPoles.ChangeValue(3, 35) = gp_Pnt(-70.40883481115771800000, +1.36634677727753220000, -96.56858555851044900000); + aWeights.ChangeValue(3, 36) = +0.99800295834605834000; + aPoles.ChangeValue(3, 36) = gp_Pnt(-77.18812120943384500000, +1.36580100206191160000, -94.97190570545618000000); + aWeights.ChangeValue(3, 37) = +0.99800438851666018000; + aPoles.ChangeValue(3, 37) = gp_Pnt(-87.04430869357409500000, +1.36486684103840930000, -92.36516064771883800000); + aWeights.ChangeValue(3, 38) = +0.99800487302440710000; + aPoles.ChangeValue(3, 38) = gp_Pnt(-90.15904180478642600000, +1.36455036334574700000, -91.49906951050012100000); + aWeights.ChangeValue(3, 39) = +0.99800538998403165000; + aPoles.ChangeValue(3, 39) = gp_Pnt(-93.26280104894121300000, +1.36421268117563340000, -90.59356682763008500000); + aWeights.ChangeValue(3, 40) = +0.99800594114472085000; + aPoles.ChangeValue(3, 40) = gp_Pnt(-96.35501076566437500000, +1.36385265030680070000, -89.64881447076304300000); + aWeights.ChangeValue(3, 41) = +0.99800652872047668000; + aPoles.ChangeValue(3, 41) = gp_Pnt(-99.43509702281136200000, +1.36346882243976730000, -88.66498478868943800000); + aWeights.ChangeValue(3, 42) = +0.99800715539011531000; + aPoles.ChangeValue(3, 42) = gp_Pnt(-102.50248760972849000000, +1.36305944519955100000, -87.64226061031386900000); + aWeights.ChangeValue(3, 43) = +0.99800782429726853000; + aPoles.ChangeValue(3, 43) = gp_Pnt(-105.55661203062589000000, +1.36262246213878830000, -86.58083524789229600000); + aWeights.ChangeValue(3, 44) = +0.99800929984388531000; + aPoles.ChangeValue(3, 44) = gp_Pnt(-111.87105232543304000000, +1.36165848631400000000, -84.29637819122412200000); + aWeights.ChangeValue(3, 45) = +0.99801015470554688000; + aPoles.ChangeValue(3, 45) = gp_Pnt(-115.12916723990907000000, +1.36109998387148300000, -83.06721412498791300000); + aWeights.ChangeValue(3, 46) = +0.99801097177629106000; + aPoles.ChangeValue(3, 46) = gp_Pnt(-118.37050305702043000000, +1.36056615831231790000, -81.79361556056927900000); + aWeights.ChangeValue(3, 47) = +0.99801197939908182000; + aPoles.ChangeValue(3, 47) = gp_Pnt(-121.59440429164877000000, +1.35990780214188640000, -80.47594855348815200000); + aWeights.ChangeValue(3, 48) = +0.99801295017732938000; + aPoles.ChangeValue(3, 48) = gp_Pnt(-124.80011198391350000000, +1.35927349774917520000, -79.11439339164216700000); + aWeights.ChangeValue(3, 49) = +0.99801403220993246000; + aPoles.ChangeValue(3, 49) = gp_Pnt(-127.98695272451793000000, +1.35856646260703170000, -77.70931006235629500000); + aWeights.ChangeValue(3, 50) = +0.99801521135673477000; + aPoles.ChangeValue(3, 50) = gp_Pnt(-131.15422466608416000000, +1.35779592883408770000, -76.26099835790641600000); + aWeights.ChangeValue(3, 51) = +0.99801760008173268000; + aPoles.ChangeValue(3, 51) = gp_Pnt(-137.22341426940562000000, +1.35623488186342090000, -73.38505097675174200000); + aWeights.ChangeValue(3, 52) = +0.99801898347031770000; + aPoles.ChangeValue(3, 52) = gp_Pnt(-140.12817143218851000000, +1.35533077140178190000, -71.96340636458091900000); + aWeights.ChangeValue(3, 53) = +0.99801998518653323000; + aPoles.ChangeValue(3, 53) = gp_Pnt(-143.01477271081365000000, +1.35467609324036100000, -70.50482384325539400000); + aWeights.ChangeValue(3, 54) = +0.99802187318341851000; + aPoles.ChangeValue(3, 54) = gp_Pnt(-145.88296929650440000000, +1.35344206211285110000, -69.01011970904052400000); + aWeights.ChangeValue(3, 55) = +0.99802301113749214000; + aPoles.ChangeValue(3, 55) = gp_Pnt(-148.73181832948791000000, +1.35269822187277230000, -67.47885556090747600000); + aWeights.ChangeValue(3, 56) = +0.99802485896116799000; + aPoles.ChangeValue(3, 56) = gp_Pnt(-151.56108889838526000000, +1.35149030610332030000, -65.91196867904423600000); + aWeights.ChangeValue(3, 57) = +0.99802660746081140000; + aPoles.ChangeValue(3, 57) = gp_Pnt(-154.37005843077941000000, +1.35034719652907540000, -64.30939181125272300000); + aWeights.ChangeValue(3, 58) = +0.99803055992501810000; + aPoles.ChangeValue(3, 58) = gp_Pnt(-160.16078498432634000000, +1.34776300585323040000, -60.90758294114521500000); + aWeights.ChangeValue(3, 59) = +0.99803322842151521000; + aPoles.ChangeValue(3, 59) = gp_Pnt(-163.13986451909619000000, +1.34601805132734250000, -59.10384793755353900000); + aWeights.ChangeValue(3, 60) = +0.99803464125751229000; + aPoles.ChangeValue(3, 60) = gp_Pnt(-166.09208359425281000000, +1.34509430571165490000, -57.25595351707911400000); + aWeights.ChangeValue(3, 61) = +0.99803901668572381000; + aPoles.ChangeValue(3, 61) = gp_Pnt(-169.02259847263389000000, +1.34223252516315280000, -55.37471701865561600000); + aWeights.ChangeValue(3, 62) = +0.99804026123487555000; + aPoles.ChangeValue(3, 62) = gp_Pnt(-171.92274649713781000000, +1.34141857200850120000, -53.44681670722970100000); + aWeights.ChangeValue(3, 63) = +0.99804470691034153000; + aPoles.ChangeValue(3, 63) = gp_Pnt(-174.79824691248783000000, +1.33851025764084610000, -51.48277226031661500000); + aWeights.ChangeValue(3, 64) = +0.99804786265209489000; + aPoles.ChangeValue(3, 64) = gp_Pnt(-177.64589658566118000000, +1.33644541377468110000, -49.47887210970986900000); + aWeights.ChangeValue(3, 65) = +0.99805209132461004000; + aPoles.ChangeValue(3, 65) = gp_Pnt(-180.46609411219177000000, +1.33367801102763010000, -47.43691639460438100000); + aWeights.ChangeValue(3, 66) = +0.99805585511720041000; + aPoles.ChangeValue(3, 66) = gp_Pnt(-183.08478109176986000000, +1.33121501172845690000, -45.54077967192022000000); + aWeights.ChangeValue(3, 67) = +0.99806110806405779000; + aPoles.ChangeValue(3, 67) = gp_Pnt(-185.68001727848417000000, +1.32777577033982250000, -43.61205685047624300000); + aWeights.ChangeValue(3, 68) = +0.99806241123000117000; + aPoles.ChangeValue(3, 68) = gp_Pnt(-188.24953622256075000000, +1.32692526187276720000, -41.64902509374122300000); + aWeights.ChangeValue(3, 69) = +0.99807437025077705000; + aPoles.ChangeValue(3, 69) = gp_Pnt(-190.79766796840426000000, +1.31909012471800140000, -39.65777616520052400000); + aWeights.ChangeValue(3, 70) = +0.99807032269259688000; + aPoles.ChangeValue(3, 70) = gp_Pnt(-193.31511620328166000000, +1.32174544077043810000, -37.62798636408343400000); + aWeights.ChangeValue(3, 71) = +0.99808625039380772000; + aPoles.ChangeValue(3, 71) = gp_Pnt(-195.81278252670535000000, +1.31130937814640340000, -35.57429171163009600000); + aWeights.ChangeValue(3, 72) = +0.99809097922828749000; + aPoles.ChangeValue(3, 72) = gp_Pnt(-198.28008499427182000000, +1.30820906528388470000, -33.48422839734306700000); + aWeights.ChangeValue(3, 73) = +0.99809984631895698000; + aPoles.ChangeValue(3, 73) = gp_Pnt(-200.72099421295775000000, +1.30239515227575060000, -31.36416391357070300000); + aWeights.ChangeValue(3, 74) = +0.99810637147759285000; + aPoles.ChangeValue(3, 74) = gp_Pnt(-203.16127009409345000000, +1.29812048781277520000, -29.24337154392900800000); + aWeights.ChangeValue(3, 75) = +0.99812847998895315000; + aPoles.ChangeValue(3, 75) = gp_Pnt(-205.57777363915829000000, +1.28359951668439790000, -27.09591401257074100000); + aWeights.ChangeValue(3, 76) = +0.99809892249848597000; + aPoles.ChangeValue(3, 76) = gp_Pnt(-207.95321979211485000000, +1.30303533816127510000, -24.90029856221717000000); + aWeights.ChangeValue(3, 77) = +0.99819234539248169000; + aPoles.ChangeValue(3, 77) = gp_Pnt(-210.32920376311637000000, +1.24168994973372330000, -22.71372419603407900000); + aWeights.ChangeValue(3, 78) = +0.99816706733577565000; + aPoles.ChangeValue(3, 78) = gp_Pnt(-212.65404345030839000000, +1.25824740351837460000, -20.46200135460381000000); + aWeights.ChangeValue(3, 79) = +0.99818127776964660000; + aPoles.ChangeValue(3, 79) = gp_Pnt(-214.94032188963598000000, +1.24888524402456480000, -18.17894168737611000000); + aWeights.ChangeValue(3, 80) = +0.99819475509197664000; + aPoles.ChangeValue(3, 80) = gp_Pnt(-217.21049138159862000000, +1.24010538580557930000, -15.87773552075580100000); + aWeights.ChangeValue(3, 81) = +0.99826376750414003000; + aPoles.ChangeValue(3, 81) = gp_Pnt(-219.45963474898130000000, +1.19454909379966280000, -13.56324778739743800000); + aWeights.ChangeValue(4, 1) = +0.99424302042862245000; + aPoles.ChangeValue(4, 1) = gp_Pnt(+132.13618409480023000000, +0.70840889522526063000, -66.94024029007874800000); + aWeights.ChangeValue(4, 2) = +0.99423758610938695000; + aPoles.ChangeValue(4, 2) = gp_Pnt(+129.08297406972278000000, +0.70909252303575865000, -68.62615176496952100000); + aWeights.ChangeValue(4, 3) = +0.99423305718875432000; + aPoles.ChangeValue(4, 3) = gp_Pnt(+126.00685240811242000000, +0.70966228194967051000, -70.27050713058781600000); + aWeights.ChangeValue(4, 4) = +0.99422944886444642000; + aPoles.ChangeValue(4, 4) = gp_Pnt(+122.90845587213282000000, +0.71011623149435366000, -71.87297804945868100000); + aWeights.ChangeValue(4, 5) = +0.99422505844796127000; + aPoles.ChangeValue(4, 5) = gp_Pnt(+119.78834767262531000000, +0.71066859395963999000, -73.43294438704307900000); + aWeights.ChangeValue(4, 6) = +0.99422091417503022000; + aPoles.ChangeValue(4, 6) = gp_Pnt(+116.64728496160824000000, +0.71119000548737488000, -74.95024473036627900000); + aWeights.ChangeValue(4, 7) = +0.99421796254996875000; + aPoles.ChangeValue(4, 7) = gp_Pnt(+113.48602386120655000000, +0.71156137519735096000, -76.42471498016054500000); + aWeights.ChangeValue(4, 8) = +0.99421452605999638000; + aPoles.ChangeValue(4, 8) = gp_Pnt(+110.30511547520040000000, +0.71199375553590705000, -77.85578472764748900000); + aWeights.ChangeValue(4, 9) = +0.99420857626658776000; + aPoles.ChangeValue(4, 9) = gp_Pnt(+103.90553506044348000000, +0.71274238201017392000, -80.63083668700706100000); + aWeights.ChangeValue(4, 10) = +0.99420570386914531000; + aPoles.ChangeValue(4, 10) = gp_Pnt(+100.68683453164211000000, +0.71310380757531833000, -81.97476109354066400000); + aWeights.ChangeValue(4, 11) = +0.99420317017586146000; + aPoles.ChangeValue(4, 11) = gp_Pnt(+97.44994659335081600000, +0.71342262156961334000, -83.27482261755635300000); + aWeights.ChangeValue(4, 12) = +0.99420071368291341000; + aPoles.ChangeValue(4, 12) = gp_Pnt(+94.19554253170841200000, +0.71373172711717636000, -84.53069694549194000000); + aWeights.ChangeValue(4, 13) = +0.99419840439350793000; + aPoles.ChangeValue(4, 13) = gp_Pnt(+90.92433917217061900000, +0.71402231445757036000, -85.74211902365664200000); + aWeights.ChangeValue(4, 14) = +0.99419634212229768000; + aPoles.ChangeValue(4, 14) = gp_Pnt(+87.63705473050230000000, +0.71428182289044062000, -86.90884124933938900000); + aWeights.ChangeValue(4, 15) = +0.99419431112670464000; + aPoles.ChangeValue(4, 15) = gp_Pnt(+84.33436439436984200000, +0.71453739893908408000, -88.03058362353205300000); + aWeights.ChangeValue(4, 16) = +0.99418875003915341000; + aPoles.ChangeValue(4, 16) = gp_Pnt(+74.38231313217285400000, +0.71523720648163680000, -91.26025430410756200000); + aWeights.ChangeValue(4, 17) = +0.99418554160984429000; + aPoles.ChangeValue(4, 17) = gp_Pnt(+67.68910051798944500000, +0.71564096751482986000, -93.23244050128337800000); + aWeights.ChangeValue(4, 18) = +0.99418277570171931000; + aPoles.ChangeValue(4, 18) = gp_Pnt(+60.94265918181897500000, +0.71598904839509359000, -95.02180567308657500000); + aWeights.ChangeValue(4, 19) = +0.99418039790864621000; + aPoles.ChangeValue(4, 19) = gp_Pnt(+54.14855416044807900000, +0.71628829211206946000, -96.62671289123449000000); + aWeights.ChangeValue(4, 20) = +0.99417836479981814000; + aPoles.ChangeValue(4, 20) = gp_Pnt(+47.31263275511362600000, +0.71654416141740851000, -98.04576467050098600000); + aWeights.ChangeValue(4, 21) = +0.99417664391975691000; + aPoles.ChangeValue(4, 21) = gp_Pnt(+40.44102486854357200000, +0.71676073875086976000, -99.27780280738555500000); + aWeights.ChangeValue(4, 22) = +0.99417521378830997000; + aPoles.ChangeValue(4, 22) = gp_Pnt(+33.54014335198198900000, +0.71694072618465221000, -100.32190824729783000000); + aWeights.ChangeValue(4, 23) = +0.99417291266204433000; + aPoles.ChangeValue(4, 23) = gp_Pnt(+19.69298272358705000000, +0.71723033475882103000, -102.03287833894613000000); + aWeights.ChangeValue(4, 24) = +0.99417203636017570000; + aPoles.ChangeValue(4, 24) = gp_Pnt(+12.74619890889187300000, +0.71734062296661449000, -102.69970663658552000000); + aWeights.ChangeValue(4, 25) = +0.99417141958182476000; + aPoles.ChangeValue(4, 25) = gp_Pnt(+5.78245043030823250000, +0.71741824902277995000, -103.17717197796689000000); + aWeights.ChangeValue(4, 26) = +0.99417105170022846000; + aPoles.ChangeValue(4, 26) = gp_Pnt(-1.19217909208406270000, +0.71746454980293017000, -103.46478315098152000000); + aWeights.ChangeValue(4, 27) = +0.99417092687508068000; + aPoles.ChangeValue(4, 27) = gp_Pnt(-8.17163978203099180000, +0.71748026003105458000, -103.56227159755184000000); + aWeights.ChangeValue(4, 28) = +0.99417104405253187000; + aPoles.ChangeValue(4, 28) = gp_Pnt(-15.14991535484593800000, +0.71746551227361877000, -103.46959139663633000000); + aWeights.ChangeValue(4, 29) = +0.99417140696519068000; + aPoles.ChangeValue(4, 29) = gp_Pnt(-22.12102296425817400000, +0.71741983693815459000, -103.18691926012113000000); + aWeights.ChangeValue(4, 30) = +0.99417264018315676000; + aPoles.ChangeValue(4, 30) = gp_Pnt(-36.03699423807252300000, +0.71726462804712465000, -102.24239043165372000000); + aWeights.ChangeValue(4, 31) = +0.99417351313460955000; + aPoles.ChangeValue(4, 31) = gp_Pnt(-42.98185258768797500000, +0.71715476185170723000, -101.58053487832193000000); + aWeights.ChangeValue(4, 32) = +0.99417464796983568000; + aPoles.ChangeValue(4, 32) = gp_Pnt(-49.90763755490115700000, +0.71701193671091712000, -100.72948788576410000000); + aWeights.ChangeValue(4, 33) = +0.99417605745995530000; + aPoles.ChangeValue(4, 33) = gp_Pnt(-56.80843390632649900000, +0.71683454604177377000, -99.68987236817491700000); + aWeights.ChangeValue(4, 34) = +0.99417776216385467000; + aPoles.ChangeValue(4, 34) = gp_Pnt(-63.67836146608049600000, +0.71662000367742562000, -98.46253420440308400000); + aWeights.ChangeValue(4, 35) = +0.99417979042818705000; + aPoles.ChangeValue(4, 35) = gp_Pnt(-70.51157486810592400000, +0.71636474389607163000, -97.04854231351581000000); + aWeights.ChangeValue(4, 36) = +0.99418217838737100000; + aPoles.ChangeValue(4, 36) = gp_Pnt(-77.30226331485057800000, +0.71606422146024096000, -95.44918875092946600000); + aWeights.ChangeValue(4, 37) = +0.99418626551507883000; + aPoles.ChangeValue(4, 37) = gp_Pnt(-87.17503156127875700000, +0.71554987190288122000, -92.83807781738744300000); + aWeights.ChangeValue(4, 38) = +0.99418765014289556000; + aPoles.ChangeValue(4, 38) = gp_Pnt(-90.29499963358738100000, +0.71537562386381059000, -91.97053762881716900000); + aWeights.ChangeValue(4, 39) = +0.99418912751868260000; + aPoles.ChangeValue(4, 39) = gp_Pnt(-93.40397633478176000000, +0.71518970580821706000, -91.06351986664817800000); + aWeights.ChangeValue(4, 40) = +0.99419070264287346000; + aPoles.ChangeValue(4, 40) = gp_Pnt(-96.50138523104767800000, +0.71499148886670094000, -90.11718659777564300000); + aWeights.ChangeValue(4, 41) = +0.99419238184469383000; + aPoles.ChangeValue(4, 41) = gp_Pnt(-99.58665166110419900000, +0.71478017704711161000, -89.13171035602891800000); + aWeights.ChangeValue(4, 42) = +0.99419417278216393000; + aPoles.ChangeValue(4, 42) = gp_Pnt(-102.65920271683186000000, +0.71455480723882170000, -88.10727415073346000000); + aWeights.ChangeValue(4, 43) = +0.99419608444209617000; + aPoles.ChangeValue(4, 43) = gp_Pnt(-105.71846722422283000000, +0.71431424921765596000, -87.04407147601585800000); + aWeights.ChangeValue(4, 44) = +0.99420030141669824000; + aPoles.ChangeValue(4, 44) = gp_Pnt(-112.04353021881408000000, +0.71378360593609291000, -84.75579106017932000000); + aWeights.ChangeValue(4, 45) = +0.99420274455295243000; + aPoles.ChangeValue(4, 45) = gp_Pnt(-115.30712351688430000000, +0.71347617951477893000, -83.52457168950516600000); + aWeights.ChangeValue(4, 46) = +0.99420507969516914000; + aPoles.ChangeValue(4, 46) = gp_Pnt(-118.55391065270935000000, +0.71318234625457844000, -82.24884224143599500000); + aWeights.ChangeValue(4, 47) = +0.99420795946419460000; + aPoles.ChangeValue(4, 47) = gp_Pnt(-121.78323693095153000000, +0.71281998990170370000, -80.92897147787398600000); + aWeights.ChangeValue(4, 48) = +0.99421073394729520000; + aPoles.ChangeValue(4, 48) = gp_Pnt(-124.99434061394447000000, +0.71247088780699119000, -79.56513754354314500000); + aWeights.ChangeValue(4, 49) = +0.99421382643715051000; + aPoles.ChangeValue(4, 49) = gp_Pnt(-128.18654935306802000000, +0.71208178090166396000, -78.15770189412481300000); + aWeights.ChangeValue(4, 50) = +0.99421719652005114000; + aPoles.ChangeValue(4, 50) = gp_Pnt(-131.35915951555538000000, +0.71165775668839981000, -76.70696466864815500000); + aWeights.ChangeValue(4, 51) = +0.99422402375653052000; + aPoles.ChangeValue(4, 51) = gp_Pnt(-137.43857370930490000000, +0.71079877890710363000, -73.82620311743470200000); + aWeights.ChangeValue(4, 52) = +0.99422797768691740000; + aPoles.ChangeValue(4, 52) = gp_Pnt(-140.34822128390073000000, +0.71030132584778982000, -72.40218284379008700000); + aWeights.ChangeValue(4, 53) = +0.99423084075610579000; + aPoles.ChangeValue(4, 53) = gp_Pnt(-143.23968120103163000000, +0.70994112075449667000, -70.94115847846593700000); + aWeights.ChangeValue(4, 54) = +0.99423623706224973000; + aPoles.ChangeValue(4, 54) = gp_Pnt(-146.11271315064005000000, +0.70926223398833632000, -69.44395856663618400000); + aWeights.ChangeValue(4, 55) = +0.99423948964319253000; + aPoles.ChangeValue(4, 55) = gp_Pnt(-148.96636467875118000000, +0.70885305306993507000, -67.91012785943519200000); + aWeights.ChangeValue(4, 56) = +0.99424477127021760000; + aPoles.ChangeValue(4, 56) = gp_Pnt(-151.80041102174371000000, +0.70818863107582075000, -66.34061951491401000000); + aWeights.ChangeValue(4, 57) = +0.99424976912431906000; + aPoles.ChangeValue(4, 57) = gp_Pnt(-154.61412826195317000000, +0.70755993553172780000, -64.73535576374381200000); + aWeights.ChangeValue(4, 58) = +0.99426106692542415000; + aPoles.ChangeValue(4, 58) = gp_Pnt(-160.41462700323274000000, +0.70613881146866808000, -61.32785485541679500000); + aWeights.ChangeValue(4, 59) = +0.99426869485276259000; + aPoles.ChangeValue(4, 59) = gp_Pnt(-163.39874797129167000000, +0.70517937516238605000, -59.52109641918814000000); + aWeights.ChangeValue(4, 60) = +0.99427273335051769000; + aPoles.ChangeValue(4, 60) = gp_Pnt(-166.35588428707737000000, +0.70467140031138198000, -57.67014968010805400000); + aWeights.ChangeValue(4, 61) = +0.99428524121150996000; + aPoles.ChangeValue(4, 61) = gp_Pnt(-169.29147402675417000000, +0.70309833118760823000, -55.78569706052214600000); + aWeights.ChangeValue(4, 62) = +0.99428879891231192000; + aPoles.ChangeValue(4, 62) = gp_Pnt(-172.19641321622018000000, +0.70265088960130029000, -53.85463096447261900000); + aWeights.ChangeValue(4, 63) = +0.99430150819260854000; + aPoles.ChangeValue(4, 63) = gp_Pnt(-175.07684836851479000000, +0.70105264832187786000, -51.88726956537038900000); + aWeights.ChangeValue(4, 64) = +0.99431053021705873000; + aPoles.ChangeValue(4, 64) = gp_Pnt(-177.92932492963632000000, +0.69991818857623234000, -49.88000737868681300000); + aWeights.ChangeValue(4, 65) = +0.99432262020918794000; + aPoles.ChangeValue(4, 65) = gp_Pnt(-180.75433885652521000000, +0.69839807993520564000, -47.83460859504128800000); + aWeights.ChangeValue(4, 66) = +0.99433338093448842000; + aPoles.ChangeValue(4, 66) = gp_Pnt(-183.37745173242254000000, +0.69704510882650861000, -45.93530736698277700000); + aWeights.ChangeValue(4, 67) = +0.99434840096468768000; + aPoles.ChangeValue(4, 67) = gp_Pnt(-185.97711214268182000000, +0.69515696483250133000, -44.00334265992864100000); + aWeights.ChangeValue(4, 68) = +0.99435212441487342000; + aPoles.ChangeValue(4, 68) = gp_Pnt(-188.55092060214918000000, +0.69468843290184534000, -42.03706245316480100000); + aWeights.ChangeValue(4, 69) = +0.99438632495837886000; + aPoles.ChangeValue(4, 69) = gp_Pnt(-191.10351948864678000000, +0.69039032514405918000, -40.04240176159244400000); + aWeights.ChangeValue(4, 70) = +0.99437474610357146000; + aPoles.ChangeValue(4, 70) = gp_Pnt(-193.62512272227769000000, +0.69184483548244469000, -38.00925246210125900000); + aWeights.ChangeValue(4, 71) = +0.99442029730057158000; + aPoles.ChangeValue(4, 71) = gp_Pnt(-196.12715745709386000000, +0.68612074693666814000, -35.95207510226987300000); + aWeights.ChangeValue(4, 72) = +0.99443382321708784000; + aPoles.ChangeValue(4, 72) = gp_Pnt(-198.59871781224271000000, +0.68442148883790921000, -33.85842837168388500000); + aWeights.ChangeValue(4, 73) = +0.99445918644353237000; + aPoles.ChangeValue(4, 73) = gp_Pnt(-201.04387700918369000000, +0.68123533540985159000, -31.73471330438436400000); + aWeights.ChangeValue(4, 74) = +0.99447784672499884000; + aPoles.ChangeValue(4, 74) = gp_Pnt(-203.48830197003542000000, +0.67889067518118906000, -29.61036197082074800000); + aWeights.ChangeValue(4, 75) = +0.99454111417144087000; + aPoles.ChangeValue(4, 75) = gp_Pnt(-205.90905874701556000000, +0.67094847421818948000, -27.45911353863423800000); + aWeights.ChangeValue(4, 76) = +0.99445650432969468000; + aPoles.ChangeValue(4, 76) = gp_Pnt(-208.28851122415659000000, +0.68156618053615436000, -25.25989914496455000000); + aWeights.ChangeValue(4, 77) = +0.99472383917628937000; + aPoles.ChangeValue(4, 77) = gp_Pnt(-210.66819860636727000000, +0.64801004101885640000, -23.06997485052475800000); + aWeights.ChangeValue(4, 78) = +0.99465154011060308000; + aPoles.ChangeValue(4, 78) = gp_Pnt(-212.99829629837927000000, +0.65709020698928045000, -20.81293704958459000000); + aWeights.ChangeValue(4, 79) = +0.99469225299704522000; + aPoles.ChangeValue(4, 79) = gp_Pnt(-215.28778722004142000000, +0.65198647566642243000, -18.52648999480212300000); + aWeights.ChangeValue(4, 80) = +0.99473072608314816000; + aPoles.ChangeValue(4, 80) = gp_Pnt(-217.56233176434088000000, +0.64714607636795729000, -16.22125679272672700000); + aWeights.ChangeValue(4, 81) = +0.99492849872148770000; + aPoles.ChangeValue(4, 81) = gp_Pnt(-219.81591407133737000000, +0.62237708094437050000, -13.90082269618381800000); + aWeights.ChangeValue(5, 1) = +0.99802424639217535000; + aPoles.ChangeValue(5, 1) = gp_Pnt(+132.45622778603641000000, +0.24240580374773624000, -67.51941232824347600000); + aWeights.ChangeValue(5, 2) = +0.99802234515930366000; + aPoles.ChangeValue(5, 2) = gp_Pnt(+129.39621499227619000000, +0.24264599956164210000, -69.20932849809996400000); + aWeights.ChangeValue(5, 3) = +0.99802076064199163000; + aPoles.ChangeValue(5, 3) = gp_Pnt(+126.31320722587012000000, +0.24284620475411531000, -70.85757023346207000000); + aWeights.ChangeValue(5, 4) = +0.99801949820656444000; + aPoles.ChangeValue(5, 4) = gp_Pnt(+123.20785947444472000000, +0.24300571706284735000, -72.46379895615213200000); + aWeights.ChangeValue(5, 5) = +0.99801796211084626000; + aPoles.ChangeValue(5, 5) = gp_Pnt(+120.08075545981777000000, +0.24319982314295371000, -74.02745916652884300000); + aWeights.ChangeValue(5, 6) = +0.99801651211139986000; + aPoles.ChangeValue(5, 6) = gp_Pnt(+116.93263892914923000000, +0.24338306180645181000, -75.54835063375608700000); + aWeights.ChangeValue(5, 7) = +0.99801547938007906000; + aPoles.ChangeValue(5, 7) = gp_Pnt(+113.76425167349765000000, +0.24351357797625062000, -77.02627451676777100000); + aWeights.ChangeValue(5, 8) = +0.99801427699593348000; + aPoles.ChangeValue(5, 8) = gp_Pnt(+110.57618061475338000000, +0.24366553774363486000, -78.46071663606139200000); + aWeights.ChangeValue(5, 9) = +0.99801219521177365000; + aPoles.ChangeValue(5, 9) = gp_Pnt(+104.16217613984874000000, +0.24392865233284403000, -81.24228081548614000000); + aWeights.ChangeValue(5, 10) = +0.99801119017243534000; + aPoles.ChangeValue(5, 10) = gp_Pnt(+100.93622072836907000000, +0.24405568433254640000, -82.58935804874866400000); + aWeights.ChangeValue(5, 11) = +0.99801030363411136000; + aPoles.ChangeValue(5, 11) = gp_Pnt(+97.69202612265307600000, +0.24416774311013159000, -83.89246252379766100000); + aWeights.ChangeValue(5, 12) = +0.99800944410126124000; + aPoles.ChangeValue(5, 12) = gp_Pnt(+94.43027249107268500000, +0.24427639255629080000, -85.15127753548810600000); + aWeights.ChangeValue(5, 13) = +0.99800863606905588000; + aPoles.ChangeValue(5, 13) = gp_Pnt(+91.15167507122404800000, +0.24437853537532742000, -86.36553541507953500000); + aWeights.ChangeValue(5, 14) = +0.99800791446282866000; + aPoles.ChangeValue(5, 14) = gp_Pnt(+87.85695090009397700000, +0.24446975628264125000, -87.53498464352057300000); + aWeights.ChangeValue(5, 15) = +0.99800720379704511000; + aPoles.ChangeValue(5, 15) = gp_Pnt(+84.54678770958248900000, +0.24455959646371978000, -88.65934979276558200000); + aWeights.ChangeValue(5, 16) = +0.99800525790220262000; + aPoles.ChangeValue(5, 16) = gp_Pnt(+74.57222162875666500000, +0.24480559775636487000, -91.89655746079053200000); + aWeights.ChangeValue(5, 17) = +0.99800413521623044000; + aPoles.ChangeValue(5, 17) = gp_Pnt(+67.86385477996348900000, +0.24494753702776123000, -93.87334138726605200000); + aWeights.ChangeValue(5, 18) = +0.99800316736440708000; + aPoles.ChangeValue(5, 18) = gp_Pnt(+61.10212188651380700000, +0.24506990714535715000, -95.66687639706128700000); + aWeights.ChangeValue(5, 19) = +0.99800233531441618000; + aPoles.ChangeValue(5, 19) = gp_Pnt(+54.29260355218377000000, +0.24517511152453569000, -97.27552257290322800000); + aWeights.ChangeValue(5, 20) = +0.99800162387306812000; + aPoles.ChangeValue(5, 20) = gp_Pnt(+47.44116356008504500000, +0.24526506890417449000, -98.69787956398771200000); + aWeights.ChangeValue(5, 21) = +0.99800102168629923000; + aPoles.ChangeValue(5, 21) = gp_Pnt(+40.55394899036769400000, +0.24534121333759545000, -99.93278652962781900000); + aWeights.ChangeValue(5, 22) = +0.99800052123917249000; + aPoles.ChangeValue(5, 22) = gp_Pnt(+33.63739034141031700000, +0.24540449418574758000, -100.97932209286283000000); + aWeights.ChangeValue(5, 23) = +0.99799971600020576000; + aPoles.ChangeValue(5, 23) = gp_Pnt(+19.75877904385457000000, +0.24550631764576064000, -102.69427034587730000000); + aWeights.ChangeValue(5, 24) = +0.99799940935225595000; + aPoles.ChangeValue(5, 24) = gp_Pnt(+12.79621461719473900000, +0.24554509442498113000, -103.36264862290150000000); + aWeights.ChangeValue(5, 25) = +0.99799919351964361000; + aPoles.ChangeValue(5, 25) = gp_Pnt(+5.81664173483571470000, +0.24557238768930081000, -103.84122357926364000000); + aWeights.ChangeValue(5, 26) = +0.99799906478454914000; + aPoles.ChangeValue(5, 26) = gp_Pnt(-1.17384006705611750000, +0.24558866712534574000, -104.12950288114470000000); + aWeights.ChangeValue(5, 27) = +0.99799902110371452000; + aPoles.ChangeValue(5, 27) = gp_Pnt(-8.16916502467035950000, +0.24559419086566145000, -104.22721740658889000000); + aWeights.ChangeValue(5, 28) = +0.99799906210844525000; + aPoles.ChangeValue(5, 28) = gp_Pnt(-15.16330109337111900000, +0.24558900548798951000, -104.13432123956672000000); + aWeights.ChangeValue(5, 29) = +0.99799918910460916000; + aPoles.ChangeValue(5, 29) = gp_Pnt(-22.15024989420349800000, +0.24557294601509544000, -103.85099166853988000000); + aWeights.ChangeValue(5, 30) = +0.99799962065035952000; + aPoles.ChangeValue(5, 30) = gp_Pnt(-36.09784025928350100000, +0.24551837507724711000, -102.90426687944763000000); + aWeights.ChangeValue(5, 31) = +0.99799992612548860000; + aPoles.ChangeValue(5, 31) = gp_Pnt(-43.05848024708384300000, +0.24547974681812620000, -102.24087223758063000000); + aWeights.ChangeValue(5, 32) = +0.99800032324181287000; + aPoles.ChangeValue(5, 32) = gp_Pnt(-50.00000136683811300000, +0.24542953068576923000, -101.38784584473753000000); + aWeights.ChangeValue(5, 33) = +0.99800081646744143000; + aPoles.ChangeValue(5, 33) = gp_Pnt(-56.91647304260395400000, +0.24536716218422927000, -100.34581179308852000000); + aWeights.ChangeValue(5, 34) = +0.99800141299480460000; + aPoles.ChangeValue(5, 34) = gp_Pnt(-63.80199929133657100000, +0.24529173277606747000, -99.11561770524215800000); + aWeights.ChangeValue(5, 35) = +0.99800212274065292000; + aPoles.ChangeValue(5, 35) = gp_Pnt(-70.65071863638867500000, +0.24520198988589620000, -97.69833476064030700000); + aWeights.ChangeValue(5, 36) = +0.99800295834605834000; + aPoles.ChangeValue(5, 36) = gp_Pnt(-77.45680402323041800000, +0.24509633690518939000, -96.09525772913629300000); + aWeights.ChangeValue(5, 37) = +0.99800438851665707000; + aPoles.ChangeValue(5, 37) = gp_Pnt(-87.35194268844766400000, +0.24491551610541196000, -93.47806376363495000000); + aWeights.ChangeValue(5, 38) = +0.99800487302440644000; + aPoles.ChangeValue(5, 38) = gp_Pnt(-90.47898339307414500000, +0.24485425955861742000, -92.60850028621504700000); + aWeights.ChangeValue(5, 39) = +0.99800538998403221000; + aPoles.ChangeValue(5, 39) = gp_Pnt(-93.59500505694055100000, +0.24478890139349116000, -91.69936647202810300000); + aWeights.ChangeValue(5, 40) = +0.99800594114472096000; + aPoles.ChangeValue(5, 40) = gp_Pnt(-96.69942959625443300000, +0.24471922075774133000, -90.75082469114758500000); + aWeights.ChangeValue(5, 41) = +0.99800652872047502000; + aPoles.ChangeValue(5, 41) = gp_Pnt(-99.79168063143930600000, +0.24464493811196314000, -89.76304779373697300000); + aWeights.ChangeValue(5, 42) = +0.99800715539011187000; + aPoles.ChangeValue(5, 42) = gp_Pnt(-102.87118348036965000000, +0.24456571523016235000, -88.73621911304020700000); + aWeights.ChangeValue(5, 43) = +0.99800782429726465000; + aPoles.ChangeValue(5, 43) = gp_Pnt(-105.93736515171811000000, +0.24448115520035879000, -87.67053246863201800000); + aWeights.ChangeValue(5, 44) = +0.99800929984371112000; + aPoles.ChangeValue(5, 44) = gp_Pnt(-112.27672847568951000000, +0.24429462970498794000, -85.37690123862388700000); + aWeights.ChangeValue(5, 45) = +0.99801015470633669000; + aPoles.ChangeValue(5, 45) = gp_Pnt(-115.54769755356581000000, +0.24418656943131900000, -84.14279592325505100000); + aWeights.ChangeValue(5, 46) = +0.99801097177455889000; + aPoles.ChangeValue(5, 46) = gp_Pnt(-118.80182311076892000000, +0.24408328894344730000, -82.86408351153079400000); + aWeights.ChangeValue(5, 47) = +0.99801197940129383000; + aPoles.ChangeValue(5, 47) = gp_Pnt(-122.03843417449148000000, +0.24395592759703674000, -81.54111184389478200000); + aWeights.ChangeValue(5, 48) = +0.99801295017559344000; + aPoles.ChangeValue(5, 48) = gp_Pnt(-125.25678060282321000000, +0.24383322797751039000, -80.17408187890907800000); + aWeights.ChangeValue(5, 49) = +0.99801403221073270000; + aPoles.ChangeValue(5, 49) = gp_Pnt(-128.45617956663568000000, +0.24369647262362162000, -78.76334161483092100000); + aWeights.ChangeValue(5, 50) = +0.99801521135655380000; + aPoles.ChangeValue(5, 50) = gp_Pnt(-131.63592529803751000000, +0.24354745092247693000, -77.30919404502431300000); + aWeights.ChangeValue(5, 51) = +0.99801760008187401000; + aPoles.ChangeValue(5, 51) = gp_Pnt(-137.72900951211963000000, +0.24324557860805471000, -74.42165429070698200000); + aWeights.ChangeValue(5, 52) = +0.99801898346970708000; + aPoles.ChangeValue(5, 52) = gp_Pnt(-140.64518873661288000000, +0.24307076523393223000, -72.99426192178911800000); + aWeights.ChangeValue(5, 53) = +0.99801998518786039000; + aPoles.ChangeValue(5, 53) = gp_Pnt(-143.54316005505726000000, +0.24294418386170585000, -71.52981926220020600000); + aWeights.ChangeValue(5, 54) = +0.99802187318168345000; + aPoles.ChangeValue(5, 54) = gp_Pnt(-146.42260629144496000000, +0.24270562978064991000, -70.02903356238938700000); + aWeights.ChangeValue(5, 55) = +0.99802301113888081000; + aPoles.ChangeValue(5, 55) = gp_Pnt(-149.28266198929455000000, +0.24256185427332766000, -68.49161271016626500000); + aWeights.ChangeValue(5, 56) = +0.99802485896051119000; + aPoles.ChangeValue(5, 56) = gp_Pnt(-152.12302992679020000000, +0.24232840183433180000, -66.91836178765569800000); + aWeights.ChangeValue(5, 57) = +0.99802660746095961000; + aPoles.ChangeValue(5, 57) = gp_Pnt(-154.94301695331424000000, +0.24210751871096883000, -65.30929034698890200000); + aWeights.ChangeValue(5, 58) = +0.99803055992501044000; + aPoles.ChangeValue(5, 58) = gp_Pnt(-160.75642720778953000000, +0.24160825342055195000, -61.89368007550259400000); + aWeights.ChangeValue(5, 59) = +0.99803322842160846000; + aPoles.ChangeValue(5, 59) = gp_Pnt(-163.74717060555361000000, +0.24127121961594802000, -60.08255013672670200000); + aWeights.ChangeValue(5, 60) = +0.99803464125717123000; + aPoles.ChangeValue(5, 60) = gp_Pnt(-166.71086689375946000000, +0.24109275824918924000, -58.22731479955884700000); + aWeights.ChangeValue(5, 61) = +0.99803901668628470000; + aPoles.ChangeValue(5, 61) = gp_Pnt(-169.65297207222594000000, +0.24054025241076704000, -56.33806928337021700000); + aWeights.ChangeValue(5, 62) = +0.99804026123435818000; + aPoles.ChangeValue(5, 62) = gp_Pnt(-172.56427255537395000000, +0.24038308942389072000, -54.40260496408483000000); + aWeights.ChangeValue(5, 63) = +0.99804470691060532000; + aPoles.ChangeValue(5, 63) = gp_Pnt(-175.45101016300779000000, +0.23982181928534163000, -52.43032166263763100000); + aWeights.ChangeValue(5, 64) = +0.99804786265202527000; + aPoles.ChangeValue(5, 64) = gp_Pnt(-178.30970270493245000000, +0.23942347201733374000, -50.41823769283568900000); + aWeights.ChangeValue(5, 65) = +0.99805209132460959000; + aPoles.ChangeValue(5, 65) = gp_Pnt(-181.14080917168710000000, +0.23888978094458979000, -48.36782293133622100000); + aWeights.ChangeValue(5, 66) = +0.99805585511722006000; + aPoles.ChangeValue(5, 66) = gp_Pnt(-183.76963089028271000000, +0.23841474156011525000, -46.46384963887197700000); + aWeights.ChangeValue(5, 67) = +0.99806110806389992000; + aPoles.ChangeValue(5, 67) = gp_Pnt(-186.37480135254410000000, +0.23775204017864099000, -44.52702607060874100000); + aWeights.ChangeValue(5, 68) = +0.99806241123039841000; + aPoles.ChangeValue(5, 68) = gp_Pnt(-188.95443339023049000000, +0.23758721013871806000, -42.55611011320790700000); + aWeights.ChangeValue(5, 69) = +0.99807437025022461000; + aPoles.ChangeValue(5, 69) = gp_Pnt(-191.51185439080101000000, +0.23607937004601673000, -40.55588840407725800000); + aWeights.ChangeValue(5, 70) = +0.99807032269304363000; + aPoles.ChangeValue(5, 70) = gp_Pnt(-194.03956238778505000000, +0.23658914396266717000, -38.51843887702921200000); + aWeights.ChangeValue(5, 71) = +0.99808625039358922000; + aPoles.ChangeValue(5, 71) = gp_Pnt(-196.54607703546344000000, +0.23458111537982981000, -36.45513422497234800000); + aWeights.ChangeValue(5, 72) = +0.99809097922833689000; + aPoles.ChangeValue(5, 72) = gp_Pnt(-199.02284030117690000000, +0.23398526561785285000, -34.35633603568415100000); + aWeights.ChangeValue(5, 73) = +0.99809984631895676000; + aPoles.ChangeValue(5, 73) = gp_Pnt(-201.47284391020807000000, +0.23286808083306546000, -32.22700780168109700000); + aWeights.ChangeValue(5, 74) = +0.99810637147739267000; + aPoles.ChangeValue(5, 74) = gp_Pnt(-203.92239692899503000000, +0.23204542949601353000, -30.09717639714928000000); + aWeights.ChangeValue(5, 75) = +0.99812847998973830000; + aPoles.ChangeValue(5, 75) = gp_Pnt(-206.34684289021220000000, +0.22926391512904498000, -27.93902362306789300000); + aWeights.ChangeValue(5, 76) = +0.99809892249694432000; + aPoles.ChangeValue(5, 76) = gp_Pnt(-208.73420674519565000000, +0.23297935369059405000, -25.73750919512989600000); + aWeights.ChangeValue(5, 77) = +0.99819234539430379000; + aPoles.ChangeValue(5, 77) = gp_Pnt(-211.11258262007470000000, +0.22122441504945897000, -23.53328220960779800000); + aWeights.ChangeValue(5, 78) = +0.99816706733442118000; + aPoles.ChangeValue(5, 78) = gp_Pnt(-213.44890831521380000000, +0.22441150695403267000, -21.27426418813643800000); + aWeights.ChangeValue(5, 79) = +0.99818127777024523000; + aPoles.ChangeValue(5, 79) = gp_Pnt(-215.74298068197336000000, +0.22262736656649654000, -18.98075706196405200000); + aWeights.ChangeValue(5, 80) = +0.99819475509184485000; + aPoles.ChangeValue(5, 80) = gp_Pnt(-218.02209738817496000000, +0.22092240555297402000, -16.66880151580776100000); + aWeights.ChangeValue(5, 81) = +0.99826376750413803000; + aPoles.ChangeValue(5, 81) = gp_Pnt(-220.27506837008727000000, +0.21227676902692139000, -14.33587171753685400000); + aWeights.ChangeValue(6, 1) = +1.00955713824395920000; + aPoles.ChangeValue(6, 1) = gp_Pnt(+132.82497533600920000000, -0.00000000000000355271, -68.18672206105269100000); + aWeights.ChangeValue(6, 2) = +1.00956608612165510000; + aPoles.ChangeValue(6, 2) = gp_Pnt(+129.75720107675980000000, -0.00000000000001501048, -69.88134023490506800000); + aWeights.ChangeValue(6, 3) = +1.00957354292813720000; + aPoles.ChangeValue(6, 3) = gp_Pnt(+126.66630562875893000000, +0.00000000000001468880, -71.53414324810810900000); + aWeights.ChangeValue(6, 4) = +1.00957948395969920000; + aPoles.ChangeValue(6, 4) = gp_Pnt(+123.55299204973852000000, -0.00000000000002420214, -73.14476521965842400000); + aWeights.ChangeValue(6, 5) = +1.00958671248272540000; + aPoles.ChangeValue(6, 5) = gp_Pnt(+120.41786571412476000000, +0.00000000000000774289, -74.71276629883676900000); + aWeights.ChangeValue(6, 6) = +1.00959353559449030000; + aPoles.ChangeValue(6, 6) = gp_Pnt(+117.26165038381876000000, +0.00000000000002827238, -76.23787924846354300000); + aWeights.ChangeValue(6, 7) = +1.00959839503053540000; + aPoles.ChangeValue(6, 7) = gp_Pnt(+114.08506189168672000000, -0.00000000000002567399, -77.71984701658058700000); + aWeights.ChangeValue(6, 8) = +1.00960405269295440000; + aPoles.ChangeValue(6, 8) = gp_Pnt(+110.88875430250306000000, +0.00000000000001531652, -79.15824703626482500000); + aWeights.ChangeValue(6, 9) = +1.00961384794965610000; + aPoles.ChangeValue(6, 9) = gp_Pnt(+104.45816547225203000000, +0.00000000000002372811, -81.94743615023858800000); + aWeights.ChangeValue(6, 10) = +1.00961857675613920000; + aPoles.ChangeValue(6, 10) = gp_Pnt(+101.22387341781818000000, -0.00000000000003253030, -83.29820264563102200000); + aWeights.ChangeValue(6, 11) = +1.00962274789490230000; + aPoles.ChangeValue(6, 11) = gp_Pnt(+97.97127406275538400000, +0.00000000000002165813, -84.60486564781918200000); + aWeights.ChangeValue(6, 12) = +1.00962679188945900000; + aPoles.ChangeValue(6, 12) = gp_Pnt(+94.70106106239124700000, +0.00000000000003307844, -85.86712155505158300000); + aWeights.ChangeValue(6, 13) = +1.00963059350859920000; + aPoles.ChangeValue(6, 13) = gp_Pnt(+91.41394873512904000000, -0.00000000000001002370, -87.08469757155246800000); + aWeights.ChangeValue(6, 14) = +1.00963398843787310000; + aPoles.ChangeValue(6, 14) = gp_Pnt(+88.11065082060795800000, -0.00000000000001620026, -88.25733602781997400000); + aWeights.ChangeValue(6, 15) = +1.00963733185343440000; + aPoles.ChangeValue(6, 15) = gp_Pnt(+84.79187377942922400000, +0.00000000000001387836, -89.38476986722990600000); + aWeights.ChangeValue(6, 16) = +1.00964648640037490000; + aPoles.ChangeValue(6, 16) = gp_Pnt(+74.79138897281484300000, +0.00000000000001147648, -92.63077806554609600000); + aWeights.ChangeValue(6, 17) = +1.00965176794147980000; + aPoles.ChangeValue(6, 17) = gp_Pnt(+68.06556894151637500000, +0.00000000000001348105, -94.61292925638954900000); + aWeights.ChangeValue(6, 18) = +1.00965632094816880000; + aPoles.ChangeValue(6, 18) = gp_Pnt(+61.28620656548358900000, +0.00000000000001132208, -96.41133393799678700000); + aWeights.ChangeValue(6, 19) = +1.00966023501695920000; + aPoles.ChangeValue(6, 19) = gp_Pnt(+54.45890525472331200000, +0.00000000000000779610, -98.02434736777235000000); + aWeights.ChangeValue(6, 20) = +1.00966358166845540000; + aPoles.ChangeValue(6, 20) = gp_Pnt(+47.58955228763309700000, +0.00000000000000496426, -99.45056478986435900000); + aWeights.ChangeValue(6, 21) = +1.00966641434734750000; + aPoles.ChangeValue(6, 21) = gp_Pnt(+40.68431826182812500000, +0.00000000000000415229, -100.68882169811890000000); + aWeights.ChangeValue(6, 22) = +1.00966876842241240000; + aPoles.ChangeValue(6, 22) = gp_Pnt(+33.74965652868991100000, +0.00000000000000595055, -101.73819405254569000000); + aWeights.ChangeValue(6, 23) = +1.00967255617655690000; + aPoles.ChangeValue(6, 23) = gp_Pnt(+19.83474481990451800000, +0.00000000000000626687, -103.45778313292877000000); + aWeights.ChangeValue(6, 24) = +1.00967399859793900000; + aPoles.ChangeValue(6, 24) = gp_Pnt(+12.85396744583563800000, +0.00000000000000961706, -104.12796934503771000000); + aWeights.ChangeValue(6, 25) = +1.00967501382969150000; + aPoles.ChangeValue(6, 25) = gp_Pnt(+5.85612456199985140000, +0.00000000000001451316, -104.60783896197547000000); + aWeights.ChangeValue(6, 26) = +1.00967561936958040000; + aPoles.ChangeValue(6, 26) = gp_Pnt(-1.15266320632332260000, +0.00000000000001739414, -104.89689790453474000000); + aWeights.ChangeValue(6, 27) = +1.00967582483410530000; + aPoles.ChangeValue(6, 27) = gp_Pnt(-8.16630892272242730000, +0.00000000000001688939, -104.99487618531697000000); + aWeights.ChangeValue(6, 28) = +1.00967563195849790000; + aPoles.ChangeValue(6, 28) = gp_Pnt(-15.17875958769639600000, +0.00000000000001381871, -104.90172793642448000000); + aWeights.ChangeValue(6, 29) = +1.00967503459672230000; + aPoles.ChangeValue(6, 29) = gp_Pnt(-22.18399638815323600000, +0.00000000000001119232, -104.61763141615558000000); + aWeights.ChangeValue(6, 30) = +1.00967300468446440000; + aPoles.ChangeValue(6, 30) = gp_Pnt(-36.16808769247344200000, +0.00000000000001926896, -103.66834538209933000000); + aWeights.ChangeValue(6, 31) = +1.00967156777535520000; + aPoles.ChangeValue(6, 31) = gp_Pnt(-43.14695215605046700000, +0.00000000000002086710, -103.00315490229345000000); + aWeights.ChangeValue(6, 32) = +1.00966969979090850000; + aPoles.ChangeValue(6, 32) = gp_Pnt(-50.10664482445217500000, +0.00000000000002115378, -102.14781821392242000000); + aWeights.ChangeValue(6, 33) = +1.00966737970297340000; + aPoles.ChangeValue(6, 33) = gp_Pnt(-57.04121502398449900000, +0.00000000000002158031, -101.10296070558179000000); + aWeights.ChangeValue(6, 34) = +1.00966457365849420000; + aPoles.ChangeValue(6, 34) = gp_Pnt(-63.94474533155499800000, +0.00000000000002290082, -99.86943240681669900000); + aWeights.ChangeValue(6, 35) = +1.00966123497950670000; + aPoles.ChangeValue(6, 35) = gp_Pnt(-70.81135197820185600000, +0.00000000000002517228, -98.44830786498150100000); + aWeights.ChangeValue(6, 36) = +1.00965730416314160000; + aPoles.ChangeValue(6, 36) = gp_Pnt(-77.63518524225725100000, +0.00000000000002775445, -96.84088598857995600000); + aWeights.ChangeValue(6, 37) = +1.00965057624219750000; + aPoles.ChangeValue(6, 37) = gp_Pnt(-87.55609990295042200000, +0.00000000000002423047, -94.21659328767886200000); + aWeights.ChangeValue(6, 38) = +1.00964829695753600000; + aPoles.ChangeValue(6, 38) = gp_Pnt(-90.69129861847109500000, +0.00000000000002587407, -93.34466557470412300000); + aWeights.ChangeValue(6, 39) = +1.00964586498085130000; + aPoles.ChangeValue(6, 39) = gp_Pnt(-93.81544408055053500000, +0.00000000000003006614, -92.43305897005754400000); + aWeights.ChangeValue(6, 40) = +1.00964327207695040000; + aPoles.ChangeValue(6, 40) = gp_Pnt(-96.92795589621758300000, +0.00000000000003388207, -91.48193626907418300000); + aWeights.ChangeValue(6, 41) = +1.00964050782223150000; + aPoles.ChangeValue(6, 41) = gp_Pnt(-100.02825520717420000000, +0.00000000000003564727, -90.49147079864104600000); + aWeights.ChangeValue(6, 42) = +1.00963755960468200000; + aPoles.ChangeValue(6, 42) = gp_Pnt(-103.11576472135789000000, +0.00000000000003493709, -89.46184640324143800000); + aWeights.ChangeValue(6, 43) = +1.00963441262388120000; + aPoles.ChangeValue(6, 43) = gp_Pnt(-106.18990874397944000000, +0.00000000000003257692, -88.39325742978746800000); + aWeights.ChangeValue(6, 44) = +1.00962747055172470000; + aPoles.ChangeValue(6, 44) = gp_Pnt(-112.54574015681582000000, +0.00000000000006160655, -86.09336936272072200000); + aWeights.ChangeValue(6, 45) = +1.00962344856191890000; + aPoles.ChangeValue(6, 45) = gp_Pnt(-115.82520602454126000000, -0.00000000000003931317, -84.85588414554271700000); + aWeights.ChangeValue(6, 46) = +1.00961960432502520000; + aPoles.ChangeValue(6, 46) = gp_Pnt(-119.08778487668772000000, +0.00000000000016494845, -83.57368219250022900000); + aWeights.ChangeValue(6, 47) = +1.00961486341637220000; + aPoles.ChangeValue(6, 47) = gp_Pnt(-122.33277704237545000000, -0.00000000000006102663, -82.24707666574315100000); + aWeights.ChangeValue(6, 48) = +1.00961029578642010000; + aPoles.ChangeValue(6, 48) = gp_Pnt(-125.55945424028559000000, +0.00000000000005443726, -80.87630621413205700000); + aWeights.ChangeValue(6, 49) = +1.00960520453872830000; + aPoles.ChangeValue(6, 49) = gp_Pnt(-128.76711471386264000000, +0.00000000000006731284, -79.46169679871513800000); + aWeights.ChangeValue(6, 50) = +1.00959965618806670000; + aPoles.ChangeValue(6, 50) = gp_Pnt(-131.95505034236234000000, +0.00000000000001744703, -78.00355594499717400000); + aWeights.ChangeValue(6, 51) = +1.00958841592259230000; + aPoles.ChangeValue(6, 51) = gp_Pnt(-138.06383173526737000000, +0.00000000000005091738, -75.10807262033468100000); + aWeights.ChangeValue(6, 52) = +1.00958190609477040000; + aPoles.ChangeValue(6, 52) = gp_Pnt(-140.98751167669514000000, +0.00000000000001249767, -73.67671445695528100000); + aWeights.ChangeValue(6, 53) = +1.00957719226123470000; + aPoles.ChangeValue(6, 53) = gp_Pnt(-143.89297197091258000000, +0.00000000000004304958, -72.20827197874005800000); + aWeights.ChangeValue(6, 54) = +1.00956830736954160000; + aPoles.ChangeValue(6, 54) = gp_Pnt(-146.77976177895343000000, +0.00000000000014315600, -70.70325097869228200000); + aWeights.ChangeValue(6, 55) = +1.00956295195680430000; + aPoles.ChangeValue(6, 55) = gp_Pnt(-149.64716302220674000000, -0.00000000000013374459, -69.16163316263994400000); + aWeights.ChangeValue(6, 56) = +1.00955425555763600000; + aPoles.ChangeValue(6, 56) = gp_Pnt(-152.49476001470052000000, +0.00000000000014982315, -67.58397318476696100000); + aWeights.ChangeValue(6, 57) = +1.00954602613024340000; + aPoles.ChangeValue(6, 57) = gp_Pnt(-155.32190503332637000000, -0.00000000000000021066, -65.97043121899140800000); + aWeights.ChangeValue(6, 58) = +1.00952742278739690000; + aPoles.ChangeValue(6, 58) = gp_Pnt(-161.15007234465017000000, -0.00000000000001992904, -62.54527347940126700000); + aWeights.ChangeValue(6, 59) = +1.00951486183122910000; + aPoles.ChangeValue(6, 59) = gp_Pnt(-164.14837014605524000000, +0.00000000000023572067, -60.72896647597298900000); + aWeights.ChangeValue(6, 60) = +1.00950821186278380000; + aPoles.ChangeValue(6, 60) = gp_Pnt(-167.11960531963629000000, -0.00000000000028988207, -58.86870049528032900000); + aWeights.ChangeValue(6, 61) = +1.00948761363721440000; + aPoles.ChangeValue(6, 61) = gp_Pnt(-170.06906478280905000000, +0.00000000000040689923, -56.97372124744497800000); + aWeights.ChangeValue(6, 62) = +1.00948175483910860000; + aPoles.ChangeValue(6, 62) = gp_Pnt(-172.98765254825670000000, -0.00000000000024250881, -55.03312548926784600000); + aWeights.ChangeValue(6, 63) = +1.00946082358368820000; + aPoles.ChangeValue(6, 63) = gp_Pnt(-175.88148729884773000000, +0.00000000000015443744, -53.05496328096450000000); + aWeights.ChangeValue(6, 64) = +1.00944596410276510000; + aPoles.ChangeValue(6, 64) = gp_Pnt(-178.74719668858941000000, +0.00000000000002184305, -51.03719587787818300000); + aWeights.ChangeValue(6, 65) = +1.00942605045267690000; + aPoles.ChangeValue(6, 65) = gp_Pnt(-181.58512029181043000000, +0.00000000000003863576, -48.98084041218928800000); + aWeights.ChangeValue(6, 66) = +1.00940832657292460000; + aPoles.ChangeValue(6, 66) = gp_Pnt(-184.22041885135505000000, +0.00000000000012642202, -47.07128183802177500000); + aWeights.ChangeValue(6, 67) = +1.00938358350016230000; + aPoles.ChangeValue(6, 67) = gp_Pnt(-186.83172267077580000000, -0.00000000000026075896, -45.12863792869809700000); + aWeights.ChangeValue(6, 68) = +1.00937745534316470000; + aPoles.ChangeValue(6, 68) = gp_Pnt(-189.41814135962036000000, +0.00000000000050815389, -43.15221363464823400000); + aWeights.ChangeValue(6, 69) = +1.00932110415609880000; + aPoles.ChangeValue(6, 69) = gp_Pnt(-191.98049421722968000000, -0.00000000000036869153, -41.14519558079494000000); + aWeights.ChangeValue(6, 70) = +1.00934018958992230000; + aPoles.ChangeValue(6, 70) = gp_Pnt(-194.51554398045388000000, +0.00000000000024701945, -39.10283303403318900000); + aWeights.ChangeValue(6, 71) = +1.00926513417534820000; + aPoles.ChangeValue(6, 71) = gp_Pnt(-197.02654362639632000000, +0.00000000000002378284, -37.03182458375535900000); + aWeights.ChangeValue(6, 72) = +1.00924284324015100000; + aPoles.ChangeValue(6, 72) = gp_Pnt(-199.50902604112426000000, +0.00000000000001468063, -34.92696457232537500000); + aWeights.ChangeValue(6, 73) = +1.00920104311988210000; + aPoles.ChangeValue(6, 73) = gp_Pnt(-201.96417476016930000000, +0.00000000000004485301, -32.79087292323346500000); + aWeights.ChangeValue(6, 74) = +1.00917029694376930000; + aPoles.ChangeValue(6, 74) = gp_Pnt(-204.41947086956830000000, +0.00000000000007013856, -30.65436716589900700000); + aWeights.ChangeValue(6, 75) = +1.00906597799622610000; + aPoles.ChangeValue(6, 75) = gp_Pnt(-206.84718146821811000000, -0.00000000000006381675, -28.48746943619916600000); + aWeights.ChangeValue(6, 76) = +1.00920552993238920000; + aPoles.ChangeValue(6, 76) = gp_Pnt(-209.24487385523256000000, +0.00000000000020688933, -26.28443183778934900000); + aWeights.ChangeValue(6, 77) = +1.00876475817276390000; + aPoles.ChangeValue(6, 77) = gp_Pnt(-211.61934752962611000000, -0.00000000000012087895, -24.05869960942788700000); + aWeights.ChangeValue(6, 78) = +1.00888387250480620000; + aPoles.ChangeValue(6, 78) = gp_Pnt(-213.96155431166437000000, +0.00000000000019025578, -21.80066237623914200000); + aWeights.ChangeValue(6, 79) = +1.00881670070678450000; + aPoles.ChangeValue(6, 79) = gp_Pnt(-216.26151615033589000000, -0.00000000000009572292, -19.49741392382435400000); + aWeights.ChangeValue(6, 80) = +1.00875338528797620000; + aPoles.ChangeValue(6, 80) = gp_Pnt(-218.54531424806936000000, +0.00000000000008182630, -17.17704407009146500000); + aWeights.ChangeValue(6, 81) = +1.00842683370719580000; + aPoles.ChangeValue(6, 81) = gp_Pnt(-220.79435406720884000000, +0.00000000000004973799, -14.82789528118522200000); + aWeights.ChangeValue(7, 1) = +1.02986327036737910000; + aPoles.ChangeValue(7, 1) = gp_Pnt(+133.20307692191452000000, -0.00000000000000177636, -68.87095947031473000000); + aWeights.ChangeValue(7, 2) = +1.02989244478762340000; + aPoles.ChangeValue(7, 2) = gp_Pnt(+130.12738123407763000000, -0.00000000000000516390, -70.57040146390383500000); + aWeights.ChangeValue(7, 3) = +1.02991676091110000000; + aPoles.ChangeValue(7, 3) = gp_Pnt(+127.02840986317391000000, +0.00000000000000554535, -72.22789464235242500000); + aWeights.ChangeValue(7, 4) = +1.02993613450137910000; + aPoles.ChangeValue(7, 4) = gp_Pnt(+123.90694758506712000000, -0.00000000000000702621, -73.84302715009133100000); + aWeights.ChangeValue(7, 5) = +1.02995970896171030000; + aPoles.ChangeValue(7, 5) = gp_Pnt(+120.76360256847768000000, -0.00000000000000047370, -75.41549467632542300000); + aWeights.ChangeValue(7, 6) = +1.02998196300924330000; + aPoles.ChangeValue(7, 6) = gp_Pnt(+117.59908279457284000000, +0.00000000000000772901, -76.94495426059752700000); + aWeights.ChangeValue(7, 7) = +1.02999781361776170000; + aPoles.ChangeValue(7, 7) = gp_Pnt(+114.41407453952652000000, -0.00000000000000327310, -78.43108601253017300000); + aWeights.ChangeValue(7, 8) = +1.03001626830282000000; + aPoles.ChangeValue(7, 8) = gp_Pnt(+111.20931631680004000000, +0.00000000000000421483, -79.87356087705671800000); + aWeights.ChangeValue(7, 9) = +1.03004822145821140000; + aPoles.ChangeValue(7, 9) = gp_Pnt(+104.76172782897289000000, +0.00000000000000259283, -82.67059011797552200000); + aWeights.ChangeValue(7, 10) = +1.03006364818919470000; + aPoles.ChangeValue(7, 10) = gp_Pnt(+101.51889932580750000000, +0.00000000000000793496, -84.02514647707548100000); + aWeights.ChangeValue(7, 11) = +1.03007725635610380000; + aPoles.ChangeValue(7, 11) = gp_Pnt(+98.25768758130365700000, +0.00000000000000127608, -85.33546669488836800000); + aWeights.ChangeValue(7, 12) = +1.03009045031501540000; + aPoles.ChangeValue(7, 12) = gp_Pnt(+94.97880175952953200000, +0.00000000000000289709, -86.60126064632369500000); + aWeights.ChangeValue(7, 13) = +1.03010285398165520000; + aPoles.ChangeValue(7, 13) = gp_Pnt(+91.68295682468645700000, +0.00000000000000548904, -87.82224920548925700000); + aWeights.ChangeValue(7, 14) = +1.03011393120368040000; + aPoles.ChangeValue(7, 14) = gp_Pnt(+88.37086140882031800000, -0.00000000000000004450, -88.99816853898946100000); + aWeights.ChangeValue(7, 15) = +1.03012484065781210000; + aPoles.ChangeValue(7, 15) = gp_Pnt(+85.04324466385365600000, +0.00000000000000407116, -90.12875955698966400000); + aWeights.ChangeValue(7, 16) = +1.03015471267321310000; + aPoles.ChangeValue(7, 16) = gp_Pnt(+75.01621211174902700000, +0.00000000000001208092, -93.38380423550353300000); + aWeights.ChangeValue(7, 17) = +1.03017194800922480000; + aPoles.ChangeValue(7, 17) = gp_Pnt(+68.27251352067813200000, +0.00000000000001147779, -95.37146758037383200000); + aWeights.ChangeValue(7, 18) = +1.03018680682765580000; + aPoles.ChangeValue(7, 18) = gp_Pnt(+61.47507566136914600000, +0.00000000000000851456, -97.17487791831784700000); + aWeights.ChangeValue(7, 19) = +1.03019958109549560000; + aPoles.ChangeValue(7, 19) = gp_Pnt(+54.62953031922813800000, +0.00000000000000645560, -98.79238303220959900000); + aWeights.ChangeValue(7, 20) = +1.03021050389503310000; + aPoles.ChangeValue(7, 20) = gp_Pnt(+47.74179355100338300000, +0.00000000000000683493, -100.22257163394704000000); + aWeights.ChangeValue(7, 21) = +1.03021974942385920000; + aPoles.ChangeValue(7, 21) = gp_Pnt(+40.81806392732334400000, +0.00000000000000945638, -101.46427420633951000000); + aWeights.ChangeValue(7, 22) = +1.03022743299486530000; + aPoles.ChangeValue(7, 22) = gp_Pnt(+33.86482072309787100000, +0.00000000000001239365, -102.51656369616552000000); + aWeights.ChangeValue(7, 23) = +1.03023979631718960000; + aPoles.ChangeValue(7, 23) = gp_Pnt(+19.91267581058432200000, +0.00000000000001269021, -104.24092170462040000000); + aWeights.ChangeValue(7, 24) = +1.03024450452679180000; + aPoles.ChangeValue(7, 24) = gp_Pnt(+12.91322103073442500000, +0.00000000000001310657, -104.91296575233191000000); + aWeights.ChangeValue(7, 25) = +1.03024781840890150000; + aPoles.ChangeValue(7, 25) = gp_Pnt(+5.89663552968925500000, +0.00000000000001362222, -105.39416639705574000000); + aWeights.ChangeValue(7, 26) = +1.03024979501191980000; + aPoles.ChangeValue(7, 26) = gp_Pnt(-1.13093554742009240000, +0.00000000000001442955, -105.68402704533355000000); + aWeights.ChangeValue(7, 27) = +1.03025046568879810000; + aPoles.ChangeValue(7, 27) = gp_Pnt(-8.16338049757019310000, +0.00000000000001553070, -105.78227646648484000000); + aWeights.ChangeValue(7, 28) = +1.03024983609703620000; + aPoles.ChangeValue(7, 28) = gp_Pnt(-15.19462185431612500000, +0.00000000000001673746, -105.68886888131540000000); + aWeights.ChangeValue(7, 29) = +1.03024788619868390000; + aPoles.ChangeValue(7, 29) = gp_Pnt(-22.21861718693262200000, +0.00000000000001767135, -105.40398398356824000000); + aWeights.ChangeValue(7, 30) = +1.03024126030624560000; + aPoles.ChangeValue(7, 30) = gp_Pnt(-36.24014829916134100000, +0.00000000000002019891, -104.45206611492652000000); + aWeights.ChangeValue(7, 31) = +1.03023657011944200000; + aPoles.ChangeValue(7, 31) = gp_Pnt(-43.23771519136024500000, +0.00000000000002161068, -103.78502949380328000000); + aWeights.ChangeValue(7, 32) = +1.03023047292900840000; + aPoles.ChangeValue(7, 32) = gp_Pnt(-50.21605719916001900000, +0.00000000000002249329, -102.92731708926736000000); + aWeights.ChangeValue(7, 33) = +1.03022290017099440000; + aPoles.ChangeValue(7, 33) = gp_Pnt(-57.16920057960702200000, +0.00000000000002320995, -101.87955571848956000000); + aWeights.ChangeValue(7, 34) = +1.03021374148842140000; + aPoles.ChangeValue(7, 34) = gp_Pnt(-64.09120253994868200000, +0.00000000000002399266, -100.64259867222304000000); + aWeights.ChangeValue(7, 35) = +1.03020284473128120000; + aPoles.ChangeValue(7, 35) = gp_Pnt(-70.97615252947152000000, +0.00000000000002494226, -99.21752532044712300000); + aWeights.ChangeValue(7, 36) = +1.03019001595653670000; + aPoles.ChangeValue(7, 36) = gp_Pnt(-77.81817349811507300000, +0.00000000000002602838, -97.60564061068184600000); + aWeights.ChangeValue(7, 37) = +1.03016805964614980000; + aPoles.ChangeValue(7, 37) = gp_Pnt(-87.76549855749630100000, +0.00000000000002703745, -94.97405836608523100000); + aWeights.ChangeValue(7, 38) = +1.03016062145972500000; + aPoles.ChangeValue(7, 38) = gp_Pnt(-90.90906843451735100000, +0.00000000000002735353, -94.09969925934423400000); + aWeights.ChangeValue(7, 39) = +1.03015268516758060000; + aPoles.ChangeValue(7, 39) = gp_Pnt(-94.04154842308000200000, +0.00000000000002795160, -93.18554984223239000000); + aWeights.ChangeValue(7, 40) = +1.03014422393874510000; + aPoles.ChangeValue(7, 40) = gp_Pnt(-97.16235536263198500000, +0.00000000000002873660, -92.23177350871787900000); + aWeights.ChangeValue(7, 41) = +1.03013520381253840000; + aPoles.ChangeValue(7, 41) = gp_Pnt(-100.27090735629974000000, +0.00000000000002960449, -91.23854430518403500000); + aWeights.ChangeValue(7, 42) = +1.03012558369857450000; + aPoles.ChangeValue(7, 42) = gp_Pnt(-103.36662387191370000000, +0.00000000000003044224, -90.20604688574815100000); + aWeights.ChangeValue(7, 43) = +1.03011531537676040000; + aPoles.ChangeValue(7, 43) = gp_Pnt(-106.44892584135401000000, +0.00000000000003112785, -89.13447646370049400000); + aWeights.ChangeValue(7, 44) = +1.03009266486582220000; + aPoles.ChangeValue(7, 44) = gp_Pnt(-112.82164316087234000000, +0.00000000000002877514, -86.82815610446842000000); + aWeights.ChangeValue(7, 45) = +1.03007954250937140000; + aPoles.ChangeValue(7, 45) = gp_Pnt(-116.10982863064515000000, +0.00000000000005217709, -85.58719260568324200000); + aWeights.ChangeValue(7, 46) = +1.03006700046765860000; + aPoles.ChangeValue(7, 46) = gp_Pnt(-119.38108228759732000000, -0.00000000000000364635, -84.30140001571530200000); + aWeights.ChangeValue(7, 47) = +1.03005153385603830000; + aPoles.ChangeValue(7, 47) = gp_Pnt(-122.63466837574235000000, +0.00000000000007773224, -82.97105629274108200000); + aWeights.ChangeValue(7, 48) = +1.03003663316235050000; + aPoles.ChangeValue(7, 48) = gp_Pnt(-125.86988610286646000000, +0.00000000000000501775, -81.59643931580511400000); + aWeights.ChangeValue(7, 49) = +1.03002002524069390000; + aPoles.ChangeValue(7, 49) = gp_Pnt(-129.08600965998806000000, +0.00000000000004872530, -80.17785297868806500000); + aWeights.ChangeValue(7, 50) = +1.03000192732158440000; + aPoles.ChangeValue(7, 50) = gp_Pnt(-132.28232849510800000000, +0.00000000000003627431, -78.71561001568775900000); + aWeights.ChangeValue(7, 51) = +1.02996526567106140000; + aPoles.ChangeValue(7, 51) = gp_Pnt(-138.40719443250111000000, +0.00000000000004030865, -75.81195871455292900000); + aWeights.ChangeValue(7, 52) = +1.02994403451619650000; + aPoles.ChangeValue(7, 52) = gp_Pnt(-141.33856968181306000000, +0.00000000000003444592, -74.37651555974527200000); + aWeights.ChangeValue(7, 53) = +1.02992866105480000000; + aPoles.ChangeValue(7, 53) = gp_Pnt(-144.25171811139330000000, +0.00000000000003429445, -72.90395453557894700000); + aWeights.ChangeValue(7, 54) = +1.02989968743351530000; + aPoles.ChangeValue(7, 54) = gp_Pnt(-147.14603336223070000000, +0.00000000000004355038, -71.39457006641885100000); + aWeights.ChangeValue(7, 55) = +1.02988222474475720000; + aPoles.ChangeValue(7, 55) = gp_Pnt(-150.02095857157173000000, +0.00000000000003217269, -69.84863841933133700000); + aWeights.ChangeValue(7, 56) = +1.02985386954430420000; + aPoles.ChangeValue(7, 56) = gp_Pnt(-152.87595706513403000000, +0.00000000000003648661, -68.26644064265008200000); + aWeights.ChangeValue(7, 57) = +1.02982704006085530000; + aPoles.ChangeValue(7, 57) = gp_Pnt(-155.71041601974636000000, +0.00000000000003591181, -66.64830754728993200000); + aWeights.ChangeValue(7, 58) = +1.02976639514271140000; + aPoles.ChangeValue(7, 58) = gp_Pnt(-161.55369960091491000000, +0.00000000000003646415, -63.21332070345936700000); + aWeights.ChangeValue(7, 59) = +1.02972545417744080000; + aPoles.ChangeValue(7, 59) = gp_Pnt(-164.55974256681068000000, +0.00000000000003294676, -61.39167299907511900000); + aWeights.ChangeValue(7, 60) = +1.02970377642180270000; + aPoles.ChangeValue(7, 60) = gp_Pnt(-167.53873683551103000000, +0.00000000000002190344, -59.52621075357659900000); + aWeights.ChangeValue(7, 61) = +1.02963665582099750000; + aPoles.ChangeValue(7, 61) = gp_Pnt(-170.49570646978711000000, +0.00000000000009010479, -57.62531748377598000000); + aWeights.ChangeValue(7, 62) = +1.02961756328110620000; + aPoles.ChangeValue(7, 62) = gp_Pnt(-173.42176702363508000000, -0.00000000000003499440, -55.67944052993496500000); + aWeights.ChangeValue(7, 63) = +1.02954937293567860000; + aPoles.ChangeValue(7, 63) = gp_Pnt(-176.32284460610933000000, +0.00000000000007636921, -53.69521656711459900000); + aWeights.ChangeValue(7, 64) = +1.02950097342681770000; + aPoles.ChangeValue(7, 64) = gp_Pnt(-179.19569709355173000000, +0.00000000000003273955, -51.67161593723249500000); + aWeights.ChangeValue(7, 65) = +1.02943612532291810000; + aPoles.ChangeValue(7, 65) = gp_Pnt(-182.04053139917158000000, +0.00000000000003996803, -49.60917258111981500000); + aWeights.ChangeValue(7, 66) = +1.02937840445762090000; + aPoles.ChangeValue(7, 66) = gp_Pnt(-184.68250151172640000000, +0.00000000000004112926, -47.69381589112448700000); + aWeights.ChangeValue(7, 67) = +1.02929786839945800000; + aPoles.ChangeValue(7, 67) = gp_Pnt(-187.30004443981446000000, +0.00000000000003629801, -45.74517623046489900000); + aWeights.ChangeValue(7, 68) = +1.02927785532615720000; + aPoles.ChangeValue(7, 68) = gp_Pnt(-189.89358418563035000000, +0.00000000000003708012, -43.76295173174737800000); + aWeights.ChangeValue(7, 69) = +1.02909457173661250000; + aPoles.ChangeValue(7, 69) = gp_Pnt(-192.46070903458983000000, +0.00000000000005500515, -41.74904085552218200000); + aWeights.ChangeValue(7, 70) = +1.02915656102268340000; + aPoles.ChangeValue(7, 70) = gp_Pnt(-195.00353322314638000000, +0.00000000000002645256, -39.70148425813464900000); + aWeights.ChangeValue(7, 71) = +1.02891246604057510000; + aPoles.ChangeValue(7, 71) = gp_Pnt(-197.51895024482548000000, +0.00000000000005006422, -37.62251287581096900000); + aWeights.ChangeValue(7, 72) = +1.02884001996279940000; + aPoles.ChangeValue(7, 72) = gp_Pnt(-200.00717902020989000000, +0.00000000000003866246, -35.51147139839754600000); + aWeights.ChangeValue(7, 73) = +1.02870418206103280000; + aPoles.ChangeValue(7, 73) = gp_Pnt(-202.46745722827831000000, +0.00000000000003996803, -33.36845405838467800000); + aWeights.ChangeValue(7, 74) = +1.02860417892808040000; + aPoles.ChangeValue(7, 74) = gp_Pnt(-204.92874075079348000000, +0.00000000000003952569, -31.22492832365916000000); + aWeights.ChangeValue(7, 75) = +1.02826579045574770000; + aPoles.ChangeValue(7, 75) = gp_Pnt(-207.35951843182116000000, +0.00000000000002864861, -29.04902036970887700000); + aWeights.ChangeValue(7, 76) = +1.02871793966685040000; + aPoles.ChangeValue(7, 76) = gp_Pnt(-209.76815931164757000000, +0.00000000000007786791, -26.84449461829588300000); + aWeights.ChangeValue(7, 77) = +1.02728787827248790000; + aPoles.ChangeValue(7, 77) = gp_Pnt(-212.13952611955784000000, -0.00000000000002645359, -24.59453985262025100000); + aWeights.ChangeValue(7, 78) = +1.02767535385751650000; + aPoles.ChangeValue(7, 78) = gp_Pnt(-214.48523983715771000000, +0.00000000000011316462, -22.34028621398329100000); + aWeights.ChangeValue(7, 79) = +1.02745809923196680000; + aPoles.ChangeValue(7, 79) = gp_Pnt(-216.79261871005519000000, -0.00000000000002978790, -20.02558452892611700000); + aWeights.ChangeValue(7, 80) = +1.02725110106353260000; + aPoles.ChangeValue(7, 80) = gp_Pnt(-219.08116944862113000000, +0.00000000000005732296, -17.69632354506026700000); + aWeights.ChangeValue(7, 81) = +1.02619749797986360000; + aPoles.ChangeValue(7, 81) = gp_Pnt(-221.32510969435936000000, +0.00000000000004618528, -15.33078661161192400000); + } + //// + + const Handle(Geom_Surface) aS1 = new Geom_BSplineSurface(aPoles, aWeights, aUKnots, aVKnots, aUMult, aVMult, aUDegree, aVDegree); + + char buff[1024]; + + Sprintf(buff, "%s_1", theArgVal[1]); + DrawTrSurf::Set(buff, aS1); + theDI << buff << " "; + + Sprintf(buff, "%s_2", theArgVal[1]); + DrawTrSurf::Set(buff, aS2); + theDI << buff << "\n"; + + return 0; +} + +void QABugs::Commands_20(Draw_Interpretor& theCommands) { + const char *group = "QABugs"; + + theCommands.Add ("OCC26675_1", "OCC26675_1 result", __FILE__, SurfaceGenOCC26675_1, group); + + return; +} diff --git a/src/QABugs/QABugs_3.cxx b/src/QABugs/QABugs_3.cxx index c4681b7cc4..d2c53f518d 100644 --- a/src/QABugs/QABugs_3.cxx +++ b/src/QABugs/QABugs_3.cxx @@ -286,17 +286,15 @@ static Standard_Integer BUC60652(Draw_Interpretor& di, Standard_Integer argc, co static Standard_Integer defNbPntMax = 30; static Standard_Real defTol3d = 1.e-7; static Standard_Real defTol2d = 1.e-7; -static Standard_Boolean defRelativeTol=Standard_True; Standard_Integer NbPntMax = defNbPntMax; Standard_Real Toler3d =defTol3d; Standard_Real Toler2d = defTol2d; -Standard_Boolean RelativeTol= defRelativeTol; // //== // ksection : operateur section appelant BRepAlgo_BooleanOperation //== // ksection : operateur section appelant BRepAlgo_BooleanOperations //======================================================================= Standard_Integer ksection(Draw_Interpretor& di, Standard_Integer n, const char ** a) { if (n < 8) { - di << "Usage : " << a[0] << " resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol" << "\n"; + di << "Usage : " << a[0] << " resultat shell1 shell2 NbPntMax Toler3d Toler2d" << "\n"; return -1; } // a[1]= resultat @@ -305,20 +303,18 @@ Standard_Integer ksection(Draw_Interpretor& di, Standard_Integer n, const char * // a[4]= NbPntMax // a[5]= Toler3d // a[6]= Toler2d - // a[7]= RelativeTol TopoDS_Shape s1 = DBRep::Get(a[2],TopAbs_SHELL); TopoDS_Shape s2 = DBRep::Get(a[3],TopAbs_SHELL); if (s1.IsNull() || s2.IsNull()) return 1; NbPntMax=Draw::Atoi(a[4]); Toler3d=Draw::Atof(a[5]); Toler2d=Draw::Atof(a[6]); - RelativeTol=Draw::Atoi(a[7]); di << "BRepAlgo_BooleanOperations myalgo\n"; BRepAlgo_BooleanOperations myalgo; myalgo.Shapes(s1, s2); - myalgo.SetApproxParameters(NbPntMax,Toler3d,Toler2d,RelativeTol); + myalgo.SetApproxParameters(NbPntMax,Toler3d,Toler2d); TopoDS_Shape res; res = myalgo.Section(); DBRep::Set(a[1],res); return 0; @@ -1816,10 +1812,10 @@ void QABugs::Commands_3(Draw_Interpretor& theCommands) { theCommands.Add("BUC60609","BUC60609 shape name [U V]",__FILE__,BUC60609,group); theCommands.Add("BUC60632","BUC60632 mode length",__FILE__,BUC60632,group); theCommands.Add("BUC60652","BUC60652 face",__FILE__,BUC60652,group); - theCommands.Add("ksection","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol",__FILE__,ksection,group); - theCommands.Add("BUC60682","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol",__FILE__,ksection,group); - theCommands.Add("BUC60669","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol",__FILE__,ksection,group); - theCommands.Add("PRO19626","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol",__FILE__,ksection,group); + theCommands.Add("ksection","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d",__FILE__,ksection,group); + theCommands.Add("BUC60682","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d",__FILE__,ksection,group); + theCommands.Add("BUC60669","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d",__FILE__,ksection,group); + theCommands.Add("PRO19626","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d",__FILE__,ksection,group); theCommands.Add("BUC60574","BUC60574 ",__FILE__,BUC60574,group); theCommands.Add("BUC60699","BUC60699 ",__FILE__,BUC60699,group); diff --git a/src/ShapeAlgo/ShapeAlgo_AlgoContainer.cxx b/src/ShapeAlgo/ShapeAlgo_AlgoContainer.cxx index 62a985c2de..d7ad117808 100644 --- a/src/ShapeAlgo/ShapeAlgo_AlgoContainer.cxx +++ b/src/ShapeAlgo/ShapeAlgo_AlgoContainer.cxx @@ -217,7 +217,7 @@ void ShapeAlgo_AlgoContainer::ApproxBSplineCurve (const Handle(Geom_BSplineCurve } GeomInt_WLApprox theapp3d; Standard_Real Tol = Precision::Approximation(); - theapp3d.SetParameters(Tol, Tol, 4, 8, 0, Standard_True); + theapp3d.SetParameters(Tol, Tol, 4, 8, 0, 30, Standard_True); Handle(IntPatch_WLine) WL = new IntPatch_WLine(R, Standard_False); Standard_Integer indicemin = 1; Standard_Integer indicemax = jpole; @@ -349,7 +349,7 @@ void ShapeAlgo_AlgoContainer::ApproxBSplineCurve (const Handle(Geom2d_BSplineCur } GeomInt_WLApprox theapp3d; Standard_Real Tol = Precision::PApproximation(); - theapp3d.SetParameters(Tol, Tol, 4, 8, 0, Standard_True); + theapp3d.SetParameters(Tol, Tol, 4, 8, 0, 30, Standard_True); Handle(IntPatch_WLine) WL = new IntPatch_WLine(R, Standard_False); Standard_Integer indicemin = 1; Standard_Integer indicemax = jpole; diff --git a/src/TopOpeBRep/TopOpeBRep_FacesIntersector.cxx b/src/TopOpeBRep/TopOpeBRep_FacesIntersector.cxx index 2d86e74e2b..6c728124ee 100644 --- a/src/TopOpeBRep/TopOpeBRep_FacesIntersector.cxx +++ b/src/TopOpeBRep/TopOpeBRep_FacesIntersector.cxx @@ -217,7 +217,8 @@ void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Sh myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection); myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2, - myTol1,myTol2,Standard_True,Standard_True); + myTol1,myTol2,Standard_True,Standard_True, + Standard_False); #ifdef OCCT_DEBUG if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop(); diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_CurveTool.cxx b/src/TopOpeBRepTool/TopOpeBRepTool_CurveTool.cxx index d66abadccb..2bdfe386ca 100644 --- a/src/TopOpeBRepTool/TopOpeBRepTool_CurveTool.cxx +++ b/src/TopOpeBRepTool/TopOpeBRepTool_CurveTool.cxx @@ -318,8 +318,7 @@ Standard_Boolean TopOpeBRepTool_CurveTool::MakeCurves Standard_Boolean CompPC1 = myGeomTool.CompPC1(); Standard_Boolean CompPC2 = myGeomTool.CompPC2(); Standard_Real tol3d,tol2d; - Standard_Boolean RelativeTol; - myGeomTool.GetTolerances(tol3d,tol2d,RelativeTol); + myGeomTool.GetTolerances(tol3d,tol2d); Standard_Integer NbPntMax = myGeomTool.NbPntMax(); #ifdef OCCT_DEBUG @@ -599,7 +598,7 @@ Standard_Boolean TopOpeBRepTool_CurveTool::MakeCurves Handle(BRepApprox_ApproxLine) AL; AL = new BRepApprox_ApproxLine(HC3D,HPC1,HPC2); - Approx.SetParameters(tol3d,tol2d,RelativeTol,degmin,degmax,nitmax,NbPntMax,withtangency, + Approx.SetParameters(tol3d,tol2d,degmin,degmax,nitmax,NbPntMax,withtangency, parametrization); if (CompC3D && CompPC1 && BAS1.GetType() == GeomAbs_Plane) { diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.cxx b/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.cxx index f70264ea25..5c37c7622d 100644 --- a/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.cxx +++ b/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.cxx @@ -33,7 +33,6 @@ TopOpeBRepTool_GeomTool::TopOpeBRepTool_GeomTool myCompPC2(CompPC2), myTol3d(Precision::Approximation()), myTol2d(Precision::PApproximation()), - myRelativeTol(Standard_True), myNbPntMax(30) { } @@ -133,34 +132,6 @@ void TopOpeBRepTool_GeomTool::SetTolerances { myTol3d = tol3d; myTol2d = tol2d; - myRelativeTol = Standard_True; -} - -//======================================================================= -//function : GetTolerances -//purpose : -//======================================================================= - -void TopOpeBRepTool_GeomTool::GetTolerances - (Standard_Real& tol3d, Standard_Real& tol2d, Standard_Boolean& relative) const -{ - tol3d = myTol3d; - tol2d = myTol2d; - relative = myRelativeTol; -} - - -//======================================================================= -//function : SetTolerances -//purpose : -//======================================================================= - -void TopOpeBRepTool_GeomTool::SetTolerances - (const Standard_Real tol3d, const Standard_Real tol2d, const Standard_Boolean relative) -{ - myTol3d = tol3d; - myTol2d = tol2d; - myRelativeTol = relative; } //======================================================================= diff --git a/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.hxx b/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.hxx index 1efda8ece9..9b64eab763 100644 --- a/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.hxx +++ b/src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.hxx @@ -63,10 +63,6 @@ public: Standard_EXPORT void SetTolerances (const Standard_Real tol3d, const Standard_Real tol2d); - Standard_EXPORT void GetTolerances (Standard_Real& tol3d, Standard_Real& tol2d, Standard_Boolean& relative) const; - - Standard_EXPORT void SetTolerances (const Standard_Real tol3d, const Standard_Real tol2d, const Standard_Boolean relative); - Standard_EXPORT Standard_Integer NbPntMax() const; Standard_EXPORT void SetNbPntMax (const Standard_Integer NbPntMax); @@ -98,7 +94,6 @@ private: Standard_Real myTol3d; Standard_Real myTol2d; - Standard_Boolean myRelativeTol; Standard_Integer myNbPntMax; diff --git a/tests/blend/buildevol/B3 b/tests/blend/buildevol/B3 index 56aa0fbae9..a640b6d34e 100644 --- a/tests/blend/buildevol/B3 +++ b/tests/blend/buildevol/B3 @@ -11,4 +11,4 @@ mkevol result s updatevol s_7 0 10 1 20 2 10 buildevol -set square 11500.5 +set square 12023.4 diff --git a/tests/blend/simple/G6 b/tests/blend/simple/G6 index ec922e3f72..633790a6d0 100644 --- a/tests/blend/simple/G6 +++ b/tests/blend/simple/G6 @@ -1,3 +1,5 @@ +puts "TODO OCC26932 Linux: Faulty shapes in variables faulty_1 to faulty" + beziercurve w1 5 0 0 0 20 0 0 20 5 0 25 10 0 10 20 0 mkedge w1 w1 polyline w2 10 20 0 0 0 0 diff --git a/tests/blend/simple/X4 b/tests/blend/simple/X4 index cfb6e23eee..4bd5ec485b 100644 --- a/tests/blend/simple/X4 +++ b/tests/blend/simple/X4 @@ -4,6 +4,8 @@ ## Comment : From CV tests serie page 25/26 ## =========================================== +puts "TODO #OCC26740 ALL: Faulty shapes in variables faulty_1 to faulty_" + restore [locate_data_file CCV_1_h1_gsk.rle] s explode s E blend result s 30 s_14 diff --git a/tests/boolean/bcommon_complex/C7 b/tests/boolean/bcommon_complex/C7 index 3a0c90f348..123ab2dd21 100644 --- a/tests/boolean/bcommon_complex/C7 +++ b/tests/boolean/bcommon_complex/C7 @@ -5,7 +5,7 @@ restore [locate_data_file buc60290b.rle] sol2 bcommon result sol2 sol1 -set square 667287 +set square 685602 if { [regexp {Windows} [dversion]] } { if { [regexp {64} [dversion]] } { #set square 804392 diff --git a/tests/boolean/bsection/M3 b/tests/boolean/bsection/M3 index 08a3f95292..3bf78734d6 100644 --- a/tests/boolean/bsection/M3 +++ b/tests/boolean/bsection/M3 @@ -1,3 +1,5 @@ +puts "TODO #OCC26777 ALL: Error : The length of the resulting shape is" + restore [locate_data_file GEN758_nofog.rle] a explode a bsection result a_1 a_2 diff --git a/tests/boolean/bsection/N2 b/tests/boolean/bsection/N2 index ae758156b8..294ced79c7 100644 --- a/tests/boolean/bsection/N2 +++ b/tests/boolean/bsection/N2 @@ -1,3 +1,5 @@ +puts "TODO #OCC26814 ALL: Error : The length of the resulting shape is" + restore [locate_data_file lh3d_px1.brep] a plane p 0 0 0 1 0 0 mkface f p diff --git a/tests/boolean/volumemaker/C5 b/tests/boolean/volumemaker/C5 index 0a56a0439b..c94d9935c1 100644 --- a/tests/boolean/volumemaker/C5 +++ b/tests/boolean/volumemaker/C5 @@ -34,5 +34,5 @@ mkface f6 con_f6 0 6.2831853071795862 0 1000000 # make volume operation mkvolume result f1 f2 f3 f4 f5 f6 -set square 3.67285e+006 +set square 5.1932e+006 diff --git a/tests/boolean/volumemaker/C6 b/tests/boolean/volumemaker/C6 index 9160f01c38..783a41cace 100644 --- a/tests/boolean/volumemaker/C6 +++ b/tests/boolean/volumemaker/C6 @@ -39,4 +39,4 @@ mkface f7 con_f7 0 6.2831853071795862 0 1000000 # make volume operation mkvolume result f1 f2 f3 f4 f5 f6 f7 -set square 4.20797e+006 +set square 6.22995e+006 diff --git a/tests/boolean/volumemaker/F9 b/tests/boolean/volumemaker/F9 index 84c9fb86eb..2c8a4b60af 100644 --- a/tests/boolean/volumemaker/F9 +++ b/tests/boolean/volumemaker/F9 @@ -1,8 +1,6 @@ # test script on make volume operation # cone cylinder plane -puts "TODO OCC26020 ALL: Faulty shapes in variables faulty_1 to faulty_" - # planar face plane pln_f1 2.3537565147188571e-015 -592.35294118000002 1.1044592656221142e-015 0.90529096719956037 4.7161388709779336e-017 0.42479202523927467 erase pln_f1 @@ -41,5 +39,5 @@ mkface f7 cyl_f7 0 6.2831853071795862 -1000000 1000000 # make volume operation mkvolume result f1 f2 f3 f4 f5 f6 f7 -set square 1.71122e+013 +set square 9.42987e+007 diff --git a/tests/boolean/volumemaker/G1 b/tests/boolean/volumemaker/G1 index d7be6d1778..93ad36a42f 100644 --- a/tests/boolean/volumemaker/G1 +++ b/tests/boolean/volumemaker/G1 @@ -2,6 +2,8 @@ # cone cylinder plane # Error status: 102 +puts "TODO OCC26020 ALL: Error : is WRONG because number of " + # conical face cone con_f1 -59.814698440000001 384.36473473000001 127 0.41716766026590824 -0.90882954575006414 -5.4874902763032048e-016 89.995898744693349 0 erase con_f1 @@ -24,3 +26,6 @@ mkface f4 cyl_f4 0 6.2831853071795862 -1000000 1000000 # make volume operation mkvolume result f1 f2 f3 f4 + +checknbshapes result -vertex 6 -edge 11 -wire 11 -face 8 -shell 4 -solid 2 -compsolid 0 -compound 1 -shape 43 + diff --git a/tests/bugs/modalg_1/buc60533 b/tests/bugs/modalg_1/buc60533 index fffdb9fb9a..30cffbec75 100755 --- a/tests/bugs/modalg_1/buc60533 +++ b/tests/bugs/modalg_1/buc60533 @@ -66,5 +66,5 @@ copy r_1 result # An exception was caught Standard_ConstructionError: # ** Exception ** Standard_ConstructionError: -set square 1.59518e+07 +set square 2.15333e+007 set 2dviewer 0 diff --git a/tests/bugs/modalg_1/buc60555_1 b/tests/bugs/modalg_1/buc60555_1 index 8f988fa8be..bd3629e562 100755 --- a/tests/bugs/modalg_1/buc60555_1 +++ b/tests/bugs/modalg_1/buc60555_1 @@ -33,5 +33,5 @@ if { $MaxFaceTolerance > 1 || $MaxEdgeTolerance > 1 || $MaxVertexTolerance > 1 } puts "Tolerance of shape is less then 1.0" } -set square 4.21741e+007 +set square 3.87049e+007 set 2dviewer 0 diff --git a/tests/bugs/modalg_1/buc60555_2 b/tests/bugs/modalg_1/buc60555_2 index a9ff829af8..45941122fd 100755 --- a/tests/bugs/modalg_1/buc60555_2 +++ b/tests/bugs/modalg_1/buc60555_2 @@ -50,5 +50,5 @@ if { $MaxFaceTolerance > 1 || $MaxEdgeTolerance > 1 || $MaxVertexTolerance > 1 } } else { puts "Tolerance of shape is less then 1.0" } -set square 4.03996e+007 +set square 3.71909e+007 set 2dviewer 0 diff --git a/tests/bugs/modalg_1/buc60555_3 b/tests/bugs/modalg_1/buc60555_3 index 48c897fd10..2118391843 100755 --- a/tests/bugs/modalg_1/buc60555_3 +++ b/tests/bugs/modalg_1/buc60555_3 @@ -66,5 +66,5 @@ if { $MaxFaceTolerance > 2 || $MaxEdgeTolerance > 2 || $MaxVertexTolerance > 2 } } else { puts "Tolerance of shape is less then 2.0" } -set square 1.74934e+007 +set square 1.341e+007 set 2dviewer 0 diff --git a/tests/bugs/modalg_1/bug10160_3 b/tests/bugs/modalg_1/bug10160_3 index 2b123caf0b..2b4ac8114c 100755 --- a/tests/bugs/modalg_1/bug10160_3 +++ b/tests/bugs/modalg_1/bug10160_3 @@ -1,5 +1,4 @@ puts "TODO OCC11111 ALL: Error : is WRONG because number of " -puts "TODO OCC11111 ALL: Error : The square of result shape is" puts "============" puts "OCC10160" puts "============" diff --git a/tests/bugs/modalg_1/bug1255 b/tests/bugs/modalg_1/bug1255 index 30580f8436..3b09f007b8 100755 --- a/tests/bugs/modalg_1/bug1255 +++ b/tests/bugs/modalg_1/bug1255 @@ -2,7 +2,11 @@ puts "================" puts "OCC1255" puts "================" puts "" -# Exception in command 'section' +############################################### +## Exception in command 'section' +############################################### + +puts "TODO #OCC26815 ALL: Error : The length of result shape is" restore [locate_data_file OCC1255.brep] a checkshape a diff --git a/tests/bugs/modalg_1/bug1255_1 b/tests/bugs/modalg_1/bug1255_1 index b0df2d6821..e5327fc770 100755 --- a/tests/bugs/modalg_1/bug1255_1 +++ b/tests/bugs/modalg_1/bug1255_1 @@ -7,6 +7,8 @@ puts "" # (This script tests new topology) ############################################### +puts "TODO #OCC26815 ALL: Error : The length of result shape is" + restore [locate_data_file OCC1255.brep] a checkshape a diff --git a/tests/bugs/modalg_2/bug22557 b/tests/bugs/modalg_2/bug22557 index 56892c21fc..879507c2cd 100755 --- a/tests/bugs/modalg_2/bug22557 +++ b/tests/bugs/modalg_2/bug22557 @@ -1,6 +1,3 @@ -puts "TODO OCC21564 ALL: The square of result shape is" -puts "TODO OCC21564 ALL: Error : is WRONG because number of " - puts "============" puts "OCC22557" puts "============" @@ -24,7 +21,7 @@ puts "Start boolean operation ..." bopcut result puts "Finish boolean operation ..." -set square 0.172993 +set square 0.172994 checknbshapes result -vertex 192 -edge 288 -wire 98 -face 98 -shell 1 -solid 1 -compsolid 0 -compound 1 -shape 679 diff --git a/tests/bugs/modalg_2/bug5805_18 b/tests/bugs/modalg_2/bug5805_18 index 3b73c18644..50ff43b79f 100755 --- a/tests/bugs/modalg_2/bug5805_18 +++ b/tests/bugs/modalg_2/bug5805_18 @@ -1,4 +1,7 @@ -puts "TODO OCC25925 ALL: Faulty shapes in variables faulty_1 to" +puts "TODO OCC25925 ALL: ERROR. offsetperform operation not done." +puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape" +puts "TODO OCC25925 ALL: Tcl Exception: Error : command \\\"nbshapes result\\\" gives an empty result" +puts "TODO OCC25925 ALL: TEST INCOMPLETE" puts "============" puts "OCC5805" diff --git a/tests/bugs/modalg_2/bug5805_42 b/tests/bugs/modalg_2/bug5805_42 index 7c4d0f5883..7d164389c8 100755 --- a/tests/bugs/modalg_2/bug5805_42 +++ b/tests/bugs/modalg_2/bug5805_42 @@ -1,5 +1,6 @@ -puts "TODO OCC25925 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC25925 ALL: Error : is WRONG because number of" +puts "TODO OCC25925 ALL: ERROR. offsetperform operation not done." +puts "TODO OCC25925 ALL: Tcl Exception: Error : command \\\"nbshapes result\\\" gives an empty result" +puts "TODO OCC25925 ALL: TEST INCOMPLETE" puts "============" puts "OCC5805" diff --git a/tests/bugs/modalg_2/bug5805_46 b/tests/bugs/modalg_2/bug5805_46 index 8f85786fa0..858cb7d908 100755 --- a/tests/bugs/modalg_2/bug5805_46 +++ b/tests/bugs/modalg_2/bug5805_46 @@ -30,7 +30,7 @@ set distance -0.1 catch { OFFSETSHAPE $distance {s_3} $calcul $type } -set square 1470.32 +set square 1485.75 checknbshapes result -vertex 4 -edge 6 -wire 6 -face 5 -shell 1 -solid 1 -compsolid 0 -compound 0 -shape 23 diff --git a/tests/bugs/modalg_3/bug602 b/tests/bugs/modalg_3/bug602 index 0245268c17..f62ee9cec3 100755 --- a/tests/bugs/modalg_3/bug602 +++ b/tests/bugs/modalg_3/bug602 @@ -1,5 +1,6 @@ -puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC12345 ALL: Error : The square of result shape is" +puts "TODO OCC00000 ALL: Faulty OCC602: function BLEND works wrongly" +puts "TODO OCC00000 ALL: Tcl Exception: result is not a topological shape!!!" +puts "TODO OCC00000 ALL: TEST INCOMPLETE" puts "========================" puts " OCC602 " diff --git a/tests/bugs/modalg_5/bug24585_1 b/tests/bugs/modalg_5/bug24585_1 index bd7a99f188..331e6c4be3 100644 --- a/tests/bugs/modalg_5/bug24585_1 +++ b/tests/bugs/modalg_5/bug24585_1 @@ -5,7 +5,8 @@ puts "" ########################################################### # Wrong pcurve of the section curve ########################################################### -set MaxTol 1.05e-6 + +set MaxTol 3.0e-5 set NbCurv_OK 1 restore [locate_data_file bug24585_b1.brep] b1 @@ -50,4 +51,18 @@ if {${delta_l} != 0} { puts "Error: Bad value. U_end = [dval U_end], Ulast = [dval U1l_exp]." } else { puts "OK: Good value. U_end matches with Ulast of surface." -} \ No newline at end of file +} + +puts "" +puts "Check if tangents in first and last point of line have the same directions" + +#See bug#26752 +cvalue c_1 U1 xx yy zz dx1 dy1 dz1 +cvalue c_1 U2 xx yy zz dx2 dy2 dz2 + +set DP [dval dx1*dx2+dy1*dy2+dz1*dz2] +if {${DP} < 0} { + puts "Error: Tangents are reversed. Bug 26752 is reproduced." +} else { + puts "OK: Tangents are not reversed." +} diff --git a/tests/bugs/modalg_5/bug24915 b/tests/bugs/modalg_5/bug24915 index 3cdee87475..69a98c06c6 100755 --- a/tests/bugs/modalg_5/bug24915 +++ b/tests/bugs/modalg_5/bug24915 @@ -1,10 +1,4 @@ -puts "TODO OCC25929 ALL: Error: Tolerance is too big!" - -puts "TODO OCC21564 Linux: Error : T=0.464646\tD=0.000326627" -puts "TODO OCC21564 Linux: Error : T=0.464646\tD=0.00032747" - -puts "TODO OCC21564 Windows: Error : T=0.464646\tD=0.000326671" -puts "TODO OCC21564 Windows: Error : T=0.464646\tD=0.000327516" +puts "TODO OCC26927 ALL: Error: Tolerance is too big!" puts "=========" puts "CR24915" @@ -30,8 +24,8 @@ bbuild r checkshape r # 2. geometry -set MaxTol 5.0e-7 -set log [bopcurves b1 b2] +set MaxTol 1.0e-7 +set log [bopcurves b1 b2 -2d] if { ! [regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv] } { puts "Error: Cannot find tolerance value in output of bopcurve command" @@ -41,18 +35,6 @@ if {${Toler} > ${MaxTol}} { puts "Error: Tolerance is too big!" } -mksurface s1 b1 -mksurface s2 b2 - -set Tolerance 2.0e-5 -set WarnTol 1.0e-7 - -for {set i 1} {$i <= ${NbCurv}} {incr i} { - bounds c_$i U1 U2 - xdistcs c_$i s1 U1 U2 100 $Tolerance $WarnTol - xdistcs c_$i s2 U1 U2 100 $Tolerance $WarnTol -} - smallview donly b2 c_2 fit diff --git a/tests/bugs/modalg_5/bug25319_1 b/tests/bugs/modalg_5/bug25319_1 index 31448b0af1..0e02a42413 100644 --- a/tests/bugs/modalg_5/bug25319_1 +++ b/tests/bugs/modalg_5/bug25319_1 @@ -1,5 +1,3 @@ -puts "TODO OCC26417 ALL: Faulty shapes in variables faulty_1" - puts "================" puts "OCC25319" puts "================" @@ -15,5 +13,5 @@ bcommon result b1 b2 set square 1690.81 -checknbshapes result -vertex 19 -edge 30 -wire 13 -face 13 -shell 1 -solid 1 -compsolid 0 -compound 1 -shape 78 +checknbshapes result -vertex 20 -edge 31 -wire 13 -face 13 -shell 1 -solid 1 -compsolid 0 -compound 1 -shape 80 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug25319_2 b/tests/bugs/modalg_5/bug25319_2 index 60dc3fd113..4ab5d8b534 100644 --- a/tests/bugs/modalg_5/bug25319_2 +++ b/tests/bugs/modalg_5/bug25319_2 @@ -1,5 +1,3 @@ -puts "TODO OCC26417 ALL: Faulty shapes in variables faulty_1" - puts "================" puts "OCC25319" puts "================" @@ -18,5 +16,5 @@ bcommon result b1 b2 set square 1690.81 -checknbshapes result -vertex 19 -edge 30 -wire 13 -face 13 -shell 1 -solid 1 -compsolid 0 -compound 1 -shape 78 +checknbshapes result -vertex 20 -edge 31 -wire 13 -face 13 -shell 1 -solid 1 -compsolid 0 -compound 1 -shape 80 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug25838 b/tests/bugs/modalg_5/bug25838 index 610b6ef56e..c619c1353f 100644 --- a/tests/bugs/modalg_5/bug25838 +++ b/tests/bugs/modalg_5/bug25838 @@ -5,6 +5,8 @@ puts "" ############################################### # Wrong result obtained by General Fuse operator. ############################################### +puts "TODO #OCC26816 ALL: Error : Result done by General Fuse operator is WRONG because number of" +puts "TODO #OCC26816 ALL: Faulty shapes in variables faulty_1 to faulty_" restore [locate_data_file bug25715_p02c3s1.brep] b1 restore [locate_data_file bug25838_p02c3s2.brep] b2 diff --git a/tests/bugs/modalg_6/bug26431_1 b/tests/bugs/modalg_6/bug26431_1 new file mode 100644 index 0000000000..201859a439 --- /dev/null +++ b/tests/bugs/modalg_6/bug26431_1 @@ -0,0 +1,21 @@ +puts "============" +puts "OCC26431" +puts "============" +puts "" +############################### +## Can't cut a sphere from a cylinder +############################### + +restore [locate_data_file bug26431_Body.brep] b1 +restore [locate_data_file bug26431_Sphere.brep] b2 + +explode b1 f +explode b2 f + +set log [bopcurves b1_3 b2_1 -2d] +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Tolerance_Reached NbCurv + +set expected_Tolerance_Reached 6.1899285293702062e-006 +set tol_abs_Tolerance_Reached 1.0e-7 +set tol_rel_Tolerance_Reached 0.0 +checkreal "Tolerance Reached" ${Tolerance_Reached} ${expected_Tolerance_Reached} ${tol_abs_Tolerance_Reached} ${tol_rel_Tolerance_Reached} diff --git a/tests/bugs/modalg_6/bug26431_2 b/tests/bugs/modalg_6/bug26431_2 new file mode 100644 index 0000000000..f593e7cf66 --- /dev/null +++ b/tests/bugs/modalg_6/bug26431_2 @@ -0,0 +1,28 @@ +puts "============" +puts "OCC26431" +puts "============" +puts "" +############################### +## Can't cut a sphere from a cylinder +############################### + +restore [locate_data_file bug26431_Body.brep] b1 +restore [locate_data_file bug26431_Sphere.brep] b2 + +explode b1 f +explode b2 f + +bsection result b1_3 b2_1 + +set log [checksection result] + +if { [string compare -nocase $log " nb alone Vertices : 0\n\n"] } { + puts "ERROR: the section is not closed" +} else { + puts "The section is OK" +} + +smallview +donly result +fit +set only_screen_axo 1 diff --git a/tests/bugs/modalg_6/bug26431_3 b/tests/bugs/modalg_6/bug26431_3 new file mode 100644 index 0000000000..11dde957ce --- /dev/null +++ b/tests/bugs/modalg_6/bug26431_3 @@ -0,0 +1,68 @@ +puts "============" +puts "OCC26431" +puts "============" +puts "" +############################### +## Can't cut a sphere from a cylinder +############################### + +restore [locate_data_file bug26431_Body.brep] b1 +restore [locate_data_file bug26431_Sphere.brep] b2 + +bop b1 b2 +bopcut result + +checkshape result + +decho off +dlog reset +dlog on + +bopargcheck result #F + +set info [dlog get] +dlog reset +dlog off +decho on + +set MessageList { +"Faulties for FIRST shape found : 9" +"Shapes are not suppotrted by BOP: NO" +"Self-Intersections : NO" +"Check for SI has been aborted : NO" +"Too small edges : NO" +"Bad faces : NO" +"Too close vertices : DISABLED" +"Too close edges : DISABLED" +"Shapes with Continuity C0 : YES Cases\\(9\\) Total shapes\\(9\\)" +"Invalid Curve on Surface : NO" +"Faulties for SECOND shape found : 0" +} +for {set i 1} {$i <= 11} {incr i} { + set str [ lindex ${MessageList} [expr $i - 1] ] + if { [regexp ${str} ${info}] == 1 } { + puts "OK : There is #$i message" + } else { + puts "Error : There is not #$i message" + puts $str + } +} + +set square 14.4399 + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 7 + EDGE : 20 + WIRE : 7 + FACE : 6 + SHELL : 1 + SOLID : 1 + COMPSOLID : 0 + COMPOUND : 1 + SHAPE : 43 +" +checknbshapes result -ref ${nbshapes_expected} -t -m "solid construction" + + +set 3dviewer 1 diff --git a/tests/bugs/modalg_6/bug26675 b/tests/bugs/modalg_6/bug26675 new file mode 100644 index 0000000000..17dc5f0f7c --- /dev/null +++ b/tests/bugs/modalg_6/bug26675 @@ -0,0 +1,58 @@ +puts "============" +puts "OCC26675" +puts "============" +puts "" +############################### +## 0026675: Eliminate normalization of coordinates in ApproxInt package +############################### + +set GoodNbCurv 1 + +pload QAcommands +OCC26675_1 ss + +intersect res ss_1 ss_2 + +set che [whatis res] +set ind [string first "3d curve" $che] +if {${ind} >= 0} { + #Only variable "res" exists + renamevar res res_1 +} + + +set ic 1 +set AllowRepeate 1 +while { $AllowRepeate != 0 } { + set che [whatis res_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 + } else { + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" + } + + xdistcs res_$ic ss_1 U1 U2 10 4.6e-6 + xdistcs res_$ic ss_2 U1 U2 10 4.3e-6 + + incr ic + } +} + +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Curve Number is good!" +} else { + puts "Error: Curve Number is bad!" +} + +smallview +fit +set only_screen_axo 1 diff --git a/tests/draft/angle/G2 b/tests/draft/angle/G2 index c6579f443b..e3742e608a 100755 --- a/tests/draft/angle/G2 +++ b/tests/draft/angle/G2 @@ -1,8 +1,4 @@ #E6---------------------------------------------- -#puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC26426 ALL: Error: The tolerance of the resulting shape is too big " - - ptorus pt 25 24 90 profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \ t -7 0 @@ -12,5 +8,4 @@ nexplode f f depouille result f 0 0 1 f_5 3 0 0 35 0 0 1 \ f_6 3 0 0 35 0 0 1 -# square is different according to issue 25111, the result is visually good but invalid (bad orientation of subshape), that's why the area may occur negative set square 10782.8 diff --git a/tests/offset/shape/A1 b/tests/offset/shape/A1 index a85e2345f0..b0799889c5 100644 --- a/tests/offset/shape/A1 +++ b/tests/offset/shape/A1 @@ -1,11 +1,13 @@ -puts "TODO OCC23068 ALL: Error : The offset is not valid" -puts "TODO OCC26556 ALL: ERROR. offsetperform operation not done." # Original bug : hkg60144 -# Date : 17Juillet98 +# Date : July, 17 1998 + +puts "TODO OCC23068 Linux: Error : The offset is not valid" +puts "TODO OCC23068 Linux: ERROR. offsetperform operation not done." +puts "TODO OCC23068 Linux: Error : The volume of the resulting shape is" restore [locate_data_file CHE900_hkg60iob.rle] s explode s f offsetshape result s -5 s_1 -set volume 0 +set volume 2.12817e+006 diff --git a/tests/offset/with_intersect_80/L6 b/tests/offset/with_intersect_80/L6 index 303c6b847a..05aed64a79 100644 --- a/tests/offset/with_intersect_80/L6 +++ b/tests/offset/with_intersect_80/L6 @@ -1,6 +1,5 @@ puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape" puts "TODO OCC26577 All: Error : is WRONG because number of SHELL entities in shape" -puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty" restore [locate_data_file bug26663_test_offset_L6.brep] s OFFSETSHAPE ${off_param} {} ${calcul} ${type} checknbshapes result -ref [lrange [nbshapes s] 8 19]