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