mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-30 12:14:08 +03:00
ApproxInt_Approx, ApproxInt_KnotTools, BRepApprox_Approx, GeomInt_IntSS, IntTools_FaceFace: Analysis of curvature is added for adjusting ParametrizationType IntPatch_Intersection.cxx - adding methods for estimation of UV max step depending on used surfaces GeomInt_IntSS.cxx, IntTools_FaceFace.cxx - using methods for max step estimation Approx_SameParameter.cxx - adding control against big values. BOPAlgo_PaveFiller_6.cxx - adjusting position of faces before intersection
727 lines
24 KiB
Plaintext
727 lines
24 KiB
Plaintext
// Created on: 1993-03-30
|
|
// Created by: Laurent BUCHARD
|
|
// Copyright (c) 1993-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <AppParCurves_Constraint.hxx>
|
|
#include <GeomAbs_SurfaceType.hxx>
|
|
#include <IntSurf_Quadric.hxx>
|
|
#include <gp_Trsf.hxx>
|
|
#include <gp_Trsf2d.hxx>
|
|
#include <IntSurf_PntOn2S.hxx>
|
|
#include <Precision.hxx>
|
|
#include <ApproxInt_KnotTools.hxx>
|
|
|
|
// If quantity of points is less than aMinNbPointsForApprox
|
|
// then interpolation is used.
|
|
const Standard_Integer aMinNbPointsForApprox = 5;
|
|
|
|
// This constant should be removed in the future.
|
|
const Standard_Real RatioTol = 1.5 ;
|
|
|
|
//=======================================================================
|
|
//function : ComputeTrsf3d
|
|
//purpose :
|
|
//=======================================================================
|
|
static void ComputeTrsf3d(const Handle(TheWLine)& theline,
|
|
Standard_Real& theXo,
|
|
Standard_Real& theYo,
|
|
Standard_Real& theZo)
|
|
{
|
|
const Standard_Integer aNbPnts = theline->NbPnts();
|
|
Standard_Real aXmin = RealLast(), aYmin = RealLast(), aZmin = RealLast();
|
|
for(Standard_Integer i=1;i<=aNbPnts;i++)
|
|
{
|
|
const gp_Pnt P = theline->Point(i).Value();
|
|
aXmin = Min(P.X(), aXmin);
|
|
aYmin = Min(P.Y(), aYmin);
|
|
aZmin = Min(P.Z(), aZmin);
|
|
}
|
|
|
|
theXo = -aXmin;
|
|
theYo = -aYmin;
|
|
theZo = -aZmin;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ComputeTrsf2d
|
|
//purpose :
|
|
//=======================================================================
|
|
static void ComputeTrsf2d(const Handle(TheWLine)& theline,
|
|
const Standard_Boolean onFirst,
|
|
Standard_Real& theUo,
|
|
Standard_Real& theVo)
|
|
{
|
|
const Standard_Integer aNbPnts = theline->NbPnts();
|
|
Standard_Real aUmin = RealLast(), aVmin = RealLast();
|
|
|
|
// pointer to a member-function
|
|
void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
|
|
|
|
if (onFirst)
|
|
pfunc = &IntSurf_PntOn2S::ParametersOnS1;
|
|
else
|
|
pfunc = &IntSurf_PntOn2S::ParametersOnS2;
|
|
|
|
for(Standard_Integer i=1; i<=aNbPnts; i++)
|
|
{
|
|
const IntSurf_PntOn2S POn2S = theline->Point(i);
|
|
Standard_Real U,V;
|
|
(POn2S.*pfunc)(U,V);
|
|
aUmin = Min(U, aUmin);
|
|
aVmin = Min(V, aVmin);
|
|
}
|
|
|
|
theUo = -aUmin;
|
|
theVo = -aVmin;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Parameters
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_Approx::Parameters(const ApproxInt_TheMultiLine& Line,
|
|
const Standard_Integer firstP,
|
|
const Standard_Integer lastP,
|
|
const Approx_ParametrizationType Par,
|
|
math_Vector& TheParameters)
|
|
{
|
|
Standard_Integer i, j, nbP2d, nbP3d;
|
|
Standard_Real dist;
|
|
|
|
if (Par == Approx_ChordLength || Par == Approx_Centripetal) {
|
|
nbP3d = ApproxInt_TheMultiLineTool::NbP3d(Line);
|
|
nbP2d = ApproxInt_TheMultiLineTool::NbP2d(Line);
|
|
Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
|
|
if (nbP3d == 0) mynbP3d = 1;
|
|
if (nbP2d == 0) mynbP2d = 1;
|
|
|
|
TheParameters(firstP) = 0.0;
|
|
dist = 0.0;
|
|
TColgp_Array1OfPnt tabP(1, mynbP3d);
|
|
TColgp_Array1OfPnt tabPP(1, mynbP3d);
|
|
TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
|
|
TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
|
|
|
|
for (i = firstP+1; i <= lastP; i++) {
|
|
if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP, tabP2d);
|
|
else if (nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP2d);
|
|
else if (nbP3d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP);
|
|
|
|
if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP, tabPP2d);
|
|
else if (nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP2d);
|
|
else if (nbP3d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP);
|
|
dist = 0;
|
|
for (j = 1; j <= nbP3d; j++) {
|
|
const gp_Pnt &aP1 = tabP(j),
|
|
&aP2 = tabPP(j);
|
|
dist += aP2.SquareDistance(aP1);
|
|
}
|
|
for (j = 1; j <= nbP2d; j++) {
|
|
const gp_Pnt2d &aP12d = tabP2d(j),
|
|
&aP22d = tabPP2d(j);
|
|
|
|
dist += aP22d.SquareDistance(aP12d);
|
|
}
|
|
|
|
dist = Sqrt(dist);
|
|
if(Par == Approx_ChordLength)
|
|
{
|
|
TheParameters(i) = TheParameters(i - 1) + dist;
|
|
}
|
|
else
|
|
{// Par == Approx_Centripetal
|
|
TheParameters(i) = TheParameters(i - 1) + Sqrt(dist);
|
|
}
|
|
}
|
|
for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
|
|
}
|
|
else {
|
|
for (i = firstP; i <= lastP; i++) {
|
|
TheParameters(i) = (Standard_Real(i)-firstP)/
|
|
(Standard_Real(lastP)-Standard_Real(firstP));
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Default constructor
|
|
//purpose :
|
|
//=======================================================================
|
|
ApproxInt_Approx::ApproxInt_Approx():
|
|
myComputeLine(4, 8, 0.001, 0.001, 5),
|
|
myComputeLineBezier(4, 8, 0.001, 0.001, 5),
|
|
myWithTangency(Standard_True),
|
|
myTol3d(0.001),
|
|
myTol2d(0.001),
|
|
myDegMin(4),
|
|
myDegMax(8),
|
|
myNbIterMax(5),
|
|
myTolReached3d(0.0),
|
|
myTolReached2d(0.0)
|
|
{
|
|
myComputeLine.SetContinuity(2);
|
|
//myComputeLineBezier.SetContinuity(2);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose : Build without surfaces information.
|
|
//=======================================================================
|
|
void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
|
|
const Standard_Boolean ApproxXYZ,
|
|
const Standard_Boolean ApproxU1V1,
|
|
const Standard_Boolean ApproxU2V2,
|
|
const Standard_Integer indicemin,
|
|
const Standard_Integer indicemax)
|
|
{
|
|
// Prepare DS.
|
|
prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
|
|
|
|
const Standard_Integer nbpntbez = myData.indicemax - myData.indicemin;
|
|
if(nbpntbez < aMinNbPointsForApprox)
|
|
myData.myBezierApprox = Standard_False;
|
|
else
|
|
myData.myBezierApprox = Standard_True;
|
|
|
|
// Fill data structure.
|
|
fillData(theline);
|
|
|
|
// Build knots.
|
|
buildKnots(theline, NULL);
|
|
if (myKnots.Length() == 2 &&
|
|
indicemax - indicemin > 2 * myData.myNbPntMax)
|
|
{
|
|
// At least 3 knots for BrepApprox.
|
|
myKnots.ChangeLast() = (indicemax - indicemin) / 2;
|
|
myKnots.Append(indicemax);
|
|
}
|
|
|
|
myComputeLine.Init (myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization);
|
|
myComputeLineBezier.Init(myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization);
|
|
|
|
buildCurve(theline, NULL);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose : Definition of next steps according to surface types
|
|
// (i.e. coordination algorithm).
|
|
//=======================================================================
|
|
void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
|
|
const ThePSurface& Surf2,
|
|
const Handle(TheWLine)& theline,
|
|
const Standard_Boolean ApproxXYZ,
|
|
const Standard_Boolean ApproxU1V1,
|
|
const Standard_Boolean ApproxU2V2,
|
|
const Standard_Integer indicemin,
|
|
const Standard_Integer indicemax)
|
|
{
|
|
|
|
myTolReached3d = myTolReached2d = 0.;
|
|
|
|
const GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
|
|
const GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
|
|
|
|
const Standard_Boolean isQuadric = ((typeS1 == GeomAbs_Plane) ||
|
|
(typeS1 == GeomAbs_Cylinder) ||
|
|
(typeS1 == GeomAbs_Sphere) ||
|
|
(typeS1 == GeomAbs_Cone) ||
|
|
(typeS2 == GeomAbs_Plane) ||
|
|
(typeS2 == GeomAbs_Cylinder) ||
|
|
(typeS2 == GeomAbs_Sphere) ||
|
|
(typeS2 == GeomAbs_Cone));
|
|
|
|
if(isQuadric)
|
|
{
|
|
IntSurf_Quadric Quad;
|
|
Standard_Boolean SecondIsImplicit=Standard_False;
|
|
switch (typeS1)
|
|
{
|
|
case GeomAbs_Plane:
|
|
Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
|
|
break;
|
|
|
|
case GeomAbs_Cylinder:
|
|
Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
|
|
break;
|
|
|
|
case GeomAbs_Sphere:
|
|
Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
|
|
break;
|
|
|
|
case GeomAbs_Cone:
|
|
Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
|
|
break;
|
|
|
|
default:
|
|
{
|
|
SecondIsImplicit = Standard_True;
|
|
switch (typeS2)
|
|
{
|
|
case GeomAbs_Plane:
|
|
Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
|
|
break;
|
|
|
|
case GeomAbs_Cylinder:
|
|
Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
|
|
break;
|
|
|
|
case GeomAbs_Sphere:
|
|
Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
|
|
break;
|
|
|
|
case GeomAbs_Cone:
|
|
Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}//switch (typeS2)
|
|
}
|
|
|
|
break;
|
|
}//switch (typeS1)
|
|
|
|
Perform(Quad, (SecondIsImplicit? Surf1: Surf2), theline,
|
|
ApproxXYZ, ApproxU1V1, ApproxU2V2,
|
|
indicemin, indicemax, !SecondIsImplicit);
|
|
|
|
return;
|
|
}
|
|
|
|
// Here, isQuadric == FALSE.
|
|
|
|
// Prepare DS.
|
|
prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
|
|
|
|
// Non-analytical case: Param-Param perform.
|
|
ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
|
|
|
|
Standard_Integer nbpntbez = indicemax-indicemin;
|
|
|
|
if(nbpntbez < aMinNbPointsForApprox)
|
|
{
|
|
myData.myBezierApprox = Standard_False;
|
|
}
|
|
else
|
|
{
|
|
myData.myBezierApprox = Standard_True;
|
|
}
|
|
|
|
// Fill data structure.
|
|
fillData(theline);
|
|
|
|
const Standard_Boolean cut = myData.myBezierApprox;
|
|
const Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces;
|
|
|
|
// Build knots.
|
|
buildKnots(theline, ptrsvsurf);
|
|
|
|
myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d,
|
|
myNbIterMax, cut, myData.parametrization);
|
|
myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
|
|
myNbIterMax, cut, myData.parametrization);
|
|
|
|
buildCurve(theline, ptrsvsurf);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose : Analytic-Param perform.
|
|
//=======================================================================
|
|
void ApproxInt_Approx::Perform(const TheISurface& ISurf,
|
|
const ThePSurface& PSurf,
|
|
const Handle(TheWLine)& theline,
|
|
const Standard_Boolean ApproxXYZ,
|
|
const Standard_Boolean ApproxU1V1,
|
|
const Standard_Boolean ApproxU2V2,
|
|
const Standard_Integer indicemin,
|
|
const Standard_Integer indicemax,
|
|
const Standard_Boolean isTheQuadFirst)
|
|
{
|
|
// Prepare DS.
|
|
prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
|
|
|
|
// Non-analytical case: Analytic-Param perform.
|
|
ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces =
|
|
isTheQuadFirst? ApproxInt_TheImpPrmSvSurfaces(ISurf, PSurf):
|
|
ApproxInt_TheImpPrmSvSurfaces(PSurf, ISurf);
|
|
|
|
myImpPrmSvSurfaces.SetUseSolver(Standard_False);
|
|
|
|
const Standard_Integer nbpntbez = indicemax-indicemin;
|
|
if(nbpntbez < aMinNbPointsForApprox)
|
|
{
|
|
myData.myBezierApprox = Standard_False;
|
|
}
|
|
else
|
|
{
|
|
myData.myBezierApprox = Standard_True;
|
|
}
|
|
|
|
const Standard_Boolean cut = myData.myBezierApprox;
|
|
const Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
|
|
|
|
// Fill data structure.
|
|
fillData(theline);
|
|
|
|
// Build knots.
|
|
buildKnots(theline, ptrsvsurf);
|
|
|
|
myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d,
|
|
myNbIterMax, cut, myData.parametrization);
|
|
myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
|
|
myNbIterMax, cut, myData.parametrization);
|
|
|
|
buildCurve(theline, ptrsvsurf);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetParameters
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_Approx::SetParameters( const Standard_Real Tol3d,
|
|
const Standard_Real Tol2d,
|
|
const Standard_Integer DegMin,
|
|
const Standard_Integer DegMax,
|
|
const Standard_Integer NbIterMax,
|
|
const Standard_Integer NbPntMax,
|
|
const Standard_Boolean ApproxWithTangency,
|
|
const Approx_ParametrizationType Parametrization)
|
|
{
|
|
myData.myNbPntMax = NbPntMax;
|
|
myWithTangency = ApproxWithTangency;
|
|
myTol3d = Tol3d/RatioTol;
|
|
myTol2d = Tol2d/RatioTol;
|
|
myDegMin = DegMin;
|
|
myDegMax = DegMax;
|
|
myNbIterMax = NbIterMax;
|
|
|
|
myComputeLine.Init ( myDegMin, myDegMax, myTol3d, myTol2d,
|
|
myNbIterMax, Standard_True, Parametrization);
|
|
myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
|
|
myNbIterMax, Standard_True, Parametrization);
|
|
|
|
if(!ApproxWithTangency)
|
|
{
|
|
myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
|
|
myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
|
|
}
|
|
|
|
myData.myBezierApprox = Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : NbMultiCurves
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Integer ApproxInt_Approx::NbMultiCurves() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : UpdateTolReached
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_Approx::UpdateTolReached()
|
|
{
|
|
if (myData.myBezierApprox)
|
|
{
|
|
const Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
|
|
for (Standard_Integer ICur = 1 ; ICur <= NbCurves ; ICur++)
|
|
{
|
|
Standard_Real Tol3D, Tol2D ;
|
|
myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
|
|
myTolReached3d = Max(myTolReached3d, Tol3D);
|
|
myTolReached2d = Max(myTolReached2d, Tol2D);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myComputeLine.Error (myTolReached3d, myTolReached2d);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TolReached3d
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Real ApproxInt_Approx::TolReached3d() const
|
|
{
|
|
return myTolReached3d * RatioTol;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TolReached2d
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Real ApproxInt_Approx::TolReached2d() const
|
|
{
|
|
return myTolReached2d * RatioTol;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsDone
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean ApproxInt_Approx::IsDone() const
|
|
{
|
|
if(myData.myBezierApprox)
|
|
{
|
|
return(myComputeLineBezier.NbMultiCurves() > 0);
|
|
}
|
|
else
|
|
{
|
|
return(myComputeLine.IsToleranceReached());
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Value
|
|
//purpose :
|
|
//=======================================================================
|
|
const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const
|
|
{
|
|
if(myData.myBezierApprox)
|
|
{
|
|
return(myBezToBSpl.Value());
|
|
}
|
|
else
|
|
{
|
|
return(myComputeLine.Value());
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : fillData
|
|
//purpose : Fill ApproxInt data structure.
|
|
//=======================================================================
|
|
void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline)
|
|
{
|
|
if(myData.ApproxXYZ)
|
|
ComputeTrsf3d(theline, myData.Xo, myData.Yo, myData.Zo);
|
|
else
|
|
myData.Xo = myData.Yo = myData.Zo = 0.0;
|
|
|
|
if(myData.ApproxU1V1)
|
|
ComputeTrsf2d(theline, Standard_True, myData.U1o, myData.V1o);
|
|
else
|
|
myData.U1o = myData.V1o = 0.0;
|
|
|
|
if(myData.ApproxU2V2)
|
|
ComputeTrsf2d(theline, Standard_False, myData.U2o, myData.V2o);
|
|
else
|
|
myData.U2o = myData.V2o = 0.0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : prepareDS
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_Approx::prepareDS(const Standard_Boolean theApproxXYZ,
|
|
const Standard_Boolean theApproxU1V1,
|
|
const Standard_Boolean theApproxU2V2,
|
|
const Standard_Integer theIndicemin,
|
|
const Standard_Integer theIndicemax)
|
|
{
|
|
myTolReached3d = myTolReached2d = 0.0;
|
|
myData.ApproxU1V1 = theApproxU1V1;
|
|
myData.ApproxU2V2 = theApproxU2V2;
|
|
myData.ApproxXYZ = theApproxXYZ;
|
|
myData.indicemin = theIndicemin;
|
|
myData.indicemax = theIndicemax;
|
|
myData.parametrization = myComputeLineBezier.Parametrization();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : buildKnots
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline,
|
|
const Standard_Address thePtrSVSurf)
|
|
{
|
|
myKnots.Clear();
|
|
if(!myData.myBezierApprox)
|
|
{
|
|
myKnots.Append(myData.indicemin);
|
|
myKnots.Append(myData.indicemax);
|
|
return;
|
|
}
|
|
|
|
const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf,
|
|
((myData.ApproxXYZ)? 1 : 0),
|
|
((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
|
|
myData.ApproxU1V1, myData.ApproxU2V2,
|
|
myData.Xo, myData.Yo, myData.Zo,
|
|
myData.U1o, myData.V1o, myData.U2o, myData.V2o,
|
|
myData.ApproxU1V1,
|
|
myData.indicemin, myData.indicemax);
|
|
|
|
const Standard_Integer nbp3d = aTestLine.NbP3d(),
|
|
nbp2d = aTestLine.NbP2d();
|
|
TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d));
|
|
TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d));
|
|
TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax);
|
|
TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax);
|
|
TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax);
|
|
|
|
for(Standard_Integer i = myData.indicemin; i <= myData.indicemax; ++i)
|
|
{
|
|
if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d);
|
|
else if (nbp2d != 0) aTestLine.Value(i, aTabPnt2d);
|
|
else if (nbp3d != 0) aTestLine.Value(i, aTabPnt3d);
|
|
//
|
|
if(nbp3d > 0)
|
|
{
|
|
aPntXYZ(i) = aTabPnt3d(1);
|
|
}
|
|
if(nbp2d > 1)
|
|
{
|
|
aPntU1V1(i) = aTabPnt2d(1);
|
|
aPntU2V2(i) = aTabPnt2d(2);
|
|
}
|
|
else if(nbp2d > 0)
|
|
{
|
|
if(myData.ApproxU1V1)
|
|
{
|
|
aPntU1V1(i) = aTabPnt2d(1);
|
|
}
|
|
else
|
|
{
|
|
aPntU2V2(i) = aTabPnt2d(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
Standard_Integer aMinNbPnts = myData.myNbPntMax;
|
|
|
|
// Expected parametrization.
|
|
math_Vector aPars(myData.indicemin, myData.indicemax);
|
|
Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars);
|
|
|
|
ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars,
|
|
myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : buildCurve
|
|
//purpose :
|
|
//=======================================================================
|
|
void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline,
|
|
const Standard_Address thePtrSVSurf)
|
|
{
|
|
if(myData.myBezierApprox)
|
|
{
|
|
myBezToBSpl.Reset();
|
|
}
|
|
|
|
Standard_Integer kind = myKnots.Lower();
|
|
Standard_Integer imin = 0, imax = 0;
|
|
Standard_Boolean OtherInter = Standard_False;
|
|
do
|
|
{
|
|
// Base cycle: iterate over knots.
|
|
imin = myKnots(kind);
|
|
imax = myKnots(kind+1);
|
|
ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf,
|
|
((myData.ApproxXYZ)? 1 : 0),
|
|
((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
|
|
myData.ApproxU1V1, myData.ApproxU2V2,
|
|
myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o,
|
|
myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax);
|
|
|
|
if(myData.myBezierApprox)
|
|
{
|
|
myComputeLineBezier.Perform(myMultiLine);
|
|
if (myComputeLineBezier.NbMultiCurves() == 0)
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
myComputeLine.Perform(myMultiLine);
|
|
}
|
|
|
|
UpdateTolReached();
|
|
|
|
Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3;
|
|
if(!myData.ApproxXYZ) { indice2d1--; indice2d2--; }
|
|
if(!myData.ApproxU1V1) { indice2d2--; }
|
|
if(myData.ApproxXYZ)
|
|
{
|
|
if(myData.myBezierApprox)
|
|
{
|
|
for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
|
|
{
|
|
myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
|
|
}
|
|
}
|
|
if(myData.ApproxU1V1)
|
|
{
|
|
if(myData.myBezierApprox) {
|
|
for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
|
|
{
|
|
myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
|
|
}
|
|
}
|
|
if(myData.ApproxU2V2)
|
|
{
|
|
if(myData.myBezierApprox)
|
|
{
|
|
for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
|
|
{
|
|
myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
|
|
}
|
|
}
|
|
|
|
OtherInter = Standard_False;
|
|
if(myData.myBezierApprox)
|
|
{
|
|
for(Standard_Integer nbmc = 1;
|
|
nbmc <= myComputeLineBezier.NbMultiCurves();
|
|
nbmc++)
|
|
{
|
|
myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
|
|
}
|
|
kind++;
|
|
if(kind < myKnots.Upper())
|
|
{
|
|
OtherInter = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
while(OtherInter);
|
|
|
|
if(myData.myBezierApprox)
|
|
{
|
|
myBezToBSpl.Perform();
|
|
}
|
|
}
|