1 // Created on: 1993-03-30
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
24 #include <AppParCurves_Constraint.hxx>
25 #include <GeomAbs_SurfaceType.hxx>
26 #include <IntSurf_Quadric.hxx>
27 #include <gp_Trsf.hxx>
28 #include <gp_Trsf2d.hxx>
29 #include <IntSurf_PntOn2S.hxx>
30 #include <Precision.hxx>
32 const Standard_Integer LimRajout = 5;
33 const Standard_Integer NbPntMaxDecoupage = 30 ;
34 const Standard_Real RatioTol = 1.5 ;
36 static Standard_Real MINABS3(Standard_Real a, Standard_Real b,Standard_Real c) {
45 static Standard_Real MINABS4(Standard_Real a, Standard_Real b,Standard_Real c,Standard_Real d) {
56 static void ComputeTrsf3d(const Handle(TheWLine)& theline,
57 Standard_Real& Xo, Standard_Real& Ax,
58 Standard_Real& Yo, Standard_Real& Ay,
59 Standard_Real& Zo, Standard_Real& Az) {
61 Standard_Integer nbp = theline->NbPnts();
62 Standard_Real z0,z1,x0,x1,y0,y1;
65 for(Standard_Integer i=1;i<=nbp;i++) {
66 const gp_Pnt& P = theline->Point(i).Value();
67 Standard_Real X = P.X();
68 Standard_Real Y = P.Y();
69 Standard_Real Z = P.Z();
77 //-deb- cout << "ComputeTrsf3d -- NbPnt = " << nbp << endl ;
78 //-deb- cout << "ComputeTrsf3d -- Xm = " << x0 << " Ym = " << y0 << " Zm = " << z0 << endl ;
79 //-deb- cout << "ComputeTrsf3d -- XM = " << x1 << " YM = " << y1 << " ZM = " << z1 << endl ;
80 Standard_Real dx = x1-x0;
81 Standard_Real dy = y1-y0;
82 Standard_Real dz = z1-z0;
83 Standard_Real MaxD = dx;
84 if(MaxD < dy) MaxD=dy;
85 if(MaxD < dz) MaxD=dz;
86 Standard_Real MaxDF = 0.01*MaxD;
88 //-- lbr le 22 fev99 : FPE
93 if(dx > MaxDF) { Ax = 1.0 / dx; Xo = -Ax * x0; }
94 else { Ax = 1.0/( MaxDF) ; Xo = -Ax*x0; }
95 if(dy > MaxDF) { Ay = 1.0 / dy; Yo = -Ay * y0; }
96 else { Ay = 1.0/( MaxDF); Yo = -Ay*y0; }
97 if(dz > MaxDF) { Az = 1.0 / dz; Zo = -Az * z0; }
98 else { Az = 1.0/(MaxDF); Zo = -Az*z0; }
101 static void ComputeTrsf2d(const Handle(TheWLine)& theline,
102 Standard_Real& Uo, Standard_Real& Au,
103 Standard_Real& Vo, Standard_Real& Av,
104 const Standard_Boolean onFirst,
105 const Standard_Real UVResRatio = 1.) {
106 Standard_Integer nbp = theline->NbPnts();
107 Standard_Real u0,u1,v0,v1;
108 u0 = v0 = RealLast();
109 u1 = v1 = RealFirst();
110 // pointer to a member-function
111 void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
113 pfunc = &IntSurf_PntOn2S::ParametersOnS1;
115 pfunc = &IntSurf_PntOn2S::ParametersOnS2;
116 for(Standard_Integer i=1;i<=nbp;i++) {
117 const IntSurf_PntOn2S& POn2S = theline->Point(i);
126 Standard_Real du = (u1-u0);
127 Standard_Real dv = (v1-v0);
131 else if (UVResRatio < 1.)
134 Standard_Real MaxUV=du;
135 if(MaxUV<dv) MaxUV=dv;
137 Standard_Real MaxUVF=0.01*MaxUV;
139 //-- lbr le 22 fev 99 (FPE)
143 if(du > MaxUVF) { Au = 1.0 / du; Uo = -Au * u0; }
144 else { Au = 1.0/(MaxUVF); Uo = -Au*u0; }
145 if(dv > MaxUVF) { Av = 1.0 / dv; Vo = -Av * v0; }
146 else { Av = 1.0/(MaxUVF); Vo = -Av*v0; }
151 ApproxInt_Approx::ApproxInt_Approx():
158 myComputeLineBezier(4,
165 myComputeLine.SetContinuity(2);
166 //-- myComputeLineBezier.SetContinuity(2);
167 myApproxBez = Standard_True;
169 myRelativeTol = Standard_True ;
170 myNbPntMax = NbPntMaxDecoupage ;
171 myMinFactorXYZ = 0.0;
173 myTolReached3d = myTolReached2d = 0.;
177 void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
178 const Standard_Boolean ApproxXYZ,
179 const Standard_Boolean ApproxU1V1,
180 const Standard_Boolean ApproxU2V2,
181 const Standard_Integer indicemin,
182 const Standard_Integer indicemax) {
184 myMinFactorXYZ = 0.0;
186 myTolReached3d = myTolReached2d = 0.;
189 Standard_Integer nbpntbez = indicemax-indicemin;
190 Standard_Integer nbpntmax = myNbPntMax;
191 Standard_Boolean OtherInter = Standard_False;
192 if(nbpntbez < LimRajout)
193 myApproxBez = Standard_False;
195 myApproxBez = Standard_True;
198 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
200 nbpntbez = (indicemax-indicemin)/nbi;
203 Standard_Integer imin = indicemin;
204 Standard_Integer imax = imin + nbpntbez;
205 myTolReached = Standard_True;
207 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
209 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
212 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
215 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
218 U1o=V1o=0.0; A1u=A1v=1.0;
221 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
224 U2o=V2o=0.0; A2u=A2v=1.0;
227 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
228 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
229 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
230 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
231 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
232 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
233 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
234 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
236 Standard_Real A3d = MINABS3(Ax,Ay,Az);
237 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
238 myMinFactorXYZ = A3d;
241 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
242 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
246 Standard_Boolean cut=Standard_True;
247 Approx_ParametrizationType parametrization;
248 myComputeLineBezier.Parametrization(parametrization);
250 if(myRelativeTol==Standard_False) {
252 myComputeLine.Init(myDegMin,
254 myTol3d*myMinFactorXYZ,
255 myTol2d*myMinFactorUV,
259 myComputeLineBezier.Init(myDegMin,
261 myTol3d*myMinFactorXYZ,
262 myTol2d*myMinFactorUV,
269 ApproxInt_TheMultiLine myMultiLine(theline,
270 ((ApproxXYZ)? 1 : 0),
271 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
272 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
278 myComputeLineBezier.Perform(myMultiLine);
279 if (myComputeLineBezier.NbMultiCurves() == 0)
281 myTolReached&=myComputeLineBezier.IsToleranceReached();
284 myComputeLine.Perform(myMultiLine);
288 Standard_Integer indice3d,indice2d1,indice2d2;
292 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
293 if(!ApproxU1V1) { indice2d2--; }
295 Standard_Real ax,bx,ay,by,az,bz;
296 ax = 1.0/Ax; bx = -Xo*ax;
297 ay = 1.0/Ay; by = -Yo*ay;
298 az = 1.0/Az; bz = -Zo*az;
300 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
301 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
305 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
309 Standard_Real ax,bx,ay,by;
310 ax = 1.0/A1u; bx = -U1o*ax;
311 ay = 1.0/A1v; by = -V1o*ay;
313 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
314 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
318 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
322 Standard_Real ax,bx,ay,by;
323 ax = 1.0/A2u; bx = -U2o*ax;
324 ay = 1.0/A2v; by = -V2o*ay;
326 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
327 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
331 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
335 OtherInter = Standard_False;
337 for(Standard_Integer nbmc = 1;
338 nbmc <= myComputeLineBezier.NbMultiCurves() ;
340 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
344 imax = imin+nbpntbez;
345 OtherInter = Standard_True;
346 if((indicemax-imax)<(nbpntbez/2)) {
354 myBezToBSpl.Perform();
358 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
359 const ThePSurface& Surf2,
360 const Handle(TheWLine)& theline,
361 const Standard_Boolean ApproxXYZ,
362 const Standard_Boolean ApproxU1V1,
363 const Standard_Boolean ApproxU2V2,
364 const Standard_Integer indicemin,
365 const Standard_Integer indicemax) {
366 myMinFactorXYZ = 0.0;
368 myTolReached3d = myTolReached2d = 0.;
370 GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
371 GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
372 if ((typeS1 != GeomAbs_Plane &&
373 typeS1 != GeomAbs_Cylinder &&
374 typeS1 != GeomAbs_Sphere &&
375 typeS1 != GeomAbs_Cone)
377 (typeS2 != GeomAbs_Plane &&
378 typeS2 != GeomAbs_Cylinder &&
379 typeS2 != GeomAbs_Sphere &&
380 typeS2 != GeomAbs_Cone)) {
382 //------------------------------------------------------------
383 //-- Construction du SvSurfaces
384 //------------------------------------------------------------
385 ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
386 //------------------------------------------------------------
387 //-- Construction de la MultiLine
388 //------------------------------------------------------------
389 Standard_Integer nbpntbez = indicemax-indicemin;
390 Standard_Integer nbpntmax = myNbPntMax;
391 Standard_Boolean OtherInter = Standard_False;
393 if(nbpntbez < LimRajout)
394 myApproxBez = Standard_False;
396 myApproxBez = Standard_True;
398 Standard_Address ptrsvsurf = NULL;
399 Standard_Boolean cut = Standard_True;
400 if(nbpntbez < LimRajout) {
401 cut = Standard_False;
402 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
404 ptrsvsurf = &myPrmPrmSvSurfaces;
409 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
411 nbpntbez = (indicemax-indicemin)/nbi;
414 Standard_Integer imin = indicemin;
415 Standard_Integer imax = imin + nbpntbez;
416 myTolReached = Standard_True;
419 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
421 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
424 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
427 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf1,1.)/
428 ThePSurfaceTool::VResolution(Surf1,1.);
429 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
432 U1o=V1o=0.0; A1u=A1v=1.0;
435 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf2,1.)/
436 ThePSurfaceTool::VResolution(Surf2,1.);
437 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
440 U2o=V2o=0.0; A2u=A2v=1.0;
443 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
444 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
445 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
446 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
447 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
448 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
449 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
450 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
453 Standard_Real A3d = MINABS3(Ax,Ay,Az);
454 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
455 myMinFactorXYZ = A3d;
458 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
459 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
464 Approx_ParametrizationType parametrization;
465 myComputeLineBezier.Parametrization(parametrization);
467 if(myRelativeTol==Standard_False) {
468 myComputeLine.Init(myDegMin,
470 myTol3d*myMinFactorXYZ,
471 myTol2d*myMinFactorUV,
475 myComputeLineBezier.Init(myDegMin,
477 myTol3d*myMinFactorXYZ,
478 myTol2d*myMinFactorUV,
484 myComputeLine.Init(myDegMin,
491 myComputeLineBezier.Init(myDegMin,
504 ApproxInt_TheMultiLine myMultiLine(theline,
506 ((ApproxXYZ)? 1 : 0),
507 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
508 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
514 myComputeLineBezier.Perform(myMultiLine);
515 if (myComputeLineBezier.NbMultiCurves() == 0)
517 myTolReached&=myComputeLineBezier.IsToleranceReached();
520 myComputeLine.Perform(myMultiLine);
524 Standard_Integer indice3d,indice2d1,indice2d2;
528 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
529 if(!ApproxU1V1) { indice2d2--; }
531 Standard_Real ax,bx,ay,by,az,bz;
532 ax = 1.0/Ax; bx = -Xo*ax;
533 ay = 1.0/Ay; by = -Yo*ay;
534 az = 1.0/Az; bz = -Zo*az;
536 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
537 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
541 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
545 Standard_Real ax,bx,ay,by;
546 ax = 1.0/A1u; bx = -U1o*ax;
547 ay = 1.0/A1v; by = -V1o*ay;
549 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
550 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
554 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
558 Standard_Real ax,bx,ay,by;
559 ax = 1.0/A2u; bx = -U2o*ax;
560 ay = 1.0/A2v; by = -V2o*ay;
562 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
563 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
567 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
570 OtherInter = Standard_False;
572 for(Standard_Integer nbmc = 1;
573 nbmc <= myComputeLineBezier.NbMultiCurves() ;
575 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
579 imax = imin+nbpntbez;
580 OtherInter = Standard_True;
581 if((indicemax-imax)<(nbpntbez/2)) {
589 myBezToBSpl.Perform();
594 IntSurf_Quadric Quad;
595 Standard_Boolean SecondIsImplicit=Standard_False;
599 Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
602 case GeomAbs_Cylinder:
603 Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
607 Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
611 Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
616 SecondIsImplicit = Standard_True;
619 Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
622 case GeomAbs_Cylinder:
623 Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
627 Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
631 Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
640 if(SecondIsImplicit) {
641 Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
644 Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
648 //--------------------------------------------------------------------------------
649 void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d,
650 const Standard_Real Tol2d,
651 const Standard_Integer DegMin,
652 const Standard_Integer DegMax,
653 const Standard_Integer NbIterMax,
654 const Standard_Boolean ApproxWithTangency,
655 const Approx_ParametrizationType Parametrization) {
656 myWithTangency = ApproxWithTangency;
657 myTol3d = Tol3d / RatioTol;
658 myTol2d = Tol2d / RatioTol;
661 myNbIterMax = NbIterMax;
662 myComputeLine.Init(myDegMin,
670 if(!ApproxWithTangency) {
671 myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
673 myComputeLineBezier.Init(myDegMin,
680 if(!ApproxWithTangency) {
681 myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
683 myApproxBez = Standard_True;
686 void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d,
687 const Standard_Real Tol2d,
688 const Standard_Boolean RelativeTol,
689 const Standard_Integer DegMin,
690 const Standard_Integer DegMax,
691 const Standard_Integer NbIterMax,
692 const Standard_Integer NbPntMax,
693 const Standard_Boolean ApproxWithTangency,
694 const Approx_ParametrizationType Parametrization)
696 myNbPntMax = NbPntMax ;
697 myRelativeTol = RelativeTol ;
698 SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ;
701 //--------------------------------------------------------------------------------
702 void ApproxInt_Approx::Perform(const ThePSurface& PSurf,
703 const TheISurface& ISurf,
704 const Handle(TheWLine)& theline,
705 const Standard_Boolean ApproxXYZ,
706 const Standard_Boolean ApproxU1V1,
707 const Standard_Boolean ApproxU2V2,
708 const Standard_Integer indicemin,
709 const Standard_Integer indicemax)
711 myMinFactorXYZ = 0.0;
713 myTolReached3d = myTolReached2d = 0.;
715 ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf);
716 Standard_Integer nbpntbez = indicemax-indicemin;
717 Standard_Integer nbpntmax = myNbPntMax;
718 Standard_Boolean OtherInter = Standard_False;
719 if(nbpntbez < LimRajout)
720 myApproxBez = Standard_False;
722 myApproxBez = Standard_True;
724 Standard_Address ptrsvsurf = NULL;
725 Standard_Boolean cut = Standard_True;
726 if(nbpntbez < LimRajout) {
727 cut = Standard_False;
728 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
732 Approx_ParametrizationType parametrization;
733 myComputeLineBezier.Parametrization(parametrization);
736 ptrsvsurf = &myImpPrmSvSurfaces;
737 myComputeLine.Init(myDegMin,
745 myComputeLineBezier.Init(myDegMin,
754 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
756 nbpntbez = (indicemax-indicemin)/nbi;
759 Standard_Integer imin = indicemin;
760 Standard_Integer imax = imin + nbpntbez;
761 myTolReached = Standard_True;
762 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
764 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
767 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
770 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
771 ThePSurfaceTool::VResolution(PSurf,1.);
772 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
775 U1o=V1o=0.0; A1u=A1v=1.0;
778 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
781 U2o=V2o=0.0; A2u=A2v=1.0;
784 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
785 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
786 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
787 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
788 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
789 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
790 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
791 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
794 Standard_Real A3d = MINABS3(Ax,Ay,Az);
795 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
796 myMinFactorXYZ = A3d;
799 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
800 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
804 myComputeLineBezier.Parametrization(parametrization);
806 if(myRelativeTol==Standard_False) {
807 myComputeLine.Init(myDegMin,
809 myTol3d*myMinFactorXYZ,
810 myTol2d*myMinFactorUV,
814 myComputeLineBezier.Init(myDegMin,
816 myTol3d*myMinFactorXYZ,
817 myTol2d*myMinFactorUV,
823 myComputeLine.Init(myDegMin,
830 myComputeLineBezier.Init(myDegMin,
842 ApproxInt_TheMultiLine myMultiLine(theline,
844 ((ApproxXYZ)? 1 : 0),
845 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
846 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
851 myComputeLineBezier.Perform(myMultiLine);
852 if (myComputeLineBezier.NbMultiCurves() == 0)
854 myTolReached&=myComputeLineBezier.IsToleranceReached();
857 myComputeLine.Perform(myMultiLine);
860 Standard_Integer indice3d,indice2d1,indice2d2;
864 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
865 if(!ApproxU1V1) { indice2d2--; }
867 Standard_Real ax,bx,ay,by,az,bz;
868 ax = 1.0/Ax; bx = -Xo*ax;
869 ay = 1.0/Ay; by = -Yo*ay;
870 az = 1.0/Az; bz = -Zo*az;
872 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
873 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
877 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
881 Standard_Real ax,bx,ay,by;
882 ax = 1.0/A1u; bx = -U1o*ax;
883 ay = 1.0/A1v; by = -V1o*ay;
885 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
886 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
890 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
894 Standard_Real ax,bx,ay,by;
895 ax = 1.0/A2u; bx = -U2o*ax;
896 ay = 1.0/A2v; by = -V2o*ay;
898 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
899 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
903 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
906 OtherInter = Standard_False;
908 for(Standard_Integer nbmc = 1;
909 nbmc <= myComputeLineBezier.NbMultiCurves() ;
911 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
915 imax = imin+nbpntbez;
916 OtherInter = Standard_True;
917 if((indicemax-imax)<(nbpntbez/2)) {
925 myBezToBSpl.Perform();
928 //--------------------------------------------------------------------------------
929 void ApproxInt_Approx::Perform(const TheISurface& ISurf,
930 const ThePSurface& PSurf,
931 const Handle(TheWLine)& theline,
932 const Standard_Boolean ApproxXYZ,
933 const Standard_Boolean ApproxU1V1,
934 const Standard_Boolean ApproxU2V2,
935 const Standard_Integer indicemin,
936 const Standard_Integer indicemax)
939 myMinFactorXYZ = 0.0;
941 myTolReached3d = myTolReached2d = 0.;
943 ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf,PSurf);
944 Standard_Integer nbpntbez = indicemax-indicemin;
946 Standard_Address ptrsvsurf = NULL;
947 Standard_Boolean cut = Standard_True;
948 if(nbpntbez < LimRajout)
949 myApproxBez = Standard_False;
951 myApproxBez = Standard_True;
953 if(nbpntbez < LimRajout) {
954 cut = Standard_False;
955 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
957 ptrsvsurf = &myImpPrmSvSurfaces;
959 if(nbpntbez < LimRajout) myApproxBez = Standard_False;
961 Standard_Integer nbpntmax = myNbPntMax;
962 Standard_Boolean OtherInter = Standard_False;
965 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
967 nbpntbez = (indicemax-indicemin)/nbi;
970 Standard_Integer imin = indicemin;
971 Standard_Integer imax = imin + nbpntbez;
972 myTolReached = Standard_True;
974 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
976 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
979 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
982 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
985 U1o=V1o=0.0; A1u=A1v=1.0;
988 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
989 ThePSurfaceTool::VResolution(PSurf,1.);
990 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
993 U2o=V2o=0.0; A2u=A2v=1.0;
996 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
997 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
998 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
999 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
1000 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
1001 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
1002 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
1003 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
1006 Standard_Real A3d = MINABS3(Ax,Ay,Az);
1007 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
1008 myMinFactorXYZ = A3d;
1011 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
1012 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
1013 myMinFactorUV = A2d;
1016 Approx_ParametrizationType parametrization;
1017 myComputeLineBezier.Parametrization(parametrization);
1020 if(myRelativeTol==Standard_False) {
1021 myComputeLine.Init(myDegMin,
1023 myTol3d*myMinFactorXYZ,
1024 myTol2d*myMinFactorUV,
1028 myComputeLineBezier.Init(myDegMin,
1030 myTol3d*myMinFactorXYZ,
1031 myTol2d*myMinFactorUV,
1037 myComputeLine.Init(myDegMin,
1044 myComputeLineBezier.Init(myDegMin,
1057 ApproxInt_TheMultiLine myMultiLine(theline,
1059 ((ApproxXYZ)? 1 : 0),
1060 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
1061 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
1066 myComputeLineBezier.Perform(myMultiLine);
1067 if (myComputeLineBezier.NbMultiCurves() == 0)
1069 myTolReached&=myComputeLineBezier.IsToleranceReached();
1072 myComputeLine.Perform(myMultiLine);
1076 Standard_Integer indice3d,indice2d1,indice2d2;
1080 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
1081 if(!ApproxU1V1) { indice2d2--; }
1083 Standard_Real ax,bx,ay,by,az,bz;
1084 ax = 1.0/Ax; bx = -Xo*ax;
1085 ay = 1.0/Ay; by = -Yo*ay;
1086 az = 1.0/Az; bz = -Zo*az;
1088 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1089 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
1093 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
1097 Standard_Real ax,bx,ay,by;
1098 ax = 1.0/A1u; bx = -U1o*ax;
1099 ay = 1.0/A1v; by = -V1o*ay;
1101 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1102 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
1106 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
1110 Standard_Real ax,bx,ay,by;
1111 ax = 1.0/A2u; bx = -U2o*ax;
1112 ay = 1.0/A2v; by = -V2o*ay;
1114 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1115 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
1119 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
1122 OtherInter = Standard_False;
1124 for(Standard_Integer nbmc = 1;
1125 nbmc <= myComputeLineBezier.NbMultiCurves() ;
1127 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
1129 if(imax<indicemax) {
1131 imax = imin+nbpntbez;
1132 OtherInter = Standard_True;
1133 if((indicemax-imax)<(nbpntbez/2)) {
1141 myBezToBSpl.Perform();
1144 //--------------------------------------------------------------------------------
1145 Standard_Integer ApproxInt_Approx::NbMultiCurves() const {
1146 // return(myComputeLine.NbMultiCurves());
1149 //--------------------------------------------------------------------------------
1150 void ApproxInt_Approx::UpdateTolReached() {
1153 Standard_Integer ICur ;
1154 Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
1155 for (ICur = 1 ; ICur <= NbCurves ; ICur++) {
1156 Standard_Real Tol3D, Tol2D ;
1157 myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
1158 myTolReached3d = Max(myTolReached3d, Tol3D);
1159 myTolReached2d = Max(myTolReached2d, Tol2D);
1162 myComputeLine.Error (myTolReached3d, myTolReached2d);
1165 //--------------------------------------------------------------------------------
1166 Standard_Real ApproxInt_Approx::TolReached3d() const {
1168 Standard_Real TheTol3D = RatioTol * myTolReached3d ;
1169 //modified by NIZNHY-PKV Mon Aug 27 14:21:33 2007f
1170 //if (myMinFactorXYZ)
1171 //TheTol3D = TheTol3D / myMinFactorXYZ ;
1172 if (myMinFactorXYZ>1.5e-7) {
1173 TheTol3D = TheTol3D / myMinFactorXYZ ;
1175 //modified by NIZNHY-PKV Mon Aug 27 14:21:50 2007t
1178 //--------------------------------------------------------------------------------
1179 Standard_Real ApproxInt_Approx::TolReached2d() const {
1181 Standard_Real TheTol2D = RatioTol * myTolReached2d ;
1182 //modified by NIZNHY-PKV Mon Aug 27 14:20:50 2007f
1183 //if (myMinFactorUV)
1184 //TheTol2D = TheTol2D / myMinFactorUV ;
1185 if (myMinFactorUV>1.5e-7) {
1186 TheTol2D = TheTol2D / myMinFactorUV ;
1188 //modified by NIZNHY-PKV Mon Aug 27 14:20:55 2007t
1191 //--------------------------------------------------------------------------------
1192 Standard_Boolean ApproxInt_Approx::IsDone() const {
1194 return(myComputeLineBezier.NbMultiCurves() > 0);
1195 //-- Lorsque la tolerance n est pas atteinte et qu il
1196 //-- faudrait rajouter des points sur la ligne
1197 //-- les approx sortent avec la meilleure tolerance
1198 //-- atteinte. ( Pas de rajout de points ds cette version)
1199 //-- return(myTolReached);
1202 return(myComputeLine.IsToleranceReached());
1205 //--------------------------------------------------------------------------------
1206 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const {
1208 return(myBezToBSpl.Value());
1211 return(myComputeLine.Value());