0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / ApproxInt / ApproxInt_Approx.gxx
CommitLineData
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.
28const Standard_Integer aMinNbPointsForApprox = 5;
7fd59977 29
4e14c88f 30// This constant should be removed in the future.
31const Standard_Real RatioTol = 1.5 ;
7fd59977 32
f44aa197 33//=======================================================================
34//function : ComputeTrsf3d
35//purpose :
36//=======================================================================
37static 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//=======================================================================
61static 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//=======================================================================
94static 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 158ApproxInt_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 178void 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 218void 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 340void 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
385//=======================================================================
4e14c88f 386//function : SetParameters
387//purpose :
388//=======================================================================
389void 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
420//=======================================================================
f44aa197 421//function : NbMultiCurves
422//purpose :
423//=======================================================================
424Standard_Integer ApproxInt_Approx::NbMultiCurves() const
425{
426 return 1;
427}
428
429//=======================================================================
430//function : UpdateTolReached
431//purpose :
432//=======================================================================
433void 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//=======================================================================
456Standard_Real ApproxInt_Approx::TolReached3d() const
457{
4e14c88f 458 return myTolReached3d * RatioTol;
f44aa197 459}
460
461//=======================================================================
462//function : TolReached2d
463//purpose :
464//=======================================================================
465Standard_Real ApproxInt_Approx::TolReached2d() const
466{
4e14c88f 467 return myTolReached2d * RatioTol;
f44aa197 468}
469
470//=======================================================================
471//function : IsDone
472//purpose :
473//=======================================================================
474Standard_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//=======================================================================
490const 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 506void 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//=======================================================================
528void 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//=======================================================================
547void 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),
2c26a53d 560 ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
561 myData.ApproxU1V1, myData.ApproxU2V2,
4e14c88f 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//=======================================================================
617void 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,
2c26a53d 634 ((myData.ApproxXYZ)? 1 : 0),
635 ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
636 myData.ApproxU1V1, myData.ApproxU2V2,
637 myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o,
638 myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax);
7c32c7c4 639
f44aa197 640 if(myData.myBezierApprox)
641 {
642 myComputeLineBezier.Perform(myMultiLine);
7fd59977 643 if (myComputeLineBezier.NbMultiCurves() == 0)
f44aa197 644 return;
7fd59977 645 }
f44aa197 646 else
647 {
7fd59977 648 myComputeLine.Perform(myMultiLine);
649 }
4e14c88f 650
7fd59977 651 UpdateTolReached();
f44aa197 652
4e14c88f 653 Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3;
f44aa197 654 if(!myData.ApproxXYZ) { indice2d1--; indice2d2--; }
655 if(!myData.ApproxU1V1) { indice2d2--; }
656 if(myData.ApproxXYZ)
657 {
f44aa197 658 if(myData.myBezierApprox)
659 {
660 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
661 {
4e14c88f 662 myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
f44aa197 663 }
7fd59977 664 }
f44aa197 665 else
666 {
4e14c88f 667 myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
7fd59977 668 }
669 }
f44aa197 670 if(myData.ApproxU1V1)
671 {
f44aa197 672 if(myData.myBezierApprox) {
673 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
674 {
4e14c88f 675 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
f44aa197 676 }
7fd59977 677 }
f44aa197 678 else
679 {
4e14c88f 680 myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
7fd59977 681 }
682 }
f44aa197 683 if(myData.ApproxU2V2)
684 {
f44aa197 685 if(myData.myBezierApprox)
686 {
687 for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
688 {
4e14c88f 689 myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
f44aa197 690 }
7fd59977 691 }
f44aa197 692 else
693 {
4e14c88f 694 myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
7fd59977 695 }
696 }
f44aa197 697
7fd59977 698 OtherInter = Standard_False;
f44aa197 699 if(myData.myBezierApprox)
0cbfb9f1 700 {
f44aa197 701 for(Standard_Integer nbmc = 1;
702 nbmc <= myComputeLineBezier.NbMultiCurves();
0cbfb9f1 703 nbmc++)
f44aa197 704 {
0cbfb9f1 705 myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
7fd59977 706 }
f44aa197 707 kind++;
708 if(kind < myKnots.Upper())
0cbfb9f1 709 {
0cbfb9f1 710 OtherInter = Standard_True;
7fd59977 711 }
0cbfb9f1 712 }
7fd59977 713 }
f44aa197 714 while(OtherInter);
0cbfb9f1 715
f44aa197 716 if(myData.myBezierApprox)
0cbfb9f1 717 {
f44aa197 718 myBezToBSpl.Perform();
0cbfb9f1 719 }
2c26a53d 720}