b311480e |
1 | // Created on: 1993-03-30 |
2 | // Created by: Laurent BUCHARD |
3 | // Copyright (c) 1993-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | #include <AppParCurves_Constraint.hxx> |
18 | #include <GeomAbs_SurfaceType.hxx> |
19 | #include <IntSurf_Quadric.hxx> |
20 | #include <gp_Trsf.hxx> |
21 | #include <gp_Trsf2d.hxx> |
22 | #include <IntSurf_PntOn2S.hxx> |
23 | #include <Precision.hxx> |
f44aa197 |
24 | #include <ApproxInt_KnotTools.hxx> |
7fd59977 |
25 | |
4e14c88f |
26 | // If quantity of points is less than aMinNbPointsForApprox |
27 | // then interpolation is used. |
28 | const Standard_Integer aMinNbPointsForApprox = 5; |
7fd59977 |
29 | |
4e14c88f |
30 | // This constant should be removed in the future. |
31 | const Standard_Real RatioTol = 1.5 ; |
7fd59977 |
32 | |
f44aa197 |
33 | //======================================================================= |
34 | //function : ComputeTrsf3d |
35 | //purpose : |
36 | //======================================================================= |
37 | static void ComputeTrsf3d(const Handle(TheWLine)& theline, |
4e14c88f |
38 | Standard_Real& theXo, |
39 | Standard_Real& theYo, |
40 | Standard_Real& theZo) |
f44aa197 |
41 | { |
4e14c88f |
42 | const Standard_Integer aNbPnts = theline->NbPnts(); |
43 | Standard_Real aXmin = RealLast(), aYmin = RealLast(), aZmin = RealLast(); |
44 | for(Standard_Integer i=1;i<=aNbPnts;i++) |
45 | { |
46 | const gp_Pnt& P = theline->Point(i).Value(); |
47 | aXmin = Min(P.X(), aXmin); |
48 | aYmin = Min(P.Y(), aYmin); |
49 | aZmin = Min(P.Z(), aZmin); |
50 | } |
51 | |
52 | theXo = -aXmin; |
53 | theYo = -aYmin; |
54 | theZo = -aZmin; |
7fd59977 |
55 | } |
56 | |
f44aa197 |
57 | //======================================================================= |
58 | //function : ComputeTrsf2d |
4e14c88f |
59 | //purpose : |
f44aa197 |
60 | //======================================================================= |
61 | static void ComputeTrsf2d(const Handle(TheWLine)& theline, |
f44aa197 |
62 | const Standard_Boolean onFirst, |
4e14c88f |
63 | Standard_Real& theUo, |
64 | Standard_Real& theVo) |
65 | { |
66 | const Standard_Integer aNbPnts = theline->NbPnts(); |
67 | Standard_Real aUmin = RealLast(), aVmin = RealLast(); |
7fd59977 |
68 | |
4e14c88f |
69 | // pointer to a member-function |
70 | void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const; |
7fd59977 |
71 | |
4e14c88f |
72 | if (onFirst) |
73 | pfunc = &IntSurf_PntOn2S::ParametersOnS1; |
74 | else |
75 | pfunc = &IntSurf_PntOn2S::ParametersOnS2; |
76 | |
77 | for(Standard_Integer i=1; i<=aNbPnts; i++) |
78 | { |
79 | const IntSurf_PntOn2S& POn2S = theline->Point(i); |
80 | Standard_Real U,V; |
81 | (POn2S.*pfunc)(U,V); |
82 | aUmin = Min(U, aUmin); |
83 | aVmin = Min(V, aVmin); |
84 | } |
7fd59977 |
85 | |
4e14c88f |
86 | theUo = -aUmin; |
87 | theVo = -aVmin; |
7fd59977 |
88 | } |
89 | |
f44aa197 |
90 | //======================================================================= |
91 | //function : Parameters |
92 | //purpose : |
93 | //======================================================================= |
94 | static void Parameters(const ApproxInt_TheMultiLine& Line, |
95 | const Standard_Integer firstP, |
96 | const Standard_Integer lastP, |
97 | const Approx_ParametrizationType Par, |
98 | math_Vector& TheParameters) |
99 | { |
100 | Standard_Integer i, j, nbP2d, nbP3d; |
101 | Standard_Real dist; |
102 | gp_Pnt P1, P2; |
103 | gp_Pnt2d P12d, P22d; |
104 | |
105 | if (Par == Approx_ChordLength || Par == Approx_Centripetal) { |
106 | nbP3d = ApproxInt_TheMultiLineTool::NbP3d(Line); |
107 | nbP2d = ApproxInt_TheMultiLineTool::NbP2d(Line); |
108 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; |
109 | if (nbP3d == 0) mynbP3d = 1; |
110 | if (nbP2d == 0) mynbP2d = 1; |
7fd59977 |
111 | |
f44aa197 |
112 | TheParameters(firstP) = 0.0; |
113 | dist = 0.0; |
114 | TColgp_Array1OfPnt tabP(1, mynbP3d); |
115 | TColgp_Array1OfPnt tabPP(1, mynbP3d); |
116 | TColgp_Array1OfPnt2d tabP2d(1, mynbP2d); |
117 | TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d); |
7fd59977 |
118 | |
f44aa197 |
119 | for (i = firstP+1; i <= lastP; i++) { |
120 | if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP, tabP2d); |
121 | else if (nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP2d); |
122 | else if (nbP3d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP); |
123 | |
124 | if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP, tabPP2d); |
125 | else if (nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP2d); |
126 | else if (nbP3d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP); |
127 | dist = 0; |
128 | for (j = 1; j <= nbP3d; j++) { |
129 | P1 = tabP(j); |
130 | P2 = tabPP(j); |
131 | dist += P2.Distance(P1); |
132 | } |
133 | for (j = 1; j <= nbP2d; j++) { |
134 | P12d = tabP2d(j); |
135 | P22d = tabPP2d(j); |
136 | dist += P22d.Distance(P12d); |
137 | } |
138 | if(Par == Approx_ChordLength) |
139 | TheParameters(i) = TheParameters(i-1) + dist; |
140 | else {// Par == Approx_Centripetal |
141 | TheParameters(i) = TheParameters(i-1) + Sqrt(dist); |
142 | } |
143 | } |
144 | for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP); |
145 | } |
146 | else { |
147 | for (i = firstP; i <= lastP; i++) { |
148 | TheParameters(i) = (Standard_Real(i)-firstP)/ |
149 | (Standard_Real(lastP)-Standard_Real(firstP)); |
150 | } |
151 | } |
152 | } |
153 | |
154 | //======================================================================= |
4e14c88f |
155 | //function : Default constructor |
156 | //purpose : |
f44aa197 |
157 | //======================================================================= |
4e14c88f |
158 | ApproxInt_Approx::ApproxInt_Approx(): |
159 | myComputeLine(4, 8, 0.001, 0.001, 5), |
160 | myComputeLineBezier(4, 8, 0.001, 0.001, 5), |
161 | myWithTangency(Standard_True), |
162 | myTol3d(0.001), |
163 | myTol2d(0.001), |
164 | myDegMin(4), |
165 | myDegMax(8), |
166 | myNbIterMax(5), |
167 | myTolReached3d(0.0), |
168 | myTolReached2d(0.0) |
f44aa197 |
169 | { |
7fd59977 |
170 | myComputeLine.SetContinuity(2); |
4e14c88f |
171 | //myComputeLineBezier.SetContinuity(2); |
7fd59977 |
172 | } |
7fd59977 |
173 | |
f44aa197 |
174 | //======================================================================= |
175 | //function : Perform |
176 | //purpose : Build without surfaces information. |
177 | //======================================================================= |
7fd59977 |
178 | void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline, |
f44aa197 |
179 | const Standard_Boolean ApproxXYZ, |
180 | const Standard_Boolean ApproxU1V1, |
181 | const Standard_Boolean ApproxU2V2, |
182 | const Standard_Integer indicemin, |
183 | const Standard_Integer indicemax) |
184 | { |
185 | // Prepare DS. |
186 | prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); |
187 | |
4e14c88f |
188 | const Standard_Integer nbpntbez = myData.indicemax - myData.indicemin; |
189 | if(nbpntbez < aMinNbPointsForApprox) |
f44aa197 |
190 | myData.myBezierApprox = Standard_False; |
7fd59977 |
191 | else |
f44aa197 |
192 | myData.myBezierApprox = Standard_True; |
193 | |
194 | // Fill data structure. |
4e14c88f |
195 | fillData(theline); |
f44aa197 |
196 | |
197 | // Build knots. |
198 | buildKnots(theline, NULL); |
4e14c88f |
199 | if (myKnots.Length() == 2 && |
200 | indicemax - indicemin > 2 * myData.myNbPntMax) |
f44aa197 |
201 | { |
4e14c88f |
202 | // At least 3 knots for BrepApprox. |
203 | myKnots.ChangeLast() = (indicemax - indicemin) / 2; |
204 | myKnots.Append(indicemax); |
7fd59977 |
205 | } |
f44aa197 |
206 | |
4e14c88f |
207 | myComputeLine.Init (myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization); |
208 | myComputeLineBezier.Init(myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization); |
209 | |
f44aa197 |
210 | buildCurve(theline, NULL); |
7fd59977 |
211 | } |
212 | |
f44aa197 |
213 | //======================================================================= |
214 | //function : Perform |
4e14c88f |
215 | //purpose : Definition of next steps according to surface types |
216 | // (i.e. coordination algorithm). |
f44aa197 |
217 | //======================================================================= |
7fd59977 |
218 | void ApproxInt_Approx::Perform(const ThePSurface& Surf1, |
f44aa197 |
219 | const ThePSurface& Surf2, |
220 | const Handle(TheWLine)& theline, |
221 | const Standard_Boolean ApproxXYZ, |
222 | const Standard_Boolean ApproxU1V1, |
223 | const Standard_Boolean ApproxU2V2, |
224 | const Standard_Integer indicemin, |
225 | const Standard_Integer indicemax) |
226 | { |
7fd59977 |
227 | |
4e14c88f |
228 | myTolReached3d = myTolReached2d = 0.; |
f44aa197 |
229 | |
4e14c88f |
230 | const GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1); |
231 | const GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2); |
f44aa197 |
232 | |
4e14c88f |
233 | const Standard_Boolean isQuadric = ((typeS1 == GeomAbs_Plane) || |
234 | (typeS1 == GeomAbs_Cylinder) || |
235 | (typeS1 == GeomAbs_Sphere) || |
236 | (typeS1 == GeomAbs_Cone) || |
237 | (typeS2 == GeomAbs_Plane) || |
238 | (typeS2 == GeomAbs_Cylinder) || |
239 | (typeS2 == GeomAbs_Sphere) || |
240 | (typeS2 == GeomAbs_Cone)); |
7fd59977 |
241 | |
4e14c88f |
242 | if(isQuadric) |
f44aa197 |
243 | { |
7fd59977 |
244 | IntSurf_Quadric Quad; |
245 | Standard_Boolean SecondIsImplicit=Standard_False; |
f44aa197 |
246 | switch (typeS1) |
247 | { |
7fd59977 |
248 | case GeomAbs_Plane: |
249 | Quad.SetValue(ThePSurfaceTool::Plane(Surf1)); |
250 | break; |
f44aa197 |
251 | |
7fd59977 |
252 | case GeomAbs_Cylinder: |
253 | Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1)); |
254 | break; |
f44aa197 |
255 | |
7fd59977 |
256 | case GeomAbs_Sphere: |
257 | Quad.SetValue(ThePSurfaceTool::Sphere(Surf1)); |
258 | break; |
f44aa197 |
259 | |
7fd59977 |
260 | case GeomAbs_Cone: |
261 | Quad.SetValue(ThePSurfaceTool::Cone(Surf1)); |
262 | break; |
263 | |
264 | default: |
265 | { |
f44aa197 |
266 | SecondIsImplicit = Standard_True; |
267 | switch (typeS2) |
268 | { |
269 | case GeomAbs_Plane: |
270 | Quad.SetValue(ThePSurfaceTool::Plane(Surf2)); |
271 | break; |
272 | |
273 | case GeomAbs_Cylinder: |
274 | Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2)); |
275 | break; |
276 | |
277 | case GeomAbs_Sphere: |
278 | Quad.SetValue(ThePSurfaceTool::Sphere(Surf2)); |
279 | break; |
280 | |
281 | case GeomAbs_Cone: |
282 | Quad.SetValue(ThePSurfaceTool::Cone(Surf2)); |
283 | break; |
284 | |
285 | default: |
286 | break; |
4e14c88f |
287 | }//switch (typeS2) |
7fd59977 |
288 | } |
4e14c88f |
289 | |
7fd59977 |
290 | break; |
4e14c88f |
291 | }//switch (typeS1) |
f44aa197 |
292 | |
4e14c88f |
293 | Perform(Quad, (SecondIsImplicit? Surf1: Surf2), theline, |
294 | ApproxXYZ, ApproxU1V1, ApproxU2V2, |
295 | indicemin, indicemax, !SecondIsImplicit); |
7fd59977 |
296 | |
4e14c88f |
297 | return; |
298 | } |
299 | |
300 | // Here, isQuadric == FALSE. |
7fd59977 |
301 | |
f44aa197 |
302 | // Prepare DS. |
303 | prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); |
304 | |
4e14c88f |
305 | // Non-analytical case: Param-Param perform. |
306 | ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2); |
f44aa197 |
307 | |
7fd59977 |
308 | Standard_Integer nbpntbez = indicemax-indicemin; |
4e14c88f |
309 | |
310 | if(nbpntbez < aMinNbPointsForApprox) |
311 | { |
f44aa197 |
312 | myData.myBezierApprox = Standard_False; |
4e14c88f |
313 | } |
7fd59977 |
314 | else |
f44aa197 |
315 | { |
4e14c88f |
316 | myData.myBezierApprox = Standard_True; |
7fd59977 |
317 | } |
318 | |
f44aa197 |
319 | // Fill data structure. |
4e14c88f |
320 | fillData(theline); |
321 | |
322 | const Standard_Boolean cut = myData.myBezierApprox; |
323 | const Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces; |
7fd59977 |
324 | |
f44aa197 |
325 | // Build knots. |
f44aa197 |
326 | buildKnots(theline, ptrsvsurf); |
7fd59977 |
327 | |
4e14c88f |
328 | myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, |
329 | myNbIterMax, cut, myData.parametrization); |
330 | myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, |
331 | myNbIterMax, cut, myData.parametrization); |
f44aa197 |
332 | |
333 | buildCurve(theline, ptrsvsurf); |
7fd59977 |
334 | } |
f44aa197 |
335 | |
336 | //======================================================================= |
337 | //function : Perform |
338 | //purpose : Analytic-Param perform. |
339 | //======================================================================= |
7fd59977 |
340 | void ApproxInt_Approx::Perform(const TheISurface& ISurf, |
f44aa197 |
341 | const ThePSurface& PSurf, |
342 | const Handle(TheWLine)& theline, |
343 | const Standard_Boolean ApproxXYZ, |
344 | const Standard_Boolean ApproxU1V1, |
345 | const Standard_Boolean ApproxU2V2, |
346 | const Standard_Integer indicemin, |
4e14c88f |
347 | const Standard_Integer indicemax, |
348 | const Standard_Boolean isTheQuadFirst) |
7fd59977 |
349 | { |
f44aa197 |
350 | // Prepare DS. |
351 | prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); |
352 | |
353 | // Non-analytical case: Analytic-Param perform. |
4e14c88f |
354 | ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces = |
355 | isTheQuadFirst? ApproxInt_TheImpPrmSvSurfaces(ISurf, PSurf): |
356 | ApproxInt_TheImpPrmSvSurfaces(PSurf, ISurf); |
7fd59977 |
357 | |
4e14c88f |
358 | const Standard_Integer nbpntbez = indicemax-indicemin; |
359 | if(nbpntbez < aMinNbPointsForApprox) |
360 | { |
f44aa197 |
361 | myData.myBezierApprox = Standard_False; |
4e14c88f |
362 | } |
7fd59977 |
363 | else |
f44aa197 |
364 | { |
4e14c88f |
365 | myData.myBezierApprox = Standard_True; |
7fd59977 |
366 | } |
f44aa197 |
367 | |
4e14c88f |
368 | const Standard_Boolean cut = myData.myBezierApprox; |
369 | const Standard_Address ptrsvsurf = &myImpPrmSvSurfaces; |
f44aa197 |
370 | |
371 | // Fill data structure. |
4e14c88f |
372 | fillData(theline); |
f44aa197 |
373 | |
374 | // Build knots. |
f44aa197 |
375 | buildKnots(theline, ptrsvsurf); |
376 | |
4e14c88f |
377 | myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, |
378 | myNbIterMax, cut, myData.parametrization); |
379 | myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, |
380 | myNbIterMax, cut, myData.parametrization); |
f44aa197 |
381 | |
382 | buildCurve(theline, ptrsvsurf); |
383 | } |
384 | |
4e14c88f |
385 | //======================================================================= |
386 | //function : SetParameters |
387 | //purpose : |
388 | //======================================================================= |
389 | void ApproxInt_Approx::SetParameters( const Standard_Real Tol3d, |
390 | const Standard_Real Tol2d, |
391 | const Standard_Integer DegMin, |
392 | const Standard_Integer DegMax, |
393 | const Standard_Integer NbIterMax, |
394 | const Standard_Integer NbPntMax, |
395 | const Standard_Boolean ApproxWithTangency, |
396 | const Approx_ParametrizationType Parametrization) |
397 | { |
398 | myData.myNbPntMax = NbPntMax; |
399 | myWithTangency = ApproxWithTangency; |
400 | myTol3d = Tol3d/RatioTol; |
401 | myTol2d = Tol2d/RatioTol; |
402 | myDegMin = DegMin; |
403 | myDegMax = DegMax; |
404 | myNbIterMax = NbIterMax; |
405 | |
406 | myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, |
407 | myNbIterMax, Standard_True, Parametrization); |
408 | myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, |
409 | myNbIterMax, Standard_True, Parametrization); |
410 | |
411 | if(!ApproxWithTangency) |
412 | { |
413 | myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); |
414 | myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); |
415 | } |
416 | |
417 | myData.myBezierApprox = Standard_True; |
418 | } |
419 | |
f44aa197 |
420 | //======================================================================= |
421 | //function : NbMultiCurves |
422 | //purpose : |
423 | //======================================================================= |
424 | Standard_Integer ApproxInt_Approx::NbMultiCurves() const |
425 | { |
426 | return 1; |
427 | } |
428 | |
429 | //======================================================================= |
430 | //function : UpdateTolReached |
431 | //purpose : |
432 | //======================================================================= |
433 | void ApproxInt_Approx::UpdateTolReached() |
434 | { |
435 | if (myData.myBezierApprox) |
436 | { |
4e14c88f |
437 | const Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ; |
438 | for (Standard_Integer ICur = 1 ; ICur <= NbCurves ; ICur++) |
f44aa197 |
439 | { |
440 | Standard_Real Tol3D, Tol2D ; |
441 | myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ; |
442 | myTolReached3d = Max(myTolReached3d, Tol3D); |
443 | myTolReached2d = Max(myTolReached2d, Tol2D); |
7fd59977 |
444 | } |
445 | } |
f44aa197 |
446 | else |
447 | { |
448 | myComputeLine.Error (myTolReached3d, myTolReached2d); |
7fd59977 |
449 | } |
f44aa197 |
450 | } |
451 | |
452 | //======================================================================= |
453 | //function : TolReached3d |
454 | //purpose : |
455 | //======================================================================= |
456 | Standard_Real ApproxInt_Approx::TolReached3d() const |
457 | { |
4e14c88f |
458 | return myTolReached3d * RatioTol; |
f44aa197 |
459 | } |
460 | |
461 | //======================================================================= |
462 | //function : TolReached2d |
463 | //purpose : |
464 | //======================================================================= |
465 | Standard_Real ApproxInt_Approx::TolReached2d() const |
466 | { |
4e14c88f |
467 | return myTolReached2d * RatioTol; |
f44aa197 |
468 | } |
469 | |
470 | //======================================================================= |
471 | //function : IsDone |
472 | //purpose : |
473 | //======================================================================= |
474 | Standard_Boolean ApproxInt_Approx::IsDone() const |
475 | { |
476 | if(myData.myBezierApprox) |
477 | { |
478 | return(myComputeLineBezier.NbMultiCurves() > 0); |
7fd59977 |
479 | } |
f44aa197 |
480 | else |
481 | { |
482 | return(myComputeLine.IsToleranceReached()); |
7fd59977 |
483 | } |
f44aa197 |
484 | } |
485 | |
486 | //======================================================================= |
487 | //function : Value |
488 | //purpose : |
489 | //======================================================================= |
490 | const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const |
491 | { |
492 | if(myData.myBezierApprox) |
4e14c88f |
493 | { |
f44aa197 |
494 | return(myBezToBSpl.Value()); |
7fd59977 |
495 | } |
f44aa197 |
496 | else |
4e14c88f |
497 | { |
f44aa197 |
498 | return(myComputeLine.Value()); |
7fd59977 |
499 | } |
f44aa197 |
500 | } |
501 | |
502 | //======================================================================= |
503 | //function : fillData |
504 | //purpose : Fill ApproxInt data structure. |
505 | //======================================================================= |
4e14c88f |
506 | void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline) |
f44aa197 |
507 | { |
4e14c88f |
508 | if(myData.ApproxXYZ) |
509 | ComputeTrsf3d(theline, myData.Xo, myData.Yo, myData.Zo); |
f44aa197 |
510 | else |
f44aa197 |
511 | myData.Xo = myData.Yo = myData.Zo = 0.0; |
f44aa197 |
512 | |
4e14c88f |
513 | if(myData.ApproxU1V1) |
514 | ComputeTrsf2d(theline, Standard_True, myData.U1o, myData.V1o); |
f44aa197 |
515 | else |
f44aa197 |
516 | myData.U1o = myData.V1o = 0.0; |
f44aa197 |
517 | |
4e14c88f |
518 | if(myData.ApproxU2V2) |
519 | ComputeTrsf2d(theline, Standard_False, myData.U2o, myData.V2o); |
f44aa197 |
520 | else |
f44aa197 |
521 | myData.U2o = myData.V2o = 0.0; |
f44aa197 |
522 | } |
523 | |
524 | //======================================================================= |
525 | //function : prepareDS |
526 | //purpose : |
527 | //======================================================================= |
528 | void ApproxInt_Approx::prepareDS(const Standard_Boolean theApproxXYZ, |
529 | const Standard_Boolean theApproxU1V1, |
530 | const Standard_Boolean theApproxU2V2, |
531 | const Standard_Integer theIndicemin, |
532 | const Standard_Integer theIndicemax) |
533 | { |
f44aa197 |
534 | myTolReached3d = myTolReached2d = 0.0; |
f44aa197 |
535 | myData.ApproxU1V1 = theApproxU1V1; |
536 | myData.ApproxU2V2 = theApproxU2V2; |
537 | myData.ApproxXYZ = theApproxXYZ; |
538 | myData.indicemin = theIndicemin; |
539 | myData.indicemax = theIndicemax; |
4e14c88f |
540 | myData.parametrization = myComputeLineBezier.Parametrization(); |
f44aa197 |
541 | } |
542 | |
543 | //======================================================================= |
544 | //function : buildKnots |
545 | //purpose : |
546 | //======================================================================= |
547 | void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline, |
548 | const Standard_Address thePtrSVSurf) |
549 | { |
550 | myKnots.Clear(); |
4e14c88f |
551 | if(!myData.myBezierApprox) |
f44aa197 |
552 | { |
4e14c88f |
553 | myKnots.Append(myData.indicemin); |
554 | myKnots.Append(myData.indicemax); |
555 | return; |
556 | } |
557 | |
558 | const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf, |
559 | ((myData.ApproxXYZ)? 1 : 0), |
560 | ((myData.ApproxU1V1)? 1: 0) + |
561 | ((myData.ApproxU2V2)? 1: 0), |
562 | myData.Xo, myData.Yo, myData.Zo, |
563 | myData.U1o, myData.V1o, myData.U2o, myData.V2o, |
564 | myData.ApproxU1V1, |
565 | myData.indicemin, myData.indicemax); |
566 | |
567 | const Standard_Integer nbp3d = aTestLine.NbP3d(), |
568 | nbp2d = aTestLine.NbP2d(); |
569 | TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d)); |
570 | TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d)); |
571 | TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax); |
572 | TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax); |
573 | TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax); |
574 | |
575 | for(Standard_Integer i = myData.indicemin; i <= myData.indicemax; ++i) |
576 | { |
577 | if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d); |
578 | else if (nbp2d != 0) aTestLine.Value(i, aTabPnt2d); |
579 | else if (nbp3d != 0) aTestLine.Value(i, aTabPnt3d); |
580 | // |
581 | if(nbp3d > 0) |
f44aa197 |
582 | { |
4e14c88f |
583 | aPntXYZ(i) = aTabPnt3d(1); |
584 | } |
585 | if(nbp2d > 1) |
586 | { |
587 | aPntU1V1(i) = aTabPnt2d(1); |
588 | aPntU2V2(i) = aTabPnt2d(2); |
589 | } |
590 | else if(nbp2d > 0) |
591 | { |
592 | if(myData.ApproxU1V1) |
f44aa197 |
593 | { |
594 | aPntU1V1(i) = aTabPnt2d(1); |
f44aa197 |
595 | } |
4e14c88f |
596 | else |
f44aa197 |
597 | { |
4e14c88f |
598 | aPntU2V2(i) = aTabPnt2d(1); |
f44aa197 |
599 | } |
600 | } |
4e14c88f |
601 | } |
f44aa197 |
602 | |
4e14c88f |
603 | Standard_Integer aMinNbPnts = myData.myNbPntMax; |
f44aa197 |
604 | |
4e14c88f |
605 | // Expected parametrization. |
606 | math_Vector aPars(myData.indicemin, myData.indicemax); |
607 | Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars); |
f44aa197 |
608 | |
4e14c88f |
609 | ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars, |
610 | myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots); |
f44aa197 |
611 | } |
612 | |
613 | //======================================================================= |
614 | //function : buildCurve |
615 | //purpose : |
616 | //======================================================================= |
617 | void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline, |
618 | const Standard_Address thePtrSVSurf) |
619 | { |
620 | if(myData.myBezierApprox) |
621 | { |
622 | myBezToBSpl.Reset(); |
7fd59977 |
623 | } |
7c32c7c4 |
624 | |
f44aa197 |
625 | Standard_Integer kind = myKnots.Lower(); |
4e14c88f |
626 | Standard_Integer imin = 0, imax = 0; |
f44aa197 |
627 | Standard_Boolean OtherInter = Standard_False; |
628 | do |
629 | { |
630 | // Base cycle: iterate over knots. |
631 | imin = myKnots(kind); |
632 | imax = myKnots(kind+1); |
4e14c88f |
633 | ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf, |
f44aa197 |
634 | ((myData.ApproxXYZ)? 1 : 0), |
635 | ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), |
4e14c88f |
636 | myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o, |
637 | myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax); |
7c32c7c4 |
638 | |
f44aa197 |
639 | if(myData.myBezierApprox) |
640 | { |
641 | myComputeLineBezier.Perform(myMultiLine); |
7fd59977 |
642 | if (myComputeLineBezier.NbMultiCurves() == 0) |
f44aa197 |
643 | return; |
7fd59977 |
644 | } |
f44aa197 |
645 | else |
646 | { |
7fd59977 |
647 | myComputeLine.Perform(myMultiLine); |
648 | } |
4e14c88f |
649 | |
7fd59977 |
650 | UpdateTolReached(); |
f44aa197 |
651 | |
4e14c88f |
652 | Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3; |
f44aa197 |
653 | if(!myData.ApproxXYZ) { indice2d1--; indice2d2--; } |
654 | if(!myData.ApproxU1V1) { indice2d2--; } |
655 | if(myData.ApproxXYZ) |
656 | { |
f44aa197 |
657 | if(myData.myBezierApprox) |
658 | { |
659 | for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) |
660 | { |
4e14c88f |
661 | myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0); |
f44aa197 |
662 | } |
7fd59977 |
663 | } |
f44aa197 |
664 | else |
665 | { |
4e14c88f |
666 | myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0); |
7fd59977 |
667 | } |
668 | } |
f44aa197 |
669 | if(myData.ApproxU1V1) |
670 | { |
f44aa197 |
671 | if(myData.myBezierApprox) { |
672 | for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) |
673 | { |
4e14c88f |
674 | myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0); |
f44aa197 |
675 | } |
7fd59977 |
676 | } |
f44aa197 |
677 | else |
678 | { |
4e14c88f |
679 | myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0); |
7fd59977 |
680 | } |
681 | } |
f44aa197 |
682 | if(myData.ApproxU2V2) |
683 | { |
f44aa197 |
684 | if(myData.myBezierApprox) |
685 | { |
686 | for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) |
687 | { |
4e14c88f |
688 | myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0); |
f44aa197 |
689 | } |
7fd59977 |
690 | } |
f44aa197 |
691 | else |
692 | { |
4e14c88f |
693 | myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0); |
7fd59977 |
694 | } |
695 | } |
f44aa197 |
696 | |
7fd59977 |
697 | OtherInter = Standard_False; |
f44aa197 |
698 | if(myData.myBezierApprox) |
0cbfb9f1 |
699 | { |
f44aa197 |
700 | for(Standard_Integer nbmc = 1; |
701 | nbmc <= myComputeLineBezier.NbMultiCurves(); |
0cbfb9f1 |
702 | nbmc++) |
f44aa197 |
703 | { |
0cbfb9f1 |
704 | myBezToBSpl.Append(myComputeLineBezier.Value(nbmc)); |
7fd59977 |
705 | } |
f44aa197 |
706 | kind++; |
707 | if(kind < myKnots.Upper()) |
0cbfb9f1 |
708 | { |
0cbfb9f1 |
709 | OtherInter = Standard_True; |
7fd59977 |
710 | } |
0cbfb9f1 |
711 | } |
7fd59977 |
712 | } |
f44aa197 |
713 | while(OtherInter); |
0cbfb9f1 |
714 | |
f44aa197 |
715 | if(myData.myBezierApprox) |
0cbfb9f1 |
716 | { |
f44aa197 |
717 | myBezToBSpl.Perform(); |
0cbfb9f1 |
718 | } |
f44aa197 |
719 | } |