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