0024023: Revamp the OCCT Handle -- automatic
[occt.git] / src / GeomConvert / GeomConvert_1.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 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
18
19
20#include <GeomConvert.ixx>
21
22
23#include <BSplCLib.hxx>
24
25#include <Standard_DomainError.hxx>
26#include <Standard_NotImplemented.hxx>
27
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>
34
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>
49
50#include <GeomAdaptor_Surface.hxx>
51
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>
60
61#include <Precision.hxx>
62#include <gp_Vec.hxx>
63#include <gp_Sphere.hxx>
64#include <gp_Cylinder.hxx>
65#include <gp_Cone.hxx>
66#include <gp_Torus.hxx>
67#include <gp_Pln.hxx>
68#include <gp_Trsf.hxx>
69#include <gp_GTrsf.hxx>
70
71
72
73typedef Geom_Surface Surface;
74typedef Geom_BSplineSurface BSplineSurface;
75typedef Handle(Geom_Curve) Handle(Curve);
76typedef Handle(Geom_BSplineCurve) Handle(BSplineCurve);
77typedef Handle(Geom_BezierSurface) Handle(BezierSurface);
78typedef Handle(Geom_Geometry) Handle(Geometry);
79typedef Handle(Geom_Surface) Handle(Surface);
80typedef Handle(Geom_Plane) Handle(Plane);
81typedef Handle(Geom_CylindricalSurface) Handle(CylindricalSurface);
82typedef Handle(Geom_ConicalSurface) Handle(ConicalSurface);
83typedef Handle(Geom_SphericalSurface) Handle(SphericalSurface);
84typedef Handle(Geom_ToroidalSurface) Handle(ToroidalSurface);
85typedef Handle(Geom_BSplineSurface) Handle(BSplineSurface);
86typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
87typedef Handle(Geom_SurfaceOfLinearExtrusion) Handle(SurfaceOfLinearExtrusion);
88typedef Handle(Geom_RectangularTrimmedSurface)
7331b4ee 89 Handle(RectangularTrimmedSurface);
7fd59977 90
91
92typedef TColStd_Array1OfReal Array1OfReal;
93typedef TColStd_Array2OfReal Array2OfReal;
94typedef TColStd_Array1OfInteger Array1OfInteger;
95typedef TColStd_Array2OfInteger Array2OfInteger;
96typedef TColgp_Array2OfPnt Array2OfPnt;
97typedef TColgp_Array1OfPnt Array1OfPnt;
98
99
100typedef gp_Pnt Pnt;
101
102
103//=======================================================================
104//function : BSplineSurfaceBuilder
105//purpose :
106//=======================================================================
107
108Handle(BSplineSurface) BSplineSurfaceBuilder
109 (const Convert_ElementarySurfaceToBSplineSurface& Convert)
110{
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);
129 }
130 }
131 for (i = 1; i <= NbUKnots; i++) {
132 UKnots (i) = Convert.UKnot (i);
133 UMults (i) = Convert.UMultiplicity (i);
134 }
135 for (i = 1; i <= NbVKnots; i++) {
136 VKnots (i) = Convert.VKnot (i);
137 VMults (i) = Convert.VMultiplicity (i);
138 }
139 TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
7331b4ee 140 UMults, VMults, UDegree, VDegree,
141 Convert.IsUPeriodic(),
142 Convert.IsVPeriodic());
7fd59977 143 return TheSurface;
144}
145
146//=======================================================================
147//function : SplitBSplineSurface
148//purpose :
149//=======================================================================
150
151Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
152 (const Handle(BSplineSurface)& S,
7331b4ee 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 )
7fd59977 159{
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 ||
7331b4ee 170 FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
7fd59977 171
172 Handle(BSplineSurface) S1= Handle(BSplineSurface)::DownCast(S->Copy());
7331b4ee 173
7fd59977 174 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
7331b4ee 175 S1->VKnot(FirstVK),S1->VKnot(LastVK));
7fd59977 176
177 if (S->IsUPeriodic()) {
178 if (!SameUOrientation) S1->UReverse();
179 }
180 else {
181 if (FromUK1 > ToUK2) S1->UReverse();
182 }
183 if (S->IsVPeriodic()) {
184 if (!SameVOrientation) S1->VReverse();
185 }
186 else {
187 if (FromVK1 > ToVK2) S1->VReverse();
188 }
189 return S1;
190}
191
192
193//=======================================================================
194//function : SplitBSplineSurface
195//purpose :
196//=======================================================================
197
198Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
199 (const Handle(BSplineSurface)& S,
7331b4ee 200 const Standard_Integer FromK1,
201 const Standard_Integer ToK2,
202 const Standard_Boolean USplit,
203 const Standard_Boolean SameOrientation )
7fd59977 204{
205 if (FromK1 == ToK2) Standard_DomainError::Raise();
206
207
208 Handle(BSplineSurface) S1 = Handle(BSplineSurface)::DownCast(S->Copy());
209
210 if (USplit) {
211
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();
217
218 S1->Segment( S1->UKnot(FirstUK),
7331b4ee 219 S1->UKnot(LastUK),
220 S1->VKnot(S1->FirstVKnotIndex()),
221 S1->VKnot(S1->LastVKnotIndex()));
7fd59977 222
223 if (S->IsUPeriodic()) {
224 if (!SameOrientation) S1->UReverse();
225 }
226 else {
227 if (FromK1 > ToK2) S1->UReverse();
228 }
229
230 }
231 else {
232
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();
238
239 S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
7331b4ee 240 S1->UKnot(S1->LastUKnotIndex()),
241 S1->VKnot(FirstVK),
242 S1->VKnot(LastVK));
7fd59977 243
244
245 if (S->IsVPeriodic()) {
246 if (!SameOrientation) S1->VReverse();
247 }
248 else {
249 if (FromK1 > ToK2) S1->VReverse();
250 }
251 }
252 return S1;
253}
254
255
256//=======================================================================
257//function : SplitBSplineSurface
258//purpose :
259//=======================================================================
260
261Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
262 (const Handle(BSplineSurface)& S,
7331b4ee 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 )
7fd59977 271{
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);
276
277 Handle (Geom_BSplineSurface) NewSurface
278 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
279
280 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
281
282 if (S->IsUPeriodic()) {
283 if (!SameUOrientation) NewSurface->UReverse();
284 }
285 else {
286 if (FromU1 > ToU2) NewSurface->UReverse();
287 }
288 if (S->IsVPeriodic()) {
289 if (!SameVOrientation) NewSurface->VReverse();
290 }
291 else {
292 if (FromV1 > ToV2) NewSurface->VReverse();
293 }
294 return NewSurface;
295}
296
297
298//=======================================================================
299//function : SplitBSplineSurface
300//purpose :
301//=======================================================================
302
303Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
304 (const Handle(BSplineSurface)& S,
7331b4ee 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 )
7fd59977 310{
311 if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
312 Standard_DomainError::Raise();
313 }
314 Handle(BSplineSurface) NewSurface
315 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
316
317 if (USplit) {
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());
322
323 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
324
325 if (S->IsUPeriodic()) {
326 if (!SameOrientation) NewSurface->UReverse();
327 }
328 else {
329 if (FromParam1 > ToParam2) NewSurface->UReverse();
330 }
331
332 }
333 else {
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);
338
339 NewSurface->Segment(FirstU, LastU, FirstV, LastV);
340
341 if (S->IsUPeriodic()) {
342 if (!SameOrientation) NewSurface->UReverse();
343 }
344 else {
345 if (FromParam1 > ToParam2) NewSurface->UReverse();
346 }
347
348 }
349 return NewSurface;
350}
351
352
353//=======================================================================
354//function : SurfaceToBSplineSurface
355//purpose :
356//=======================================================================
357
7331b4ee 358Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
7fd59977 359 (const Handle(Surface)& Sr)
360{
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);
367
368 //If the surface Sr is infinite stop the computation
369 if (Precision::IsNegativeInfinite(UFirst) ||
7331b4ee 370 Precision::IsPositiveInfinite(ULast) ||
371 Precision::IsNegativeInfinite(VFirst) ||
372 Precision::IsPositiveInfinite(VLast) ) {
373 Standard_DomainError::Raise("");
374 }
375
7fd59977 376 Handle(Geom_BSplineSurface) TheSurface;
377 Handle(Surface) S;
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);
384 }
385 }
386 S = Sr;
387
388 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
389 Handle(Geom_RectangularTrimmedSurface) Strim =
7331b4ee 390 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
391
7fd59977 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 =
7331b4ee 396 Handle(Geom_OffsetSurface)::DownCast(Surf);
7fd59977 397
398 S = OffsetSur->Surface();
399 if (!S.IsNull()) {
7331b4ee 400 Surf = S;
7fd59977 401 }
402 else S = Surf;
403 }
404
405 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
7331b4ee 406 Handle(Geom_RectangularTrimmedSurface) Strim = new
407 (Geom_RectangularTrimmedSurface) (Surf,
408 UFirst, ULast,
409 VFirst, VLast);
410 return SurfaceToBSplineSurface(Strim);
7fd59977 411 }
7331b4ee 412
7fd59977 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);
423 UKnots (1) = U1;
424 UKnots (2) = U2;
425 VKnots (1) = V1;
426 VKnots (2) = V2;
427 UMults (1) = 2;
428 UMults (2) = 2;
429 VMults (1) = 2;
430 VMults (2) = 2;
431 Standard_Integer UDegree = 1;
432 Standard_Integer VDegree = 1;
433 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
7331b4ee 434 VMults, UDegree, VDegree);
7fd59977 435 }
436 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
437 Handle(Geom_CylindricalSurface) TheElSurf=
7331b4ee 438 Handle(Geom_CylindricalSurface)::DownCast(Surf);
439
7fd59977 440 gp_Cylinder Cyl = TheElSurf->Cylinder();
441 if (Strim->IsUClosed()) {
442 Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
443 TheSurface = BSplineSurfaceBuilder (Convert);
444 }
445 else {
446 Convert_CylinderToBSplineSurface
7331b4ee 447 Conv (Cyl, UFirst, ULast, VFirst, VLast);
7fd59977 448 TheSurface = BSplineSurfaceBuilder (Conv);
449 }
450 }
7331b4ee 451
452
7fd59977 453 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
454 Handle(Geom_ConicalSurface) TheElSurf =
7331b4ee 455 Handle(Geom_ConicalSurface)::DownCast(Surf);
7fd59977 456 gp_Cone Co = TheElSurf->Cone();
457 if (Strim->IsUClosed()) {
458 Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
459 TheSurface = BSplineSurfaceBuilder (Convert);
460 }
461 else {
462 Convert_ConeToBSplineSurface
7331b4ee 463 Convert (Co, UFirst, ULast, VFirst, VLast);
7fd59977 464 TheSurface = BSplineSurfaceBuilder (Convert);
465 }
466 }
7331b4ee 467
468
7fd59977 469 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
470 Handle(Geom_SphericalSurface) TheElSurf =
7331b4ee 471 Handle(Geom_SphericalSurface)::DownCast(Surf);
7fd59977 472 gp_Sphere Sph = TheElSurf->Sphere();
473 //OCC217
474 if (Strim->IsUClosed()) {
7331b4ee 475 //if (Strim->IsVClosed()) {
7fd59977 476 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
7331b4ee 477 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
478 TheSurface = BSplineSurfaceBuilder (Convert);
7fd59977 479 }
480 else {
7331b4ee 481 Convert_SphereToBSplineSurface
482 Convert (Sph, UFirst, ULast, VFirst, VLast);
483 TheSurface = BSplineSurfaceBuilder (Convert);
7fd59977 484 }
485 }
7331b4ee 486
487
7fd59977 488 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
489 Handle(Geom_ToroidalSurface) TheElSurf =
7331b4ee 490 Handle(Geom_ToroidalSurface)::DownCast(Surf);
491
7fd59977 492 gp_Torus Tr = TheElSurf->Torus();
493 if (Strim->IsUClosed()) {
494 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
7331b4ee 495 Standard_False);
7fd59977 496 TheSurface = BSplineSurfaceBuilder (Convert);
497 }
498 else if (Strim->IsVClosed()) {
499 Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
500 TheSurface = BSplineSurfaceBuilder (Convert);
501 }
502 else {
503 Convert_TorusToBSplineSurface
7331b4ee 504 Convert (Tr, UFirst, ULast, VFirst, VLast);
7fd59977 505 TheSurface = BSplineSurfaceBuilder (Convert);
506 }
507 }
7331b4ee 508
509
7fd59977 510 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
511 Handle(Geom_SurfaceOfRevolution) Revol =
7331b4ee 512 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
513
7fd59977 514 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
515 Handle(Geom_BSplineCurve) C;
516 if (Strim->IsVClosed()) {
7331b4ee 517 C = GeomConvert::CurveToBSplineCurve (Meridian);
7fd59977 518 }
519 else {
7331b4ee 520 Handle(Geom_TrimmedCurve) CT =
521 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
522 C = GeomConvert::CurveToBSplineCurve (CT);
7fd59977 523 }
524 Standard_Integer NbUPoles, NbUKnots;
525 Standard_Integer NbVPoles, NbVKnots;
526 Standard_Boolean periodic = Standard_False;
527
528 // Poles of meridian = Vpoles
529 NbVPoles = C->NbPoles();
530 TColgp_Array1OfPnt Poles(1, NbVPoles);
531 C->Poles(Poles);
532 TColStd_Array1OfReal Weights( 1, NbVPoles);
533 Weights.Init(1.);
534 if ( C->IsRational()) C->Weights(Weights);
535
536 Standard_Integer nbUSpans;
537 Standard_Real AlfaU;
538 if (Strim->IsUPeriodic()) {
7331b4ee 539 NbUKnots = 4;
540 nbUSpans = 3;
541 AlfaU = M_PI / 3.;
542 NbUPoles = 6;
543 periodic = Standard_True;
7fd59977 544 }
545 else {
7331b4ee 546 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
547 nbUSpans =
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;
7fd59977 552 }
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++) {
7331b4ee 558 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
559 UMults(i) = 2;
7fd59977 560 }
561 if (!periodic) {
7331b4ee 562 UMults(1)++; UMults(NbUKnots)++;
7fd59977 563 }
564 NbVKnots = C->NbKnots();
565 TColStd_Array1OfReal VKnots(1, NbVKnots);
566 TColStd_Array1OfInteger VMults(1, NbVKnots);
567 C->Knots(VKnots);
568 C->Multiplicities(VMults);
569
570 // Compute the poles.
571 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
572 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
573 gp_Trsf Trsf;
574
575 for ( i = 1; i<= NbUPoles; i+=2) {
7331b4ee 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);
580 }
7fd59977 581 }
582 gp_GTrsf Aff;
583 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
584 gp_XYZ coord;
585 for ( j= 1; j<= NbVPoles; j++) {
7331b4ee 586 coord = Poles(j).XYZ();
587 Aff.Transforms(coord);
588 Poles(j).SetXYZ(coord);
7fd59977 589 }
590 for ( i = 2; i<= NbUPoles; i+=2) {
7331b4ee 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);
595 }
7fd59977 596 }
597
598 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
7331b4ee 599 UKnots, VKnots,
600 UMults, VMults,
601 2 , C->Degree(),
602 periodic, C->IsPeriodic());
7fd59977 603
604
605 }
7331b4ee 606
607
7fd59977 608 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
609 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
7331b4ee 610 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
611
7fd59977 612 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
613 Handle(Geom_BSplineCurve) C;
614 if (Strim->IsUClosed()) {
7331b4ee 615 C = GeomConvert::CurveToBSplineCurve (Meridian);
7fd59977 616 }
617 else {
7331b4ee 618 Handle(Geom_TrimmedCurve) CT =
619 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
620 C = GeomConvert::CurveToBSplineCurve (CT);
7fd59977 621 }
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());
625 C->Knots(UKnots);
626 TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
627 C->Multiplicities(UMults);
628 TColStd_Array1OfReal VKnots ( 1, 2);
629 VKnots(1) = VFirst;
630 VKnots(2) = VLast;
631 TColStd_Array1OfInteger VMults ( 1, 2);
632 VMults.Init(2);
7331b4ee 633
7fd59977 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++) {
7331b4ee 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);
7fd59977 641 }
642 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
7331b4ee 643 UMults, VMults,
644 C->Degree(), 1,
645 C->IsPeriodic(), Standard_False);
7fd59977 646 }
647
7331b4ee 648
7fd59977 649 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
7331b4ee 650
7fd59977 651 Handle(Geom_BezierSurface) SBez =
7331b4ee 652 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
653
7fd59977 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);
664 UKnots (1) = 0.0;
665 UKnots (2) = 1.0;
666 UMults (1) = UDegree + 1;
667 UMults (2) = UDegree + 1;
668 VKnots (1) = 0.0;
669 VKnots (2) = 1.0;
670 VMults (1) = VDegree + 1;
671 VMults (2) = VDegree + 1;
672 SBez->Poles (Poles);
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,
7331b4ee 677 UMults, VMults,
678 UDegree, VDegree);
7fd59977 679 }
680 else {
681 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
7331b4ee 682 UMults, VMults,
683 UDegree, VDegree);
7fd59977 684 }
685 }
7331b4ee 686
7fd59977 687 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
688 Handle(Geom_BSplineSurface) BS =
7331b4ee 689 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
7fd59977 690 Standard_Real umin, umax, vmin, vmax;
691 BS->Bounds(umin, umax, vmin, vmax);
692 if (!BS->IsUPeriodic()) {
7331b4ee 693 if (U1 < umin)
694 U1 = umin;
695 if (U2 > umax)
696 U2 = umax;
7fd59977 697 }
698
699 if (!BS->IsVPeriodic()) {
7331b4ee 700 if (V1 < vmin)
701 V1 = vmin;
702 if (V2 > vmax)
703 V2 = vmax;
7fd59977 704 }
ecbdb1b0 705 if (BS->IsUPeriodic() || BS->IsVPeriodic())
706 BS->CheckAndSegment (U1, U2, V1, V2);
707 else
708 BS->Segment (U1, U2, V1, V2);
7fd59977 709 TheSurface = BS;
710 }
711
712 else {
713 Standard_Real Tol3d=1.e-4;
714 Standard_Integer MaxDegree =14, MaxSeg;
715 GeomAbs_Shape cont;
716 GeomAdaptor_Surface AS(Sr);
717 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
7331b4ee 718 cont=GeomAbs_C1;
7fd59977 719 else
7331b4ee 720 cont=GeomAbs_C2;
7fd59977 721 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
722 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
7331b4ee 723 MaxDegree, MaxDegree, MaxSeg, 1);
7fd59977 724 TheSurface = BSpS.Surface();
725 }
726 } // Fin du cas Rectangular::TrimmedSurface
7331b4ee 727
7fd59977 728 else {
729
730 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
731 Handle(Geom_SphericalSurface) TheElSurf =
7331b4ee 732 Handle(Geom_SphericalSurface)::DownCast(S);
733
7fd59977 734 gp_Sphere Sph = TheElSurf->Sphere();
735 Convert_SphereToBSplineSurface Convert(Sph);
736 TheSurface = BSplineSurfaceBuilder(Convert);
737 }
7331b4ee 738
7fd59977 739
740 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
741 Handle(Geom_ToroidalSurface) TheElSurf =
7331b4ee 742 Handle(Geom_ToroidalSurface)::DownCast(S);
743
7fd59977 744 gp_Torus Tr = TheElSurf->Torus();
745 Convert_TorusToBSplineSurface Convert(Tr);
746 TheSurface = BSplineSurfaceBuilder(Convert);
747 }
7331b4ee 748
749
7fd59977 750 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
7331b4ee 751
7fd59977 752 Handle(Geom_SurfaceOfRevolution) Revol =
753 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
7331b4ee 754
7fd59977 755 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
756 Handle(Geom_BSplineCurve) C
7331b4ee 757 = GeomConvert::CurveToBSplineCurve (Meridian);
7fd59977 758
759 Standard_Integer NbUPoles, NbUKnots;
760 Standard_Integer NbVPoles, NbVKnots;
761 Standard_Boolean periodic = Standard_True;
762
763 // Poles of meridian = Vpoles
764 NbVPoles = C->NbPoles();
765 TColgp_Array1OfPnt Poles(1, NbVPoles);
766 C->Poles(Poles);
767 TColStd_Array1OfReal Weights( 1, NbVPoles);
768 Weights.Init(1.);
769 if ( C->IsRational()) C->Weights(Weights);
770
7fd59977 771 Standard_Real AlfaU;
772 NbUKnots = 4;
c6541a0c 773 AlfaU = M_PI / 3.;
7fd59977 774 NbUPoles = 6;
775
776 // Compute Knots and Mults
777 TColStd_Array1OfReal UKnots(1, NbUKnots);
778 TColStd_Array1OfInteger UMults( 1, NbUKnots);
779 Standard_Integer i,j;
780 for ( i = 1; i <= NbUKnots; i++) {
7331b4ee 781 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
782 UMults(i) = 2;
7fd59977 783 }
784 NbVKnots = C->NbKnots();
785 TColStd_Array1OfReal VKnots(1, NbVKnots);
786 TColStd_Array1OfInteger VMults(1, NbVKnots);
787 C->Knots(VKnots);
788 C->Multiplicities(VMults);
789
790 // Compute the poles.
791 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
792 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
793 gp_Trsf Trsf;
794
795 for ( i = 1; i<= NbUPoles; i+=2) {
7331b4ee 796 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
797 for ( j = 1; j <= NbVPoles; j++) {
798 NewPoles(i,j) = Poles(j).Transformed(Trsf);
799 NewWeights(i,j) = Weights(j);
800 }
7fd59977 801 }
802 gp_GTrsf Aff;
803 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
804 gp_XYZ coord;
805 for ( j= 1; j<= NbVPoles; j++) {
7331b4ee 806 coord = Poles(j).XYZ();
807 Aff.Transforms(coord);
808 Poles(j).SetXYZ(coord);
7fd59977 809 }
810 for ( i = 2; i<= NbUPoles; i+=2) {
7331b4ee 811 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
812 for ( j = 1; j <= NbVPoles; j++) {
813 NewPoles(i,j) = Poles(j).Transformed(Trsf);
814 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
815 }
7fd59977 816 }
817
818 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
7331b4ee 819 UKnots, VKnots,
820 UMults, VMults,
821 2 , C->Degree(),
822 periodic, C->IsPeriodic());
7fd59977 823 }
7331b4ee 824
825
7fd59977 826 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
7331b4ee 827
7fd59977 828 Handle(Geom_BezierSurface) SBez =
7331b4ee 829 Handle(Geom_BezierSurface)::DownCast(S);
830
7fd59977 831 Standard_Integer NbUPoles = SBez->NbUPoles();
832 Standard_Integer NbVPoles = SBez->NbVPoles();
833 Standard_Integer UDegree = SBez->UDegree();
834 Standard_Integer VDegree = SBez->VDegree();
835 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
836 TColStd_Array1OfReal UKnots(1, 2);
837 TColStd_Array1OfInteger UMults(1, 2);
838 TColStd_Array1OfReal VKnots(1, 2);
839 TColStd_Array1OfInteger VMults(1, 2);
840 UKnots (1) = 0.0;
841 UKnots (2) = 1.0;
842 UMults (1) = UDegree + 1;
843 UMults (2) = UDegree + 1;
844 VKnots (1) = 0.0;
845 VKnots (2) = 1.0;
846 VMults (1) = VDegree + 1;
847 VMults (2) = VDegree + 1;
848 SBez->Poles (Poles);
849 if (SBez->IsURational() || SBez->IsVRational()) {
7331b4ee 850 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
851 SBez->Weights (Weights);
852 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
853 UMults, VMults,
854 UDegree, VDegree);
7fd59977 855 }
856 else {
7331b4ee 857 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
858 UMults, VMults,
859 UDegree, VDegree);
7fd59977 860 }
861 }
862
863 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
864 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
865 }
866
867 else { // In other cases => Approx
868 Standard_Real Tol3d=1.e-4;
7331b4ee 869 Standard_Integer MaxDegree = 14, MaxSeg;
870 GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
7fd59977 871 GeomAdaptor_Surface AS(Sr);
7331b4ee 872 //
873 if (Sr->IsCNu(2))
874 {
875 ucont=GeomAbs_C2;
876 }
877 else if(Sr->IsCNu(1))
878 {
879 ucont=GeomAbs_C1;
880 }
881 //
882 if (Sr->IsCNv(2))
883 {
884 vcont=GeomAbs_C2;
885 }
886 else if(Sr->IsCNv(1))
887 {
888 vcont=GeomAbs_C1;
889 }
890 //
7fd59977 891 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
7331b4ee 892 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
893 MaxDegree, MaxDegree, MaxSeg, 1);
7fd59977 894 TheSurface = BSpS.Surface();
895 }
896 } // Fin du cas direct
897 return TheSurface;
898}
899
900
901