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(X<x0) x0=X;
- if(X>x1) x1=X;
- if(Y<y0) y0=Y;
- if(Y>y1) y1=Y;
- if(Z<z0) z0=Z;
- if(Z>z1) 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(U<u0) u0=U;
- if(U>u1) u1=U;
- if(V<v0) v0=V;
- if(V>v1) 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<dv) MaxUV=dv;
-
- Standard_Real MaxUVF=0.01*MaxUV;
-
- //-- lbr le 22 fev 99 (FPE)
- if(MaxUVF<1e-12)
- MaxUVF=1.0;
-
- if(du > 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,
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 ;
//-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;
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 ;
//-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);
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 ;
//-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);
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 ;
//-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);
}
}
+//=======================================================================
+//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<Standard_Integer>(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<Standard_Integer>(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<Standard_Integer>(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<Standard_Integer>(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
//======================================================================
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 :
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 :