0024157: Parallelization of assembly part of BO
[occt.git] / src / CPnts / CPnts_UniformDeflection.cxx
CommitLineData
b311480e 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
7fd59977 19//-------------------------------------------------------------------
0d969553 20// Algorithm concerns the constant arrow
0d969553
Y
21// cases processed : parameterized curve
22// the curve should be C2
23// provide a max arrow
0d969553 24// algorithm of parameterized curve:
0d969553 25// calculation of the step of advancement is
7fd59977 26// du = sqrt(8*fleche*||P'(u)||/||P'(u)^P''(u)||
0d969553 27// calculate each point such as u+Du
0d969553
Y
28// check if the arrow is actually taken into account, if yes, continue
29// otherwise correct the step
0d969553
Y
30// si du cannot be calculated (null curvature, singularity on the curve)
31// take a constant step to reach the last point or to go past it
32// The last point is readjusted by the following criteria:
0d969553
Y
33// if the last calculated parameter is <2*resolution, reframe the last point found
34// between itself and the previous point and add the end point
35// (avoid a concentration at the end)
0d969553
Y
36// otherwise if the distance (last calculated point, end point)<arrow,
37// replace the last calculated point by the end point
0d969553
Y
38// otherwise calculate max arrow between the last but one calculated point
39// and the end point; if this arrow is greater than the arrow
40// replace the last point by this one and the end point
0d969553 41// CONTROLS OF ARROW AND THE LAST POINT ARE DONE ONLY IF withControl=true
0d969553 42// each iteration calculates at maximum 3 points
7fd59977 43//-------------------------------------------------------------------------
44
45#include <CPnts_UniformDeflection.ixx>
46
47#include <StdFail_NotDone.hxx>
48#include <Standard_DomainError.hxx>
49#include <Standard_OutOfRange.hxx>
50#include <Standard_ConstructionError.hxx>
51
52#include <gp_Pnt.hxx>
53#include <gp_Vec.hxx>
54#include <gp_Pnt2d.hxx>
55#include <gp_Vec2d.hxx>
56
57static inline void D03d(const Standard_Address C, const Standard_Real U,
58 gp_Pnt& P)
59{
60 ((Adaptor3d_Curve*)C)->D0(U,P);
61}
62
63static void D02d(const Standard_Address C, const Standard_Real U,
64 gp_Pnt& PP)
65{
66 gp_Pnt2d P;
67 ((Adaptor2d_Curve2d*)C)->D0(U,P);
68 PP.SetCoord(P.X(),P.Y(),0.);
69}
70
71static inline void D13d(const Standard_Address C, const Standard_Real U,
72 gp_Pnt& P, gp_Vec& V1)
73{
74 ((Adaptor3d_Curve*)C)->D1(U,P,V1);
75}
76
7fd59977 77static inline void D23d(const Standard_Address C, const Standard_Real U,
78 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2)
79{
80 ((Adaptor3d_Curve*)C)->D2(U,P,V1,V2);
81}
82
83static void D22d(const Standard_Address C, const Standard_Real U,
84 gp_Pnt& PP, gp_Vec& VV1, gp_Vec& VV2)
85{
86 gp_Pnt2d P;
87 gp_Vec2d V1,V2;
88 ((Adaptor2d_Curve2d*)C)->D2(U,P,V1,V2);
89 PP.SetCoord(P.X(),P.Y(),0.);
90 VV1.SetCoord(V1.X(),V1.Y(),0.);
91 VV2.SetCoord(V2.X(),V2.Y(),0.);
92}
93
94//=======================================================================
95//function : Perform
96//purpose :
97//=======================================================================
98
99void CPnts_UniformDeflection::Perform()
100{
101 gp_Pnt P, P1, P2;
102// gp_Vec V1, V2, VV1, VV2, VV;
103 gp_Vec V1, V2, VV;
104 Standard_Real Un1;
105 Standard_Real NormD1, NormD2;
106
107 myIPoint = -1;
108 myNbPoints = -1;
109
110 while ( (myNbPoints<2) && (!myFinish) ) {
111
112 myNbPoints = myNbPoints + 1;
113 myParams[myNbPoints] = myFirstParam;
114
115 if (my3d)
116 D23d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
117 else
118 D22d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
119 P = myPoints[myNbPoints] ;
120 NormD1 = V1.Magnitude();
121 if (NormD1 < myTolCur || V2.Magnitude() < myTolCur) {
0d969553 122 // singularity on the tangent or null curvature
7fd59977 123 myDu = Min(myDwmax, 1.5 * myDu);
124 }
125 else {
126 NormD2 = V2.CrossMagnitude(V1);
0d969553 127 if (NormD2 / NormD1 < myDeflection) { // collinearity of derivatives
7fd59977 128 myDu = Min(myDwmax, 1.5 * myDu);
129 }
130 else {
131 myDu = Sqrt(8.* myDeflection * NormD1 / NormD2 );
132 myDu = Min(Max(myDu, myTolCur), myDwmax);
133 }
134 }
135
0d969553 136 // check if the arrow is observed if WithControl
7fd59977 137
138 if (myControl) {
139 myDu = Min(myDu, myLastParam-myFirstParam);
140 if (my3d) {
141
142 D03d(myCurve, myFirstParam + myDu,P);
143 D03d(myCurve, myFirstParam + (myDu / 2.0),P1);
144 }
145 else {
146
147 D02d(myCurve, myFirstParam + myDu,P);
148 D02d(myCurve, myFirstParam + (myDu / 2.0),P1);
149 }
150 V1= gp_Vec(myPoints[myNbPoints], P);
151 NormD1 = V1.Magnitude();
152 if (NormD1 >= myDeflection) {
153 V2 = gp_Vec(myPoints[myNbPoints], P1);
154 NormD2 = V2.CrossMagnitude(V1) / NormD1;
155
0d969553
Y
156 // passing of arrow starting from which the redivision is done is arbitrary
157 // probably it will be necessary to readjust it (differenciate the first point
158 // from the others) this test does not work on the points of inflexion
7fd59977 159
160 if (NormD2 > myDeflection / 5.0) {
161 NormD2 = Max(NormD2, 1.1 * myDeflection);
162 myDu = myDu * Sqrt(myDeflection / NormD2);
163 myDu = Min(Max(myDu, myTolCur), myDwmax);
164 }
165 }
166 }
167 myFirstParam = myFirstParam + myDu;
168 myFinish = (myLastParam - myFirstParam < myTolCur) || (myDu == 0.);
169 }
170 if (myFinish) {
0d969553 171 // the last point is corrected if control
7fd59977 172 if (myControl && (myNbPoints == 1) ) {
173 Un1 = myParams[0];
174 if (myLastParam - Un1 < 0.33*(myLastParam-myFirstParam)) {
175 myFirstParam = (myLastParam + Un1) / 2.0;
176 myParams[0]= myFirstParam;
177 myParams[1]= myLastParam;
178 if (my3d) {
179 D03d(myCurve, myParams[0], myPoints[0]);
180 D03d(myCurve, myParams[1], myPoints[1]);
181 }
182 else {
183 D02d(myCurve, myParams[0], myPoints[0]);
184 D02d(myCurve, myParams[1], myPoints[1]);
185 }
186 }
187 else {
188 if (my3d) {
189 D23d(myCurve, myLastParam, P1, V1, V2);
190 }
191 else {
192 D22d(myCurve, myLastParam, P1, V1, V2);
193 }
194 P = myPoints[0] ;
195 VV = gp_Vec(P1, P);
196 NormD1 = VV.Magnitude();
197 if ( NormD1 < myDeflection) {
198 myParams[1]= myLastParam;
199 myPoints[1]= P1 ;
200 }
201 else {
202 myFirstParam = (myLastParam * (myParams[1] - Un1) + Un1 * myDu)
203 /(myFirstParam -Un1);
204 if (my3d)
205 D03d(myCurve, myFirstParam, P2);
206 else
207 D02d(myCurve, myFirstParam, P2);
208
209 if ((VV.CrossMagnitude(gp_Vec(P2, P)) / NormD1 < myDeflection) &&
210 (Un1 >= myLastParam - myDwmax) ) {
0d969553 211 // point n is removed
7fd59977 212 myParams[1]= myLastParam;
213 myPoints[1] = P1 ;
214 }
215 else {
216 myParams[1]=myFirstParam;
217 myPoints[1] = P2 ;
218 myParams[2]=myLastParam;
219 myPoints[2] = P1 ;
220 myNbPoints = myNbPoints +1;
221 }
222 }
223 }
224 }
225 else {
226 myNbPoints = myNbPoints +1 ;
227 if (myNbPoints >= 3) myNbPoints = 2;
228 myParams[myNbPoints]= myLastParam;
229 if (my3d) {
230 D03d(myCurve, myLastParam, myPoints[myNbPoints]);
231 }
232 else {
233 D02d(myCurve, myLastParam, myPoints[myNbPoints]);
234 }
235 }
236 }
237}
238
239//=======================================================================
240//function : CPnts_UniformDeflection
241//purpose :
242//=======================================================================
243
244CPnts_UniformDeflection::CPnts_UniformDeflection ()
245{
246 myDone = Standard_False;
247}
248
249//=======================================================================
250//function : CPnts_UniformDeflection
251//purpose :
252//=======================================================================
253
254CPnts_UniformDeflection::CPnts_UniformDeflection
255 (const Adaptor3d_Curve& C,
256 const Standard_Real Deflection,
257 const Standard_Real Resolution,
258 const Standard_Boolean WithControl)
259{
260 Initialize(C, Deflection, Resolution, WithControl);
261}
262
263//=======================================================================
264//function : CPnts_UniformDeflection
265//purpose :
266//=======================================================================
267
268CPnts_UniformDeflection::CPnts_UniformDeflection
269 (const Adaptor2d_Curve2d& C,
270 const Standard_Real Deflection,
271 const Standard_Real Resolution,
272 const Standard_Boolean WithControl)
273{
274 Initialize(C, Deflection, Resolution, WithControl);
275}
276
277//=======================================================================
278//function : Initialize
279//purpose :
280//=======================================================================
281
282void CPnts_UniformDeflection::Initialize(const Adaptor3d_Curve& C,
283 const Standard_Real Deflection,
284 const Standard_Real Resolution,
285 const Standard_Boolean WithControl)
286{
287 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
288 Resolution,WithControl);
289}
290
291//=======================================================================
292//function : Initialize
293//purpose :
294//=======================================================================
295
296void CPnts_UniformDeflection::Initialize(const Adaptor2d_Curve2d& C,
297 const Standard_Real Deflection,
298 const Standard_Real Resolution,
299 const Standard_Boolean WithControl)
300{
301 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
302 Resolution,WithControl);
303}
304
305//=======================================================================
306//function : CPnts_UniformDeflection
307//purpose :
308//=======================================================================
309
310CPnts_UniformDeflection ::CPnts_UniformDeflection
311 (const Adaptor3d_Curve& C,
312 const Standard_Real Deflection,
313 const Standard_Real U1,
314 const Standard_Real U2,
315 const Standard_Real Resolution,
316 const Standard_Boolean WithControl)
317{
318 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
319}
320
321//=======================================================================
322//function : CPnts_UniformDeflection
323//purpose :
324//=======================================================================
325
326CPnts_UniformDeflection ::CPnts_UniformDeflection
327 (const Adaptor2d_Curve2d& C,
328 const Standard_Real Deflection,
329 const Standard_Real U1,
330 const Standard_Real U2,
331 const Standard_Real Resolution,
332 const Standard_Boolean WithControl)
333{
334 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
335}
336
337//=======================================================================
338//function : Initialize
339//purpose :
340//=======================================================================
341
342void CPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& C,
343 const Standard_Real Deflection,
344 const Standard_Real U1,
345 const Standard_Real U2,
346 const Standard_Real Resolution,
347 const Standard_Boolean WithControl)
348{
349 if (U1 > U2) {
350 myFirstParam = U2;
351 myLastParam = U1;
352 }
353 else {
354 myFirstParam = U1;
355 myLastParam = U2;
356 }
357 my3d = Standard_True;
358 myDwmax = myLastParam-myFirstParam;
359 myDu = myDwmax/2. ;
360 myDone = Standard_True;
361 myCurve = (Standard_Address) &C;
362 myFinish = Standard_False;
363 myTolCur = Resolution;
364 myDeflection = Deflection;
365 myControl = WithControl;
366 Perform();
367}
368
369//=======================================================================
370//function : Initialize
371//purpose :
372//=======================================================================
373
374void CPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& C,
375 const Standard_Real Deflection,
376 const Standard_Real U1,
377 const Standard_Real U2,
378 const Standard_Real Resolution,
379 const Standard_Boolean WithControl)
380{
381 if (U1 > U2) {
382 myFirstParam = U2;
383 myLastParam = U1;
384 }
385 else {
386 myFirstParam = U1;
387 myLastParam = U2;
388 }
389 my3d = Standard_False;
390 myDwmax = myLastParam-myFirstParam;
391 myDu = myDwmax/2. ;
392 myDone = Standard_True;
393 myCurve = (Standard_Address) &C;
394 myFinish = Standard_False;
395 myTolCur = Resolution;
396 myDeflection = Deflection;
397 myControl = WithControl;
398 Perform();
399}
400
401//=======================================================================
402//function : More
403//purpose :
404//=======================================================================
405
406Standard_Boolean CPnts_UniformDeflection::More()
407{
408 if(!myDone) {
409 return Standard_False;
410 }
411 else if (myIPoint == myNbPoints) {
412 if (myFinish) {
413 return Standard_False;
414 }
415 else {
416 Perform();
417 return myDone;
418 }
419 }
420 else {
421 return myIPoint < myNbPoints;
422 }
423}
424
425
426
427
428
429
430