1 // Created on: 1995-06-06
2 // Created by: Xavier BENVENISTE
3 // Copyright (c) 1995-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 // Modified by skv - Wed Jun 2 11:49:59 2004 OCC5898
19 #include <Adaptor2d_HCurve2d.hxx>
20 #include <Adaptor3d_CurveOnSurface.hxx>
21 #include <Adaptor3d_HCurve.hxx>
22 #include <Adaptor3d_HSurface.hxx>
23 #include <AdvApprox_ApproxAFunction.hxx>
24 #include <Approx_SameParameter.hxx>
25 #include <BSplCLib.hxx>
26 #include <Extrema_ExtPC.hxx>
27 #include <Extrema_LocateExtPC.hxx>
28 #include <GCPnts_QuasiUniformDeflection.hxx>
29 #include <Geom2d_BSplineCurve.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom2dAdaptor_Curve.hxx>
32 #include <Geom2dAdaptor_HCurve.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <GeomAdaptor_Curve.hxx>
36 #include <GeomAdaptor_HCurve.hxx>
37 #include <GeomAdaptor_HSurface.hxx>
38 #include <GeomAdaptor_Surface.hxx>
39 #include <GeomLib_MakeCurvefromApprox.hxx>
40 #include <Precision.hxx>
41 #include <Standard_ConstructionError.hxx>
42 #include <Standard_OutOfRange.hxx>
43 #include <TColStd_Array1OfReal.hxx>
47 #include <DrawTrSurf.hxx>
49 #include <Geom2d_BSplineCurve.hxx>
51 static Standard_Boolean Voir = Standard_False;
52 static Standard_Boolean AffichFw = Standard_False;
53 static Standard_Integer NbCurve = 0;
56 // allows testing if Extrema produces correct results/
59 static void ProjectPointOnCurve(const Standard_Real InitValue,
61 const Standard_Real Tolerance,
62 const Standard_Integer NumIteration,
63 const Adaptor3d_Curve& Curve,
64 Standard_Boolean& Status,
65 Standard_Real& Result)
67 Standard_Integer num_iter = 0,
78 Status = Standard_False ;
79 Standard_Real Toler = 1.0e-12;
86 for (ii = 1 ; ii <= 3 ; ii++) {
87 vector.SetCoord(ii, APoint.Coord(ii) - a_point.Coord(ii)) ;
89 func = vector.Dot(d1) ;
90 func_derivative = vector.Dot(d2) ;
91 func_derivative -= d1.Dot(d1) ;
92 if ( Abs(func) < Tolerance * d1.Magnitude()) {
94 Status = Standard_True ;
97 { // fixing a bug PRO18577 : avoid divizion by zero
98 if( Abs(func_derivative) > Toler ) {
99 param -= func / func_derivative ;
101 param = Max(param,Curve.FirstParameter()) ;
102 param = Min(param,Curve.LastParameter()) ;
103 //Status = Standard_True ;
106 while (not_done && num_iter <= NumIteration) ;
112 //=======================================================================
113 //class : Approx_SameParameter_Evaluator
115 //=======================================================================
117 class Approx_SameParameter_Evaluator : public AdvApprox_EvaluatorFunction
120 Approx_SameParameter_Evaluator (const TColStd_Array1OfReal& theFlatKnots,
121 const TColStd_Array1OfReal& thePoles,
122 const Handle(Adaptor2d_HCurve2d)& theHCurve2d)
123 : FlatKnots(theFlatKnots), Poles(thePoles), HCurve2d(theHCurve2d) {}
125 virtual void Evaluate (Standard_Integer *Dimension,
126 Standard_Real StartEnd[2],
127 Standard_Real *Parameter,
128 Standard_Integer *DerivativeRequest,
129 Standard_Real *Result, // [Dimension]
130 Standard_Integer *ErrorCode);
133 const TColStd_Array1OfReal& FlatKnots;
134 const TColStd_Array1OfReal& Poles;
135 Handle(Adaptor2d_HCurve2d) HCurve2d;
138 void Approx_SameParameter_Evaluator::Evaluate (Standard_Integer *,/*Dimension*/
139 Standard_Real /*StartEnd*/[2],
140 Standard_Real *Parameter,
141 Standard_Integer *DerivativeRequest,
142 Standard_Real *Result,
143 Standard_Integer *ReturnCode)
147 Standard_Integer extrap_mode[2] ;
148 extrap_mode[0] = extrap_mode[1] = 3;
149 Standard_Real eval_result[2] ;
150 Standard_Real *PolesArray =
151 (Standard_Real *) &Poles(Poles.Lower()) ;
153 // evaluate the 1D bspline that represents the change in parameterization
155 BSplCLib::Eval(*Parameter,
166 if (*DerivativeRequest == 0){
167 HCurve2d->D0(eval_result[0],Point);
168 Point.Coord(Result[0],Result[1]);
170 else if (*DerivativeRequest == 1){
171 HCurve2d->D1(eval_result[0], Point, Vector);
172 Vector.Multiply(eval_result[1]);
173 Vector.Coord(Result[0],Result[1]);
178 static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d,
179 const Adaptor3d_CurveOnSurface& cons,
180 const Standard_Integer nbp)
182 Standard_Real d2 = 0.;
183 const Standard_Real first = c3d->FirstParameter();
184 const Standard_Real last = c3d->LastParameter();
185 for(Standard_Integer i = 0; i <= nbp; i++){
186 Standard_Real t = IntToReal(i)/IntToReal(nbp);
187 Standard_Real u = first*(1.-t) + last*t;
188 gp_Pnt Pc3d = c3d->Value(u);
189 gp_Pnt Pcons = cons.Value(u);
190 if (Precision::IsInfinite(Pcons.X()) ||
191 Precision::IsInfinite(Pcons.Y()) ||
192 Precision::IsInfinite(Pcons.Z())) {
193 d2=Precision::Infinite();
196 Standard_Real temp = Pc3d.SquareDistance(Pcons);
197 if(temp > d2) d2 = temp;
200 if(d2<1.e-7) d2 = 1.e-7;
204 static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
205 const TColStd_Array1OfReal& Poles,
206 const Standard_Integer nbp,
207 const TColStd_Array1OfReal& pc3d,
208 // const TColStd_Array1OfReal& pcons,
209 const TColStd_Array1OfReal& ,
210 const Handle(Adaptor3d_HCurve)& c3d,
211 const Adaptor3d_CurveOnSurface& cons,
213 const Standard_Real oldtol)
215 Standard_Real d = tol;
216 Standard_Integer extrap_mode[2] ;
217 extrap_mode[0] = extrap_mode[1] = 3;
222 cout<<"Control the change of variable : "<<endl;
223 cout<<"yawn mesured by projection : "<<d<<endl;
224 cout<<"Number of points : "<<nbp<<endl;
228 Standard_Real glis = 0., dglis = 0.;
229 for(i = 1; i <= nbp; i++){
230 Standard_Real tc3d = pc3d(i);
231 gp_Pnt Pc3d = c3d->Value(tc3d);
233 BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
234 3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
235 gp_Pnt Pcons = cons.Value(tcons);
236 Standard_Real temp = Pc3d.SquareDistance(Pcons);
237 if(temp >= dglis) dglis = temp;
238 temp = Abs(tcons-pcons(i));
239 if(temp >= glis) glis = temp;
244 cout<<"shift of parameter to the imposed points : "<<glis<<endl;
245 cout<<"shift distance at the imposed points : "<<dglis<<endl;
249 for(i = 1; i < nbp; i++){
250 Standard_Real tc3d = 0.5*(pc3d(i)+pc3d(i+1));
251 gp_Pnt Pc3d = c3d->Value(tc3d);
253 BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
254 3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
255 gp_Pnt Pcons = cons.Value(tcons);
256 Standard_Real temp = Pc3d.SquareDistance(Pcons);
257 if(temp >= dglis) dglis = temp;
262 cout<<"distance de glissement en milieu d intervals : "<<dglis<<endl;
266 Standard_Real d2 = 0.;
267 Standard_Integer nn = 2*nbp;
268 Standard_Real unsurnn = 1./nn;
269 // Modified by skv - Wed Jun 2 11:49:59 2004 OCC5898 Begin
270 // Correction of the interval of valid values. This condition has no sensible
271 // grounds. But it is better then the old one (which is commented out) because
272 // it fixes the bug OCC5898. To develop more or less sensible criterion it is
273 // necessary to deeply investigate this problem which is not possible in frames
276 // Standard_Real firstborne= 2*pc3d(1)-pc3d(nbp);
277 // Standard_Real lastborne= 2*pc3d(nbp)-pc3d(1);
278 Standard_Real firstborne= 3.*pc3d(1) - 2.*pc3d(nbp);
279 Standard_Real lastborne = 3.*pc3d(nbp) - 2.*pc3d(1);
280 // Modified by skv - Wed Jun 2 11:50:03 2004 OCC5898 End
282 Standard_Real FirstPar = cons.FirstParameter();
283 Standard_Real LastPar = cons.LastParameter();
284 if (firstborne < FirstPar)
285 firstborne = FirstPar;
286 if (lastborne > LastPar)
289 for(i = 0; i <= nn; i++){
290 Standard_Real t = unsurnn*i;
291 Standard_Real tc3d = pc3d(1)*(1.-t) + pc3d(nbp)*t;
292 gp_Pnt Pc3d = c3d->Value(tc3d);
294 BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
295 3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
296 if (tcons < firstborne || tcons > lastborne) {
297 tol=Precision::Infinite();
298 return Standard_False;
300 gp_Pnt Pcons = cons.Value(tcons);
301 Standard_Real temp = Pc3d.SquareDistance(Pcons);
302 if(temp > d2) d2 = temp;
307 cout<<"distance max on "<<nn<<" points : "<<tol<<endl<<endl;
309 return ((tol <= d) || (tol > 0.8 * oldtol));
313 //=======================================================================
314 //function : Approx_SameParameter
316 //=======================================================================
318 Approx_SameParameter::Approx_SameParameter(const Handle(Geom_Curve)& C3D,
319 const Handle(Geom2d_Curve)& C2D,
320 const Handle(Geom_Surface)& S,
321 const Standard_Real Tol):
322 mySameParameter(Standard_True), myDone(Standard_False)
324 myHCurve2d = new Geom2dAdaptor_HCurve(C2D);
325 myC3d = new GeomAdaptor_HCurve(C3D);
326 mySurf = new GeomAdaptor_HSurface(S);
331 //=======================================================================
332 //function : Approx_SameParameter
334 //=======================================================================
336 Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D,
337 const Handle(Geom2d_Curve)& C2D,
338 const Handle(Adaptor3d_HSurface)& S,
339 const Standard_Real Tol):
340 mySameParameter(Standard_True), myDone(Standard_False)
344 myHCurve2d = new Geom2dAdaptor_HCurve(C2D);
349 //=======================================================================
350 //function : Approx_SameParameter
352 //=======================================================================
354 Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D,
355 const Handle(Adaptor2d_HCurve2d)& C2D,
356 const Handle(Adaptor3d_HSurface)& S,
357 const Standard_Real Tol):
358 mySameParameter(Standard_True), myDone(Standard_False)
367 //=======================================================================
370 //=======================================================================
371 void Approx_SameParameter::Build(const Standard_Real Tolerance)
373 const Standard_Real anErrorMAX = 1.0e15;
374 const Standard_Integer aMaxArraySize = 1000;
375 const Standard_Integer NCONTROL = 22;
377 Standard_Integer ii ;
378 Adaptor3d_CurveOnSurface CurveOnSurface(myHCurve2d,mySurf);
379 Standard_Real fcons = CurveOnSurface.FirstParameter();
380 Standard_Real lcons = CurveOnSurface.LastParameter();
381 Standard_Real fc3d = myC3d->FirstParameter();
382 Standard_Real lc3d = myC3d->LastParameter();
384 GeomAbs_Shape Continuity = myHCurve2d->Continuity();
386 if(Continuity > GeomAbs_C1) Continuity = GeomAbs_C1;
388 //Control tangents at the extremities to know if the
389 //reparametring is possible and calculate the tangents
390 //at the extremities of the function of change of variable.
391 Standard_Real tangent[2] = { 0.0, 0.0 };
395 Standard_Real Tol = Tolerance;
396 Standard_Real Tol2 = Tol * Tol;
397 Standard_Real deltamin = Precision::PConfusion();//50*Tolp;
399 Standard_Real besttol2 = Tol2;
400 Standard_Boolean extrok = 0;
403 CurveOnSurface.D1(fcons,Pcons,Vcons);
404 myC3d->D1(fc3d,Pc3d,Vc3d);
405 Standard_Real dist2 = Pcons.SquareDistance(Pc3d);
406 Standard_Real dmax2 = dist2;
408 Standard_Real magVcons = Vcons.Magnitude();
409 if (magVcons > 1.e-12){
410 tangent[0] = Vc3d.Magnitude() / magVcons;
414 CurveOnSurface.D1(lcons,Pcons,Vcons);
415 myC3d->D1(lc3d,Pc3d,Vc3d);
416 dist2 = Pcons.SquareDistance(Pc3d);
418 if(dist2 > dmax2) dmax2 = dist2;
419 magVcons = Vcons.Magnitude();
420 if (magVcons > 1.e-12){
421 tangent[1] = Vc3d.Magnitude() / magVcons;
426 //if(dmax2 > besttol2) besttol2 = dmax2;
428 //Take a multiple of the sample pof CheckShape,
429 //at least the control points will be correct. No comment!!!
432 Standard_Integer nbcoups = 0;
435 Standard_Boolean interpolok = 0;
436 Standard_Real tolsov = 1.e200;
437 //Take parameters with constant step on the curve on surface
439 Standard_Real deltacons = lcons - fcons;
440 deltacons /= (NCONTROL);
441 Standard_Real deltac3d = lc3d - fc3d;
442 deltac3d /= (NCONTROL);
444 Standard_Real wcons = fcons;
445 Standard_Real wc3d = fc3d;
447 Standard_Real qpcons[aMaxArraySize], qnewpcons[aMaxArraySize],
448 qpc3d[aMaxArraySize], qnewpc3d[aMaxArraySize];
449 Standard_Real * pcons = qpcons; Standard_Real * newpcons = qnewpcons;
450 Standard_Real * pc3d = qpc3d; Standard_Real * newpc3d = qnewpc3d;
452 for ( ii = 0 ; ii < NCONTROL; ii++) {
458 pcons[NCONTROL] = lcons;
459 pc3d[NCONTROL] = lc3d;
461 Standard_Integer New_NCONTROL = NCONTROL;
462 if(Continuity < GeomAbs_C1) {
463 Standard_Integer NbInt = myHCurve2d->NbIntervals(GeomAbs_C1) + 1;
464 TColStd_Array1OfReal Param_de_decoupeC1 (1, NbInt);
465 myHCurve2d->Intervals(Param_de_decoupeC1, GeomAbs_C1);
466 TColStd_SequenceOfReal new_par;
467 Standard_Integer inter = 1;
469 new_par.Append(fcons);
471 while(inter <= NbInt && Param_de_decoupeC1(inter) <= fcons + deltamin) inter++;
472 while(NbInt > 0 && Param_de_decoupeC1(NbInt) >= lcons - deltamin) NbInt--;
474 while(inter <= NbInt || (ii < NCONTROL && inter <= Param_de_decoupeC1.Length()) ) {
475 if(Param_de_decoupeC1(inter) < pcons[ii]) {
476 new_par.Append(Param_de_decoupeC1(inter));
477 if((pcons[ii] - Param_de_decoupeC1(inter)) <= deltamin) {
479 if(ii > NCONTROL) {ii = NCONTROL;}
484 if((Param_de_decoupeC1(inter) - pcons[ii]) > deltamin) {
485 new_par.Append(pcons[ii]);
491 new_par.Append(lcons);
492 New_NCONTROL = new_par.Length() - 1;
493 // Simple protection if New_NCONTROL > allocated elements in array but one
494 // aMaxArraySize - 1 index may be filled after projection.
495 if (New_NCONTROL > aMaxArraySize - 1) {
496 mySameParameter = Standard_False;
499 for(ii = 1; ii <= New_NCONTROL; ii++){
500 pcons[ii] = pc3d[ii] = new_par.Value(ii + 1);
502 pc3d[New_NCONTROL] = lc3d;
506 Extrema_LocateExtPC Projector;
507 Projector.Initialize(myC3d->Curve(),fc3d,lc3d,Tol);
509 Standard_Integer count = 1;
510 Standard_Real previousp = fc3d, initp=0, curp;//, deltamin = 50*Tolp;
511 Standard_Real bornesup = lc3d - deltamin;
512 Standard_Boolean projok = 0,
514 for (ii = 1; ii < New_NCONTROL; ii++){
515 CurveOnSurface.D0(pcons[ii],Pcons);
516 myC3d->D0(pc3d[ii],Pc3d);
517 dist2 = Pcons.SquareDistance(Pc3d);
518 use_parameter = (dist2 <= Tol2 && (pc3d[ii] > pc3d[count-1] + deltamin)) ;
519 Standard_Real aDistMin = RealLast();;
522 if(dist2 > dmax2) dmax2 = dist2;
523 initp = previousp = pc3d[count] = pc3d[ii];
524 pcons[count] = pcons[ii];
529 if(!projok) initp = pc3d[ii];
530 projok = mySameParameter = Standard_False;
531 Projector.Perform(Pcons, initp);
532 if (Projector.IsDone()) {
533 curp = Projector.Point().Parameter();
534 Standard_Real dist_2 = Projector.SquareDistance();
535 projok = Standard_True;
540 ProjectPointOnCurve(initp,Pcons,Tol,30,myC3d->Curve(),projok,curp);
543 const gp_Pnt& ap1 =myC3d->Value(curp);
544 aDistMin = Pcons.SquareDistance(ap1);
547 projok = (projok && (curp > previousp + deltamin && curp < bornesup));
550 initp = previousp = pc3d[count] = curp;
551 pcons[count] = pcons[ii];
557 Extrema_ExtPC PR(Pcons,myC3d->Curve(),fc3d,lc3d,Tol);
560 const Standard_Integer aNbExt = PR.NbExt();
563 Standard_Integer anIndMin = 0;
564 Standard_Real aCurDistMin = RealLast();
565 for(Standard_Integer i = 1; i <= aNbExt; i++)
567 const gp_Pnt &aP = PR.Point(i).Value();
568 Standard_Real aDist2 = aP.SquareDistance(Pcons);
569 if(aDist2 < aCurDistMin)
571 aCurDistMin = aDist2;
577 curp = PR.Point(anIndMin).Parameter();
578 if( curp > previousp + deltamin && curp < bornesup)
580 aDistMin = aCurDistMin;
581 initp = previousp = pc3d[count] = curp;
582 pcons[count] = pcons[ii];
584 projok = Standard_True;
592 if(projok && besttol2 < aDistMin)
600 cout << "Projection not done" << endl;
607 myTolReached = 1.5*sqrt(dmax2);
611 if(!extrok) { // If not already SameP and tangent to mill, abandon.
612 mySameParameter = Standard_False;
614 cout<<"SameParameter problem : zero tangent to extremities"<<endl;
619 pcons[count] = lcons;
626 TColgp_Array1OfPnt2d DEBP2d (0,count);
627 TColStd_Array1OfInteger DEBMults(0,count);
628 DEBMults.Init(1); DEBMults(0) = 2; DEBMults(count) = 2;
629 TColStd_Array1OfReal DEBKnots(0,count);
630 for (Standard_Integer DEBi = 0; DEBi <= count; DEBi++) {
631 DEBKnots(DEBi) = DEBi;
632 DEBP2d (DEBi) = gp_Pnt2d(pc3d[DEBi],pcons[DEBi]);
634 Handle(Geom2d_BSplineCurve) DEBBS =
635 new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
636 Sprintf(Name,"DEBC2d_%d",++NbCurve);
638 DrawTrSurf::Set(Name,DEBBS);
643 Standard_Boolean hasCountChanged = Standard_False;
647 // The tables and their limits for the interpolation.
648 Standard_Integer num_knots = count + 7;
649 Standard_Integer num_poles = count + 3;
650 TColStd_Array1OfReal Paramc3d(*pc3d,1,count+1);
651 TColStd_Array1OfReal Paramcons(*pcons,1,count+1);
652 TColStd_Array1OfInteger ContactOrder(1,num_poles) ;
653 TColStd_Array1OfReal Poles(1,num_poles) ;
654 TColStd_Array1OfReal InterpolationParameters(1,num_poles) ;
655 TColStd_Array1OfReal FlatKnots(1,num_knots) ;
657 // Fill tables taking attention to end values.
658 ContactOrder.Init(0);
659 ContactOrder(2) = ContactOrder(num_poles - 1) = 1;
661 FlatKnots(1) = FlatKnots(2) = FlatKnots(3) = FlatKnots(4) = fc3d;
662 FlatKnots(num_poles + 1) = FlatKnots(num_poles + 2) =
663 FlatKnots(num_poles + 3) = FlatKnots(num_poles + 4) = lc3d;
665 Poles(1) = fcons; Poles(num_poles) = lcons;
666 Poles(2) = tangent[0]; Poles(num_poles - 1) = tangent[1];
668 InterpolationParameters(1) = InterpolationParameters(2) = fc3d;
669 InterpolationParameters(num_poles - 1) = InterpolationParameters(num_poles) = lc3d;
671 for (ii = 3; ii <= num_poles - 2; ii++) {
672 Poles(ii) = Paramcons(ii - 1);
673 InterpolationParameters(ii) = FlatKnots(ii+2) = Paramc3d(ii - 1);
675 Standard_Integer inversion_problem;
676 BSplCLib::Interpolate(3,FlatKnots,InterpolationParameters,ContactOrder,
677 1,Poles(1),inversion_problem);
678 if(inversion_problem) {
679 Standard_ConstructionError::Raise();
682 //-------------------------------------------
688 Standard_Integer nnn = 100;
689 TColgp_Array1OfPnt2d DEBP2d (0,nnn);
690 TColStd_Array1OfInteger DEBMults(0,nnn);
691 DEBMults.Init(1); DEBMults(0) = 2; DEBMults(nnn) = 2;
692 TColStd_Array1OfReal DEBKnots(0,nnn);
693 Standard_Real du = (lc3d - fc3d) / nnn;
694 Standard_Real u3d = fc3d;
695 Standard_Integer extrap_mode[2] ;
696 extrap_mode[0] = extrap_mode[1] = 3;
697 Standard_Real eval_result[2] ;
698 Standard_Integer DerivativeRequest = 0;
699 Standard_Real *PolesArray =
700 (Standard_Real *) &Poles(Poles.Lower()) ;
702 for (Standard_Integer DEBi = 0; DEBi <= nnn; DEBi++) {
703 DEBKnots(DEBi) = DEBi;
714 DEBP2d (DEBi) = gp_Pnt2d(u3d,eval_result[0]);
718 Handle(Geom2d_BSplineCurve) DEBBS =
719 new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
720 Sprintf(Name,"DEBC2d_%d_%d",NbCurve,nbcoups );
722 DrawTrSurf::Set(Name,DEBBS);
726 //-------------------------------------------
728 //-------------------------------------------
729 // Test if par2d(par3d) is monotonous function or not ----- IFV, Jan 2000
730 // and try to insert new point to improve BSpline interpolation
732 Standard_Integer extrap_mode[2] ;
733 extrap_mode[0] = extrap_mode[1] = 3;
734 Standard_Real eval_result[2] ;
735 Standard_Integer DerivativeRequest = 0;
736 Standard_Real *PolesArray =
737 (Standard_Real *) &Poles(Poles.Lower()) ;
739 Standard_Integer newcount = 0;
740 for (ii = 0; ii < count; ii++) {
742 newpcons[newcount] = pcons[ii];
743 newpc3d[newcount] = pc3d[ii];
746 if(count - ii + newcount == aMaxArraySize) continue;
748 BSplCLib::Eval(.5*(pc3d[ii]+pc3d[ii+1]), Standard_False, DerivativeRequest,
749 extrap_mode[0], 3, FlatKnots, 1, PolesArray[0], eval_result[0]);
751 if(eval_result[0] < pcons[ii] || eval_result[0] > pcons[ii+1]) {
752 Standard_Real ucons = 0.5*(pcons[ii]+pcons[ii+1]);
753 Standard_Real uc3d = 0.5*(pc3d[ii]+pc3d[ii+1]);
755 CurveOnSurface.D0(ucons,Pcons);
756 Projector.Perform(Pcons, uc3d);
757 if (Projector.IsDone()) {
758 curp = Projector.Point().Parameter();
759 Standard_Real dist_2 = Projector.SquareDistance();
760 if(dist_2 > besttol2) besttol2 = dist_2;
764 ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
767 if(curp > pc3d[ii] + deltamin && curp < pc3d[ii+1] - deltamin){
768 newpc3d[newcount] = curp;
769 newpcons[newcount] = ucons;
776 cout << "Projection not done" << endl;
783 newpc3d[newcount] = pc3d[count];
784 newpcons[newcount] = pcons[count];
785 Standard_Real * temp;
793 if((count != newcount) && newcount < aMaxArraySize) { count = newcount; continue;}
797 Standard_Real algtol = sqrt(besttol2);
799 interpolok = Check (FlatKnots, Poles, count+1, Paramc3d, Paramcons,
800 myC3d, CurveOnSurface, algtol, tolsov);
802 if (Precision::IsInfinite(algtol)) {
803 mySameParameter = Standard_False;
805 cout<<"SameParameter problem : function of interpolation of parametration at mills !!"<<endl;
812 interpolok = (interpolok || count >= aMaxArraySize);
815 Standard_Real besttol = sqrt(besttol2);
818 if(algtol > besttol){
819 cout<<"SameParameter : Tol can't be reached before approx"<<endl;
823 Handle(TColStd_HArray1OfReal) tol1d,tol2d,tol3d;
824 tol1d = new TColStd_HArray1OfReal(1,2) ;
825 tol1d->SetValue(1, mySurf->UResolution(besttol));
826 tol1d->SetValue(2, mySurf->VResolution(besttol));
828 Approx_SameParameter_Evaluator ev (FlatKnots, Poles, myHCurve2d);
829 AdvApprox_ApproxAFunction anApproximator(2,0,0,tol1d,tol2d,tol3d,fc3d,lc3d,
830 Continuity,11,40,ev);
832 if (anApproximator.IsDone() || anApproximator.HasResult()) {
833 Adaptor3d_CurveOnSurface ACS = CurveOnSurface;
834 GeomLib_MakeCurvefromApprox aCurveBuilder(anApproximator) ;
835 Handle(Geom2d_BSplineCurve) aC2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ;
836 Handle(Adaptor2d_HCurve2d) aHCurve2d = new Geom2dAdaptor_HCurve(aC2d);
837 CurveOnSurface.Load(aHCurve2d);
839 myTolReached = ComputeTolReached(myC3d,CurveOnSurface,NCONTROL);
841 if(myTolReached > anErrorMAX)
843 //This tolerance is too big. Probably, we will not can get
844 //edge with sameparameter in this case.
846 myDone = Standard_False;
850 if( (myTolReached < 250.0*besttol) ||
851 (count >= aMaxArraySize-2) ||
852 !hasCountChanged) //if count does not change after adding new point
853 //(else we can have circularity)
856 myHCurve2d = new Geom2dAdaptor_HCurve(myCurve2d);
857 myDone = Standard_True;
861 interpolok = Standard_False;
862 CurveOnSurface = ACS;
871 cout<<"SameParameter : Not enough points, enrich"<<endl;
875 for(Standard_Integer n = 0; n < count; n++){
876 newpc3d[newcount] = pc3d[n];
877 newpcons[newcount] = pcons[n];
880 if(count - n + newcount == aMaxArraySize) continue;
882 Standard_Real ucons = 0.5*(pcons[n]+pcons[n+1]);
883 Standard_Real uc3d = 0.5*(pc3d[n]+pc3d[n+1]);
885 CurveOnSurface.D0(ucons,Pcons);
886 Projector.Perform(Pcons, uc3d);
887 if (Projector.IsDone()) {
888 curp = Projector.Point().Parameter();
889 Standard_Real dist_2 = Projector.SquareDistance();
890 if(dist_2 > besttol2) besttol2 = dist_2;
894 ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
897 if(curp > pc3d[n] + deltamin && curp < pc3d[n+1] - deltamin){
898 newpc3d[newcount] = curp;
899 newpcons[newcount] = ucons;
906 cout << "Projection not done" << endl;
910 newpc3d[newcount] = pc3d[count];
911 newpcons[newcount] = pcons[count];
912 Standard_Real * tempx;
920 if(count != newcount)
923 hasCountChanged = Standard_True;
927 hasCountChanged = Standard_False;