0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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++)
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//=======================================================================
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++)
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 94void 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 162ApproxInt_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 182void 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 222void 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 344void 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//=======================================================================
395void 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//=======================================================================
430Standard_Integer ApproxInt_Approx::NbMultiCurves() const
431{
432 return 1;
433}
434
435//=======================================================================
436//function : UpdateTolReached
437//purpose :
438//=======================================================================
439void 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//=======================================================================
462Standard_Real ApproxInt_Approx::TolReached3d() const
463{
4e14c88f 464 return myTolReached3d * RatioTol;
f44aa197 465}
466
467//=======================================================================
468//function : TolReached2d
469//purpose :
470//=======================================================================
471Standard_Real ApproxInt_Approx::TolReached2d() const
472{
4e14c88f 473 return myTolReached2d * RatioTol;
f44aa197 474}
475
476//=======================================================================
477//function : IsDone
478//purpose :
479//=======================================================================
480Standard_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//=======================================================================
496const 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 512void 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//=======================================================================
534void 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//=======================================================================
553void 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//=======================================================================
623void 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}