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 | |
51 | ShapeUpgrade_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 | |
64 | void 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 | |
413 | static 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 | |
489 | void 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 | |
572 | Handle(ShapeExtend_CompositeSurface) ShapeUpgrade_ConvertSurfaceToBezierBasis::Segments() const |
573 | { |
574 | return mySegments; |
575 | } |