1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 //Jean-Claude Vauthier Novembre 1991
16 //Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline
17 //Modif JCV correction bug le 02/08/1993
20 #include <GeomConvert.ixx>
23 #include <BSplCLib.hxx>
25 #include <Standard_DomainError.hxx>
26 #include <Standard_NotImplemented.hxx>
28 #include <Convert_ElementarySurfaceToBSplineSurface.hxx>
29 #include <Convert_ConeToBSplineSurface.hxx>
30 #include <Convert_CylinderToBSplineSurface.hxx>
31 #include <Convert_SphereToBSplineSurface.hxx>
32 #include <Convert_TorusToBSplineSurface.hxx>
33 #include <GeomConvert_ApproxSurface.hxx>
35 #include <Geom_OffsetSurface.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_CylindricalSurface.hxx>
39 #include <Geom_ConicalSurface.hxx>
40 #include <Geom_SphericalSurface.hxx>
41 #include <Geom_ToroidalSurface.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_SurfaceOfRevolution.hxx>
44 #include <Geom_SurfaceOfLinearExtrusion.hxx>
45 #include <Geom_BSplineSurface.hxx>
46 #include <Geom_BezierSurface.hxx>
47 #include <Geom_Geometry.hxx>
48 #include <Geom_TrimmedCurve.hxx>
50 #include <GeomAdaptor_Surface.hxx>
52 #include <TColgp_Array2OfPnt.hxx>
53 #include <TColgp_Array1OfPnt.hxx>
54 #include <TColStd_Array1OfReal.hxx>
55 #include <TColStd_Array2OfReal.hxx>
56 #include <TColStd_Array1OfInteger.hxx>
57 #include <TColStd_Array2OfInteger.hxx>
58 #include <TColStd_HArray1OfReal.hxx>
59 #include <TColStd_HArray1OfInteger.hxx>
61 #include <Precision.hxx>
63 #include <gp_Sphere.hxx>
64 #include <gp_Cylinder.hxx>
65 #include <gp_Cone.hxx>
66 #include <gp_Torus.hxx>
68 #include <gp_Trsf.hxx>
69 #include <gp_GTrsf.hxx>
71 typedef Geom_Surface Surface;
72 typedef Geom_BSplineSurface BSplineSurface;
73 typedef TColStd_Array1OfReal Array1OfReal;
74 typedef TColStd_Array2OfReal Array2OfReal;
75 typedef TColStd_Array1OfInteger Array1OfInteger;
76 typedef TColStd_Array2OfInteger Array2OfInteger;
77 typedef TColgp_Array2OfPnt Array2OfPnt;
78 typedef TColgp_Array1OfPnt Array1OfPnt;
81 //=======================================================================
82 //function : BSplineSurfaceBuilder
84 //=======================================================================
86 Handle(Geom_BSplineSurface) BSplineSurfaceBuilder
87 (const Convert_ElementarySurfaceToBSplineSurface& Convert)
89 Handle(Geom_BSplineSurface) TheSurface;
90 Standard_Integer UDegree = Convert.UDegree ();
91 Standard_Integer VDegree = Convert.VDegree ();
92 Standard_Integer NbUPoles = Convert.NbUPoles();
93 Standard_Integer NbVPoles = Convert.NbVPoles();
94 Standard_Integer NbUKnots = Convert.NbUKnots();
95 Standard_Integer NbVKnots = Convert.NbVKnots();
96 Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
97 Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
98 Array1OfReal UKnots (1, NbUKnots);
99 Array1OfReal VKnots (1, NbVKnots);
100 Array1OfInteger UMults (1, NbUKnots);
101 Array1OfInteger VMults (1, NbVKnots);
102 Standard_Integer i, j;
103 for (j = 1; j <= NbVPoles; j++) {
104 for (i = 1; i <= NbUPoles; i++) {
105 Poles (i, j) = Convert.Pole (i, j);
106 Weights (i, j) = Convert.Weight (i, j);
109 for (i = 1; i <= NbUKnots; i++) {
110 UKnots (i) = Convert.UKnot (i);
111 UMults (i) = Convert.UMultiplicity (i);
113 for (i = 1; i <= NbVKnots; i++) {
114 VKnots (i) = Convert.VKnot (i);
115 VMults (i) = Convert.VMultiplicity (i);
117 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
118 UMults, VMults, UDegree, VDegree,
119 Convert.IsUPeriodic(),
120 Convert.IsVPeriodic());
124 //=======================================================================
125 //function : SplitBSplineSurface
127 //=======================================================================
129 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
130 (const Handle(Geom_BSplineSurface)& S,
131 const Standard_Integer FromUK1,
132 const Standard_Integer ToUK2,
133 const Standard_Integer FromVK1,
134 const Standard_Integer ToVK2,
135 const Standard_Boolean SameUOrientation,
136 const Standard_Boolean SameVOrientation )
138 Standard_Integer FirstU = S->FirstUKnotIndex ();
139 Standard_Integer FirstV = S->FirstVKnotIndex ();
140 Standard_Integer LastU = S->LastUKnotIndex ();
141 Standard_Integer LastV = S->LastVKnotIndex ();
142 if (FromUK1 == ToUK2 || FromVK1 == ToVK2) Standard_DomainError::Raise();
143 Standard_Integer FirstUK = Min (FromUK1, ToUK2);
144 Standard_Integer LastUK = Max (FromUK1, ToUK2);
145 Standard_Integer FirstVK = Min (FromVK1, ToVK2);
146 Standard_Integer LastVK = Max (FromVK1, ToVK2);
147 if (FirstUK < FirstU || LastUK > LastU ||
148 FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
150 Handle(Geom_BSplineSurface) S1= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
152 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
153 S1->VKnot(FirstVK),S1->VKnot(LastVK));
155 if (S->IsUPeriodic()) {
156 if (!SameUOrientation) S1->UReverse();
159 if (FromUK1 > ToUK2) S1->UReverse();
161 if (S->IsVPeriodic()) {
162 if (!SameVOrientation) S1->VReverse();
165 if (FromVK1 > ToVK2) S1->VReverse();
171 //=======================================================================
172 //function : SplitBSplineSurface
174 //=======================================================================
176 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
177 (const Handle(Geom_BSplineSurface)& S,
178 const Standard_Integer FromK1,
179 const Standard_Integer ToK2,
180 const Standard_Boolean USplit,
181 const Standard_Boolean SameOrientation )
183 if (FromK1 == ToK2) Standard_DomainError::Raise();
186 Handle(Geom_BSplineSurface) S1 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
190 Standard_Integer FirstU = S->FirstUKnotIndex ();
191 Standard_Integer LastU = S->LastUKnotIndex ();
192 Standard_Integer FirstUK = Min (FromK1, ToK2);
193 Standard_Integer LastUK = Max (FromK1, ToK2);
194 if (FirstUK < FirstU || LastUK > LastU) Standard_DomainError::Raise();
196 S1->Segment( S1->UKnot(FirstUK),
198 S1->VKnot(S1->FirstVKnotIndex()),
199 S1->VKnot(S1->LastVKnotIndex()));
201 if (S->IsUPeriodic()) {
202 if (!SameOrientation) S1->UReverse();
205 if (FromK1 > ToK2) S1->UReverse();
211 Standard_Integer FirstV = S->FirstVKnotIndex ();
212 Standard_Integer LastV = S->LastVKnotIndex ();
213 Standard_Integer FirstVK = Min (FromK1, ToK2);
214 Standard_Integer LastVK = Max (FromK1, ToK2);
215 if (FirstVK < FirstV || LastVK > LastV) Standard_DomainError::Raise();
217 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
218 S1->UKnot(S1->LastUKnotIndex()),
223 if (S->IsVPeriodic()) {
224 if (!SameOrientation) S1->VReverse();
227 if (FromK1 > ToK2) S1->VReverse();
234 //=======================================================================
235 //function : SplitBSplineSurface
237 //=======================================================================
239 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
240 (const Handle(Geom_BSplineSurface)& S,
241 const Standard_Real FromU1,
242 const Standard_Real ToU2,
243 const Standard_Real FromV1,
244 const Standard_Real ToV2,
245 // const Standard_Real ParametricTolerance,
246 const Standard_Real ,
247 const Standard_Boolean SameUOrientation,
248 const Standard_Boolean SameVOrientation )
250 Standard_Real FirstU = Min( FromU1, ToU2);
251 Standard_Real LastU = Max( FromU1, ToU2);
252 Standard_Real FirstV = Min( FromV1, ToV2);
253 Standard_Real LastV = Max( FromV1, ToV2);
255 Handle (Geom_BSplineSurface) NewSurface
256 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
258 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
260 if (S->IsUPeriodic()) {
261 if (!SameUOrientation) NewSurface->UReverse();
264 if (FromU1 > ToU2) NewSurface->UReverse();
266 if (S->IsVPeriodic()) {
267 if (!SameVOrientation) NewSurface->VReverse();
270 if (FromV1 > ToV2) NewSurface->VReverse();
276 //=======================================================================
277 //function : SplitBSplineSurface
279 //=======================================================================
281 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
282 (const Handle(Geom_BSplineSurface)& S,
283 const Standard_Real FromParam1,
284 const Standard_Real ToParam2,
285 const Standard_Boolean USplit,
286 const Standard_Real ParametricTolerance,
287 const Standard_Boolean SameOrientation )
289 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
290 Standard_DomainError::Raise();
292 Handle(Geom_BSplineSurface) NewSurface
293 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
296 Standard_Real FirstU = Min( FromParam1, ToParam2);
297 Standard_Real LastU = Max( FromParam1, ToParam2);
298 Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
299 Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
301 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
303 if (S->IsUPeriodic()) {
304 if (!SameOrientation) NewSurface->UReverse();
307 if (FromParam1 > ToParam2) NewSurface->UReverse();
312 Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
313 Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
314 Standard_Real FirstV = Min( FromParam1, ToParam2);
315 Standard_Real LastV = Max( FromParam1, ToParam2);
317 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
319 if (S->IsUPeriodic()) {
320 if (!SameOrientation) NewSurface->UReverse();
323 if (FromParam1 > ToParam2) NewSurface->UReverse();
331 //=======================================================================
332 //function : SurfaceToBSplineSurface
334 //=======================================================================
336 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
337 (const Handle(Geom_Surface)& Sr)
339 Standard_Real U1, U2, V1, V2;
340 Sr->Bounds (U1, U2, V1, V2);
341 Standard_Real UFirst = Min (U1, U2);
342 Standard_Real ULast = Max (U1, U2);
343 Standard_Real VFirst = Min (V1, V2);
344 Standard_Real VLast = Max (V1, V2);
346 //If the surface Sr is infinite stop the computation
347 if (Precision::IsNegativeInfinite(UFirst) ||
348 Precision::IsPositiveInfinite(ULast) ||
349 Precision::IsNegativeInfinite(VFirst) ||
350 Precision::IsPositiveInfinite(VLast) ) {
351 Standard_DomainError::Raise("");
354 Handle(Geom_BSplineSurface) TheSurface;
355 Handle(Geom_Surface) S;
356 Handle(Geom_OffsetSurface) OffsetSur;
357 if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
358 OffsetSur = *((Handle(Geom_OffsetSurface)*)& Sr);
359 S = OffsetSur->Surface();
360 if (!S.IsNull()) { // Convert the equivalent surface.
361 return SurfaceToBSplineSurface(S);
366 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
367 Handle(Geom_RectangularTrimmedSurface) Strim =
368 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
370 Handle(Geom_Surface) Surf = Strim->BasisSurface();
371 UFirst = U1; ULast = U2; VFirst = V1; VLast = V2;
372 if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
373 Handle(Geom_OffsetSurface) OffsetSur =
374 Handle(Geom_OffsetSurface)::DownCast(Surf);
376 S = OffsetSur->Surface();
383 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
384 Handle(Geom_RectangularTrimmedSurface) Strim = new
385 (Geom_RectangularTrimmedSurface) (Surf,
388 return SurfaceToBSplineSurface(Strim);
391 if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
392 TColgp_Array2OfPnt Poles (1, 2, 1, 2);
393 Poles (1, 1) = Strim->Value (U1, V1);
394 Poles (1, 2) = Strim->Value (U1, V2);
395 Poles (2, 1) = Strim->Value (U2, V1);
396 Poles (2, 2) = Strim->Value (U2, V2);
397 TColStd_Array1OfReal UKnots (1, 2);
398 TColStd_Array1OfReal VKnots (1, 2);
399 TColStd_Array1OfInteger UMults (1, 2);
400 TColStd_Array1OfInteger VMults (1, 2);
409 Standard_Integer UDegree = 1;
410 Standard_Integer VDegree = 1;
411 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
412 VMults, UDegree, VDegree);
414 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
415 Handle(Geom_CylindricalSurface) TheElSurf=
416 Handle(Geom_CylindricalSurface)::DownCast(Surf);
418 gp_Cylinder Cyl = TheElSurf->Cylinder();
419 if (Strim->IsUClosed()) {
420 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
421 TheSurface = BSplineSurfaceBuilder (Convert);
424 Convert_CylinderToBSplineSurface
425 Conv (Cyl, UFirst, ULast, VFirst, VLast);
426 TheSurface = BSplineSurfaceBuilder (Conv);
431 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
432 Handle(Geom_ConicalSurface) TheElSurf =
433 Handle(Geom_ConicalSurface)::DownCast(Surf);
434 gp_Cone Co = TheElSurf->Cone();
435 if (Strim->IsUClosed()) {
436 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
437 TheSurface = BSplineSurfaceBuilder (Convert);
440 Convert_ConeToBSplineSurface
441 Convert (Co, UFirst, ULast, VFirst, VLast);
442 TheSurface = BSplineSurfaceBuilder (Convert);
447 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
448 Handle(Geom_SphericalSurface) TheElSurf =
449 Handle(Geom_SphericalSurface)::DownCast(Surf);
450 gp_Sphere Sph = TheElSurf->Sphere();
452 if (Strim->IsUClosed()) {
453 //if (Strim->IsVClosed()) {
454 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
455 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
456 TheSurface = BSplineSurfaceBuilder (Convert);
459 Convert_SphereToBSplineSurface
460 Convert (Sph, UFirst, ULast, VFirst, VLast);
461 TheSurface = BSplineSurfaceBuilder (Convert);
466 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
467 Handle(Geom_ToroidalSurface) TheElSurf =
468 Handle(Geom_ToroidalSurface)::DownCast(Surf);
470 gp_Torus Tr = TheElSurf->Torus();
471 if (Strim->IsUClosed()) {
472 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
474 TheSurface = BSplineSurfaceBuilder (Convert);
476 else if (Strim->IsVClosed()) {
477 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
478 TheSurface = BSplineSurfaceBuilder (Convert);
481 Convert_TorusToBSplineSurface
482 Convert (Tr, UFirst, ULast, VFirst, VLast);
483 TheSurface = BSplineSurfaceBuilder (Convert);
488 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
489 Handle(Geom_SurfaceOfRevolution) Revol =
490 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
492 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
493 Handle(Geom_BSplineCurve) C;
494 if (Strim->IsVClosed()) {
495 C = GeomConvert::CurveToBSplineCurve (Meridian);
498 Handle(Geom_TrimmedCurve) CT =
499 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
500 C = GeomConvert::CurveToBSplineCurve (CT);
502 Standard_Integer NbUPoles, NbUKnots;
503 Standard_Integer NbVPoles, NbVKnots;
504 Standard_Boolean periodic = Standard_False;
506 // Poles of meridian = Vpoles
507 NbVPoles = C->NbPoles();
508 TColgp_Array1OfPnt Poles(1, NbVPoles);
510 TColStd_Array1OfReal Weights( 1, NbVPoles);
512 if ( C->IsRational()) C->Weights(Weights);
514 Standard_Integer nbUSpans;
516 if (Strim->IsUPeriodic()) {
521 periodic = Standard_True;
524 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
526 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
527 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
528 NbUPoles = 2 * nbUSpans + 1;
529 NbUKnots = nbUSpans + 1;
531 // Compute Knots and Mults
532 TColStd_Array1OfReal UKnots(1, NbUKnots);
533 TColStd_Array1OfInteger UMults( 1, NbUKnots);
534 Standard_Integer i,j;
535 for ( i = 1; i <= NbUKnots; i++) {
536 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
540 UMults(1)++; UMults(NbUKnots)++;
542 NbVKnots = C->NbKnots();
543 TColStd_Array1OfReal VKnots(1, NbVKnots);
544 TColStd_Array1OfInteger VMults(1, NbVKnots);
546 C->Multiplicities(VMults);
548 // Compute the poles.
549 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
550 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
553 for ( i = 1; i<= NbUPoles; i+=2) {
554 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
555 for ( j = 1; j <= NbVPoles; j++) {
556 NewPoles(i,j) = Poles(j).Transformed(Trsf);
557 NewWeights(i,j) = Weights(j);
561 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
563 for ( j= 1; j<= NbVPoles; j++) {
564 coord = Poles(j).XYZ();
565 Aff.Transforms(coord);
566 Poles(j).SetXYZ(coord);
568 for ( i = 2; i<= NbUPoles; i+=2) {
569 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
570 for ( j = 1; j <= NbVPoles; j++) {
571 NewPoles(i,j) = Poles(j).Transformed(Trsf);
572 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
576 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
580 periodic, C->IsPeriodic());
586 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
587 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
588 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
590 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
591 Handle(Geom_BSplineCurve) C;
592 if (Strim->IsUClosed()) {
593 C = GeomConvert::CurveToBSplineCurve (Meridian);
596 Handle(Geom_TrimmedCurve) CT =
597 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
598 C = GeomConvert::CurveToBSplineCurve (CT);
600 TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
601 TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
602 TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
604 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
605 C->Multiplicities(UMults);
606 TColStd_Array1OfReal VKnots ( 1, 2);
609 TColStd_Array1OfInteger VMults ( 1, 2);
612 gp_Vec D( Extru->Direction());
613 gp_Vec DV1 = VFirst * D;
614 gp_Vec DV2 = VLast * D;
615 for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
616 Poles(i,1) = C->Pole(i).Translated(DV1);
617 Poles(i,2) = C->Pole(i).Translated(DV2);
618 Weights(i,1) = Weights(i,2) = C->Weight(i);
620 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
623 C->IsPeriodic(), Standard_False);
627 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
629 Handle(Geom_BezierSurface) SBez =
630 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
632 SBez->Segment (U1, U2, V1, V2);
633 Standard_Integer NbUPoles = SBez->NbUPoles();
634 Standard_Integer NbVPoles = SBez->NbVPoles();
635 Standard_Integer UDegree = SBez->UDegree();
636 Standard_Integer VDegree = SBez->VDegree();
637 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
638 TColStd_Array1OfReal UKnots (1, 2);
639 TColStd_Array1OfInteger UMults (1, 2);
640 TColStd_Array1OfReal VKnots (1, 2);
641 TColStd_Array1OfInteger VMults (1, 2);
644 UMults (1) = UDegree + 1;
645 UMults (2) = UDegree + 1;
648 VMults (1) = VDegree + 1;
649 VMults (2) = VDegree + 1;
651 if (SBez->IsURational() || SBez->IsVRational()) {
652 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
653 SBez->Weights (Weights);
654 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
659 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
665 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
666 Handle(Geom_BSplineSurface) BS =
667 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
668 Standard_Real umin, umax, vmin, vmax;
669 BS->Bounds(umin, umax, vmin, vmax);
670 if (!BS->IsUPeriodic()) {
677 if (!BS->IsVPeriodic()) {
683 if (BS->IsUPeriodic() || BS->IsVPeriodic())
684 BS->CheckAndSegment (U1, U2, V1, V2);
686 BS->Segment (U1, U2, V1, V2);
691 Standard_Real Tol3d=1.e-4;
692 Standard_Integer MaxDegree =14, MaxSeg;
694 GeomAdaptor_Surface AS(Sr);
695 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
699 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
700 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
701 MaxDegree, MaxDegree, MaxSeg, 1);
702 TheSurface = BSpS.Surface();
704 } // Fin du cas Rectangular::TrimmedSurface
708 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
709 Handle(Geom_SphericalSurface) TheElSurf =
710 Handle(Geom_SphericalSurface)::DownCast(S);
712 gp_Sphere Sph = TheElSurf->Sphere();
713 Convert_SphereToBSplineSurface Convert(Sph);
714 TheSurface = BSplineSurfaceBuilder(Convert);
718 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
719 Handle(Geom_ToroidalSurface) TheElSurf =
720 Handle(Geom_ToroidalSurface)::DownCast(S);
722 gp_Torus Tr = TheElSurf->Torus();
723 Convert_TorusToBSplineSurface Convert(Tr);
724 TheSurface = BSplineSurfaceBuilder(Convert);
728 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
730 Handle(Geom_SurfaceOfRevolution) Revol =
731 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
733 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
734 Handle(Geom_BSplineCurve) C
735 = GeomConvert::CurveToBSplineCurve (Meridian);
737 Standard_Integer NbUPoles, NbUKnots;
738 Standard_Integer NbVPoles, NbVKnots;
739 Standard_Boolean periodic = Standard_True;
741 // Poles of meridian = Vpoles
742 NbVPoles = C->NbPoles();
743 TColgp_Array1OfPnt Poles(1, NbVPoles);
745 TColStd_Array1OfReal Weights( 1, NbVPoles);
747 if ( C->IsRational()) C->Weights(Weights);
754 // Compute Knots and Mults
755 TColStd_Array1OfReal UKnots(1, NbUKnots);
756 TColStd_Array1OfInteger UMults( 1, NbUKnots);
757 Standard_Integer i,j;
758 for ( i = 1; i <= NbUKnots; i++) {
759 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
762 NbVKnots = C->NbKnots();
763 TColStd_Array1OfReal VKnots(1, NbVKnots);
764 TColStd_Array1OfInteger VMults(1, NbVKnots);
766 C->Multiplicities(VMults);
768 // Compute the poles.
769 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
770 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
773 for ( i = 1; i<= NbUPoles; i+=2) {
774 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
775 for ( j = 1; j <= NbVPoles; j++) {
776 NewPoles(i,j) = Poles(j).Transformed(Trsf);
777 NewWeights(i,j) = Weights(j);
781 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
783 for ( j= 1; j<= NbVPoles; j++) {
784 coord = Poles(j).XYZ();
785 Aff.Transforms(coord);
786 Poles(j).SetXYZ(coord);
788 for ( i = 2; i<= NbUPoles; i+=2) {
789 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
790 for ( j = 1; j <= NbVPoles; j++) {
791 NewPoles(i,j) = Poles(j).Transformed(Trsf);
792 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
796 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
800 periodic, C->IsPeriodic());
804 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
806 Handle(Geom_BezierSurface) SBez =
807 Handle(Geom_BezierSurface)::DownCast(S);
809 Standard_Integer NbUPoles = SBez->NbUPoles();
810 Standard_Integer NbVPoles = SBez->NbVPoles();
811 Standard_Integer UDegree = SBez->UDegree();
812 Standard_Integer VDegree = SBez->VDegree();
813 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
814 TColStd_Array1OfReal UKnots(1, 2);
815 TColStd_Array1OfInteger UMults(1, 2);
816 TColStd_Array1OfReal VKnots(1, 2);
817 TColStd_Array1OfInteger VMults(1, 2);
820 UMults (1) = UDegree + 1;
821 UMults (2) = UDegree + 1;
824 VMults (1) = VDegree + 1;
825 VMults (2) = VDegree + 1;
827 if (SBez->IsURational() || SBez->IsVRational()) {
828 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
829 SBez->Weights (Weights);
830 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
835 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
841 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
842 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
845 else { // In other cases => Approx
846 Standard_Real Tol3d=1.e-4;
847 Standard_Integer MaxDegree = 14, MaxSeg;
848 GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
849 GeomAdaptor_Surface AS(Sr);
855 else if(Sr->IsCNu(1))
864 else if(Sr->IsCNv(1))
869 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
870 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
871 MaxDegree, MaxDegree, MaxSeg, 1);
872 TheSurface = BSpS.Surface();
874 } // Fin du cas direct