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