0024157: Parallelization of assembly part of BO
[occt.git] / src / GCPnts / GCPnts_UniformDeflection.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <StdFail_NotDone.hxx>
20 #include <Standard_DomainError.hxx>
21 #include <Standard_OutOfRange.hxx>
22 #include <Standard_ConstructionError.hxx>
23 #include <Standard_NotImplemented.hxx>
24 #include <GCPnts_DeflectionType.hxx>
25 #include <CPnts_UniformDeflection.hxx>
26 #include <TColStd_Array1OfReal.hxx>
27 #include <TColStd_SequenceOfReal.hxx>
28 #include <BSplCLib.hxx>
29 #include <gp_Circ.hxx>
30 #include <gp_Circ2d.hxx>
31 #include <Precision.hxx>
32
33
34 //=======================================================================
35 //function : Controle
36 //purpose  :
37 //=======================================================================
38 static void Controle (const TheCurve& C,
39                       TColStd_SequenceOfReal& Parameters,
40                       TColgp_SequenceOfPnt& Points,
41                       const Standard_Real U2)
42 {
43   Standard_Integer nbp = Points.Length();
44
45   if (nbp > 2)
46   {
47     Standard_Real Ua = Parameters (nbp - 2);
48     Standard_Real Ub = Parameters (nbp - 1);
49     if (U2 - Ub < 0.33 * (U2 - Ua))
50     {
51       Standard_Real Uc = (U2 + Ua) * 0.5;
52       Parameters (nbp - 1) = Uc;
53       Points (nbp - 1) = Value (C, Uc);
54     }
55   }
56 }
57
58
59 //=======================================================================
60 //function : PerformLinear
61 //purpose  :
62 //=======================================================================
63 static Standard_Boolean PerformLinear (const TheCurve& C,
64                                        TColStd_SequenceOfReal& Parameters,
65                                        TColgp_SequenceOfPnt& Points,
66                                        const Standard_Real U1,
67                                        const Standard_Real U2)
68 {
69   gp_Pnt aPoint;
70   Parameters.Append (U1);
71   aPoint = Value (C, U1);
72   Points.Append (aPoint);
73
74   Parameters.Append (U2);
75   aPoint = Value (C, U2);
76   Points.Append (aPoint);
77   return Standard_True;
78 }
79
80
81 //=======================================================================
82 //function : PerformCircular
83 //purpose  :
84 //=======================================================================
85 static Standard_Boolean PerformCircular (const TheCurve& C,
86                                          TColStd_SequenceOfReal& Parameters,
87                                          TColgp_SequenceOfPnt& Points,
88                                          const Standard_Real Deflection,
89                                          const Standard_Real U1,
90                                          const Standard_Real U2)
91 {
92   gp_Pnt aPoint;
93   Standard_Real Angle = Max (1.0e0 - (Deflection / C.Circle().Radius()), 0.0e0);
94   Angle = 2.0e0 * ACos (Angle);
95   Standard_Integer NbPoints = (Standard_Integer )((U2 - U1) / Angle);
96   NbPoints += 2;
97   Angle = (U2 - U1) / (Standard_Real) (NbPoints - 1);
98   Standard_Real U = U1;
99   for (Standard_Integer i = 1; i <= NbPoints; ++i)
100   {
101     Parameters.Append (U);
102     aPoint = Value (C, U);
103     Points.Append (aPoint);
104     U += Angle;
105   }
106   return Standard_True;
107 }
108
109
110 static GCPnts_DeflectionType GetDefType (TheCurve& C)
111 {
112   if (C.NbIntervals (GeomAbs_C2) > 1)
113     return GCPnts_DefComposite;
114
115   switch (C.GetType())
116   {
117     case GeomAbs_Line:   return GCPnts_Linear;
118     case GeomAbs_Circle: return GCPnts_Circular;
119     case GeomAbs_BSplineCurve:
120     {
121       Handle_TheBSplineCurve aBSpline = C.BSpline();
122       return (aBSpline->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
123     }
124     case GeomAbs_BezierCurve:
125     {
126       Handle_TheBezierCurve aBezier = C.Bezier();
127       return (aBezier->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
128     }
129     default: return GCPnts_Curved;
130   }
131 }
132
133
134 //=======================================================================
135 //function : PerformCurve
136 //purpose  :
137 //=======================================================================
138 static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& Parameters,
139                                       TColgp_SequenceOfPnt&   Points,
140                                       const TheCurve& C,
141                                       const Standard_Real Deflection,
142                                       const Standard_Real U1,
143                                       const Standard_Real U2,
144                                       const Standard_Real EPSILON,
145                                       const Standard_Boolean WithControl)
146 {
147   CPnts_UniformDeflection Iterator (C, Deflection, U1, U2, EPSILON, WithControl);
148   for(; Iterator.More(); Iterator.Next())
149   {
150     Parameters.Append (Iterator.Value());
151     Points.Append (Iterator.Point());
152   }
153   return Iterator.IsAllDone();
154 }
155
156
157 //=======================================================================
158 //function : PerformComposite
159 //purpose  :
160 //=======================================================================
161 static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& Parameters,
162                                           TColgp_SequenceOfPnt& Points,
163                                           TheCurve& C,
164                                           const Standard_Real Deflection,
165                                           const Standard_Real U1,
166                                           const Standard_Real U2,
167                                           const Standard_Real EPSILON,
168                                           const Standard_Boolean WithControl)
169 {
170   Standard_Integer NbIntervals = C.NbIntervals (GeomAbs_C2);
171   Standard_Integer PIndex;
172
173   TColStd_Array1OfReal TI (1, NbIntervals + 1);
174   C.Intervals (TI, GeomAbs_C2);
175   BSplCLib::Hunt (TI, U1, PIndex);
176
177   // iterate by continuous segments
178   Standard_Real Ua = U1;
179   for (Standard_Integer Index = PIndex;;)
180   {
181     Standard_Real Ub = Min (U2, TI (Index + 1));
182     if (!PerformCurve (Parameters, Points, C, Deflection,
183                     Ua, Ub, EPSILON, WithControl))
184     {
185       return Standard_False;
186     }
187     ++Index;
188     if (Index > NbIntervals || U2 < TI (Index))
189       return Standard_True;
190
191     // remove last point to avoid duplication
192     Parameters.Remove (Parameters.Length());
193     Points.Remove (Parameters.Length());
194
195     Ua = Ub;
196   }
197 }
198
199
200 //=======================================================================
201 //function : GCPnts_UniformDeflection
202 //purpose  :
203 //=======================================================================
204 GCPnts_UniformDeflection::GCPnts_UniformDeflection (TheCurve& C,
205                                                     const Standard_Real Deflection,
206                                                     const Standard_Real U1,
207                                                     const Standard_Real U2,
208                                                     const Standard_Boolean WithControl)
209 {
210   Initialize (C, Deflection, U1, U2, WithControl);
211 }
212
213
214 //=======================================================================
215 //function : GCPnts_UniformDeflection
216 //purpose  :
217 //=======================================================================
218 GCPnts_UniformDeflection::GCPnts_UniformDeflection (TheCurve& C,
219                                                     const Standard_Real Deflection,
220                                                     const Standard_Boolean WithControl)
221 {
222   Initialize(C, Deflection, WithControl);
223 }
224
225
226 //=======================================================================
227 //function : Initialize
228 //purpose  :
229 //=======================================================================
230 void   GCPnts_UniformDeflection::Initialize (TheCurve& C,
231                                              const Standard_Real Deflection,
232                                              const Standard_Boolean WithControl)
233 {
234   Initialize (C, Deflection, C.FirstParameter(), C.LastParameter(), WithControl);
235 }
236
237
238 //=======================================================================
239 //function : Initialize
240 //purpose  :
241 //=======================================================================
242 void GCPnts_UniformDeflection::Initialize (TheCurve& C,
243                                            const Standard_Real Deflection,
244                                            const Standard_Real theU1,
245                                            const Standard_Real theU2,
246                                            const Standard_Boolean WithControl)
247 {
248   Standard_Real EPSILON = C.Resolution (Precision::Confusion());
249   myDeflection = Deflection;
250   myDone = Standard_False;
251   myParams.Clear();
252   myPoints.Clear();
253   Standard_Real U1 = Min (theU1, theU2);
254   Standard_Real U2 = Max (theU1, theU2);
255   GCPnts_DeflectionType Type = GetDefType (C);
256   switch (Type)
257   {
258     case GCPnts_Linear:
259       myDone = PerformLinear (C, myParams, myPoints, U1, U2);
260       break;
261     case GCPnts_Circular:
262       myDone = PerformCircular (C, myParams, myPoints, Deflection, U1, U2);
263       break;
264     case GCPnts_Curved:
265       myDone = PerformCurve (myParams, myPoints, C, Deflection,
266                              U1, U2, EPSILON, WithControl);
267       break;
268     case GCPnts_DefComposite:
269       myDone = PerformComposite (myParams, myPoints, C, Deflection,
270                                  U1, U2, EPSILON, WithControl);
271       break;
272   }
273
274   // controle des derniers points:
275   Controle (C, myParams, myPoints, U2);
276 }