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));
337 imax = imin+nbpntbez;
338 OtherInter = Standard_True;
339 if((indicemax-imax)<(nbpntbez/2)) {
347 myBezToBSpl.Perform();
351 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
352 const ThePSurface& Surf2,
353 const Handle(TheWLine)& theline,
354 const Standard_Boolean ApproxXYZ,
355 const Standard_Boolean ApproxU1V1,
356 const Standard_Boolean ApproxU2V2,
357 const Standard_Integer indicemin,
358 const Standard_Integer indicemax) {
359 myMinFactorXYZ = 0.0;
361 myTolReached3d = myTolReached2d = 0.;
363 GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
364 GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
365 if ((typeS1 != GeomAbs_Plane &&
366 typeS1 != GeomAbs_Cylinder &&
367 typeS1 != GeomAbs_Sphere &&
368 typeS1 != GeomAbs_Cone)
370 (typeS2 != GeomAbs_Plane &&
371 typeS2 != GeomAbs_Cylinder &&
372 typeS2 != GeomAbs_Sphere &&
373 typeS2 != GeomAbs_Cone)) {
375 //------------------------------------------------------------
376 //-- Construction du SvSurfaces
377 //------------------------------------------------------------
378 ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
379 //------------------------------------------------------------
380 //-- Construction de la MultiLine
381 //------------------------------------------------------------
382 Standard_Integer nbpntbez = indicemax-indicemin;
383 Standard_Integer nbpntmax = myNbPntMax;
384 Standard_Boolean OtherInter = Standard_False;
386 if(nbpntbez < LimRajout)
387 myApproxBez = Standard_False;
389 myApproxBez = Standard_True;
391 Standard_Address ptrsvsurf = NULL;
392 Standard_Boolean cut = Standard_True;
393 if(nbpntbez < LimRajout) {
394 cut = Standard_False;
395 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
397 ptrsvsurf = &myPrmPrmSvSurfaces;
402 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
404 nbpntbez = (indicemax-indicemin)/nbi;
407 Standard_Integer imin = indicemin;
408 Standard_Integer imax = imin + nbpntbez;
409 myTolReached = Standard_True;
412 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
414 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
417 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
420 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf1,1.)/
421 ThePSurfaceTool::VResolution(Surf1,1.);
422 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
425 U1o=V1o=0.0; A1u=A1v=1.0;
428 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf2,1.)/
429 ThePSurfaceTool::VResolution(Surf2,1.);
430 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
433 U2o=V2o=0.0; A2u=A2v=1.0;
436 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
437 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
438 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
439 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
440 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
441 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
442 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
443 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
446 Standard_Real A3d = MINABS3(Ax,Ay,Az);
447 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
448 myMinFactorXYZ = A3d;
451 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
452 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
457 Approx_ParametrizationType parametrization;
458 myComputeLineBezier.Parametrization(parametrization);
460 if(myRelativeTol==Standard_False) {
461 myComputeLine.Init(myDegMin,
463 myTol3d*myMinFactorXYZ,
464 myTol2d*myMinFactorUV,
468 myComputeLineBezier.Init(myDegMin,
470 myTol3d*myMinFactorXYZ,
471 myTol2d*myMinFactorUV,
477 myComputeLine.Init(myDegMin,
484 myComputeLineBezier.Init(myDegMin,
497 ApproxInt_TheMultiLine myMultiLine(theline,
499 ((ApproxXYZ)? 1 : 0),
500 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
501 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
507 myComputeLineBezier.Perform(myMultiLine);
508 if (myComputeLineBezier.NbMultiCurves() == 0)
510 myTolReached&=myComputeLineBezier.IsToleranceReached();
513 myComputeLine.Perform(myMultiLine);
517 Standard_Integer indice3d,indice2d1,indice2d2;
521 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
522 if(!ApproxU1V1) { indice2d2--; }
524 Standard_Real ax,bx,ay,by,az,bz;
525 ax = 1.0/Ax; bx = -Xo*ax;
526 ay = 1.0/Ay; by = -Yo*ay;
527 az = 1.0/Az; bz = -Zo*az;
529 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
530 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
534 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
538 Standard_Real ax,bx,ay,by;
539 ax = 1.0/A1u; bx = -U1o*ax;
540 ay = 1.0/A1v; by = -V1o*ay;
542 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
543 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
547 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
551 Standard_Real ax,bx,ay,by;
552 ax = 1.0/A2u; bx = -U2o*ax;
553 ay = 1.0/A2v; by = -V2o*ay;
555 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
556 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
560 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
563 OtherInter = Standard_False;
565 for(Standard_Integer nbmc = 1;
566 nbmc <= myComputeLineBezier.NbMultiCurves() ;
568 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
572 imax = imin+nbpntbez;
573 OtherInter = Standard_True;
574 if((indicemax-imax)<(nbpntbez/2)) {
582 myBezToBSpl.Perform();
587 IntSurf_Quadric Quad;
588 Standard_Boolean SecondIsImplicit=Standard_False;
592 Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
595 case GeomAbs_Cylinder:
596 Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
600 Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
604 Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
609 SecondIsImplicit = Standard_True;
612 Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
615 case GeomAbs_Cylinder:
616 Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
620 Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
624 Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
633 if(SecondIsImplicit) {
634 Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
637 Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
641 //--------------------------------------------------------------------------------
642 void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d,
643 const Standard_Real Tol2d,
644 const Standard_Integer DegMin,
645 const Standard_Integer DegMax,
646 const Standard_Integer NbIterMax,
647 const Standard_Boolean ApproxWithTangency,
648 const Approx_ParametrizationType Parametrization) {
649 myWithTangency = ApproxWithTangency;
650 myTol3d = Tol3d / RatioTol;
651 myTol2d = Tol2d / RatioTol;
654 myNbIterMax = NbIterMax;
655 myComputeLine.Init(myDegMin,
663 if(!ApproxWithTangency) {
664 myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
666 myComputeLineBezier.Init(myDegMin,
673 if(!ApproxWithTangency) {
674 myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
676 myApproxBez = Standard_True;
679 void ApproxInt_Approx::SetParameters(const Standard_Real Tol3d,
680 const Standard_Real Tol2d,
681 const Standard_Boolean RelativeTol,
682 const Standard_Integer DegMin,
683 const Standard_Integer DegMax,
684 const Standard_Integer NbIterMax,
685 const Standard_Integer NbPntMax,
686 const Standard_Boolean ApproxWithTangency,
687 const Approx_ParametrizationType Parametrization)
689 myNbPntMax = NbPntMax ;
690 myRelativeTol = RelativeTol ;
691 SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ;
694 //--------------------------------------------------------------------------------
695 void ApproxInt_Approx::Perform(const ThePSurface& PSurf,
696 const TheISurface& ISurf,
697 const Handle(TheWLine)& theline,
698 const Standard_Boolean ApproxXYZ,
699 const Standard_Boolean ApproxU1V1,
700 const Standard_Boolean ApproxU2V2,
701 const Standard_Integer indicemin,
702 const Standard_Integer indicemax)
704 myMinFactorXYZ = 0.0;
706 myTolReached3d = myTolReached2d = 0.;
708 ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf);
709 Standard_Integer nbpntbez = indicemax-indicemin;
710 Standard_Integer nbpntmax = myNbPntMax;
711 Standard_Boolean OtherInter = Standard_False;
712 if(nbpntbez < LimRajout)
713 myApproxBez = Standard_False;
715 myApproxBez = Standard_True;
717 Standard_Address ptrsvsurf = NULL;
718 Standard_Boolean cut = Standard_True;
719 if(nbpntbez < LimRajout) {
720 cut = Standard_False;
721 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
725 Approx_ParametrizationType parametrization;
726 myComputeLineBezier.Parametrization(parametrization);
729 ptrsvsurf = &myImpPrmSvSurfaces;
730 myComputeLine.Init(myDegMin,
738 myComputeLineBezier.Init(myDegMin,
747 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
749 nbpntbez = (indicemax-indicemin)/nbi;
752 Standard_Integer imin = indicemin;
753 Standard_Integer imax = imin + nbpntbez;
754 myTolReached = Standard_True;
755 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
757 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
760 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
763 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
764 ThePSurfaceTool::VResolution(PSurf,1.);
765 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
768 U1o=V1o=0.0; A1u=A1v=1.0;
771 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
774 U2o=V2o=0.0; A2u=A2v=1.0;
777 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
778 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
779 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
780 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
781 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
782 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
783 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
784 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
787 Standard_Real A3d = MINABS3(Ax,Ay,Az);
788 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
789 myMinFactorXYZ = A3d;
792 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
793 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
797 myComputeLineBezier.Parametrization(parametrization);
799 if(myRelativeTol==Standard_False) {
800 myComputeLine.Init(myDegMin,
802 myTol3d*myMinFactorXYZ,
803 myTol2d*myMinFactorUV,
807 myComputeLineBezier.Init(myDegMin,
809 myTol3d*myMinFactorXYZ,
810 myTol2d*myMinFactorUV,
816 myComputeLine.Init(myDegMin,
823 myComputeLineBezier.Init(myDegMin,
835 ApproxInt_TheMultiLine myMultiLine(theline,
837 ((ApproxXYZ)? 1 : 0),
838 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
839 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
844 myComputeLineBezier.Perform(myMultiLine);
845 if (myComputeLineBezier.NbMultiCurves() == 0)
847 myTolReached&=myComputeLineBezier.IsToleranceReached();
850 myComputeLine.Perform(myMultiLine);
853 Standard_Integer indice3d,indice2d1,indice2d2;
857 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
858 if(!ApproxU1V1) { indice2d2--; }
860 Standard_Real ax,bx,ay,by,az,bz;
861 ax = 1.0/Ax; bx = -Xo*ax;
862 ay = 1.0/Ay; by = -Yo*ay;
863 az = 1.0/Az; bz = -Zo*az;
865 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
866 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
870 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
874 Standard_Real ax,bx,ay,by;
875 ax = 1.0/A1u; bx = -U1o*ax;
876 ay = 1.0/A1v; by = -V1o*ay;
878 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
879 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
883 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
887 Standard_Real ax,bx,ay,by;
888 ax = 1.0/A2u; bx = -U2o*ax;
889 ay = 1.0/A2v; by = -V2o*ay;
891 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
892 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
896 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
899 OtherInter = Standard_False;
901 for(Standard_Integer nbmc = 1;
902 nbmc <= myComputeLineBezier.NbMultiCurves() ;
904 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
908 imax = imin+nbpntbez;
909 OtherInter = Standard_True;
910 if((indicemax-imax)<(nbpntbez/2)) {
918 myBezToBSpl.Perform();
921 //--------------------------------------------------------------------------------
922 void ApproxInt_Approx::Perform(const TheISurface& ISurf,
923 const ThePSurface& PSurf,
924 const Handle(TheWLine)& theline,
925 const Standard_Boolean ApproxXYZ,
926 const Standard_Boolean ApproxU1V1,
927 const Standard_Boolean ApproxU2V2,
928 const Standard_Integer indicemin,
929 const Standard_Integer indicemax)
932 myMinFactorXYZ = 0.0;
934 myTolReached3d = myTolReached2d = 0.;
936 ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf,PSurf);
937 Standard_Integer nbpntbez = indicemax-indicemin;
939 Standard_Boolean cut = Standard_True;
940 if(nbpntbez < LimRajout)
941 myApproxBez = Standard_False;
943 myApproxBez = Standard_True;
945 if(nbpntbez < LimRajout) {
946 cut = Standard_False;
947 //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
949 Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
951 if(nbpntbez < LimRajout) myApproxBez = Standard_False;
953 Standard_Integer nbpntmax = myNbPntMax;
954 Standard_Boolean OtherInter = Standard_False;
957 Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
959 nbpntbez = (indicemax-indicemin)/nbi;
962 Standard_Integer imin = indicemin;
963 Standard_Integer imax = imin + nbpntbez;
964 myTolReached = Standard_True;
966 Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
968 ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
971 Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
974 ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
977 U1o=V1o=0.0; A1u=A1v=1.0;
980 Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
981 ThePSurfaceTool::VResolution(PSurf,1.);
982 ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
985 U2o=V2o=0.0; A2u=A2v=1.0;
988 //-deb- cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax << endl ;
989 //-deb- cout << "ApproxInt_Approx -- Tol3D = " << myTol3d << endl ;
990 //-deb- cout << "ApproxInt_Approx -- Tol2D = " << myTol2d << endl ;
991 //-deb- cout << "ApproxInt_Approx -- RelTol = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ;
992 //-deb- cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
993 //-deb- cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ;
994 //-deb- cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ;
995 //-deb- cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ;
998 Standard_Real A3d = MINABS3(Ax,Ay,Az);
999 if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) {
1000 myMinFactorXYZ = A3d;
1003 Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
1004 if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) {
1005 myMinFactorUV = A2d;
1008 Approx_ParametrizationType parametrization;
1009 myComputeLineBezier.Parametrization(parametrization);
1012 if(myRelativeTol==Standard_False) {
1013 myComputeLine.Init(myDegMin,
1015 myTol3d*myMinFactorXYZ,
1016 myTol2d*myMinFactorUV,
1020 myComputeLineBezier.Init(myDegMin,
1022 myTol3d*myMinFactorXYZ,
1023 myTol2d*myMinFactorUV,
1029 myComputeLine.Init(myDegMin,
1036 myComputeLineBezier.Init(myDegMin,
1049 ApproxInt_TheMultiLine myMultiLine(theline,
1051 ((ApproxXYZ)? 1 : 0),
1052 ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
1053 Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
1058 myComputeLineBezier.Perform(myMultiLine);
1061 //myMultiLine.Dump();
1064 if (myComputeLineBezier.NbMultiCurves() == 0)
1066 myTolReached&=myComputeLineBezier.IsToleranceReached();
1069 myComputeLine.Perform(myMultiLine);
1073 Standard_Integer indice3d,indice2d1,indice2d2;
1077 if(!ApproxXYZ) { indice2d1--; indice2d2--; }
1078 if(!ApproxU1V1) { indice2d2--; }
1080 Standard_Real ax,bx,ay,by,az,bz;
1081 ax = 1.0/Ax; bx = -Xo*ax;
1082 ay = 1.0/Ay; by = -Yo*ay;
1083 az = 1.0/Az; bz = -Zo*az;
1085 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1086 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
1090 myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
1094 Standard_Real ax,bx,ay,by;
1095 ax = 1.0/A1u; bx = -U1o*ax;
1096 ay = 1.0/A1v; by = -V1o*ay;
1098 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1099 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
1103 myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
1107 Standard_Real ax,bx,ay,by;
1108 ax = 1.0/A2u; bx = -U2o*ax;
1109 ay = 1.0/A2v; by = -V2o*ay;
1111 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) {
1112 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
1116 myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
1119 OtherInter = Standard_False;
1121 for(Standard_Integer nbmc = 1;
1122 nbmc <= myComputeLineBezier.NbMultiCurves() ;
1124 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
1126 if(imax<indicemax) {
1128 imax = imin+nbpntbez;
1129 OtherInter = Standard_True;
1130 if((indicemax-imax)<(nbpntbez/2)) {
1138 myBezToBSpl.Perform();
1141 //--------------------------------------------------------------------------------
1142 Standard_Integer ApproxInt_Approx::NbMultiCurves() const {
1143 // return(myComputeLine.NbMultiCurves());
1146 //--------------------------------------------------------------------------------
1147 void ApproxInt_Approx::UpdateTolReached() {
1150 Standard_Integer ICur ;
1151 Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
1152 for (ICur = 1 ; ICur <= NbCurves ; ICur++) {
1153 Standard_Real Tol3D, Tol2D ;
1154 myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
1155 myTolReached3d = Max(myTolReached3d, Tol3D);
1156 myTolReached2d = Max(myTolReached2d, Tol2D);
1159 myComputeLine.Error (myTolReached3d, myTolReached2d);
1162 //--------------------------------------------------------------------------------
1163 Standard_Real ApproxInt_Approx::TolReached3d() const {
1165 Standard_Real TheTol3D = RatioTol * myTolReached3d ;
1166 //modified by NIZNHY-PKV Mon Aug 27 14:21:33 2007f
1167 //if (myMinFactorXYZ)
1168 //TheTol3D = TheTol3D / myMinFactorXYZ ;
1169 if (myMinFactorXYZ>1.5e-7) {
1170 TheTol3D = TheTol3D / myMinFactorXYZ ;
1172 //modified by NIZNHY-PKV Mon Aug 27 14:21:50 2007t
1175 //--------------------------------------------------------------------------------
1176 Standard_Real ApproxInt_Approx::TolReached2d() const {
1178 Standard_Real TheTol2D = RatioTol * myTolReached2d ;
1179 //modified by NIZNHY-PKV Mon Aug 27 14:20:50 2007f
1180 //if (myMinFactorUV)
1181 //TheTol2D = TheTol2D / myMinFactorUV ;
1182 if (myMinFactorUV>1.5e-7) {
1183 TheTol2D = TheTol2D / myMinFactorUV ;
1185 //modified by NIZNHY-PKV Mon Aug 27 14:20:55 2007t
1188 //--------------------------------------------------------------------------------
1189 Standard_Boolean ApproxInt_Approx::IsDone() const {
1191 return(myComputeLineBezier.NbMultiCurves() > 0);
1192 //-- Lorsque la tolerance n est pas atteinte et qu il
1193 //-- faudrait rajouter des points sur la ligne
1194 //-- les approx sortent avec la meilleure tolerance
1195 //-- atteinte. ( Pas de rajout de points ds cette version)
1196 //-- return(myTolReached);
1199 return(myComputeLine.IsToleranceReached());
1202 //--------------------------------------------------------------------------------
1203 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const {
1205 return(myBezToBSpl.Value());
1208 return(myComputeLine.Value());