1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Adaptor3d_HSurface.hxx>
17 #include <AdvApp2Var_ApproxAFunc2Var.hxx>
18 #include <AdvApprox_PrefAndRec.hxx>
19 #include <Geom_BSplineSurface.hxx>
20 #include <Geom_Surface.hxx>
21 #include <GeomAdaptor_HSurface.hxx>
22 #include <GeomConvert_ApproxSurface.hxx>
23 #include <Precision.hxx>
24 #include <Standard_OutOfRange.hxx>
25 #include <Standard_Real.hxx>
26 #include <TColStd_HArray1OfReal.hxx>
27 #include <TColStd_HArray2OfReal.hxx>
29 class GeomConvert_ApproxSurface_Eval : public AdvApp2Var_EvaluatorFunc2Var
34 GeomConvert_ApproxSurface_Eval (const Handle(Adaptor3d_HSurface)& theAdaptor)
35 : myAdaptor (theAdaptor) {}
37 virtual void Evaluate (Standard_Integer* theDimension,
38 Standard_Real* theUStartEnd,
39 Standard_Real* theVStartEnd,
40 Standard_Integer* theFavorIso,
41 Standard_Real* theConstParam,
42 Standard_Integer* theNbParams,
43 Standard_Real* theParameters,
44 Standard_Integer* theUOrder,
45 Standard_Integer* theVOrder,
46 Standard_Real* theResult,
47 Standard_Integer* theErrorCode) const;
51 mutable Handle(Adaptor3d_HSurface) myAdaptor;
56 void GeomConvert_ApproxSurface_Eval::Evaluate (Standard_Integer * Dimension,
58 Standard_Real * UStartEnd,
60 Standard_Real * VStartEnd,
62 Standard_Integer * FavorIso,
63 // Choice of constante, 1 for U, 2 for V
64 Standard_Real * ConstParam,
65 // Value of constant parameter
66 Standard_Integer * NbParams,
67 // Number of parameters N
68 Standard_Real * Parameters,
69 // Values of parameters,
70 Standard_Integer * UOrder,
71 // Derivative Request in U
72 Standard_Integer * VOrder,
73 // Derivative Request in V
74 Standard_Real * Result,
75 // Result[Dimension,N]
76 Standard_Integer * ErrorCode) const
80 // Standard_Integer idim;
81 Standard_Integer jpar;
82 Standard_Real Upar,Vpar;
84 // Dimension incorrecte
89 // Parametres incorrects
90 /* if (*FavorIso==1) {
92 if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) {
95 for (jpar=1;jpar<=*NbParams;jpar++) {
96 Vpar = Parameters[jpar-1];
97 if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) {
104 if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) {
107 for (jpar=1;jpar<=*NbParams;jpar++) {
108 Upar = Parameters[jpar-1];
109 if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) {
117 myAdaptor = myAdaptor->UTrim (UStartEnd[0], UStartEnd[1], Precision::PConfusion());
118 myAdaptor = myAdaptor->VTrim (VStartEnd[0], VStartEnd[1], Precision::PConfusion());
120 for (idim=1;idim<=*Dimension;idim++) {
121 for (jpar=1;jpar<=*NbParams;jpar++) {
122 Result[idim-1+(jpar-1)*(*Dimension)] = 0.;
127 Standard_Integer Order = *UOrder + *VOrder;
129 gp_Vec vect, v1, v2, v3, v4, v5, v6, v7, v8, v9;
135 for (jpar=1;jpar<=*NbParams;jpar++) {
136 Vpar = Parameters[jpar-1];
137 pnt = myAdaptor->Value (Upar, Vpar);
138 Result[(jpar-1)*(*Dimension)] = pnt.X();
139 Result[1+(jpar-1)*(*Dimension)] = pnt.Y();
140 Result[2+(jpar-1)*(*Dimension)] = pnt.Z();
144 for (jpar=1;jpar<=*NbParams;jpar++) {
145 Vpar = Parameters[jpar-1];
146 myAdaptor->D1 (Upar, Vpar, pnt, v1, v2);
148 Result[(jpar-1)*(*Dimension)] = v1.X();
149 Result[1+(jpar-1)*(*Dimension)] = v1.Y();
150 Result[2+(jpar-1)*(*Dimension)] = v1.Z();
153 Result[(jpar-1)*(*Dimension)] = v2.X();
154 Result[1+(jpar-1)*(*Dimension)] = v2.Y();
155 Result[2+(jpar-1)*(*Dimension)] = v2.Z();
160 for (jpar=1;jpar<=*NbParams;jpar++) {
161 Vpar = Parameters[jpar-1];
162 myAdaptor->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5);
164 Result[(jpar-1)*(*Dimension)] = v3.X();
165 Result[1+(jpar-1)*(*Dimension)] = v3.Y();
166 Result[2+(jpar-1)*(*Dimension)] = v3.Z();
168 else if (*UOrder==1) {
169 Result[(jpar-1)*(*Dimension)] = v5.X();
170 Result[1+(jpar-1)*(*Dimension)] = v5.Y();
171 Result[2+(jpar-1)*(*Dimension)] = v5.Z();
173 else if (*UOrder==0) {
174 Result[(jpar-1)*(*Dimension)] = v4.X();
175 Result[1+(jpar-1)*(*Dimension)] = v4.Y();
176 Result[2+(jpar-1)*(*Dimension)] = v4.Z();
181 for (jpar=1;jpar<=*NbParams;jpar++) {
182 Vpar = Parameters[jpar-1];
183 myAdaptor->D3 (Upar, Vpar, pnt, v1, v2, v3, v4, v5, v6, v7, v8, v9);
185 Result[(jpar-1)*(*Dimension)] = v8.X();
186 Result[1+(jpar-1)*(*Dimension)] = v8.Y();
187 Result[2+(jpar-1)*(*Dimension)] = v8.Z();
189 else if (*UOrder==1) {
190 Result[(jpar-1)*(*Dimension)] = v9.X();
191 Result[1+(jpar-1)*(*Dimension)] = v9.Y();
192 Result[2+(jpar-1)*(*Dimension)] = v9.Z();
197 for (jpar=1;jpar<=*NbParams;jpar++) {
198 Vpar = Parameters[jpar-1];
199 vect = myAdaptor->DN (Upar, Vpar, *UOrder, *VOrder);
200 Result[(jpar-1)*(*Dimension)] = vect.X();
201 Result[1+(jpar-1)*(*Dimension)] = vect.Y();
202 Result[2+(jpar-1)*(*Dimension)] = vect.Z();
211 for (jpar=1;jpar<=*NbParams;jpar++) {
212 Upar = Parameters[jpar-1];
213 pnt = myAdaptor->Value (Upar, Vpar);
214 Result[(jpar-1)*(*Dimension)] = pnt.X();
215 Result[1+(jpar-1)*(*Dimension)] = pnt.Y();
216 Result[2+(jpar-1)*(*Dimension)] = pnt.Z();
220 for (jpar=1;jpar<=*NbParams;jpar++) {
221 Upar = Parameters[jpar-1];
222 myAdaptor->D1 (Upar, Vpar, pnt, v1, v2);
224 Result[(jpar-1)*(*Dimension)] = v1.X();
225 Result[1+(jpar-1)*(*Dimension)] = v1.Y();
226 Result[2+(jpar-1)*(*Dimension)] = v1.Z();
229 Result[(jpar-1)*(*Dimension)] = v2.X();
230 Result[1+(jpar-1)*(*Dimension)] = v2.Y();
231 Result[2+(jpar-1)*(*Dimension)] = v2.Z();
236 for (jpar=1;jpar<=*NbParams;jpar++) {
237 Upar = Parameters[jpar-1];
238 myAdaptor->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5);
240 Result[(jpar-1)*(*Dimension)] = v3.X();
241 Result[1+(jpar-1)*(*Dimension)] = v3.Y();
242 Result[2+(jpar-1)*(*Dimension)] = v3.Z();
244 else if (*UOrder==1) {
245 Result[(jpar-1)*(*Dimension)] = v5.X();
246 Result[1+(jpar-1)*(*Dimension)] = v5.Y();
247 Result[2+(jpar-1)*(*Dimension)] = v5.Z();
249 else if (*UOrder==0) {
250 Result[(jpar-1)*(*Dimension)] = v4.X();
251 Result[1+(jpar-1)*(*Dimension)] = v4.Y();
252 Result[2+(jpar-1)*(*Dimension)] = v4.Z();
257 for (jpar=1;jpar<=*NbParams;jpar++) {
258 Upar = Parameters[jpar-1];
259 myAdaptor->D3 (Upar, Vpar, pnt, v1, v2, v3, v4, v5, v6, v7, v8, v9);
261 Result[(jpar-1)*(*Dimension)] = v8.X();
262 Result[1+(jpar-1)*(*Dimension)] = v8.Y();
263 Result[2+(jpar-1)*(*Dimension)] = v8.Z();
265 else if (*UOrder==1) {
266 Result[(jpar-1)*(*Dimension)] = v9.X();
267 Result[1+(jpar-1)*(*Dimension)] = v9.Y();
268 Result[2+(jpar-1)*(*Dimension)] = v9.Z();
273 for (jpar=1;jpar<=*NbParams;jpar++) {
274 Upar = Parameters[jpar-1];
275 vect = myAdaptor->DN (Upar, Vpar, *UOrder, *VOrder);
276 Result[(jpar-1)*(*Dimension)] = vect.X();
277 Result[1+(jpar-1)*(*Dimension)] = vect.Y();
278 Result[2+(jpar-1)*(*Dimension)] = vect.Z();
287 //=======================================================================
288 //function : GeomConvert_ApproxSurface
290 //=======================================================================
292 GeomConvert_ApproxSurface::GeomConvert_ApproxSurface(const Handle(Geom_Surface)& Surf,
293 const Standard_Real Tol3d,
294 const GeomAbs_Shape UContinuity,
295 const GeomAbs_Shape VContinuity,
296 const Standard_Integer MaxDegU,
297 const Standard_Integer MaxDegV,
298 const Standard_Integer MaxSegments,
299 const Standard_Integer PrecisCode)
301 Handle(Adaptor3d_HSurface) aSurfAdaptor = new GeomAdaptor_HSurface (Surf);
302 Approximate(aSurfAdaptor, Tol3d, UContinuity, VContinuity, MaxDegU, MaxDegV, MaxSegments, PrecisCode);
305 GeomConvert_ApproxSurface::GeomConvert_ApproxSurface(const Handle(Adaptor3d_HSurface)& Surf,
306 const Standard_Real Tol3d,
307 const GeomAbs_Shape UContinuity,
308 const GeomAbs_Shape VContinuity,
309 const Standard_Integer MaxDegU,
310 const Standard_Integer MaxDegV,
311 const Standard_Integer MaxSegments,
312 const Standard_Integer PrecisCode)
314 Approximate(Surf, Tol3d, UContinuity, VContinuity, MaxDegU, MaxDegV, MaxSegments, PrecisCode);
317 void GeomConvert_ApproxSurface::Approximate(const Handle(Adaptor3d_HSurface)& theSurf,
318 const Standard_Real theTol3d,
319 const GeomAbs_Shape theUContinuity,
320 const GeomAbs_Shape theVContinuity,
321 const Standard_Integer theMaxDegU,
322 const Standard_Integer theMaxDegV,
323 const Standard_Integer theMaxSegments,
324 const Standard_Integer thePrecisCode)
326 Standard_Real U0 = theSurf->FirstUParameter();
327 Standard_Real U1 = theSurf->LastUParameter();
328 Standard_Real V0 = theSurf->FirstVParameter();
329 Standard_Real V1 = theSurf->LastVParameter();
331 // " Init des nombres de sous-espaces et des tolerances"
332 Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1;
333 Handle(TColStd_HArray1OfReal) nul1 = new TColStd_HArray1OfReal(1,1);
334 nul1->SetValue(1, 0.);
335 Handle(TColStd_HArray2OfReal) nul2 = new TColStd_HArray2OfReal(1,1,1,4);
336 nul2->SetValue(1, 1, 0.);
337 nul2->SetValue(1, 2, 0.);
338 nul2->SetValue(1, 3, 0.);
339 nul2->SetValue(1, 4, 0.);
340 Handle(TColStd_HArray1OfReal) eps3D = new TColStd_HArray1OfReal(1,1);
341 eps3D->SetValue(1, theTol3d);
342 Handle(TColStd_HArray2OfReal) epsfr = new TColStd_HArray2OfReal(1,1,1,4);
343 epsfr->SetValue(1, 1, theTol3d);
344 epsfr->SetValue(1, 2, theTol3d);
345 epsfr->SetValue(1, 3, theTol3d);
346 epsfr->SetValue(1, 4, theTol3d);
348 // " Init du type d'iso"
349 GeomAbs_IsoType IsoType = GeomAbs_IsoV;
350 Standard_Integer NbDec;
352 NbDec = theSurf->NbUIntervals(GeomAbs_C2);
353 TColStd_Array1OfReal UDec_C2(1, NbDec+1);
354 theSurf->UIntervals(UDec_C2, GeomAbs_C2);
355 NbDec = theSurf->NbVIntervals(GeomAbs_C2);
356 TColStd_Array1OfReal VDec_C2(1, NbDec+1);
357 theSurf->VIntervals(VDec_C2, GeomAbs_C2);
359 NbDec = theSurf->NbUIntervals(GeomAbs_C3);
360 TColStd_Array1OfReal UDec_C3(1, NbDec+1);
361 theSurf->UIntervals(UDec_C3, GeomAbs_C3);
363 NbDec = theSurf->NbVIntervals(GeomAbs_C3);
364 TColStd_Array1OfReal VDec_C3(1, NbDec+1);
365 theSurf->VIntervals(VDec_C3, GeomAbs_C3);
366 // Approximation avec decoupe preferentiel
367 // aux lieux de discontinuitees C2
368 AdvApprox_PrefAndRec pUDec(UDec_C2,UDec_C3);
369 AdvApprox_PrefAndRec pVDec(VDec_C2,VDec_C3);
372 GeomConvert_ApproxSurface_Eval ev (theSurf);
373 AdvApp2Var_ApproxAFunc2Var approx(nb1, nb2, nb3,
377 IsoType,theUContinuity,theVContinuity,thePrecisCode,
378 theMaxDegU,theMaxDegV,theMaxSegments,ev,
381 myMaxError = approx.MaxError(3,1);
382 myBSplSurf = approx.Surface(1);
383 myIsDone = approx.IsDone();
384 myHasResult = approx.HasResult();
388 //=======================================================================
391 //=======================================================================
393 Handle(Geom_BSplineSurface) GeomConvert_ApproxSurface::Surface() const
398 //=======================================================================
401 //=======================================================================
403 Standard_Boolean GeomConvert_ApproxSurface::IsDone() const
408 //=======================================================================
409 //function : HasResult
411 //=======================================================================
413 Standard_Boolean GeomConvert_ApproxSurface::HasResult() const
418 //=======================================================================
419 //function : MaxError
421 //=======================================================================
423 Standard_Real GeomConvert_ApproxSurface::MaxError() const
427 //=======================================================================
430 //=======================================================================
432 void GeomConvert_ApproxSurface::Dump(Standard_OStream& o) const
435 if (!myHasResult) { o<<"No result"<<endl; }
437 o<<"Result max error :"<< myMaxError <<endl;