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