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 | #include <StdFail_NotDone.hxx> |
16 | #include <Standard_DomainError.hxx> |
17 | #include <Standard_OutOfRange.hxx> |
18 | #include <Standard_ConstructionError.hxx> |
19 | #include <Standard_NotImplemented.hxx> |
20 | #include <GCPnts_DeflectionType.hxx> |
21 | #include <CPnts_UniformDeflection.hxx> |
22 | #include <TColStd_Array1OfReal.hxx> |
23 | #include <TColStd_SequenceOfReal.hxx> |
24 | #include <BSplCLib.hxx> |
25 | #include <gp_Circ.hxx> |
26 | #include <gp_Circ2d.hxx> |
27 | #include <Precision.hxx> |
28 | |
29 | |
30 | //======================================================================= |
31 | //function : Controle |
32 | //purpose : |
33 | //======================================================================= |
34 | static void Controle (const TheCurve& C, |
35 | TColStd_SequenceOfReal& Parameters, |
36 | TColgp_SequenceOfPnt& Points, |
37 | const Standard_Real U2) |
38 | { |
39 | Standard_Integer nbp = Points.Length(); |
40 | |
41 | if (nbp > 2) |
42 | { |
43 | Standard_Real Ua = Parameters (nbp - 2); |
44 | Standard_Real Ub = Parameters (nbp - 1); |
45 | if (U2 - Ub < 0.33 * (U2 - Ua)) |
46 | { |
47 | Standard_Real Uc = (U2 + Ua) * 0.5; |
48 | Parameters (nbp - 1) = Uc; |
49 | Points (nbp - 1) = Value (C, Uc); |
50 | } |
51 | } |
52 | } |
53 | |
54 | |
55 | //======================================================================= |
56 | //function : PerformLinear |
57 | //purpose : |
58 | //======================================================================= |
59 | static Standard_Boolean PerformLinear (const TheCurve& C, |
60 | TColStd_SequenceOfReal& Parameters, |
61 | TColgp_SequenceOfPnt& Points, |
62 | const Standard_Real U1, |
63 | const Standard_Real U2) |
64 | { |
65 | gp_Pnt aPoint; |
66 | Parameters.Append (U1); |
67 | aPoint = Value (C, U1); |
68 | Points.Append (aPoint); |
69 | |
70 | Parameters.Append (U2); |
71 | aPoint = Value (C, U2); |
72 | Points.Append (aPoint); |
73 | return Standard_True; |
74 | } |
75 | |
76 | |
77 | //======================================================================= |
78 | //function : PerformCircular |
79 | //purpose : |
80 | //======================================================================= |
81 | static Standard_Boolean PerformCircular (const TheCurve& C, |
82 | TColStd_SequenceOfReal& Parameters, |
83 | TColgp_SequenceOfPnt& Points, |
84 | const Standard_Real Deflection, |
85 | const Standard_Real U1, |
86 | const Standard_Real U2) |
87 | { |
88 | gp_Pnt aPoint; |
89 | Standard_Real Angle = Max (1.0e0 - (Deflection / C.Circle().Radius()), 0.0e0); |
90 | Angle = 2.0e0 * ACos (Angle); |
91 | Standard_Integer NbPoints = (Standard_Integer )((U2 - U1) / Angle); |
92 | NbPoints += 2; |
93 | Angle = (U2 - U1) / (Standard_Real) (NbPoints - 1); |
94 | Standard_Real U = U1; |
95 | for (Standard_Integer i = 1; i <= NbPoints; ++i) |
96 | { |
97 | Parameters.Append (U); |
98 | aPoint = Value (C, U); |
99 | Points.Append (aPoint); |
100 | U += Angle; |
101 | } |
102 | return Standard_True; |
103 | } |
104 | |
105 | |
37782ec2 |
106 | static GCPnts_DeflectionType GetDefType (const TheCurve& C) |
7fd59977 |
107 | { |
108 | if (C.NbIntervals (GeomAbs_C2) > 1) |
109 | return GCPnts_DefComposite; |
110 | |
111 | switch (C.GetType()) |
112 | { |
113 | case GeomAbs_Line: return GCPnts_Linear; |
114 | case GeomAbs_Circle: return GCPnts_Circular; |
115 | case GeomAbs_BSplineCurve: |
116 | { |
117 | Handle_TheBSplineCurve aBSpline = C.BSpline(); |
118 | return (aBSpline->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved; |
119 | } |
120 | case GeomAbs_BezierCurve: |
121 | { |
122 | Handle_TheBezierCurve aBezier = C.Bezier(); |
123 | return (aBezier->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved; |
124 | } |
125 | default: return GCPnts_Curved; |
126 | } |
127 | } |
128 | |
129 | |
130 | //======================================================================= |
131 | //function : PerformCurve |
132 | //purpose : |
133 | //======================================================================= |
134 | static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& Parameters, |
135 | TColgp_SequenceOfPnt& Points, |
136 | const TheCurve& C, |
137 | const Standard_Real Deflection, |
138 | const Standard_Real U1, |
139 | const Standard_Real U2, |
140 | const Standard_Real EPSILON, |
141 | const Standard_Boolean WithControl) |
142 | { |
143 | CPnts_UniformDeflection Iterator (C, Deflection, U1, U2, EPSILON, WithControl); |
144 | for(; Iterator.More(); Iterator.Next()) |
145 | { |
146 | Parameters.Append (Iterator.Value()); |
147 | Points.Append (Iterator.Point()); |
148 | } |
149 | return Iterator.IsAllDone(); |
150 | } |
151 | |
152 | |
153 | //======================================================================= |
154 | //function : PerformComposite |
155 | //purpose : |
156 | //======================================================================= |
157 | static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& Parameters, |
158 | TColgp_SequenceOfPnt& Points, |
37782ec2 |
159 | const TheCurve& C, |
7fd59977 |
160 | const Standard_Real Deflection, |
161 | const Standard_Real U1, |
162 | const Standard_Real U2, |
163 | const Standard_Real EPSILON, |
164 | const Standard_Boolean WithControl) |
165 | { |
166 | Standard_Integer NbIntervals = C.NbIntervals (GeomAbs_C2); |
167 | Standard_Integer PIndex; |
168 | |
169 | TColStd_Array1OfReal TI (1, NbIntervals + 1); |
170 | C.Intervals (TI, GeomAbs_C2); |
171 | BSplCLib::Hunt (TI, U1, PIndex); |
172 | |
173 | // iterate by continuous segments |
174 | Standard_Real Ua = U1; |
175 | for (Standard_Integer Index = PIndex;;) |
176 | { |
177 | Standard_Real Ub = Min (U2, TI (Index + 1)); |
178 | if (!PerformCurve (Parameters, Points, C, Deflection, |
179 | Ua, Ub, EPSILON, WithControl)) |
180 | { |
181 | return Standard_False; |
182 | } |
183 | ++Index; |
184 | if (Index > NbIntervals || U2 < TI (Index)) |
185 | return Standard_True; |
186 | |
187 | // remove last point to avoid duplication |
188 | Parameters.Remove (Parameters.Length()); |
189 | Points.Remove (Parameters.Length()); |
190 | |
191 | Ua = Ub; |
192 | } |
7fd59977 |
193 | } |
194 | |
195 | |
196 | //======================================================================= |
197 | //function : GCPnts_UniformDeflection |
198 | //purpose : |
199 | //======================================================================= |
37782ec2 |
200 | GCPnts_UniformDeflection::GCPnts_UniformDeflection (const TheCurve& C, |
7fd59977 |
201 | const Standard_Real Deflection, |
202 | const Standard_Real U1, |
203 | const Standard_Real U2, |
204 | const Standard_Boolean WithControl) |
205 | { |
206 | Initialize (C, Deflection, U1, U2, WithControl); |
207 | } |
208 | |
209 | |
210 | //======================================================================= |
211 | //function : GCPnts_UniformDeflection |
212 | //purpose : |
213 | //======================================================================= |
37782ec2 |
214 | GCPnts_UniformDeflection::GCPnts_UniformDeflection (const TheCurve& C, |
7fd59977 |
215 | const Standard_Real Deflection, |
216 | const Standard_Boolean WithControl) |
217 | { |
218 | Initialize(C, Deflection, WithControl); |
219 | } |
220 | |
221 | |
222 | //======================================================================= |
223 | //function : Initialize |
224 | //purpose : |
225 | //======================================================================= |
37782ec2 |
226 | void GCPnts_UniformDeflection::Initialize (const TheCurve& C, |
7fd59977 |
227 | const Standard_Real Deflection, |
228 | const Standard_Boolean WithControl) |
229 | { |
230 | Initialize (C, Deflection, C.FirstParameter(), C.LastParameter(), WithControl); |
231 | } |
232 | |
233 | |
234 | //======================================================================= |
235 | //function : Initialize |
236 | //purpose : |
237 | //======================================================================= |
37782ec2 |
238 | void GCPnts_UniformDeflection::Initialize (const TheCurve& C, |
7fd59977 |
239 | const Standard_Real Deflection, |
240 | const Standard_Real theU1, |
241 | const Standard_Real theU2, |
242 | const Standard_Boolean WithControl) |
243 | { |
244 | Standard_Real EPSILON = C.Resolution (Precision::Confusion()); |
245 | myDeflection = Deflection; |
246 | myDone = Standard_False; |
247 | myParams.Clear(); |
248 | myPoints.Clear(); |
249 | Standard_Real U1 = Min (theU1, theU2); |
250 | Standard_Real U2 = Max (theU1, theU2); |
251 | GCPnts_DeflectionType Type = GetDefType (C); |
252 | switch (Type) |
253 | { |
254 | case GCPnts_Linear: |
255 | myDone = PerformLinear (C, myParams, myPoints, U1, U2); |
256 | break; |
257 | case GCPnts_Circular: |
258 | myDone = PerformCircular (C, myParams, myPoints, Deflection, U1, U2); |
259 | break; |
260 | case GCPnts_Curved: |
261 | myDone = PerformCurve (myParams, myPoints, C, Deflection, |
262 | U1, U2, EPSILON, WithControl); |
263 | break; |
264 | case GCPnts_DefComposite: |
265 | myDone = PerformComposite (myParams, myPoints, C, Deflection, |
266 | U1, U2, EPSILON, WithControl); |
267 | break; |
268 | } |
269 | |
270 | // controle des derniers points: |
271 | Controle (C, myParams, myPoints, U2); |
272 | } |