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