Integration of OCCT 6.5.0 from SVN
[occt.git] / src / ProjLib / ProjLib_ProjectedCurve.cxx
CommitLineData
7fd59977 1
2// File: ProjLib_ProjectedCurve.gxx
3// Created: Wed Aug 25 15:39:45 1993
4// Author: Bruno DUMORTIER
5// <dub@topsn3>
6
7// Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272
8
9#include <GeomAbs_SurfaceType.hxx>
10#include <Standard_NoSuchObject.hxx>
11#include <Standard_NotImplemented.hxx>
12#include <ProjLib_ProjectedCurve.hxx>
13#include <ProjLib_CompProjectedCurve.hxx>
14#include <ProjLib_HCompProjectedCurve.hxx>
15#include <ProjLib_ComputeApproxOnPolarSurface.hxx>
16#include <ProjLib_ComputeApprox.hxx>
17#include <ProjLib_Projector.hxx>
18#include <Handle_Adaptor3d_HCurve.hxx>
19#include <Handle_Adaptor3d_HSurface.hxx>
20#include <Adaptor3d_HCurve.hxx>
21#include <Adaptor3d_HSurface.hxx>
22#include <Approx_CurveOnSurface.hxx>
23#include <ProjLib_Plane.hxx>
24#include <ProjLib_Cylinder.hxx>
25#include <ProjLib_Cone.hxx>
26#include <ProjLib_Sphere.hxx>
27#include <ProjLib_Torus.hxx>
28#include <Precision.hxx>
29#include <Handle_Geom_BSplineCurve.hxx>
30#include <Geom2d_BSplineCurve.hxx>
31#include <Handle_Geom2d_BSplineCurve.hxx>
32#include <Geom2d_BezierCurve.hxx>
33#include <Handle_Geom2d_BezierCurve.hxx>
34#include <Handle_Adaptor2d_HCurve2d.hxx>
35#include <gp_Vec2d.hxx>
36#include <StdFail_NotDone.hxx>
37#include <gp_XY.hxx>
38#include <TColgp_HArray1OfPnt2d.hxx>
39#include <TColStd_HArray1OfReal.hxx>
40#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
41#include <TColStd_Array1OfReal.hxx>
42#include <TColStd_Array1OfInteger.hxx>
43#include <TColgp_Array1OfPnt2d.hxx>
44#include <TColgp_HArray1OfVec2d.hxx>
45#include <TColStd_HArray1OfBoolean.hxx>
46#include <BSplCLib.hxx>
47#include <GeomAbs_IsoType.hxx>
48
49//=======================================================================
50//function : IsoIsDeg
51//purpose :
52//=======================================================================
53
54static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
55 const Standard_Real Param,
56 const GeomAbs_IsoType IT,
57 const Standard_Real TolMin,
58 const Standard_Real TolMax)
59{
60 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
61 Standard_Boolean Along = Standard_True;
62 U1 = S.FirstUParameter();
63 U2 = S.LastUParameter();
64 V1 = S.FirstVParameter();
65 V2 = S.LastVParameter();
66 gp_Vec D1U,D1V;
67 gp_Pnt P;
68 Standard_Real Step,D1NormMax;
69 if (IT == GeomAbs_IsoV)
70 {
71 Step = (U2 - U1)/10;
72 D1NormMax=0.;
73 for (T=U1;T<=U2;T=T+Step)
74 {
75 S.D1(T,Param,P,D1U,D1V);
76 D1NormMax=Max(D1NormMax,D1U.Magnitude());
77 }
78
79 if (D1NormMax >TolMax || D1NormMax < TolMin )
80 Along = Standard_False;
81 }
82 else
83 {
84 Step = (V2 - V1)/10;
85 D1NormMax=0.;
86 for (T=V1;T<=V2;T=T+Step)
87 {
88 S.D1(Param,T,P,D1U,D1V);
89 D1NormMax=Max(D1NormMax,D1V.Magnitude());
90 }
91
92 if (D1NormMax >TolMax || D1NormMax < TolMin )
93 Along = Standard_False;
94
95
96 }
97 return Along;
98}
99
100//=======================================================================
101//function : Interpolate
102//purpose :
103//=======================================================================
104
105static Handle(Geom2d_BSplineCurve) Interpolate(const Handle(TColgp_HArray1OfPnt2d)& myPoints,
106 const Handle(TColStd_HArray1OfReal)& myParameters,
107 const gp_Vec2d& InitialTangent,
108 const gp_Vec2d& FinalTangent)
109{
110 Handle(Geom2d_BSplineCurve) myCurve = NULL;
111
112// This code is extraction from Geom2dAPI_Interpolate with small correction
113// This is done to avoid of cyclic dependency if Geom2dAPI is used in ProjLib
114
115 Standard_Integer degree,
116 ii,
117 jj,
118 index,
119 index1,
120 index2,
121 index3,
122 mult_index,
123 inversion_problem,
124 num_points,
125 num_distinct_knots,
126 num_poles ;
127
128 gp_Pnt2d a_point ;
129
130 Standard_Boolean myTangentRequest = Standard_True;
131
132 Handle(TColgp_HArray1OfVec2d) myTangents =
133 new TColgp_HArray1OfVec2d(myPoints->Lower(),
134 myPoints->Upper()) ;
135 Handle(TColStd_HArray1OfBoolean) myTangentFlags =
136 new TColStd_HArray1OfBoolean(myPoints->Lower(),
137 myPoints->Upper()) ;
138 myTangentFlags->Init(Standard_False);
139
140 myTangentFlags->SetValue(1,Standard_True) ;
141 myTangentFlags->SetValue(myPoints->Length(),Standard_True) ;
142 myTangents->SetValue(1,InitialTangent) ;
143 myTangents->SetValue(myPoints->Length(),FinalTangent);
144
145 num_points =
146 num_distinct_knots =
147 num_poles = myPoints->Length() ;
148 if (num_poles == 2 && !myTangentRequest) {
149 degree = 1 ;
150 }
151 else if (num_poles == 3 && !myTangentRequest) {
152 degree = 2 ;
153 num_distinct_knots = 2 ;
154 }
155 else {
156 degree = 3 ;
157 num_poles += 2 ;
158 //if (myTangentRequest)
159 //for (ii = myTangentFlags->Lower() + 1 ;
160 // ii < myTangentFlags->Upper() ; ii++) {
161 //if (myTangentFlags->Value(ii)) {
162 //num_poles += 1 ;
163 //}
164 //}
165 }
166
167
168 TColStd_Array1OfReal parameters(1,num_poles) ;
169 TColStd_Array1OfReal flatknots(1,num_poles + degree + 1) ;
170 TColStd_Array1OfInteger mults(1,num_distinct_knots) ;
171 TColStd_Array1OfReal knots(1,num_distinct_knots) ;
172 TColStd_Array1OfInteger contact_order_array(1, num_poles) ;
173 TColgp_Array1OfPnt2d poles(1,num_poles) ;
174
175 for (ii = 1 ; ii <= degree + 1 ; ii++) {
176 flatknots.SetValue(ii,myParameters->Value(1)) ;
177 flatknots.SetValue(ii + num_poles,
178 myParameters->Value(num_points)) ;
179 }
180 for (ii = 1 ; ii <= num_poles ; ii++) {
181 contact_order_array.SetValue(ii,0) ;
182 }
183 for (ii = 2 ; ii < num_distinct_knots ; ii++) {
184 mults.SetValue(ii,1) ;
185 }
186 mults.SetValue(1,degree + 1) ;
187 mults.SetValue(num_distinct_knots ,degree + 1) ;
188
189 switch (degree) {
190 case 1:
191 for (ii = 1 ; ii <= num_poles ; ii++) {
192 poles.SetValue(ii ,myPoints->Value(ii)) ;
193 }
194 myCurve =
195 new Geom2d_BSplineCurve(poles,
196 myParameters->Array1(),
197 mults,
198 degree) ;
199 //myIsDone = Standard_True ;
200 break ;
201 case 2:
202 knots.SetValue(1,myParameters->Value(1)) ;
203 knots.SetValue(2,myParameters->Value(3)) ;
204 for (ii = 1 ; ii <= num_poles ; ii++) {
205 poles.SetValue(ii,myPoints->Value(ii)) ;
206
207 }
208 BSplCLib::Interpolate(degree,
209 flatknots,
210 myParameters->Array1(),
211 contact_order_array,
212 poles,
213 inversion_problem) ;
214 if (!inversion_problem) {
215 myCurve =
216 new Geom2d_BSplineCurve(poles,
217 knots,
218 mults,
219 degree) ;
220 //myIsDone = Standard_True ;
221 }
222 break ;
223 case 3:
224//
225// check if the boundary conditions are set
226//
227 //if (num_points >= 3) {
228//
229// cannot build the tangents with degree 3 with only 2 points
230// if those where not given in advance
231//
232 //BuildTangents(myPoints->Array1(),
233 //myTangents->ChangeArray1(),
234 //myTangentFlags->ChangeArray1(),
235 //myParameters->Array1()) ;
236 //}
237 contact_order_array.SetValue(2,1) ;
238 parameters.SetValue(1,myParameters->Value(1)) ;
239 parameters.SetValue(2,myParameters->Value(1)) ;
240 poles.SetValue(1,myPoints->Value(1)) ;
241 for (jj = 1 ; jj <= 2 ; jj++) {
242 a_point.SetCoord(jj,myTangents->Value(1).Coord(jj)) ;
243
244 }
245 poles.SetValue(2,a_point) ;
246 mult_index = 2 ;
247 index = 3 ;
248 index1 = 2 ;
249 index2 = myPoints->Lower() + 1 ;
250 index3 = degree + 2 ;
251 if (myTangentRequest) {
252 for (ii = myParameters->Lower() + 1 ;
253 ii < myParameters->Upper() ; ii++) {
254 parameters.SetValue(index,myParameters->Value(ii)) ;
255 poles.SetValue(index,myPoints->Value(index2)) ;
256 flatknots.SetValue(index3,myParameters->Value(ii)) ;
257 index += 1 ;
258 index3 += 1 ;
259 if (myTangentFlags->Value(index1)) {
260//
261// set the multiplicities, the order of the contact, the
262// the flatknots,
263//
264 mults.SetValue(mult_index,mults.Value(mult_index) + 1) ;
265 contact_order_array(index) = 1 ;
266 flatknots.SetValue(index3, myParameters->Value(ii)) ;
267 parameters.SetValue(index,
268 myParameters->Value(ii)) ;
269 for (jj = 1 ; jj <= 2 ; jj++) {
270 a_point.SetCoord(jj,myTangents->Value(ii).Coord(jj)) ;
271 }
272 poles.SetValue(index,a_point) ;
273 index += 1 ;
274 index3 += 1 ;
275 }
276 mult_index += 1 ;
277 index1 += 1 ;
278 index2 += 1 ;
279
280 }
281 }
282 else {
283 index1 = 2 ;
284 for(ii = myParameters->Lower() ; ii <= myParameters->Upper() ; ii++) {
285 parameters.SetValue(index1,
286 myParameters->Value(ii)) ;
287 index1 += 1 ;
288 }
289 index = 3 ;
290 for (ii = myPoints->Lower() + 1 ; ii <= myPoints->Upper() - 1 ; ii++) {
291 poles.SetValue(index,
292 myPoints->Value(ii)) ;
293 index += 1 ;
294 }
295
296
297 index = degree + 1 ;
298 for(ii = myParameters->Lower() ; ii <= myParameters->Upper() ; ii++) {
299 flatknots.SetValue(index,
300 myParameters->Value(ii)) ;
301 index += 1 ;
302 }
303 }
304 for (jj = 1 ; jj <= 2 ; jj++) {
305 a_point.SetCoord(jj,
306 myTangents->Value(num_points).Coord(jj)) ;
307 }
308 poles.SetValue(num_poles-1 ,a_point) ;
309
310 contact_order_array.SetValue(num_poles - 1,1) ;
311 parameters.SetValue(num_poles,
312 myParameters->Value(myParameters->Upper())) ;
313 parameters.SetValue(num_poles -1,
314 myParameters->Value(myParameters->Upper())) ;
315
316 poles.SetValue(num_poles,
317 myPoints->Value(num_points)) ;
318
319 BSplCLib::Interpolate(degree,
320 flatknots,
321 parameters,
322 contact_order_array,
323 poles,
324 inversion_problem) ;
325 if (!inversion_problem) {
326 myCurve =
327 new Geom2d_BSplineCurve(poles,
328 myParameters->Array1(),
329 mults,
330 degree) ;
331 //myIsDone = Standard_True ;
332 }
333 break ;
334
335 }
336
337
338 return myCurve;
339}
340
341//=======================================================================
342//function : TrimC3d
343//purpose :
344//=======================================================================
345
346static void TrimC3d(Handle(Adaptor3d_HCurve)& myCurve,
347 Standard_Boolean* IsTrimmed,
348 const Standard_Real dt,
349 const gp_Pnt& Pole)
350{
351 Standard_Real f = myCurve->FirstParameter();
352 Standard_Real l = myCurve->LastParameter();
353
354 gp_Pnt P = myCurve->Value(f);
355
356 if(P.Distance(Pole) < Precision::Confusion()) {
357 IsTrimmed[0] = Standard_True;
358 f = f+dt;
359 myCurve = myCurve->Trim(f, l, Precision::Confusion());
360 }
361
362 P = myCurve->Value(l);
363 if(P.Distance(Pole) < Precision::Confusion()) {
364 IsTrimmed[1] = Standard_True;
365 l = l-dt;
366 myCurve = myCurve->Trim(f, l, Precision::Confusion());
367 }
368}
369
370//=======================================================================
371//function : ExtendC2d
372//purpose :
373//=======================================================================
374
375static void ExtendC2d(Handle(Geom2d_BSplineCurve)& aRes,
376 const Standard_Real t,
377 const Standard_Real dt,
378 const Standard_Real u1,
379 const Standard_Real u2,
380 const Standard_Real v1,
381 const Standard_Real v2)
382{
383 gp_Pnt2d P0;
384 gp_Vec2d V01, V02;
385 aRes->D2(t, P0, V01, V02);
386
387 gp_XY XYP1 = P0.XY() + V01.XY()*dt + .5*V02.XY()*dt*dt;
388
389 gp_Vec2d V11 = V01 + V02*dt;
390
391 if(XYP1.X() < u1) XYP1.SetX(u1);
392 if(XYP1.X() > u2) XYP1.SetX(u2);
393 if(XYP1.Y() < v1) XYP1.SetY(v1);
394 if(XYP1.Y() > v2) XYP1.SetY(v2);
395
396 Handle(TColgp_HArray1OfPnt2d) aPnts = new TColgp_HArray1OfPnt2d(1, 2);
397 Handle(TColStd_HArray1OfReal) aPars = new TColStd_HArray1OfReal(1, 2);
398
399 if(dt < 0.) {
400 aPnts->SetValue(1, gp_Pnt2d(XYP1));
401 aPnts->SetValue(2, P0);
402 aPars->SetValue(1, t + dt);
403 aPars->SetValue(2, t);
404 }
405 else {
406 aPnts->SetValue(2, gp_Pnt2d(XYP1));
407 aPnts->SetValue(1, P0);
408 aPars->SetValue(2, t + dt);
409 aPars->SetValue(1, t);
410 }
411
412 Handle(Geom2d_BSplineCurve) aC;
413
414 if(dt < 0.) {
415 aC = Interpolate(aPnts, aPars, V11, V01);
416 }
417 else {
418 aC = Interpolate(aPnts, aPars, V01, V11);
419 }
420
421
422 Geom2dConvert_CompCurveToBSplineCurve aConcat(aRes);
423 aConcat.Add(aC, Precision::PConfusion());
424
425 aRes = aConcat.BSplineCurve();
426
427}
428
429//=======================================================================
430//function : Project
431//purpose :
432//=======================================================================
433
434static void Project(ProjLib_Projector& P, Handle(Adaptor3d_HCurve)& C)
435{
436 GeomAbs_CurveType CType = C->GetType();
437 switch (CType) {
438 case GeomAbs_Line:
439 P.Project(C->Line());
440 break;
441 case GeomAbs_Circle:
442 P.Project(C->Circle());
443 break;
444 case GeomAbs_Ellipse:
445 P.Project(C->Ellipse());
446 break;
447 case GeomAbs_Hyperbola:
448 P.Project(C->Hyperbola());
449 break;
450 case GeomAbs_Parabola:
451 P.Project(C->Parabola());
452 break;
453 case GeomAbs_BSplineCurve:
454 case GeomAbs_BezierCurve:
455 case GeomAbs_OtherCurve: // try the approximation
456 break;
457 default:
458 Standard_NoSuchObject::Raise(" ");
459 }
460}
461
462//=======================================================================
463//function : ProjLib_ProjectedCurve
464//purpose :
465//=======================================================================
466
467ProjLib_ProjectedCurve::ProjLib_ProjectedCurve()
468
469{
470 myTolerance = Precision::PApproximation();
471}
472
473
474//=======================================================================
475//function : ProjLib_ProjectedCurve
476//purpose :
477//=======================================================================
478
479ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
480(const Handle(Adaptor3d_HSurface)& S)
481{
482 myTolerance = Precision::PApproximation();
483 Load(S);
484}
485
486
487//=======================================================================
488//function : ProjLib_ProjectedCurve
489//purpose :
490//=======================================================================
491
492ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
493(const Handle(Adaptor3d_HSurface)& S,
494 const Handle(Adaptor3d_HCurve)& C)
495{
496 myTolerance = Precision::PApproximation();
497 Load(S);
498 Load(C);
499}
500
501
502//=======================================================================
503//function : ProjLib_ProjectedCurve
504//purpose :
505//=======================================================================
506
507ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
508(const Handle(Adaptor3d_HSurface)& S,
509 const Handle(Adaptor3d_HCurve)& C,
510 const Standard_Real Tol)
511{
512 myTolerance = Max(Tol, Precision::PApproximation());
513 Load(S);
514 Load(C);
515}
516
517
518//=======================================================================
519//function : Load
520//purpose :
521//=======================================================================
522
523void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S)
524{
525 mySurface = S ;
526}
527
528
529//=======================================================================
530//function : Load
531//purpose :
532//=======================================================================
533
534void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
535{
536 myTolerance = Max(myTolerance,Precision::PApproximation());
537 myCurve = C;
538 GeomAbs_SurfaceType SType = mySurface->GetType();
539 GeomAbs_CurveType CType = myCurve->GetType();
540
541 switch (SType) {
542
543 case GeomAbs_Plane:
544 {
545 ProjLib_Plane P(mySurface->Plane());
546 Project(P,myCurve);
547 myResult = P;
548 }
549 break;
550
551 case GeomAbs_Cylinder:
552 {
553 ProjLib_Cylinder P(mySurface->Cylinder());
554 Project(P,myCurve);
555 myResult = P;
556 }
557 break;
558
559 case GeomAbs_Cone:
560 {
561 ProjLib_Cone P(mySurface->Cone());
562 Project(P,myCurve);
563 myResult = P;
564 }
565 break;
566
567 case GeomAbs_Sphere:
568 {
569 ProjLib_Sphere P(mySurface->Sphere());
570 Project(P,myCurve);
571 if ( P.IsDone()) {
572 // on met dans la pseudo-periode ( car Sphere n'est pas
573 // periodique en V !)
574 P.SetInBounds(myCurve->FirstParameter());
575 }
576 myResult = P;
577 }
578 break;
579
580 case GeomAbs_Torus:
581 {
582 ProjLib_Torus P(mySurface->Torus());
583 Project(P,myCurve);
584 myResult = P;
585 }
586 break;
587
588 case GeomAbs_BezierSurface:
589 case GeomAbs_BSplineSurface:
590 {
591
592 Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
593 Standard_Real f, l, dt;
594 const Standard_Real eps = 0.01;
595 f = myCurve->FirstParameter();
596 l = myCurve->LastParameter();
597 dt = (l-f)*eps;
598
599 Standard_Real U1=0.,U2=0.,V1=0.,V2=0;
600 const Adaptor3d_Surface& S = mySurface->Surface();
601 U1 = S.FirstUParameter();
602 U2 = S.LastUParameter();
603 V1 = S.FirstVParameter();
604 V2 = S.LastVParameter();
605
606 if(IsoIsDeg(S, U1, GeomAbs_IsoU, 0., 1.e-9) ) {
607 //Surface has pole at U = Umin
608 gp_Pnt Pole = mySurface->Value(U1, V1);
609 TrimC3d(myCurve, IsTrimmed, dt, Pole);
610 }
611
612 if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., 1.e-9) ) {
613 //Surface has pole at U = Umax
614 gp_Pnt Pole = mySurface->Value(U2, V1);
615 TrimC3d(myCurve, IsTrimmed, dt, Pole);
616 }
617
618 if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., 1.e-9) ) {
619 //Surface has pole at V = Vmin
620 gp_Pnt Pole = mySurface->Value(U1, V1);
621 TrimC3d(myCurve, IsTrimmed, dt, Pole);
622 }
623
624 if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., 1.e-9) ) {
625 //Surface has pole at V = Vmax
626 gp_Pnt Pole = mySurface->Value(U1, V2);
627 TrimC3d(myCurve, IsTrimmed, dt, Pole);
628 }
629
630 ProjLib_ComputeApproxOnPolarSurface polar(myCurve,
631 mySurface,
632 myTolerance);
633
634 Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
635
636 if(IsTrimmed[0] || IsTrimmed[1]) {
637 if(IsTrimmed[0]) {
638 //Add segment before start of curve
639 f = myCurve->FirstParameter();
640 ExtendC2d(aRes, f, -dt, U1, U2, V1, V2);
641 }
642 if(IsTrimmed[1]) {
643 //Add segment after end of curve
644 l = myCurve->LastParameter();
645 ExtendC2d(aRes, l, dt, U1, U2, V1, V2);
646 }
647 }
648
649 myResult.SetBSpline(aRes);
650 myResult.Done();
651 myResult.SetType(GeomAbs_BSplineCurve);
652 }
653 break;
654
655 default:
656 {
657 Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
658 Standard_Real f, l, dt;
659 const Standard_Real eps = 0.01;
660
661 if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution) {
662 //Check possible singularity
663
664 gp_Pnt P = mySurface->AxeOfRevolution().Location();
665 gp_Dir N = mySurface->AxeOfRevolution().Direction();
666
667 gp_Lin L(P, N);
668
669 f = myCurve->FirstParameter();
670 l = myCurve->LastParameter();
671 dt = (l-f)*eps;
672
673 P = myCurve->Value(f);
674 if(L.Distance(P) < Precision::Confusion()) {
675 IsTrimmed[0] = Standard_True;
676 f = f+dt;
677 myCurve = myCurve->Trim(f, l, Precision::Confusion());
678 }
679
680 P = myCurve->Value(l);
681 if(L.Distance(P) < Precision::Confusion()) {
682 IsTrimmed[1] = Standard_True;
683 l = l-dt;
684 myCurve = myCurve->Trim(f, l, Precision::Confusion());
685 }
686 }
687
688 ProjLib_CompProjectedCurve Projector(mySurface,myCurve,
689 myTolerance,myTolerance);
690 Handle(ProjLib_HCompProjectedCurve) HProjector =
691 new ProjLib_HCompProjectedCurve();
692 HProjector->Set(Projector);
693
694 // Normalement, dans le cadre de ProjLib, le resultat
695 // doit etre une et une seule courbe !!!
696 // De plus, cette courbe ne doit pas etre Single point
697 Standard_Integer NbCurves = Projector.NbCurves();
698 Standard_Real Udeb,Ufin;
699 if (NbCurves > 0) {
700 Projector.Bounds(1,Udeb,Ufin);
701 }
702 else {
703 StdFail_NotDone::Raise("ProjLib CompProjectedCurve Not Done");
704 }
705 // Approximons cette courbe algorithmique.
706 Standard_Boolean Only3d = Standard_False;
707 Standard_Boolean Only2d = Standard_True;
708 GeomAbs_Shape Continuity = GeomAbs_C1;
709 Standard_Integer MaxDegree = 14;
710 Standard_Integer MaxSeg = 16;
711
712 Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin,
713 myTolerance,
714 Continuity, MaxDegree, MaxSeg,
715 Only3d, Only2d);
716
717 Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
718
719 if(IsTrimmed[0] || IsTrimmed[1]) {
720 // Treatment only for surface of revolution
721 Standard_Real u1, u2, v1, v2;
722 u1 = mySurface->FirstUParameter();
723 u2 = mySurface->LastUParameter();
724 v1 = mySurface->FirstVParameter();
725 v2 = mySurface->LastVParameter();
726
727 if(IsTrimmed[0]) {
728 //Add segment before start of curve
729 ExtendC2d(aRes, f, -dt, u1, u2, v1, v2);
730 }
731 if(IsTrimmed[1]) {
732 //Add segment after end of curve
733 ExtendC2d(aRes, l, dt, u1, u2, v1, v2);
734 }
735 }
736
737 myResult.SetBSpline(aRes);
738 myResult.Done();
739 myResult.SetType(GeomAbs_BSplineCurve);
740 }
741 }
742 if ( !myResult.IsDone()) {
743 ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
744 myResult.Done();
745
746 // set the type
747 if ( SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve) {
748 myResult.SetType(GeomAbs_BezierCurve);
749 myResult.SetBezier(Comp.Bezier()) ;
750 }
751 else {
752 myResult.SetType(GeomAbs_BSplineCurve);
753 myResult.SetBSpline(Comp.BSpline()) ;
754 }
755 // set the periodicity flag
756 if ( SType == GeomAbs_Plane &&
757 CType == GeomAbs_BSplineCurve &&
758 myCurve->IsPeriodic() ) {
759 myResult.SetPeriodic();
760 }
761 myTolerance = Comp.Tolerance();
762 }
763
764 else {
765 // On remet arbitrairement la tol atteinte a une valeur
766 // petite en attendant mieux. dub lbo 11/03/97
767 myTolerance = Min(myTolerance,Precision::Confusion());
768
769 // Translate the projected curve to keep the first point
770 // In the canonical boundaries of periodic surfaces.
771 if (mySurface->IsUPeriodic()) {
772 // xf
773 Standard_Real aT1, aT2, aU1, aU2, aUPeriod, aUr, aUm, aUmid, dUm, dUr;
774 GeomAbs_CurveType aTypeR;
775 ProjLib_Projector aResult;
776 //
777 aT1=myCurve->FirstParameter();
778 aT2=myCurve->LastParameter();
779 aU1=mySurface->FirstUParameter();
780 aU2=mySurface->LastUParameter();
781 aUPeriod=mySurface->UPeriod();
782 //
783 aTypeR=myResult.GetType();
784 if ((aU2-aU1)<(aUPeriod-myTolerance) && aTypeR == GeomAbs_Line) {
785 aResult=myResult;
786 aResult.UFrame(aT1, aT2, aU1, aUPeriod);
787 //
788 gp_Lin2d &aLr = (gp_Lin2d &) aResult.Line();
789 aUr=aLr.Location().X();
790 gp_Lin2d &aLm = (gp_Lin2d &) myResult.Line();
791 aUm=aLm.Location().X();
792 //
793 aUmid=0.5*(aU2+aU1);
794 dUm=fabs(aUm-aUmid);
795 dUr=fabs(aUr-aUmid);
796 if (dUr<dUm) {
797 myResult=aResult;
798 }
799 }
800 else {
801 myResult.UFrame(aT1, aT2, aU1, aUPeriod);
802 }
803 //
804 /*
805 myResult.UFrame(myCurve->FirstParameter(),
806 myCurve->LastParameter(),
807 mySurface->FirstUParameter(),
808 mySurface->UPeriod());
809 */
810 //xt
811 // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin
812 // Correct the U isoline in periodical surface
813 // to be inside restriction boundaries.
814 if (myResult.GetType() == GeomAbs_Line) {
815 gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line();
816
817 Standard_Real aPeriod = mySurface->UPeriod();
818 Standard_Real aFUPar = mySurface->FirstUParameter();
819 Standard_Real aLUPar = mySurface->LastUParameter();
820
821 // Check if the parametric range is lower then the period.
822 if (aLUPar - aFUPar < aPeriod - myTolerance) {
823 Standard_Real aU = aLine.Location().X();
824
825 if (Abs(aU + aPeriod - aFUPar) < myTolerance ||
826 Abs(aU - aPeriod - aFUPar) < myTolerance) {
827 gp_Pnt2d aNewLoc(aFUPar, aLine.Location().Y());
828
829 aLine.SetLocation(aNewLoc);
830 } else if (Abs(aU + aPeriod - aLUPar) < myTolerance ||
831 Abs(aU - aPeriod - aLUPar) < myTolerance) {
832 gp_Pnt2d aNewLoc(aLUPar, aLine.Location().Y());
833
834 aLine.SetLocation(aNewLoc);
835 }
836 }
837 }
838 }
839// Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End
840
841 if (mySurface->IsVPeriodic()) {
842 myResult.VFrame(myCurve->FirstParameter(),
843 myCurve->LastParameter(),
844 mySurface->FirstVParameter(),
845 mySurface->VPeriod());
846// Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin
847// Correct the V isoline in a periodical surface
848// to be inside restriction boundaries.
849 if (myResult.GetType() == GeomAbs_Line) {
850 gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line();
851
852 Standard_Real aPeriod = mySurface->VPeriod();
853 Standard_Real aFVPar = mySurface->FirstVParameter();
854 Standard_Real aLVPar = mySurface->LastVParameter();
855
856 // Check if the parametric range is lower then the period.
857 if (aLVPar - aFVPar < aPeriod - myTolerance) {
858 Standard_Real aV = aLine.Location().Y();
859
860 if (Abs(aV + aPeriod - aFVPar) < myTolerance ||
861 Abs(aV - aPeriod - aFVPar) < myTolerance) {
862 gp_Pnt2d aNewLoc(aLine.Location().X(), aFVPar);
863
864 aLine.SetLocation(aNewLoc);
865 } else if (Abs(aV + aPeriod - aLVPar) < myTolerance ||
866 Abs(aV - aPeriod - aLVPar) < myTolerance) {
867 gp_Pnt2d aNewLoc(aLine.Location().X(), aLVPar);
868
869 aLine.SetLocation(aNewLoc);
870 }
871 }
872 }
873 }
874// Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End
875 }
876}
877
878
879//=======================================================================
880//function : GetSurface
881//purpose :
882//=======================================================================
883
884const Handle(Adaptor3d_HSurface)& ProjLib_ProjectedCurve::GetSurface() const
885{
886 return mySurface;
887}
888
889
890//=======================================================================
891//function : GetCurve
892//purpose :
893//=======================================================================
894
895const Handle(Adaptor3d_HCurve)& ProjLib_ProjectedCurve::GetCurve() const
896{
897 return myCurve;
898}
899
900
901//=======================================================================
902//function : GetTolerance
903//purpose :
904//=======================================================================
905
906Standard_Real ProjLib_ProjectedCurve::GetTolerance() const
907{
908 return myTolerance;
909}
910
911
912//=======================================================================
913//function : FirstParameter
914//purpose :
915//=======================================================================
916
917Standard_Real ProjLib_ProjectedCurve::FirstParameter() const
918{
919 return myCurve->FirstParameter();
920}
921
922
923//=======================================================================
924//function : LastParameter
925//purpose :
926//=======================================================================
927
928Standard_Real ProjLib_ProjectedCurve::LastParameter() const
929{
930 return myCurve->LastParameter();
931}
932
933
934//=======================================================================
935//function : Continuity
936//purpose :
937//=======================================================================
938
939GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
940{
941 Standard_NotImplemented::Raise("");
942 return GeomAbs_C0;
943}
944
945
946//=======================================================================
947//function : NbIntervals
948//purpose :
949//=======================================================================
950
951Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const
952{
953 Standard_NotImplemented::Raise("");
954 return 0;
955}
956
957
958//=======================================================================
959//function : Intervals
960//purpose :
961//=======================================================================
962
963//void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& T,
964void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& ,
965 const GeomAbs_Shape ) const
966{
967 Standard_NotImplemented::Raise("");
968}
969
970
971//=======================================================================
972//function : IsClosed
973//purpose :
974//=======================================================================
975
976Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const
977{
978 Standard_NotImplemented::Raise("");
979 return Standard_True;
980}
981
982
983//=======================================================================
984//function : IsPeriodic
985//purpose :
986//=======================================================================
987
988Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const
989{
990 return myResult.IsPeriodic();
991}
992
993
994//=======================================================================
995//function : Period
996//purpose :
997//=======================================================================
998
999Standard_Real ProjLib_ProjectedCurve::Period() const
1000{
1001 Standard_NotImplemented::Raise("");
1002 return 0.;
1003}
1004
1005
1006//=======================================================================
1007//function : Value
1008//purpose :
1009//=======================================================================
1010
1011gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const
1012{
1013 Standard_NotImplemented::Raise("");
1014 return gp_Pnt2d(0.,0.);
1015}
1016
1017
1018//=======================================================================
1019//function : D0
1020//purpose :
1021//=======================================================================
1022
1023void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const
1024{
1025 Standard_NotImplemented::Raise("");
1026}
1027
1028
1029//=======================================================================
1030//function : D1
1031//purpose :
1032//=======================================================================
1033
1034void ProjLib_ProjectedCurve::D1(const Standard_Real ,
1035 gp_Pnt2d& ,
1036 gp_Vec2d& ) const
1037{
1038 Standard_NotImplemented::Raise("");
1039}
1040
1041
1042//=======================================================================
1043//function : D2
1044//purpose :
1045//=======================================================================
1046
1047void ProjLib_ProjectedCurve::D2(const Standard_Real ,
1048 gp_Pnt2d& ,
1049 gp_Vec2d& ,
1050 gp_Vec2d& ) const
1051{
1052 Standard_NotImplemented::Raise("");
1053}
1054
1055
1056//=======================================================================
1057//function : D3
1058//purpose :
1059//=======================================================================
1060
1061void ProjLib_ProjectedCurve::D3(const Standard_Real,
1062 gp_Pnt2d&,
1063 gp_Vec2d&,
1064 gp_Vec2d&,
1065 gp_Vec2d&) const
1066{
1067 Standard_NotImplemented::Raise("");
1068}
1069
1070
1071//=======================================================================
1072//function : DN
1073//purpose :
1074//=======================================================================
1075
1076gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real,
1077 const Standard_Integer) const
1078{
1079 Standard_NotImplemented::Raise("");
1080 return gp_Vec2d(0.,0.);
1081}
1082
1083
1084//=======================================================================
1085//function : Resolution
1086//purpose :
1087//=======================================================================
1088
1089Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const
1090{
1091 Standard_NotImplemented::Raise("");
1092 return 0.;
1093}
1094
1095
1096//=======================================================================
1097//function : GetType
1098//purpose :
1099//=======================================================================
1100
1101GeomAbs_CurveType ProjLib_ProjectedCurve::GetType() const
1102{
1103 return myResult.GetType();
1104}
1105
1106
1107//=======================================================================
1108//function : Line
1109//purpose :
1110//=======================================================================
1111
1112gp_Lin2d ProjLib_ProjectedCurve::Line() const
1113{
1114 return myResult.Line();
1115}
1116
1117
1118//=======================================================================
1119//function : Circle
1120//purpose :
1121//=======================================================================
1122
1123gp_Circ2d ProjLib_ProjectedCurve::Circle() const
1124{
1125 return myResult.Circle();
1126}
1127
1128
1129//=======================================================================
1130//function : Ellipse
1131//purpose :
1132//=======================================================================
1133
1134gp_Elips2d ProjLib_ProjectedCurve::Ellipse() const
1135{
1136 return myResult.Ellipse();
1137}
1138
1139
1140//=======================================================================
1141//function : Hyperbola
1142//purpose :
1143//=======================================================================
1144
1145gp_Hypr2d ProjLib_ProjectedCurve::Hyperbola() const
1146{
1147 return myResult.Hyperbola();
1148}
1149
1150
1151//=======================================================================
1152//function : Parabola
1153//purpose :
1154//=======================================================================
1155
1156gp_Parab2d ProjLib_ProjectedCurve::Parabola() const
1157{
1158 return myResult.Parabola();
1159}
1160
1161
1162
1163//=======================================================================
1164//function : Degree
1165//purpose :
1166//=======================================================================
1167
1168Standard_Integer ProjLib_ProjectedCurve::Degree() const
1169{
1170 Standard_NoSuchObject_Raise_if
1171 ( (GetType() != GeomAbs_BSplineCurve) &&
1172 (GetType() != GeomAbs_BezierCurve),
1173 "ProjLib_ProjectedCurve:Degree");
1174 if (GetType() == GeomAbs_BSplineCurve) {
1175 return myResult.BSpline()->Degree();
1176 }
1177 else if (GetType() == GeomAbs_BezierCurve) {
1178 return myResult.Bezier()->Degree();
1179 }
1180
1181 // portage WNT
1182 return 0;
1183}
1184
1185//=======================================================================
1186//function : IsRational
1187//purpose :
1188//=======================================================================
1189
1190Standard_Boolean ProjLib_ProjectedCurve::IsRational() const
1191{
1192 Standard_NoSuchObject_Raise_if
1193 ( (GetType() != GeomAbs_BSplineCurve) &&
1194 (GetType() != GeomAbs_BezierCurve),
1195 "ProjLib_ProjectedCurve:IsRational");
1196 if (GetType() == GeomAbs_BSplineCurve) {
1197 return myResult.BSpline()->IsRational();
1198 }
1199 else if (GetType() == GeomAbs_BezierCurve) {
1200 return myResult.Bezier()->IsRational();
1201 }
1202 // portage WNT
1203 return Standard_False;
1204}
1205
1206//=======================================================================
1207//function : NbPoles
1208//purpose :
1209//=======================================================================
1210
1211Standard_Integer ProjLib_ProjectedCurve::NbPoles() const
1212{
1213 Standard_NoSuchObject_Raise_if
1214 ( (GetType() != GeomAbs_BSplineCurve) &&
1215 (GetType() != GeomAbs_BezierCurve)
1216 ,"ProjLib_ProjectedCurve:NbPoles" );
1217 if (GetType() == GeomAbs_BSplineCurve) {
1218 return myResult.BSpline()->NbPoles();
1219 }
1220 else if (GetType() == GeomAbs_BezierCurve) {
1221 return myResult.Bezier()->NbPoles();
1222 }
1223
1224 // portage WNT
1225 return 0;
1226}
1227
1228//=======================================================================
1229//function : NbKnots
1230//purpose :
1231//=======================================================================
1232
1233Standard_Integer ProjLib_ProjectedCurve::NbKnots() const
1234{
1235 Standard_NoSuchObject_Raise_if ( GetType() != GeomAbs_BSplineCurve,
1236 "ProjLib_ProjectedCurve:NbKnots");
1237 return myResult.BSpline()->NbKnots();
1238}
1239
1240//=======================================================================
1241//function : Bezier
1242//purpose :
1243//=======================================================================
1244
1245Handle(Geom2d_BezierCurve) ProjLib_ProjectedCurve::Bezier() const
1246{
1247 return myResult.Bezier() ;
1248}
1249
1250//=======================================================================
1251//function : BSpline
1252//purpose :
1253//=======================================================================
1254
1255Handle(Geom2d_BSplineCurve) ProjLib_ProjectedCurve::BSpline() const
1256{
1257 return myResult.BSpline() ;
1258}
1259//=======================================================================
1260//function : Trim
1261//purpose :
1262//=======================================================================
1263
1264Handle(Adaptor2d_HCurve2d) ProjLib_ProjectedCurve::Trim
1265//(const Standard_Real First,
1266// const Standard_Real Last,
1267// const Standard_Real Tolerance) const
1268(const Standard_Real ,
1269 const Standard_Real ,
1270 const Standard_Real ) const
1271{
1272 Standard_NotImplemented::Raise("");
1273 return NULL ;
1274}
1275