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>
73 typedef Geom_Surface Surface;
74 typedef Geom_BSplineSurface BSplineSurface;
75 typedef Handle(Geom_Curve) Handle(Curve);
76 typedef Handle(Geom_BSplineCurve) Handle(BSplineCurve);
77 typedef Handle(Geom_BezierSurface) Handle(BezierSurface);
78 typedef Handle(Geom_Geometry) Handle(Geometry);
79 typedef Handle(Geom_Surface) Handle(Surface);
80 typedef Handle(Geom_Plane) Handle(Plane);
81 typedef Handle(Geom_CylindricalSurface) Handle(CylindricalSurface);
82 typedef Handle(Geom_ConicalSurface) Handle(ConicalSurface);
83 typedef Handle(Geom_SphericalSurface) Handle(SphericalSurface);
84 typedef Handle(Geom_ToroidalSurface) Handle(ToroidalSurface);
85 typedef Handle(Geom_BSplineSurface) Handle(BSplineSurface);
86 typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
87 typedef Handle(Geom_SurfaceOfLinearExtrusion) Handle(SurfaceOfLinearExtrusion);
88 typedef Handle(Geom_RectangularTrimmedSurface)
89 Handle(RectangularTrimmedSurface);
92 typedef TColStd_Array1OfReal Array1OfReal;
93 typedef TColStd_Array2OfReal Array2OfReal;
94 typedef TColStd_Array1OfInteger Array1OfInteger;
95 typedef TColStd_Array2OfInteger Array2OfInteger;
96 typedef TColgp_Array2OfPnt Array2OfPnt;
97 typedef TColgp_Array1OfPnt Array1OfPnt;
103 //=======================================================================
104 //function : BSplineSurfaceBuilder
106 //=======================================================================
108 Handle(BSplineSurface) BSplineSurfaceBuilder
109 (const Convert_ElementarySurfaceToBSplineSurface& Convert)
111 Handle(BSplineSurface) TheSurface;
112 Standard_Integer UDegree = Convert.UDegree ();
113 Standard_Integer VDegree = Convert.VDegree ();
114 Standard_Integer NbUPoles = Convert.NbUPoles();
115 Standard_Integer NbVPoles = Convert.NbVPoles();
116 Standard_Integer NbUKnots = Convert.NbUKnots();
117 Standard_Integer NbVKnots = Convert.NbVKnots();
118 Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
119 Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
120 Array1OfReal UKnots (1, NbUKnots);
121 Array1OfReal VKnots (1, NbVKnots);
122 Array1OfInteger UMults (1, NbUKnots);
123 Array1OfInteger VMults (1, NbVKnots);
124 Standard_Integer i, j;
125 for (j = 1; j <= NbVPoles; j++) {
126 for (i = 1; i <= NbUPoles; i++) {
127 Poles (i, j) = Convert.Pole (i, j);
128 Weights (i, j) = Convert.Weight (i, j);
131 for (i = 1; i <= NbUKnots; i++) {
132 UKnots (i) = Convert.UKnot (i);
133 UMults (i) = Convert.UMultiplicity (i);
135 for (i = 1; i <= NbVKnots; i++) {
136 VKnots (i) = Convert.VKnot (i);
137 VMults (i) = Convert.VMultiplicity (i);
139 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
140 UMults, VMults, UDegree, VDegree,
141 Convert.IsUPeriodic(),
142 Convert.IsVPeriodic());
146 //=======================================================================
147 //function : SplitBSplineSurface
149 //=======================================================================
151 Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
152 (const Handle(BSplineSurface)& S,
153 const Standard_Integer FromUK1,
154 const Standard_Integer ToUK2,
155 const Standard_Integer FromVK1,
156 const Standard_Integer ToVK2,
157 const Standard_Boolean SameUOrientation,
158 const Standard_Boolean SameVOrientation )
160 Standard_Integer FirstU = S->FirstUKnotIndex ();
161 Standard_Integer FirstV = S->FirstVKnotIndex ();
162 Standard_Integer LastU = S->LastUKnotIndex ();
163 Standard_Integer LastV = S->LastVKnotIndex ();
164 if (FromUK1 == ToUK2 || FromVK1 == ToVK2) Standard_DomainError::Raise();
165 Standard_Integer FirstUK = Min (FromUK1, ToUK2);
166 Standard_Integer LastUK = Max (FromUK1, ToUK2);
167 Standard_Integer FirstVK = Min (FromVK1, ToVK2);
168 Standard_Integer LastVK = Max (FromVK1, ToVK2);
169 if (FirstUK < FirstU || LastUK > LastU ||
170 FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
172 Handle(BSplineSurface) S1= Handle(BSplineSurface)::DownCast(S->Copy());
174 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
175 S1->VKnot(FirstVK),S1->VKnot(LastVK));
177 if (S->IsUPeriodic()) {
178 if (!SameUOrientation) S1->UReverse();
181 if (FromUK1 > ToUK2) S1->UReverse();
183 if (S->IsVPeriodic()) {
184 if (!SameVOrientation) S1->VReverse();
187 if (FromVK1 > ToVK2) S1->VReverse();
193 //=======================================================================
194 //function : SplitBSplineSurface
196 //=======================================================================
198 Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
199 (const Handle(BSplineSurface)& S,
200 const Standard_Integer FromK1,
201 const Standard_Integer ToK2,
202 const Standard_Boolean USplit,
203 const Standard_Boolean SameOrientation )
205 if (FromK1 == ToK2) Standard_DomainError::Raise();
208 Handle(BSplineSurface) S1 = Handle(BSplineSurface)::DownCast(S->Copy());
212 Standard_Integer FirstU = S->FirstUKnotIndex ();
213 Standard_Integer LastU = S->LastUKnotIndex ();
214 Standard_Integer FirstUK = Min (FromK1, ToK2);
215 Standard_Integer LastUK = Max (FromK1, ToK2);
216 if (FirstUK < FirstU || LastUK > LastU) Standard_DomainError::Raise();
218 S1->Segment( S1->UKnot(FirstUK),
220 S1->VKnot(S1->FirstVKnotIndex()),
221 S1->VKnot(S1->LastVKnotIndex()));
223 if (S->IsUPeriodic()) {
224 if (!SameOrientation) S1->UReverse();
227 if (FromK1 > ToK2) S1->UReverse();
233 Standard_Integer FirstV = S->FirstVKnotIndex ();
234 Standard_Integer LastV = S->LastVKnotIndex ();
235 Standard_Integer FirstVK = Min (FromK1, ToK2);
236 Standard_Integer LastVK = Max (FromK1, ToK2);
237 if (FirstVK < FirstV || LastVK > LastV) Standard_DomainError::Raise();
239 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
240 S1->UKnot(S1->LastUKnotIndex()),
245 if (S->IsVPeriodic()) {
246 if (!SameOrientation) S1->VReverse();
249 if (FromK1 > ToK2) S1->VReverse();
256 //=======================================================================
257 //function : SplitBSplineSurface
259 //=======================================================================
261 Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
262 (const Handle(BSplineSurface)& S,
263 const Standard_Real FromU1,
264 const Standard_Real ToU2,
265 const Standard_Real FromV1,
266 const Standard_Real ToV2,
267 // const Standard_Real ParametricTolerance,
268 const Standard_Real ,
269 const Standard_Boolean SameUOrientation,
270 const Standard_Boolean SameVOrientation )
272 Standard_Real FirstU = Min( FromU1, ToU2);
273 Standard_Real LastU = Max( FromU1, ToU2);
274 Standard_Real FirstV = Min( FromV1, ToV2);
275 Standard_Real LastV = Max( FromV1, ToV2);
277 Handle (Geom_BSplineSurface) NewSurface
278 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
280 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
282 if (S->IsUPeriodic()) {
283 if (!SameUOrientation) NewSurface->UReverse();
286 if (FromU1 > ToU2) NewSurface->UReverse();
288 if (S->IsVPeriodic()) {
289 if (!SameVOrientation) NewSurface->VReverse();
292 if (FromV1 > ToV2) NewSurface->VReverse();
298 //=======================================================================
299 //function : SplitBSplineSurface
301 //=======================================================================
303 Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
304 (const Handle(BSplineSurface)& S,
305 const Standard_Real FromParam1,
306 const Standard_Real ToParam2,
307 const Standard_Boolean USplit,
308 const Standard_Real ParametricTolerance,
309 const Standard_Boolean SameOrientation )
311 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
312 Standard_DomainError::Raise();
314 Handle(BSplineSurface) NewSurface
315 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
318 Standard_Real FirstU = Min( FromParam1, ToParam2);
319 Standard_Real LastU = Max( FromParam1, ToParam2);
320 Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
321 Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
323 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
325 if (S->IsUPeriodic()) {
326 if (!SameOrientation) NewSurface->UReverse();
329 if (FromParam1 > ToParam2) NewSurface->UReverse();
334 Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
335 Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
336 Standard_Real FirstV = Min( FromParam1, ToParam2);
337 Standard_Real LastV = Max( FromParam1, ToParam2);
339 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
341 if (S->IsUPeriodic()) {
342 if (!SameOrientation) NewSurface->UReverse();
345 if (FromParam1 > ToParam2) NewSurface->UReverse();
353 //=======================================================================
354 //function : SurfaceToBSplineSurface
356 //=======================================================================
358 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
359 (const Handle(Surface)& Sr)
361 Standard_Real U1, U2, V1, V2;
362 Sr->Bounds (U1, U2, V1, V2);
363 Standard_Real UFirst = Min (U1, U2);
364 Standard_Real ULast = Max (U1, U2);
365 Standard_Real VFirst = Min (V1, V2);
366 Standard_Real VLast = Max (V1, V2);
368 //If the surface Sr is infinite stop the computation
369 if (Precision::IsNegativeInfinite(UFirst) ||
370 Precision::IsPositiveInfinite(ULast) ||
371 Precision::IsNegativeInfinite(VFirst) ||
372 Precision::IsPositiveInfinite(VLast) ) {
373 Standard_DomainError::Raise("");
376 Handle(Geom_BSplineSurface) TheSurface;
378 Handle(Geom_OffsetSurface) OffsetSur;
379 if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
380 OffsetSur = *((Handle(Geom_OffsetSurface)*)& Sr);
381 S = OffsetSur->Surface();
382 if (!S.IsNull()) { // Convert the equivalent surface.
383 return SurfaceToBSplineSurface(S);
388 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
389 Handle(Geom_RectangularTrimmedSurface) Strim =
390 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
392 Handle(Geom_Surface) Surf = Strim->BasisSurface();
393 UFirst = U1; ULast = U2; VFirst = V1; VLast = V2;
394 if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
395 Handle(Geom_OffsetSurface) OffsetSur =
396 Handle(Geom_OffsetSurface)::DownCast(Surf);
398 S = OffsetSur->Surface();
405 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
406 Handle(Geom_RectangularTrimmedSurface) Strim = new
407 (Geom_RectangularTrimmedSurface) (Surf,
410 return SurfaceToBSplineSurface(Strim);
413 if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
414 TColgp_Array2OfPnt Poles (1, 2, 1, 2);
415 Poles (1, 1) = Strim->Value (U1, V1);
416 Poles (1, 2) = Strim->Value (U1, V2);
417 Poles (2, 1) = Strim->Value (U2, V1);
418 Poles (2, 2) = Strim->Value (U2, V2);
419 TColStd_Array1OfReal UKnots (1, 2);
420 TColStd_Array1OfReal VKnots (1, 2);
421 TColStd_Array1OfInteger UMults (1, 2);
422 TColStd_Array1OfInteger VMults (1, 2);
431 Standard_Integer UDegree = 1;
432 Standard_Integer VDegree = 1;
433 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
434 VMults, UDegree, VDegree);
436 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
437 Handle(Geom_CylindricalSurface) TheElSurf=
438 Handle(Geom_CylindricalSurface)::DownCast(Surf);
440 gp_Cylinder Cyl = TheElSurf->Cylinder();
441 if (Strim->IsUClosed()) {
442 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
443 TheSurface = BSplineSurfaceBuilder (Convert);
446 Convert_CylinderToBSplineSurface
447 Conv (Cyl, UFirst, ULast, VFirst, VLast);
448 TheSurface = BSplineSurfaceBuilder (Conv);
453 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
454 Handle(Geom_ConicalSurface) TheElSurf =
455 Handle(Geom_ConicalSurface)::DownCast(Surf);
456 gp_Cone Co = TheElSurf->Cone();
457 if (Strim->IsUClosed()) {
458 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
459 TheSurface = BSplineSurfaceBuilder (Convert);
462 Convert_ConeToBSplineSurface
463 Convert (Co, UFirst, ULast, VFirst, VLast);
464 TheSurface = BSplineSurfaceBuilder (Convert);
469 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
470 Handle(Geom_SphericalSurface) TheElSurf =
471 Handle(Geom_SphericalSurface)::DownCast(Surf);
472 gp_Sphere Sph = TheElSurf->Sphere();
474 if (Strim->IsUClosed()) {
475 //if (Strim->IsVClosed()) {
476 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
477 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
478 TheSurface = BSplineSurfaceBuilder (Convert);
481 Convert_SphereToBSplineSurface
482 Convert (Sph, UFirst, ULast, VFirst, VLast);
483 TheSurface = BSplineSurfaceBuilder (Convert);
488 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
489 Handle(Geom_ToroidalSurface) TheElSurf =
490 Handle(Geom_ToroidalSurface)::DownCast(Surf);
492 gp_Torus Tr = TheElSurf->Torus();
493 if (Strim->IsUClosed()) {
494 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
496 TheSurface = BSplineSurfaceBuilder (Convert);
498 else if (Strim->IsVClosed()) {
499 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
500 TheSurface = BSplineSurfaceBuilder (Convert);
503 Convert_TorusToBSplineSurface
504 Convert (Tr, UFirst, ULast, VFirst, VLast);
505 TheSurface = BSplineSurfaceBuilder (Convert);
510 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
511 Handle(Geom_SurfaceOfRevolution) Revol =
512 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
514 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
515 Handle(Geom_BSplineCurve) C;
516 if (Strim->IsVClosed()) {
517 C = GeomConvert::CurveToBSplineCurve (Meridian);
520 Handle(Geom_TrimmedCurve) CT =
521 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
522 C = GeomConvert::CurveToBSplineCurve (CT);
524 Standard_Integer NbUPoles, NbUKnots;
525 Standard_Integer NbVPoles, NbVKnots;
526 Standard_Boolean periodic = Standard_False;
528 // Poles of meridian = Vpoles
529 NbVPoles = C->NbPoles();
530 TColgp_Array1OfPnt Poles(1, NbVPoles);
532 TColStd_Array1OfReal Weights( 1, NbVPoles);
534 if ( C->IsRational()) C->Weights(Weights);
536 Standard_Integer nbUSpans;
538 if (Strim->IsUPeriodic()) {
543 periodic = Standard_True;
546 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
548 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
549 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
550 NbUPoles = 2 * nbUSpans + 1;
551 NbUKnots = nbUSpans + 1;
553 // Compute Knots and Mults
554 TColStd_Array1OfReal UKnots(1, NbUKnots);
555 TColStd_Array1OfInteger UMults( 1, NbUKnots);
556 Standard_Integer i,j;
557 for ( i = 1; i <= NbUKnots; i++) {
558 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
562 UMults(1)++; UMults(NbUKnots)++;
564 NbVKnots = C->NbKnots();
565 TColStd_Array1OfReal VKnots(1, NbVKnots);
566 TColStd_Array1OfInteger VMults(1, NbVKnots);
568 C->Multiplicities(VMults);
570 // Compute the poles.
571 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
572 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
575 for ( i = 1; i<= NbUPoles; i+=2) {
576 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
577 for ( j = 1; j <= NbVPoles; j++) {
578 NewPoles(i,j) = Poles(j).Transformed(Trsf);
579 NewWeights(i,j) = Weights(j);
583 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
585 for ( j= 1; j<= NbVPoles; j++) {
586 coord = Poles(j).XYZ();
587 Aff.Transforms(coord);
588 Poles(j).SetXYZ(coord);
590 for ( i = 2; i<= NbUPoles; i+=2) {
591 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
592 for ( j = 1; j <= NbVPoles; j++) {
593 NewPoles(i,j) = Poles(j).Transformed(Trsf);
594 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
598 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
602 periodic, C->IsPeriodic());
608 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
609 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
610 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
612 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
613 Handle(Geom_BSplineCurve) C;
614 if (Strim->IsUClosed()) {
615 C = GeomConvert::CurveToBSplineCurve (Meridian);
618 Handle(Geom_TrimmedCurve) CT =
619 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
620 C = GeomConvert::CurveToBSplineCurve (CT);
622 TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
623 TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
624 TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
626 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
627 C->Multiplicities(UMults);
628 TColStd_Array1OfReal VKnots ( 1, 2);
631 TColStd_Array1OfInteger VMults ( 1, 2);
634 gp_Vec D( Extru->Direction());
635 gp_Vec DV1 = VFirst * D;
636 gp_Vec DV2 = VLast * D;
637 for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
638 Poles(i,1) = C->Pole(i).Translated(DV1);
639 Poles(i,2) = C->Pole(i).Translated(DV2);
640 Weights(i,1) = Weights(i,2) = C->Weight(i);
642 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
645 C->IsPeriodic(), Standard_False);
649 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
651 Handle(Geom_BezierSurface) SBez =
652 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
654 SBez->Segment (U1, U2, V1, V2);
655 Standard_Integer NbUPoles = SBez->NbUPoles();
656 Standard_Integer NbVPoles = SBez->NbVPoles();
657 Standard_Integer UDegree = SBez->UDegree();
658 Standard_Integer VDegree = SBez->VDegree();
659 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
660 TColStd_Array1OfReal UKnots (1, 2);
661 TColStd_Array1OfInteger UMults (1, 2);
662 TColStd_Array1OfReal VKnots (1, 2);
663 TColStd_Array1OfInteger VMults (1, 2);
666 UMults (1) = UDegree + 1;
667 UMults (2) = UDegree + 1;
670 VMults (1) = VDegree + 1;
671 VMults (2) = VDegree + 1;
673 if (SBez->IsURational() || SBez->IsVRational()) {
674 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
675 SBez->Weights (Weights);
676 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
681 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
687 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
688 Handle(Geom_BSplineSurface) BS =
689 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
690 Standard_Real umin, umax, vmin, vmax;
691 BS->Bounds(umin, umax, vmin, vmax);
692 if (!BS->IsUPeriodic()) {
699 if (!BS->IsVPeriodic()) {
705 BS->Segment (U1, U2, V1, V2);
710 Standard_Real Tol3d=1.e-4;
711 Standard_Integer MaxDegree =14, MaxSeg;
713 GeomAdaptor_Surface AS(Sr);
714 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
718 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
719 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
720 MaxDegree, MaxDegree, MaxSeg, 1);
721 TheSurface = BSpS.Surface();
723 } // Fin du cas Rectangular::TrimmedSurface
727 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
728 Handle(Geom_SphericalSurface) TheElSurf =
729 Handle(Geom_SphericalSurface)::DownCast(S);
731 gp_Sphere Sph = TheElSurf->Sphere();
732 Convert_SphereToBSplineSurface Convert(Sph);
733 TheSurface = BSplineSurfaceBuilder(Convert);
737 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
738 Handle(Geom_ToroidalSurface) TheElSurf =
739 Handle(Geom_ToroidalSurface)::DownCast(S);
741 gp_Torus Tr = TheElSurf->Torus();
742 Convert_TorusToBSplineSurface Convert(Tr);
743 TheSurface = BSplineSurfaceBuilder(Convert);
747 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
749 Handle(Geom_SurfaceOfRevolution) Revol =
750 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
752 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
753 Handle(Geom_BSplineCurve) C
754 = GeomConvert::CurveToBSplineCurve (Meridian);
756 Standard_Integer NbUPoles, NbUKnots;
757 Standard_Integer NbVPoles, NbVKnots;
758 Standard_Boolean periodic = Standard_True;
760 // Poles of meridian = Vpoles
761 NbVPoles = C->NbPoles();
762 TColgp_Array1OfPnt Poles(1, NbVPoles);
764 TColStd_Array1OfReal Weights( 1, NbVPoles);
766 if ( C->IsRational()) C->Weights(Weights);
773 // Compute Knots and Mults
774 TColStd_Array1OfReal UKnots(1, NbUKnots);
775 TColStd_Array1OfInteger UMults( 1, NbUKnots);
776 Standard_Integer i,j;
777 for ( i = 1; i <= NbUKnots; i++) {
778 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
781 NbVKnots = C->NbKnots();
782 TColStd_Array1OfReal VKnots(1, NbVKnots);
783 TColStd_Array1OfInteger VMults(1, NbVKnots);
785 C->Multiplicities(VMults);
787 // Compute the poles.
788 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
789 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
792 for ( i = 1; i<= NbUPoles; i+=2) {
793 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
794 for ( j = 1; j <= NbVPoles; j++) {
795 NewPoles(i,j) = Poles(j).Transformed(Trsf);
796 NewWeights(i,j) = Weights(j);
800 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
802 for ( j= 1; j<= NbVPoles; j++) {
803 coord = Poles(j).XYZ();
804 Aff.Transforms(coord);
805 Poles(j).SetXYZ(coord);
807 for ( i = 2; i<= NbUPoles; i+=2) {
808 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
809 for ( j = 1; j <= NbVPoles; j++) {
810 NewPoles(i,j) = Poles(j).Transformed(Trsf);
811 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
815 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
819 periodic, C->IsPeriodic());
823 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
825 Handle(Geom_BezierSurface) SBez =
826 Handle(Geom_BezierSurface)::DownCast(S);
828 Standard_Integer NbUPoles = SBez->NbUPoles();
829 Standard_Integer NbVPoles = SBez->NbVPoles();
830 Standard_Integer UDegree = SBez->UDegree();
831 Standard_Integer VDegree = SBez->VDegree();
832 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
833 TColStd_Array1OfReal UKnots(1, 2);
834 TColStd_Array1OfInteger UMults(1, 2);
835 TColStd_Array1OfReal VKnots(1, 2);
836 TColStd_Array1OfInteger VMults(1, 2);
839 UMults (1) = UDegree + 1;
840 UMults (2) = UDegree + 1;
843 VMults (1) = VDegree + 1;
844 VMults (2) = VDegree + 1;
846 if (SBez->IsURational() || SBez->IsVRational()) {
847 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
848 SBez->Weights (Weights);
849 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
854 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
860 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
861 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
864 else { // In other cases => Approx
865 Standard_Real Tol3d=1.e-4;
866 Standard_Integer MaxDegree =14, MaxSeg;
868 GeomAdaptor_Surface AS(Sr);
869 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
873 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
874 GeomConvert_ApproxSurface BSpS(Sr,Tol3d,cont,cont,
875 MaxDegree,MaxDegree,MaxSeg,1);
876 TheSurface = BSpS.Surface();
878 } // Fin du cas direct