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 |
26 | static gp_Pnt Value (const Adaptor3d_Curve& theC, |
27 | const Standard_Real theParameter) |
7fd59977 |
28 | { |
3d42fbc1 |
29 | return theC.Value (theParameter); |
7fd59977 |
30 | } |
3d42fbc1 |
31 | |
32 | static 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 |
43 | GCPnts_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 | //======================================================================= |
54 | GCPnts_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 | //======================================================================= |
69 | GCPnts_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 | //======================================================================= |
82 | GCPnts_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 | //======================================================================= |
97 | GCPnts_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 | //======================================================================= |
110 | void 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 | //======================================================================= |
121 | void 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 | //======================================================================= |
132 | void 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 | //======================================================================= |
145 | void 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 | //======================================================================= |
158 | gp_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. |
165 | template<class TheCurve> |
166 | static 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 | //======================================================================= |
189 | template<class TheCurve> |
190 | static 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 |
210 | template<class TheCurve> |
211 | static 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 | //======================================================================= |
239 | template<class TheCurve> |
240 | static 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 | //======================================================================= |
272 | template<class TheCurve> |
273 | static 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 | //======================================================================= |
296 | template<class TheCurve> |
297 | static 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 | //======================================================================= |
343 | template<class TheCurve> |
344 | void 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 | } |