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