From: nbv Date: Wed, 11 Nov 2015 10:05:04 +0000 (+0300) Subject: Patch from CR26675_4 branch (to OCCT 6.9.0). X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR0_690_FixRI;p=occt-copy.git Patch from CR26675_4 branch (to OCCT 6.9.0). Attention! This patch is pared-down (in compare with CR26675_4). It includes elimination of normalization only and function CleanWline() (without addition changes, which are in CR26675_4 branch). --- diff --git a/src/ApproxInt/ApproxInt_Approx.gxx b/src/ApproxInt/ApproxInt_Approx.gxx index 6b90d71292..f5cfeb1ddb 100644 --- a/src/ApproxInt/ApproxInt_Approx.gxx +++ b/src/ApproxInt/ApproxInt_Approx.gxx @@ -26,121 +26,6 @@ const Standard_Integer LimRajout = 5; const Standard_Integer NbPntMaxDecoupage = 30 ; const Standard_Real RatioTol = 1.5 ; -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); -} - -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); -} - -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_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; - } -//-deb- cout << "ComputeTrsf3d -- NbPnt = " << nbp << endl ; -//-deb- cout << "ComputeTrsf3d -- Xm = " << x0 << " Ym = " << y0 << " Zm = " << z0 << endl ; -//-deb- cout << "ComputeTrsf3d -- XM = " << x1 << " YM = " << y1 << " ZM = " << z1 << endl ; - 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; - - //-- lbr le 22 fev99 : FPE - 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; } -} - -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.) { - 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 du = (u1-u0); - Standard_Real dv = (v1-v0); - - if (UVResRatio > 1.) - du *= UVResRatio; - else if (UVResRatio < 1.) - dv /= UVResRatio; - - 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; } -} - - - ApproxInt_Approx::ApproxInt_Approx(): myComputeLine(4, 8, @@ -197,25 +82,7 @@ void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline, Standard_Integer imax = imin + nbpntbez; myTolReached = Standard_True; - Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v; - if(ApproxXYZ) { - ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az); - } - else { - Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;; - } - if(ApproxU1V1) { - ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True); - } - else { - U1o=V1o=0.0; A1u=A1v=1.0; - } - if(ApproxU2V2) { - ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False); - } - else { - U2o=V2o=0.0; A2u=A2v=1.0; - } + Standard_Real Xo = 0.0, Ax = 1.0, Yo = 0.0, Ay = 1.0, Zo = 0.0, Az = 1.0, U1o = 0.0, A1u = 1.0, V1o = 0.0, A1v = 1.0, U2o = 0.0, A2u = 1.0, V2o = 0.0, A2v = 1.0; //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ; //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ; @@ -225,16 +92,9 @@ void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline, //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; - - Standard_Real A3d = MINABS3(Ax,Ay,Az); - if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { - myMinFactorXYZ = A3d; - } - - Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v); - if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { - myMinFactorUV = A2d; - } + + myMinFactorXYZ = Ax; + myMinFactorUV = A1u; Standard_Boolean cut=Standard_True; Approx_ParametrizationType parametrization; @@ -409,29 +269,7 @@ void ApproxInt_Approx::Perform(const ThePSurface& Surf1, myTolReached = Standard_True; - Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v; - if(ApproxXYZ) { - ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az); - } - else { - Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;; - } - if(ApproxU1V1) { - Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf1,1.)/ - ThePSurfaceTool::VResolution(Surf1,1.); - ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio); - } - else { - U1o=V1o=0.0; A1u=A1v=1.0; - } - if(ApproxU2V2) { - Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf2,1.)/ - ThePSurfaceTool::VResolution(Surf2,1.); - ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio); - } - else { - U2o=V2o=0.0; A2u=A2v=1.0; - } + Standard_Real Xo = 0.0, Ax = 1.0, Yo = 0.0, Ay = 1.0, Zo = 0.0, Az = 1.0, U1o = 0.0, A1u = 1.0, V1o = 0.0, A1v = 1.0, U2o = 0.0, A2u = 1.0, V2o = 0.0, A2v = 1.0; //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ; //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ; @@ -442,17 +280,8 @@ void ApproxInt_Approx::Perform(const ThePSurface& Surf1, //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; - - Standard_Real A3d = MINABS3(Ax,Ay,Az); - if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { - myMinFactorXYZ = A3d; - } - - Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v); - if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { - myMinFactorUV = A2d; - } - + myMinFactorXYZ = Ax; + myMinFactorUV = A1u; Approx_ParametrizationType parametrization; myComputeLineBezier.Parametrization(parametrization); @@ -752,27 +581,7 @@ void ApproxInt_Approx::Perform(const ThePSurface& PSurf, Standard_Integer imin = indicemin; Standard_Integer imax = imin + nbpntbez; myTolReached = Standard_True; - Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v; - if(ApproxXYZ) { - ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az); - } - else { - Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;; - } - if(ApproxU1V1) { - Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/ - ThePSurfaceTool::VResolution(PSurf,1.); - ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio); - } - else { - U1o=V1o=0.0; A1u=A1v=1.0; - } - if(ApproxU2V2) { - ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False); - } - else { - U2o=V2o=0.0; A2u=A2v=1.0; - } + Standard_Real Xo = 0.0, Ax = 1.0, Yo = 0.0, Ay = 1.0, Zo = 0.0, Az = 1.0, U1o = 0.0, A1u = 1.0, V1o = 0.0, A1v = 1.0, U2o = 0.0, A2u = 1.0, V2o = 0.0, A2v = 1.0; //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ; //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ; @@ -783,16 +592,8 @@ void ApproxInt_Approx::Perform(const ThePSurface& PSurf, //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; - - Standard_Real A3d = MINABS3(Ax,Ay,Az); - if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { - myMinFactorXYZ = A3d; - } - - Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v); - if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { - myMinFactorUV = A2d; - } + myMinFactorXYZ = Ax; + myMinFactorUV = A1u; myComputeLineBezier.Parametrization(parametrization); @@ -963,27 +764,7 @@ void ApproxInt_Approx::Perform(const TheISurface& ISurf, Standard_Integer imax = imin + nbpntbez; myTolReached = Standard_True; - Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v; - if(ApproxXYZ) { - ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az); - } - else { - Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;; - } - if(ApproxU1V1) { - ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True); - } - else { - U1o=V1o=0.0; A1u=A1v=1.0; - } - if(ApproxU2V2) { - Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/ - ThePSurfaceTool::VResolution(PSurf,1.); - ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio); - } - else { - U2o=V2o=0.0; A2u=A2v=1.0; - } + Standard_Real Xo = 0.0, Ax = 1.0, Yo = 0.0, Ay = 1.0, Zo = 0.0, Az = 1.0, U1o = 0.0, A1u = 1.0, V1o = 0.0, A1v = 1.0, U2o = 0.0, A2u = 1.0, V2o = 0.0, A2v = 1.0; //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ; //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ; @@ -994,16 +775,8 @@ void ApproxInt_Approx::Perform(const TheISurface& ISurf, //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; - - Standard_Real A3d = MINABS3(Ax,Ay,Az); - if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { - myMinFactorXYZ = A3d; - } - - Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v); - if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { - myMinFactorUV = A2d; - } + myMinFactorXYZ = Ax; + myMinFactorUV = A1u; Approx_ParametrizationType parametrization; myComputeLineBezier.Parametrization(parametrization); diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index 1ecb466ea9..cd6337ae84 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -243,6 +243,136 @@ static void JoinWLines(IntPatch_SequenceOfLine& theSlin, } } +//======================================================================= +//function : CleanWline +//purpose : Iterates set of points in theWline and removes several of it +// if they led to too non-uniform distribution. +//ATTENTION!!! +// 1. Removed point must not be vertex. +// 2. In the future, this method should be improved to make it more universal. +// Now, it is created only in order to avoid regressions. +//======================================================================= +static void CleanWline( const GeomAbs_SurfaceType theTypeS1, + const GeomAbs_SurfaceType theTypeS2, + const Handle(IntPatch_WLine)& theWline) +{ + const Standard_Real aFactor = 100.0; + const Standard_Integer aNbVertices = theWline->NbVertex(); + + Standard_Boolean isSurfS1WithSeam = (theTypeS1 == GeomAbs_Cylinder) || + (theTypeS1 == GeomAbs_Cone) || + (theTypeS1 == GeomAbs_Sphere) || + (theTypeS1 == GeomAbs_Torus) || + (theTypeS1 == GeomAbs_SurfaceOfRevolution), + isSurfS2WithSeam = (theTypeS2 == GeomAbs_Cylinder) || + (theTypeS2 == GeomAbs_Cone) || + (theTypeS2 == GeomAbs_Sphere) || + (theTypeS2 == GeomAbs_Torus) || + (theTypeS2 == GeomAbs_SurfaceOfRevolution); + + if(!isSurfS1WithSeam && !isSurfS2WithSeam) + return; + + //Sometimes WLine contains several vertices which have same ParameterOnLine + //(i.e. one IntSurf_PntOn2S is marked by several vertices). + //However, neighbour points should be deleted once. To provide it, we enter + //following variable. + Standard_Integer aVertIndPrev = -1; + + for(Standard_Integer aVertID = 1; aVertID <= aNbVertices; aVertID++) + { + Standard_Integer aRemoveInd = -1; + const IntPatch_Point& aVert = theWline->Vertex(aVertID); + + { + //Consider only vertices which in the seam. Another vertices are rejected. + Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0; + aVert.Parameters(u1, v1, u2, v2); + if( (!isSurfS1WithSeam || (!IsEqual(u1, 0.0) && !IsEqual(u1, 2.0*M_PI))) && + (!isSurfS2WithSeam || (!IsEqual(u2, 0.0) && !IsEqual(u2, 2.0*M_PI)))) + continue; + } + + const Standard_Integer aVertInd = static_cast(aVert.ParameterOnLine()); + + if(aVertInd == aVertIndPrev) + {//Go to the next vertex, whose ParameterOnLine is different from aVertInd. + continue; + } + + aVertIndPrev = aVertInd; + + //This condition should be removed (it is added in order to make checking easier) + if((aVertInd == 1) || (aVertInd == theWline->NbPnts())) + continue; + + const gp_Pnt &aPCurr = aVert.Value(); + const gp_Pnt &aPPrev = theWline->Curve()->Value(aVertInd-1).Value(), + &aPNext = theWline->Curve()->Value(aVertInd+1).Value(); + + const Standard_Real aSqD1 = aPCurr.SquareDistance(aPPrev), + aSqD2 = aPCurr.SquareDistance(aPNext); + + if(aSqD1 > aFactor*aSqD2) + { + aRemoveInd = aVertInd+1; + + //Check, if removed point is not the Vertex + if(aVertID < aNbVertices) + { + Standard_Integer aNextVertParam = static_cast(theWline->Vertex(aVertID+1).ParameterOnLine()); + if(aNextVertParam == aRemoveInd) + {//The candidate is the Vertex. Removing is forbidden. + aRemoveInd = -1; + } + } + } + else if(aSqD2 > aFactor*aSqD1) + { + aRemoveInd = aVertInd-1; + + //Check, if removed point is not the Vertex + if(aVertID > 1) + { + Standard_Integer aNextVertParam = static_cast(theWline->Vertex(aVertID-1).ParameterOnLine()); + if(aNextVertParam == aRemoveInd) + {//The candidate is the Vertex. Removing is forbidden. + aRemoveInd = -1; + } + } + } + else + { + aRemoveInd = -1; + } + + if(aRemoveInd < 1) + continue; + + //Removing + theWline->Curve()->RemovePoint(aRemoveInd); + + //After removing points, ParameterOnLine for some vertices should be shifted + //(usualy it means the number of this vertex in + //the sequence of Walking-line points). + for(Standard_Integer aVID = 1; aVID <= aNbVertices; aVID++) + { + const Standard_Integer aVertParam = + static_cast(theWline->Vertex(aVID).ParameterOnLine()); + + if(aVertParam < aRemoveInd) + continue; + + IntPatch_Point aVertTemp(theWline->Vertex(aVID)); + aVertTemp.SetParameter(aVertParam-1); + theWline->Replace(aVID, aVertTemp); + + if(aVID == aVertID) + aVertIndPrev--; + } + }//for(Standard_Integer aVertID = 1; aVertID <= aNbVertices; aVertID++) +} + //====================================================================== // function: SequenceOfLine //====================================================================== @@ -1159,8 +1289,17 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); } + + for(Standard_Integer i = 1; i <= slin.Length(); i++) + { + const Handle(IntPatch_WLine) WL = Handle(IntPatch_WLine)::DownCast(slin(i)); + + if(!WL.IsNull()) + CleanWline(typs1, typs2, WL); + } } + //======================================================================= //function : Perform //purpose : @@ -1378,8 +1517,17 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); } } + + for(Standard_Integer i = 1; i <= slin.Length(); i++) + { + const Handle(IntPatch_WLine) WL = Handle(IntPatch_WLine)::DownCast(slin(i)); + + if(!WL.IsNull()) + CleanWline(typs1, typs2, WL); + } } + //======================================================================= //function : ParamParamPerfom //purpose :