0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Extrema / Extrema_ExtPS.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15//-----------------------------------------------------------------
7fd59977 16
7fd59977 17#include <ElCLib.hxx>
7fd59977 18#include <Extrema_ExtPExtS.hxx>
19#include <Extrema_ExtPRevS.hxx>
42cf5bc1 20#include <Extrema_ExtPS.hxx>
21#include <Extrema_GenExtPS.hxx>
7fd59977 22#include <Extrema_POnSurf.hxx>
23#include <GeomAbs_IsoType.hxx>
42cf5bc1 24#include <gp_Pnt.hxx>
42cf5bc1 25#include <Precision.hxx>
26#include <Standard_NotImplemented.hxx>
27#include <Standard_OutOfRange.hxx>
42cf5bc1 28#include <StdFail_NotDone.hxx>
7fd59977 29
30//=======================================================================
31//function : IsoIsDeg
32//purpose :
33//=======================================================================
7fd59977 34static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
35 const Standard_Real Param,
36 const GeomAbs_IsoType IT,
37 const Standard_Real TolMin,
38 const Standard_Real TolMax)
39{
40 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
41 Standard_Boolean Along = Standard_True;
42 U1 = S.FirstUParameter();
43 U2 = S.LastUParameter();
44 V1 = S.FirstVParameter();
45 V2 = S.LastVParameter();
46 gp_Vec D1U,D1V;
47 gp_Pnt P;
48 Standard_Real Step,D1NormMax;
49 if (IT == GeomAbs_IsoV)
50 {
5368adff 51 if( !Precision::IsInfinite(U1) && !Precision::IsInfinite(U2) )
7fd59977 52 {
5368adff 53 Step = (U2 - U1)/10;
54 if(Step < Precision::PConfusion()) {
55 return Standard_False;
56 }
57 D1NormMax=0.;
58
59 for (T=U1;T<=U2;T=T+Step)
60 {
61 S.D1(T,Param,P,D1U,D1V);
62 D1NormMax=Max(D1NormMax,D1U.Magnitude());
63 }
64
65 if (D1NormMax >TolMax || D1NormMax < TolMin )
66 Along = Standard_False;
7fd59977 67 }
7fd59977 68 }
69 else
70 {
5368adff 71 if( !Precision::IsInfinite(V1) && !Precision::IsInfinite(V2) )
7fd59977 72 {
5368adff 73 Step = (V2 - V1)/10;
74 if(Step < Precision::PConfusion()) {
75 return Standard_False;
76 }
77 D1NormMax=0.;
78 for (T=V1;T<=V2;T=T+Step)
79 {
80 S.D1(Param,T,P,D1U,D1V);
81 D1NormMax=Max(D1NormMax,D1V.Magnitude());
82 }
83
84 if (D1NormMax >TolMax || D1NormMax < TolMin )
85 Along = Standard_False;
7fd59977 86 }
87
7fd59977 88
89
90 }
91 return Along;
92}
93
94//=======================================================================
95//function : TreatSolution
96//purpose :
97//=======================================================================
98
99void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
100 const Standard_Real Val)
101{
102 Standard_Real U, V;
103 PS.Parameter(U, V);
104 if (myS->IsUPeriodic()) {
9bf3177f 105 U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod());
106
107 // Handle trimmed surfaces.
108 if (U > myusup + mytolu)
109 U -= myS->UPeriod();
110 if (U < myuinf - mytolu)
111 U += myS->UPeriod();
7fd59977 112 }
113 if (myS->IsVPeriodic()) {
9bf3177f 114 V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod());
115
116 // Handle trimmed surfaces.
117 if (V > myvsup + mytolv)
118 V -= myS->VPeriod();
119 if (V < myvinf - mytolv)
120 V += myS->VPeriod();
7fd59977 121 }
122 if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
123 (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
124 myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
125 mySqDist.Append(Val);
126 }
127}
128
129
130//=======================================================================
131//function : Extrema_ExtPS
132//purpose :
133//=======================================================================
134
0734c53d 135Extrema_ExtPS::Extrema_ExtPS()
d533dafb 136: myS(NULL),
137 myDone(Standard_False),
138 myuinf(0.0),
139 myusup(0.0),
140 myvinf(0.0),
141 myvsup(0.0),
142 mytolu(0.0),
143 mytolv(0.0),
144 d11(0.0),
145 d12(0.0),
146 d21(0.0),
147 d22(0.0),
148 mytype(GeomAbs_OtherSurface)
7fd59977 149{
7fd59977 150}
151
152
153//=======================================================================
154//function : Extrema_ExtPS
155//purpose :
156//=======================================================================
157
0734c53d 158Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
159 const Adaptor3d_Surface& theS,
160 const Standard_Real theTolU,
161 const Standard_Real theTolV,
162 const Extrema_ExtFlag theF,
163 const Extrema_ExtAlgo theA)
7fd59977 164{
0734c53d 165 myExtPS.SetFlag (theF);
166 myExtPS.SetAlgo (theA);
167
168 Initialize (theS,
169 theS.FirstUParameter(),
170 theS.LastUParameter(),
171 theS.FirstVParameter(),
172 theS.LastVParameter(),
173 theTolU,
174 theTolV);
175
176 Perform (theP);
7fd59977 177}
178
179//=======================================================================
180//function : Extrema_ExtPS
181//purpose :
182//=======================================================================
183
0734c53d 184Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
185 const Adaptor3d_Surface& theS,
186 const Standard_Real theUinf,
187 const Standard_Real theUsup,
188 const Standard_Real theVinf,
189 const Standard_Real theVsup,
190 const Standard_Real theTolU,
191 const Standard_Real theTolV,
192 const Extrema_ExtFlag theF,
193 const Extrema_ExtAlgo theA)
7fd59977 194{
0734c53d 195 myExtPS.SetFlag (theF);
196 myExtPS.SetAlgo (theA);
197
198 Initialize (theS,
199 theUinf,
200 theUsup,
201 theVinf,
202 theVsup,
203 theTolU,
204 theTolV);
205
206 Perform (theP);
7fd59977 207}
208
209
210//=======================================================================
211//function : Initialize
212//purpose :
213//=======================================================================
214
0734c53d 215void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
216 const Standard_Real theUinf,
217 const Standard_Real theUsup,
218 const Standard_Real theVinf,
219 const Standard_Real theVsup,
220 const Standard_Real theTolU,
221 const Standard_Real theTolV)
7fd59977 222{
d6e050ac 223 myS = &theS;
0734c53d 224 myuinf = theUinf;
225 myusup = theUsup;
226 myvinf = theVinf;
227 myvsup = theVsup;
7fd59977 228
229 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
230 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
231 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
232 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
233
0734c53d 234 mytolu = theTolU;
235 mytolv = theTolV;
7fd59977 236 mytype = myS->GetType();
237
238 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
0734c53d 239 myS->GetType() == GeomAbs_BezierSurface );
7fd59977 240
241 Standard_Integer nbU = (isB) ? 44 : 32;
242 Standard_Integer nbV = (isB) ? 44 : 32;
243
244 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
245
246 if(myS->GetType() != GeomAbs_Plane) {
0734c53d 247 bUIsoIsDeg = IsoIsDeg(theS, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
248 IsoIsDeg(theS, myusup, GeomAbs_IsoU, 0., 1.e-9);
249 bVIsoIsDeg = IsoIsDeg(theS, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
250 IsoIsDeg(theS, myvsup, GeomAbs_IsoV, 0., 1.e-9);
7fd59977 251 }
252
253 if(bUIsoIsDeg) nbU = 300;
254 if(bVIsoIsDeg) nbV = 300;
255
256 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
0734c53d 257
258 myExtPExtS.Nullify();
259 myExtPRevS.Nullify();
7fd59977 260}
261
262//=======================================================================
263//function : Perform
264//purpose :
265//=======================================================================
266
0734c53d 267void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
7fd59977 268{
269 myPoints.Clear();
270 mySqDist.Clear();
0734c53d 271
272 switch (mytype)
273 {
274 case GeomAbs_Cylinder:
275 myExtPElS.Perform (thePoint, myS->Cylinder(), Precision::Confusion());
276 break;
277 case GeomAbs_Plane:
278 myExtPElS.Perform (thePoint, myS->Plane(), Precision::Confusion());
279 break;
280 case GeomAbs_Cone:
281 myExtPElS.Perform (thePoint, myS->Cone(), Precision::Confusion());
282 break;
283 case GeomAbs_Sphere:
284 myExtPElS.Perform (thePoint, myS->Sphere(), Precision::Confusion());
285 break;
286 case GeomAbs_Torus:
287 myExtPElS.Perform (thePoint, myS->Torus(), Precision::Confusion());
288 break;
289
290 case GeomAbs_SurfaceOfExtrusion:
291 {
292 if (myExtPExtS.IsNull())
293 {
c22b52d6 294 Handle(GeomAdaptor_SurfaceOfLinearExtrusion) aS (new GeomAdaptor_SurfaceOfLinearExtrusion (
6b84c3f7 295 GeomAdaptor_SurfaceOfLinearExtrusion (myS->BasisCurve(), myS->Direction())));
0734c53d 296
297 myExtPExtS = new Extrema_ExtPExtS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
298 }
299 else
300 {
301 myExtPExtS->Perform (thePoint);
7fd59977 302 }
7fd59977 303
0734c53d 304 myDone = myExtPExtS->IsDone();
305 if (myDone)
306 {
307 for (Standard_Integer anIdx = 1; anIdx <= myExtPExtS->NbExt(); ++anIdx)
308 {
309 TreatSolution (myExtPExtS->Point (anIdx), myExtPExtS->SquareDistance (anIdx));
310 }
7fd59977 311 }
7fd59977 312
0734c53d 313 return;
314 }
315
316 case GeomAbs_SurfaceOfRevolution:
317 {
318 if (myExtPRevS.IsNull())
319 {
c22b52d6 320 Handle(GeomAdaptor_SurfaceOfRevolution) aS (new GeomAdaptor_SurfaceOfRevolution (
6b84c3f7 321 GeomAdaptor_SurfaceOfRevolution (myS->BasisCurve(), myS->AxeOfRevolution())));
0734c53d 322
323 myExtPRevS = new Extrema_ExtPRevS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
324 }
325 else
326 {
327 myExtPRevS->Perform (thePoint);
328 }
329
330 myDone = myExtPRevS->IsDone();
331 if (myDone)
332 {
333 for (Standard_Integer anIdx = 1; anIdx <= myExtPRevS->NbExt(); ++anIdx)
334 {
335 TreatSolution (myExtPRevS->Point (anIdx), myExtPRevS->SquareDistance (anIdx));
336 }
337 }
338
339 return;
340 }
341
342 default:
343 {
344 myExtPS.Perform (thePoint);
345 myDone = myExtPS.IsDone();
346 if (myDone)
347 {
348 for (Standard_Integer anIdx = 1; anIdx <= myExtPS.NbExt(); ++anIdx)
349 {
350 TreatSolution (myExtPS.Point (anIdx), myExtPS.SquareDistance (anIdx));
351 }
352 }
353 return;
354 }
7fd59977 355 }
356
7fd59977 357 myDone = myExtPElS.IsDone();
0734c53d 358 if (myDone)
359 {
360 for (Standard_Integer anIdx = 1; anIdx <= myExtPElS.NbExt(); ++anIdx)
361 {
362 TreatSolution (myExtPElS.Point (anIdx), myExtPElS.SquareDistance (anIdx));
363 }
364 }
7fd59977 365}
366
367
7fd59977 368Standard_Boolean Extrema_ExtPS::IsDone() const
369{
370 return myDone;
371}
372
373
374Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
375{
638ad7f3 376 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 377 return mySqDist.Value(N);
378}
379
380
381Standard_Integer Extrema_ExtPS::NbExt() const
382{
638ad7f3 383 if (!IsDone()) throw StdFail_NotDone();
7fd59977 384 return mySqDist.Length();
385}
386
387
5d99f2c8 388const Extrema_POnSurf& Extrema_ExtPS::Point(const Standard_Integer N) const
7fd59977 389{
638ad7f3 390 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 391 return myPoints.Value(N);
392}
393
394
395void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
396 Standard_Real& dUfVl,
397 Standard_Real& dUlVf,
398 Standard_Real& dUlVl,
399 gp_Pnt& PUfVf,
400 gp_Pnt& PUfVl,
401 gp_Pnt& PUlVf,
402 gp_Pnt& PUlVl) const
403{
404 dUfVf = d11;
405 dUfVl = d12;
406 dUlVf = d21;
407 dUlVl = d22;
408 PUfVf = P11;
409 PUfVl = P12;
410 PUlVf = P21;
411 PUlVl = P22;
412}
92d1589b
A
413
414void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
415{
416 myExtPS.SetFlag(F);
417}
418
419void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)
420{
421 myExtPS.SetAlgo(A);
0d969553 422}