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 | |
424cd6bb |
15 | |
42cf5bc1 |
16 | #include <Bnd_Box2d.hxx> |
17 | #include <BndLib_Add2dCurve.hxx> |
18 | #include <BRepGProp_Face.hxx> |
7fd59977 |
19 | #include <Geom2d_BezierCurve.hxx> |
20 | #include <Geom2d_BSplineCurve.hxx> |
42cf5bc1 |
21 | #include <Geom2d_Line.hxx> |
424cd6bb |
22 | #include <Geom_BezierSurface.hxx> |
42cf5bc1 |
23 | #include <Geom_BSplineCurve.hxx> |
424cd6bb |
24 | #include <Geom_BSplineSurface.hxx> |
25 | #include <Geom_SurfaceOfLinearExtrusion.hxx> |
7fd59977 |
26 | #include <GeomAdaptor_Curve.hxx> |
42cf5bc1 |
27 | #include <gp_Pnt.hxx> |
28 | #include <gp_Pnt2d.hxx> |
29 | #include <gp_Vec.hxx> |
30 | #include <gp_Vec2d.hxx> |
31 | #include <math.hxx> |
7fd59977 |
32 | #include <Precision.hxx> |
42cf5bc1 |
33 | #include <TopoDS.hxx> |
34 | #include <TopoDS_Edge.hxx> |
35 | #include <TopoDS_Face.hxx> |
7fd59977 |
36 | |
f4dee9bb |
37 | static const Standard_Real Epsilon1 = Epsilon(1.); |
38 | |
7fd59977 |
39 | //======================================================================= |
40 | //function : UIntegrationOrder |
41 | //purpose : |
42 | //======================================================================= |
7fd59977 |
43 | Standard_Integer BRepGProp_Face::UIntegrationOrder() const { |
7fd59977 |
44 | |
424cd6bb |
45 | Standard_Integer Nu; |
46 | switch (mySurface.GetType()) |
47 | { |
7fd59977 |
48 | |
424cd6bb |
49 | case GeomAbs_Plane : |
50 | Nu =4; |
51 | break; |
7fd59977 |
52 | |
424cd6bb |
53 | case GeomAbs_BezierSurface : |
54 | { |
55 | Nu = (*((Handle(Geom_BezierSurface)*)&((mySurface.Surface()).Surface())))->UDegree()+1; |
56 | Nu = Max(4,Nu); |
57 | } |
58 | break; |
59 | case GeomAbs_BSplineSurface : |
60 | { |
61 | Standard_Integer a = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->UDegree()+1; |
62 | Standard_Integer b = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->NbUKnots()-1; |
63 | Nu = Max(4,a*b); |
64 | } |
65 | break; |
66 | |
67 | default : |
68 | Nu = 9; |
69 | break; |
70 | } |
7fd59977 |
71 | return Max(8,2*Nu); |
72 | } |
73 | |
74 | //======================================================================= |
75 | //function : VIntegrationOrder |
76 | //purpose : |
77 | //======================================================================= |
78 | |
79 | Standard_Integer BRepGProp_Face::VIntegrationOrder() const |
80 | { |
81 | Standard_Integer Nv; |
82 | switch (mySurface.GetType()) { |
83 | |
84 | case GeomAbs_Plane : |
85 | Nv = 4; |
86 | break; |
87 | |
88 | case GeomAbs_BezierSurface : |
89 | { |
90 | Nv = (*((Handle(Geom_BezierSurface)*)&((mySurface.Surface()).Surface())))->VDegree()+1; |
91 | Nv = Max(4,Nv); |
92 | } |
93 | break; |
94 | |
95 | case GeomAbs_BSplineSurface : |
96 | { |
97 | Standard_Integer a = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->VDegree()+1; |
98 | Standard_Integer b = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->NbVKnots()-1; |
99 | Nv = Max(4,a*b); |
100 | } |
101 | break; |
102 | |
103 | default : |
104 | Nv = 9; |
105 | break; |
106 | } |
107 | return Max(8,2*Nv); |
108 | } |
109 | |
110 | //======================================================================= |
111 | //function : IntegrationOrder |
112 | //purpose : |
113 | //======================================================================= |
114 | |
115 | Standard_Integer BRepGProp_Face::IntegrationOrder() const |
116 | { |
117 | Standard_Integer N; |
118 | |
119 | switch (myCurve.GetType()) { |
120 | |
121 | case GeomAbs_Line : |
122 | N = 2; |
123 | break; |
124 | |
125 | case GeomAbs_Circle : |
126 | case GeomAbs_Ellipse : |
127 | case GeomAbs_Hyperbola : |
128 | N = 9; |
129 | break; |
130 | |
131 | case GeomAbs_Parabola : |
132 | N = 9; |
133 | break; |
134 | |
135 | case GeomAbs_BezierCurve : |
136 | { |
137 | N = (*((Handle(Geom2d_BezierCurve)*)&(myCurve.Curve())))->Degree() + 1; |
138 | } |
139 | break; |
140 | |
141 | case GeomAbs_BSplineCurve : |
142 | { |
143 | Standard_Integer a = (*((Handle(Geom2d_BSplineCurve)*)&(myCurve.Curve())))->Degree() + 1; |
144 | Standard_Integer b = (*((Handle(Geom2d_BSplineCurve)*)&(myCurve.Curve())))->NbKnots() - 1; |
145 | N = a * b; |
146 | } |
147 | break; |
148 | |
149 | default : |
150 | N = 9; |
151 | break; |
152 | } |
153 | |
154 | return Max(4,2*N); |
155 | } |
156 | |
157 | //======================================================================= |
158 | //function : Bounds |
159 | //purpose : |
160 | //======================================================================= |
161 | |
162 | void BRepGProp_Face::Bounds(Standard_Real& U1, |
163 | Standard_Real& U2, |
164 | Standard_Real& V1, |
165 | Standard_Real& V2)const |
166 | { |
167 | U1 = mySurface.FirstUParameter(); |
168 | U2 = mySurface.LastUParameter(); |
169 | V1 = mySurface.FirstVParameter(); |
170 | V2 = mySurface.LastVParameter(); |
171 | } |
172 | |
173 | //======================================================================= |
174 | //function : Load |
175 | //purpose : |
176 | //======================================================================= |
177 | |
8ff2e494 |
178 | bool BRepGProp_Face::Load(const TopoDS_Edge& E) |
7fd59977 |
179 | { |
180 | Standard_Real a,b; |
8ff2e494 |
181 | Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E, mySurface.Face(), a,b); |
182 | if (C.IsNull()) |
183 | { |
184 | return false; |
185 | } |
7fd59977 |
186 | if (E.Orientation() == TopAbs_REVERSED) { |
187 | Standard_Real x = a; |
188 | a = C->ReversedParameter(b); |
189 | b = C->ReversedParameter(x); |
190 | C = C->Reversed(); |
191 | } |
192 | myCurve.Load(C,a,b); |
8ff2e494 |
193 | return true; |
7fd59977 |
194 | } |
195 | |
196 | //======================================================================= |
197 | //function : Load |
198 | //purpose : |
199 | //======================================================================= |
200 | |
201 | void BRepGProp_Face::Load(const TopoDS_Face& F) |
202 | { |
203 | TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD); |
204 | mySurface.Initialize(TopoDS::Face(aLocalShape)); |
205 | // mySurface.Initialize(TopoDS::Face(F.Oriented(TopAbs_FORWARD))); |
206 | mySReverse = (F.Orientation() == TopAbs_REVERSED); |
207 | } |
208 | |
209 | //======================================================================= |
210 | //function : Normal |
211 | //purpose : |
212 | //======================================================================= |
213 | |
214 | void BRepGProp_Face::Normal (const Standard_Real U, |
215 | const Standard_Real V, |
216 | gp_Pnt &P, |
217 | gp_Vec &VNor) const |
218 | { |
219 | gp_Vec D1U,D1V; |
220 | mySurface.D1(U,V,P,D1U,D1V); |
221 | VNor = D1U.Crossed(D1V); |
222 | if (mySReverse) VNor.Reverse(); |
223 | |
224 | } |
225 | |
226 | // APO 17.04.2002 (OCC104) |
227 | // This is functions that calculate coeff. to optimize "integration order". |
228 | //They had been produced experementally for some hard example. |
229 | static Standard_Real AS = -0.15, AL = -0.50, B = 1.0, C = 0.75, D = 0.25; |
230 | static inline Standard_Real SCoeff(const Standard_Real Eps){ |
231 | return Eps < 0.1? AS*(B+Log10(Eps)) + C: C; |
232 | } |
233 | static inline Standard_Real LCoeff(const Standard_Real Eps){ |
234 | return Eps < 0.1? AL*(B+Log10(Eps)) + D: D; |
235 | } |
236 | |
237 | //======================================================================= |
238 | //function : SIntOrder |
239 | //purpose : |
240 | //======================================================================= |
241 | |
242 | Standard_Integer BRepGProp_Face::SIntOrder(const Standard_Real Eps) const |
243 | { |
244 | Standard_Integer Nv, Nu; |
245 | switch (mySurface.GetType()) { |
246 | case GeomAbs_Plane: |
247 | Nu = 1; Nv = 1; break; |
248 | case GeomAbs_Cylinder: |
249 | Nu = 2; Nv = 1; break; |
250 | case GeomAbs_Cone: |
251 | Nu = 2; Nv = 1; break; |
252 | case GeomAbs_Sphere: |
253 | Nu = 2; Nv = 2; break; |
254 | case GeomAbs_Torus: |
255 | Nu = 2; Nv = 2; break; |
256 | case GeomAbs_BezierSurface: |
257 | Nv = (*((Handle(Geom_BezierSurface)*)&((mySurface.Surface()).Surface())))->VDegree(); |
258 | Nu = (*((Handle(Geom_BezierSurface)*)&((mySurface.Surface()).Surface())))->UDegree(); |
259 | break; |
260 | case GeomAbs_BSplineSurface: |
261 | Nv = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->VDegree(); |
262 | Nu = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->UDegree(); |
263 | break; |
264 | default: |
265 | Nu = 2; Nv = 2; break; |
266 | } |
267 | return Min(RealToInt(Ceiling(SCoeff(Eps)*Max((Nu+1),(Nv+1)))), math::GaussPointsMax()); |
268 | } |
269 | |
270 | //======================================================================= |
271 | //function : SUIntSubs |
272 | //purpose : |
273 | //======================================================================= |
274 | |
275 | Standard_Integer BRepGProp_Face::SUIntSubs() const |
276 | { |
277 | Standard_Integer N; |
278 | switch (mySurface.GetType()) { |
279 | case GeomAbs_Plane: |
280 | N = 2; break; |
281 | case GeomAbs_Cylinder: |
282 | N = 4; break; |
283 | case GeomAbs_Cone: |
284 | N = 4; break; |
285 | case GeomAbs_Sphere: |
286 | N = 4; break; |
287 | case GeomAbs_Torus: |
288 | N = 4; break; |
289 | case GeomAbs_BezierSurface: |
290 | N = 2; break; |
291 | case GeomAbs_BSplineSurface: |
292 | N = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->NbUKnots(); break; |
293 | default: |
294 | N = 2; break; |
295 | } |
296 | return N - 1; |
297 | } |
298 | |
299 | //======================================================================= |
300 | //function : SVIntSubs |
301 | //purpose : |
302 | //======================================================================= |
303 | |
304 | Standard_Integer BRepGProp_Face::SVIntSubs() const |
305 | { |
306 | Standard_Integer N; |
307 | switch (mySurface.GetType()) { |
308 | case GeomAbs_Plane: |
309 | N = 2; break; |
310 | case GeomAbs_Cylinder: |
311 | N = 2; break; |
312 | case GeomAbs_Cone: |
313 | N = 2; break; |
314 | case GeomAbs_Sphere: |
315 | N = 3; break; |
316 | case GeomAbs_Torus: |
317 | N = 4; break; |
318 | case GeomAbs_BezierSurface: |
319 | N = 2; break; |
320 | case GeomAbs_BSplineSurface: |
321 | N = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->NbVKnots(); |
322 | break; |
323 | default: |
324 | N = 2; break; |
325 | } |
326 | return N - 1; |
327 | } |
328 | |
329 | //======================================================================= |
330 | //function : UKnots |
331 | //purpose : |
332 | //======================================================================= |
333 | |
334 | void BRepGProp_Face::UKnots(TColStd_Array1OfReal& Knots) const |
335 | { |
336 | switch (mySurface.GetType()) { |
337 | case GeomAbs_Plane: |
338 | Knots(1) = mySurface.FirstUParameter(); Knots(2) = mySurface.LastUParameter(); |
339 | break; |
340 | case GeomAbs_Cylinder: |
341 | case GeomAbs_Cone: |
342 | case GeomAbs_Sphere: |
343 | case GeomAbs_Torus: |
c6541a0c |
344 | Knots(1) = 0.0; Knots(2) = M_PI*2.0/3.0; Knots(3) = M_PI*4.0/3.0; Knots(4) = M_PI*6.0/3.0; |
7fd59977 |
345 | break; |
346 | case GeomAbs_BSplineSurface: |
347 | (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->UKnots(Knots); |
348 | break; |
349 | default: |
350 | Knots(1) = mySurface.FirstUParameter(); Knots(2) = mySurface.LastUParameter(); |
351 | break; |
352 | } |
353 | } |
354 | |
355 | //======================================================================= |
356 | //function : VKnots |
357 | //purpose : |
358 | //======================================================================= |
359 | |
360 | void BRepGProp_Face::VKnots(TColStd_Array1OfReal& Knots) const |
361 | { |
362 | switch (mySurface.GetType()) { |
363 | case GeomAbs_Plane: |
364 | case GeomAbs_Cylinder: |
365 | case GeomAbs_Cone: |
366 | Knots(1) = mySurface.FirstUParameter(); Knots(2) = mySurface.LastUParameter(); |
367 | break; |
368 | case GeomAbs_Sphere: |
c6541a0c |
369 | Knots(1) = -M_PI/2.0; Knots(2) = 0.0; Knots(3) = +M_PI/2.0; |
7fd59977 |
370 | break; |
371 | case GeomAbs_Torus: |
c6541a0c |
372 | Knots(1) = 0.0; Knots(2) = M_PI*2.0/3.0; Knots(3) = M_PI*4.0/3.0; Knots(4) = M_PI*6.0/3.0; |
7fd59977 |
373 | break; |
374 | case GeomAbs_BSplineSurface: |
375 | (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->VKnots(Knots); |
376 | break; |
377 | default: |
378 | Knots(1) = mySurface.FirstUParameter(); Knots(2) = mySurface.LastUParameter(); |
379 | break; |
380 | } |
381 | } |
382 | |
383 | //======================================================================= |
384 | //function : LIntOrder |
385 | //purpose : |
386 | //======================================================================= |
387 | |
388 | Standard_Integer BRepGProp_Face::LIntOrder(const Standard_Real Eps) const |
389 | { |
390 | Bnd_Box2d aBox; |
6e6cd5d9 |
391 | |
392 | BndLib_Add2dCurve::Add(myCurve, 1.e-7, aBox); |
7fd59977 |
393 | Standard_Real aXmin, aXmax, aYmin, aYmax; |
394 | aBox.Get(aXmin, aYmin, aXmax, aYmax); |
395 | Standard_Real aVmin = mySurface.FirstVParameter(); |
396 | Standard_Real aVmax = mySurface.LastVParameter(); |
397 | |
f4dee9bb |
398 | Standard_Real dv = (aVmax-aVmin); |
399 | Standard_Real anR = (dv > Epsilon1 ? Min ((aYmax - aYmin) / dv, 1.) : 1.); |
7fd59977 |
400 | |
401 | // Standard_Integer anRInt = Max(RealToInt(Ceiling(SVIntSubs()*anR)), 2); |
402 | Standard_Integer anRInt = RealToInt(Ceiling(SVIntSubs()*anR)); |
403 | Standard_Integer aLSubs = LIntSubs(); |
404 | |
405 | |
406 | // Standard_Real NL, NS = Max(SIntOrder(1.0)*anRInt/LIntSubs(), 1); |
407 | Standard_Real NL, NS = Max(SIntOrder(1.)*anRInt/aLSubs, 1); |
408 | switch (myCurve.GetType()) { |
409 | case GeomAbs_Line: |
410 | NL = 1; break; |
411 | case GeomAbs_Circle: |
412 | NL = 2 * 3; break; //correction for the spans of converted curve |
413 | case GeomAbs_Ellipse: |
414 | NL = 2 * 3; break; // |
415 | case GeomAbs_Parabola: |
416 | NL = 2 * 3; break; |
417 | case GeomAbs_Hyperbola: |
418 | NL = 3 * 3; break; |
419 | case GeomAbs_BezierCurve: |
420 | NL = (*((Handle(Geom2d_BezierCurve)*)&(myCurve.Curve())))->Degree(); |
421 | break; |
422 | case GeomAbs_BSplineCurve: |
423 | NL = (*((Handle(Geom2d_BSplineCurve)*)&(myCurve.Curve())))->Degree(); |
424 | break; |
425 | default: |
426 | NL = 3 * 3; break; |
427 | } |
428 | |
429 | NL = Max(NL, NS); |
430 | |
431 | Standard_Integer nn = |
432 | RealToInt (aLSubs <= 4 ? Ceiling(LCoeff(Eps)*(NL+1)) : NL+1); |
433 | |
434 | //return Min(RealToInt(Ceiling(LCoeff(Eps)*(NL+1)*NS)), math::GaussPointsMax()); |
435 | return Min(nn, math::GaussPointsMax()); |
436 | } |
437 | |
438 | //======================================================================= |
439 | //function : LIntSubs |
440 | //purpose : |
441 | //======================================================================= |
442 | |
443 | Standard_Integer BRepGProp_Face::LIntSubs() const |
444 | { |
445 | Standard_Integer N; |
446 | switch (myCurve.GetType()) { |
447 | case GeomAbs_Line: |
448 | N = 2; break; |
449 | case GeomAbs_Circle: |
450 | case GeomAbs_Ellipse: |
451 | N = 4; break; |
452 | case GeomAbs_Parabola: |
453 | case GeomAbs_Hyperbola: |
454 | N = 2; break; |
455 | case GeomAbs_BSplineCurve: |
456 | N = (*((Handle(Geom2d_BSplineCurve)*)&(myCurve.Curve())))->NbKnots(); |
457 | break; |
458 | default: |
459 | N = 2; break; |
460 | } |
461 | return N - 1; |
462 | } |
463 | |
464 | //======================================================================= |
465 | //function : LKnots |
466 | //purpose : |
467 | //======================================================================= |
468 | |
469 | void BRepGProp_Face::LKnots(TColStd_Array1OfReal& Knots) const |
470 | { |
471 | switch (myCurve.GetType()) { |
472 | case GeomAbs_Line: |
473 | Knots(1) = myCurve.FirstParameter(); Knots(2) = myCurve.LastParameter(); |
474 | break; |
475 | case GeomAbs_Circle: |
476 | case GeomAbs_Ellipse: |
89aebdea |
477 | Knots(1) = 0.0; Knots(2) = M_PI*2.0/3.0; Knots(3) = M_PI*4.0/3.0; Knots(4) = M_PI*6.0/3.0; |
7fd59977 |
478 | break; |
479 | case GeomAbs_Parabola: |
480 | case GeomAbs_Hyperbola: |
481 | Knots(1) = myCurve.FirstParameter(); Knots(2) = myCurve.LastParameter(); |
482 | break; |
483 | case GeomAbs_BSplineCurve: |
484 | (*((Handle(Geom2d_BSplineCurve)*)&(myCurve.Curve())))->Knots(Knots); |
485 | break; |
486 | default: |
487 | Knots(1) = myCurve.FirstParameter(); Knots(2) = myCurve.LastParameter(); |
488 | break; |
489 | } |
490 | } |
491 | |
492 | //======================================================================= |
493 | //function : Load |
494 | //purpose : |
495 | //======================================================================= |
496 | |
497 | void BRepGProp_Face::Load(const Standard_Boolean IsFirstParam, |
498 | const GeomAbs_IsoType theIsoType) |
499 | { |
500 | Standard_Real aLen; |
501 | Standard_Real aU1; |
502 | Standard_Real aU2; |
503 | Standard_Real aV1; |
504 | Standard_Real aV2; |
505 | gp_Pnt2d aLoc; |
506 | gp_Dir2d aDir; |
507 | |
508 | Bounds(aU1, aU2, aV1, aV2); |
509 | |
510 | if (theIsoType == GeomAbs_IsoU) { |
511 | aLen = aV2 - aV1; |
512 | |
513 | if (IsFirstParam) { |
514 | aLoc.SetCoord(aU1, aV2); |
515 | aDir.SetCoord(0., -1.); |
516 | } else { |
517 | aLoc.SetCoord(aU2, aV1); |
518 | aDir.SetCoord(0., 1.); |
519 | } |
520 | } else if (theIsoType == GeomAbs_IsoV) { |
521 | aLen = aU2 - aU1; |
522 | |
523 | if (IsFirstParam) { |
524 | aLoc.SetCoord(aU1, aV1); |
525 | aDir.SetCoord(1., 0.); |
526 | } else { |
527 | aLoc.SetCoord(aU2, aV2); |
528 | aDir.SetCoord(-1., 0.); |
529 | } |
530 | } else |
531 | return; |
532 | |
533 | Handle(Geom2d_Curve) aLin = new Geom2d_Line(aLoc, aDir); |
534 | |
535 | myCurve.Load(aLin, 0., aLen); |
536 | } |
537 | |
538 | //======================================================================= |
539 | //function : GetRealKnots |
540 | //purpose : |
541 | //======================================================================= |
542 | |
543 | static void GetRealKnots(const Standard_Real theMin, |
544 | const Standard_Real theMax, |
545 | const Handle(TColStd_HArray1OfReal) &theKnots, |
546 | Handle(TColStd_HArray1OfReal) &theRealKnots) |
547 | { |
548 | Standard_Integer i = theKnots->Lower() - 1; |
549 | Standard_Integer iU = theKnots->Upper(); |
550 | Standard_Integer aStartI = 0; |
551 | Standard_Integer aEndI = 0; |
552 | Standard_Real aTol = Precision::Confusion(); |
553 | |
554 | while (++i < iU) { |
555 | if (aStartI == 0 && theKnots->Value(i) > theMin + aTol) |
556 | aStartI = i; |
557 | |
558 | if (aEndI == 0 && theKnots->Value(i + 1) > theMax - aTol) |
559 | aEndI = i; |
560 | |
561 | if (aStartI != 0 && aEndI != 0) |
562 | break; |
563 | } |
564 | |
565 | if (aStartI == 0) |
566 | aStartI = iU; |
567 | |
568 | Standard_Integer aNbNode = Max(0, aEndI - aStartI + 1) + 2; |
569 | Standard_Integer j; |
570 | |
571 | theRealKnots = new TColStd_HArray1OfReal(1, aNbNode); |
572 | theRealKnots->SetValue(1, theMin); |
573 | theRealKnots->SetValue(aNbNode, theMax); |
574 | |
575 | |
576 | for (i = 2, j = aStartI; j <= aEndI; i++, j++) |
577 | theRealKnots->SetValue(i, theKnots->Value(j)); |
578 | } |
579 | |
580 | //======================================================================= |
581 | //function : GetCurveKnots |
582 | //purpose : |
583 | //======================================================================= |
584 | |
585 | static void GetCurveKnots(const Standard_Real theMin, |
586 | const Standard_Real theMax, |
587 | const Geom2dAdaptor_Curve &theCurve, |
588 | Handle(TColStd_HArray1OfReal) &theKnots) |
589 | { |
590 | Standard_Boolean isSBSpline = theCurve.GetType() == GeomAbs_BSplineCurve; |
591 | |
592 | if (isSBSpline) { |
593 | Handle(Geom2d_BSplineCurve) aCrv; |
594 | Standard_Integer aNbKnots; |
595 | Handle(TColStd_HArray1OfReal) aCrvKnots; |
596 | |
597 | aCrv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve.Curve()); |
598 | aNbKnots = aCrv->NbKnots(); |
599 | aCrvKnots = new TColStd_HArray1OfReal(1, aNbKnots); |
600 | aCrv->Knots(aCrvKnots->ChangeArray1()); |
601 | GetRealKnots(theMin, theMax, aCrvKnots, theKnots); |
602 | } else { |
603 | theKnots = new TColStd_HArray1OfReal(1, 2); |
604 | theKnots->SetValue(1, theMin); |
605 | theKnots->SetValue(2, theMax); |
606 | } |
607 | } |
608 | |
7fd59977 |
609 | //======================================================================= |
610 | //function : GetUKnots |
611 | //purpose : |
612 | //======================================================================= |
613 | |
614 | void BRepGProp_Face::GetUKnots |
615 | (const Standard_Real theUMin, |
616 | const Standard_Real theUMax, |
617 | Handle(TColStd_HArray1OfReal) &theUKnots) const |
618 | { |
619 | Standard_Boolean isSBSpline = mySurface.GetType() == GeomAbs_BSplineSurface; |
620 | Standard_Boolean isCBSpline = Standard_False; |
621 | |
622 | if (!isSBSpline) { |
623 | // Check the basis curve of the surface of linear extrusion. |
624 | if (mySurface.GetType() == GeomAbs_SurfaceOfExtrusion) { |
625 | GeomAdaptor_Curve aCurve; |
626 | Handle(Geom_Surface) aSurf = mySurface.Surface().Surface(); |
627 | |
c5f3a425 |
628 | aCurve.Load(Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (aSurf)->BasisCurve()); |
7fd59977 |
629 | isCBSpline = aCurve.GetType() == GeomAbs_BSplineCurve; |
630 | } |
631 | } |
632 | |
633 | if (myIsUseSpan && (isSBSpline || isCBSpline)) { |
634 | // Using span decomposition for BSpline. |
635 | Handle(TColStd_HArray1OfReal) aKnots; |
636 | Standard_Integer aNbKnots; |
637 | |
638 | if (isSBSpline) { |
639 | // Get U knots of BSpline surface. |
640 | Handle(Geom_Surface) aSurf = mySurface.Surface().Surface(); |
641 | Handle(Geom_BSplineSurface) aBSplSurf; |
642 | |
643 | aBSplSurf = Handle(Geom_BSplineSurface)::DownCast(aSurf); |
644 | aNbKnots = aBSplSurf->NbUKnots(); |
645 | aKnots = new TColStd_HArray1OfReal(1, aNbKnots); |
646 | aBSplSurf->UKnots(aKnots->ChangeArray1()); |
647 | } else { |
648 | // Get U knots of BSpline curve - basis curve of |
649 | // the surface of linear extrusion. |
650 | GeomAdaptor_Curve aCurve; |
651 | Handle(Geom_Surface) aSurf = mySurface.Surface().Surface(); |
652 | Handle(Geom_BSplineCurve) aBSplCurve; |
653 | |
c5f3a425 |
654 | aCurve.Load(Handle(Geom_SurfaceOfLinearExtrusion)::DownCast (aSurf)->BasisCurve()); |
7fd59977 |
655 | aBSplCurve = aCurve.BSpline(); |
656 | aNbKnots = aBSplCurve->NbKnots(); |
657 | aKnots = new TColStd_HArray1OfReal(1, aNbKnots); |
658 | aBSplCurve->Knots(aKnots->ChangeArray1()); |
659 | } |
660 | |
661 | // Compute number of knots inside theUMin and theUMax. |
662 | GetRealKnots(theUMin, theUMax, aKnots, theUKnots); |
663 | } else { |
664 | // No span decomposition. |
665 | theUKnots = new TColStd_HArray1OfReal(1, 2); |
666 | theUKnots->SetValue(1, theUMin); |
667 | theUKnots->SetValue(2, theUMax); |
668 | } |
669 | } |
670 | |
671 | //======================================================================= |
672 | //function : GetTKnots |
673 | //purpose : |
674 | //======================================================================= |
675 | |
676 | void BRepGProp_Face::GetTKnots |
677 | (const Standard_Real theTMin, |
678 | const Standard_Real theTMax, |
679 | Handle(TColStd_HArray1OfReal) &theTKnots) const |
680 | { |
681 | Standard_Boolean isBSpline = mySurface.GetType() == GeomAbs_BSplineSurface; |
682 | |
683 | if (myIsUseSpan && isBSpline) { |
684 | // Using span decomposition for BSpline. |
685 | Handle(TColStd_HArray1OfReal) aSurfKnots; |
686 | Standard_Integer aNbKnots; |
687 | |
688 | // Get V knots of BSpline surface. |
689 | Handle(Geom_Surface) aSurf = mySurface.Surface().Surface(); |
690 | Handle(Geom_BSplineSurface) aBSplSurf; |
691 | |
692 | aBSplSurf = Handle(Geom_BSplineSurface)::DownCast(aSurf); |
693 | aNbKnots = aBSplSurf->NbVKnots(); |
694 | aSurfKnots = new TColStd_HArray1OfReal(1, aNbKnots); |
695 | aBSplSurf->VKnots(aSurfKnots->ChangeArray1()); |
696 | |
697 | // Handle(TColStd_HArray1OfReal) aCurveKnots; |
698 | |
699 | // GetCurveKnots(theTMin, theTMax, myCurve, aCurveKnots); |
700 | // GetRealCurveKnots(aCurveKnots, aSurfKnots, myCurve, theTKnots); |
701 | GetCurveKnots(theTMin, theTMax, myCurve, theTKnots); |
702 | } else { |
703 | theTKnots = new TColStd_HArray1OfReal(1, 2); |
704 | theTKnots->SetValue(1, theTMin); |
705 | theTKnots->SetValue(2, theTMax); |
706 | } |
707 | } |