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