Commit | Line | Data |
---|---|---|
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. | |
7fd59977 | 14 | |
15 | #include <Approx_ParametrizationType.hxx> | |
16 | #include Approx_ParLeastSquareOfMyGradient_hxx | |
17 | #include <TColStd_Array1OfReal.hxx> | |
18 | #include <TColgp_Array1OfPnt.hxx> | |
19 | #include <TColgp_Array1OfPnt2d.hxx> | |
20 | #include <gp_Pnt.hxx> | |
21 | #include <gp_Pnt2d.hxx> | |
22 | #include <gp_Vec.hxx> | |
23 | #include <gp_Vec2d.hxx> | |
24 | #include <TColgp_Array1OfVec.hxx> | |
25 | #include <TColgp_Array1OfVec2d.hxx> | |
26 | #include <AppParCurves_Constraint.hxx> | |
27 | #include <AppParCurves_HArray1OfConstraintCouple.hxx> | |
28 | #include <AppParCurves_MultiPoint.hxx> | |
29 | #include <Precision.hxx> | |
30 | #include <math_IntegerVector.hxx> | |
31 | #include <math_Gauss.hxx> | |
32 | #include <math_Uzawa.hxx> | |
33 | #include <Approx_MCurvesToBSpCurve.hxx> | |
34 | #include <AppParCurves_ConstraintCouple.hxx> | |
35 | ||
36 | #include <stdio.h> | |
37 | ||
7fd59977 | 38 | #ifdef DEB |
39 | static Standard_Boolean mydebug = Standard_False; | |
40 | ||
41 | #include <Geom_BezierCurve.hxx> | |
42 | #include <Geom2d_BezierCurve.hxx> | |
43 | #ifdef DRAW | |
44 | #include <DrawTrSurf.hxx> | |
45 | #include <Draw.hxx> | |
46 | #include <Draw_Appli.hxx> | |
47 | #endif | |
48 | static void DUMP(const MultiLine& Line) | |
49 | { | |
50 | Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP; | |
51 | gp_Pnt P1; | |
52 | gp_Pnt2d P12d; | |
53 | ||
54 | firstP = LineTool::FirstPoint(Line); | |
55 | lastP = LineTool::LastPoint(Line); | |
56 | ||
57 | nbP3d = LineTool::NbP3d(Line); | |
58 | nbP2d = LineTool::NbP2d(Line); | |
59 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; | |
60 | if (nbP3d == 0) mynbP3d = 1; | |
61 | if (nbP2d == 0) mynbP2d = 1; | |
62 | ||
63 | TColgp_Array1OfPnt tabP(1, mynbP3d); | |
64 | TColgp_Array1OfPnt2d tabP2d(1, mynbP2d); | |
65 | ||
66 | cout <<"DUMP de la MultiLine entre "<<firstP <<" et "<<lastP<<": "<<endl; | |
67 | for (i = firstP; i <= lastP; i++) { | |
68 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d); | |
69 | else if (nbP2d != 0) LineTool::Value(Line, i, tabP2d); | |
70 | else if (nbP3d != 0) LineTool::Value(Line, i, tabP); | |
71 | ||
72 | cout << "point "<<i<<":"<< endl; | |
73 | for (j = 1; j <= nbP3d; j++) { | |
74 | P1 = tabP(j); | |
75 | cout <<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl; | |
76 | } | |
77 | for (j = 1; j <= nbP2d; j++) { | |
78 | P12d = tabP2d(j); | |
79 | cout <<P12d.X()<<" "<<P12d.Y()<<endl; | |
80 | } | |
81 | } | |
82 | ||
83 | } | |
84 | ||
85 | ||
86 | static void DUMP(const AppParCurves_MultiCurve& C) { | |
87 | static Standard_Integer nbappel = 0; | |
88 | Standard_Integer i; | |
89 | Standard_Integer nbpoles = C.NbPoles(); | |
7fd59977 | 90 | |
91 | Handle(Geom_BezierCurve) BSp; | |
92 | Handle(Geom2d_BezierCurve) BSp2d; | |
93 | ||
94 | TColgp_Array1OfPnt tabPoles(1, nbpoles); | |
95 | TColgp_Array1OfPnt2d tabPoles2d(1, nbpoles); | |
96 | char solname[100]; | |
97 | ||
98 | nbappel++; | |
99 | for (i = 1; i <= C.NbCurves(); i++) { | |
100 | if (C.Dimension(i) == 3) { | |
101 | C.Curve(i, tabPoles); | |
102 | BSp = new Geom_BezierCurve(tabPoles); | |
103 | sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel); | |
104 | #ifdef DRAW | |
105 | char* Temp = solname; | |
106 | DrawTrSurf::Set(Temp, BSp); | |
107 | // DrawTrSurf::Set(solname, BSp); | |
108 | #endif | |
109 | } | |
110 | else { | |
111 | C.Curve(i, tabPoles2d); | |
112 | BSp2d = new Geom2d_BezierCurve(tabPoles2d); | |
113 | sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel); | |
114 | #ifdef DRAW | |
115 | char* Temp = solname; | |
116 | DrawTrSurf::Set(Temp, BSp2d); | |
117 | // DrawTrSurf::Set(solname, BSp2d); | |
118 | #endif | |
119 | } | |
120 | } | |
121 | #ifdef DRAW | |
122 | dout.Flush(); | |
123 | #endif | |
124 | } | |
125 | ||
126 | ||
127 | #endif | |
128 | ||
129 | void Approx_ComputeLine::FirstTangencyVector(const MultiLine& Line, | |
130 | const Standard_Integer index, | |
131 | math_Vector& V) const | |
132 | { | |
133 | ||
134 | Standard_Integer i, j, nbP2d, nbP3d; | |
135 | nbP3d = LineTool::NbP3d(Line); | |
136 | nbP2d = LineTool::NbP2d(Line); | |
137 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; | |
138 | if (nbP3d == 0) mynbP3d = 1; | |
139 | if (nbP2d == 0) mynbP2d = 1; | |
140 | Standard_Boolean Ok=Standard_False; | |
141 | TColgp_Array1OfVec TabV(1, mynbP3d); | |
142 | TColgp_Array1OfVec2d TabV2d(1, mynbP2d); | |
143 | ||
144 | if (nbP3d != 0 && nbP2d != 0) | |
145 | Ok = LineTool::Tangency(Line, index, TabV, TabV2d); | |
146 | else if (nbP2d != 0) | |
147 | Ok = LineTool::Tangency(Line, index, TabV2d); | |
148 | else if (nbP3d != 0) | |
149 | Ok = LineTool::Tangency(Line, index, TabV); | |
150 | ||
151 | if (Ok) { | |
152 | if (nbP3d != 0) { | |
153 | j = 1; | |
154 | for (i = TabV.Lower(); i <= TabV.Upper(); i++) { | |
155 | V(j) = TabV(i).X(); | |
156 | V(j+1) = TabV(i).Y(); | |
157 | V(j+2) = TabV(i).Z(); | |
158 | j += 3; | |
159 | } | |
160 | } | |
161 | if (nbP2d != 0) { | |
162 | j = nbP3d*3+1; | |
163 | for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) { | |
164 | V(j) = TabV2d(i).X(); | |
165 | V(j+1) = TabV2d(i).Y(); | |
166 | j += 2; | |
167 | } | |
168 | } | |
169 | } | |
170 | else { | |
171 | ||
172 | // recherche d un vecteur tangent par construction d une parabole: | |
173 | AppParCurves_Constraint firstC, lastC; | |
174 | firstC = lastC = AppParCurves_PassPoint; | |
175 | Standard_Integer nbpoles = 3; | |
176 | math_Vector mypar(index, index+2); | |
177 | Parameters(Line, index, index+2, mypar); | |
178 | Approx_ParLeastSquareOfMyGradient | |
179 | LSQ(Line, index, index+2, firstC, lastC, mypar, nbpoles); | |
180 | AppParCurves_MultiCurve C = LSQ.BezierValue(); | |
181 | ||
182 | gp_Pnt myP; | |
183 | gp_Vec myV; | |
184 | gp_Pnt2d myP2d; | |
185 | gp_Vec2d myV2d; | |
186 | j = 1; | |
187 | for (i = 1; i <= nbP3d; i++) { | |
188 | C.D1(i, 0.0, myP, myV); | |
189 | V(j) = myV.X(); | |
190 | V(j+1) = myV.Y(); | |
191 | V(j+2) = myV.Z(); | |
192 | j += 3; | |
193 | } | |
194 | j = nbP3d*3+1; | |
195 | for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) { | |
196 | C.D1(i, 0.0, myP2d, myV2d); | |
197 | V(j) = myV2d.X(); | |
198 | V(j+1) = myV2d.Y(); | |
199 | j += 2; | |
200 | } | |
201 | } | |
202 | } | |
203 | ||
204 | ||
205 | void Approx_ComputeLine::LastTangencyVector(const MultiLine& Line, | |
206 | const Standard_Integer index, | |
207 | math_Vector& V) const | |
208 | { | |
209 | Standard_Integer i, j, nbP2d, nbP3d; | |
210 | nbP3d = LineTool::NbP3d(Line); | |
211 | nbP2d = LineTool::NbP2d(Line); | |
212 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; | |
213 | if (nbP3d == 0) mynbP3d = 1; | |
214 | if (nbP2d == 0) mynbP2d = 1; | |
215 | Standard_Boolean Ok=Standard_False; | |
216 | TColgp_Array1OfVec TabV(1, mynbP3d); | |
217 | TColgp_Array1OfVec2d TabV2d(1, mynbP2d); | |
218 | ||
219 | ||
220 | if (nbP3d != 0 && nbP2d != 0) | |
221 | Ok = LineTool::Tangency(Line, index, TabV, TabV2d); | |
222 | else if (nbP2d != 0) | |
223 | Ok = LineTool::Tangency(Line, index, TabV2d); | |
224 | else if (nbP3d != 0) | |
225 | Ok = LineTool::Tangency(Line, index, TabV); | |
226 | ||
227 | if (Ok) { | |
228 | if (nbP3d != 0) { | |
229 | j = 1; | |
230 | for (i = TabV.Lower(); i <= TabV.Upper(); i++) { | |
231 | V(j) = TabV(i).X(); | |
232 | V(j+1) = TabV(i).Y(); | |
233 | V(j+2) = TabV(i).Z(); | |
234 | j += 3; | |
235 | } | |
236 | } | |
237 | if (nbP2d != 0) { | |
238 | j = nbP3d*3+1; | |
239 | for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) { | |
240 | V(j) = TabV2d(i).X(); | |
241 | V(j+1) = TabV2d(i).Y(); | |
242 | j += 2; | |
243 | } | |
244 | } | |
245 | } | |
246 | else { | |
247 | ||
248 | // recherche d un vecteur tangent par construction d une parabole: | |
249 | AppParCurves_Constraint firstC, lastC; | |
250 | firstC = lastC = AppParCurves_PassPoint; | |
251 | Standard_Integer nbpoles = 3; | |
252 | math_Vector mypar(index-2, index); | |
253 | Parameters(Line, index-2, index, mypar); | |
254 | Approx_ParLeastSquareOfMyGradient | |
255 | LSQ(Line, index-2, index, firstC, lastC, mypar, nbpoles); | |
256 | AppParCurves_MultiCurve C = LSQ.BezierValue(); | |
257 | ||
258 | gp_Pnt myP; | |
259 | gp_Vec myV; | |
260 | gp_Pnt2d myP2d; | |
261 | gp_Vec2d myV2d; | |
262 | j = 1; | |
263 | for (i = 1; i <= nbP3d; i++) { | |
264 | C.D1(i, 1.0, myP, myV); | |
265 | V(j) = myV.X(); | |
266 | V(j+1) = myV.Y(); | |
267 | V(j+2) = myV.Z(); | |
268 | j += 3; | |
269 | } | |
270 | j = nbP3d*3+1; | |
271 | for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) { | |
272 | C.D1(i, 1.0, myP2d, myV2d); | |
273 | V(j) = myV2d.X(); | |
274 | V(j+1) = myV2d.Y(); | |
275 | j += 2; | |
276 | } | |
277 | } | |
278 | ||
279 | } | |
280 | ||
281 | ||
282 | ||
283 | Standard_Real Approx_ComputeLine:: | |
284 | SearchFirstLambda(const MultiLine& Line, | |
285 | const math_Vector& TheParam, | |
286 | const math_Vector& V, | |
287 | const Standard_Integer index) const | |
288 | { | |
289 | ||
290 | // dq/dw = lambda* V = (p2-p1)/(u2-u1) | |
291 | ||
292 | Standard_Integer nbP2d, nbP3d; | |
293 | gp_Pnt P1, P2; | |
294 | gp_Pnt2d P12d, P22d; | |
295 | nbP3d = LineTool::NbP3d(Line); | |
296 | nbP2d = LineTool::NbP2d(Line); | |
297 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; | |
298 | if (nbP3d == 0) mynbP3d = 1; | |
299 | if (nbP2d == 0) mynbP2d = 1; | |
300 | TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d); | |
301 | TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d); | |
302 | ||
303 | ||
304 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d); | |
305 | else if (nbP2d != 0) LineTool::Value(Line, index, tabP12d); | |
306 | else if (nbP3d != 0) LineTool::Value(Line, index, tabP1); | |
307 | ||
308 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index+1, tabP2, tabP22d); | |
309 | else if (nbP2d != 0) LineTool::Value(Line, index+1, tabP22d); | |
310 | else if (nbP3d != 0) LineTool::Value(Line, index+1, tabP2); | |
311 | ||
312 | ||
313 | Standard_Real U1 = TheParam(index), U2 = TheParam(index+1); | |
314 | Standard_Real lambda, S; | |
315 | Standard_Integer low = V.Lower(); | |
316 | ||
317 | if (nbP3d != 0) { | |
318 | P1 = tabP1(1); | |
319 | P2 = tabP2(1); | |
320 | gp_Vec P1P2(P1, P2), myV; | |
321 | myV.SetCoord(V(low), V(low+1), V(low+2)); | |
322 | lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1)); | |
323 | S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0; | |
324 | } | |
325 | else { | |
326 | P12d = tabP12d(1); | |
327 | P22d = tabP22d(1); | |
328 | gp_Vec2d P1P2(P12d, P22d), myV; | |
329 | myV.SetCoord(V(low), V(low+1)); | |
330 | lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1)); | |
331 | S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0; | |
332 | } | |
333 | return (S*lambda); | |
334 | ||
335 | } | |
336 | ||
337 | ||
338 | Standard_Real Approx_ComputeLine:: | |
339 | SearchLastLambda(const MultiLine& Line, | |
340 | const math_Vector& TheParam, | |
341 | const math_Vector& V, | |
342 | const Standard_Integer index) const | |
343 | { | |
344 | // dq/dw = lambda* V = (p2-p1)/(u2-u1) | |
345 | ||
346 | Standard_Integer nbP2d, nbP3d; | |
347 | gp_Pnt P1, P2; | |
348 | gp_Pnt2d P12d, P22d; | |
349 | nbP3d = LineTool::NbP3d(Line); | |
350 | nbP2d = LineTool::NbP2d(Line); | |
351 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; | |
352 | if (nbP3d == 0) mynbP3d = 1; | |
353 | if (nbP2d == 0) mynbP2d = 1; | |
354 | TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d); | |
355 | TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d); | |
356 | ||
357 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index-1, tabP, tabP2d); | |
358 | else if (nbP2d != 0) LineTool::Value(Line, index-1, tabP2d); | |
359 | else if (nbP3d != 0) LineTool::Value(Line, index-1, tabP); | |
360 | ||
361 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d); | |
362 | else if (nbP2d != 0) LineTool::Value(Line, index, tabP22d); | |
363 | else if (nbP3d != 0) LineTool::Value(Line, index, tabP2); | |
364 | ||
365 | ||
366 | Standard_Real U1 = TheParam(index-1), U2 = TheParam(index); | |
367 | Standard_Real lambda, S; | |
368 | Standard_Integer low = V.Lower(); | |
369 | ||
370 | if (nbP3d != 0) { | |
371 | P1 = tabP(1); | |
372 | P2 = tabP2(1); | |
373 | gp_Vec P1P2(P1, P2), myV; | |
374 | myV.SetCoord(V(low), V(low+1), V(low+2)); | |
375 | lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1)); | |
376 | S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0; | |
377 | } | |
378 | else { | |
379 | P12d = tabP2d(1); | |
380 | P22d = tabP22d(1); | |
381 | gp_Vec2d P1P2(P12d, P22d), myV; | |
382 | myV.SetCoord(V(low), V(low+1)); | |
383 | lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1)); | |
384 | S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0; | |
385 | } | |
386 | ||
387 | return (S*lambda); | |
388 | } | |
389 | ||
390 | ||
391 | ||
392 | Approx_ComputeLine::Approx_ComputeLine | |
393 | (const MultiLine& Line, | |
394 | const math_Vector& Parameters, | |
395 | const Standard_Integer degreemin, | |
396 | const Standard_Integer degreemax, | |
397 | const Standard_Real Tolerance3d, | |
398 | const Standard_Real Tolerance2d, | |
399 | const Standard_Integer NbIterations, | |
400 | const Standard_Boolean cutting, | |
401 | const Standard_Boolean Squares) | |
41194117 K |
402 | : myMultiLineNb (0), |
403 | myIsClear (Standard_False) | |
7fd59977 | 404 | { |
405 | myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), | |
406 | Parameters.Upper()); | |
407 | for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) { | |
408 | myfirstParam->SetValue(i, Parameters(i)); | |
409 | } | |
410 | myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2); | |
411 | Par = Approx_IsoParametric; | |
412 | mydegremin = degreemin; | |
413 | mydegremax = degreemax; | |
414 | mytol3d = Tolerance3d; | |
415 | mytol2d = Tolerance2d; | |
416 | mysquares = Squares; | |
417 | mycut = cutting; | |
418 | myitermax = NbIterations; | |
419 | alldone = Standard_False; | |
420 | myfirstC = AppParCurves_TangencyPoint; | |
421 | mylastC = AppParCurves_TangencyPoint; | |
422 | Perform(Line); | |
423 | } | |
424 | ||
425 | ||
426 | Approx_ComputeLine::Approx_ComputeLine | |
427 | (const math_Vector& Parameters, | |
428 | const Standard_Integer degreemin, | |
429 | const Standard_Integer degreemax, | |
430 | const Standard_Real Tolerance3d, | |
431 | const Standard_Real Tolerance2d, | |
432 | const Standard_Integer NbIterations, | |
433 | const Standard_Boolean cutting, | |
434 | const Standard_Boolean Squares) | |
41194117 K |
435 | : myMultiLineNb (0), |
436 | myIsClear (Standard_False) | |
7fd59977 | 437 | { |
438 | myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), | |
439 | Parameters.Upper()); | |
440 | for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) { | |
441 | myfirstParam->SetValue(i, Parameters(i)); | |
442 | } | |
443 | myfirstC = AppParCurves_TangencyPoint; | |
444 | mylastC = AppParCurves_TangencyPoint; | |
445 | myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2); | |
446 | Par = Approx_IsoParametric; | |
447 | mydegremin = degreemin; | |
448 | mydegremax = degreemax; | |
449 | mytol3d = Tolerance3d; | |
450 | mytol2d = Tolerance2d; | |
451 | mysquares = Squares; | |
452 | mycut = cutting; | |
453 | myitermax = NbIterations; | |
454 | alldone = Standard_False; | |
455 | } | |
456 | ||
457 | Approx_ComputeLine::Approx_ComputeLine | |
458 | (const Standard_Integer degreemin, | |
459 | const Standard_Integer degreemax, | |
460 | const Standard_Real Tolerance3d, | |
461 | const Standard_Real Tolerance2d, | |
462 | const Standard_Integer NbIterations, | |
463 | const Standard_Boolean cutting, | |
464 | const Approx_ParametrizationType parametrization, | |
465 | const Standard_Boolean Squares) | |
41194117 K |
466 | : myMultiLineNb (0), |
467 | myIsClear (Standard_False) | |
7fd59977 | 468 | { |
469 | myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2); | |
470 | Par = parametrization; | |
471 | mydegremin = degreemin; | |
472 | mydegremax = degreemax; | |
473 | mytol3d = Tolerance3d; | |
474 | mytol2d = Tolerance2d; | |
475 | mysquares = Squares; | |
476 | mycut = cutting; | |
477 | myitermax = NbIterations; | |
478 | myfirstC = AppParCurves_TangencyPoint; | |
479 | mylastC = AppParCurves_TangencyPoint; | |
480 | alldone = Standard_False; | |
481 | } | |
482 | ||
483 | ||
484 | Approx_ComputeLine::Approx_ComputeLine | |
485 | (const MultiLine& Line, | |
486 | const Standard_Integer degreemin, | |
487 | const Standard_Integer degreemax, | |
488 | const Standard_Real Tolerance3d, | |
489 | const Standard_Real Tolerance2d, | |
490 | const Standard_Integer NbIterations, | |
491 | const Standard_Boolean cutting, | |
492 | const Approx_ParametrizationType parametrization, | |
493 | const Standard_Boolean Squares) | |
41194117 K |
494 | : myMultiLineNb (0), |
495 | myIsClear (Standard_False) | |
7fd59977 | 496 | { |
497 | myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2); | |
498 | alldone = Standard_False; | |
499 | mydegremin = degreemin; | |
500 | mydegremax = degreemax; | |
501 | mytol3d = Tolerance3d; | |
502 | mytol2d = Tolerance2d; | |
503 | mysquares = Squares; | |
504 | mycut = cutting; | |
505 | myitermax = NbIterations; | |
506 | Par = parametrization; | |
507 | myfirstC = AppParCurves_TangencyPoint; | |
508 | mylastC = AppParCurves_TangencyPoint; | |
509 | ||
510 | Perform(Line); | |
511 | } | |
512 | ||
513 | ||
514 | ||
515 | void Approx_ComputeLine::Perform(const MultiLine& Line) | |
516 | { | |
517 | #ifdef DEB | |
518 | if (mydebug) DUMP(Line); | |
519 | #endif | |
41194117 K |
520 | if (!myIsClear) |
521 | { | |
7fd59977 | 522 | myMultiCurves.Clear(); |
523 | myPar.Clear(); | |
524 | Tolers3d.Clear(); | |
525 | Tolers2d.Clear(); | |
41194117 | 526 | myMultiLineNb = 0; |
7fd59977 | 527 | } |
41194117 | 528 | else myIsClear = Standard_False; |
7fd59977 | 529 | |
530 | Standard_Integer i, nbp, Thefirstpt, Thelastpt, oldlastpt; | |
531 | Standard_Boolean Finish = Standard_False, | |
532 | begin = Standard_True, Ok = Standard_False, | |
533 | GoUp = Standard_False, Interpol; | |
534 | Standard_Real thetol3d, thetol2d; | |
535 | Approx_Status MyStatus; | |
536 | // gp_Vec V13d, V23d; | |
537 | // gp_Vec2d V2d; | |
538 | Thefirstpt = LineTool::FirstPoint(Line); | |
539 | Thelastpt = LineTool::LastPoint(Line); | |
540 | Standard_Integer myfirstpt = Thefirstpt; | |
541 | Standard_Integer mylastpt = Thelastpt; | |
542 | ||
543 | AppParCurves_ConstraintCouple myCouple1(myfirstpt, myfirstC); | |
544 | AppParCurves_ConstraintCouple myCouple2(mylastpt, mylastC); | |
545 | myConstraints->SetValue(1, myCouple1); | |
546 | myConstraints->SetValue(2, myCouple2); | |
547 | ||
548 | math_Vector TheParam(Thefirstpt, Thelastpt); | |
549 | ||
550 | ||
551 | if (!mycut) { | |
552 | if(myfirstParam.IsNull()) { | |
553 | Parameters(Line, Thefirstpt, Thelastpt, TheParam); | |
554 | } | |
555 | else { | |
556 | for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) { | |
557 | TheParam(i+Thefirstpt-1) = myfirstParam->Value(i); | |
558 | } | |
559 | } | |
560 | TheMultiCurve = AppParCurves_MultiCurve(); | |
561 | alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d); | |
562 | if(!alldone && TheMultiCurve.NbCurves() > 0) { | |
563 | #ifdef DEB | |
564 | if (mydebug) DUMP(TheMultiCurve); | |
565 | #endif | |
566 | myMultiCurves.Append(TheMultiCurve); | |
567 | Tolers3d.Append(currenttol3d); | |
568 | Tolers2d.Append(currenttol2d); | |
569 | Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, mylastpt); | |
570 | for (i = myfirstpt; i <= mylastpt; i++) { | |
571 | ThePar->SetValue(i, myParameters->Value(i)); | |
572 | } | |
573 | myPar.Append(ThePar); | |
574 | } | |
575 | } | |
576 | else { | |
577 | while (!Finish) { | |
578 | oldlastpt = mylastpt; | |
579 | // Gestion du decoupage de la multiline pour approximer: | |
580 | if(!begin) { | |
581 | if (!GoUp) { | |
582 | if (Ok) { | |
583 | // Calcul de la partie a approximer. | |
584 | myfirstpt = mylastpt; | |
585 | mylastpt = Thelastpt; | |
586 | if (myfirstpt == Thelastpt) { | |
587 | Finish = Standard_True; | |
588 | alldone = Standard_True; | |
589 | return; | |
590 | } | |
591 | } | |
592 | else { | |
593 | nbp = mylastpt - myfirstpt + 1; | |
594 | MyStatus = LineTool::WhatStatus(Line, myfirstpt, mylastpt); | |
595 | if (MyStatus == Approx_NoPointsAdded && nbp <= mydegremax+1) { | |
596 | Interpol = ComputeCurve(Line, myfirstpt, mylastpt); | |
597 | if (Interpol) { | |
598 | if (mylastpt == Thelastpt) { | |
599 | Finish = Standard_True; | |
600 | alldone = Standard_True; | |
601 | return; | |
602 | } | |
603 | } | |
604 | } | |
605 | mylastpt = Standard_Integer((myfirstpt + mylastpt)/2); | |
606 | } | |
607 | } | |
608 | GoUp = Standard_False; | |
609 | } | |
610 | ||
611 | // Verification du nombre de points restants par rapport au degre | |
612 | // demande. | |
613 | // ============================================================== | |
614 | nbp = mylastpt - myfirstpt + 1; | |
615 | MyStatus = LineTool::WhatStatus(Line, myfirstpt, mylastpt); | |
616 | if (nbp <= mydegremax+5 ) { | |
617 | // Rajout necessaire de points si possible. | |
618 | // ======================================== | |
619 | GoUp = Standard_False; | |
620 | Ok = Standard_True; | |
7fd59977 | 621 | if (MyStatus == Approx_PointsAdded) { |
622 | // Appel recursif du decoupage: | |
623 | GoUp = Standard_True; | |
624 | ||
625 | MultiLine OtherLine =LineTool::MakeMLBetween(Line, myfirstpt, | |
626 | mylastpt, nbp-1); | |
627 | ||
628 | Standard_Integer nbpdsotherligne = LineTool::FirstPoint(OtherLine) | |
629 | -LineTool::LastPoint(OtherLine); | |
630 | ||
631 | //-- Si MakeML a echoue on retourne une ligne vide | |
41194117 K |
632 | if ((nbpdsotherligne == 0) || myMultiLineNb >= 3) |
633 | { | |
7fd59977 | 634 | //-- cout<<" ** ApproxComputeLine MakeML Echec ** LBR lbr "<<endl; |
635 | if (myfirstpt == mylastpt) break; // Pour etre sur de ne pas | |
636 | // planter la station !! | |
637 | myCouple1.SetIndex(myfirstpt); | |
638 | myCouple2.SetIndex(mylastpt); | |
639 | myConstraints->SetValue(1, myCouple1); | |
640 | myConstraints->SetValue(2, myCouple2); | |
641 | ||
642 | math_Vector Param(myfirstpt, mylastpt); | |
643 | Approx_ParametrizationType SavePar = Par; | |
644 | Par = Approx_IsoParametric; | |
645 | Parameters(Line, myfirstpt, mylastpt, Param); | |
646 | TheMultiCurve = AppParCurves_MultiCurve(); | |
647 | Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d); | |
648 | ||
649 | if (!Ok) { | |
650 | Standard_Real tt3d = currenttol3d, tt2d = currenttol2d; | |
651 | Handle(TColStd_HArray1OfReal) saveParameters = myParameters; | |
652 | AppParCurves_MultiCurve saveMultiCurve = TheMultiCurve; | |
653 | ||
654 | if(SavePar != Approx_IsoParametric) | |
655 | Par = SavePar; | |
656 | else | |
657 | Par = Approx_ChordLength; | |
658 | ||
659 | Parameters(Line, myfirstpt, mylastpt, Param); | |
660 | Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d); | |
661 | ||
662 | if (!Ok && tt3d <= currenttol3d && tt2d <= currenttol2d) { | |
663 | currenttol3d = tt3d; currenttol2d = tt2d; | |
664 | myParameters = saveParameters; | |
665 | TheMultiCurve = saveMultiCurve; | |
666 | } | |
667 | } | |
668 | Par = SavePar; | |
669 | ||
670 | oldlastpt = mylastpt; | |
671 | if (!Ok) { | |
672 | tolreached = Standard_False; | |
673 | if (TheMultiCurve.NbCurves() == 0) { | |
674 | myMultiCurves.Clear(); | |
675 | return; | |
676 | } | |
677 | #ifdef DEB | |
678 | if (mydebug) DUMP(TheMultiCurve); | |
679 | #endif | |
680 | myMultiCurves.Append(TheMultiCurve); | |
681 | Tolers3d.Append(currenttol3d); | |
682 | Tolers2d.Append(currenttol2d); | |
683 | ||
684 | Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt); | |
685 | for (i = myfirstpt; i <= oldlastpt; i++) { | |
686 | ThePar->SetValue(i, myParameters->Value(i)); | |
687 | } | |
688 | myPar.Append(ThePar); | |
689 | } | |
690 | myfirstpt = oldlastpt; | |
691 | mylastpt = Thelastpt; | |
692 | ||
693 | } | |
41194117 K |
694 | else |
695 | { | |
696 | myIsClear = Standard_True; | |
697 | ++myMultiLineNb; | |
7fd59977 | 698 | Perform(OtherLine); |
699 | myfirstpt = mylastpt; | |
41194117 | 700 | mylastpt = Thelastpt; |
7fd59977 | 701 | } |
702 | } | |
703 | ||
704 | if (MyStatus == Approx_NoPointsAdded && !begin) { | |
705 | // On rend la meilleure approximation obtenue precedemment. | |
706 | // ======================================================== | |
707 | GoUp = Standard_True; | |
708 | tolreached = Standard_False; | |
709 | if (TheMultiCurve.NbCurves() == 0) { | |
710 | myMultiCurves.Clear(); | |
711 | return; | |
712 | } | |
713 | #ifdef DEB | |
714 | if (mydebug) DUMP(TheMultiCurve); | |
715 | #endif | |
716 | myMultiCurves.Append(TheMultiCurve); | |
717 | Tolers3d.Append(currenttol3d); | |
718 | Tolers2d.Append(currenttol2d); | |
719 | ||
720 | Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt); | |
721 | for (i = myfirstpt; i <= oldlastpt; i++) { | |
722 | ThePar->SetValue(i, myParameters->Value(i)); | |
723 | } | |
724 | myPar.Append(ThePar); | |
725 | ||
726 | myfirstpt = oldlastpt; | |
727 | mylastpt = Thelastpt; | |
728 | } | |
729 | ||
730 | else if (MyStatus == Approx_NoApproximation) { | |
731 | // On ne fait pas d approximation entre myfirstpt et mylastpt. | |
732 | // =========================================================== | |
733 | // On stocke pour pouvoir en informer l utilisateur. | |
734 | GoUp = Standard_True; | |
735 | myfirstpt = mylastpt; | |
736 | mylastpt = Thelastpt; | |
737 | } | |
738 | } | |
739 | ||
740 | if (myfirstpt == Thelastpt) { | |
741 | Finish = Standard_True; | |
742 | alldone = Standard_True; | |
743 | return; | |
744 | } | |
745 | if (!GoUp) { | |
746 | if (myfirstpt == mylastpt) break; // Pour etre sur de ne pas | |
747 | // planter la station !! | |
748 | myCouple1.SetIndex(myfirstpt); | |
749 | myCouple2.SetIndex(mylastpt); | |
750 | myConstraints->SetValue(1, myCouple1); | |
751 | myConstraints->SetValue(2, myCouple2); | |
752 | ||
753 | // Calcul des parametres sur ce nouvel intervalle. | |
754 | // On recupere les parametres initiaux lors du decoupage. | |
755 | ||
756 | math_Vector Param(myfirstpt, mylastpt); | |
757 | if (begin) { | |
758 | if(myfirstParam.IsNull()) { | |
759 | Parameters(Line, myfirstpt, mylastpt, Param); | |
760 | } | |
761 | else { | |
762 | for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) { | |
763 | Param(i) = myfirstParam->Value(i); | |
764 | } | |
765 | myfirstParam.Nullify(); | |
766 | } | |
767 | TheParam = Param; | |
768 | begin = Standard_False; | |
769 | } | |
770 | else { | |
771 | Standard_Real pfirst = TheParam.Value(myfirstpt); | |
772 | Standard_Real plast = TheParam.Value(mylastpt); | |
773 | for (i = myfirstpt; i <= mylastpt; i++) { | |
774 | Param(i) = (TheParam.Value(i)-pfirst)/(plast-pfirst); | |
775 | } | |
776 | } | |
777 | ||
778 | TheMultiCurve = AppParCurves_MultiCurve(); | |
779 | Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d); | |
780 | ||
781 | } | |
782 | } | |
783 | } | |
784 | } | |
785 | ||
786 | ||
787 | ||
788 | const TColStd_Array1OfReal& Approx_ComputeLine::Parameters(const Standard_Integer Index) const | |
789 | { | |
790 | return (myPar.Value(Index))->Array1(); | |
791 | } | |
792 | ||
793 | ||
794 | Standard_Integer Approx_ComputeLine::NbMultiCurves()const | |
795 | { | |
796 | return myMultiCurves.Length(); | |
797 | } | |
798 | ||
799 | AppParCurves_MultiCurve& Approx_ComputeLine::ChangeValue(const Standard_Integer Index) | |
800 | { | |
801 | return myMultiCurves.ChangeValue(Index); | |
802 | } | |
803 | ||
804 | ||
805 | const AppParCurves_MultiCurve& Approx_ComputeLine::Value(const Standard_Integer Index) | |
806 | const | |
807 | { | |
808 | return myMultiCurves.Value(Index); | |
809 | } | |
810 | ||
811 | ||
812 | const AppParCurves_MultiBSpCurve& Approx_ComputeLine::SplineValue() | |
813 | { | |
814 | Approx_MCurvesToBSpCurve Trans; | |
815 | Trans.Perform(myMultiCurves); | |
816 | myspline = Trans.Value(); | |
817 | return myspline; | |
818 | } | |
819 | ||
820 | ||
821 | ||
822 | ||
823 | ||
824 | void Approx_ComputeLine::Parameters(const MultiLine& Line, | |
825 | const Standard_Integer firstP, | |
826 | const Standard_Integer lastP, | |
827 | math_Vector& TheParameters) const | |
828 | { | |
96a95605 | 829 | Standard_Integer i, j, nbP2d, nbP3d; |
7fd59977 | 830 | Standard_Real dist; |
831 | gp_Pnt P1, P2; | |
832 | gp_Pnt2d P12d, P22d; | |
7fd59977 | 833 | |
834 | if (Par == Approx_ChordLength || Par == Approx_Centripetal) { | |
835 | nbP3d = LineTool::NbP3d(Line); | |
836 | nbP2d = LineTool::NbP2d(Line); | |
837 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; | |
838 | if (nbP3d == 0) mynbP3d = 1; | |
839 | if (nbP2d == 0) mynbP2d = 1; | |
840 | ||
841 | TheParameters(firstP) = 0.0; | |
842 | dist = 0.0; | |
843 | TColgp_Array1OfPnt tabP(1, mynbP3d); | |
844 | TColgp_Array1OfPnt tabPP(1, mynbP3d); | |
845 | TColgp_Array1OfPnt2d tabP2d(1, mynbP2d); | |
846 | TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d); | |
847 | ||
848 | for (i = firstP+1; i <= lastP; i++) { | |
849 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i-1, tabP, tabP2d); | |
850 | else if (nbP2d != 0) LineTool::Value(Line, i-1, tabP2d); | |
851 | else if (nbP3d != 0) LineTool::Value(Line, i-1, tabP); | |
852 | ||
853 | if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d); | |
854 | else if (nbP2d != 0) LineTool::Value(Line, i, tabPP2d); | |
855 | else if (nbP3d != 0) LineTool::Value(Line, i, tabPP); | |
856 | dist = 0; | |
857 | for (j = 1; j <= nbP3d; j++) { | |
858 | P1 = tabP(j); | |
859 | P2 = tabPP(j); | |
860 | dist += P2.Distance(P1); | |
861 | } | |
862 | for (j = 1; j <= nbP2d; j++) { | |
863 | P12d = tabP2d(j); | |
864 | P22d = tabPP2d(j); | |
865 | dist += P22d.Distance(P12d); | |
866 | } | |
867 | if(Par == Approx_ChordLength) | |
868 | TheParameters(i) = TheParameters(i-1) + dist; | |
869 | else {// Par == Approx_Centripetal | |
870 | TheParameters(i) = TheParameters(i-1) + Sqrt(dist); | |
871 | } | |
872 | } | |
873 | for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP); | |
874 | } | |
875 | else { | |
876 | for (i = firstP; i <= lastP; i++) { | |
877 | TheParameters(i) = (Standard_Real(i)-firstP)/ | |
878 | (Standard_Real(lastP)-Standard_Real(firstP)); | |
879 | } | |
880 | } | |
881 | } | |
882 | ||
883 | ||
884 | Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line, | |
885 | const Standard_Integer fpt, | |
886 | const Standard_Integer lpt, | |
887 | math_Vector& Para, | |
888 | Standard_Real& TheTol3d, | |
889 | Standard_Real& TheTol2d) | |
890 | { | |
891 | ||
892 | Standard_Integer deg, i; | |
893 | Standard_Boolean mydone; | |
894 | Standard_Real Fv; | |
895 | Standard_Integer nbp = lpt-fpt+1; | |
896 | ||
897 | math_Vector ParSav(Para.Lower(), Para.Upper()); | |
898 | for (i = Para.Lower(); i <= Para.Upper(); i++) { | |
899 | ParSav(i) = Para(i); | |
900 | } | |
901 | Standard_Integer Mdegmax = mydegremax; | |
902 | if(nbp < Mdegmax+5 && mycut) { | |
903 | Mdegmax = nbp - 5; | |
904 | } | |
905 | if(Mdegmax < mydegremin) { | |
906 | Mdegmax = mydegremin; | |
907 | } | |
908 | ||
909 | currenttol3d = currenttol2d = RealLast(); | |
910 | for (deg = Min(nbp-1,mydegremin); deg <= Mdegmax; deg++) { | |
911 | AppParCurves_MultiCurve mySCU(deg+1); | |
912 | if (mysquares) { | |
913 | Approx_ParLeastSquareOfMyGradient SQ(Line, fpt, lpt, | |
914 | myfirstC, mylastC, Para, deg+1); | |
915 | mydone = SQ.IsDone(); | |
916 | mySCU = SQ.BezierValue(); | |
917 | SQ.Error(Fv, TheTol3d, TheTol2d); | |
918 | } | |
919 | else { | |
920 | Approx_MyGradient GRAD(Line, fpt, lpt, myConstraints, | |
921 | Para, deg, mytol3d, mytol2d, myitermax); | |
922 | mydone = GRAD.IsDone(); | |
923 | mySCU = GRAD.Value(); | |
924 | if (mySCU.NbCurves() == 0) | |
925 | continue; | |
926 | TheTol3d = GRAD.MaxError3d(); | |
927 | TheTol2d = GRAD.MaxError2d(); | |
928 | } | |
929 | Standard_Real uu1 = Para(Para.Lower()), uu2; | |
930 | Standard_Boolean restau = Standard_False; | |
931 | for ( i = Para.Lower()+1; i <= Para.Upper(); i++) { | |
932 | uu2 = Para(i); | |
933 | if (uu2 <= uu1) { | |
934 | restau = Standard_True; | |
935 | // cout << "restau = Standard_True" << endl; | |
936 | break; | |
937 | } | |
938 | uu1 = uu2; | |
939 | } | |
940 | if (restau) { | |
941 | for (i = Para.Lower(); i <= Para.Upper(); i++) { | |
942 | Para(i) = ParSav(i); | |
943 | } | |
944 | } | |
945 | if (mydone) { | |
946 | if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) { | |
947 | // Stockage de la multicurve approximee. | |
948 | tolreached = Standard_True; | |
949 | #ifdef DEB | |
950 | if (mydebug) DUMP(mySCU); | |
951 | #endif | |
952 | myMultiCurves.Append(mySCU); | |
953 | // Stockage des parametres de la partie de MultiLine approximee: | |
954 | // A ameliorer !! (bq trop de recopies) | |
955 | Handle(TColStd_HArray1OfReal) ThePar = | |
956 | new TColStd_HArray1OfReal(Para.Lower(), Para.Upper()); | |
957 | for (i = Para.Lower(); i <= Para.Upper(); i++) { | |
958 | ThePar->SetValue(i, Para(i)); | |
959 | } | |
960 | myPar.Append(ThePar); | |
961 | Tolers3d.Append(TheTol3d); | |
962 | Tolers2d.Append(TheTol2d); | |
963 | return Standard_True; | |
964 | } | |
965 | } | |
966 | ||
967 | if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) { | |
968 | TheMultiCurve = mySCU; | |
969 | currenttol3d = TheTol3d; | |
970 | currenttol2d = TheTol2d; | |
971 | myParameters = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper()); | |
972 | for (i = Para.Lower(); i <= Para.Upper(); i++) { | |
973 | myParameters->SetValue(i, Para(i)); | |
974 | } | |
975 | } | |
976 | ||
977 | } | |
978 | ||
979 | return Standard_False; | |
980 | } | |
981 | ||
982 | ||
983 | ||
984 | ||
985 | Standard_Boolean Approx_ComputeLine::ComputeCurve(const MultiLine& Line, | |
986 | const Standard_Integer firstpt, | |
987 | const Standard_Integer lastpt) | |
988 | { | |
989 | Standard_Integer i, j, nbP3d, nbP2d, deg; | |
990 | gp_Vec V13d, V23d; | |
991 | gp_Vec2d V12d, V22d; | |
992 | gp_Pnt P1, P2; | |
993 | gp_Pnt2d P12d, P22d; | |
96a95605 DB |
994 | Standard_Boolean Tangent1, Tangent2, mydone= Standard_False; |
995 | #ifdef DEB | |
996 | Standard_Boolean Parallel; | |
997 | #endif | |
7fd59977 | 998 | Standard_Integer myfirstpt = firstpt, mylastpt = lastpt; |
999 | Standard_Integer nbp = lastpt-firstpt+1, Kopt = 0; | |
7fd59977 | 1000 | math_Vector Para(firstpt, lastpt); |
1001 | ||
1002 | Parameters(Line, firstpt, lastpt, Para); | |
1003 | ||
1004 | nbP3d = LineTool::NbP3d(Line); | |
1005 | nbP2d = LineTool::NbP2d(Line); | |
1006 | Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d; | |
1007 | if (nbP3d == 0) mynbP3d = 1 ; | |
1008 | if (nbP2d == 0) mynbP2d = 1 ; | |
1009 | ||
1010 | ||
1011 | TColgp_Array1OfVec tabV1(1, mynbP3d), tabV2(1, mynbP3d); | |
1012 | TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d), tabP(1, mynbP3d); | |
1013 | TColgp_Array1OfVec2d tabV12d(1, mynbP2d), tabV22d(1, mynbP2d); | |
1014 | TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d), tabP2d(1, mynbP2d); | |
1015 | ||
1016 | if (nbP3d != 0 && nbP2d != 0) { | |
1017 | LineTool::Value(Line, myfirstpt,tabP1,tabP12d); | |
1018 | LineTool::Value(Line, mylastpt,tabP2,tabP22d); | |
1019 | Tangent1 = LineTool::Tangency(Line, myfirstpt,tabV1,tabV12d); | |
1020 | Tangent2 = LineTool::Tangency(Line, mylastpt,tabV2,tabV22d); | |
1021 | } | |
1022 | else if (nbP2d != 0) { | |
1023 | LineTool::Value(Line, myfirstpt,tabP12d); | |
1024 | LineTool::Value(Line, mylastpt,tabP22d); | |
1025 | Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV12d); | |
1026 | Tangent2 = LineTool::Tangency(Line, mylastpt, tabV22d); | |
1027 | } | |
1028 | else { | |
1029 | LineTool::Value(Line, myfirstpt,tabP1); | |
1030 | LineTool::Value(Line, mylastpt,tabP2); | |
1031 | Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV1); | |
1032 | Tangent2 = LineTool::Tangency(Line, mylastpt, tabV2); | |
1033 | } | |
1034 | ||
1035 | if (Tangent1) Kopt++; | |
1036 | if (Tangent2) Kopt++; | |
1037 | ||
1038 | ||
1039 | if (nbp == 2) { | |
1040 | // S il n y a que 2 points, on verifie quand meme que les tangentes sont | |
1041 | // alignees. | |
96a95605 | 1042 | #ifdef DEB |
7fd59977 | 1043 | Parallel = Standard_True; |
96a95605 | 1044 | #endif |
7fd59977 | 1045 | if (Tangent1) { |
1046 | for (i = 1; i <= nbP3d; i++) { | |
1047 | gp_Vec PVec(tabP1(i), tabP2(i)); | |
1048 | V13d = tabV1(i); | |
1049 | if (!PVec.IsParallel(V13d, Precision::Angular())) { | |
96a95605 | 1050 | #ifdef DEB |
7fd59977 | 1051 | Parallel = Standard_False; |
96a95605 | 1052 | #endif |
7fd59977 | 1053 | break; |
1054 | } | |
1055 | } | |
1056 | for (i = 1; i <= nbP2d; i++) { | |
1057 | gp_Vec2d PVec2d(tabP12d(i), tabP22d(i)); | |
1058 | V12d = tabV12d(i); | |
1059 | if (!PVec2d.IsParallel(V12d, Precision::Angular())) { | |
96a95605 | 1060 | #ifdef DEB |
7fd59977 | 1061 | Parallel = Standard_False; |
96a95605 | 1062 | #endif |
7fd59977 | 1063 | break; |
1064 | } | |
1065 | } | |
1066 | } | |
1067 | ||
1068 | if (Tangent2) { | |
1069 | for (i = 1; i <= nbP3d; i++) { | |
1070 | gp_Vec PVec(tabP1(i), tabP2(i)); | |
1071 | V23d = tabV2(i); | |
1072 | if (!PVec.IsParallel(V23d, Precision::Angular())) { | |
96a95605 | 1073 | #ifdef DEB |
7fd59977 | 1074 | Parallel = Standard_False; |
96a95605 | 1075 | #endif |
7fd59977 | 1076 | break; |
1077 | } | |
1078 | } | |
1079 | for (i = 1; i <= nbP2d; i++) { | |
1080 | gp_Vec2d PVec2d(tabP12d(i), tabP22d(i)); | |
1081 | V22d = tabV22d(i); | |
1082 | if (!PVec2d.IsParallel(V22d, Precision::Angular())) { | |
96a95605 | 1083 | #ifdef DEB |
7fd59977 | 1084 | Parallel = Standard_False; |
96a95605 | 1085 | #endif |
7fd59977 | 1086 | break; |
1087 | } | |
1088 | } | |
1089 | } | |
1090 | ||
1091 | #ifdef DEB | |
1092 | if (!Parallel) { | |
1093 | if (mydebug) cout <<"droite mais tangentes pas vraiment paralleles!!"<< endl; | |
1094 | } | |
1095 | #endif | |
1096 | AppParCurves_MultiCurve mySCU(mydegremin+1); | |
1097 | if (nbP3d != 0 && nbP2d != 0) { | |
1098 | AppParCurves_MultiPoint MPole1(tabP1, tabP12d); | |
1099 | AppParCurves_MultiPoint MPole2(tabP2, tabP22d); | |
1100 | mySCU.SetValue(1, MPole1); | |
1101 | mySCU.SetValue(mydegremin+1, MPole2); | |
1102 | for (i = 2; i <= mydegremin; i++) { | |
1103 | for (j = 1; j<= nbP3d; j++) { | |
1104 | P1 = tabP1(j); | |
1105 | P2 = tabP2(j); | |
1106 | tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin); | |
1107 | } | |
1108 | for (j = 1; j<= nbP2d; j++) { | |
1109 | P12d = tabP12d(j); | |
1110 | P22d = tabP22d(j); | |
1111 | tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin); | |
1112 | } | |
1113 | AppParCurves_MultiPoint MPole(tabP, tabP2d); | |
1114 | mySCU.SetValue(i, MPole); | |
1115 | } | |
1116 | ||
1117 | } | |
1118 | else if (nbP3d != 0) { | |
1119 | AppParCurves_MultiPoint MPole1(tabP1); | |
1120 | AppParCurves_MultiPoint MPole2(tabP2); | |
1121 | mySCU.SetValue(1, MPole1); | |
1122 | mySCU.SetValue(mydegremin+1, MPole2); | |
1123 | for (i = 2; i <= mydegremin; i++) { | |
1124 | for (j = 1; j<= nbP3d; j++) { | |
1125 | P1 = tabP1(j); | |
1126 | P2 = tabP2(j); | |
1127 | tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin); | |
1128 | } | |
1129 | AppParCurves_MultiPoint MPole(tabP); | |
1130 | mySCU.SetValue(i, MPole); | |
1131 | } | |
1132 | } | |
1133 | else if (nbP2d != 0) { | |
1134 | AppParCurves_MultiPoint MPole1(tabP12d); | |
1135 | AppParCurves_MultiPoint MPole2(tabP22d); | |
1136 | mySCU.SetValue(1, MPole1); | |
1137 | mySCU.SetValue(mydegremin+1, MPole2); | |
1138 | for (i = 2; i <= mydegremin; i++) { | |
1139 | for (j = 1; j<= nbP2d; j++) { | |
1140 | P12d = tabP12d(j); | |
1141 | P22d = tabP22d(j); | |
1142 | tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin); | |
1143 | } | |
1144 | AppParCurves_MultiPoint MPole(tabP2d); | |
1145 | mySCU.SetValue(i, MPole); | |
1146 | } | |
1147 | } | |
1148 | mydone = Standard_True; | |
1149 | // Stockage de la multicurve approximee. | |
1150 | tolreached = Standard_True; | |
1151 | #ifdef DEB | |
1152 | if (mydebug) DUMP(mySCU); | |
1153 | #endif | |
1154 | myMultiCurves.Append(mySCU); | |
1155 | Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper()); | |
1156 | for (i = Para.Lower(); i <= Para.Upper(); i++) { | |
1157 | ThePar->SetValue(i, Para(i)); | |
1158 | } | |
1159 | myPar.Append(ThePar); | |
1160 | Tolers3d.Append(Precision::Confusion()); | |
1161 | Tolers2d.Append(Precision::PConfusion()); | |
1162 | return mydone; | |
1163 | } | |
1164 | ||
1165 | // avec les tangentes. | |
1166 | deg = nbp+1; | |
1167 | AppParCurves_MultiCurve mySCU(deg+1); | |
1168 | AppParCurves_Constraint Cons = AppParCurves_TangencyPoint; | |
1169 | Standard_Real lambda1, lambda2; | |
1170 | math_Vector V1(1, nbP3d*3+nbP2d*2); | |
1171 | math_Vector V2(1, nbP3d*3+nbP2d*2); | |
1172 | FirstTangencyVector(Line, myfirstpt, V1); | |
1173 | lambda1 = SearchFirstLambda(Line, Para, V1, myfirstpt); | |
1174 | ||
1175 | LastTangencyVector(Line, mylastpt, V2); | |
1176 | lambda2 = SearchLastLambda(Line, Para, V2, mylastpt); | |
1177 | ||
1178 | Approx_ParLeastSquareOfMyGradient | |
1179 | LSQ(Line, myfirstpt, mylastpt, | |
1180 | Cons, Cons, Para, deg+1); | |
1181 | ||
1182 | lambda1 = lambda1/deg; | |
1183 | lambda2 = lambda2/deg; | |
1184 | LSQ.Perform(Para, V1, V2, lambda1, lambda2); | |
1185 | mydone = LSQ.IsDone(); | |
1186 | mySCU = LSQ.BezierValue(); | |
1187 | ||
1188 | if (mydone) { | |
1189 | Standard_Real Fv, TheTol3d, TheTol2d; | |
1190 | LSQ.Error(Fv, TheTol3d, TheTol2d); | |
1191 | ||
1192 | // Stockage de la multicurve approximee. | |
1193 | tolreached = Standard_True; | |
1194 | #ifdef DEB | |
1195 | if (mydebug) DUMP(mySCU); | |
1196 | #endif | |
1197 | myMultiCurves.Append(mySCU); | |
1198 | Handle(TColStd_HArray1OfReal) ThePar = | |
1199 | new TColStd_HArray1OfReal(Para.Lower(), Para.Upper()); | |
1200 | for (i = Para.Lower(); i <= Para.Upper(); i++) { | |
1201 | ThePar->SetValue(i, Para(i)); | |
1202 | } | |
1203 | myPar.Append(ThePar); | |
1204 | Tolers3d.Append(TheTol3d); | |
1205 | Tolers2d.Append(TheTol2d); | |
1206 | return Standard_True; | |
1207 | } | |
1208 | return mydone; | |
1209 | } | |
1210 | ||
1211 | ||
1212 | ||
1213 | void Approx_ComputeLine::Init(const Standard_Integer degreemin, | |
1214 | const Standard_Integer degreemax, | |
1215 | const Standard_Real Tolerance3d, | |
1216 | const Standard_Real Tolerance2d, | |
1217 | const Standard_Integer NbIterations, | |
1218 | const Standard_Boolean cutting, | |
1219 | const Approx_ParametrizationType parametrization, | |
1220 | const Standard_Boolean Squares) | |
1221 | { | |
1222 | mydegremin = degreemin; | |
1223 | mydegremax = degreemax; | |
1224 | mytol3d = Tolerance3d; | |
1225 | mytol2d = Tolerance2d; | |
1226 | Par = parametrization; | |
1227 | mysquares = Squares; | |
1228 | mycut = cutting; | |
1229 | myitermax = NbIterations; | |
1230 | } | |
1231 | ||
1232 | ||
1233 | ||
1234 | void Approx_ComputeLine::SetDegrees(const Standard_Integer degreemin, | |
1235 | const Standard_Integer degreemax) | |
1236 | { | |
1237 | mydegremin = degreemin; | |
1238 | mydegremax = degreemax; | |
1239 | } | |
1240 | ||
1241 | ||
1242 | void Approx_ComputeLine::SetTolerances(const Standard_Real Tolerance3d, | |
1243 | const Standard_Real Tolerance2d) | |
1244 | { | |
1245 | mytol3d = Tolerance3d; | |
1246 | mytol2d = Tolerance2d; | |
1247 | } | |
1248 | ||
1249 | ||
1250 | void Approx_ComputeLine::SetConstraints(const AppParCurves_Constraint FirstC, | |
1251 | const AppParCurves_Constraint LastC) | |
1252 | { | |
1253 | myfirstC = FirstC; | |
1254 | mylastC = LastC; | |
1255 | } | |
1256 | ||
1257 | ||
1258 | ||
1259 | Standard_Boolean Approx_ComputeLine::IsAllApproximated() | |
1260 | const { | |
1261 | return alldone; | |
1262 | } | |
1263 | ||
1264 | Standard_Boolean Approx_ComputeLine::IsToleranceReached() | |
1265 | const { | |
1266 | return tolreached; | |
1267 | } | |
1268 | ||
1269 | void Approx_ComputeLine::Error(const Standard_Integer Index, | |
1270 | Standard_Real& tol3d, | |
1271 | Standard_Real& tol2d) const | |
1272 | { | |
1273 | tol3d = Tolers3d.Value(Index); | |
1274 | tol2d = Tolers2d.Value(Index); | |
1275 | } | |
1276 | ||
1277 | void Approx_ComputeLine::Parametrization(Approx_ParametrizationType& partype) const | |
1278 | { | |
1279 | partype = Par; | |
1280 | } |