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