0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / GCPnts / GCPnts_UniformDeflection.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
42cf5bc1 15#include <GCPnts_UniformDeflection.hxx>
3d42fbc1 16
17#include <CPnts_UniformDeflection.hxx>
18#include <GCPnts_DeflectionType.hxx>
19#include <GCPnts_TCurveTypes.hxx>
42cf5bc1 20#include <gp_Pnt.hxx>
21#include <gp_Pnt2d.hxx>
7fd59977 22#include <Standard_NotImplemented.hxx>
42cf5bc1 23#include <StdFail_NotDone.hxx>
24
7fd59977 25// mask the return of a Adaptor2d_Curve2d as a gp_Pnt
3d42fbc1 26static gp_Pnt Value (const Adaptor3d_Curve& theC,
27 const Standard_Real theParameter)
7fd59977 28{
3d42fbc1 29 return theC.Value (theParameter);
7fd59977 30}
3d42fbc1 31
32static gp_Pnt Value (const Adaptor2d_Curve2d& theC,
33 const Standard_Real theParameter)
7fd59977 34{
3d42fbc1 35 const gp_Pnt2d a2dPoint = theC.Value (theParameter);
36 return gp_Pnt (a2dPoint.X(), a2dPoint.Y(), 0.0);
7fd59977 37}
3d42fbc1 38
7fd59977 39//=======================================================================
3d42fbc1 40//function : GCPnts_UniformDeflection
41//purpose :
7fd59977 42//=======================================================================
3d42fbc1 43GCPnts_UniformDeflection::GCPnts_UniformDeflection()
44: myDone (Standard_False),
45 myDeflection (0.0)
46{
47 //
48}
7fd59977 49
3d42fbc1 50//=======================================================================
51//function : GCPnts_UniformDeflection
52//purpose :
53//=======================================================================
54GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor3d_Curve& theC,
55 const Standard_Real theDeflection,
56 const Standard_Real theU1,
57 const Standard_Real theU2,
58 const Standard_Boolean theWithControl)
59: myDone (Standard_False),
60 myDeflection (theDeflection)
61{
62 Initialize (theC, theDeflection, theU1, theU2, theWithControl);
63}
64
65//=======================================================================
66//function : GCPnts_UniformDeflection
67//purpose :
68//=======================================================================
69GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor3d_Curve& theC,
70 const Standard_Real theDeflection,
71 const Standard_Boolean theWithControl)
72: myDone (Standard_False),
73 myDeflection (theDeflection)
74{
75 Initialize (theC, theDeflection, theWithControl);
76}
77
78//=======================================================================
79//function : GCPnts_UniformDeflection
80//purpose :
81//=======================================================================
82GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor2d_Curve2d& theC,
83 const Standard_Real theDeflection,
84 const Standard_Real theU1,
85 const Standard_Real theU2,
86 const Standard_Boolean theWithControl)
87: myDone (Standard_False),
88 myDeflection (theDeflection)
89{
90 Initialize (theC, theDeflection, theU1, theU2, theWithControl);
7fd59977 91}
3d42fbc1 92
7fd59977 93//=======================================================================
94//function : GCPnts_UniformDeflection
3d42fbc1 95//purpose :
96//=======================================================================
97GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor2d_Curve2d& theC,
98 const Standard_Real theDeflection,
99 const Standard_Boolean theWithControl)
100: myDone (Standard_False),
101 myDeflection (theDeflection)
102{
103 Initialize (theC, theDeflection, theWithControl);
104}
105
106//=======================================================================
107//function : Initialize
108//purpose :
109//=======================================================================
110void GCPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& theC,
111 const Standard_Real theDeflection,
112 const Standard_Boolean theWithControl)
113{
114 Initialize (theC, theDeflection, theC.FirstParameter(), theC.LastParameter(), theWithControl);
115}
116
117//=======================================================================
118//function : Initialize
119//purpose :
120//=======================================================================
121void GCPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& theC,
122 const Standard_Real theDeflection,
123 const Standard_Boolean theWithControl)
124{
125 Initialize (theC, theDeflection, theC.FirstParameter(), theC.LastParameter(), theWithControl);
126}
127
128//=======================================================================
129//function : Initialize
130//purpose :
131//=======================================================================
132void GCPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& theC,
133 const Standard_Real theDeflection,
134 const Standard_Real theU1,
135 const Standard_Real theU2,
136 const Standard_Boolean theWithControl)
137{
138 initialize (theC, theDeflection, theU1, theU2, theWithControl);
139}
140
141//=======================================================================
142//function : Initialize
143//purpose :
144//=======================================================================
145void GCPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& theC,
146 const Standard_Real theDeflection,
147 const Standard_Real theU1,
148 const Standard_Real theU2,
149 const Standard_Boolean theWithControl)
150{
151 initialize (theC, theDeflection, theU1, theU2, theWithControl);
152}
153
154//=======================================================================
155//function : Value
156//purpose :
157//=======================================================================
158gp_Pnt GCPnts_UniformDeflection::Value (const Standard_Integer theIndex) const
159{
160 StdFail_NotDone_Raise_if(!myDone, "GCPnts_UniformAbscissa::Parameter()");
161 return myPoints.Value (theIndex);
162}
163
164//! Control of the last points.
165template<class TheCurve>
166static void Controle (const TheCurve& theC,
167 TColStd_SequenceOfReal& theParameters,
168 TColgp_SequenceOfPnt& thePoints,
169 const Standard_Real theU2)
170{
171 const Standard_Integer aNbPnts = thePoints.Length();
172 if (aNbPnts > 2)
173 {
174 const Standard_Real aUa = theParameters (aNbPnts - 2);
175 const Standard_Real aUb = theParameters (aNbPnts - 1);
176 if (theU2 - aUb < 0.33 * (theU2 - aUa))
177 {
178 const Standard_Real aUc = (theU2 + aUa) * 0.5;
179 theParameters (aNbPnts - 1) = aUc;
180 thePoints (aNbPnts - 1) = Value (theC, aUc);
181 }
182 }
183}
184
185//=======================================================================
186//function : PerformLinear
187//purpose :
188//=======================================================================
189template<class TheCurve>
190static Standard_Boolean PerformLinear (const TheCurve& theC,
191 TColStd_SequenceOfReal& theParameters,
192 TColgp_SequenceOfPnt& thePoints,
193 const Standard_Real theU1,
194 const Standard_Real theU2)
195{
196 theParameters.Append (theU1);
197 gp_Pnt aPoint = Value (theC, theU1);
198 thePoints.Append (aPoint);
199
200 theParameters.Append (theU2);
201 aPoint = Value (theC, theU2);
202 thePoints.Append (aPoint);
203 return Standard_True;
204}
205
206//=======================================================================
207//function : PerformCircular
208//purpose :
7fd59977 209//=======================================================================
3d42fbc1 210template<class TheCurve>
211static Standard_Boolean PerformCircular (const TheCurve& theC,
212 TColStd_SequenceOfReal& theParameters,
213 TColgp_SequenceOfPnt& thePoints,
214 const Standard_Real theDeflection,
215 const Standard_Real theU1,
216 const Standard_Real theU2)
217{
218 gp_Pnt aPoint;
219 Standard_Real anAngle = Max (1.0 - (theDeflection / theC.Circle().Radius()), 0.0);
220 anAngle = 2.0e0 * ACos (anAngle);
221 Standard_Integer aNbPoints = (Standard_Integer )((theU2 - theU1) / anAngle);
222 aNbPoints += 2;
223 anAngle = (theU2 - theU1) / (Standard_Real) (aNbPoints - 1);
224 Standard_Real aU = theU1;
225 for (Standard_Integer i = 1; i <= aNbPoints; ++i)
226 {
227 theParameters.Append (aU);
228 aPoint = Value (theC, aU);
229 thePoints.Append (aPoint);
230 aU += anAngle;
231 }
232 return Standard_True;
233}
7fd59977 234
3d42fbc1 235//=======================================================================
236//function : GetDefType
237//purpose :
238//=======================================================================
239template<class TheCurve>
240static GCPnts_DeflectionType GetDefType (const TheCurve& theC)
7fd59977 241{
3d42fbc1 242 if (theC.NbIntervals (GeomAbs_C2) > 1)
243 {
244 return GCPnts_DefComposite;
245 }
7fd59977 246
3d42fbc1 247 switch (theC.GetType())
248 {
249 case GeomAbs_Line: return GCPnts_Linear;
250 case GeomAbs_Circle: return GCPnts_Circular;
251 case GeomAbs_BSplineCurve:
252 {
253 Handle(typename GCPnts_TCurveTypes<TheCurve>::BSplineCurve) aBSpline = theC.BSpline();
254 return (aBSpline->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
255 }
256 case GeomAbs_BezierCurve:
257 {
258 Handle(typename GCPnts_TCurveTypes<TheCurve>::BezierCurve) aBezier = theC.Bezier();
259 return (aBezier->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
260 }
261 default:
262 {
263 return GCPnts_Curved;
264 }
265 }
266}
9bf3ef83 267
3d42fbc1 268//=======================================================================
269//function : PerformCurve
270//purpose :
271//=======================================================================
272template<class TheCurve>
273static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& theParameters,
274 TColgp_SequenceOfPnt& thePoints,
275 const TheCurve& theC,
276 const Standard_Real theDeflection,
277 const Standard_Real theU1,
278 const Standard_Real theU2,
279 const Standard_Real theEPSILON,
280 const Standard_Boolean theWithControl)
281{
282 CPnts_UniformDeflection anIterator (theC, theDeflection, theU1, theU2, theEPSILON, theWithControl);
283 for (; anIterator.More(); anIterator.Next())
284 {
285 theParameters.Append (anIterator.Value());
286 thePoints.Append (anIterator.Point());
287 }
288 return anIterator.IsAllDone();
289}
7fd59977 290
7fd59977 291
3d42fbc1 292//=======================================================================
293//function : PerformComposite
294//purpose :
295//=======================================================================
296template<class TheCurve>
297static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& theParameters,
298 TColgp_SequenceOfPnt& thePoints,
299 const TheCurve& theC,
300 const Standard_Real theDeflection,
301 const Standard_Real theU1,
302 const Standard_Real theU2,
303 const Standard_Real theEPSILON,
304 const Standard_Boolean theWithControl)
305{
306 const Standard_Integer aNbIntervals = theC.NbIntervals (GeomAbs_C2);
307 Standard_Integer aPIndex = 0;
308
309 TColStd_Array1OfReal aTI (1, aNbIntervals + 1);
310 theC.Intervals (aTI, GeomAbs_C2);
311 BSplCLib::Hunt (aTI, theU1, aPIndex);
312
313 // iterate by continuous segments
314 Standard_Real aUa = theU1;
315 for (Standard_Integer anIndex = aPIndex;;)
316 {
317 Standard_Real aUb = anIndex + 1 <= aTI.Upper()
318 ? Min (theU2, aTI (anIndex + 1))
319 : theU2;
320 if (!PerformCurve (theParameters, thePoints, theC, theDeflection,
321 aUa, aUb, theEPSILON, theWithControl))
322 {
323 return Standard_False;
324 }
325 ++anIndex;
326 if (anIndex > aNbIntervals || theU2 < aTI (anIndex))
327 {
328 return Standard_True;
329 }
7fd59977 330
3d42fbc1 331 // remove last point to avoid duplication
332 theParameters.Remove (theParameters.Length());
333 thePoints.Remove (thePoints.Length());
7fd59977 334
3d42fbc1 335 aUa = aUb;
336 }
337}
7fd59977 338
3d42fbc1 339//=======================================================================
340//function : initialize
341//purpose :
342//=======================================================================
343template<class TheCurve>
344void GCPnts_UniformDeflection::initialize (const TheCurve& theC,
345 const Standard_Real theDeflection,
346 const Standard_Real theU1,
347 const Standard_Real theU2,
348 const Standard_Boolean theWithControl)
349{
350 const Standard_Real anEPSILON = theC.Resolution (Precision::Confusion());
351 myDeflection = theDeflection;
352 myDone = Standard_False;
353 myParams.Clear();
354 myPoints.Clear();
7fd59977 355
3d42fbc1 356 const Standard_Real aU1 = Min (theU1, theU2);
357 const Standard_Real aU2 = Max (theU1, theU2);
358 const GCPnts_DeflectionType aType = GetDefType (theC);
359 switch (aType)
360 {
361 case GCPnts_Linear:
362 myDone = PerformLinear (theC, myParams, myPoints, aU1, aU2);
363 break;
364 case GCPnts_Circular:
365 myDone = PerformCircular (theC, myParams, myPoints, theDeflection, aU1, aU2);
366 break;
367 case GCPnts_Curved:
368 myDone = PerformCurve (myParams, myPoints, theC, theDeflection,
369 aU1, aU2, anEPSILON, theWithControl);
370 break;
371 case GCPnts_DefComposite:
372 myDone = PerformComposite (myParams, myPoints, theC, theDeflection,
373 aU1, aU2, anEPSILON, theWithControl);
374 break;
375 }
7fd59977 376
3d42fbc1 377 // control of the last points
378 Controle (theC, myParams, myPoints, aU2);
379}