Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GeomConvert / GeomConvert_1.cxx
CommitLineData
7fd59977 1//File GeomConvert_1.cxx
2//Jean-Claude Vauthier Novembre 1991
3//Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline
4//Modif JCV correction bug le 02/08/1993
5
6
7#include <GeomConvert.ixx>
8
9
10#include <BSplCLib.hxx>
11
12#include <Standard_DomainError.hxx>
13#include <Standard_NotImplemented.hxx>
14
15#include <Convert_ElementarySurfaceToBSplineSurface.hxx>
16#include <Convert_ConeToBSplineSurface.hxx>
17#include <Convert_CylinderToBSplineSurface.hxx>
18#include <Convert_SphereToBSplineSurface.hxx>
19#include <Convert_TorusToBSplineSurface.hxx>
20#include <GeomConvert_ApproxSurface.hxx>
21
22#include <Geom_OffsetSurface.hxx>
23#include <Geom_Surface.hxx>
24#include <Geom_Plane.hxx>
25#include <Geom_CylindricalSurface.hxx>
26#include <Geom_ConicalSurface.hxx>
27#include <Geom_SphericalSurface.hxx>
28#include <Geom_ToroidalSurface.hxx>
29#include <Geom_RectangularTrimmedSurface.hxx>
30#include <Geom_SurfaceOfRevolution.hxx>
31#include <Geom_SurfaceOfLinearExtrusion.hxx>
32#include <Geom_BSplineSurface.hxx>
33#include <Geom_BezierSurface.hxx>
34#include <Geom_Geometry.hxx>
35#include <Geom_TrimmedCurve.hxx>
36
37#include <GeomAdaptor_Surface.hxx>
38
39#include <TColgp_Array2OfPnt.hxx>
40#include <TColgp_Array1OfPnt.hxx>
41#include <TColStd_Array1OfReal.hxx>
42#include <TColStd_Array2OfReal.hxx>
43#include <TColStd_Array1OfInteger.hxx>
44#include <TColStd_Array2OfInteger.hxx>
45#include <TColStd_HArray1OfReal.hxx>
46#include <TColStd_HArray1OfInteger.hxx>
47
48#include <Precision.hxx>
49#include <gp_Vec.hxx>
50#include <gp_Sphere.hxx>
51#include <gp_Cylinder.hxx>
52#include <gp_Cone.hxx>
53#include <gp_Torus.hxx>
54#include <gp_Pln.hxx>
55#include <gp_Trsf.hxx>
56#include <gp_GTrsf.hxx>
57
58
59
60typedef Geom_Surface Surface;
61typedef Geom_BSplineSurface BSplineSurface;
62typedef Handle(Geom_Curve) Handle(Curve);
63typedef Handle(Geom_BSplineCurve) Handle(BSplineCurve);
64typedef Handle(Geom_BezierSurface) Handle(BezierSurface);
65typedef Handle(Geom_Geometry) Handle(Geometry);
66typedef Handle(Geom_Surface) Handle(Surface);
67typedef Handle(Geom_Plane) Handle(Plane);
68typedef Handle(Geom_CylindricalSurface) Handle(CylindricalSurface);
69typedef Handle(Geom_ConicalSurface) Handle(ConicalSurface);
70typedef Handle(Geom_SphericalSurface) Handle(SphericalSurface);
71typedef Handle(Geom_ToroidalSurface) Handle(ToroidalSurface);
72typedef Handle(Geom_BSplineSurface) Handle(BSplineSurface);
73typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
74typedef Handle(Geom_SurfaceOfLinearExtrusion) Handle(SurfaceOfLinearExtrusion);
75typedef Handle(Geom_RectangularTrimmedSurface)
76 Handle(RectangularTrimmedSurface);
77
78
79typedef TColStd_Array1OfReal Array1OfReal;
80typedef TColStd_Array2OfReal Array2OfReal;
81typedef TColStd_Array1OfInteger Array1OfInteger;
82typedef TColStd_Array2OfInteger Array2OfInteger;
83typedef TColgp_Array2OfPnt Array2OfPnt;
84typedef TColgp_Array1OfPnt Array1OfPnt;
85
86
87typedef gp_Pnt Pnt;
88
89
90//=======================================================================
91//function : BSplineSurfaceBuilder
92//purpose :
93//=======================================================================
94
95Handle(BSplineSurface) BSplineSurfaceBuilder
96 (const Convert_ElementarySurfaceToBSplineSurface& Convert)
97{
98 Handle(BSplineSurface) TheSurface;
99 Standard_Integer UDegree = Convert.UDegree ();
100 Standard_Integer VDegree = Convert.VDegree ();
101 Standard_Integer NbUPoles = Convert.NbUPoles();
102 Standard_Integer NbVPoles = Convert.NbVPoles();
103 Standard_Integer NbUKnots = Convert.NbUKnots();
104 Standard_Integer NbVKnots = Convert.NbVKnots();
105 Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
106 Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
107 Array1OfReal UKnots (1, NbUKnots);
108 Array1OfReal VKnots (1, NbVKnots);
109 Array1OfInteger UMults (1, NbUKnots);
110 Array1OfInteger VMults (1, NbVKnots);
111 Standard_Integer i, j;
112 for (j = 1; j <= NbVPoles; j++) {
113 for (i = 1; i <= NbUPoles; i++) {
114 Poles (i, j) = Convert.Pole (i, j);
115 Weights (i, j) = Convert.Weight (i, j);
116 }
117 }
118 for (i = 1; i <= NbUKnots; i++) {
119 UKnots (i) = Convert.UKnot (i);
120 UMults (i) = Convert.UMultiplicity (i);
121 }
122 for (i = 1; i <= NbVKnots; i++) {
123 VKnots (i) = Convert.VKnot (i);
124 VMults (i) = Convert.VMultiplicity (i);
125 }
126 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
127 UMults, VMults, UDegree, VDegree,
128 Convert.IsUPeriodic(),
129 Convert.IsVPeriodic());
130 return TheSurface;
131}
132
133//=======================================================================
134//function : SplitBSplineSurface
135//purpose :
136//=======================================================================
137
138Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
139 (const Handle(BSplineSurface)& S,
140 const Standard_Integer FromUK1,
141 const Standard_Integer ToUK2,
142 const Standard_Integer FromVK1,
143 const Standard_Integer ToVK2,
144 const Standard_Boolean SameUOrientation,
145 const Standard_Boolean SameVOrientation )
146{
147 Standard_Integer FirstU = S->FirstUKnotIndex ();
148 Standard_Integer FirstV = S->FirstVKnotIndex ();
149 Standard_Integer LastU = S->LastUKnotIndex ();
150 Standard_Integer LastV = S->LastVKnotIndex ();
151 if (FromUK1 == ToUK2 || FromVK1 == ToVK2) Standard_DomainError::Raise();
152 Standard_Integer FirstUK = Min (FromUK1, ToUK2);
153 Standard_Integer LastUK = Max (FromUK1, ToUK2);
154 Standard_Integer FirstVK = Min (FromVK1, ToVK2);
155 Standard_Integer LastVK = Max (FromVK1, ToVK2);
156 if (FirstUK < FirstU || LastUK > LastU ||
157 FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
158
159 Handle(BSplineSurface) S1= Handle(BSplineSurface)::DownCast(S->Copy());
160
161 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
162 S1->VKnot(FirstVK),S1->VKnot(LastVK));
163
164 if (S->IsUPeriodic()) {
165 if (!SameUOrientation) S1->UReverse();
166 }
167 else {
168 if (FromUK1 > ToUK2) S1->UReverse();
169 }
170 if (S->IsVPeriodic()) {
171 if (!SameVOrientation) S1->VReverse();
172 }
173 else {
174 if (FromVK1 > ToVK2) S1->VReverse();
175 }
176 return S1;
177}
178
179
180//=======================================================================
181//function : SplitBSplineSurface
182//purpose :
183//=======================================================================
184
185Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
186 (const Handle(BSplineSurface)& S,
187 const Standard_Integer FromK1,
188 const Standard_Integer ToK2,
189 const Standard_Boolean USplit,
190 const Standard_Boolean SameOrientation )
191{
192 if (FromK1 == ToK2) Standard_DomainError::Raise();
193
194
195 Handle(BSplineSurface) S1 = Handle(BSplineSurface)::DownCast(S->Copy());
196
197 if (USplit) {
198
199 Standard_Integer FirstU = S->FirstUKnotIndex ();
200 Standard_Integer LastU = S->LastUKnotIndex ();
201 Standard_Integer FirstUK = Min (FromK1, ToK2);
202 Standard_Integer LastUK = Max (FromK1, ToK2);
203 if (FirstUK < FirstU || LastUK > LastU) Standard_DomainError::Raise();
204
205 S1->Segment( S1->UKnot(FirstUK),
206 S1->UKnot(LastUK),
207 S1->VKnot(S1->FirstVKnotIndex()),
208 S1->VKnot(S1->LastVKnotIndex()));
209
210 if (S->IsUPeriodic()) {
211 if (!SameOrientation) S1->UReverse();
212 }
213 else {
214 if (FromK1 > ToK2) S1->UReverse();
215 }
216
217 }
218 else {
219
220 Standard_Integer FirstV = S->FirstVKnotIndex ();
221 Standard_Integer LastV = S->LastVKnotIndex ();
222 Standard_Integer FirstVK = Min (FromK1, ToK2);
223 Standard_Integer LastVK = Max (FromK1, ToK2);
224 if (FirstVK < FirstV || LastVK > LastV) Standard_DomainError::Raise();
225
226 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
227 S1->UKnot(S1->LastUKnotIndex()),
228 S1->VKnot(FirstVK),
229 S1->VKnot(LastVK));
230
231
232 if (S->IsVPeriodic()) {
233 if (!SameOrientation) S1->VReverse();
234 }
235 else {
236 if (FromK1 > ToK2) S1->VReverse();
237 }
238 }
239 return S1;
240}
241
242
243//=======================================================================
244//function : SplitBSplineSurface
245//purpose :
246//=======================================================================
247
248Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
249 (const Handle(BSplineSurface)& S,
250 const Standard_Real FromU1,
251 const Standard_Real ToU2,
252 const Standard_Real FromV1,
253 const Standard_Real ToV2,
254// const Standard_Real ParametricTolerance,
255 const Standard_Real ,
256 const Standard_Boolean SameUOrientation,
257 const Standard_Boolean SameVOrientation )
258{
259 Standard_Real FirstU = Min( FromU1, ToU2);
260 Standard_Real LastU = Max( FromU1, ToU2);
261 Standard_Real FirstV = Min( FromV1, ToV2);
262 Standard_Real LastV = Max( FromV1, ToV2);
263
264 Handle (Geom_BSplineSurface) NewSurface
265 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
266
267 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
268
269 if (S->IsUPeriodic()) {
270 if (!SameUOrientation) NewSurface->UReverse();
271 }
272 else {
273 if (FromU1 > ToU2) NewSurface->UReverse();
274 }
275 if (S->IsVPeriodic()) {
276 if (!SameVOrientation) NewSurface->VReverse();
277 }
278 else {
279 if (FromV1 > ToV2) NewSurface->VReverse();
280 }
281 return NewSurface;
282}
283
284
285//=======================================================================
286//function : SplitBSplineSurface
287//purpose :
288//=======================================================================
289
290Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
291 (const Handle(BSplineSurface)& S,
292 const Standard_Real FromParam1,
293 const Standard_Real ToParam2,
294 const Standard_Boolean USplit,
295 const Standard_Real ParametricTolerance,
296 const Standard_Boolean SameOrientation )
297{
298 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
299 Standard_DomainError::Raise();
300 }
301 Handle(BSplineSurface) NewSurface
302 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
303
304 if (USplit) {
305 Standard_Real FirstU = Min( FromParam1, ToParam2);
306 Standard_Real LastU = Max( FromParam1, ToParam2);
307 Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
308 Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
309
310 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
311
312 if (S->IsUPeriodic()) {
313 if (!SameOrientation) NewSurface->UReverse();
314 }
315 else {
316 if (FromParam1 > ToParam2) NewSurface->UReverse();
317 }
318
319 }
320 else {
321 Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
322 Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
323 Standard_Real FirstV = Min( FromParam1, ToParam2);
324 Standard_Real LastV = Max( FromParam1, ToParam2);
325
326 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
327
328 if (S->IsUPeriodic()) {
329 if (!SameOrientation) NewSurface->UReverse();
330 }
331 else {
332 if (FromParam1 > ToParam2) NewSurface->UReverse();
333 }
334
335 }
336 return NewSurface;
337}
338
339
340//=======================================================================
341//function : SurfaceToBSplineSurface
342//purpose :
343//=======================================================================
344
345 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
346 (const Handle(Surface)& Sr)
347{
348 Standard_Real U1, U2, V1, V2;
349 Sr->Bounds (U1, U2, V1, V2);
350 Standard_Real UFirst = Min (U1, U2);
351 Standard_Real ULast = Max (U1, U2);
352 Standard_Real VFirst = Min (V1, V2);
353 Standard_Real VLast = Max (V1, V2);
354
355 //If the surface Sr is infinite stop the computation
356 if (Precision::IsNegativeInfinite(UFirst) ||
357 Precision::IsPositiveInfinite(ULast) ||
358 Precision::IsNegativeInfinite(VFirst) ||
359 Precision::IsPositiveInfinite(VLast) ) {
360 Standard_DomainError::Raise("");
361 }
362
363 Handle(Geom_BSplineSurface) TheSurface;
364 Handle(Surface) S;
365 Handle(Geom_OffsetSurface) OffsetSur;
366 if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
367 OffsetSur = *((Handle(Geom_OffsetSurface)*)& Sr);
368 S = OffsetSur->Surface();
369 if (!S.IsNull()) { // Convert the equivalent surface.
370 return SurfaceToBSplineSurface(S);
371 }
372 }
373 S = Sr;
374
375 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
376 Handle(Geom_RectangularTrimmedSurface) Strim =
377 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
378
379 Handle(Geom_Surface) Surf = Strim->BasisSurface();
380 UFirst = U1; ULast = U2; VFirst = V1; VLast = V2;
381 if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
382 Handle(Geom_OffsetSurface) OffsetSur =
383 Handle(Geom_OffsetSurface)::DownCast(Surf);
384
385 S = OffsetSur->Surface();
386 if (!S.IsNull()) {
387 Surf = S;
388 }
389 else S = Surf;
390 }
391
392 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
393 Handle(Geom_RectangularTrimmedSurface) Strim = new
394 (Geom_RectangularTrimmedSurface) (Surf,
395 UFirst, ULast,
396 VFirst, VLast);
397 return SurfaceToBSplineSurface(Strim);
398 }
399
400 if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
401 TColgp_Array2OfPnt Poles (1, 2, 1, 2);
402 Poles (1, 1) = Strim->Value (U1, V1);
403 Poles (1, 2) = Strim->Value (U1, V2);
404 Poles (2, 1) = Strim->Value (U2, V1);
405 Poles (2, 2) = Strim->Value (U2, V2);
406 TColStd_Array1OfReal UKnots (1, 2);
407 TColStd_Array1OfReal VKnots (1, 2);
408 TColStd_Array1OfInteger UMults (1, 2);
409 TColStd_Array1OfInteger VMults (1, 2);
410 UKnots (1) = U1;
411 UKnots (2) = U2;
412 VKnots (1) = V1;
413 VKnots (2) = V2;
414 UMults (1) = 2;
415 UMults (2) = 2;
416 VMults (1) = 2;
417 VMults (2) = 2;
418 Standard_Integer UDegree = 1;
419 Standard_Integer VDegree = 1;
420 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
421 VMults, UDegree, VDegree);
422 }
423 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
424 Handle(Geom_CylindricalSurface) TheElSurf=
425 Handle(Geom_CylindricalSurface)::DownCast(Surf);
426
427 gp_Cylinder Cyl = TheElSurf->Cylinder();
428 if (Strim->IsUClosed()) {
429 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
430 TheSurface = BSplineSurfaceBuilder (Convert);
431 }
432 else {
433 Convert_CylinderToBSplineSurface
434 Conv (Cyl, UFirst, ULast, VFirst, VLast);
435 TheSurface = BSplineSurfaceBuilder (Conv);
436 }
437 }
438
439
440 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
441 Handle(Geom_ConicalSurface) TheElSurf =
442 Handle(Geom_ConicalSurface)::DownCast(Surf);
443 gp_Cone Co = TheElSurf->Cone();
444 if (Strim->IsUClosed()) {
445 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
446 TheSurface = BSplineSurfaceBuilder (Convert);
447 }
448 else {
449 Convert_ConeToBSplineSurface
450 Convert (Co, UFirst, ULast, VFirst, VLast);
451 TheSurface = BSplineSurfaceBuilder (Convert);
452 }
453 }
454
455
456 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
457 Handle(Geom_SphericalSurface) TheElSurf =
458 Handle(Geom_SphericalSurface)::DownCast(Surf);
459 gp_Sphere Sph = TheElSurf->Sphere();
460 //OCC217
461 if (Strim->IsUClosed()) {
462 //if (Strim->IsVClosed()) {
463 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
464 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
465 TheSurface = BSplineSurfaceBuilder (Convert);
466 }
467 else {
468 Convert_SphereToBSplineSurface
469 Convert (Sph, UFirst, ULast, VFirst, VLast);
470 TheSurface = BSplineSurfaceBuilder (Convert);
471 }
472 }
473
474
475 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
476 Handle(Geom_ToroidalSurface) TheElSurf =
477 Handle(Geom_ToroidalSurface)::DownCast(Surf);
478
479 gp_Torus Tr = TheElSurf->Torus();
480 if (Strim->IsUClosed()) {
481 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
482 Standard_False);
483 TheSurface = BSplineSurfaceBuilder (Convert);
484 }
485 else if (Strim->IsVClosed()) {
486 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
487 TheSurface = BSplineSurfaceBuilder (Convert);
488 }
489 else {
490 Convert_TorusToBSplineSurface
491 Convert (Tr, UFirst, ULast, VFirst, VLast);
492 TheSurface = BSplineSurfaceBuilder (Convert);
493 }
494 }
495
496
497 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
498 Handle(Geom_SurfaceOfRevolution) Revol =
499 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
500
501 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
502 Handle(Geom_BSplineCurve) C;
503 if (Strim->IsVClosed()) {
504 C = GeomConvert::CurveToBSplineCurve (Meridian);
505 }
506 else {
507 Handle(Geom_TrimmedCurve) CT =
508 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
509 C = GeomConvert::CurveToBSplineCurve (CT);
510 }
511 Standard_Integer NbUPoles, NbUKnots;
512 Standard_Integer NbVPoles, NbVKnots;
513 Standard_Boolean periodic = Standard_False;
514
515 // Poles of meridian = Vpoles
516 NbVPoles = C->NbPoles();
517 TColgp_Array1OfPnt Poles(1, NbVPoles);
518 C->Poles(Poles);
519 TColStd_Array1OfReal Weights( 1, NbVPoles);
520 Weights.Init(1.);
521 if ( C->IsRational()) C->Weights(Weights);
522
523 Standard_Integer nbUSpans;
524 Standard_Real AlfaU;
525 if (Strim->IsUPeriodic()) {
526 NbUKnots = 4;
527 nbUSpans = 3;
528 AlfaU = PI / 3.;
529 NbUPoles = 6;
530 periodic = Standard_True;
531 }
532 else {
533 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
534 nbUSpans =
535 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / PI) + 1;
536 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
537 NbUPoles = 2 * nbUSpans + 1;
538 NbUKnots = nbUSpans + 1;
539 }
540 // Compute Knots and Mults
541 TColStd_Array1OfReal UKnots(1, NbUKnots);
542 TColStd_Array1OfInteger UMults( 1, NbUKnots);
543 Standard_Integer i,j;
544 for ( i = 1; i <= NbUKnots; i++) {
545 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
546 UMults(i) = 2;
547 }
548 if (!periodic) {
549 UMults(1)++; UMults(NbUKnots)++;
550 }
551 NbVKnots = C->NbKnots();
552 TColStd_Array1OfReal VKnots(1, NbVKnots);
553 TColStd_Array1OfInteger VMults(1, NbVKnots);
554 C->Knots(VKnots);
555 C->Multiplicities(VMults);
556
557 // Compute the poles.
558 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
559 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
560 gp_Trsf Trsf;
561
562 for ( i = 1; i<= NbUPoles; i+=2) {
563 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
564 for ( j = 1; j <= NbVPoles; j++) {
565 NewPoles(i,j) = Poles(j).Transformed(Trsf);
566 NewWeights(i,j) = Weights(j);
567 }
568 }
569 gp_GTrsf Aff;
570 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
571 gp_XYZ coord;
572 for ( j= 1; j<= NbVPoles; j++) {
573 coord = Poles(j).XYZ();
574 Aff.Transforms(coord);
575 Poles(j).SetXYZ(coord);
576 }
577 for ( i = 2; i<= NbUPoles; i+=2) {
578 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
579 for ( j = 1; j <= NbVPoles; j++) {
580 NewPoles(i,j) = Poles(j).Transformed(Trsf);
581 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
582 }
583 }
584
585 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
586 UKnots, VKnots,
587 UMults, VMults,
588 2 , C->Degree(),
589 periodic, C->IsPeriodic());
590
591
592 }
593
594
595 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
596 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
597 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
598
599 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
600 Handle(Geom_BSplineCurve) C;
601 if (Strim->IsUClosed()) {
602 C = GeomConvert::CurveToBSplineCurve (Meridian);
603 }
604 else {
605 Handle(Geom_TrimmedCurve) CT =
606 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
607 C = GeomConvert::CurveToBSplineCurve (CT);
608 }
609 TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
610 TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
611 TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
612 C->Knots(UKnots);
613 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
614 C->Multiplicities(UMults);
615 TColStd_Array1OfReal VKnots ( 1, 2);
616 VKnots(1) = VFirst;
617 VKnots(2) = VLast;
618 TColStd_Array1OfInteger VMults ( 1, 2);
619 VMults.Init(2);
620
621 gp_Vec D( Extru->Direction());
622 gp_Vec DV1 = VFirst * D;
623 gp_Vec DV2 = VLast * D;
624 for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
625 Poles(i,1) = C->Pole(i).Translated(DV1);
626 Poles(i,2) = C->Pole(i).Translated(DV2);
627 Weights(i,1) = Weights(i,2) = C->Weight(i);
628 }
629 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
630 UMults, VMults,
631 C->Degree(), 1,
632 C->IsPeriodic(), Standard_False);
633 }
634
635
636 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
637
638 Handle(Geom_BezierSurface) SBez =
639 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
640
641 SBez->Segment (U1, U2, V1, V2);
642 Standard_Integer NbUPoles = SBez->NbUPoles();
643 Standard_Integer NbVPoles = SBez->NbVPoles();
644 Standard_Integer UDegree = SBez->UDegree();
645 Standard_Integer VDegree = SBez->VDegree();
646 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
647 TColStd_Array1OfReal UKnots (1, 2);
648 TColStd_Array1OfInteger UMults (1, 2);
649 TColStd_Array1OfReal VKnots (1, 2);
650 TColStd_Array1OfInteger VMults (1, 2);
651 UKnots (1) = 0.0;
652 UKnots (2) = 1.0;
653 UMults (1) = UDegree + 1;
654 UMults (2) = UDegree + 1;
655 VKnots (1) = 0.0;
656 VKnots (2) = 1.0;
657 VMults (1) = VDegree + 1;
658 VMults (2) = VDegree + 1;
659 SBez->Poles (Poles);
660 if (SBez->IsURational() || SBez->IsVRational()) {
661 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
662 SBez->Weights (Weights);
663 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
664 UMults, VMults,
665 UDegree, VDegree);
666 }
667 else {
668 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
669 UMults, VMults,
670 UDegree, VDegree);
671 }
672 }
673
674 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
675 Handle(Geom_BSplineSurface) BS =
676 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
677 Standard_Real umin, umax, vmin, vmax;
678 BS->Bounds(umin, umax, vmin, vmax);
679 if (!BS->IsUPeriodic()) {
680 if (U1 < umin)
681 U1 = umin;
682 if (U2 > umax)
683 U2 = umax;
684 }
685
686 if (!BS->IsVPeriodic()) {
687 if (V1 < vmin)
688 V1 = vmin;
689 if (V2 > vmax)
690 V2 = vmax;
691 }
692 BS->Segment (U1, U2, V1, V2);
693 TheSurface = BS;
694 }
695
696 else {
697 Standard_Real Tol3d=1.e-4;
698 Standard_Integer MaxDegree =14, MaxSeg;
699 GeomAbs_Shape cont;
700 GeomAdaptor_Surface AS(Sr);
701 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
702 cont=GeomAbs_C1;
703 else
704 cont=GeomAbs_C2;
705 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
706 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
707 MaxDegree, MaxDegree, MaxSeg, 1);
708 TheSurface = BSpS.Surface();
709 }
710 } // Fin du cas Rectangular::TrimmedSurface
711
712 else {
713
714 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
715 Handle(Geom_SphericalSurface) TheElSurf =
716 Handle(Geom_SphericalSurface)::DownCast(S);
717
718 gp_Sphere Sph = TheElSurf->Sphere();
719 Convert_SphereToBSplineSurface Convert(Sph);
720 TheSurface = BSplineSurfaceBuilder(Convert);
721 }
722
723
724 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
725 Handle(Geom_ToroidalSurface) TheElSurf =
726 Handle(Geom_ToroidalSurface)::DownCast(S);
727
728 gp_Torus Tr = TheElSurf->Torus();
729 Convert_TorusToBSplineSurface Convert(Tr);
730 TheSurface = BSplineSurfaceBuilder(Convert);
731 }
732
733
734 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
735
736 Handle(Geom_SurfaceOfRevolution) Revol =
737 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
738
739 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
740 Handle(Geom_BSplineCurve) C
741 = GeomConvert::CurveToBSplineCurve (Meridian);
742
743 Standard_Integer NbUPoles, NbUKnots;
744 Standard_Integer NbVPoles, NbVKnots;
745 Standard_Boolean periodic = Standard_True;
746
747 // Poles of meridian = Vpoles
748 NbVPoles = C->NbPoles();
749 TColgp_Array1OfPnt Poles(1, NbVPoles);
750 C->Poles(Poles);
751 TColStd_Array1OfReal Weights( 1, NbVPoles);
752 Weights.Init(1.);
753 if ( C->IsRational()) C->Weights(Weights);
754
755 Standard_Integer nbUSpans;
756 Standard_Real AlfaU;
757 NbUKnots = 4;
758 nbUSpans = 3;
759 AlfaU = PI / 3.;
760 NbUPoles = 6;
761
762 // Compute Knots and Mults
763 TColStd_Array1OfReal UKnots(1, NbUKnots);
764 TColStd_Array1OfInteger UMults( 1, NbUKnots);
765 Standard_Integer i,j;
766 for ( i = 1; i <= NbUKnots; i++) {
767 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
768 UMults(i) = 2;
769 }
770 NbVKnots = C->NbKnots();
771 TColStd_Array1OfReal VKnots(1, NbVKnots);
772 TColStd_Array1OfInteger VMults(1, NbVKnots);
773 C->Knots(VKnots);
774 C->Multiplicities(VMults);
775
776 // Compute the poles.
777 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
778 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
779 gp_Trsf Trsf;
780
781 for ( i = 1; 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);
786 }
787 }
788 gp_GTrsf Aff;
789 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
790 gp_XYZ coord;
791 for ( j= 1; j<= NbVPoles; j++) {
792 coord = Poles(j).XYZ();
793 Aff.Transforms(coord);
794 Poles(j).SetXYZ(coord);
795 }
796 for ( i = 2; i<= NbUPoles; i+=2) {
797 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
798 for ( j = 1; j <= NbVPoles; j++) {
799 NewPoles(i,j) = Poles(j).Transformed(Trsf);
800 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
801 }
802 }
803
804 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
805 UKnots, VKnots,
806 UMults, VMults,
807 2 , C->Degree(),
808 periodic, C->IsPeriodic());
809 }
810
811
812 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
813
814 Handle(Geom_BezierSurface) SBez =
815 Handle(Geom_BezierSurface)::DownCast(S);
816
817 Standard_Integer NbUPoles = SBez->NbUPoles();
818 Standard_Integer NbVPoles = SBez->NbVPoles();
819 Standard_Integer UDegree = SBez->UDegree();
820 Standard_Integer VDegree = SBez->VDegree();
821 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
822 TColStd_Array1OfReal UKnots(1, 2);
823 TColStd_Array1OfInteger UMults(1, 2);
824 TColStd_Array1OfReal VKnots(1, 2);
825 TColStd_Array1OfInteger VMults(1, 2);
826 UKnots (1) = 0.0;
827 UKnots (2) = 1.0;
828 UMults (1) = UDegree + 1;
829 UMults (2) = UDegree + 1;
830 VKnots (1) = 0.0;
831 VKnots (2) = 1.0;
832 VMults (1) = VDegree + 1;
833 VMults (2) = VDegree + 1;
834 SBez->Poles (Poles);
835 if (SBez->IsURational() || SBez->IsVRational()) {
836 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
837 SBez->Weights (Weights);
838 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
839 UMults, VMults,
840 UDegree, VDegree);
841 }
842 else {
843 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
844 UMults, VMults,
845 UDegree, VDegree);
846 }
847 }
848
849 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
850 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
851 }
852
853 else { // In other cases => Approx
854 Standard_Real Tol3d=1.e-4;
855 Standard_Integer MaxDegree =14, MaxSeg;
856 GeomAbs_Shape cont;
857 GeomAdaptor_Surface AS(Sr);
858 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
859 cont=GeomAbs_C1;
860 else
861 cont=GeomAbs_C2;
862 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
863 GeomConvert_ApproxSurface BSpS(Sr,Tol3d,cont,cont,
864 MaxDegree,MaxDegree,MaxSeg,1);
865 TheSurface = BSpS.Surface();
866 }
867 } // Fin du cas direct
868 return TheSurface;
869}
870
871
872