0022627: Change OCCT memory management defaults
[occt.git] / src / IntTools / IntTools_TopolTool.cxx
1 #include <IntTools_TopolTool.ixx>
2
3 #include <Standard_NotImplemented.hxx>
4 #include <Precision.hxx>
5 #include <TColgp_Array2OfPnt.hxx>
6 #include <Geom_BSplineSurface.hxx>
7 #include <Geom_BezierSurface.hxx>
8 #include <gp_Circ.hxx>
9 #include <gp_Cone.hxx>
10 #include <ElSLib.hxx>
11
12 #include <TColStd_HArray1OfReal.hxx>
13
14 static void Analyse(const TColgp_Array2OfPnt& array2,
15                     Standard_Integer&         theNbSamplesU,
16                     Standard_Integer&         theNbSamplesV);
17
18 // =====================================================================================
19 // function: Constructor
20 // purpose:
21 // =====================================================================================
22 IntTools_TopolTool::IntTools_TopolTool()
23 {
24   myNbSmplU = 0;
25   myNbSmplV = 0;
26   myDU = 1.;
27   myDV = 1.;
28 }
29
30 // =====================================================================================
31 // function: Constructor
32 // purpose:
33 // =====================================================================================
34 IntTools_TopolTool::IntTools_TopolTool(const Handle(Adaptor3d_HSurface)& theSurface)
35 {
36   Initialize(theSurface);
37   myNbSmplU = 0;
38   myNbSmplV = 0;
39   myDU = 1.;
40   myDV = 1.;
41 }
42
43 // =====================================================================================
44 // function: Initialize
45 // purpose:
46 // =====================================================================================
47 void IntTools_TopolTool::Initialize() 
48 {
49   Standard_NotImplemented::Raise("IntTools_TopolTool::Initialize ()");
50 }
51
52 // =====================================================================================
53 // function: Initialize
54 // purpose:
55 // =====================================================================================
56 void IntTools_TopolTool::Initialize(const Handle(Adaptor3d_HSurface)& theSurface) 
57 {
58   Adaptor3d_TopolTool::Initialize(theSurface);
59   //myS = theSurface;
60   myNbSmplU = 0;
61   myNbSmplV = 0;
62   myDU = 1.;
63   myDV = 1.;
64 }
65
66 // =====================================================================================
67 // function: ComputeSamplePoints
68 // purpose:
69 // =====================================================================================
70 void IntTools_TopolTool::ComputeSamplePoints() 
71 {
72   Standard_Real uinf, usup, vinf, vsup;
73   uinf = myS->FirstUParameter();  
74   usup = myS->LastUParameter();
75   vinf = myS->FirstVParameter();  
76   vsup = myS->LastVParameter();
77   const Standard_Integer aMaxNbSample = 50;
78
79   if (usup < uinf) { Standard_Real temp = uinf; uinf = usup; usup = temp; }
80   if (vsup < vinf) { Standard_Real temp = vinf; vinf = vsup; vsup = temp; }
81   Standard_Boolean isbiguinf, isbigusup, isbigvinf, isbigvsup;
82   isbiguinf = Precision::IsNegativeInfinite(uinf);
83   isbigusup = Precision::IsPositiveInfinite(usup);
84   isbigvinf = Precision::IsNegativeInfinite(vinf);
85   isbigvsup = Precision::IsPositiveInfinite(vsup);
86
87   if(isbiguinf && isbigusup) {uinf = -1.e5; usup = 1.e5;}
88   else if(isbiguinf) {uinf = usup - 2.e5;}
89   else if(isbigusup) {usup = uinf + 2.e5;}
90
91   if(isbigvinf && isbigvsup) {vinf = -1.e5; vsup = 1.e5;}
92   else if(isbigvinf) {vinf = vsup - 2.e5;}
93   else if(isbigvsup) {vsup = vinf + 2.e5;}
94   myU0 = uinf;
95   myV0 = vinf;
96
97   Standard_Integer nbsu,nbsv;
98   GeomAbs_SurfaceType typS = myS->GetType();
99
100   switch(typS) {
101   case GeomAbs_Plane: { 
102     nbsu = 10; nbsv = 10;
103   }
104     break;
105   case GeomAbs_Cylinder: {
106     Standard_Real aRadius = myS->Cylinder().Radius();
107     Standard_Real aMaxAngle = M_PI * 0.5;
108     Standard_Real aDeflection = 1.e-02;
109
110     if(aRadius > aDeflection) {
111       aMaxAngle = ACos(1. - aDeflection / aRadius) * 2.;
112     }
113     if(aMaxAngle > Precision::Angular()) {
114       nbsu = Standard_Integer((usup-uinf) / aMaxAngle);
115     }
116     nbsv = (Standard_Integer)(vsup-vinf);
117     nbsv /= 10;
118
119     if(nbsu < 2) nbsu = 2;
120     if(nbsv < 2) nbsv = 2;
121
122 //    if(nbsu < 10) nbsu = 10;
123 //    if(nbsv < 10) nbsv = 10;
124     if(nbsu > aMaxNbSample) nbsu = aMaxNbSample;
125     if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
126   }
127     break;
128   case GeomAbs_Cone: {
129     gp_Cone aCone = myS->Cone();
130     gp_Circ aCircle = ElSLib::ConeVIso(aCone.Position(), aCone.RefRadius(), aCone.SemiAngle(), vinf);
131     Standard_Real aRadius = aCircle.Radius();
132     aCircle = ElSLib::ConeVIso(aCone.Position(), aCone.RefRadius(), aCone.SemiAngle(), vsup);
133
134     if(aRadius < aCircle.Radius())
135       aRadius = aCircle.Radius();
136     Standard_Real aMaxAngle = M_PI * 0.5;
137     Standard_Real aDeflection = 1.e-02;
138
139     if(aRadius > aDeflection) {
140       aMaxAngle = ACos(1. - aDeflection / aRadius) * 2.;
141     }
142
143     if(aMaxAngle > Precision::Angular()) {
144       nbsu = Standard_Integer((usup - uinf) / aMaxAngle);
145     }
146     nbsv = (Standard_Integer)(vsup - vinf);
147     nbsv /= 10;
148
149 //     if(nbsu < 2) nbsu = 2;
150 //     if(nbsv < 2) nbsv = 2;
151
152     if(nbsu < 10) nbsu = 10;
153     if(nbsv < 10) nbsv = 10;
154     if(nbsu > aMaxNbSample) nbsu = aMaxNbSample;
155     if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
156   }
157     break;
158   case GeomAbs_Sphere:
159   case GeomAbs_Torus: {
160     gp_Circ aCircle;
161     Standard_Real aRadius1, aRadius2;
162
163     if(typS == GeomAbs_Torus) {
164       gp_Torus aTorus = myS->Torus();
165       aCircle = ElSLib::TorusUIso(aTorus.Position(), aTorus.MajorRadius(), aTorus.MinorRadius(), uinf);
166       aRadius2 = aCircle.Radius();
167       aCircle = ElSLib::TorusUIso(aTorus.Position(), aTorus.MajorRadius(), aTorus.MinorRadius(), usup);
168       aRadius2 = (aRadius2 < aCircle.Radius()) ? aCircle.Radius() : aRadius2;
169       
170       aCircle = ElSLib::TorusVIso(aTorus.Position(), aTorus.MajorRadius(), aTorus.MinorRadius(), vinf);
171       aRadius1 = aCircle.Radius();
172       aCircle = ElSLib::TorusVIso(aTorus.Position(), aTorus.MajorRadius(), aTorus.MinorRadius(), vsup);
173       aRadius1 = (aRadius1 < aCircle.Radius()) ? aCircle.Radius() : aRadius1;
174     }
175     else {
176       gp_Sphere aSphere = myS->Sphere();
177       aRadius1 = aSphere.Radius();
178       aRadius2 = aSphere.Radius();
179     }
180     Standard_Real aMaxAngle = M_PI * 0.5;
181     Standard_Real aDeflection = 1.e-02;
182     
183     if(aRadius1 > aDeflection) {
184       aMaxAngle = ACos(1. - aDeflection / aRadius1) * 2.;
185     }
186     
187     if(aMaxAngle > Precision::Angular()) {
188       nbsu = Standard_Integer((usup - uinf) / aMaxAngle);
189     }
190     aMaxAngle = M_PI * 0.5;
191
192     if(aRadius2 > aDeflection) {
193       aMaxAngle = ACos(1. - aDeflection / aRadius2) * 2.;
194     }
195     
196     if(aMaxAngle > Precision::Angular()) {
197       nbsv = Standard_Integer((vsup - vinf) / aMaxAngle);
198     }
199     if(nbsu < 10) nbsu = 10;
200     if(nbsv < 10) nbsv = 10;
201     if(nbsu > aMaxNbSample) nbsu = aMaxNbSample;
202     if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
203   }
204     break;
205   case GeomAbs_BezierSurface: {
206     nbsv = 3 + myS->NbVPoles(); 
207     nbsu = 3 + myS->NbUPoles();
208
209     if(nbsu > 10 || nbsv > 10) {
210       TColgp_Array2OfPnt array2(1, myS->NbUPoles(), 1, myS->NbVPoles());
211       myS->Bezier()->Poles(array2);
212       Analyse(array2, nbsu, nbsv);
213     }
214
215     if(nbsu < 10) nbsu = 10;
216     if(nbsv < 10) nbsv = 10;
217   }
218     break;
219   case GeomAbs_BSplineSurface: {
220     nbsv = myS->NbVKnots();     nbsv *= myS->VDegree();     if(nbsv < 4) nbsv=4;    
221     nbsu = myS->NbUKnots();     nbsu *= myS->UDegree();     if(nbsu < 4) nbsu=4;
222     
223     if(nbsu > 10 || nbsv > 10) {
224       TColgp_Array2OfPnt array2(1, myS->NbUPoles(), 1, myS->NbVPoles());
225       myS->BSpline()->Poles(array2);
226       Analyse(array2, nbsu, nbsv);
227     }
228     if(nbsu < 10) nbsu = 10;
229     if(nbsv < 10) nbsv = 10;
230   }
231     break;
232   case GeomAbs_SurfaceOfExtrusion: {
233     nbsu = 15;
234     nbsv = (Standard_Integer)(vsup - vinf);
235     nbsv /= 10;
236     if(nbsv < 15) nbsv = 15;
237     if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
238   }
239     break;
240   case GeomAbs_SurfaceOfRevolution: {
241     nbsv = 15; nbsu = 15;
242   }
243     break;
244   default: {
245     nbsu = 10; nbsv = 10;
246   }
247     break;
248   }
249   myNbSmplU = nbsu;
250   myNbSmplV = nbsv;
251
252   myNbSamplesU = myNbSmplU;
253   myNbSamplesV = myNbSmplV;
254
255   myDU = (usup - uinf)/(myNbSmplU + 1);
256   myDV = (vsup - vinf)/(myNbSmplV + 1);
257 }
258
259 // =====================================================================================
260 // function: NbSamplesU
261 // purpose:
262 // =====================================================================================
263 Standard_Integer IntTools_TopolTool::NbSamplesU() 
264 {
265   if(myNbSmplU <= 0) {
266     ComputeSamplePoints();
267   }
268   return myNbSmplU;
269 }
270
271 // =====================================================================================
272 // function: NbSamplesV
273 // purpose:
274 // =====================================================================================
275 Standard_Integer IntTools_TopolTool::NbSamplesV() 
276 {
277   if(myNbSmplV <= 0) {
278     ComputeSamplePoints();
279   }
280   return myNbSmplV;
281 }
282
283 // =====================================================================================
284 // function: NbSamples
285 // purpose:
286 // =====================================================================================
287 Standard_Integer IntTools_TopolTool::NbSamples() 
288 {
289   if(myNbSmplU <= 0) { 
290     ComputeSamplePoints();    
291   }
292   return(myNbSmplU * myNbSmplV);
293 }
294
295 // =====================================================================================
296 // function: SamplePoint
297 // purpose:
298 // =====================================================================================
299 void IntTools_TopolTool::SamplePoint(const Standard_Integer Index,
300                                      gp_Pnt2d&              P2d,
301                                      gp_Pnt&                P3d) 
302 {
303   if (myUPars.IsNull())
304     {
305       if(myNbSmplU <= 0) { 
306         ComputeSamplePoints();    
307       }
308       Standard_Integer iv = 1 + Index / myNbSmplU;
309       Standard_Integer iu = 1 + Index - (iv - 1) * myNbSmplU;
310       Standard_Real u = myU0 + iu * myDU;
311       Standard_Real v = myV0 + iv * myDV;
312       P2d.SetCoord(u, v);
313       P3d = myS->Value(u, v);
314     }
315   else
316     Adaptor3d_TopolTool::SamplePoint(Index, P2d, P3d);
317 }
318
319
320 //=======================================================================
321 // function : Analyse
322 // purpose  : 
323 //=======================================================================
324 void Analyse(const TColgp_Array2OfPnt& array2,
325              Standard_Integer&         theNbSamplesU,
326              Standard_Integer&         theNbSamplesV) 
327
328   gp_Vec Vi,Vip1;
329   Standard_Integer sh,nbch,i,j;
330   const Standard_Integer nbup = array2.UpperRow() - array2.LowerRow() + 1;
331   const Standard_Integer nbvp = array2.UpperCol() - array2.LowerCol() + 1;
332   
333   sh = 1;
334   nbch = 0;
335   if(nbvp>2) {
336
337     for(i = array2.LowerRow(); i <= array2.UpperRow(); i++) {
338       const gp_Pnt& A=array2.Value(i,1);
339       const gp_Pnt& B=array2.Value(i,2);
340       const gp_Pnt& C=array2.Value(i,3);
341       Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
342                   C.Y()-B.Y()-B.Y()+A.Y(),
343                   C.Z()-B.Z()-B.Z()+A.Z());
344       Standard_Integer locnbch=0;
345
346       for(j = array2.LowerCol() + 2; j < array2.UpperCol();j++) {  //-- essai
347         const gp_Pnt& Ax=array2.Value(i,j-1);
348         const gp_Pnt& Bx=array2.Value(i,j);
349         const gp_Pnt& Cx=array2.Value(i,j+1);
350         Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
351                       Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
352                       Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
353         Standard_Real pd = Vi.Dot(Vip1);
354         Vi=Vip1;
355         if(pd>1.0e-7 || pd<-1.0e-7) {  
356           if(pd>0) {  if(sh==-1) {   sh=1; locnbch++;   }  }
357           else {        if(sh==1) {  sh=-1; locnbch++;  }  }
358         }
359       }
360       if(locnbch>nbch) { 
361         nbch=locnbch; 
362       }
363     }
364   }
365   theNbSamplesV = nbch+5;
366   
367
368   nbch=0;
369   if(nbup > 2) { 
370     for(j = array2.LowerCol(); j <= array2.UpperCol(); j++) { 
371       const gp_Pnt& A=array2.Value(array2.LowerRow(),     j);
372       const gp_Pnt& B=array2.Value(array2.LowerRow() + 1, j);
373       const gp_Pnt& C=array2.Value(array2.LowerRow() + 2, j);
374       Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
375                   C.Y()-B.Y()-B.Y()+A.Y(),
376                   C.Z()-B.Z()-B.Z()+A.Z());
377       Standard_Integer locnbch=0;
378
379       for(i = array2.LowerRow() + 2; i < array2.UpperRow(); i++) {  //-- essai
380         const gp_Pnt& Ax=array2.Value(i-1,j);
381         const gp_Pnt& Bx=array2.Value(i,j);
382         const gp_Pnt& Cx=array2.Value(i+1,j);
383         Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
384                     Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
385                     Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
386         Standard_Real pd = Vi.Dot(Vip1);
387         Vi=Vip1;
388         if(pd>1.0e-7 || pd<-1.0e-7) {  
389           if(pd>0) {  if(sh==-1) {   sh=1; locnbch++;   }  }
390           else {        if(sh==1) {  sh=-1; locnbch++;  }  }
391         }
392       }
393       if(locnbch>nbch) nbch=locnbch;
394     }  
395   }
396   theNbSamplesU = nbch+5;
397 }
398
399 //Modified IFV
400 //=======================================================================
401 //function : SamplePnts
402 //purpose  : 
403 //=======================================================================
404
405 void IntTools_TopolTool::SamplePnts(const Standard_Real theDefl, 
406                                     const Standard_Integer theNUmin,
407                                     const Standard_Integer theNVmin)
408
409   Adaptor3d_TopolTool::SamplePnts(theDefl, theNUmin, theNVmin);
410
411   myNbSmplU = Adaptor3d_TopolTool::NbSamplesU();
412   myNbSmplV = Adaptor3d_TopolTool::NbSamplesV();
413
414   myU0 = myUPars->Value(1);
415   myV0 = myVPars->Value(1);
416
417   myDU = (myUPars->Value(myNbSmplU) - myU0)/(myNbSmplU-1);  
418   myDV = (myVPars->Value(myNbSmplV) - myU0)/(myNbSmplV-1);
419 }