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