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
19 #include <BSplCLib.hxx>
20 #include <Convert_ConeToBSplineSurface.hxx>
21 #include <Convert_CylinderToBSplineSurface.hxx>
22 #include <Convert_ElementarySurfaceToBSplineSurface.hxx>
23 #include <Convert_SphereToBSplineSurface.hxx>
24 #include <Convert_TorusToBSplineSurface.hxx>
25 #include <Geom_BezierSurface.hxx>
26 #include <Geom_BSplineCurve.hxx>
27 #include <Geom_BSplineSurface.hxx>
28 #include <Geom_ConicalSurface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_Geometry.hxx>
32 #include <Geom_OffsetSurface.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_RectangularTrimmedSurface.hxx>
35 #include <Geom_SphericalSurface.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_SurfaceOfLinearExtrusion.hxx>
38 #include <Geom_SurfaceOfRevolution.hxx>
39 #include <Geom_ToroidalSurface.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <GeomAdaptor_Surface.hxx>
42 #include <GeomConvert.hxx>
43 #include <GeomConvert_ApproxSurface.hxx>
44 #include <gp_Cone.hxx>
45 #include <gp_Cylinder.hxx>
46 #include <gp_GTrsf.hxx>
48 #include <gp_Sphere.hxx>
49 #include <gp_Torus.hxx>
50 #include <gp_Trsf.hxx>
52 #include <Precision.hxx>
53 #include <Standard_DomainError.hxx>
54 #include <Standard_NotImplemented.hxx>
55 #include <TColgp_Array1OfPnt.hxx>
56 #include <TColgp_Array2OfPnt.hxx>
57 #include <TColStd_Array1OfInteger.hxx>
58 #include <TColStd_Array1OfReal.hxx>
59 #include <TColStd_Array2OfInteger.hxx>
60 #include <TColStd_Array2OfReal.hxx>
61 #include <TColStd_HArray1OfInteger.hxx>
62 #include <TColStd_HArray1OfReal.hxx>
64 typedef Geom_Surface Surface;
65 typedef Geom_BSplineSurface BSplineSurface;
66 typedef TColStd_Array1OfReal Array1OfReal;
67 typedef TColStd_Array2OfReal Array2OfReal;
68 typedef TColStd_Array1OfInteger Array1OfInteger;
69 typedef TColStd_Array2OfInteger Array2OfInteger;
70 typedef TColgp_Array2OfPnt Array2OfPnt;
71 typedef TColgp_Array1OfPnt Array1OfPnt;
74 //=======================================================================
75 //function : BSplineSurfaceBuilder
77 //=======================================================================
79 static Handle(Geom_BSplineSurface) BSplineSurfaceBuilder (const Convert_ElementarySurfaceToBSplineSurface& Convert)
81 Handle(Geom_BSplineSurface) TheSurface;
82 Standard_Integer UDegree = Convert.UDegree ();
83 Standard_Integer VDegree = Convert.VDegree ();
84 Standard_Integer NbUPoles = Convert.NbUPoles();
85 Standard_Integer NbVPoles = Convert.NbVPoles();
86 Standard_Integer NbUKnots = Convert.NbUKnots();
87 Standard_Integer NbVKnots = Convert.NbVKnots();
88 Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
89 Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
90 Array1OfReal UKnots (1, NbUKnots);
91 Array1OfReal VKnots (1, NbVKnots);
92 Array1OfInteger UMults (1, NbUKnots);
93 Array1OfInteger VMults (1, NbVKnots);
94 Standard_Integer i, j;
95 for (j = 1; j <= NbVPoles; j++) {
96 for (i = 1; i <= NbUPoles; i++) {
97 Poles (i, j) = Convert.Pole (i, j);
98 Weights (i, j) = Convert.Weight (i, j);
101 for (i = 1; i <= NbUKnots; i++) {
102 UKnots (i) = Convert.UKnot (i);
103 UMults (i) = Convert.UMultiplicity (i);
105 for (i = 1; i <= NbVKnots; i++) {
106 VKnots (i) = Convert.VKnot (i);
107 VMults (i) = Convert.VMultiplicity (i);
109 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
110 UMults, VMults, UDegree, VDegree,
111 Convert.IsUPeriodic(),
112 Convert.IsVPeriodic());
116 //=======================================================================
117 //function : SplitBSplineSurface
119 //=======================================================================
121 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
122 (const Handle(Geom_BSplineSurface)& S,
123 const Standard_Integer FromUK1,
124 const Standard_Integer ToUK2,
125 const Standard_Integer FromVK1,
126 const Standard_Integer ToVK2,
127 const Standard_Boolean SameUOrientation,
128 const Standard_Boolean SameVOrientation )
130 Standard_Integer FirstU = S->FirstUKnotIndex ();
131 Standard_Integer FirstV = S->FirstVKnotIndex ();
132 Standard_Integer LastU = S->LastUKnotIndex ();
133 Standard_Integer LastV = S->LastVKnotIndex ();
134 if (FromUK1 == ToUK2 || FromVK1 == ToVK2) throw Standard_DomainError();
135 Standard_Integer FirstUK = Min (FromUK1, ToUK2);
136 Standard_Integer LastUK = Max (FromUK1, ToUK2);
137 Standard_Integer FirstVK = Min (FromVK1, ToVK2);
138 Standard_Integer LastVK = Max (FromVK1, ToVK2);
139 if (FirstUK < FirstU || LastUK > LastU ||
140 FirstVK < FirstV || LastVK > LastV) { throw Standard_DomainError(); }
142 Handle(Geom_BSplineSurface) S1= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
144 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
145 S1->VKnot(FirstVK),S1->VKnot(LastVK));
147 if (S->IsUPeriodic()) {
148 if (!SameUOrientation) S1->UReverse();
151 if (FromUK1 > ToUK2) S1->UReverse();
153 if (S->IsVPeriodic()) {
154 if (!SameVOrientation) S1->VReverse();
157 if (FromVK1 > ToVK2) S1->VReverse();
163 //=======================================================================
164 //function : SplitBSplineSurface
166 //=======================================================================
168 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
169 (const Handle(Geom_BSplineSurface)& S,
170 const Standard_Integer FromK1,
171 const Standard_Integer ToK2,
172 const Standard_Boolean USplit,
173 const Standard_Boolean SameOrientation )
175 if (FromK1 == ToK2) throw Standard_DomainError();
178 Handle(Geom_BSplineSurface) S1 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
182 Standard_Integer FirstU = S->FirstUKnotIndex ();
183 Standard_Integer LastU = S->LastUKnotIndex ();
184 Standard_Integer FirstUK = Min (FromK1, ToK2);
185 Standard_Integer LastUK = Max (FromK1, ToK2);
186 if (FirstUK < FirstU || LastUK > LastU) throw Standard_DomainError();
188 S1->Segment( S1->UKnot(FirstUK),
190 S1->VKnot(S1->FirstVKnotIndex()),
191 S1->VKnot(S1->LastVKnotIndex()));
193 if (S->IsUPeriodic()) {
194 if (!SameOrientation) S1->UReverse();
197 if (FromK1 > ToK2) S1->UReverse();
203 Standard_Integer FirstV = S->FirstVKnotIndex ();
204 Standard_Integer LastV = S->LastVKnotIndex ();
205 Standard_Integer FirstVK = Min (FromK1, ToK2);
206 Standard_Integer LastVK = Max (FromK1, ToK2);
207 if (FirstVK < FirstV || LastVK > LastV) throw Standard_DomainError();
209 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
210 S1->UKnot(S1->LastUKnotIndex()),
215 if (S->IsVPeriodic()) {
216 if (!SameOrientation) S1->VReverse();
219 if (FromK1 > ToK2) S1->VReverse();
226 //=======================================================================
227 //function : SplitBSplineSurface
229 //=======================================================================
231 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
232 (const Handle(Geom_BSplineSurface)& S,
233 const Standard_Real FromU1,
234 const Standard_Real ToU2,
235 const Standard_Real FromV1,
236 const Standard_Real ToV2,
237 // const Standard_Real ParametricTolerance,
238 const Standard_Real ,
239 const Standard_Boolean SameUOrientation,
240 const Standard_Boolean SameVOrientation )
242 Standard_Real FirstU = Min( FromU1, ToU2);
243 Standard_Real LastU = Max( FromU1, ToU2);
244 Standard_Real FirstV = Min( FromV1, ToV2);
245 Standard_Real LastV = Max( FromV1, ToV2);
247 Handle (Geom_BSplineSurface) NewSurface
248 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
250 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
252 if (S->IsUPeriodic()) {
253 if (!SameUOrientation) NewSurface->UReverse();
256 if (FromU1 > ToU2) NewSurface->UReverse();
258 if (S->IsVPeriodic()) {
259 if (!SameVOrientation) NewSurface->VReverse();
262 if (FromV1 > ToV2) NewSurface->VReverse();
268 //=======================================================================
269 //function : SplitBSplineSurface
271 //=======================================================================
273 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
274 (const Handle(Geom_BSplineSurface)& S,
275 const Standard_Real FromParam1,
276 const Standard_Real ToParam2,
277 const Standard_Boolean USplit,
278 const Standard_Real ParametricTolerance,
279 const Standard_Boolean SameOrientation )
281 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
282 throw Standard_DomainError();
284 Handle(Geom_BSplineSurface) NewSurface
285 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
288 Standard_Real FirstU = Min( FromParam1, ToParam2);
289 Standard_Real LastU = Max( FromParam1, ToParam2);
290 Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
291 Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
293 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
295 if (S->IsUPeriodic()) {
296 if (!SameOrientation) NewSurface->UReverse();
299 if (FromParam1 > ToParam2) NewSurface->UReverse();
304 Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
305 Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
306 Standard_Real FirstV = Min( FromParam1, ToParam2);
307 Standard_Real LastV = Max( FromParam1, ToParam2);
309 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
311 if (S->IsUPeriodic()) {
312 if (!SameOrientation) NewSurface->UReverse();
315 if (FromParam1 > ToParam2) NewSurface->UReverse();
323 //=======================================================================
324 //function : SurfaceToBSplineSurface
326 //=======================================================================
328 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
329 (const Handle(Geom_Surface)& Sr)
332 Standard_Real U1, U2, V1, V2;
333 Sr->Bounds (U1, U2, V1, V2);
334 Standard_Real UFirst = Min (U1, U2);
335 Standard_Real ULast = Max (U1, U2);
336 Standard_Real VFirst = Min (V1, V2);
337 Standard_Real VLast = Max (V1, V2);
339 //If the surface Sr is infinite stop the computation
340 if (Precision::IsNegativeInfinite(UFirst) ||
341 Precision::IsPositiveInfinite(ULast) ||
342 Precision::IsNegativeInfinite(VFirst) ||
343 Precision::IsPositiveInfinite(VLast) ) {
344 throw Standard_DomainError ("GeomConvert::SurfaceToBSplineSurface() - infinite surface");
347 Handle(Geom_BSplineSurface) TheSurface;
348 Handle(Geom_Surface) S;
349 Handle(Geom_OffsetSurface) OffsetSur;
350 if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
351 OffsetSur = Handle(Geom_OffsetSurface)::DownCast (Sr);
352 S = OffsetSur->Surface();
353 if (!S.IsNull()) { // Convert the equivalent surface.
354 return SurfaceToBSplineSurface(S);
359 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
360 Handle(Geom_RectangularTrimmedSurface) Strim =
361 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
363 Handle(Geom_Surface) Surf = Strim->BasisSurface();
364 UFirst = U1; ULast = U2; VFirst = V1; VLast = V2;
365 if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
366 Handle(Geom_OffsetSurface) OffsetSurBasis =
367 Handle(Geom_OffsetSurface)::DownCast(Surf);
369 S = OffsetSurBasis->Surface();
376 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
377 Handle(Geom_RectangularTrimmedSurface) aStrim = new
378 (Geom_RectangularTrimmedSurface) (Surf,
381 return SurfaceToBSplineSurface(aStrim);
384 //For cylinders, cones, spheres, toruses
385 const Standard_Boolean isUClosed = Abs((ULast - UFirst) - 2. * M_PI) <= Precision::PConfusion();
387 if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
388 TColgp_Array2OfPnt Poles (1, 2, 1, 2);
389 Poles (1, 1) = Strim->Value (U1, V1);
390 Poles (1, 2) = Strim->Value (U1, V2);
391 Poles (2, 1) = Strim->Value (U2, V1);
392 Poles (2, 2) = Strim->Value (U2, V2);
393 TColStd_Array1OfReal UKnots (1, 2);
394 TColStd_Array1OfReal VKnots (1, 2);
395 TColStd_Array1OfInteger UMults (1, 2);
396 TColStd_Array1OfInteger VMults (1, 2);
405 Standard_Integer UDegree = 1;
406 Standard_Integer VDegree = 1;
407 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
408 VMults, UDegree, VDegree);
410 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
411 Handle(Geom_CylindricalSurface) TheElSurf=
412 Handle(Geom_CylindricalSurface)::DownCast(Surf);
414 gp_Cylinder Cyl = TheElSurf->Cylinder();
416 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
417 TheSurface = BSplineSurfaceBuilder (Convert);
420 Convert_CylinderToBSplineSurface
421 Conv (Cyl, UFirst, ULast, VFirst, VLast);
422 TheSurface = BSplineSurfaceBuilder (Conv);
427 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
428 Handle(Geom_ConicalSurface) TheElSurf =
429 Handle(Geom_ConicalSurface)::DownCast(Surf);
430 gp_Cone Co = TheElSurf->Cone();
432 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
433 TheSurface = BSplineSurfaceBuilder (Convert);
436 Convert_ConeToBSplineSurface
437 Convert (Co, UFirst, ULast, VFirst, VLast);
438 TheSurface = BSplineSurfaceBuilder (Convert);
443 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
444 Handle(Geom_SphericalSurface) TheElSurf =
445 Handle(Geom_SphericalSurface)::DownCast(Surf);
446 gp_Sphere Sph = TheElSurf->Sphere();
449 //if (Strim->IsVClosed()) {
450 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
451 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
452 TheSurface = BSplineSurfaceBuilder (Convert);
455 Convert_SphereToBSplineSurface
456 Convert (Sph, UFirst, ULast, VFirst, VLast);
457 TheSurface = BSplineSurfaceBuilder (Convert);
462 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
463 Handle(Geom_ToroidalSurface) TheElSurf =
464 Handle(Geom_ToroidalSurface)::DownCast(Surf);
466 gp_Torus Tr = TheElSurf->Torus();
468 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
470 TheSurface = BSplineSurfaceBuilder (Convert);
472 else if (Strim->IsVClosed()) {
473 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
474 TheSurface = BSplineSurfaceBuilder (Convert);
477 Convert_TorusToBSplineSurface
478 Convert (Tr, UFirst, ULast, VFirst, VLast);
479 TheSurface = BSplineSurfaceBuilder (Convert);
484 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
485 Handle(Geom_SurfaceOfRevolution) Revol =
486 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
488 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
489 Handle(Geom_BSplineCurve) C;
490 if (Strim->IsVClosed()) {
491 C = GeomConvert::CurveToBSplineCurve (Meridian);
494 Handle(Geom_TrimmedCurve) CT =
495 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
496 C = GeomConvert::CurveToBSplineCurve (CT);
498 Standard_Integer NbUPoles, NbUKnots;
499 Standard_Integer NbVPoles, NbVKnots;
500 Standard_Boolean periodic = Standard_False;
502 // Poles of meridian = Vpoles
503 NbVPoles = C->NbPoles();
504 TColgp_Array1OfPnt Poles(1, NbVPoles);
506 TColStd_Array1OfReal Weights( 1, NbVPoles);
508 if ( C->IsRational()) C->Weights(Weights);
510 Standard_Integer nbUSpans;
512 if (Strim->IsUPeriodic()) {
517 periodic = Standard_True;
520 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
522 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
523 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
524 NbUPoles = 2 * nbUSpans + 1;
525 NbUKnots = nbUSpans + 1;
527 // Compute Knots and Mults
528 TColStd_Array1OfReal UKnots(1, NbUKnots);
529 TColStd_Array1OfInteger UMults( 1, NbUKnots);
530 Standard_Integer i,j;
531 for ( i = 1; i <= NbUKnots; i++) {
532 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
536 UMults(1)++; UMults(NbUKnots)++;
538 NbVKnots = C->NbKnots();
539 TColStd_Array1OfReal VKnots(1, NbVKnots);
540 TColStd_Array1OfInteger VMults(1, NbVKnots);
542 C->Multiplicities(VMults);
544 // Compute the poles.
545 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
546 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
549 for ( i = 1; i<= NbUPoles; i+=2) {
550 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
551 for ( j = 1; j <= NbVPoles; j++) {
552 NewPoles(i,j) = Poles(j).Transformed(Trsf);
553 NewWeights(i,j) = Weights(j);
557 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
559 for ( j= 1; j<= NbVPoles; j++) {
560 coord = Poles(j).XYZ();
561 Aff.Transforms(coord);
562 Poles(j).SetXYZ(coord);
564 for ( i = 2; i<= NbUPoles; i+=2) {
565 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
566 for ( j = 1; j <= NbVPoles; j++) {
567 NewPoles(i,j) = Poles(j).Transformed(Trsf);
568 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
572 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
576 periodic, C->IsPeriodic());
582 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
583 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
584 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
586 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
587 Handle(Geom_BSplineCurve) C;
588 if (Strim->IsUClosed()) {
589 C = GeomConvert::CurveToBSplineCurve (Meridian);
592 Handle(Geom_TrimmedCurve) CT =
593 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
594 C = GeomConvert::CurveToBSplineCurve (CT);
596 TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
597 TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
598 TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
600 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
601 C->Multiplicities(UMults);
602 TColStd_Array1OfReal VKnots ( 1, 2);
605 TColStd_Array1OfInteger VMults ( 1, 2);
608 gp_Vec D( Extru->Direction());
609 gp_Vec DV1 = VFirst * D;
610 gp_Vec DV2 = VLast * D;
611 for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
612 Poles(i,1) = C->Pole(i).Translated(DV1);
613 Poles(i,2) = C->Pole(i).Translated(DV2);
614 Weights(i,1) = Weights(i,2) = C->Weight(i);
616 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
619 C->IsPeriodic(), Standard_False);
623 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
625 Handle(Geom_BezierSurface) SBez =
626 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
628 SBez->Segment (U1, U2, V1, V2);
629 Standard_Integer NbUPoles = SBez->NbUPoles();
630 Standard_Integer NbVPoles = SBez->NbVPoles();
631 Standard_Integer UDegree = SBez->UDegree();
632 Standard_Integer VDegree = SBez->VDegree();
633 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
634 TColStd_Array1OfReal UKnots (1, 2);
635 TColStd_Array1OfInteger UMults (1, 2);
636 TColStd_Array1OfReal VKnots (1, 2);
637 TColStd_Array1OfInteger VMults (1, 2);
640 UMults (1) = UDegree + 1;
641 UMults (2) = UDegree + 1;
644 VMults (1) = VDegree + 1;
645 VMults (2) = VDegree + 1;
647 if (SBez->IsURational() || SBez->IsVRational()) {
648 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
649 SBez->Weights (Weights);
650 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
655 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
661 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
662 Handle(Geom_BSplineSurface) BS =
663 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
664 Standard_Real umin, umax, vmin, vmax;
665 BS->Bounds(umin, umax, vmin, vmax);
666 if (!BS->IsUPeriodic()) {
673 if (!BS->IsVPeriodic()) {
679 if (BS->IsUPeriodic() || BS->IsVPeriodic())
680 BS->CheckAndSegment (U1, U2, V1, V2);
682 BS->Segment (U1, U2, V1, V2);
687 Standard_Real Tol3d=1.e-4;
688 Standard_Integer MaxDegree =14, MaxSeg;
690 GeomAdaptor_Surface AS(Sr);
691 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
695 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
696 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
697 MaxDegree, MaxDegree, MaxSeg, 1);
698 TheSurface = BSpS.Surface();
700 } // Fin du cas Rectangular::TrimmedSurface
704 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
705 Handle(Geom_SphericalSurface) TheElSurf =
706 Handle(Geom_SphericalSurface)::DownCast(S);
708 gp_Sphere Sph = TheElSurf->Sphere();
709 Convert_SphereToBSplineSurface Convert(Sph);
710 TheSurface = BSplineSurfaceBuilder(Convert);
714 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
715 Handle(Geom_ToroidalSurface) TheElSurf =
716 Handle(Geom_ToroidalSurface)::DownCast(S);
718 gp_Torus Tr = TheElSurf->Torus();
719 Convert_TorusToBSplineSurface Convert(Tr);
720 TheSurface = BSplineSurfaceBuilder(Convert);
724 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
726 Handle(Geom_SurfaceOfRevolution) Revol =
727 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
729 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
730 Handle(Geom_BSplineCurve) C
731 = GeomConvert::CurveToBSplineCurve (Meridian);
733 Standard_Integer NbUPoles, NbUKnots;
734 Standard_Integer NbVPoles, NbVKnots;
735 Standard_Boolean periodic = Standard_True;
737 // Poles of meridian = Vpoles
738 NbVPoles = C->NbPoles();
739 TColgp_Array1OfPnt Poles(1, NbVPoles);
741 TColStd_Array1OfReal Weights( 1, NbVPoles);
743 if ( C->IsRational()) C->Weights(Weights);
750 // Compute Knots and Mults
751 TColStd_Array1OfReal UKnots(1, NbUKnots);
752 TColStd_Array1OfInteger UMults( 1, NbUKnots);
753 Standard_Integer i,j;
754 for ( i = 1; i <= NbUKnots; i++) {
755 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
758 NbVKnots = C->NbKnots();
759 TColStd_Array1OfReal VKnots(1, NbVKnots);
760 TColStd_Array1OfInteger VMults(1, NbVKnots);
762 C->Multiplicities(VMults);
764 // Compute the poles.
765 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
766 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
769 for ( i = 1; i<= NbUPoles; i+=2) {
770 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
771 for ( j = 1; j <= NbVPoles; j++) {
772 NewPoles(i,j) = Poles(j).Transformed(Trsf);
773 NewWeights(i,j) = Weights(j);
777 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
779 for ( j= 1; j<= NbVPoles; j++) {
780 coord = Poles(j).XYZ();
781 Aff.Transforms(coord);
782 Poles(j).SetXYZ(coord);
784 for ( i = 2; i<= NbUPoles; i+=2) {
785 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
786 for ( j = 1; j <= NbVPoles; j++) {
787 NewPoles(i,j) = Poles(j).Transformed(Trsf);
788 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
792 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
796 periodic, C->IsPeriodic());
800 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
802 Handle(Geom_BezierSurface) SBez =
803 Handle(Geom_BezierSurface)::DownCast(S);
805 Standard_Integer NbUPoles = SBez->NbUPoles();
806 Standard_Integer NbVPoles = SBez->NbVPoles();
807 Standard_Integer UDegree = SBez->UDegree();
808 Standard_Integer VDegree = SBez->VDegree();
809 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
810 TColStd_Array1OfReal UKnots(1, 2);
811 TColStd_Array1OfInteger UMults(1, 2);
812 TColStd_Array1OfReal VKnots(1, 2);
813 TColStd_Array1OfInteger VMults(1, 2);
816 UMults (1) = UDegree + 1;
817 UMults (2) = UDegree + 1;
820 VMults (1) = VDegree + 1;
821 VMults (2) = VDegree + 1;
823 if (SBez->IsURational() || SBez->IsVRational()) {
824 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
825 SBez->Weights (Weights);
826 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
831 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
837 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
838 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
841 else { // In other cases => Approx
842 Standard_Real Tol3d=1.e-4;
843 Standard_Integer MaxDegree = 14, MaxSeg;
844 GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
845 GeomAdaptor_Surface AS(Sr);
851 else if(Sr->IsCNu(1))
860 else if(Sr->IsCNv(1))
865 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
866 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
867 MaxDegree, MaxDegree, MaxSeg, 1);
868 TheSurface = BSpS.Surface();
870 } // Fin du cas direct