1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

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).
This commit is contained in:
nbv
2015-11-11 13:05:04 +03:00
parent b3b55601fb
commit e03e39296e
2 changed files with 161 additions and 240 deletions

View File

@@ -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(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,
@@ -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 ;
@@ -226,15 +93,8 @@ void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
//-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);

View File

@@ -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<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
//======================================================================
@@ -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 :