0025969: Wrong result obtained by 2d classifier algorithm.
[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)
89 Handle(RectangularTrimmedSurface);
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,
140 UMults, VMults, UDegree, VDegree,
141 Convert.IsUPeriodic(),
142 Convert.IsVPeriodic());
143 return TheSurface;
144}
145
146//=======================================================================
147//function : SplitBSplineSurface
148//purpose :
149//=======================================================================
150
151Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
152 (const Handle(BSplineSurface)& S,
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 )
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 ||
170 FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
171
172 Handle(BSplineSurface) S1= Handle(BSplineSurface)::DownCast(S->Copy());
173
174 S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
175 S1->VKnot(FirstVK),S1->VKnot(LastVK));
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,
200 const Standard_Integer FromK1,
201 const Standard_Integer ToK2,
202 const Standard_Boolean USplit,
203 const Standard_Boolean SameOrientation )
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),
219 S1->UKnot(LastUK),
220 S1->VKnot(S1->FirstVKnotIndex()),
221 S1->VKnot(S1->LastVKnotIndex()));
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()),
240 S1->UKnot(S1->LastUKnotIndex()),
241 S1->VKnot(FirstVK),
242 S1->VKnot(LastVK));
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,
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 )
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,
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 )
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
358 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
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) ||
370 Precision::IsPositiveInfinite(ULast) ||
371 Precision::IsNegativeInfinite(VFirst) ||
372 Precision::IsPositiveInfinite(VLast) ) {
373 Standard_DomainError::Raise("");
374 }
375
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 =
390 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
391
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 =
396 Handle(Geom_OffsetSurface)::DownCast(Surf);
397
398 S = OffsetSur->Surface();
399 if (!S.IsNull()) {
400 Surf = S;
401 }
402 else S = Surf;
403 }
404
405 if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
406 Handle(Geom_RectangularTrimmedSurface) Strim = new
407 (Geom_RectangularTrimmedSurface) (Surf,
408 UFirst, ULast,
409 VFirst, VLast);
410 return SurfaceToBSplineSurface(Strim);
411 }
412
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,
434 VMults, UDegree, VDegree);
435 }
436 else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
437 Handle(Geom_CylindricalSurface) TheElSurf=
438 Handle(Geom_CylindricalSurface)::DownCast(Surf);
439
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
447 Conv (Cyl, UFirst, ULast, VFirst, VLast);
448 TheSurface = BSplineSurfaceBuilder (Conv);
449 }
450 }
451
452
453 else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
454 Handle(Geom_ConicalSurface) TheElSurf =
455 Handle(Geom_ConicalSurface)::DownCast(Surf);
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
463 Convert (Co, UFirst, ULast, VFirst, VLast);
464 TheSurface = BSplineSurfaceBuilder (Convert);
465 }
466 }
467
468
469 else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
470 Handle(Geom_SphericalSurface) TheElSurf =
471 Handle(Geom_SphericalSurface)::DownCast(Surf);
472 gp_Sphere Sph = TheElSurf->Sphere();
473 //OCC217
474 if (Strim->IsUClosed()) {
475 //if (Strim->IsVClosed()) {
476 //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
477 Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
478 TheSurface = BSplineSurfaceBuilder (Convert);
479 }
480 else {
481 Convert_SphereToBSplineSurface
482 Convert (Sph, UFirst, ULast, VFirst, VLast);
483 TheSurface = BSplineSurfaceBuilder (Convert);
484 }
485 }
486
487
488 else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
489 Handle(Geom_ToroidalSurface) TheElSurf =
490 Handle(Geom_ToroidalSurface)::DownCast(Surf);
491
492 gp_Torus Tr = TheElSurf->Torus();
493 if (Strim->IsUClosed()) {
494 Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
495 Standard_False);
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
504 Convert (Tr, UFirst, ULast, VFirst, VLast);
505 TheSurface = BSplineSurfaceBuilder (Convert);
506 }
507 }
508
509
510 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
511 Handle(Geom_SurfaceOfRevolution) Revol =
512 Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
513
514 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
515 Handle(Geom_BSplineCurve) C;
516 if (Strim->IsVClosed()) {
517 C = GeomConvert::CurveToBSplineCurve (Meridian);
518 }
519 else {
520 Handle(Geom_TrimmedCurve) CT =
521 new Geom_TrimmedCurve( Meridian, VFirst, VLast);
522 C = GeomConvert::CurveToBSplineCurve (CT);
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()) {
539 NbUKnots = 4;
540 nbUSpans = 3;
c6541a0c 541 AlfaU = M_PI / 3.;
7fd59977 542 NbUPoles = 6;
543 periodic = Standard_True;
544 }
545 else {
546 // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
547 nbUSpans =
c6541a0c 548 (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
7fd59977 549 AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
550 NbUPoles = 2 * nbUSpans + 1;
551 NbUKnots = nbUSpans + 1;
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++) {
558 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
559 UMults(i) = 2;
560 }
561 if (!periodic) {
562 UMults(1)++; UMults(NbUKnots)++;
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) {
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 }
581 }
582 gp_GTrsf Aff;
583 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
584 gp_XYZ coord;
585 for ( j= 1; j<= NbVPoles; j++) {
586 coord = Poles(j).XYZ();
587 Aff.Transforms(coord);
588 Poles(j).SetXYZ(coord);
589 }
590 for ( i = 2; i<= NbUPoles; i+=2) {
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 }
596 }
597
598 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
599 UKnots, VKnots,
600 UMults, VMults,
601 2 , C->Degree(),
602 periodic, C->IsPeriodic());
603
604
605 }
606
607
608 else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
609 Handle(Geom_SurfaceOfLinearExtrusion) Extru =
610 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
611
612 Handle(Geom_Curve) Meridian = Extru->BasisCurve();
613 Handle(Geom_BSplineCurve) C;
614 if (Strim->IsUClosed()) {
615 C = GeomConvert::CurveToBSplineCurve (Meridian);
616 }
617 else {
618 Handle(Geom_TrimmedCurve) CT =
619 new Geom_TrimmedCurve( Meridian, UFirst, ULast);
620 C = GeomConvert::CurveToBSplineCurve (CT);
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);
633
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++) {
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);
641 }
642 TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
643 UMults, VMults,
644 C->Degree(), 1,
645 C->IsPeriodic(), Standard_False);
646 }
647
648
649 else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
650
651 Handle(Geom_BezierSurface) SBez =
652 Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
653
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,
677 UMults, VMults,
678 UDegree, VDegree);
679 }
680 else {
681 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
682 UMults, VMults,
683 UDegree, VDegree);
684 }
685 }
686
687 else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
688 Handle(Geom_BSplineSurface) BS =
689 Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
690 Standard_Real umin, umax, vmin, vmax;
691 BS->Bounds(umin, umax, vmin, vmax);
692 if (!BS->IsUPeriodic()) {
693 if (U1 < umin)
694 U1 = umin;
695 if (U2 > umax)
696 U2 = umax;
697 }
698
699 if (!BS->IsVPeriodic()) {
700 if (V1 < vmin)
701 V1 = vmin;
702 if (V2 > vmax)
703 V2 = vmax;
704 }
705 BS->Segment (U1, U2, V1, V2);
706 TheSurface = BS;
707 }
708
709 else {
710 Standard_Real Tol3d=1.e-4;
711 Standard_Integer MaxDegree =14, MaxSeg;
712 GeomAbs_Shape cont;
713 GeomAdaptor_Surface AS(Sr);
714 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
715 cont=GeomAbs_C1;
716 else
717 cont=GeomAbs_C2;
718 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
719 GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
720 MaxDegree, MaxDegree, MaxSeg, 1);
721 TheSurface = BSpS.Surface();
722 }
723 } // Fin du cas Rectangular::TrimmedSurface
724
725 else {
726
727 if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
728 Handle(Geom_SphericalSurface) TheElSurf =
729 Handle(Geom_SphericalSurface)::DownCast(S);
730
731 gp_Sphere Sph = TheElSurf->Sphere();
732 Convert_SphereToBSplineSurface Convert(Sph);
733 TheSurface = BSplineSurfaceBuilder(Convert);
734 }
735
736
737 else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
738 Handle(Geom_ToroidalSurface) TheElSurf =
739 Handle(Geom_ToroidalSurface)::DownCast(S);
740
741 gp_Torus Tr = TheElSurf->Torus();
742 Convert_TorusToBSplineSurface Convert(Tr);
743 TheSurface = BSplineSurfaceBuilder(Convert);
744 }
745
746
747 else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
748
749 Handle(Geom_SurfaceOfRevolution) Revol =
750 Handle(Geom_SurfaceOfRevolution)::DownCast(S);
751
752 Handle(Geom_Curve) Meridian = Revol->BasisCurve();
753 Handle(Geom_BSplineCurve) C
754 = GeomConvert::CurveToBSplineCurve (Meridian);
755
756 Standard_Integer NbUPoles, NbUKnots;
757 Standard_Integer NbVPoles, NbVKnots;
758 Standard_Boolean periodic = Standard_True;
759
760 // Poles of meridian = Vpoles
761 NbVPoles = C->NbPoles();
762 TColgp_Array1OfPnt Poles(1, NbVPoles);
763 C->Poles(Poles);
764 TColStd_Array1OfReal Weights( 1, NbVPoles);
765 Weights.Init(1.);
766 if ( C->IsRational()) C->Weights(Weights);
767
7fd59977 768 Standard_Real AlfaU;
769 NbUKnots = 4;
c6541a0c 770 AlfaU = M_PI / 3.;
7fd59977 771 NbUPoles = 6;
772
773 // Compute Knots and Mults
774 TColStd_Array1OfReal UKnots(1, NbUKnots);
775 TColStd_Array1OfInteger UMults( 1, NbUKnots);
776 Standard_Integer i,j;
777 for ( i = 1; i <= NbUKnots; i++) {
778 UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
779 UMults(i) = 2;
780 }
781 NbVKnots = C->NbKnots();
782 TColStd_Array1OfReal VKnots(1, NbVKnots);
783 TColStd_Array1OfInteger VMults(1, NbVKnots);
784 C->Knots(VKnots);
785 C->Multiplicities(VMults);
786
787 // Compute the poles.
788 TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
789 TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
790 gp_Trsf Trsf;
791
792 for ( i = 1; i<= NbUPoles; i+=2) {
793 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
794 for ( j = 1; j <= NbVPoles; j++) {
795 NewPoles(i,j) = Poles(j).Transformed(Trsf);
796 NewWeights(i,j) = Weights(j);
797 }
798 }
799 gp_GTrsf Aff;
800 Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
801 gp_XYZ coord;
802 for ( j= 1; j<= NbVPoles; j++) {
803 coord = Poles(j).XYZ();
804 Aff.Transforms(coord);
805 Poles(j).SetXYZ(coord);
806 }
807 for ( i = 2; i<= NbUPoles; i+=2) {
808 Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
809 for ( j = 1; j <= NbVPoles; j++) {
810 NewPoles(i,j) = Poles(j).Transformed(Trsf);
811 NewWeights(i,j) = Weights(j) * Cos(AlfaU);
812 }
813 }
814
815 TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
816 UKnots, VKnots,
817 UMults, VMults,
818 2 , C->Degree(),
819 periodic, C->IsPeriodic());
820 }
821
822
823 else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
824
825 Handle(Geom_BezierSurface) SBez =
826 Handle(Geom_BezierSurface)::DownCast(S);
827
828 Standard_Integer NbUPoles = SBez->NbUPoles();
829 Standard_Integer NbVPoles = SBez->NbVPoles();
830 Standard_Integer UDegree = SBez->UDegree();
831 Standard_Integer VDegree = SBez->VDegree();
832 TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
833 TColStd_Array1OfReal UKnots(1, 2);
834 TColStd_Array1OfInteger UMults(1, 2);
835 TColStd_Array1OfReal VKnots(1, 2);
836 TColStd_Array1OfInteger VMults(1, 2);
837 UKnots (1) = 0.0;
838 UKnots (2) = 1.0;
839 UMults (1) = UDegree + 1;
840 UMults (2) = UDegree + 1;
841 VKnots (1) = 0.0;
842 VKnots (2) = 1.0;
843 VMults (1) = VDegree + 1;
844 VMults (2) = VDegree + 1;
845 SBez->Poles (Poles);
846 if (SBez->IsURational() || SBez->IsVRational()) {
847 TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
848 SBez->Weights (Weights);
849 TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
850 UMults, VMults,
851 UDegree, VDegree);
852 }
853 else {
854 TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
855 UMults, VMults,
856 UDegree, VDegree);
857 }
858 }
859
860 else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
861 TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
862 }
863
864 else { // In other cases => Approx
865 Standard_Real Tol3d=1.e-4;
866 Standard_Integer MaxDegree =14, MaxSeg;
867 GeomAbs_Shape cont;
868 GeomAdaptor_Surface AS(Sr);
869 if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
870 cont=GeomAbs_C1;
871 else
872 cont=GeomAbs_C2;
873 MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
874 GeomConvert_ApproxSurface BSpS(Sr,Tol3d,cont,cont,
875 MaxDegree,MaxDegree,MaxSeg,1);
876 TheSurface = BSpS.Surface();
877 }
878 } // Fin du cas direct
879 return TheSurface;
880}
881
882
883