0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_ConvertSurfaceToBezierBasis.cxx
1 // Created on: 1999-05-21
2 // Created by: Pavel DURANDIN
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //   svv  10.01.00 porting on DEC
18
19 #include <Geom_BezierCurve.hxx>
20 #include <Geom_BezierSurface.hxx>
21 #include <Geom_BSplineSurface.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_OffsetCurve.hxx>
24 #include <Geom_OffsetSurface.hxx>
25 #include <Geom_Plane.hxx>
26 #include <Geom_RectangularTrimmedSurface.hxx>
27 #include <Geom_SurfaceOfLinearExtrusion.hxx>
28 #include <Geom_SurfaceOfRevolution.hxx>
29 #include <Geom_TrimmedCurve.hxx>
30 #include <GeomConvert_BSplineSurfaceToBezierSurface.hxx>
31 #include <Precision.hxx>
32 #include <ShapeExtend.hxx>
33 #include <ShapeExtend_CompositeSurface.hxx>
34 #include <ShapeUpgrade_ConvertCurve3dToBezier.hxx>
35 #include <ShapeUpgrade_ConvertSurfaceToBezierBasis.hxx>
36 #include <Standard_Type.hxx>
37 #include <TColGeom_Array2OfBezierSurface.hxx>
38 #include <TColGeom_HArray1OfCurve.hxx>
39 #include <TColGeom_HArray2OfSurface.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
41 #include <TColgp_Array2OfPnt.hxx>
42 #include <TColStd_Array1OfBoolean.hxx>
43 #include <TColStd_Array1OfReal.hxx>
44 #include <TColStd_HArray1OfReal.hxx>
45 #include <TColStd_HSequenceOfReal.hxx>
46
47 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_ConvertSurfaceToBezierBasis,ShapeUpgrade_SplitSurface)
48
49 ShapeUpgrade_ConvertSurfaceToBezierBasis::ShapeUpgrade_ConvertSurfaceToBezierBasis()
50 {
51   myPlaneMode      = Standard_True;
52   myRevolutionMode = Standard_True;
53   myExtrusionMode  = Standard_True;
54   myBSplineMode    = Standard_True;
55 }
56
57 //=======================================================================
58 //function : Compute
59 //purpose  : 
60 //=======================================================================
61
62 void ShapeUpgrade_ConvertSurfaceToBezierBasis::Compute(const Standard_Boolean Segment)
63 {
64   if(!Segment) {
65     Standard_Real UF,UL,VF,VL;
66     mySurface->Bounds(UF,UL,VF,VL);
67     if(!Precision::IsInfinite(UF)) myUSplitValues->SetValue(1,UF);
68     if(!Precision::IsInfinite(UL)) myUSplitValues->SetValue(myUSplitValues->Length(),UL);
69     if(!Precision::IsInfinite(VF)) myVSplitValues->SetValue(1,VF);
70     if(!Precision::IsInfinite(VL)) myVSplitValues->SetValue(myVSplitValues->Length(),VL);
71   }
72        
73   Standard_Real UFirst = myUSplitValues->Value(1);
74   Standard_Real ULast  = myUSplitValues->Value(myUSplitValues->Length());
75   Standard_Real VFirst = myVSplitValues->Value(1);
76   Standard_Real VLast  = myVSplitValues->Value(myVSplitValues->Length());
77   Standard_Real precision = Precision::PConfusion();
78   
79   if (mySurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
80     Handle(Geom_RectangularTrimmedSurface) Surface = Handle(Geom_RectangularTrimmedSurface)::DownCast(mySurface);
81     Handle(Geom_Surface) BasSurf = Surface->BasisSurface();
82     ShapeUpgrade_ConvertSurfaceToBezierBasis converter;
83     converter.Init(BasSurf,UFirst,ULast,VFirst,VLast);
84     converter.SetUSplitValues(myUSplitValues);
85     converter.SetVSplitValues(myVSplitValues);
86     converter.Compute(Standard_True);
87     myUSplitValues->ChangeSequence() = converter.USplitValues()->Sequence();
88     myVSplitValues->ChangeSequence() = converter.VSplitValues()->Sequence();
89     myStatus |= converter.myStatus;
90     mySegments = converter.Segments();
91     return;
92   } else if(mySurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
93     Handle(Geom_OffsetSurface) Offset = Handle(Geom_OffsetSurface)::DownCast(mySurface);
94     Handle(Geom_Surface) BasSurf = Offset->BasisSurface();
95     ShapeUpgrade_ConvertSurfaceToBezierBasis converter;
96     converter.Init(BasSurf,UFirst,ULast,VFirst,VLast);
97     converter.SetUSplitValues(myUSplitValues);
98     converter.SetVSplitValues(myVSplitValues);
99     converter.Compute(Standard_True);
100     myUSplitValues->ChangeSequence() = converter.USplitValues()->Sequence();
101     myVSplitValues->ChangeSequence() = converter.VSplitValues()->Sequence();
102     myStatus |= converter.myStatus;
103     mySegments = converter.Segments();
104     return;
105   } else if(mySurface->IsKind(STANDARD_TYPE(Geom_Plane))&&myPlaneMode) {
106     Handle(Geom_Plane) pln = Handle(Geom_Plane)::DownCast(mySurface);
107     TColgp_Array2OfPnt poles(1,2,1,2);
108     gp_Pnt dp;
109     poles(1,1) = dp = pln->Value(UFirst,VFirst); poles(1,2) = dp = pln->Value(UFirst,VLast);
110     poles(2,1) = dp = pln->Value(ULast,VFirst);  poles(2,2) = dp = pln->Value(ULast,VLast);
111     Handle(Geom_BezierSurface) bezier = new Geom_BezierSurface(poles);
112     TColStd_Array1OfReal UJoints(1,2);
113     UJoints(1) = UFirst; UJoints(2) = ULast;
114     TColStd_Array1OfReal VJoints(1,2);
115     VJoints(1) = VFirst; VJoints(2) = VLast;
116     Handle(TColGeom_HArray2OfSurface) surf = new TColGeom_HArray2OfSurface(1,1,1,1);
117     surf->SetValue(1,1,bezier);
118     mySegments = new ShapeExtend_CompositeSurface(surf,UJoints,VJoints);
119     myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
120     return;
121   } else if(mySurface->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
122     Handle(Geom_BezierSurface) bezier = Handle(Geom_BezierSurface)::DownCast(mySurface);
123     Handle(TColGeom_HArray2OfSurface) surf = new TColGeom_HArray2OfSurface(1,1,1,1);
124     TColStd_Array1OfReal UJoints(1,2);
125     UJoints(1) = UFirst; UJoints(2) = ULast;
126     TColStd_Array1OfReal VJoints(1,2);
127     VJoints(1) = VFirst; VJoints(2) = VLast;
128     if(UFirst < precision && ULast > 1 - precision &&
129        VFirst < precision && VLast > 1 - precision) {
130       surf->SetValue(1,1,bezier);
131       myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
132     } else {
133       Handle(Geom_BezierSurface) besNew = Handle(Geom_BezierSurface)::DownCast(bezier->Copy());
134       //pdn K4L+ (work around)
135       // Standard_Real u1 = 2*UFirst - 1;
136       // Standard_Real u2 = 2*ULast - 1;
137       // Standard_Real v1 = 2*VFirst - 1;
138       // Standard_Real v2 = 2*VLast - 1;
139       //rln C30 (direct use)
140       Standard_Real u1 = UFirst;
141       Standard_Real u2 = ULast;
142       Standard_Real v1 = VFirst;
143       Standard_Real v2 = VLast;
144       besNew->Segment(u1,u2,v1,v2);
145       surf->SetValue(1,1,besNew);
146       myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
147     }
148     mySegments = new ShapeExtend_CompositeSurface(surf,UJoints,VJoints);
149     return;
150   } else if(mySurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface))&&myBSplineMode) {
151     Handle(Geom_BSplineSurface) bspline = Handle(Geom_BSplineSurface)::DownCast(mySurface);
152     //pdn
153     Standard_Real u1,u2,v1,v2;
154     bspline->Bounds(u1,u2,v1,v2);
155     GeomConvert_BSplineSurfaceToBezierSurface converter(bspline);//,UFirst,ULast,VFirst,VLast,precision;
156     Standard_Integer nbUPatches = converter.NbUPatches();
157     Standard_Integer nbVPatches = converter.NbVPatches();
158     TColStd_Array1OfReal UJoints(1, nbUPatches+1);
159     TColStd_Array1OfBoolean UReject(1, nbUPatches+1);
160     UReject.Init(Standard_False);
161     TColStd_Array1OfReal VJoints(1, nbVPatches+1);
162     TColStd_Array1OfBoolean VReject(1, nbVPatches+1);
163     VReject.Init(Standard_False);
164     Standard_Integer NbUFiltered = 0;
165     Standard_Integer NbVFiltered = 0;
166     
167     converter.UKnots(UJoints);
168     TColStd_SequenceOfReal UFilteredJoints;
169     UFilteredJoints.Append(UJoints(1));
170     Standard_Integer i;
171     for(i = 2; i <= nbUPatches+1; i++)
172       if(UJoints(i)-UJoints(i-1) < precision) {
173         NbUFiltered++;
174         UReject(i-1) = Standard_True;
175       }
176       else
177         UFilteredJoints.Append(UJoints(i));
178     
179     converter.VKnots(VJoints);
180     TColStd_SequenceOfReal VFilteredJoints;
181     VFilteredJoints.Append(VJoints(1));
182     for( i = 2; i <= nbVPatches+1; i++)
183       if(VJoints(i)-VJoints(i-1) < precision) {
184         NbVFiltered++;
185         VReject(i-1) = Standard_True;
186       }
187       else
188         VFilteredJoints.Append(VJoints(i));
189
190 #ifdef OCCT_DEBUG
191     if(NbVFiltered || NbUFiltered)
192       std::cout<<"Warning: ShapeUpgrade_ConvertSurfaceToBezierBasis: thin patches dropped."<<std::endl;
193 #endif
194     
195     TColGeom_Array2OfBezierSurface Surfaces(1, nbUPatches, 1, nbVPatches);
196     converter.Patches(Surfaces);
197     Handle(TColGeom_HArray2OfSurface) srf = 
198       new TColGeom_HArray2OfSurface(1,nbUPatches-NbUFiltered,1,nbVPatches-NbVFiltered);
199     Standard_Integer indApp1 = 0;
200     for(Standard_Integer ind1 = 1; ind1 <= nbUPatches; ind1++) {
201       if(UReject(ind1)) continue;
202       indApp1++;
203       Standard_Integer indApp2 = 0;
204       for(Standard_Integer ind2 = 1; ind2 <= nbVPatches; ind2++) {
205         if(VReject(ind2)) continue;
206         indApp2++;
207         srf->SetValue(indApp1,indApp2,Surfaces(ind1,ind2));
208       }
209     }
210     
211     TColStd_Array1OfReal uj (1,UFilteredJoints.Length());
212     for(i = 1; i <=UFilteredJoints.Length(); i++)
213       uj(i) = UFilteredJoints.Value(i);
214     
215     TColStd_Array1OfReal vj (1,VFilteredJoints.Length());
216     for(i = 1; i <=VFilteredJoints.Length(); i++)
217       vj(i) = VFilteredJoints.Value(i);
218     
219     mySegments = new ShapeExtend_CompositeSurface(srf,uj,vj);
220     
221     Standard_Integer j; // svv #1
222     for(j = 2; j <= myUSplitValues->Length(); j++) {
223       ULast =  myUSplitValues->Value(j);
224       for(Standard_Integer ii = 2; ii <= nbUPatches+1; ii++) {
225         Standard_Real valknot = UJoints(ii);
226         if(valknot-UFirst <=  precision) continue;
227         if(ULast -valknot <=  precision) break;
228         myUSplitValues->InsertBefore(j++,valknot);
229       }
230       UFirst = ULast;
231     }
232     for(j = 2; j <= myVSplitValues->Length(); j++) {
233       VLast =  myVSplitValues->Value(j);
234       for(Standard_Integer ii = 2; ii <= nbVPatches+1; ii++) {
235         Standard_Real valknot = VJoints(ii);
236         if(valknot-VFirst <= precision) continue;
237         if(VLast -valknot <= precision) break;
238         myVSplitValues->InsertBefore(j++,valknot);
239       }
240       VFirst = VLast;
241     }
242     myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
243     return;
244   } else if(mySurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))&&myRevolutionMode) {
245     Handle(Geom_SurfaceOfRevolution) revol = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface);
246     Handle(Geom_Curve) basis = revol->BasisCurve();
247     if(basis->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
248       Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(basis);
249       basis = tc->BasisCurve();
250     }
251     Handle(TColGeom_HArray1OfCurve) curves;
252     Standard_Integer nbCurves;
253     Handle(TColStd_HSequenceOfReal) vPar = new TColStd_HSequenceOfReal;
254     Handle(TColStd_HSequenceOfReal) vSVal= new TColStd_HSequenceOfReal;
255     if(basis->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
256       Handle(Geom_OffsetCurve) offset = Handle(Geom_OffsetCurve)::DownCast(basis);
257       Standard_Real value = offset->Offset();
258       gp_Dir direction = offset->Direction();
259       Handle(Geom_Curve) bas = offset->BasisCurve();
260       ShapeUpgrade_ConvertCurve3dToBezier converter;
261       converter.Init(bas,VFirst,VLast);
262       converter.Perform(Standard_True);
263       if(converter.Status(ShapeExtend_DONE)) 
264         myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
265       else
266         myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
267       
268       vPar->ChangeSequence() = converter.SplitParams()->Sequence();
269       vSVal->ChangeSequence()= converter.SplitValues()->Sequence();
270       curves = converter.GetCurves();
271       nbCurves = curves->Length();
272       for(Standard_Integer i = 1; i <= nbCurves; i++) {
273         Handle(Geom_OffsetCurve) offCur = new Geom_OffsetCurve(curves->Value(i),value,direction);
274         curves->SetValue(i,offCur);
275       }
276     } else {
277       ShapeUpgrade_ConvertCurve3dToBezier converter;
278       converter.Init(basis,VFirst,VLast);
279       converter.Perform(Standard_True);
280       if(converter.Status(ShapeExtend_DONE)) 
281         myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
282       else
283         myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
284
285       vPar->ChangeSequence() = converter.SplitParams()->Sequence();
286       vSVal->ChangeSequence()= converter.SplitValues()->Sequence();
287       curves = converter.GetCurves();
288       nbCurves = curves->Length();
289     }
290     
291     gp_Ax1 axis = revol->Axis();
292     Handle(TColGeom_HArray2OfSurface) surf = new TColGeom_HArray2OfSurface(1,1,1,nbCurves);
293     Standard_Real Umin,Umax,Vmin,Vmax;
294     mySurface->Bounds(Umin,Umax,Vmin,Vmax);
295     Standard_Integer i; // svv #1
296     for(i = 1; i <= nbCurves; i++) {
297       Handle(Geom_SurfaceOfRevolution) rev = new Geom_SurfaceOfRevolution(curves->Value(i),axis);
298       if( UFirst-Umin < Precision::PConfusion() &&
299          Umax-ULast < Precision::PConfusion() )
300         surf->SetValue(1,i,rev);
301       else {
302         Handle(Geom_RectangularTrimmedSurface) rect = new Geom_RectangularTrimmedSurface(rev,UFirst,ULast,Standard_True);
303         surf->SetValue(1,i,rect);
304       }
305     }
306     TColStd_Array1OfReal UJoints(1, 2);
307     TColStd_Array1OfReal VJoints(1, nbCurves+1);
308     UJoints(1) = UFirst;  UJoints(2) = ULast;
309     for(i = 1 ; i <= nbCurves+1; i++)
310       VJoints(i) = vPar->Value(i);
311     
312     mySegments = new ShapeExtend_CompositeSurface(surf,UJoints,VJoints);
313     
314     for(Standard_Integer  j = 2; j <= myVSplitValues->Length(); j++) {
315       VLast =  myVSplitValues->Value(j);
316       for(Standard_Integer ii = 2; ii <= nbCurves+1; ii++) {
317         Standard_Real valknot = vSVal->Value(ii);
318         if(valknot-VFirst <= precision) continue;
319         if(VLast -valknot <= precision) break;
320         myVSplitValues->InsertBefore(j++,valknot);
321       }
322       VFirst = VLast;
323     }
324     return;
325   } else if(mySurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))&&myExtrusionMode) {
326     Handle(Geom_SurfaceOfLinearExtrusion) extr = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurface);
327     Handle(Geom_Curve) basis = extr->BasisCurve();
328     //gp_Dir direction = extr->Direction(); // direction not used (skl)
329     
330     Handle(TColGeom_HArray1OfCurve) curves;
331     Standard_Integer nbCurves;
332     Handle(TColStd_HSequenceOfReal) uPar = new TColStd_HSequenceOfReal;
333     Handle(TColStd_HSequenceOfReal) uSVal= new TColStd_HSequenceOfReal;
334     ShapeUpgrade_ConvertCurve3dToBezier converter;
335     converter.Init(basis,UFirst,ULast);
336     converter.Perform(Standard_True);
337     uPar->ChangeSequence() = converter.SplitParams()->Sequence();
338     uSVal->ChangeSequence()= converter.SplitValues()->Sequence();
339     curves = converter.GetCurves();
340     nbCurves = curves->Length();
341     
342     gp_Trsf shiftF,shiftL;
343     shiftF.SetTranslation(extr->Value(UFirst,0),extr->Value(UFirst,VFirst));
344     shiftL.SetTranslation(extr->Value(UFirst,0),extr->Value(UFirst,VLast));
345     Handle(TColGeom_HArray2OfSurface) surf = new TColGeom_HArray2OfSurface(1,nbCurves,1,1);
346     
347     Standard_Integer i; // svv #1
348     for(i = 1; i <= nbCurves; i++) {
349       Handle(Geom_BezierCurve) bez = Handle(Geom_BezierCurve)::DownCast(curves->Value(i));
350       Standard_Integer nbPoles = bez->NbPoles();
351       TColgp_Array1OfPnt poles(1,nbPoles);
352       bez->Poles(poles);
353       TColgp_Array2OfPnt resPoles(1,nbPoles,1,2);
354       for(Standard_Integer j = 1; j <= nbPoles; j++) {
355         resPoles(j,1) = poles(j).Transformed(shiftF);
356         resPoles(j,2) = poles(j).Transformed(shiftL);
357       }
358       Handle(Geom_BezierSurface) bezier = new Geom_BezierSurface(resPoles);
359       surf->SetValue(i,1,bezier);
360     }
361     
362     TColStd_Array1OfReal UJoints(1, nbCurves+1);
363     TColStd_Array1OfReal VJoints(1, 2);
364     VJoints(1) = VFirst;  VJoints(2) = VLast;
365     for(i = 1 ; i <= nbCurves+1; i++)
366       UJoints(i) = uPar->Value(i);
367     
368     mySegments = new ShapeExtend_CompositeSurface(surf,UJoints,VJoints);
369     
370     for(Standard_Integer j = 2; j <= myUSplitValues->Length(); j++) {
371       ULast =  myUSplitValues->Value(j);
372       for(Standard_Integer ii = 2; ii <= nbCurves+1; ii++) {
373         Standard_Real valknot = uSVal->Value(ii);
374         if(valknot+UFirst <= precision) continue;
375         if(ULast -valknot <= precision) break;
376         myUSplitValues->InsertBefore(j++,valknot);
377       }
378       UFirst = ULast;
379     }
380     myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
381     return;
382   }
383   else {
384     TColStd_Array1OfReal UJoints(1,2);
385     UJoints(1) = UFirst; UJoints(2) = ULast;
386     TColStd_Array1OfReal VJoints(1,2);
387     VJoints(1) = VFirst; VJoints(2) = VLast;
388     Handle(TColGeom_HArray2OfSurface) surf = new TColGeom_HArray2OfSurface(1,1,1,1);
389     Standard_Real U1,U2,V1,V2;
390     mySurface->Bounds(U1,U2,V1,V2);
391     Handle(Geom_Surface) S;
392     if(U1-UFirst < precision && ULast - U2 < precision &&
393        V2-VFirst < precision && VLast - V2 < precision)
394       S = mySurface;
395     else {
396       Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(mySurface,UFirst,ULast,VFirst,VLast);
397       S = rts;
398     }
399     surf->SetValue(1,1,S);
400     mySegments = new ShapeExtend_CompositeSurface(surf,UJoints,VJoints);
401     myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
402     return;
403   }
404 }
405
406 //=======================================================================
407 //function : Build
408 //purpose  : 
409 //=======================================================================
410
411 static Handle(Geom_Surface) GetSegment(const Handle(Geom_Surface) surf,
412                                        const Standard_Real U1,
413                                        const Standard_Real U2,
414                                        const Standard_Real V1,
415                                        const Standard_Real V2)
416 {
417   if(surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
418     Handle(Geom_BezierSurface) bezier = Handle(Geom_BezierSurface)::DownCast(surf->Copy());
419     Standard_Real prec = Precision::PConfusion();
420     if(U1 < prec && U2 > 1-prec && V1 < prec && V2 > 1-prec)
421       return bezier;
422     //pdn K4L+ (work around)
423     // Standard_Real u1 = 2*U1 - 1;
424     // Standard_Real u2 = 2*U2 - 1;
425     // Standard_Real v1 = 2*V1 - 1;
426     // Standard_Real v2 = 2*V2 - 1; 
427     //rln C30 (direct use)
428     Standard_Real u1 = U1;
429     Standard_Real u2 = U2;
430     Standard_Real v1 = V1;
431     Standard_Real v2 = V2;
432     bezier->Segment(u1,u2,v1,v2);
433     return bezier;
434   }
435   
436   Handle(Geom_Surface) S;
437   if(surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
438     Handle(Geom_RectangularTrimmedSurface) rect = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf);
439     S = rect->BasisSurface();
440   } else 
441     S = surf;
442   
443   if(S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
444     Handle(Geom_SurfaceOfRevolution) revol = Handle(Geom_SurfaceOfRevolution)::DownCast(S->Copy());
445     Standard_Real Umin,Umax,Vmin,Vmax;
446     revol->Bounds(Umin,Umax,Vmin,Vmax);
447     Handle(Geom_Curve) basis = revol->BasisCurve();
448     if(basis->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
449       Handle(Geom_OffsetCurve) offset = Handle(Geom_OffsetCurve)::DownCast(basis);
450       basis = offset->BasisCurve();
451     }
452     if(basis->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
453       Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast(basis);
454       bezier->Segment(V1,V2);    
455     }
456     else {
457 #ifdef OCCT_DEBUG
458       std::cout <<"Warning: Resulting path is not surface of revolution basis on bezier curve"<<std::endl;
459 #endif
460     }
461     if(Abs(U1-Umin) < Precision::PConfusion() &&
462        Abs(U2-Umax) < Precision::PConfusion() )
463       return revol;
464         
465     Handle(Geom_RectangularTrimmedSurface) res = new Geom_RectangularTrimmedSurface(revol,U1,U2,Standard_True);
466     return res;
467   }
468   else {
469     Standard_Real Umin,Umax,Vmin,Vmax;
470     surf->Bounds(Umin,Umax,Vmin,Vmax);
471     if( U1-Umin < Precision::PConfusion() &&
472         Umax-U2 < Precision::PConfusion() &&
473         V1-Vmin < Precision::PConfusion() &&
474         Vmax-V2 < Precision::PConfusion() )
475       return surf;
476     
477     Handle(Geom_RectangularTrimmedSurface) res = new Geom_RectangularTrimmedSurface(surf,U1,U2,V1,V2);
478     return res;
479   }
480 }
481
482 //=======================================================================
483 //function : Build
484 //purpose  : 
485 //=======================================================================
486
487 void ShapeUpgrade_ConvertSurfaceToBezierBasis::Build(const Standard_Boolean /*Segment*/)
488 {
489   Standard_Boolean isOffset = Standard_False;
490   Standard_Real offsetValue=0;
491   Handle(Geom_Surface) S;
492   if (mySurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
493     Handle(Geom_RectangularTrimmedSurface) Surface = Handle(Geom_RectangularTrimmedSurface)::DownCast(mySurface);
494     S = Surface->BasisSurface();
495   }
496   else 
497     S = mySurface;
498   if(S->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
499     Handle(Geom_OffsetSurface) offSur = Handle(Geom_OffsetSurface)::DownCast(S);
500     isOffset = Standard_True;
501     offsetValue = offSur->Offset();
502   }
503
504   Standard_Real prec = Precision::PConfusion();
505   Handle(TColStd_HArray1OfReal) myUSplitParams = mySegments->UJointValues();
506   Handle(TColStd_HArray1OfReal) myVSplitParams = mySegments->VJointValues();
507   Standard_Integer nbU = myUSplitValues->Length();
508   Standard_Integer nbV = myVSplitValues->Length();
509   
510   Handle(TColGeom_HArray2OfSurface) resSurfaces = new TColGeom_HArray2OfSurface(1,nbU-1,1,nbV-1);
511   Standard_Integer j1 = 2;
512   for(Standard_Integer i1 = 2; i1 <= nbU; i1++) {
513     Standard_Real parU = myUSplitValues->Value(i1);
514     for(; j1<= myUSplitParams->Length(); j1++) {
515       Standard_Real param = myUSplitParams->Value(j1);
516       if(parU - param < prec)
517         break;
518     }
519     
520     Standard_Integer j2 = 2;
521     for(Standard_Integer i2 = 2; i2 <= nbV; i2++) {
522       Standard_Real parV = myVSplitValues->Value(i2);
523       for(; j2<= myVSplitParams->Length(); j2++) 
524         if(parV - myVSplitParams->Value(j2) < prec)
525           break;
526       
527       Handle(Geom_Surface) patch = mySegments->Patch(j1-1,j2-1);
528       Standard_Real U1, U2, V1, V2;
529       patch->Bounds(U1,U2,V1,V2);
530       //linear recomputation of part:
531       Standard_Real uFirst = myUSplitParams->Value(j1-1);
532       Standard_Real uLast  = myUSplitParams->Value(j1);
533       Standard_Real vFirst = myVSplitParams->Value(j2-1);
534       Standard_Real vLast  = myVSplitParams->Value(j2);
535       Standard_Real uFact = (U2-U1)/(uLast - uFirst);
536       Standard_Real vFact = (V2-V1)/(vLast - vFirst);
537       Standard_Real ppU = myUSplitValues->Value(i1-1);
538       Standard_Real ppV = myVSplitValues->Value(i2-1);
539       //defining a part
540       Standard_Real uL1 = U1+(ppU - uFirst)*uFact;
541       Standard_Real uL2 = U1+(parU- uFirst)*uFact;
542       Standard_Real vL1 = V1+(ppV - vFirst)*vFact;
543       Standard_Real vL2 = V1+(parV- vFirst)*vFact;
544       Handle(Geom_Surface) res = GetSegment(patch,uL1, uL2, vL1, vL2);
545       if(isOffset) {
546         Handle(Geom_OffsetSurface) resOff = new Geom_OffsetSurface(res,offsetValue);
547         res = resOff;
548       }
549       resSurfaces->SetValue(i1-1,i2-1,res);
550     }
551   }
552   
553   TColStd_Array1OfReal UJoints(1,nbU);
554   Standard_Integer i; // svv #1
555   for(i = 1; i <= nbU; i++)
556     UJoints(i) = myUSplitValues->Value(i);
557   
558   TColStd_Array1OfReal VJoints(1,nbV);
559   for(i = 1; i <= nbV; i++)
560     VJoints(i) = myVSplitValues->Value(i);
561       
562   myResSurfaces = new ShapeExtend_CompositeSurface(resSurfaces,UJoints,VJoints);
563 }
564
565 //=======================================================================
566 //function : Segments
567 //purpose  : 
568 //=======================================================================
569
570 Handle(ShapeExtend_CompositeSurface) ShapeUpgrade_ConvertSurfaceToBezierBasis::Segments() const
571 {
572   return mySegments;
573 }