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