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 Handle(Geom_BSplineSurface) BSplineSurfaceBuilder
80 (const Convert_ElementarySurfaceToBSplineSurface& Convert)
82 Handle(Geom_BSplineSurface) TheSurface;
83 Standard_Integer UDegree = Convert.UDegree ();
84 Standard_Integer VDegree = Convert.VDegree ();
85 Standard_Integer NbUPoles = Convert.NbUPoles();
86 Standard_Integer NbVPoles = Convert.NbVPoles();
87 Standard_Integer NbUKnots = Convert.NbUKnots();
88 Standard_Integer NbVKnots = Convert.NbVKnots();
89 Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
90 Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
91 Array1OfReal UKnots (1, NbUKnots);
92 Array1OfReal VKnots (1, NbVKnots);
93 Array1OfInteger UMults (1, NbUKnots);
94 Array1OfInteger VMults (1, NbVKnots);
95 Standard_Integer i, j;
96 for (j = 1; j <= NbVPoles; j++) {
97 for (i = 1; i <= NbUPoles; i++) {
98 Poles (i, j) = Convert.Pole (i, j);
99 Weights (i, j) = Convert.Weight (i, j);
102 for (i = 1; i <= NbUKnots; i++) {
103 UKnots (i) = Convert.UKnot (i);
104 UMults (i) = Convert.UMultiplicity (i);
106 for (i = 1; i <= NbVKnots; i++) {
107 VKnots (i) = Convert.VKnot (i);
108 VMults (i) = Convert.VMultiplicity (i);
110 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
111 UMults, VMults, UDegree, VDegree,
112 Convert.IsUPeriodic(),
113 Convert.IsVPeriodic());
117 //=======================================================================
118 //function : SplitBSplineSurface
120 //=======================================================================
122 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
123 (const Handle(Geom_BSplineSurface)& S,
124 const Standard_Integer FromUK1,
125 const Standard_Integer ToUK2,
126 const Standard_Integer FromVK1,
127 const Standard_Integer ToVK2,
128 const Standard_Boolean SameUOrientation,
129 const Standard_Boolean SameVOrientation )
131 Standard_Integer FirstU = S->FirstUKnotIndex ();
132 Standard_Integer FirstV = S->FirstVKnotIndex ();
133 Standard_Integer LastU = S->LastUKnotIndex ();
134 Standard_Integer LastV = S->LastVKnotIndex ();
135 if (FromUK1 == ToUK2 || FromVK1 == ToVK2) Standard_DomainError::Raise();
136 Standard_Integer FirstUK = Min (FromUK1, ToUK2);
137 Standard_Integer LastUK = Max (FromUK1, ToUK2);
138 Standard_Integer FirstVK = Min (FromVK1, ToVK2);
139 Standard_Integer LastVK = Max (FromVK1, ToVK2);
140 if (FirstUK < FirstU || LastUK > LastU ||
141 FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
143 Handle(Geom_BSplineSurface) S1= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
145 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
146 S1->VKnot(FirstVK),S1->VKnot(LastVK));
148 if (S->IsUPeriodic()) {
149 if (!SameUOrientation) S1->UReverse();
152 if (FromUK1 > ToUK2) S1->UReverse();
154 if (S->IsVPeriodic()) {
155 if (!SameVOrientation) S1->VReverse();
158 if (FromVK1 > ToVK2) S1->VReverse();
164 //=======================================================================
165 //function : SplitBSplineSurface
167 //=======================================================================
169 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
170 (const Handle(Geom_BSplineSurface)& S,
171 const Standard_Integer FromK1,
172 const Standard_Integer ToK2,
173 const Standard_Boolean USplit,
174 const Standard_Boolean SameOrientation )
176 if (FromK1 == ToK2) Standard_DomainError::Raise();
179 Handle(Geom_BSplineSurface) S1 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
183 Standard_Integer FirstU = S->FirstUKnotIndex ();
184 Standard_Integer LastU = S->LastUKnotIndex ();
185 Standard_Integer FirstUK = Min (FromK1, ToK2);
186 Standard_Integer LastUK = Max (FromK1, ToK2);
187 if (FirstUK < FirstU || LastUK > LastU) Standard_DomainError::Raise();
189 S1->Segment( S1->UKnot(FirstUK),
191 S1->VKnot(S1->FirstVKnotIndex()),
192 S1->VKnot(S1->LastVKnotIndex()));
194 if (S->IsUPeriodic()) {
195 if (!SameOrientation) S1->UReverse();
198 if (FromK1 > ToK2) S1->UReverse();
204 Standard_Integer FirstV = S->FirstVKnotIndex ();
205 Standard_Integer LastV = S->LastVKnotIndex ();
206 Standard_Integer FirstVK = Min (FromK1, ToK2);
207 Standard_Integer LastVK = Max (FromK1, ToK2);
208 if (FirstVK < FirstV || LastVK > LastV) Standard_DomainError::Raise();
210 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
211 S1->UKnot(S1->LastUKnotIndex()),
216 if (S->IsVPeriodic()) {
217 if (!SameOrientation) S1->VReverse();
220 if (FromK1 > ToK2) S1->VReverse();
227 //=======================================================================
228 //function : SplitBSplineSurface
230 //=======================================================================
232 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
233 (const Handle(Geom_BSplineSurface)& S,
234 const Standard_Real FromU1,
235 const Standard_Real ToU2,
236 const Standard_Real FromV1,
237 const Standard_Real ToV2,
238 // const Standard_Real ParametricTolerance,
239 const Standard_Real ,
240 const Standard_Boolean SameUOrientation,
241 const Standard_Boolean SameVOrientation )
243 Standard_Real FirstU = Min( FromU1, ToU2);
244 Standard_Real LastU = Max( FromU1, ToU2);
245 Standard_Real FirstV = Min( FromV1, ToV2);
246 Standard_Real LastV = Max( FromV1, ToV2);
248 Handle (Geom_BSplineSurface) NewSurface
249 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
251 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
253 if (S->IsUPeriodic()) {
254 if (!SameUOrientation) NewSurface->UReverse();
257 if (FromU1 > ToU2) NewSurface->UReverse();
259 if (S->IsVPeriodic()) {
260 if (!SameVOrientation) NewSurface->VReverse();
263 if (FromV1 > ToV2) NewSurface->VReverse();
269 //=======================================================================
270 //function : SplitBSplineSurface
272 //=======================================================================
274 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
275 (const Handle(Geom_BSplineSurface)& S,
276 const Standard_Real FromParam1,
277 const Standard_Real ToParam2,
278 const Standard_Boolean USplit,
279 const Standard_Real ParametricTolerance,
280 const Standard_Boolean SameOrientation )
282 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
283 Standard_DomainError::Raise();
285 Handle(Geom_BSplineSurface) NewSurface
286 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
289 Standard_Real FirstU = Min( FromParam1, ToParam2);
290 Standard_Real LastU = Max( FromParam1, ToParam2);
291 Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
292 Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
294 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
296 if (S->IsUPeriodic()) {
297 if (!SameOrientation) NewSurface->UReverse();
300 if (FromParam1 > ToParam2) NewSurface->UReverse();
305 Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
306 Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
307 Standard_Real FirstV = Min( FromParam1, ToParam2);
308 Standard_Real LastV = Max( FromParam1, ToParam2);
310 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
312 if (S->IsUPeriodic()) {
313 if (!SameOrientation) NewSurface->UReverse();
316 if (FromParam1 > ToParam2) NewSurface->UReverse();
324 //=======================================================================
325 //function : SurfaceToBSplineSurface
327 //=======================================================================
329 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
330 (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 Standard_DomainError::Raise("");
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 if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
385 TColgp_Array2OfPnt Poles (1, 2, 1, 2);
386 Poles (1, 1) = Strim->Value (U1, V1);
387 Poles (1, 2) = Strim->Value (U1, V2);
388 Poles (2, 1) = Strim->Value (U2, V1);
389 Poles (2, 2) = Strim->Value (U2, V2);
390 TColStd_Array1OfReal UKnots (1, 2);
391 TColStd_Array1OfReal VKnots (1, 2);
392 TColStd_Array1OfInteger UMults (1, 2);
393 TColStd_Array1OfInteger VMults (1, 2);
402 Standard_Integer UDegree = 1;
403 Standard_Integer VDegree = 1;
404 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
405 VMults, UDegree, VDegree);
407 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
408 Handle(Geom_CylindricalSurface) TheElSurf=
409 Handle(Geom_CylindricalSurface)::DownCast(Surf);
411 gp_Cylinder Cyl = TheElSurf->Cylinder();
412 if (Strim->IsUClosed()) {
413 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
414 TheSurface = BSplineSurfaceBuilder (Convert);
417 Convert_CylinderToBSplineSurface
418 Conv (Cyl, UFirst, ULast, VFirst, VLast);
419 TheSurface = BSplineSurfaceBuilder (Conv);
424 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
425 Handle(Geom_ConicalSurface) TheElSurf =
426 Handle(Geom_ConicalSurface)::DownCast(Surf);
427 gp_Cone Co = TheElSurf->Cone();
428 if (Strim->IsUClosed()) {
429 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
430 TheSurface = BSplineSurfaceBuilder (Convert);
433 Convert_ConeToBSplineSurface
434 Convert (Co, UFirst, ULast, VFirst, VLast);
435 TheSurface = BSplineSurfaceBuilder (Convert);
440 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
441 Handle(Geom_SphericalSurface) TheElSurf =
442 Handle(Geom_SphericalSurface)::DownCast(Surf);
443 gp_Sphere Sph = TheElSurf->Sphere();
445 if (Strim->IsUClosed()) {
446 //if (Strim->IsVClosed()) {
447 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
448 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
449 TheSurface = BSplineSurfaceBuilder (Convert);
452 Convert_SphereToBSplineSurface
453 Convert (Sph, UFirst, ULast, VFirst, VLast);
454 TheSurface = BSplineSurfaceBuilder (Convert);
459 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
460 Handle(Geom_ToroidalSurface) TheElSurf =
461 Handle(Geom_ToroidalSurface)::DownCast(Surf);
463 gp_Torus Tr = TheElSurf->Torus();
464 if (Strim->IsUClosed()) {
465 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
467 TheSurface = BSplineSurfaceBuilder (Convert);
469 else if (Strim->IsVClosed()) {
470 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
471 TheSurface = BSplineSurfaceBuilder (Convert);
474 Convert_TorusToBSplineSurface
475 Convert (Tr, UFirst, ULast, VFirst, VLast);
476 TheSurface = BSplineSurfaceBuilder (Convert);
481 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
482 Handle(Geom_SurfaceOfRevolution) Revol =
483 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
485 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
486 Handle(Geom_BSplineCurve) C;
487 if (Strim->IsVClosed()) {
488 C = GeomConvert::CurveToBSplineCurve (Meridian);
491 Handle(Geom_TrimmedCurve) CT =
492 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
493 C = GeomConvert::CurveToBSplineCurve (CT);
495 Standard_Integer NbUPoles, NbUKnots;
496 Standard_Integer NbVPoles, NbVKnots;
497 Standard_Boolean periodic = Standard_False;
499 // Poles of meridian = Vpoles
500 NbVPoles = C->NbPoles();
501 TColgp_Array1OfPnt Poles(1, NbVPoles);
503 TColStd_Array1OfReal Weights( 1, NbVPoles);
505 if ( C->IsRational()) C->Weights(Weights);
507 Standard_Integer nbUSpans;
509 if (Strim->IsUPeriodic()) {
514 periodic = Standard_True;
517 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
519 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
520 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
521 NbUPoles = 2 * nbUSpans + 1;
522 NbUKnots = nbUSpans + 1;
524 // Compute Knots and Mults
525 TColStd_Array1OfReal UKnots(1, NbUKnots);
526 TColStd_Array1OfInteger UMults( 1, NbUKnots);
527 Standard_Integer i,j;
528 for ( i = 1; i <= NbUKnots; i++) {
529 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
533 UMults(1)++; UMults(NbUKnots)++;
535 NbVKnots = C->NbKnots();
536 TColStd_Array1OfReal VKnots(1, NbVKnots);
537 TColStd_Array1OfInteger VMults(1, NbVKnots);
539 C->Multiplicities(VMults);
541 // Compute the poles.
542 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
543 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
546 for ( i = 1; i<= NbUPoles; i+=2) {
547 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
548 for ( j = 1; j <= NbVPoles; j++) {
549 NewPoles(i,j) = Poles(j).Transformed(Trsf);
550 NewWeights(i,j) = Weights(j);
554 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
556 for ( j= 1; j<= NbVPoles; j++) {
557 coord = Poles(j).XYZ();
558 Aff.Transforms(coord);
559 Poles(j).SetXYZ(coord);
561 for ( i = 2; i<= NbUPoles; i+=2) {
562 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
563 for ( j = 1; j <= NbVPoles; j++) {
564 NewPoles(i,j) = Poles(j).Transformed(Trsf);
565 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
569 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
573 periodic, C->IsPeriodic());
579 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
580 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
581 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
583 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
584 Handle(Geom_BSplineCurve) C;
585 if (Strim->IsUClosed()) {
586 C = GeomConvert::CurveToBSplineCurve (Meridian);
589 Handle(Geom_TrimmedCurve) CT =
590 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
591 C = GeomConvert::CurveToBSplineCurve (CT);
593 TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
594 TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
595 TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
597 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
598 C->Multiplicities(UMults);
599 TColStd_Array1OfReal VKnots ( 1, 2);
602 TColStd_Array1OfInteger VMults ( 1, 2);
605 gp_Vec D( Extru->Direction());
606 gp_Vec DV1 = VFirst * D;
607 gp_Vec DV2 = VLast * D;
608 for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
609 Poles(i,1) = C->Pole(i).Translated(DV1);
610 Poles(i,2) = C->Pole(i).Translated(DV2);
611 Weights(i,1) = Weights(i,2) = C->Weight(i);
613 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
616 C->IsPeriodic(), Standard_False);
620 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
622 Handle(Geom_BezierSurface) SBez =
623 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
625 SBez->Segment (U1, U2, V1, V2);
626 Standard_Integer NbUPoles = SBez->NbUPoles();
627 Standard_Integer NbVPoles = SBez->NbVPoles();
628 Standard_Integer UDegree = SBez->UDegree();
629 Standard_Integer VDegree = SBez->VDegree();
630 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
631 TColStd_Array1OfReal UKnots (1, 2);
632 TColStd_Array1OfInteger UMults (1, 2);
633 TColStd_Array1OfReal VKnots (1, 2);
634 TColStd_Array1OfInteger VMults (1, 2);
637 UMults (1) = UDegree + 1;
638 UMults (2) = UDegree + 1;
641 VMults (1) = VDegree + 1;
642 VMults (2) = VDegree + 1;
644 if (SBez->IsURational() || SBez->IsVRational()) {
645 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
646 SBez->Weights (Weights);
647 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
652 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
658 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
659 Handle(Geom_BSplineSurface) BS =
660 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
661 Standard_Real umin, umax, vmin, vmax;
662 BS->Bounds(umin, umax, vmin, vmax);
663 if (!BS->IsUPeriodic()) {
670 if (!BS->IsVPeriodic()) {
676 if (BS->IsUPeriodic() || BS->IsVPeriodic())
677 BS->CheckAndSegment (U1, U2, V1, V2);
679 BS->Segment (U1, U2, V1, V2);
684 Standard_Real Tol3d=1.e-4;
685 Standard_Integer MaxDegree =14, MaxSeg;
687 GeomAdaptor_Surface AS(Sr);
688 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
692 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
693 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
694 MaxDegree, MaxDegree, MaxSeg, 1);
695 TheSurface = BSpS.Surface();
697 } // Fin du cas Rectangular::TrimmedSurface
701 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
702 Handle(Geom_SphericalSurface) TheElSurf =
703 Handle(Geom_SphericalSurface)::DownCast(S);
705 gp_Sphere Sph = TheElSurf->Sphere();
706 Convert_SphereToBSplineSurface Convert(Sph);
707 TheSurface = BSplineSurfaceBuilder(Convert);
711 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
712 Handle(Geom_ToroidalSurface) TheElSurf =
713 Handle(Geom_ToroidalSurface)::DownCast(S);
715 gp_Torus Tr = TheElSurf->Torus();
716 Convert_TorusToBSplineSurface Convert(Tr);
717 TheSurface = BSplineSurfaceBuilder(Convert);
721 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
723 Handle(Geom_SurfaceOfRevolution) Revol =
724 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
726 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
727 Handle(Geom_BSplineCurve) C
728 = GeomConvert::CurveToBSplineCurve (Meridian);
730 Standard_Integer NbUPoles, NbUKnots;
731 Standard_Integer NbVPoles, NbVKnots;
732 Standard_Boolean periodic = Standard_True;
734 // Poles of meridian = Vpoles
735 NbVPoles = C->NbPoles();
736 TColgp_Array1OfPnt Poles(1, NbVPoles);
738 TColStd_Array1OfReal Weights( 1, NbVPoles);
740 if ( C->IsRational()) C->Weights(Weights);
747 // Compute Knots and Mults
748 TColStd_Array1OfReal UKnots(1, NbUKnots);
749 TColStd_Array1OfInteger UMults( 1, NbUKnots);
750 Standard_Integer i,j;
751 for ( i = 1; i <= NbUKnots; i++) {
752 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
755 NbVKnots = C->NbKnots();
756 TColStd_Array1OfReal VKnots(1, NbVKnots);
757 TColStd_Array1OfInteger VMults(1, NbVKnots);
759 C->Multiplicities(VMults);
761 // Compute the poles.
762 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
763 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
766 for ( i = 1; i<= NbUPoles; i+=2) {
767 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
768 for ( j = 1; j <= NbVPoles; j++) {
769 NewPoles(i,j) = Poles(j).Transformed(Trsf);
770 NewWeights(i,j) = Weights(j);
774 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
776 for ( j= 1; j<= NbVPoles; j++) {
777 coord = Poles(j).XYZ();
778 Aff.Transforms(coord);
779 Poles(j).SetXYZ(coord);
781 for ( i = 2; i<= NbUPoles; i+=2) {
782 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
783 for ( j = 1; j <= NbVPoles; j++) {
784 NewPoles(i,j) = Poles(j).Transformed(Trsf);
785 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
789 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
793 periodic, C->IsPeriodic());
797 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
799 Handle(Geom_BezierSurface) SBez =
800 Handle(Geom_BezierSurface)::DownCast(S);
802 Standard_Integer NbUPoles = SBez->NbUPoles();
803 Standard_Integer NbVPoles = SBez->NbVPoles();
804 Standard_Integer UDegree = SBez->UDegree();
805 Standard_Integer VDegree = SBez->VDegree();
806 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
807 TColStd_Array1OfReal UKnots(1, 2);
808 TColStd_Array1OfInteger UMults(1, 2);
809 TColStd_Array1OfReal VKnots(1, 2);
810 TColStd_Array1OfInteger VMults(1, 2);
813 UMults (1) = UDegree + 1;
814 UMults (2) = UDegree + 1;
817 VMults (1) = VDegree + 1;
818 VMults (2) = VDegree + 1;
820 if (SBez->IsURational() || SBez->IsVRational()) {
821 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
822 SBez->Weights (Weights);
823 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
828 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
834 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
835 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
838 else { // In other cases => Approx
839 Standard_Real Tol3d=1.e-4;
840 Standard_Integer MaxDegree = 14, MaxSeg;
841 GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
842 GeomAdaptor_Surface AS(Sr);
848 else if(Sr->IsCNu(1))
857 else if(Sr->IsCNv(1))
862 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
863 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
864 MaxDegree, MaxDegree, MaxSeg, 1);
865 TheSurface = BSpS.Surface();
867 } // Fin du cas direct