0022550: Fixing data races
[occt.git] / src / GeomConvert / GeomConvert_ApproxSurface.cxx
1 #include <GeomConvert_ApproxSurface.ixx>
2
3 #include <GeomAdaptor_HSurface.hxx>
4 #include <Precision.hxx>
5 #include <AdvApp2Var_ApproxAFunc2Var.hxx>
6 #include <Standard_Real.hxx>
7 #include <TColStd_HArray2OfReal.hxx>
8 #include <TColStd_HArray1OfReal.hxx>
9 #include <AdvApprox_PrefAndRec.hxx>
10
11 class GeomConvert_ApproxSurface_Eval : public AdvApp2Var_EvaluatorFunc2Var
12 {
13
14 public:
15
16   GeomConvert_ApproxSurface_Eval (const Handle(Adaptor3d_HSurface)& theAdaptor)
17   : myAdaptor (theAdaptor) {}
18
19   virtual void Evaluate (Standard_Integer* theDimension,
20                          Standard_Real*    theUStartEnd,
21                          Standard_Real*    theVStartEnd,
22                          Standard_Integer* theFavorIso,
23                          Standard_Real*    theConstParam,
24                          Standard_Integer* theNbParams,
25                          Standard_Real*    theParameters,
26                          Standard_Integer* theUOrder,
27                          Standard_Integer* theVOrder,
28                          Standard_Real*    theResult,
29                          Standard_Integer* theErrorCode) const;
30
31 private:
32
33   mutable Handle(Adaptor3d_HSurface) myAdaptor;
34
35 };
36
37
38 void GeomConvert_ApproxSurface_Eval::Evaluate (Standard_Integer * Dimension,
39                            // Dimension
40                            Standard_Real    * UStartEnd,
41                            // StartEnd[2] in U
42                            Standard_Real    * VStartEnd,
43                            // StartEnd[2] in V
44                            Standard_Integer * FavorIso,
45                            // Choice of constante, 1 for U, 2 for V
46                            Standard_Real    * ConstParam,
47                            // Value of constant parameter
48                            Standard_Integer * NbParams,
49                            // Number of parameters N
50                            Standard_Real    * Parameters,
51                            // Values of parameters,
52                            Standard_Integer * UOrder,
53                            // Derivative Request in U
54                            Standard_Integer * VOrder,
55                            // Derivative Request in V
56                            Standard_Real    * Result, 
57                            // Result[Dimension,N]
58                            Standard_Integer * ErrorCode) const
59                            // Error Code
60
61   *ErrorCode = 0;
62 //  Standard_Integer idim;
63   Standard_Integer jpar;
64   Standard_Real Upar,Vpar;
65
66 // Dimension incorrecte
67   if (*Dimension!=3) {
68     *ErrorCode = 1;
69   }
70
71 // Parametres incorrects
72 /* if (*FavorIso==1) {
73     Upar = *ConstParam;
74     if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) {
75       *ErrorCode = 2;
76     }
77     for (jpar=1;jpar<=*NbParams;jpar++) {
78       Vpar = Parameters[jpar-1];
79       if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) {
80         *ErrorCode = 2;
81       }
82     }
83  }
84  else {
85     Vpar = *ConstParam;
86     if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) {
87       *ErrorCode = 2;
88     }
89     for (jpar=1;jpar<=*NbParams;jpar++) {
90       Upar = Parameters[jpar-1];
91       if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) {
92         *ErrorCode = 2;
93       }
94     }
95  }*/
96
97 // Initialisation
98
99   myAdaptor = myAdaptor->UTrim (UStartEnd[0], UStartEnd[1], Precision::PConfusion());
100   myAdaptor = myAdaptor->VTrim (VStartEnd[0], VStartEnd[1], Precision::PConfusion());
101 /*
102   for (idim=1;idim<=*Dimension;idim++) {
103     for (jpar=1;jpar<=*NbParams;jpar++) {
104       Result[idim-1+(jpar-1)*(*Dimension)] = 0.;
105     }
106   }*/
107  
108
109  Standard_Integer Order = *UOrder + *VOrder;
110  gp_Pnt pnt;
111  gp_Vec vect, v1, v2, v3, v4, v5, v6, v7, v8, v9;
112
113  if (*FavorIso==1) {
114   Upar = *ConstParam;
115   switch (Order) {
116   case 0 :
117     for (jpar=1;jpar<=*NbParams;jpar++) {
118         Vpar = Parameters[jpar-1];
119         pnt = myAdaptor->Value (Upar, Vpar);
120         Result[(jpar-1)*(*Dimension)] = pnt.X();
121         Result[1+(jpar-1)*(*Dimension)] = pnt.Y(); 
122         Result[2+(jpar-1)*(*Dimension)] = pnt.Z();
123     }
124     break;
125   case 1 :
126     for (jpar=1;jpar<=*NbParams;jpar++) {
127         Vpar = Parameters[jpar-1];
128         myAdaptor->D1 (Upar, Vpar, pnt, v1, v2);
129         if (*UOrder==1) {
130           Result[(jpar-1)*(*Dimension)] = v1.X();
131           Result[1+(jpar-1)*(*Dimension)] = v1.Y(); 
132           Result[2+(jpar-1)*(*Dimension)] = v1.Z();
133         }
134         else {
135           Result[(jpar-1)*(*Dimension)] = v2.X();
136           Result[1+(jpar-1)*(*Dimension)] = v2.Y(); 
137           Result[2+(jpar-1)*(*Dimension)] = v2.Z();
138         }
139     }
140     break;
141   case 2 :
142     for (jpar=1;jpar<=*NbParams;jpar++) {
143         Vpar = Parameters[jpar-1];
144         myAdaptor->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5);
145         if (*UOrder==2) {
146           Result[(jpar-1)*(*Dimension)] = v3.X();
147           Result[1+(jpar-1)*(*Dimension)] = v3.Y(); 
148           Result[2+(jpar-1)*(*Dimension)] = v3.Z();
149         }
150         else if (*UOrder==1) {
151           Result[(jpar-1)*(*Dimension)] = v5.X();
152           Result[1+(jpar-1)*(*Dimension)] = v5.Y(); 
153           Result[2+(jpar-1)*(*Dimension)] = v5.Z();
154         }
155         else if (*UOrder==0) {
156           Result[(jpar-1)*(*Dimension)] = v4.X();
157           Result[1+(jpar-1)*(*Dimension)] = v4.Y(); 
158           Result[2+(jpar-1)*(*Dimension)] = v4.Z();
159         }
160     }
161     break;
162   case 3 :
163     for (jpar=1;jpar<=*NbParams;jpar++) {
164         Vpar = Parameters[jpar-1];
165         myAdaptor->D3 (Upar, Vpar, pnt, v1, v2, v3, v4, v5, v6, v7, v8, v9);
166         if (*UOrder==2) {
167           Result[(jpar-1)*(*Dimension)] = v8.X();
168           Result[1+(jpar-1)*(*Dimension)] = v8.Y(); 
169           Result[2+(jpar-1)*(*Dimension)] = v8.Z();
170         }
171         else if (*UOrder==1) {
172           Result[(jpar-1)*(*Dimension)] = v9.X();
173           Result[1+(jpar-1)*(*Dimension)] = v9.Y(); 
174           Result[2+(jpar-1)*(*Dimension)] = v9.Z();
175         }
176     }
177     break;
178   case 4 :
179     for (jpar=1;jpar<=*NbParams;jpar++) {
180         Vpar = Parameters[jpar-1];
181         vect = myAdaptor->DN (Upar, Vpar, *UOrder, *VOrder);
182         Result[(jpar-1)*(*Dimension)] = vect.X();
183         Result[1+(jpar-1)*(*Dimension)] = vect.Y(); 
184         Result[2+(jpar-1)*(*Dimension)] = vect.Z();
185     }
186     break;
187   }
188  }
189  else { 
190   Vpar = *ConstParam;
191   switch (Order) {
192   case 0 :
193     for (jpar=1;jpar<=*NbParams;jpar++) {
194         Upar = Parameters[jpar-1];
195         pnt = myAdaptor->Value (Upar, Vpar);
196         Result[(jpar-1)*(*Dimension)] = pnt.X();
197         Result[1+(jpar-1)*(*Dimension)] = pnt.Y(); 
198         Result[2+(jpar-1)*(*Dimension)] = pnt.Z();
199     }
200     break;
201   case 1 :
202     for (jpar=1;jpar<=*NbParams;jpar++) {
203         Upar = Parameters[jpar-1];
204         myAdaptor->D1 (Upar, Vpar, pnt, v1, v2);
205         if (*UOrder==1) {
206           Result[(jpar-1)*(*Dimension)] = v1.X();
207           Result[1+(jpar-1)*(*Dimension)] = v1.Y(); 
208           Result[2+(jpar-1)*(*Dimension)] = v1.Z();
209         }
210         else {
211           Result[(jpar-1)*(*Dimension)] = v2.X();
212           Result[1+(jpar-1)*(*Dimension)] = v2.Y(); 
213           Result[2+(jpar-1)*(*Dimension)] = v2.Z();
214         }
215     }
216     break;
217   case 2 :
218     for (jpar=1;jpar<=*NbParams;jpar++) {
219         Upar = Parameters[jpar-1];
220         myAdaptor->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5);
221         if (*UOrder==2) {
222           Result[(jpar-1)*(*Dimension)] = v3.X();
223           Result[1+(jpar-1)*(*Dimension)] = v3.Y(); 
224           Result[2+(jpar-1)*(*Dimension)] = v3.Z();
225         }
226         else if (*UOrder==1) {
227           Result[(jpar-1)*(*Dimension)] = v5.X();
228           Result[1+(jpar-1)*(*Dimension)] = v5.Y(); 
229           Result[2+(jpar-1)*(*Dimension)] = v5.Z();
230         }
231         else if (*UOrder==0) {
232           Result[(jpar-1)*(*Dimension)] = v4.X();
233           Result[1+(jpar-1)*(*Dimension)] = v4.Y(); 
234           Result[2+(jpar-1)*(*Dimension)] = v4.Z();
235         }
236     }
237     break;
238   case 3 :
239     for (jpar=1;jpar<=*NbParams;jpar++) {
240         Upar = Parameters[jpar-1];
241         myAdaptor->D3 (Upar, Vpar, pnt, v1, v2, v3, v4, v5, v6, v7, v8, v9);
242         if (*UOrder==2) {
243           Result[(jpar-1)*(*Dimension)] = v8.X();
244           Result[1+(jpar-1)*(*Dimension)] = v8.Y(); 
245           Result[2+(jpar-1)*(*Dimension)] = v8.Z();
246         }
247         else if (*UOrder==1) {
248           Result[(jpar-1)*(*Dimension)] = v9.X();
249           Result[1+(jpar-1)*(*Dimension)] = v9.Y(); 
250           Result[2+(jpar-1)*(*Dimension)] = v9.Z();
251         }
252     }
253     break;
254   case 4 :
255     for (jpar=1;jpar<=*NbParams;jpar++) {
256         Upar = Parameters[jpar-1];
257         vect = myAdaptor->DN (Upar, Vpar, *UOrder, *VOrder);
258         Result[(jpar-1)*(*Dimension)] = vect.X();
259         Result[1+(jpar-1)*(*Dimension)] = vect.Y(); 
260         Result[2+(jpar-1)*(*Dimension)] = vect.Z();
261     }
262     break;
263   }
264  }      
265
266 }
267
268
269 //=======================================================================
270 //function : GeomConvert_ApproxSurface
271 //purpose  : 
272 //=======================================================================
273
274 GeomConvert_ApproxSurface::GeomConvert_ApproxSurface(const Handle(Geom_Surface)& Surf,
275                                                            const Standard_Real Tol3d,
276                                                            const GeomAbs_Shape UContinuity,
277                                                            const GeomAbs_Shape VContinuity,
278                                                            const Standard_Integer MaxDegU,
279                                                            const Standard_Integer MaxDegV,
280                                                            const Standard_Integer MaxSegments,
281                                                            const Standard_Integer PrecisCode)
282 {
283   Standard_Real U0, U1, V0, V1;
284
285   Handle(Adaptor3d_HSurface) aSurfAdaptor = new GeomAdaptor_HSurface (Surf);
286   Surf->Bounds(U0, U1, V0, V1);
287
288 // " Init des nombres de sous-espaces et des tolerances"
289   Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1;
290   Handle(TColStd_HArray1OfReal) nul1 =
291                  new TColStd_HArray1OfReal(1,1);
292   nul1->SetValue(1,0.);
293   Handle(TColStd_HArray2OfReal) nul2 =
294                  new TColStd_HArray2OfReal(1,1,1,4);
295   nul2->SetValue(1,1,0.);
296   nul2->SetValue(1,2,0.);
297   nul2->SetValue(1,3,0.);
298   nul2->SetValue(1,4,0.);
299   Handle(TColStd_HArray1OfReal) eps3D =
300                  new TColStd_HArray1OfReal(1,1);
301   eps3D->SetValue(1,Tol3d);
302   Handle(TColStd_HArray2OfReal) epsfr =
303                  new TColStd_HArray2OfReal(1,1,1,4);
304   epsfr->SetValue(1,1,Tol3d);
305   epsfr->SetValue(1,2,Tol3d);
306   epsfr->SetValue(1,3,Tol3d);
307   epsfr->SetValue(1,4,Tol3d);
308
309 // " Init du type d'iso"
310   GeomAbs_IsoType IsoType = GeomAbs_IsoV; 
311   Standard_Integer NbDec;
312
313   NbDec = aSurfAdaptor->NbUIntervals(GeomAbs_C2);
314   TColStd_Array1OfReal UDec_C2(1, NbDec+1);
315   aSurfAdaptor->UIntervals(UDec_C2, GeomAbs_C2);
316   NbDec = aSurfAdaptor->NbVIntervals(GeomAbs_C2);
317   TColStd_Array1OfReal VDec_C2(1, NbDec+1);
318   aSurfAdaptor->VIntervals(VDec_C2, GeomAbs_C2);
319
320   NbDec = aSurfAdaptor->NbUIntervals(GeomAbs_C3);
321   TColStd_Array1OfReal UDec_C3(1, NbDec+1);
322   aSurfAdaptor->UIntervals(UDec_C3, GeomAbs_C3);
323
324   NbDec = aSurfAdaptor->NbVIntervals(GeomAbs_C3);
325   TColStd_Array1OfReal VDec_C3(1, NbDec+1);
326   aSurfAdaptor->VIntervals(VDec_C3, GeomAbs_C3);
327   // Approximation avec decoupe preferentiel 
328   // aux lieux de discontinuitees C2
329   AdvApprox_PrefAndRec pUDec(UDec_C2,UDec_C3);
330   AdvApprox_PrefAndRec pVDec(VDec_C2,VDec_C3);
331
332 //POP pour WNT
333   GeomConvert_ApproxSurface_Eval ev (aSurfAdaptor);
334   AdvApp2Var_ApproxAFunc2Var approx(nb1, nb2, nb3,
335                                     nul1,nul1,eps3D,
336                                     nul2,nul2,epsfr,
337                                     U0,U1,V0,V1,
338                                     IsoType,UContinuity,VContinuity,PrecisCode,
339 //                                  MaxDegU,MaxDegV,MaxSegments,mySurfEval1,
340                                     MaxDegU,MaxDegV,MaxSegments,ev,
341                                     pUDec,pVDec);
342
343   myMaxError  = approx.MaxError(3,1);
344   myBSplSurf  = approx.Surface(1);
345   myIsDone    = approx.IsDone();
346   myHasResult = approx.HasResult();
347 }
348
349
350 //=======================================================================
351 //function : Surface
352 //purpose  : 
353 //=======================================================================
354
355  Handle(Geom_BSplineSurface) GeomConvert_ApproxSurface::Surface() const
356 {
357   return myBSplSurf;
358 }
359
360 //=======================================================================
361 //function : IsDone
362 //purpose  : 
363 //=======================================================================
364
365  Standard_Boolean GeomConvert_ApproxSurface::IsDone() const
366 {
367   return myIsDone;
368 }
369
370 //=======================================================================
371 //function : HasResult
372 //purpose  : 
373 //=======================================================================
374
375  Standard_Boolean GeomConvert_ApproxSurface::HasResult() const
376 {
377   return myHasResult;
378 }
379
380 //=======================================================================
381 //function : MaxError
382 //purpose  : 
383 //=======================================================================
384
385  Standard_Real GeomConvert_ApproxSurface::MaxError() const
386 {
387   return myMaxError;
388 }
389 //=======================================================================
390 //function : Dump
391 //purpose  : 
392 //=======================================================================
393
394 void GeomConvert_ApproxSurface::Dump(Standard_OStream& o) const 
395 {
396   o<<endl;
397   if (!myHasResult) { o<<"No result"<<endl; }
398   else {
399     o<<"Result max error :"<< myMaxError <<endl;
400     }
401   o<<endl;
402 }
403
404
405
406
407
408
409