1 // Created on: 1993-03-30
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <AppParCurves_Constraint.hxx>
18 #include <GeomAbs_SurfaceType.hxx>
19 #include <IntSurf_Quadric.hxx>
20 #include <gp_Trsf.hxx>
21 #include <gp_Trsf2d.hxx>
22 #include <IntSurf_PntOn2S.hxx>
23 #include <Precision.hxx>
25 const Standard_Integer LimRajout = 5;
26 const Standard_Integer NbPntMaxDecoupage = 30 ;
27 const Standard_Real RatioTol = 1.5 ;
29 static Standard_Real MINABS3(Standard_Real a, Standard_Real b,Standard_Real c) {
38 static Standard_Real MINABS4(Standard_Real a, Standard_Real b,Standard_Real c,Standard_Real d) {
49 static void ComputeTrsf3d(const Handle(TheWLine)& theline,
50 Standard_Real& Xo, Standard_Real& Ax,
51 Standard_Real& Yo, Standard_Real& Ay,
52 Standard_Real& Zo, Standard_Real& Az) {
54 Standard_Integer nbp = theline->NbPnts();
55 Standard_Real z0,z1,x0,x1,y0,y1;
58 for(Standard_Integer i=1;i<=nbp;i++) {
59 const gp_Pnt& P = theline->Point(i).Value();
60 Standard_Real X = P.X();
61 Standard_Real Y = P.Y();
62 Standard_Real Z = P.Z();
70 //-deb- cout << "ComputeTrsf3d -- NbPnt = " << nbp << endl ;
71 //-deb- cout << "ComputeTrsf3d -- Xm = " << x0 << " Ym = " << y0 << " Zm = " << z0 << endl ;
72 //-deb- cout << "ComputeTrsf3d -- XM = " << x1 << " YM = " << y1 << " ZM = " << z1 << endl ;
73 Standard_Real dx = x1-x0;
74 Standard_Real dy = y1-y0;
75 Standard_Real dz = z1-z0;
76 Standard_Real MaxD = dx;
77 if(MaxD < dy) MaxD=dy;
78 if(MaxD < dz) MaxD=dz;
79 Standard_Real MaxDF = 0.01*MaxD;
81 //-- lbr le 22 fev99 : FPE
86 if(dx > MaxDF) { Ax = 1.0 / dx; Xo = -Ax * x0; }
87 else { Ax = 1.0/( MaxDF) ; Xo = -Ax*x0; }
88 if(dy > MaxDF) { Ay = 1.0 / dy; Yo = -Ay * y0; }
89 else { Ay = 1.0/( MaxDF); Yo = -Ay*y0; }
90 if(dz > MaxDF) { Az = 1.0 / dz; Zo = -Az * z0; }
91 else { Az = 1.0/(MaxDF); Zo = -Az*z0; }
94 static void ComputeTrsf2d(const Handle(TheWLine)& theline,
95 Standard_Real& Uo, Standard_Real& Au,
96 Standard_Real& Vo, Standard_Real& Av,
97 const Standard_Boolean onFirst,
98 const Standard_Real UVResRatio = 1.) {
99 Standard_Integer nbp = theline->NbPnts();
100 Standard_Real u0,u1,v0,v1;
101 u0 = v0 = RealLast();
102 u1 = v1 = RealFirst();
103 // pointer to a member-function
104 void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
106 pfunc = &IntSurf_PntOn2S::ParametersOnS1;
108 pfunc = &IntSurf_PntOn2S::ParametersOnS2;
109 for(Standard_Integer i=1;i<=nbp;i++) {
110 const IntSurf_PntOn2S& POn2S = theline->Point(i);
119 Standard_Real du = (u1-u0);
120 Standard_Real dv = (v1-v0);
124 else if (UVResRatio < 1.)
127 Standard_Real MaxUV=du;
128 if(MaxUV<dv) MaxUV=dv;
130 Standard_Real MaxUVF=0.01*MaxUV;
132 //-- lbr le 22 fev 99 (FPE)
136 if(du > MaxUVF) { Au = 1.0 / du; Uo = -Au * u0; }
137 else { Au = 1.0/(MaxUVF); Uo = -Au*u0; }
138 if(dv > MaxUVF) { Av = 1.0 / dv; Vo = -Av * v0; }
139 else { Av = 1.0/(MaxUVF); Vo = -Av*v0; }
144 ApproxInt_Approx::ApproxInt_Approx():
151 myComputeLineBezier(4,
158 myComputeLine.SetContinuity(2);
159 //-- myComputeLineBezier.SetContinuity(2);
160 myApproxBez = Standard_True;
162 myRelativeTol = Standard_True ;
163 myNbPntMax = NbPntMaxDecoupage ;
164 myMinFactorXYZ = 0.0;
166 myTolReached3d = myTolReached2d = 0.;
170 void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
171 const Standard_Boolean ApproxXYZ,
172 const Standard_Boolean ApproxU1V1,
173 const Standard_Boolean ApproxU2V2,
174 const Standard_Integer indicemin,
175 const Standard_Integer indicemax) {
177 myMinFactorXYZ = 0.0;
179 myTolReached3d = myTolReached2d = 0.;
182 Standard_Integer nbpntbez = indicemax-indicemin;
183 Standard_Integer nbpntmax = myNbPntMax;
184 Standard_Boolean OtherInter = Standard_False;
185 if(nbpntbez < LimRajout)
186 myApproxBez = Standard_False;
188 myApproxBez = Standard_True;
191 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
193 nbpntbez = (indicemax-indicemin)/nbi;
196 Standard_Integer imin = indicemin;
197 Standard_Integer imax = imin + nbpntbez;
198 myTolReached = Standard_True;
200 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
202 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
205 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
208 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
211 U1o=V1o=0.0; A1u=A1v=1.0;
214 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
217 U2o=V2o=0.0; A2u=A2v=1.0;
220 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
221 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
222 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
223 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
224 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
225 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
226 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
227 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
229 Standard_Real A3d = MINABS3(Ax,Ay,Az);
230 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
231 myMinFactorXYZ = A3d;
234 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
235 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
239 Standard_Boolean cut=Standard_True;
240 Approx_ParametrizationType parametrization;
241 myComputeLineBezier.Parametrization(parametrization);
243 if(myRelativeTol==Standard_False) {
245 myComputeLine.Init(myDegMin,
247 myTol3d*myMinFactorXYZ,
248 myTol2d*myMinFactorUV,
252 myComputeLineBezier.Init(myDegMin,
254 myTol3d*myMinFactorXYZ,
255 myTol2d*myMinFactorUV,
262 ApproxInt_TheMultiLine myMultiLine(theline,
263 ((ApproxXYZ)? 1 : 0),
264 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
265 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
271 myComputeLineBezier.Perform(myMultiLine);
272 if (myComputeLineBezier.NbMultiCurves() == 0)
274 myTolReached&=myComputeLineBezier.IsToleranceReached();
277 myComputeLine.Perform(myMultiLine);
281 Standard_Integer indice3d,indice2d1,indice2d2;
285 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
286 if(!ApproxU1V1) { indice2d2--; }
288 Standard_Real ax,bx,ay,by,az,bz;
289 ax = 1.0/Ax; bx = -Xo*ax;
290 ay = 1.0/Ay; by = -Yo*ay;
291 az = 1.0/Az; bz = -Zo*az;
293 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
294 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
298 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
302 Standard_Real ax,bx,ay,by;
303 ax = 1.0/A1u; bx = -U1o*ax;
304 ay = 1.0/A1v; by = -V1o*ay;
306 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
307 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
311 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
315 Standard_Real ax,bx,ay,by;
316 ax = 1.0/A2u; bx = -U2o*ax;
317 ay = 1.0/A2v; by = -V2o*ay;
319 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
320 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
324 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
328 OtherInter = Standard_False;
330 for(Standard_Integer nbmc = 1;
331 nbmc <= myComputeLineBezier.NbMultiCurves() ;
333 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
338 imax = imin+nbpntbez;
339 OtherInter = Standard_True;
340 if((indicemax-imax)<(nbpntbez/2))
344 imax = CorrectFinishIdx(imin, imax, theline);
350 myBezToBSpl.Perform();
354 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
355 const ThePSurface& Surf2,
356 const Handle(TheWLine)& theline,
357 const Standard_Boolean ApproxXYZ,
358 const Standard_Boolean ApproxU1V1,
359 const Standard_Boolean ApproxU2V2,
360 const Standard_Integer indicemin,
361 const Standard_Integer indicemax) {
362 myMinFactorXYZ = 0.0;
364 myTolReached3d = myTolReached2d = 0.;
366 GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
367 GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
368 if ((typeS1 != GeomAbs_Plane &&
369 typeS1 != GeomAbs_Cylinder &&
370 typeS1 != GeomAbs_Sphere &&
371 typeS1 != GeomAbs_Cone)
373 (typeS2 != GeomAbs_Plane &&
374 typeS2 != GeomAbs_Cylinder &&
375 typeS2 != GeomAbs_Sphere &&
376 typeS2 != GeomAbs_Cone)) {
378 //------------------------------------------------------------
379 //-- Construction du SvSurfaces
380 //------------------------------------------------------------
381 ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
382 //------------------------------------------------------------
383 //-- Construction de la MultiLine
384 //------------------------------------------------------------
385 Standard_Integer nbpntbez = indicemax-indicemin;
386 Standard_Integer nbpntmax = myNbPntMax;
387 Standard_Boolean OtherInter = Standard_False;
389 if(nbpntbez < LimRajout)
390 myApproxBez = Standard_False;
392 myApproxBez = Standard_True;
394 Standard_Address ptrsvsurf = NULL;
395 Standard_Boolean cut = Standard_True;
396 if(nbpntbez < LimRajout) {
397 cut = Standard_False;
398 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
400 ptrsvsurf = &myPrmPrmSvSurfaces;
405 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
407 nbpntbez = (indicemax-indicemin)/nbi;
410 Standard_Integer imin = indicemin;
411 Standard_Integer imax = imin + nbpntbez;
412 myTolReached = Standard_True;
415 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
417 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
420 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
423 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf1,1.)/
424 ThePSurfaceTool::VResolution(Surf1,1.);
425 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
428 U1o=V1o=0.0; A1u=A1v=1.0;
431 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf2,1.)/
432 ThePSurfaceTool::VResolution(Surf2,1.);
433 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
436 U2o=V2o=0.0; A2u=A2v=1.0;
439 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
440 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
441 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
442 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
443 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
444 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
445 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
446 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
449 Standard_Real A3d = MINABS3(Ax,Ay,Az);
450 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
451 myMinFactorXYZ = A3d;
454 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
455 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
460 Approx_ParametrizationType parametrization;
461 myComputeLineBezier.Parametrization(parametrization);
463 if(myRelativeTol==Standard_False) {
464 myComputeLine.Init(myDegMin,
466 myTol3d*myMinFactorXYZ,
467 myTol2d*myMinFactorUV,
471 myComputeLineBezier.Init(myDegMin,
473 myTol3d*myMinFactorXYZ,
474 myTol2d*myMinFactorUV,
480 myComputeLine.Init(myDegMin,
487 myComputeLineBezier.Init(myDegMin,
500 ApproxInt_TheMultiLine myMultiLine(theline,
502 ((ApproxXYZ)? 1 : 0),
503 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
504 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
510 myComputeLineBezier.Perform(myMultiLine);
511 if (myComputeLineBezier.NbMultiCurves() == 0)
513 myTolReached&=myComputeLineBezier.IsToleranceReached();
516 myComputeLine.Perform(myMultiLine);
520 Standard_Integer indice3d,indice2d1,indice2d2;
524 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
525 if(!ApproxU1V1) { indice2d2--; }
527 Standard_Real ax,bx,ay,by,az,bz;
528 ax = 1.0/Ax; bx = -Xo*ax;
529 ay = 1.0/Ay; by = -Yo*ay;
530 az = 1.0/Az; bz = -Zo*az;
532 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
533 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
537 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
541 Standard_Real ax,bx,ay,by;
542 ax = 1.0/A1u; bx = -U1o*ax;
543 ay = 1.0/A1v; by = -V1o*ay;
545 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
546 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
550 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
554 Standard_Real ax,bx,ay,by;
555 ax = 1.0/A2u; bx = -U2o*ax;
556 ay = 1.0/A2v; by = -V2o*ay;
558 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
559 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
563 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
566 OtherInter = Standard_False;
568 for(Standard_Integer nbmc = 1;
569 nbmc <= myComputeLineBezier.NbMultiCurves() ;
571 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
576 imax = imin+nbpntbez;
577 OtherInter = Standard_True;
578 if((indicemax-imax)<(nbpntbez/2))
582 imax = CorrectFinishIdx(imin, imax, theline);
588 myBezToBSpl.Perform();
593 IntSurf_Quadric Quad;
594 Standard_Boolean SecondIsImplicit=Standard_False;
598 Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
601 case GeomAbs_Cylinder:
602 Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
606 Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
610 Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
615 SecondIsImplicit = Standard_True;
618 Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
621 case GeomAbs_Cylinder:
622 Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
626 Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
630 Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
639 if(SecondIsImplicit) {
640 Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
643 Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
647 //--------------------------------------------------------------------------------
648 void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d,
649 const Standard_Real Tol2d,
650 const Standard_Integer DegMin,
651 const Standard_Integer DegMax,
652 const Standard_Integer NbIterMax,
653 const Standard_Boolean ApproxWithTangency,
654 const Approx_ParametrizationType Parametrization) {
655 myWithTangency = ApproxWithTangency;
656 myTol3d = Tol3d / RatioTol;
657 myTol2d = Tol2d / RatioTol;
660 myNbIterMax = NbIterMax;
661 myComputeLine.Init(myDegMin,
669 if(!ApproxWithTangency) {
670 myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
672 myComputeLineBezier.Init(myDegMin,
679 if(!ApproxWithTangency) {
680 myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
682 myApproxBez = Standard_True;
685 void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d,
686 const Standard_Real Tol2d,
687 const Standard_Boolean RelativeTol,
688 const Standard_Integer DegMin,
689 const Standard_Integer DegMax,
690 const Standard_Integer NbIterMax,
691 const Standard_Integer NbPntMax,
692 const Standard_Boolean ApproxWithTangency,
693 const Approx_ParametrizationType Parametrization)
695 myNbPntMax = NbPntMax ;
696 myRelativeTol = RelativeTol ;
697 SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ;
700 //--------------------------------------------------------------------------------
701 void ApproxInt_Approx::Perform(const ThePSurface& PSurf,
702 const TheISurface& ISurf,
703 const Handle(TheWLine)& theline,
704 const Standard_Boolean ApproxXYZ,
705 const Standard_Boolean ApproxU1V1,
706 const Standard_Boolean ApproxU2V2,
707 const Standard_Integer indicemin,
708 const Standard_Integer indicemax)
710 myMinFactorXYZ = 0.0;
712 myTolReached3d = myTolReached2d = 0.;
714 ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf);
715 Standard_Integer nbpntbez = indicemax-indicemin;
716 Standard_Integer nbpntmax = myNbPntMax;
717 Standard_Boolean OtherInter = Standard_False;
718 if(nbpntbez < LimRajout)
719 myApproxBez = Standard_False;
721 myApproxBez = Standard_True;
723 Standard_Address ptrsvsurf = NULL;
724 Standard_Boolean cut = Standard_True;
725 if(nbpntbez < LimRajout) {
726 cut = Standard_False;
727 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
731 Approx_ParametrizationType parametrization;
732 myComputeLineBezier.Parametrization(parametrization);
735 ptrsvsurf = &myImpPrmSvSurfaces;
736 myComputeLine.Init(myDegMin,
744 myComputeLineBezier.Init(myDegMin,
753 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
755 nbpntbez = (indicemax-indicemin)/nbi;
758 Standard_Integer imin = indicemin;
759 Standard_Integer imax = imin + nbpntbez;
760 myTolReached = Standard_True;
761 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
763 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
766 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
769 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
770 ThePSurfaceTool::VResolution(PSurf,1.);
771 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
774 U1o=V1o=0.0; A1u=A1v=1.0;
777 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
780 U2o=V2o=0.0; A2u=A2v=1.0;
783 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
784 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
785 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
786 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
787 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
788 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
789 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
790 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
793 Standard_Real A3d = MINABS3(Ax,Ay,Az);
794 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
795 myMinFactorXYZ = A3d;
798 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
799 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
803 myComputeLineBezier.Parametrization(parametrization);
805 if(myRelativeTol==Standard_False) {
806 myComputeLine.Init(myDegMin,
808 myTol3d*myMinFactorXYZ,
809 myTol2d*myMinFactorUV,
813 myComputeLineBezier.Init(myDegMin,
815 myTol3d*myMinFactorXYZ,
816 myTol2d*myMinFactorUV,
822 myComputeLine.Init(myDegMin,
829 myComputeLineBezier.Init(myDegMin,
841 ApproxInt_TheMultiLine myMultiLine(theline,
843 ((ApproxXYZ)? 1 : 0),
844 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
845 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
850 myComputeLineBezier.Perform(myMultiLine);
851 if (myComputeLineBezier.NbMultiCurves() == 0)
853 myTolReached&=myComputeLineBezier.IsToleranceReached();
856 myComputeLine.Perform(myMultiLine);
859 Standard_Integer indice3d,indice2d1,indice2d2;
863 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
864 if(!ApproxU1V1) { indice2d2--; }
866 Standard_Real ax,bx,ay,by,az,bz;
867 ax = 1.0/Ax; bx = -Xo*ax;
868 ay = 1.0/Ay; by = -Yo*ay;
869 az = 1.0/Az; bz = -Zo*az;
871 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
872 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
876 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
880 Standard_Real ax,bx,ay,by;
881 ax = 1.0/A1u; bx = -U1o*ax;
882 ay = 1.0/A1v; by = -V1o*ay;
884 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
885 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
889 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
893 Standard_Real ax,bx,ay,by;
894 ax = 1.0/A2u; bx = -U2o*ax;
895 ay = 1.0/A2v; by = -V2o*ay;
897 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
898 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
902 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
905 OtherInter = Standard_False;
907 for(Standard_Integer nbmc = 1;
908 nbmc <= myComputeLineBezier.NbMultiCurves() ;
910 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
915 imax = imin+nbpntbez;
916 OtherInter = Standard_True;
917 if((indicemax-imax)<(nbpntbez/2))
921 imax = CorrectFinishIdx(imin, imax, theline);
927 myBezToBSpl.Perform();
930 //--------------------------------------------------------------------------------
931 void ApproxInt_Approx::Perform(const TheISurface& ISurf,
932 const ThePSurface& PSurf,
933 const Handle(TheWLine)& theline,
934 const Standard_Boolean ApproxXYZ,
935 const Standard_Boolean ApproxU1V1,
936 const Standard_Boolean ApproxU2V2,
937 const Standard_Integer indicemin,
938 const Standard_Integer indicemax)
941 myMinFactorXYZ = 0.0;
943 myTolReached3d = myTolReached2d = 0.;
945 ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf,PSurf);
946 Standard_Integer nbpntbez = indicemax-indicemin;
948 Standard_Boolean cut = Standard_True;
949 if(nbpntbez < LimRajout)
950 myApproxBez = Standard_False;
952 myApproxBez = Standard_True;
954 if(nbpntbez < LimRajout) {
955 cut = Standard_False;
956 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
958 Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
960 if(nbpntbez < LimRajout) myApproxBez = Standard_False;
962 Standard_Integer nbpntmax = myNbPntMax;
963 Standard_Boolean OtherInter = Standard_False;
966 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
968 nbpntbez = (indicemax-indicemin)/nbi;
971 Standard_Integer imin = indicemin;
972 Standard_Integer imax = imin + nbpntbez;
973 myTolReached = Standard_True;
975 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
977 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
980 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
983 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
986 U1o=V1o=0.0; A1u=A1v=1.0;
989 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
990 ThePSurfaceTool::VResolution(PSurf,1.);
991 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
994 U2o=V2o=0.0; A2u=A2v=1.0;
997 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
998 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
999 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
1000 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
1001 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
1002 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
1003 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
1004 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
1007 Standard_Real A3d = MINABS3(Ax,Ay,Az);
1008 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
1009 myMinFactorXYZ = A3d;
1012 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
1013 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
1014 myMinFactorUV = A2d;
1017 Approx_ParametrizationType parametrization;
1018 myComputeLineBezier.Parametrization(parametrization);
1021 if(myRelativeTol==Standard_False) {
1022 myComputeLine.Init(myDegMin,
1024 myTol3d*myMinFactorXYZ,
1025 myTol2d*myMinFactorUV,
1029 myComputeLineBezier.Init(myDegMin,
1031 myTol3d*myMinFactorXYZ,
1032 myTol2d*myMinFactorUV,
1038 myComputeLine.Init(myDegMin,
1045 myComputeLineBezier.Init(myDegMin,
1058 ApproxInt_TheMultiLine myMultiLine(theline,
1060 ((ApproxXYZ)? 1 : 0),
1061 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
1062 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
1067 myComputeLineBezier.Perform(myMultiLine);
1070 //myMultiLine.Dump();
1073 if (myComputeLineBezier.NbMultiCurves() == 0)
1075 myTolReached&=myComputeLineBezier.IsToleranceReached();
1078 myComputeLine.Perform(myMultiLine);
1082 Standard_Integer indice3d,indice2d1,indice2d2;
1086 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
1087 if(!ApproxU1V1) { indice2d2--; }
1089 Standard_Real ax,bx,ay,by,az,bz;
1090 ax = 1.0/Ax; bx = -Xo*ax;
1091 ay = 1.0/Ay; by = -Yo*ay;
1092 az = 1.0/Az; bz = -Zo*az;
1094 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1095 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
1099 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
1103 Standard_Real ax,bx,ay,by;
1104 ax = 1.0/A1u; bx = -U1o*ax;
1105 ay = 1.0/A1v; by = -V1o*ay;
1107 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1108 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
1112 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
1116 Standard_Real ax,bx,ay,by;
1117 ax = 1.0/A2u; bx = -U2o*ax;
1118 ay = 1.0/A2v; by = -V2o*ay;
1120 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1121 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
1125 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
1128 OtherInter = Standard_False;
1131 for(Standard_Integer nbmc = 1;
1132 nbmc <= myComputeLineBezier.NbMultiCurves() ;
1135 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
1140 imax = imin+nbpntbez;
1141 OtherInter = Standard_True;
1142 if((indicemax-imax)<(nbpntbez/2))
1146 imax = CorrectFinishIdx(imin, imax, theline);
1152 myBezToBSpl.Perform();
1155 //--------------------------------------------------------------------------------
1156 Standard_Integer ApproxInt_Approx::NbMultiCurves() const {
1157 // return(myComputeLine.NbMultiCurves());
1160 //--------------------------------------------------------------------------------
1161 void ApproxInt_Approx::UpdateTolReached() {
1164 Standard_Integer ICur ;
1165 Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
1166 for (ICur = 1 ; ICur <= NbCurves ; ICur++) {
1167 Standard_Real Tol3D, Tol2D ;
1168 myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
1169 myTolReached3d = Max(myTolReached3d, Tol3D);
1170 myTolReached2d = Max(myTolReached2d, Tol2D);
1173 myComputeLine.Error (myTolReached3d, myTolReached2d);
1176 //--------------------------------------------------------------------------------
1177 Standard_Real ApproxInt_Approx::TolReached3d() const {
1179 Standard_Real TheTol3D = RatioTol * myTolReached3d ;
1180 //modified by NIZNHY-PKV Mon Aug 27 14:21:33 2007f
1181 //if (myMinFactorXYZ)
1182 //TheTol3D = TheTol3D / myMinFactorXYZ ;
1183 if (myMinFactorXYZ>1.5e-7) {
1184 TheTol3D = TheTol3D / myMinFactorXYZ ;
1186 //modified by NIZNHY-PKV Mon Aug 27 14:21:50 2007t
1189 //--------------------------------------------------------------------------------
1190 Standard_Real ApproxInt_Approx::TolReached2d() const {
1192 Standard_Real TheTol2D = RatioTol * myTolReached2d ;
1193 //modified by NIZNHY-PKV Mon Aug 27 14:20:50 2007f
1194 //if (myMinFactorUV)
1195 //TheTol2D = TheTol2D / myMinFactorUV ;
1196 if (myMinFactorUV>1.5e-7) {
1197 TheTol2D = TheTol2D / myMinFactorUV ;
1199 //modified by NIZNHY-PKV Mon Aug 27 14:20:55 2007t
1202 //--------------------------------------------------------------------------------
1203 Standard_Boolean ApproxInt_Approx::IsDone() const {
1205 return(myComputeLineBezier.NbMultiCurves() > 0);
1206 //-- Lorsque la tolerance n est pas atteinte et qu il
1207 //-- faudrait rajouter des points sur la ligne
1208 //-- les approx sortent avec la meilleure tolerance
1209 //-- atteinte. ( Pas de rajout de points ds cette version)
1210 //-- return(myTolReached);
1213 return(myComputeLine.IsToleranceReached());
1216 //--------------------------------------------------------------------------------
1217 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const {
1219 return(myBezToBSpl.Value());
1222 return(myComputeLine.Value());
1225 //--------------------------------------------------------------------------------
1226 Standard_Integer ApproxInt_Approx::CorrectFinishIdx(const Standard_Integer theMinIdx,
1227 const Standard_Integer theMaxIdx,
1228 const Handle(TheWLine)& theline)
1230 const Standard_Real aNullCoeff = 1.0e-16;
1231 Standard_Real aLimitMaxCoeff = 1.0 / 2500.0;
1232 Standard_Real aDist = theline->Point(theMinIdx).Value().SquareDistance(
1233 theline->Point(theMinIdx + 1).Value());
1235 for(Standard_Integer anIdx = theMinIdx + 1; anIdx < theMaxIdx - 1; anIdx++)
1237 Standard_Real aNextDist = theline->Point(anIdx).Value().SquareDistance(
1238 theline->Point(anIdx + 1).Value());
1239 Standard_Real aCoeff = Min (aNextDist, aDist) / Max (aNextDist, aDist);
1242 if (aCoeff < aLimitMaxCoeff && // Base criteria.
1243 aNextDist > aDist && // Step increasing.
1244 aNextDist > aNullCoeff && // Avoid separation in case of too small step.
1245 aDist > aNullCoeff) // Usually found when purger not invoked (blend).