1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
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>
30 //=======================================================================
33 //=======================================================================
34 static void Controle (const TheCurve& C,
35 TColStd_SequenceOfReal& Parameters,
36 TColgp_SequenceOfPnt& Points,
37 const Standard_Real U2)
39 Standard_Integer nbp = Points.Length();
43 Standard_Real Ua = Parameters (nbp - 2);
44 Standard_Real Ub = Parameters (nbp - 1);
45 if (U2 - Ub < 0.33 * (U2 - Ua))
47 Standard_Real Uc = (U2 + Ua) * 0.5;
48 Parameters (nbp - 1) = Uc;
49 Points (nbp - 1) = Value (C, Uc);
55 //=======================================================================
56 //function : PerformLinear
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)
66 Parameters.Append (U1);
67 aPoint = Value (C, U1);
68 Points.Append (aPoint);
70 Parameters.Append (U2);
71 aPoint = Value (C, U2);
72 Points.Append (aPoint);
77 //=======================================================================
78 //function : PerformCircular
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)
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);
93 Angle = (U2 - U1) / (Standard_Real) (NbPoints - 1);
95 for (Standard_Integer i = 1; i <= NbPoints; ++i)
97 Parameters.Append (U);
98 aPoint = Value (C, U);
99 Points.Append (aPoint);
102 return Standard_True;
106 static GCPnts_DeflectionType GetDefType (const TheCurve& C)
108 if (C.NbIntervals (GeomAbs_C2) > 1)
109 return GCPnts_DefComposite;
113 case GeomAbs_Line: return GCPnts_Linear;
114 case GeomAbs_Circle: return GCPnts_Circular;
115 case GeomAbs_BSplineCurve:
117 Handle_TheBSplineCurve aBSpline = C.BSpline();
118 return (aBSpline->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
120 case GeomAbs_BezierCurve:
122 Handle_TheBezierCurve aBezier = C.Bezier();
123 return (aBezier->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
125 default: return GCPnts_Curved;
130 //=======================================================================
131 //function : PerformCurve
133 //=======================================================================
134 static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& Parameters,
135 TColgp_SequenceOfPnt& Points,
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)
143 CPnts_UniformDeflection Iterator (C, Deflection, U1, U2, EPSILON, WithControl);
144 for(; Iterator.More(); Iterator.Next())
146 Parameters.Append (Iterator.Value());
147 Points.Append (Iterator.Point());
149 return Iterator.IsAllDone();
153 //=======================================================================
154 //function : PerformComposite
156 //=======================================================================
157 static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& Parameters,
158 TColgp_SequenceOfPnt& Points,
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)
166 Standard_Integer NbIntervals = C.NbIntervals (GeomAbs_C2);
167 Standard_Integer PIndex;
169 TColStd_Array1OfReal TI (1, NbIntervals + 1);
170 C.Intervals (TI, GeomAbs_C2);
171 BSplCLib::Hunt (TI, U1, PIndex);
173 // iterate by continuous segments
174 Standard_Real Ua = U1;
175 for (Standard_Integer Index = PIndex;;)
177 Standard_Real Ub = Min (U2, TI (Index + 1));
178 if (!PerformCurve (Parameters, Points, C, Deflection,
179 Ua, Ub, EPSILON, WithControl))
181 return Standard_False;
184 if (Index > NbIntervals || U2 < TI (Index))
185 return Standard_True;
187 // remove last point to avoid duplication
188 Parameters.Remove (Parameters.Length());
189 Points.Remove (Points.Length());
196 //=======================================================================
197 //function : GCPnts_UniformDeflection
199 //=======================================================================
200 GCPnts_UniformDeflection::GCPnts_UniformDeflection (const TheCurve& C,
201 const Standard_Real Deflection,
202 const Standard_Real U1,
203 const Standard_Real U2,
204 const Standard_Boolean WithControl)
206 Initialize (C, Deflection, U1, U2, WithControl);
210 //=======================================================================
211 //function : GCPnts_UniformDeflection
213 //=======================================================================
214 GCPnts_UniformDeflection::GCPnts_UniformDeflection (const TheCurve& C,
215 const Standard_Real Deflection,
216 const Standard_Boolean WithControl)
218 Initialize(C, Deflection, WithControl);
222 //=======================================================================
223 //function : Initialize
225 //=======================================================================
226 void GCPnts_UniformDeflection::Initialize (const TheCurve& C,
227 const Standard_Real Deflection,
228 const Standard_Boolean WithControl)
230 Initialize (C, Deflection, C.FirstParameter(), C.LastParameter(), WithControl);
234 //=======================================================================
235 //function : Initialize
237 //=======================================================================
238 void GCPnts_UniformDeflection::Initialize (const TheCurve& C,
239 const Standard_Real Deflection,
240 const Standard_Real theU1,
241 const Standard_Real theU2,
242 const Standard_Boolean WithControl)
244 Standard_Real EPSILON = C.Resolution (Precision::Confusion());
245 myDeflection = Deflection;
246 myDone = Standard_False;
249 Standard_Real U1 = Min (theU1, theU2);
250 Standard_Real U2 = Max (theU1, theU2);
251 GCPnts_DeflectionType Type = GetDefType (C);
255 myDone = PerformLinear (C, myParams, myPoints, U1, U2);
257 case GCPnts_Circular:
258 myDone = PerformCircular (C, myParams, myPoints, Deflection, U1, U2);
261 myDone = PerformCurve (myParams, myPoints, C, Deflection,
262 U1, U2, EPSILON, WithControl);
264 case GCPnts_DefComposite:
265 myDone = PerformComposite (myParams, myPoints, C, Deflection,
266 U1, U2, EPSILON, WithControl);
270 // controle des derniers points:
271 Controle (C, myParams, myPoints, U2);