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