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 | |
73 | typedef Geom_Surface Surface; |
74 | typedef Geom_BSplineSurface BSplineSurface; |
75 | typedef Handle(Geom_Curve) Handle(Curve); |
76 | typedef Handle(Geom_BSplineCurve) Handle(BSplineCurve); |
77 | typedef Handle(Geom_BezierSurface) Handle(BezierSurface); |
78 | typedef Handle(Geom_Geometry) Handle(Geometry); |
79 | typedef Handle(Geom_Surface) Handle(Surface); |
80 | typedef Handle(Geom_Plane) Handle(Plane); |
81 | typedef Handle(Geom_CylindricalSurface) Handle(CylindricalSurface); |
82 | typedef Handle(Geom_ConicalSurface) Handle(ConicalSurface); |
83 | typedef Handle(Geom_SphericalSurface) Handle(SphericalSurface); |
84 | typedef Handle(Geom_ToroidalSurface) Handle(ToroidalSurface); |
85 | typedef Handle(Geom_BSplineSurface) Handle(BSplineSurface); |
86 | typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution); |
87 | typedef Handle(Geom_SurfaceOfLinearExtrusion) Handle(SurfaceOfLinearExtrusion); |
88 | typedef Handle(Geom_RectangularTrimmedSurface) |
89 | Handle(RectangularTrimmedSurface); |
90 | |
91 | |
92 | typedef TColStd_Array1OfReal Array1OfReal; |
93 | typedef TColStd_Array2OfReal Array2OfReal; |
94 | typedef TColStd_Array1OfInteger Array1OfInteger; |
95 | typedef TColStd_Array2OfInteger Array2OfInteger; |
96 | typedef TColgp_Array2OfPnt Array2OfPnt; |
97 | typedef TColgp_Array1OfPnt Array1OfPnt; |
98 | |
99 | |
100 | typedef gp_Pnt Pnt; |
101 | |
102 | |
103 | //======================================================================= |
104 | //function : BSplineSurfaceBuilder |
105 | //purpose : |
106 | //======================================================================= |
107 | |
108 | Handle(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 | |
151 | Handle(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 | |
198 | Handle(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 | |
261 | Handle(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 | |
303 | Handle(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 | |