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++) |
b053e5d6 |
45 | { |
46 | const gp_Pnt P = theline->Point(i).Value(); |
4e14c88f |
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++) |
b053e5d6 |
78 | { |
79 | const IntSurf_PntOn2S POn2S = theline->Point(i); |
4e14c88f |
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 | //======================================================================= |
9eee5ab7 |
94 | void ApproxInt_Approx::Parameters(const ApproxInt_TheMultiLine& Line, |
f44aa197 |
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; |
f44aa197 |
102 | |
103 | if (Par == Approx_ChordLength || Par == Approx_Centripetal) { |
104 | nbP3d = ApproxInt_TheMultiLineTool::NbP3d(Line); |
105 | nbP2d = ApproxInt_TheMultiLineTool::NbP2d(Line); |
106 | Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; |
107 | if (nbP3d == 0) mynbP3d = 1; |
108 | if (nbP2d == 0) mynbP2d = 1; |
7fd59977 |
109 | |
f44aa197 |
110 | TheParameters(firstP) = 0.0; |
111 | dist = 0.0; |
112 | TColgp_Array1OfPnt tabP(1, mynbP3d); |
113 | TColgp_Array1OfPnt tabPP(1, mynbP3d); |
114 | TColgp_Array1OfPnt2d tabP2d(1, mynbP2d); |
115 | TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d); |
7fd59977 |
116 | |
f44aa197 |
117 | for (i = firstP+1; i <= lastP; i++) { |
118 | if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP, tabP2d); |
119 | else if (nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP2d); |
120 | else if (nbP3d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP); |
121 | |
122 | if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP, tabPP2d); |
123 | else if (nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP2d); |
124 | else if (nbP3d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP); |
125 | dist = 0; |
126 | for (j = 1; j <= nbP3d; j++) { |
624c599c |
127 | const gp_Pnt &aP1 = tabP(j), |
128 | &aP2 = tabPP(j); |
129 | dist += aP2.SquareDistance(aP1); |
f44aa197 |
130 | } |
131 | for (j = 1; j <= nbP2d; j++) { |
624c599c |
132 | const gp_Pnt2d &aP12d = tabP2d(j), |
133 | &aP22d = tabPP2d(j); |
134 | |
135 | dist += aP22d.SquareDistance(aP12d); |
f44aa197 |
136 | } |
624c599c |
137 | |
138 | dist = Sqrt(dist); |
f44aa197 |
139 | if(Par == Approx_ChordLength) |
624c599c |
140 | { |
141 | TheParameters(i) = TheParameters(i - 1) + dist; |
142 | } |
143 | else |
144 | {// Par == Approx_Centripetal |
145 | TheParameters(i) = TheParameters(i - 1) + Sqrt(dist); |
f44aa197 |
146 | } |
147 | } |
148 | for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP); |
149 | } |
150 | else { |
151 | for (i = firstP; i <= lastP; i++) { |
152 | TheParameters(i) = (Standard_Real(i)-firstP)/ |
153 | (Standard_Real(lastP)-Standard_Real(firstP)); |
154 | } |
155 | } |
156 | } |
157 | |
158 | //======================================================================= |
4e14c88f |
159 | //function : Default constructor |
160 | //purpose : |
f44aa197 |
161 | //======================================================================= |
4e14c88f |
162 | ApproxInt_Approx::ApproxInt_Approx(): |
163 | myComputeLine(4, 8, 0.001, 0.001, 5), |
164 | myComputeLineBezier(4, 8, 0.001, 0.001, 5), |
165 | myWithTangency(Standard_True), |
166 | myTol3d(0.001), |
167 | myTol2d(0.001), |
168 | myDegMin(4), |
169 | myDegMax(8), |
170 | myNbIterMax(5), |
171 | myTolReached3d(0.0), |
172 | myTolReached2d(0.0) |
f44aa197 |
173 | { |
7fd59977 |
174 | myComputeLine.SetContinuity(2); |
4e14c88f |
175 | //myComputeLineBezier.SetContinuity(2); |
7fd59977 |
176 | } |
7fd59977 |
177 | |
f44aa197 |
178 | //======================================================================= |
179 | //function : Perform |
180 | //purpose : Build without surfaces information. |
181 | //======================================================================= |
7fd59977 |
182 | void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline, |
f44aa197 |
183 | const Standard_Boolean ApproxXYZ, |
184 | const Standard_Boolean ApproxU1V1, |
185 | const Standard_Boolean ApproxU2V2, |
186 | const Standard_Integer indicemin, |
187 | const Standard_Integer indicemax) |
188 | { |
189 | // Prepare DS. |
190 | prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); |
191 | |
4e14c88f |
192 | const Standard_Integer nbpntbez = myData.indicemax - myData.indicemin; |
193 | if(nbpntbez < aMinNbPointsForApprox) |
f44aa197 |
194 | myData.myBezierApprox = Standard_False; |
7fd59977 |
195 | else |
f44aa197 |
196 | myData.myBezierApprox = Standard_True; |
197 | |
198 | // Fill data structure. |
4e14c88f |
199 | fillData(theline); |
f44aa197 |
200 | |
201 | // Build knots. |
202 | buildKnots(theline, NULL); |
4e14c88f |
203 | if (myKnots.Length() == 2 && |
204 | indicemax - indicemin > 2 * myData.myNbPntMax) |
f44aa197 |
205 | { |
4e14c88f |
206 | // At least 3 knots for BrepApprox. |
207 | myKnots.ChangeLast() = (indicemax - indicemin) / 2; |
208 | myKnots.Append(indicemax); |
7fd59977 |
209 | } |
f44aa197 |
210 | |
4e14c88f |
211 | myComputeLine.Init (myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization); |
212 | myComputeLineBezier.Init(myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization); |
213 | |
f44aa197 |
214 | buildCurve(theline, NULL); |
7fd59977 |
215 | } |
216 | |
f44aa197 |
217 | //======================================================================= |
218 | //function : Perform |
4e14c88f |
219 | //purpose : Definition of next steps according to surface types |
220 | // (i.e. coordination algorithm). |
f44aa197 |
221 | //======================================================================= |
7fd59977 |
222 | void ApproxInt_Approx::Perform(const ThePSurface& Surf1, |
f44aa197 |
223 | const ThePSurface& Surf2, |
224 | const Handle(TheWLine)& theline, |
225 | const Standard_Boolean ApproxXYZ, |
226 | const Standard_Boolean ApproxU1V1, |
227 | const Standard_Boolean ApproxU2V2, |
228 | const Standard_Integer indicemin, |
229 | const Standard_Integer indicemax) |
230 | { |
7fd59977 |
231 | |
4e14c88f |
232 | myTolReached3d = myTolReached2d = 0.; |
f44aa197 |
233 | |
4e14c88f |
234 | const GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1); |
235 | const GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2); |
f44aa197 |
236 | |
4e14c88f |
237 | const Standard_Boolean isQuadric = ((typeS1 == GeomAbs_Plane) || |
238 | (typeS1 == GeomAbs_Cylinder) || |
239 | (typeS1 == GeomAbs_Sphere) || |
240 | (typeS1 == GeomAbs_Cone) || |
241 | (typeS2 == GeomAbs_Plane) || |
242 | (typeS2 == GeomAbs_Cylinder) || |
243 | (typeS2 == GeomAbs_Sphere) || |
244 | (typeS2 == GeomAbs_Cone)); |
7fd59977 |
245 | |
4e14c88f |
246 | if(isQuadric) |
f44aa197 |
247 | { |
7fd59977 |
248 | IntSurf_Quadric Quad; |
249 | Standard_Boolean SecondIsImplicit=Standard_False; |
f44aa197 |
250 | switch (typeS1) |
251 | { |
7fd59977 |
252 | case GeomAbs_Plane: |
253 | Quad.SetValue(ThePSurfaceTool::Plane(Surf1)); |
254 | break; |
f44aa197 |
255 | |
7fd59977 |
256 | case GeomAbs_Cylinder: |
257 | Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1)); |
258 | break; |
f44aa197 |
259 | |
7fd59977 |
260 | case GeomAbs_Sphere: |
261 | Quad.SetValue(ThePSurfaceTool::Sphere(Surf1)); |
262 | break; |
f44aa197 |
263 | |
7fd59977 |
264 | case GeomAbs_Cone: |
265 | Quad.SetValue(ThePSurfaceTool::Cone(Surf1)); |
266 | break; |
267 | |
268 | default: |
269 | { |
f44aa197 |
270 | SecondIsImplicit = Standard_True; |
271 | switch (typeS2) |
272 | { |
273 | case GeomAbs_Plane: |
274 | Quad.SetValue(ThePSurfaceTool::Plane(Surf2)); |
275 | break; |
276 | |
277 | case GeomAbs_Cylinder: |
278 | Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2)); |
279 | break; |
280 | |
281 | case GeomAbs_Sphere: |
282 | Quad.SetValue(ThePSurfaceTool::Sphere(Surf2)); |
283 | break; |
284 | |
285 | case GeomAbs_Cone: |
286 | Quad.SetValue(ThePSurfaceTool::Cone(Surf2)); |
287 | break; |
288 | |
289 | default: |
290 | break; |
4e14c88f |
291 | }//switch (typeS2) |
7fd59977 |
292 | } |
4e14c88f |
293 | |
7fd59977 |
294 | break; |
4e14c88f |
295 | }//switch (typeS1) |
f44aa197 |
296 | |
4e14c88f |
297 | Perform(Quad, (SecondIsImplicit? Surf1: Surf2), theline, |
298 | ApproxXYZ, ApproxU1V1, ApproxU2V2, |
299 | indicemin, indicemax, !SecondIsImplicit); |
7fd59977 |
300 | |
4e14c88f |
301 | return; |
302 | } |
303 | |
304 | // Here, isQuadric == FALSE. |
7fd59977 |
305 | |
f44aa197 |
306 | // Prepare DS. |
307 | prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); |
308 | |
4e14c88f |
309 | // Non-analytical case: Param-Param perform. |
310 | ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2); |
f44aa197 |
311 | |
7fd59977 |
312 | Standard_Integer nbpntbez = indicemax-indicemin; |
4e14c88f |
313 | |
314 | if(nbpntbez < aMinNbPointsForApprox) |
315 | { |
f44aa197 |
316 | myData.myBezierApprox = Standard_False; |
4e14c88f |
317 | } |
7fd59977 |
318 | else |
f44aa197 |
319 | { |
4e14c88f |
320 | myData.myBezierApprox = Standard_True; |
7fd59977 |
321 | } |
322 | |
f44aa197 |
323 | // Fill data structure. |
4e14c88f |
324 | fillData(theline); |
325 | |
326 | const Standard_Boolean cut = myData.myBezierApprox; |
327 | const Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces; |
7fd59977 |
328 | |
f44aa197 |
329 | // Build knots. |
f44aa197 |
330 | buildKnots(theline, ptrsvsurf); |
7fd59977 |
331 | |
4e14c88f |
332 | myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, |
333 | myNbIterMax, cut, myData.parametrization); |
334 | myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, |
335 | myNbIterMax, cut, myData.parametrization); |
f44aa197 |
336 | |
337 | buildCurve(theline, ptrsvsurf); |
7fd59977 |
338 | } |
f44aa197 |
339 | |
340 | //======================================================================= |
341 | //function : Perform |
342 | //purpose : Analytic-Param perform. |
343 | //======================================================================= |
7fd59977 |
344 | void ApproxInt_Approx::Perform(const TheISurface& ISurf, |
f44aa197 |
345 | const ThePSurface& PSurf, |
346 | const Handle(TheWLine)& theline, |
347 | const Standard_Boolean ApproxXYZ, |
348 | const Standard_Boolean ApproxU1V1, |
349 | const Standard_Boolean ApproxU2V2, |
350 | const Standard_Integer indicemin, |
4e14c88f |
351 | const Standard_Integer indicemax, |
352 | const Standard_Boolean isTheQuadFirst) |
7fd59977 |
353 | { |
f44aa197 |
354 | // Prepare DS. |
355 | prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax); |
356 | |
357 | // Non-analytical case: Analytic-Param perform. |
4e14c88f |
358 | ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces = |
359 | isTheQuadFirst? ApproxInt_TheImpPrmSvSurfaces(ISurf, PSurf): |
360 | ApproxInt_TheImpPrmSvSurfaces(PSurf, ISurf); |
7fd59977 |
361 | |
a2cb8561 |
362 | myImpPrmSvSurfaces.SetUseSolver(Standard_False); |
363 | |
4e14c88f |
364 | const Standard_Integer nbpntbez = indicemax-indicemin; |
365 | if(nbpntbez < aMinNbPointsForApprox) |
366 | { |
f44aa197 |
367 | myData.myBezierApprox = Standard_False; |
4e14c88f |
368 | } |
7fd59977 |
369 | else |
f44aa197 |
370 | { |
4e14c88f |
371 | myData.myBezierApprox = Standard_True; |
7fd59977 |
372 | } |
f44aa197 |
373 | |
4e14c88f |
374 | const Standard_Boolean cut = myData.myBezierApprox; |
375 | const Standard_Address ptrsvsurf = &myImpPrmSvSurfaces; |
f44aa197 |
376 | |
377 | // Fill data structure. |
4e14c88f |
378 | fillData(theline); |
f44aa197 |
379 | |
380 | // Build knots. |
f44aa197 |
381 | buildKnots(theline, ptrsvsurf); |
382 | |
4e14c88f |
383 | myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, |
384 | myNbIterMax, cut, myData.parametrization); |
385 | myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, |
386 | myNbIterMax, cut, myData.parametrization); |
f44aa197 |
387 | |
388 | buildCurve(theline, ptrsvsurf); |
389 | } |
390 | |
4e14c88f |
391 | //======================================================================= |
392 | //function : SetParameters |
393 | //purpose : |
394 | //======================================================================= |
395 | void ApproxInt_Approx::SetParameters( const Standard_Real Tol3d, |
396 | const Standard_Real Tol2d, |
397 | const Standard_Integer DegMin, |
398 | const Standard_Integer DegMax, |
399 | const Standard_Integer NbIterMax, |
400 | const Standard_Integer NbPntMax, |
401 | const Standard_Boolean ApproxWithTangency, |
402 | const Approx_ParametrizationType Parametrization) |
403 | { |
404 | myData.myNbPntMax = NbPntMax; |
405 | myWithTangency = ApproxWithTangency; |
406 | myTol3d = Tol3d/RatioTol; |
407 | myTol2d = Tol2d/RatioTol; |
408 | myDegMin = DegMin; |
409 | myDegMax = DegMax; |
410 | myNbIterMax = NbIterMax; |
411 | |
412 | myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d, |
413 | myNbIterMax, Standard_True, Parametrization); |
414 | myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d, |
415 | myNbIterMax, Standard_True, Parametrization); |
416 | |
417 | if(!ApproxWithTangency) |
418 | { |
419 | myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); |
420 | myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint); |
421 | } |
422 | |
423 | myData.myBezierApprox = Standard_True; |
424 | } |
425 | |
f44aa197 |
426 | //======================================================================= |
427 | //function : NbMultiCurves |
428 | //purpose : |
429 | //======================================================================= |
430 | Standard_Integer ApproxInt_Approx::NbMultiCurves() const |
431 | { |
432 | return 1; |
433 | } |
434 | |
435 | //======================================================================= |
436 | //function : UpdateTolReached |
437 | //purpose : |
438 | //======================================================================= |
439 | void ApproxInt_Approx::UpdateTolReached() |
440 | { |
441 | if (myData.myBezierApprox) |
442 | { |
4e14c88f |
443 | const Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ; |
444 | for (Standard_Integer ICur = 1 ; ICur <= NbCurves ; ICur++) |
f44aa197 |
445 | { |
446 | Standard_Real Tol3D, Tol2D ; |
447 | myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ; |
448 | myTolReached3d = Max(myTolReached3d, Tol3D); |
449 | myTolReached2d = Max(myTolReached2d, Tol2D); |
7fd59977 |
450 | } |
451 | } |
f44aa197 |
452 | else |
453 | { |
454 | myComputeLine.Error (myTolReached3d, myTolReached2d); |
7fd59977 |
455 | } |
f44aa197 |
456 | } |
457 | |
458 | //======================================================================= |
459 | //function : TolReached3d |
460 | //purpose : |
461 | //======================================================================= |
462 | Standard_Real ApproxInt_Approx::TolReached3d() const |
463 | { |
4e14c88f |
464 | return myTolReached3d * RatioTol; |
f44aa197 |
465 | } |
466 | |
467 | //======================================================================= |
468 | //function : TolReached2d |
469 | //purpose : |
470 | //======================================================================= |
471 | Standard_Real ApproxInt_Approx::TolReached2d() const |
472 | { |
4e14c88f |
473 | return myTolReached2d * RatioTol; |
f44aa197 |
474 | } |
475 | |
476 | //======================================================================= |
477 | //function : IsDone |
478 | //purpose : |
479 | //======================================================================= |
480 | Standard_Boolean ApproxInt_Approx::IsDone() const |
481 | { |
482 | if(myData.myBezierApprox) |
483 | { |
484 | return(myComputeLineBezier.NbMultiCurves() > 0); |
7fd59977 |
485 | } |
f44aa197 |
486 | else |
487 | { |
488 | return(myComputeLine.IsToleranceReached()); |
7fd59977 |
489 | } |
f44aa197 |
490 | } |
491 | |
492 | //======================================================================= |
493 | //function : Value |
494 | //purpose : |
495 | //======================================================================= |
496 | const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const |
497 | { |
498 | if(myData.myBezierApprox) |
4e14c88f |
499 | { |
f44aa197 |
500 | return(myBezToBSpl.Value()); |
7fd59977 |
501 | } |
f44aa197 |
502 | else |
4e14c88f |
503 | { |
f44aa197 |
504 | return(myComputeLine.Value()); |
7fd59977 |
505 | } |
f44aa197 |
506 | } |
507 | |
508 | //======================================================================= |
509 | //function : fillData |
510 | //purpose : Fill ApproxInt data structure. |
511 | //======================================================================= |
4e14c88f |
512 | void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline) |
f44aa197 |
513 | { |
4e14c88f |
514 | if(myData.ApproxXYZ) |
515 | ComputeTrsf3d(theline, myData.Xo, myData.Yo, myData.Zo); |
f44aa197 |
516 | else |
f44aa197 |
517 | myData.Xo = myData.Yo = myData.Zo = 0.0; |
f44aa197 |
518 | |
4e14c88f |
519 | if(myData.ApproxU1V1) |
520 | ComputeTrsf2d(theline, Standard_True, myData.U1o, myData.V1o); |
f44aa197 |
521 | else |
f44aa197 |
522 | myData.U1o = myData.V1o = 0.0; |
f44aa197 |
523 | |
4e14c88f |
524 | if(myData.ApproxU2V2) |
525 | ComputeTrsf2d(theline, Standard_False, myData.U2o, myData.V2o); |
f44aa197 |
526 | else |
f44aa197 |
527 | myData.U2o = myData.V2o = 0.0; |
f44aa197 |
528 | } |
529 | |
530 | //======================================================================= |
531 | //function : prepareDS |
532 | //purpose : |
533 | //======================================================================= |
534 | void ApproxInt_Approx::prepareDS(const Standard_Boolean theApproxXYZ, |
535 | const Standard_Boolean theApproxU1V1, |
536 | const Standard_Boolean theApproxU2V2, |
537 | const Standard_Integer theIndicemin, |
538 | const Standard_Integer theIndicemax) |
539 | { |
f44aa197 |
540 | myTolReached3d = myTolReached2d = 0.0; |
f44aa197 |
541 | myData.ApproxU1V1 = theApproxU1V1; |
542 | myData.ApproxU2V2 = theApproxU2V2; |
543 | myData.ApproxXYZ = theApproxXYZ; |
544 | myData.indicemin = theIndicemin; |
545 | myData.indicemax = theIndicemax; |
4e14c88f |
546 | myData.parametrization = myComputeLineBezier.Parametrization(); |
f44aa197 |
547 | } |
548 | |
549 | //======================================================================= |
550 | //function : buildKnots |
551 | //purpose : |
552 | //======================================================================= |
553 | void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline, |
554 | const Standard_Address thePtrSVSurf) |
555 | { |
556 | myKnots.Clear(); |
4e14c88f |
557 | if(!myData.myBezierApprox) |
f44aa197 |
558 | { |
4e14c88f |
559 | myKnots.Append(myData.indicemin); |
560 | myKnots.Append(myData.indicemax); |
561 | return; |
562 | } |
563 | |
564 | const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf, |
565 | ((myData.ApproxXYZ)? 1 : 0), |
2c26a53d |
566 | ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), |
567 | myData.ApproxU1V1, myData.ApproxU2V2, |
4e14c88f |
568 | myData.Xo, myData.Yo, myData.Zo, |
569 | myData.U1o, myData.V1o, myData.U2o, myData.V2o, |
570 | myData.ApproxU1V1, |
571 | myData.indicemin, myData.indicemax); |
572 | |
573 | const Standard_Integer nbp3d = aTestLine.NbP3d(), |
574 | nbp2d = aTestLine.NbP2d(); |
575 | TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d)); |
576 | TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d)); |
577 | TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax); |
578 | TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax); |
579 | TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax); |
580 | |
581 | for(Standard_Integer i = myData.indicemin; i <= myData.indicemax; ++i) |
582 | { |
583 | if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d); |
584 | else if (nbp2d != 0) aTestLine.Value(i, aTabPnt2d); |
585 | else if (nbp3d != 0) aTestLine.Value(i, aTabPnt3d); |
586 | // |
587 | if(nbp3d > 0) |
f44aa197 |
588 | { |
4e14c88f |
589 | aPntXYZ(i) = aTabPnt3d(1); |
590 | } |
591 | if(nbp2d > 1) |
592 | { |
593 | aPntU1V1(i) = aTabPnt2d(1); |
594 | aPntU2V2(i) = aTabPnt2d(2); |
595 | } |
596 | else if(nbp2d > 0) |
597 | { |
598 | if(myData.ApproxU1V1) |
f44aa197 |
599 | { |
600 | aPntU1V1(i) = aTabPnt2d(1); |
f44aa197 |
601 | } |
4e14c88f |
602 | else |
f44aa197 |
603 | { |
4e14c88f |
604 | aPntU2V2(i) = aTabPnt2d(1); |
f44aa197 |
605 | } |
606 | } |
4e14c88f |
607 | } |
f44aa197 |
608 | |
4e14c88f |
609 | Standard_Integer aMinNbPnts = myData.myNbPntMax; |
f44aa197 |
610 | |
4e14c88f |
611 | // Expected parametrization. |
612 | math_Vector aPars(myData.indicemin, myData.indicemax); |
613 | Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars); |
f44aa197 |
614 | |
4e14c88f |
615 | ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars, |
616 | myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots); |
f44aa197 |
617 | } |
618 | |
619 | //======================================================================= |
620 | //function : buildCurve |
621 | //purpose : |
622 | //======================================================================= |
623 | void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline, |
624 | const Standard_Address thePtrSVSurf) |
625 | { |
626 | if(myData.myBezierApprox) |
627 | { |
628 | myBezToBSpl.Reset(); |
7fd59977 |
629 | } |
7c32c7c4 |
630 | |
f44aa197 |
631 | Standard_Integer kind = myKnots.Lower(); |
4e14c88f |
632 | Standard_Integer imin = 0, imax = 0; |
f44aa197 |
633 | Standard_Boolean OtherInter = Standard_False; |
634 | do |
635 | { |
636 | // Base cycle: iterate over knots. |
637 | imin = myKnots(kind); |
638 | imax = myKnots(kind+1); |
4e14c88f |
639 | ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf, |
2c26a53d |
640 | ((myData.ApproxXYZ)? 1 : 0), |
641 | ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), |
642 | myData.ApproxU1V1, myData.ApproxU2V2, |
643 | myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o, |
644 | myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax); |
7c32c7c4 |
645 | |
f44aa197 |
646 | if(myData.myBezierApprox) |
647 | { |
648 | myComputeLineBezier.Perform(myMultiLine); |
7fd59977 |
649 | if (myComputeLineBezier.NbMultiCurves() == 0) |
f44aa197 |
650 | return; |
7fd59977 |
651 | } |
f44aa197 |
652 | else |
653 | { |
7fd59977 |
654 | myComputeLine.Perform(myMultiLine); |
655 | } |
4e14c88f |
656 | |
7fd59977 |
657 | UpdateTolReached(); |
f44aa197 |
658 | |
4e14c88f |
659 | Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3; |
f44aa197 |
660 | if(!myData.ApproxXYZ) { indice2d1--; indice2d2--; } |
661 | if(!myData.ApproxU1V1) { indice2d2--; } |
662 | if(myData.ApproxXYZ) |
663 | { |
f44aa197 |
664 | if(myData.myBezierApprox) |
665 | { |
666 | for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) |
667 | { |
4e14c88f |
668 | myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0); |
f44aa197 |
669 | } |
7fd59977 |
670 | } |
f44aa197 |
671 | else |
672 | { |
4e14c88f |
673 | myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0); |
7fd59977 |
674 | } |
675 | } |
f44aa197 |
676 | if(myData.ApproxU1V1) |
677 | { |
f44aa197 |
678 | if(myData.myBezierApprox) { |
679 | for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) |
680 | { |
4e14c88f |
681 | myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0); |
f44aa197 |
682 | } |
7fd59977 |
683 | } |
f44aa197 |
684 | else |
685 | { |
4e14c88f |
686 | myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0); |
7fd59977 |
687 | } |
688 | } |
f44aa197 |
689 | if(myData.ApproxU2V2) |
690 | { |
f44aa197 |
691 | if(myData.myBezierApprox) |
692 | { |
693 | for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) |
694 | { |
4e14c88f |
695 | myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0); |
f44aa197 |
696 | } |
7fd59977 |
697 | } |
f44aa197 |
698 | else |
699 | { |
4e14c88f |
700 | myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0); |
7fd59977 |
701 | } |
702 | } |
f44aa197 |
703 | |
7fd59977 |
704 | OtherInter = Standard_False; |
f44aa197 |
705 | if(myData.myBezierApprox) |
0cbfb9f1 |
706 | { |
f44aa197 |
707 | for(Standard_Integer nbmc = 1; |
708 | nbmc <= myComputeLineBezier.NbMultiCurves(); |
0cbfb9f1 |
709 | nbmc++) |
f44aa197 |
710 | { |
0cbfb9f1 |
711 | myBezToBSpl.Append(myComputeLineBezier.Value(nbmc)); |
7fd59977 |
712 | } |
f44aa197 |
713 | kind++; |
714 | if(kind < myKnots.Upper()) |
0cbfb9f1 |
715 | { |
0cbfb9f1 |
716 | OtherInter = Standard_True; |
7fd59977 |
717 | } |
0cbfb9f1 |
718 | } |
7fd59977 |
719 | } |
f44aa197 |
720 | while(OtherInter); |
0cbfb9f1 |
721 | |
f44aa197 |
722 | if(myData.myBezierApprox) |
0cbfb9f1 |
723 | { |
f44aa197 |
724 | myBezToBSpl.Perform(); |
0cbfb9f1 |
725 | } |
2c26a53d |
726 | } |