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 #include <GeomConvert.hxx>
17 #include <Convert_ConeToBSplineSurface.hxx>
18 #include <Convert_CylinderToBSplineSurface.hxx>
19 #include <Convert_ElementarySurfaceToBSplineSurface.hxx>
20 #include <Convert_SphereToBSplineSurface.hxx>
21 #include <Convert_TorusToBSplineSurface.hxx>
22 #include <Geom_BezierSurface.hxx>
23 #include <Geom_BSplineCurve.hxx>
24 #include <Geom_ConicalSurface.hxx>
25 #include <Geom_Curve.hxx>
26 #include <Geom_CylindricalSurface.hxx>
27 #include <Geom_Geometry.hxx>
28 #include <Geom_OffsetSurface.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_RectangularTrimmedSurface.hxx>
31 #include <Geom_SphericalSurface.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom_SurfaceOfLinearExtrusion.hxx>
34 #include <Geom_SurfaceOfRevolution.hxx>
35 #include <Geom_ToroidalSurface.hxx>
36 #include <Geom_TrimmedCurve.hxx>
37 #include <GeomAdaptor_Surface.hxx>
38 #include <GeomConvert_ApproxSurface.hxx>
39 #include <gp_Cone.hxx>
40 #include <gp_Cylinder.hxx>
41 #include <gp_GTrsf.hxx>
42 #include <gp_Sphere.hxx>
43 #include <gp_Torus.hxx>
44 #include <gp_Trsf.hxx>
46 #include <Precision.hxx>
47 #include <Standard_DomainError.hxx>
48 #include <TColgp_Array1OfPnt.hxx>
49 #include <TColgp_Array2OfPnt.hxx>
50 #include <TColStd_Array1OfInteger.hxx>
51 #include <TColStd_Array1OfReal.hxx>
52 #include <TColStd_Array2OfInteger.hxx>
53 #include <TColStd_Array2OfReal.hxx>
55 typedef Geom_Surface Surface;
56 typedef Geom_BSplineSurface BSplineSurface;
57 typedef TColStd_Array1OfReal Array1OfReal;
58 typedef TColStd_Array2OfReal Array2OfReal;
59 typedef TColStd_Array1OfInteger Array1OfInteger;
60 typedef TColStd_Array2OfInteger Array2OfInteger;
61 typedef TColgp_Array2OfPnt Array2OfPnt;
62 typedef TColgp_Array1OfPnt Array1OfPnt;
65 //=======================================================================
66 //function : BSplineSurfaceBuilder
68 //=======================================================================
70 static Handle(Geom_BSplineSurface) BSplineSurfaceBuilder (const Convert_ElementarySurfaceToBSplineSurface& Convert)
72 Handle(Geom_BSplineSurface) TheSurface;
73 Standard_Integer UDegree = Convert.UDegree ();
74 Standard_Integer VDegree = Convert.VDegree ();
75 Standard_Integer NbUPoles = Convert.NbUPoles();
76 Standard_Integer NbVPoles = Convert.NbVPoles();
77 Standard_Integer NbUKnots = Convert.NbUKnots();
78 Standard_Integer NbVKnots = Convert.NbVKnots();
79 Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
80 Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
81 Array1OfReal UKnots (1, NbUKnots);
82 Array1OfReal VKnots (1, NbVKnots);
83 Array1OfInteger UMults (1, NbUKnots);
84 Array1OfInteger VMults (1, NbVKnots);
85 Standard_Integer i, j;
86 for (j = 1; j <= NbVPoles; j++) {
87 for (i = 1; i <= NbUPoles; i++) {
88 Poles (i, j) = Convert.Pole (i, j);
89 Weights (i, j) = Convert.Weight (i, j);
92 for (i = 1; i <= NbUKnots; i++) {
93 UKnots (i) = Convert.UKnot (i);
94 UMults (i) = Convert.UMultiplicity (i);
96 for (i = 1; i <= NbVKnots; i++) {
97 VKnots (i) = Convert.VKnot (i);
98 VMults (i) = Convert.VMultiplicity (i);
100 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
101 UMults, VMults, UDegree, VDegree,
102 Convert.IsUPeriodic(),
103 Convert.IsVPeriodic());
107 //=======================================================================
108 //function : SplitBSplineSurface
110 //=======================================================================
112 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
113 (const Handle(Geom_BSplineSurface)& S,
114 const Standard_Integer FromUK1,
115 const Standard_Integer ToUK2,
116 const Standard_Integer FromVK1,
117 const Standard_Integer ToVK2,
118 const Standard_Boolean SameUOrientation,
119 const Standard_Boolean SameVOrientation )
121 Standard_Integer FirstU = S->FirstUKnotIndex ();
122 Standard_Integer FirstV = S->FirstVKnotIndex ();
123 Standard_Integer LastU = S->LastUKnotIndex ();
124 Standard_Integer LastV = S->LastVKnotIndex ();
125 if (FromUK1 == ToUK2 || FromVK1 == ToVK2) throw Standard_DomainError();
126 Standard_Integer FirstUK = Min (FromUK1, ToUK2);
127 Standard_Integer LastUK = Max (FromUK1, ToUK2);
128 Standard_Integer FirstVK = Min (FromVK1, ToVK2);
129 Standard_Integer LastVK = Max (FromVK1, ToVK2);
130 if (FirstUK < FirstU || LastUK > LastU ||
131 FirstVK < FirstV || LastVK > LastV) { throw Standard_DomainError(); }
133 Handle(Geom_BSplineSurface) S1= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
135 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
136 S1->VKnot(FirstVK),S1->VKnot(LastVK));
138 if (S->IsUPeriodic()) {
139 if (!SameUOrientation) S1->UReverse();
142 if (FromUK1 > ToUK2) S1->UReverse();
144 if (S->IsVPeriodic()) {
145 if (!SameVOrientation) S1->VReverse();
148 if (FromVK1 > ToVK2) S1->VReverse();
154 //=======================================================================
155 //function : SplitBSplineSurface
157 //=======================================================================
159 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
160 (const Handle(Geom_BSplineSurface)& S,
161 const Standard_Integer FromK1,
162 const Standard_Integer ToK2,
163 const Standard_Boolean USplit,
164 const Standard_Boolean SameOrientation )
166 if (FromK1 == ToK2) throw Standard_DomainError();
169 Handle(Geom_BSplineSurface) S1 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
173 Standard_Integer FirstU = S->FirstUKnotIndex ();
174 Standard_Integer LastU = S->LastUKnotIndex ();
175 Standard_Integer FirstUK = Min (FromK1, ToK2);
176 Standard_Integer LastUK = Max (FromK1, ToK2);
177 if (FirstUK < FirstU || LastUK > LastU) throw Standard_DomainError();
179 S1->Segment( S1->UKnot(FirstUK),
181 S1->VKnot(S1->FirstVKnotIndex()),
182 S1->VKnot(S1->LastVKnotIndex()));
184 if (S->IsUPeriodic()) {
185 if (!SameOrientation) S1->UReverse();
188 if (FromK1 > ToK2) S1->UReverse();
194 Standard_Integer FirstV = S->FirstVKnotIndex ();
195 Standard_Integer LastV = S->LastVKnotIndex ();
196 Standard_Integer FirstVK = Min (FromK1, ToK2);
197 Standard_Integer LastVK = Max (FromK1, ToK2);
198 if (FirstVK < FirstV || LastVK > LastV) throw Standard_DomainError();
200 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
201 S1->UKnot(S1->LastUKnotIndex()),
206 if (S->IsVPeriodic()) {
207 if (!SameOrientation) S1->VReverse();
210 if (FromK1 > ToK2) S1->VReverse();
217 //=======================================================================
218 //function : SplitBSplineSurface
220 //=======================================================================
222 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
223 (const Handle(Geom_BSplineSurface)& S,
224 const Standard_Real FromU1,
225 const Standard_Real ToU2,
226 const Standard_Real FromV1,
227 const Standard_Real ToV2,
228 // const Standard_Real ParametricTolerance,
229 const Standard_Real ,
230 const Standard_Boolean SameUOrientation,
231 const Standard_Boolean SameVOrientation )
233 Standard_Real FirstU = Min( FromU1, ToU2);
234 Standard_Real LastU = Max( FromU1, ToU2);
235 Standard_Real FirstV = Min( FromV1, ToV2);
236 Standard_Real LastV = Max( FromV1, ToV2);
238 Handle (Geom_BSplineSurface) NewSurface
239 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
241 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
243 if (S->IsUPeriodic()) {
244 if (!SameUOrientation) NewSurface->UReverse();
247 if (FromU1 > ToU2) NewSurface->UReverse();
249 if (S->IsVPeriodic()) {
250 if (!SameVOrientation) NewSurface->VReverse();
253 if (FromV1 > ToV2) NewSurface->VReverse();
259 //=======================================================================
260 //function : SplitBSplineSurface
262 //=======================================================================
264 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
265 (const Handle(Geom_BSplineSurface)& S,
266 const Standard_Real FromParam1,
267 const Standard_Real ToParam2,
268 const Standard_Boolean USplit,
269 const Standard_Real ParametricTolerance,
270 const Standard_Boolean SameOrientation )
272 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
273 throw Standard_DomainError();
275 Handle(Geom_BSplineSurface) NewSurface
276 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
279 Standard_Real FirstU = Min( FromParam1, ToParam2);
280 Standard_Real LastU = Max( FromParam1, ToParam2);
281 Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
282 Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
284 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
286 if (S->IsUPeriodic()) {
287 if (!SameOrientation) NewSurface->UReverse();
290 if (FromParam1 > ToParam2) NewSurface->UReverse();
295 Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
296 Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
297 Standard_Real FirstV = Min( FromParam1, ToParam2);
298 Standard_Real LastV = Max( FromParam1, ToParam2);
300 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
302 if (S->IsUPeriodic()) {
303 if (!SameOrientation) NewSurface->UReverse();
306 if (FromParam1 > ToParam2) NewSurface->UReverse();
314 //=======================================================================
315 //function : SurfaceToBSplineSurface
317 //=======================================================================
319 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
320 (const Handle(Geom_Surface)& Sr)
323 Standard_Real U1, U2, V1, V2;
324 Sr->Bounds (U1, U2, V1, V2);
325 Standard_Real UFirst = Min (U1, U2);
326 Standard_Real ULast = Max (U1, U2);
327 Standard_Real VFirst = Min (V1, V2);
328 Standard_Real VLast = Max (V1, V2);
330 //If the surface Sr is infinite stop the computation
331 if (Precision::IsNegativeInfinite(UFirst) ||
332 Precision::IsPositiveInfinite(ULast) ||
333 Precision::IsNegativeInfinite(VFirst) ||
334 Precision::IsPositiveInfinite(VLast) ) {
335 throw Standard_DomainError ("GeomConvert::SurfaceToBSplineSurface() - infinite surface");
338 Handle(Geom_BSplineSurface) TheSurface;
339 Handle(Geom_Surface) S;
340 Handle(Geom_OffsetSurface) OffsetSur;
341 if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
342 OffsetSur = Handle(Geom_OffsetSurface)::DownCast (Sr);
343 S = OffsetSur->Surface();
344 if (!S.IsNull()) { // Convert the equivalent surface.
345 return SurfaceToBSplineSurface(S);
350 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
351 Handle(Geom_RectangularTrimmedSurface) Strim =
352 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
354 Handle(Geom_Surface) Surf = Strim->BasisSurface();
355 UFirst = U1; ULast = U2; VFirst = V1; VLast = V2;
356 if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
357 Handle(Geom_OffsetSurface) OffsetSurBasis =
358 Handle(Geom_OffsetSurface)::DownCast(Surf);
360 S = OffsetSurBasis->Surface();
367 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
368 Handle(Geom_RectangularTrimmedSurface) aStrim = new
369 (Geom_RectangularTrimmedSurface) (Surf,
372 return SurfaceToBSplineSurface(aStrim);
375 //For cylinders, cones, spheres, toruses
376 const Standard_Boolean isUClosed = Abs((ULast - UFirst) - 2. * M_PI) <= Precision::PConfusion();
377 const Standard_Real eps = 100. * Epsilon(2. * M_PI);
379 if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
380 TColgp_Array2OfPnt Poles (1, 2, 1, 2);
381 Poles (1, 1) = Strim->Value (U1, V1);
382 Poles (1, 2) = Strim->Value (U1, V2);
383 Poles (2, 1) = Strim->Value (U2, V1);
384 Poles (2, 2) = Strim->Value (U2, V2);
385 TColStd_Array1OfReal UKnots (1, 2);
386 TColStd_Array1OfReal VKnots (1, 2);
387 TColStd_Array1OfInteger UMults (1, 2);
388 TColStd_Array1OfInteger VMults (1, 2);
397 Standard_Integer UDegree = 1;
398 Standard_Integer VDegree = 1;
399 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
400 VMults, UDegree, VDegree);
402 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
403 Handle(Geom_CylindricalSurface) TheElSurf=
404 Handle(Geom_CylindricalSurface)::DownCast(Surf);
406 gp_Cylinder Cyl = TheElSurf->Cylinder();
408 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
409 TheSurface = BSplineSurfaceBuilder (Convert);
410 Standard_Integer aNbK = TheSurface->NbUKnots();
411 if (Abs(TheSurface->UKnot(1) - UFirst) > eps || Abs(TheSurface->UKnot(aNbK) - ULast) > eps)
413 TheSurface->CheckAndSegment(UFirst, ULast, VFirst, VLast);
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();
429 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
430 TheSurface = BSplineSurfaceBuilder (Convert);
431 Standard_Integer aNbK = TheSurface->NbUKnots();
432 if (Abs(TheSurface->UKnot(1) - UFirst) > eps || Abs(TheSurface->UKnot(aNbK) - ULast) > eps)
434 TheSurface->CheckAndSegment(UFirst, ULast, VFirst, VLast);
438 Convert_ConeToBSplineSurface
439 Convert (Co, UFirst, ULast, VFirst, VLast);
440 TheSurface = BSplineSurfaceBuilder (Convert);
445 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
446 Handle(Geom_SphericalSurface) TheElSurf =
447 Handle(Geom_SphericalSurface)::DownCast(Surf);
448 gp_Sphere Sph = TheElSurf->Sphere();
451 //if (Strim->IsVClosed()) {
452 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
453 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
454 TheSurface = BSplineSurfaceBuilder (Convert);
455 Standard_Integer aNbK = TheSurface->NbUKnots();
456 if (Abs(TheSurface->UKnot(1) - UFirst) > eps || Abs(TheSurface->UKnot(aNbK) - ULast) > eps)
458 TheSurface->CheckAndSegment(UFirst, ULast, VFirst, VLast);
462 Convert_SphereToBSplineSurface
463 Convert (Sph, UFirst, ULast, VFirst, VLast);
464 TheSurface = BSplineSurfaceBuilder (Convert);
469 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
470 Handle(Geom_ToroidalSurface) TheElSurf =
471 Handle(Geom_ToroidalSurface)::DownCast(Surf);
473 gp_Torus Tr = TheElSurf->Torus();
475 // if isUClosed = true and U trim does not coinside with first period of torus,
476 // method CheckAndSegment shifts position of U seam boundary of surface.
477 // probably bug? So, for this case we must build not periodic surface.
478 Standard_Boolean isUFirstPeriod = !(UFirst < 0. || ULast > 2.*M_PI);
479 Standard_Boolean isVFirstPeriod = !(VFirst < 0. || VLast > 2.*M_PI);
480 if (isUClosed && isUFirstPeriod) {
481 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
483 TheSurface = BSplineSurfaceBuilder (Convert);
484 Standard_Integer aNbK = TheSurface->NbUKnots();
485 if (Abs(TheSurface->UKnot(1) - UFirst) > eps || Abs(TheSurface->UKnot(aNbK) - ULast) > eps)
487 TheSurface->CheckAndSegment(UFirst, ULast, VFirst, VLast);
490 else if (Strim->IsVClosed() && isVFirstPeriod) {
491 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
492 TheSurface = BSplineSurfaceBuilder (Convert);
493 Standard_Integer aNbK = TheSurface->NbVKnots();
494 if (Abs(TheSurface->VKnot(1) - VFirst) > eps || Abs(TheSurface->VKnot(aNbK) - VLast) > eps)
496 TheSurface->CheckAndSegment(UFirst, ULast, VFirst, VLast);
500 Convert_TorusToBSplineSurface
501 Convert (Tr, UFirst, ULast, VFirst, VLast);
502 TheSurface = BSplineSurfaceBuilder (Convert);
507 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
508 Handle(Geom_SurfaceOfRevolution) Revol =
509 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
511 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
512 Handle(Geom_BSplineCurve) C;
513 if (Strim->IsVClosed()) {
514 C = GeomConvert::CurveToBSplineCurve (Meridian);
517 Handle(Geom_TrimmedCurve) CT =
518 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
519 C = GeomConvert::CurveToBSplineCurve (CT);
521 Standard_Integer NbUPoles, NbUKnots;
522 Standard_Integer NbVPoles, NbVKnots;
523 Standard_Boolean periodic = Standard_False;
525 // Poles of meridian = Vpoles
526 NbVPoles = C->NbPoles();
527 TColgp_Array1OfPnt Poles(1, NbVPoles);
529 TColStd_Array1OfReal Weights( 1, NbVPoles);
531 if ( C->IsRational()) C->Weights(Weights);
533 Standard_Integer nbUSpans;
535 if (Strim->IsUPeriodic()) {
540 periodic = Standard_True;
543 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
545 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
546 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
547 NbUPoles = 2 * nbUSpans + 1;
548 NbUKnots = nbUSpans + 1;
550 // Compute Knots and Mults
551 TColStd_Array1OfReal UKnots(1, NbUKnots);
552 TColStd_Array1OfInteger UMults( 1, NbUKnots);
553 Standard_Integer i,j;
554 for ( i = 1; i <= NbUKnots; i++) {
555 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
559 UMults(1)++; UMults(NbUKnots)++;
561 NbVKnots = C->NbKnots();
562 TColStd_Array1OfReal VKnots(1, NbVKnots);
563 TColStd_Array1OfInteger VMults(1, NbVKnots);
565 C->Multiplicities(VMults);
567 // Compute the poles.
568 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
569 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
572 for ( i = 1; i<= NbUPoles; i+=2) {
573 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
574 for ( j = 1; j <= NbVPoles; j++) {
575 NewPoles(i,j) = Poles(j).Transformed(Trsf);
576 NewWeights(i,j) = Weights(j);
580 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
582 for ( j= 1; j<= NbVPoles; j++) {
583 coord = Poles(j).XYZ();
584 Aff.Transforms(coord);
585 Poles(j).SetXYZ(coord);
587 for ( i = 2; i<= NbUPoles; i+=2) {
588 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
589 for ( j = 1; j <= NbVPoles; j++) {
590 NewPoles(i,j) = Poles(j).Transformed(Trsf);
591 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
595 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
599 periodic, C->IsPeriodic());
604 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
605 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
606 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
608 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
609 Handle(Geom_BSplineCurve) C;
610 if (Strim->IsUClosed()) {
611 C = GeomConvert::CurveToBSplineCurve (Meridian);
614 Handle(Geom_TrimmedCurve) CT =
615 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
616 C = GeomConvert::CurveToBSplineCurve (CT);
618 TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
619 TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
620 TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
622 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
623 C->Multiplicities(UMults);
624 TColStd_Array1OfReal VKnots ( 1, 2);
627 TColStd_Array1OfInteger VMults ( 1, 2);
630 gp_Vec D( Extru->Direction());
631 gp_Vec DV1 = VFirst * D;
632 gp_Vec DV2 = VLast * D;
633 for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
634 Poles(i,1) = C->Pole(i).Translated(DV1);
635 Poles(i,2) = C->Pole(i).Translated(DV2);
636 Weights(i,1) = Weights(i,2) = C->Weight(i);
638 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
641 C->IsPeriodic(), Standard_False);
645 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
647 Handle(Geom_BezierSurface) SBez =
648 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
650 SBez->Segment (U1, U2, V1, V2);
651 Standard_Integer NbUPoles = SBez->NbUPoles();
652 Standard_Integer NbVPoles = SBez->NbVPoles();
653 Standard_Integer UDegree = SBez->UDegree();
654 Standard_Integer VDegree = SBez->VDegree();
655 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
656 TColStd_Array1OfReal UKnots (1, 2);
657 TColStd_Array1OfInteger UMults (1, 2);
658 TColStd_Array1OfReal VKnots (1, 2);
659 TColStd_Array1OfInteger VMults (1, 2);
662 UMults (1) = UDegree + 1;
663 UMults (2) = UDegree + 1;
666 VMults (1) = VDegree + 1;
667 VMults (2) = VDegree + 1;
669 if (SBez->IsURational() || SBez->IsVRational()) {
670 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
671 SBez->Weights (Weights);
672 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
677 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
683 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
684 Handle(Geom_BSplineSurface) BS =
685 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
686 Standard_Real umin, umax, vmin, vmax;
687 BS->Bounds(umin, umax, vmin, vmax);
688 if (!BS->IsUPeriodic()) {
695 if (!BS->IsVPeriodic()) {
701 if (BS->IsUPeriodic() || BS->IsVPeriodic())
702 BS->CheckAndSegment (U1, U2, V1, V2);
704 BS->Segment (U1, U2, V1, V2);
709 Standard_Real Tol3d=1.e-4;
710 Standard_Integer MaxDegree =14, MaxSeg;
712 GeomAdaptor_Surface AS(Sr);
713 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
717 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
718 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
719 MaxDegree, MaxDegree, MaxSeg, 1);
720 TheSurface = BSpS.Surface();
722 } // Fin du cas Rectangular::TrimmedSurface
726 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
727 Handle(Geom_SphericalSurface) TheElSurf =
728 Handle(Geom_SphericalSurface)::DownCast(S);
730 gp_Sphere Sph = TheElSurf->Sphere();
731 Convert_SphereToBSplineSurface Convert(Sph);
732 TheSurface = BSplineSurfaceBuilder(Convert);
736 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
737 Handle(Geom_ToroidalSurface) TheElSurf =
738 Handle(Geom_ToroidalSurface)::DownCast(S);
740 gp_Torus Tr = TheElSurf->Torus();
741 Convert_TorusToBSplineSurface Convert(Tr);
742 TheSurface = BSplineSurfaceBuilder(Convert);
746 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
748 Handle(Geom_SurfaceOfRevolution) Revol =
749 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
751 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
752 Handle(Geom_BSplineCurve) C
753 = GeomConvert::CurveToBSplineCurve (Meridian);
755 Standard_Integer NbUPoles, NbUKnots;
756 Standard_Integer NbVPoles, NbVKnots;
757 Standard_Boolean periodic = Standard_True;
759 // Poles of meridian = Vpoles
760 NbVPoles = C->NbPoles();
761 TColgp_Array1OfPnt Poles(1, NbVPoles);
763 TColStd_Array1OfReal Weights( 1, NbVPoles);
765 if ( C->IsRational()) C->Weights(Weights);
772 // Compute Knots and Mults
773 TColStd_Array1OfReal UKnots(1, NbUKnots);
774 TColStd_Array1OfInteger UMults( 1, NbUKnots);
775 Standard_Integer i,j;
776 for ( i = 1; i <= NbUKnots; i++) {
777 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
780 NbVKnots = C->NbKnots();
781 TColStd_Array1OfReal VKnots(1, NbVKnots);
782 TColStd_Array1OfInteger VMults(1, NbVKnots);
784 C->Multiplicities(VMults);
786 // Compute the poles.
787 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
788 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
791 for ( i = 1; i<= NbUPoles; i+=2) {
792 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
793 for ( j = 1; j <= NbVPoles; j++) {
794 NewPoles(i,j) = Poles(j).Transformed(Trsf);
795 NewWeights(i,j) = Weights(j);
799 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
801 for ( j= 1; j<= NbVPoles; j++) {
802 coord = Poles(j).XYZ();
803 Aff.Transforms(coord);
804 Poles(j).SetXYZ(coord);
806 for ( i = 2; i<= NbUPoles; i+=2) {
807 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
808 for ( j = 1; j <= NbVPoles; j++) {
809 NewPoles(i,j) = Poles(j).Transformed(Trsf);
810 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
814 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
818 periodic, C->IsPeriodic());
822 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
824 Handle(Geom_BezierSurface) SBez =
825 Handle(Geom_BezierSurface)::DownCast(S);
827 Standard_Integer NbUPoles = SBez->NbUPoles();
828 Standard_Integer NbVPoles = SBez->NbVPoles();
829 Standard_Integer UDegree = SBez->UDegree();
830 Standard_Integer VDegree = SBez->VDegree();
831 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
832 TColStd_Array1OfReal UKnots(1, 2);
833 TColStd_Array1OfInteger UMults(1, 2);
834 TColStd_Array1OfReal VKnots(1, 2);
835 TColStd_Array1OfInteger VMults(1, 2);
838 UMults (1) = UDegree + 1;
839 UMults (2) = UDegree + 1;
842 VMults (1) = VDegree + 1;
843 VMults (2) = VDegree + 1;
845 if (SBez->IsURational() || SBez->IsVRational()) {
846 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
847 SBez->Weights (Weights);
848 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
853 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
859 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
860 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
863 else { // In other cases => Approx
864 Standard_Real Tol3d=1.e-4;
865 Standard_Integer MaxDegree = 14, MaxSeg;
866 GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
867 GeomAdaptor_Surface AS(Sr);
873 else if(Sr->IsCNu(1))
882 else if(Sr->IsCNv(1))
887 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
888 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
889 MaxDegree, MaxDegree, MaxSeg, 1);
890 TheSurface = BSpS.Surface();
892 } // Fin du cas direct