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