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