1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
15 #include <Adaptor3d_Surface.hxx>
17 #include <Geom_BezierSurface.hxx>
18 #include <Geom_BSplineSurface.hxx>
19 #include <gp_Circ.hxx>
20 #include <gp_Cone.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>
31 IMPLEMENT_STANDARD_RTTIEXT(IntTools_TopolTool,Adaptor3d_TopolTool)
33 static void Analyse(const TColgp_Array2OfPnt& array2,
34 Standard_Integer& theNbSamplesU,
35 Standard_Integer& theNbSamplesV);
37 // =====================================================================================
38 // function: Constructor
40 // =====================================================================================
41 IntTools_TopolTool::IntTools_TopolTool()
49 // =====================================================================================
50 // function: Constructor
52 // =====================================================================================
53 IntTools_TopolTool::IntTools_TopolTool(const Handle(Adaptor3d_Surface)& theSurface)
55 Initialize(theSurface);
62 // =====================================================================================
63 // function: Initialize
65 // =====================================================================================
66 void IntTools_TopolTool::Initialize()
68 throw Standard_NotImplemented("IntTools_TopolTool::Initialize ()");
71 // =====================================================================================
72 // function: Initialize
74 // =====================================================================================
75 void IntTools_TopolTool::Initialize(const Handle(Adaptor3d_Surface)& theSurface)
77 Adaptor3d_TopolTool::Initialize(theSurface);
85 // =====================================================================================
86 // function: ComputeSamplePoints
88 // =====================================================================================
89 void IntTools_TopolTool::ComputeSamplePoints()
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;
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);
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;}
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;}
116 Standard_Integer nbsu = 0,nbsv = 0;
117 GeomAbs_SurfaceType typS = myS->GetType();
120 case GeomAbs_Plane: {
121 nbsu = 10; nbsv = 10;
124 case GeomAbs_Cylinder: {
125 Standard_Real aRadius = myS->Cylinder().Radius();
126 Standard_Real aMaxAngle = M_PI * 0.5;
127 Standard_Real aDeflection = 1.e-02;
129 if(aRadius > aDeflection) {
130 aMaxAngle = ACos(1. - aDeflection / aRadius) * 2.;
132 if(aMaxAngle > Precision::Angular()) {
133 nbsu = Standard_Integer((usup-uinf) / aMaxAngle);
135 nbsv = (Standard_Integer)(vsup-vinf);
138 if(nbsu < 2) nbsu = 2;
139 if(nbsv < 2) nbsv = 2;
141 // if(nbsu < 10) nbsu = 10;
142 // if(nbsv < 10) nbsv = 10;
143 if(nbsu > aMaxNbSample) nbsu = aMaxNbSample;
144 if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
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);
153 if(aRadius < aCircle.Radius())
154 aRadius = aCircle.Radius();
155 Standard_Real aMaxAngle = M_PI * 0.5;
156 Standard_Real aDeflection = 1.e-02;
158 if(aRadius > aDeflection) {
159 aMaxAngle = ACos(1. - aDeflection / aRadius) * 2.;
162 if(aMaxAngle > Precision::Angular()) {
163 nbsu = Standard_Integer((usup - uinf) / aMaxAngle);
165 nbsv = (Standard_Integer)(vsup - vinf);
168 // if(nbsu < 2) nbsu = 2;
169 // if(nbsv < 2) nbsv = 2;
171 if(nbsu < 10) nbsu = 10;
172 if(nbsv < 10) nbsv = 10;
173 if(nbsu > aMaxNbSample) nbsu = aMaxNbSample;
174 if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
178 case GeomAbs_Torus: {
180 Standard_Real aRadius1, aRadius2;
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;
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;
195 gp_Sphere aSphere = myS->Sphere();
196 aRadius1 = aSphere.Radius();
197 aRadius2 = aSphere.Radius();
199 Standard_Real aMaxAngle = M_PI * 0.5;
200 Standard_Real aDeflection = 1.e-02;
202 if(aRadius1 > aDeflection) {
203 aMaxAngle = ACos(1. - aDeflection / aRadius1) * 2.;
206 if(aMaxAngle > Precision::Angular()) {
207 nbsu = Standard_Integer((usup - uinf) / aMaxAngle);
209 aMaxAngle = M_PI * 0.5;
211 if(aRadius2 > aDeflection) {
212 aMaxAngle = ACos(1. - aDeflection / aRadius2) * 2.;
215 if(aMaxAngle > Precision::Angular()) {
216 nbsv = Standard_Integer((vsup - vinf) / aMaxAngle);
218 if(nbsu < 10) nbsu = 10;
219 if(nbsv < 10) nbsv = 10;
220 if(nbsu > aMaxNbSample) nbsu = aMaxNbSample;
221 if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
224 case GeomAbs_BezierSurface: {
225 nbsv = 3 + myS->NbVPoles();
226 nbsu = 3 + myS->NbUPoles();
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);
234 if(nbsu < 10) nbsu = 10;
235 if(nbsv < 10) nbsv = 10;
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;
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);
247 if(nbsu < 10) nbsu = 10;
248 if(nbsv < 10) nbsv = 10;
250 Standard_Real anULen = (usup - uinf) / myS->UResolution(1.);
251 Standard_Real anVLen = (vsup - vinf) / myS->VResolution(1.);
252 Standard_Real aRatio = anULen / anVLen;
256 nbsu = Min(nbsu, aMaxNbSample);
258 else if (aRatio <= 0.1 )
261 nbsv = Min(nbsv, aMaxNbSample);
265 case GeomAbs_SurfaceOfExtrusion: {
267 nbsv = (Standard_Integer)(vsup - vinf);
269 if(nbsv < 15) nbsv = 15;
270 if(nbsv > aMaxNbSample) nbsv = aMaxNbSample;
273 case GeomAbs_SurfaceOfRevolution: {
274 nbsv = 15; nbsu = 15;
278 nbsu = 10; nbsv = 10;
285 myNbSamplesU = myNbSmplU;
286 myNbSamplesV = myNbSmplV;
288 myDU = (usup - uinf)/(myNbSmplU + 1);
289 myDV = (vsup - vinf)/(myNbSmplV + 1);
292 // =====================================================================================
293 // function: NbSamplesU
295 // =====================================================================================
296 Standard_Integer IntTools_TopolTool::NbSamplesU()
299 ComputeSamplePoints();
304 // =====================================================================================
305 // function: NbSamplesV
307 // =====================================================================================
308 Standard_Integer IntTools_TopolTool::NbSamplesV()
311 ComputeSamplePoints();
316 // =====================================================================================
317 // function: NbSamples
319 // =====================================================================================
320 Standard_Integer IntTools_TopolTool::NbSamples()
323 ComputeSamplePoints();
325 return(myNbSmplU * myNbSmplV);
328 // =====================================================================================
329 // function: SamplePoint
331 // =====================================================================================
332 void IntTools_TopolTool::SamplePoint(const Standard_Integer Index,
336 if (myUPars.IsNull())
339 ComputeSamplePoints();
341 Standard_Integer iv = 1 + Index / myNbSmplU;
342 Standard_Integer iu = 1 + Index - (iv - 1) * myNbSmplU;
343 Standard_Real u = myU0 + iu * myDU;
344 Standard_Real v = myV0 + iv * myDV;
346 P3d = myS->Value(u, v);
349 Adaptor3d_TopolTool::SamplePoint(Index, P2d, P3d);
353 //=======================================================================
354 // function : Analyse
356 //=======================================================================
357 void Analyse(const TColgp_Array2OfPnt& array2,
358 Standard_Integer& theNbSamplesU,
359 Standard_Integer& theNbSamplesV)
362 Standard_Integer sh,nbch,i,j;
363 const Standard_Integer nbup = array2.UpperRow() - array2.LowerRow() + 1;
364 const Standard_Integer nbvp = array2.UpperCol() - array2.LowerCol() + 1;
370 for(i = array2.LowerRow(); i <= array2.UpperRow(); i++) {
371 const gp_Pnt& A=array2.Value(i,1);
372 const gp_Pnt& B=array2.Value(i,2);
373 const gp_Pnt& C=array2.Value(i,3);
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;
379 for(j = array2.LowerCol() + 2; j < array2.UpperCol();j++) { //-- essai
380 const gp_Pnt& Ax=array2.Value(i,j-1);
381 const gp_Pnt& Bx=array2.Value(i,j);
382 const gp_Pnt& Cx=array2.Value(i,j+1);
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);
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++; } }
398 theNbSamplesV = nbch+5;
403 for(j = array2.LowerCol(); j <= array2.UpperCol(); j++) {
404 const gp_Pnt& A=array2.Value(array2.LowerRow(), j);
405 const gp_Pnt& B=array2.Value(array2.LowerRow() + 1, j);
406 const gp_Pnt& C=array2.Value(array2.LowerRow() + 2, j);
407 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
408 C.Y()-B.Y()-B.Y()+A.Y(),
409 C.Z()-B.Z()-B.Z()+A.Z());
410 Standard_Integer locnbch=0;
412 for(i = array2.LowerRow() + 2; i < array2.UpperRow(); i++) { //-- essai
413 const gp_Pnt& Ax=array2.Value(i-1,j);
414 const gp_Pnt& Bx=array2.Value(i,j);
415 const gp_Pnt& Cx=array2.Value(i+1,j);
416 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
417 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
418 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
419 Standard_Real pd = Vi.Dot(Vip1);
421 if(pd>1.0e-7 || pd<-1.0e-7) {
422 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
423 else { if(sh==1) { sh=-1; locnbch++; } }
426 if(locnbch>nbch) nbch=locnbch;
429 theNbSamplesU = nbch+5;
433 //=======================================================================
434 //function : SamplePnts
436 //=======================================================================
438 void IntTools_TopolTool::SamplePnts(const Standard_Real theDefl,
439 const Standard_Integer theNUmin,
440 const Standard_Integer theNVmin)
442 Adaptor3d_TopolTool::SamplePnts(theDefl, theNUmin, theNVmin);
444 myNbSmplU = Adaptor3d_TopolTool::NbSamplesU();
445 myNbSmplV = Adaptor3d_TopolTool::NbSamplesV();
447 myU0 = myUPars->Value(1);
448 myV0 = myVPars->Value(1);
450 myDU = (myUPars->Value(myNbSmplU) - myU0)/(myNbSmplU-1);
451 myDV = (myVPars->Value(myNbSmplV) - myV0)/(myNbSmplV-1);