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