Loading files
// Created on: 1999-06-18
// Created by: Galina Koulikova
// Copyright (c) 1999-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 <BRep_Builder.hxx>
#include <BRep_GCurve.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepTools_Modifier.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_Conic.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2d_OffsetCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dConvert.hxx>
#include <Geom2dConvert_ApproxCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_Conic.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Line.hxx>
#include <Geom_OffsetCurve.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_SweptSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomConvert.hxx>
#include <GeomConvert_ApproxCurve.hxx>
#include <GeomConvert_ApproxSurface.hxx>
#include <gp_Pnt.hxx>
#include <Message_Msg.hxx>
#include <Precision.hxx>
#include <ShapeAnalysis_Curve.hxx>
#include <ShapeConstruct.hxx>
#include <ShapeCustom_BSplineRestriction.hxx>
#include <ShapeCustom_RestrictionParameters.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <Standard_Type.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_Array2.hxx>
#include <Standard_Integer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ShapeCustom_BSplineRestriction, ShapeCustom_Modification)
static GeomAbs_Shape IntegerToGeomAbsShape(const int i)
{
GeomAbs_Shape result = GeomAbs_C0;
switch (i)
{
case 0:
result = GeomAbs_C0;
break;
case 1:
result = GeomAbs_C1;
break;
case 2:
result = GeomAbs_C2;
break;
case 3:
result = GeomAbs_C3;
break;
default:
result = GeomAbs_CN;
break;
}
return result;
}
static int ContToInteger(const GeomAbs_Shape Cont)
{
int result = 0;
switch (Cont)
{
case GeomAbs_C0:
case GeomAbs_G1:
result = 0;
break;
case GeomAbs_C1:
case GeomAbs_G2:
result = 1;
break;
case GeomAbs_C2:
result = 2;
break;
case GeomAbs_C3:
result = 3;
break;
default:
result = 4;
break;
}
return result;
}
static bool IsConvertCurve3d(const occ::handle<Geom_Curve>& aCurve,
int Degree,
int NbSeg,
bool myRational,
const occ::handle<ShapeCustom_RestrictionParameters>& aParameters)
{
if (aCurve.IsNull())
{
return false;
}
if (aParameters->ConvertCurve3d())
{
return true;
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
{
occ::handle<Geom_TrimmedCurve> tmp = occ::down_cast<Geom_TrimmedCurve>(aCurve);
occ::handle<Geom_Curve> BasCurve = tmp->BasisCurve();
return IsConvertCurve3d(BasCurve, Degree, NbSeg, myRational, aParameters);
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
{
if (aParameters->ConvertOffsetCurv3d())
{
return true;
}
occ::handle<Geom_OffsetCurve> tmp = occ::down_cast<Geom_OffsetCurve>(aCurve);
occ::handle<Geom_Curve> BasCurve = tmp->BasisCurve();
return IsConvertCurve3d(BasCurve, Degree, NbSeg, myRational, aParameters);
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
occ::handle<Geom_BSplineCurve> BsC = occ::down_cast<Geom_BSplineCurve>(aCurve);
if (BsC->Degree() > Degree || ((BsC->NbKnots() - 1) >= NbSeg))
{
return true;
}
return myRational && BsC->IsRational();
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve))
&& (occ::down_cast<Geom_BezierCurve>(aCurve)->Degree() > Degree
|| (myRational && occ::down_cast<Geom_BezierCurve>(aCurve)->IsRational())))
{
return true;
}
// else return false;
return false;
}
static bool IsConvertSurface(const occ::handle<Geom_Surface>& aSurface,
const int Degree,
const int NbSeg,
const bool myRational,
const occ::handle<ShapeCustom_RestrictionParameters>& aParameters)
{
if (aSurface.IsNull())
{
return false;
}
if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
{
return aParameters->ConvertPlane();
}
else if (aSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))
{
return aParameters->ConvertConicalSurf();
}
else if (aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)))
{
return aParameters->ConvertSphericalSurf();
}
else if (aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
{
return aParameters->ConvertCylindricalSurf();
}
else if (aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))
{
return aParameters->ConvertToroidalSurf();
}
// else if(aSurface->IsKind(STANDARD_TYPE(Geom_ElementarySurface))) {
// return aParameters->ConvertElementarySurf();
// }
if (aSurface->IsKind(STANDARD_TYPE(Geom_SweptSurface)))
{
if (aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))
&& aParameters->ConvertRevolutionSurf())
{
return true;
}
if (aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
&& aParameters->ConvertExtrusionSurf())
{
return true;
}
occ::handle<Geom_SweptSurface> aSurf = occ::down_cast<Geom_SweptSurface>(aSurface);
occ::handle<Geom_Curve> BasCurve = aSurf->BasisCurve();
return IsConvertCurve3d(BasCurve, Degree, NbSeg, myRational, aParameters);
}
if (aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
{
occ::handle<Geom_RectangularTrimmedSurface> aSurf =
occ::down_cast<Geom_RectangularTrimmedSurface>(aSurface);
occ::handle<Geom_Surface> theSurf = aSurf->BasisSurface();
return IsConvertSurface(theSurf, Degree, NbSeg, myRational, aParameters);
}
if (aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
{
if (aParameters->ConvertOffsetSurf())
{
return true;
}
occ::handle<Geom_OffsetSurface> aSurf = occ::down_cast<Geom_OffsetSurface>(aSurface);
occ::handle<Geom_Surface> theSurf = aSurf->BasisSurface();
return IsConvertSurface(theSurf, Degree, NbSeg, myRational, aParameters);
}
if (aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface)))
{
occ::handle<Geom_BSplineSurface> theSurf = occ::down_cast<Geom_BSplineSurface>(aSurface);
if (theSurf->UDegree() > Degree || theSurf->VDegree() > Degree)
{
return true;
}
if ((theSurf->NbUKnots() - 1) * (theSurf->NbVKnots() - 1) > NbSeg)
{
return true;
}
if (myRational && (theSurf->IsURational() || theSurf->IsVRational()))
{
return true;
}
return false;
}
if (aSurface->IsKind(STANDARD_TYPE(Geom_BezierSurface)))
{
if (aParameters->ConvertBezierSurf())
{
return true;
}
occ::handle<Geom_BezierSurface> theSurf = occ::down_cast<Geom_BezierSurface>(aSurface);
if (theSurf->UDegree() > Degree || theSurf->VDegree() > Degree)
{
return true;
}
if (myRational && (theSurf->IsURational() || theSurf->IsVRational()))
{
return true;
}
return false;
}
return false;
}
static bool IsConvertCurve2d(const occ::handle<Geom2d_Curve>& aCurve,
int Degree,
int NbSeg,
bool myRational,
const occ::handle<ShapeCustom_RestrictionParameters>& aParameters)
{
if (aCurve.IsNull())
{
return false;
}
if (aParameters->ConvertCurve2d())
{
return true;
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
{
occ::handle<Geom2d_TrimmedCurve> tmp = occ::down_cast<Geom2d_TrimmedCurve>(aCurve);
occ::handle<Geom2d_Curve> BasCurve = tmp->BasisCurve();
return IsConvertCurve2d(BasCurve, Degree, NbSeg, myRational, aParameters);
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
{
if (aParameters->ConvertOffsetCurv2d())
{
return true;
}
occ::handle<Geom2d_OffsetCurve> tmp = occ::down_cast<Geom2d_OffsetCurve>(aCurve);
occ::handle<Geom2d_Curve> BasCurve = tmp->BasisCurve();
return IsConvertCurve2d(BasCurve, Degree, NbSeg, myRational, aParameters);
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
&& ((occ::down_cast<Geom2d_BSplineCurve>(aCurve)->Degree() > Degree
|| ((occ::down_cast<Geom2d_BSplineCurve>(aCurve)->NbKnots() - 1) > NbSeg))
|| (myRational && occ::down_cast<Geom2d_BSplineCurve>(aCurve)->IsRational())))
{
return true;
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))
&& ((occ::down_cast<Geom2d_BezierCurve>(aCurve)->Degree() > Degree)
|| (myRational && occ::down_cast<Geom2d_BezierCurve>(aCurve)->IsRational())))
{
return true;
}
// else return false;
return false;
}
//=================================================================================================
ShapeCustom_BSplineRestriction::ShapeCustom_BSplineRestriction()
{
myApproxSurfaceFlag = true;
myApproxCurve3dFlag = true;
myApproxCurve2dFlag = true;
myTol3d = 0.01;
myTol2d = 1E-6;
myContinuity3d = GeomAbs_C1;
myContinuity2d = GeomAbs_C2;
myMaxDegree = 9;
myNbMaxSeg = 10000;
mySurfaceError = Precision::Confusion();
myCurve3dError = Precision::Confusion();
myCurve2dError = Precision::PConfusion();
myNbOfSpan = 0;
myConvert = false;
myDeg = true;
myRational = false;
myParameters = new ShapeCustom_RestrictionParameters;
}
ShapeCustom_BSplineRestriction::ShapeCustom_BSplineRestriction(const bool anApproxSurfaceFlag,
const bool anApproxCurve3dFlag,
const bool anApproxCurve2dFlag,
const double aTol3d,
const double aTol2d,
const GeomAbs_Shape aContinuity3d,
const GeomAbs_Shape aContinuity2d,
const int aMaxDegree,
const int aNbMaxSeg,
const bool Deg,
const bool Rational)
{
myApproxSurfaceFlag = anApproxSurfaceFlag;
myApproxCurve3dFlag = anApproxCurve3dFlag;
myApproxCurve2dFlag = anApproxCurve2dFlag;
myTol3d = aTol3d;
myTol2d = aTol2d;
myMaxDegree = aMaxDegree;
myContinuity3d = aContinuity3d;
myContinuity2d = aContinuity2d;
myNbMaxSeg = aNbMaxSeg;
mySurfaceError = Precision::Confusion();
myCurve3dError = Precision::Confusion();
myCurve2dError = Precision::PConfusion();
myNbOfSpan = 0;
myConvert = false;
myDeg = Deg;
myRational = Rational;
myParameters = new ShapeCustom_RestrictionParameters;
}
ShapeCustom_BSplineRestriction::ShapeCustom_BSplineRestriction(
const bool anApproxSurfaceFlag,
const bool anApproxCurve3dFlag,
const bool anApproxCurve2dFlag,
const double aTol3d,
const double aTol2d,
const GeomAbs_Shape aContinuity3d,
const GeomAbs_Shape aContinuity2d,
const int aMaxDegree,
const int aNbMaxSeg,
const bool Deg,
const bool Rational,
const occ::handle<ShapeCustom_RestrictionParameters>& aModes)
{
myApproxSurfaceFlag = anApproxSurfaceFlag;
myApproxCurve3dFlag = anApproxCurve3dFlag;
myApproxCurve2dFlag = anApproxCurve2dFlag;
myTol3d = aTol3d;
myTol2d = aTol2d;
myMaxDegree = aMaxDegree;
myContinuity3d = aContinuity3d;
myContinuity2d = aContinuity2d;
myNbMaxSeg = aNbMaxSeg;
mySurfaceError = Precision::Confusion();
myCurve3dError = Precision::Confusion();
myCurve2dError = Precision::PConfusion();
myNbOfSpan = 0;
myConvert = false;
myDeg = Deg;
myRational = Rational;
myParameters = aModes;
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::NewSurface(const TopoDS_Face& F,
occ::handle<Geom_Surface>& S,
TopLoc_Location& L,
double& Tol,
bool& RevWires,
bool& RevFace)
{
if (!myApproxSurfaceFlag)
{
return false;
}
RevWires = false;
RevFace = false;
myConvert = false;
occ::handle<Geom_Surface> aSurface = BRep_Tool::Surface(F, L);
if (aSurface.IsNull())
{
return false;
}
bool IsOf = true;
if (myParameters->ConvertOffsetSurf())
{
IsOf = false;
}
double UF, UL, VF, VL;
aSurface->Bounds(UF, UL, VF, VL);
double Umin, Umax, Vmin, Vmax;
BRepTools::UVBounds(F, Umin, Umax, Vmin, Vmax);
if (myParameters->SegmentSurfaceMode())
{
UF = Umin;
UL = Umax;
VF = Vmin;
VL = Vmax;
}
else
{
if (Precision::IsInfinite(UF) || Precision::IsInfinite(UL))
{
UF = Umin;
UL = Umax;
}
if (Precision::IsInfinite(VF) || Precision::IsInfinite(VL))
{
VF = Vmin;
VL = Vmax;
}
}
bool IsConv = ConvertSurface(aSurface, S, UF, UL, VF, VL, IsOf);
Tol = Precision::Confusion(); // mySurfaceError;
if (IsConv)
{
bool wasBSpline = aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface));
occ::handle<Geom_RectangularTrimmedSurface> rts =
occ::down_cast<Geom_RectangularTrimmedSurface>(aSurface);
if (!rts.IsNull())
{
wasBSpline = rts->BasisSurface()->IsKind(STANDARD_TYPE(Geom_BSplineSurface));
}
if (wasBSpline)
{
SendMsg(F, Message_Msg("BSplineRestriction.NewSurface.MSG1"));
}
else
{
SendMsg(F, Message_Msg("BSplineRestriction.NewSurface.MSG0"));
}
}
return IsConv;
}
//=================================================================================================
static void ConvertExtrusion(const occ::handle<Geom_Curve>& C, /*const gp_Dir& direction,*/
gp_Trsf& shiftF,
gp_Trsf& shiftL,
const double VF,
const double VL,
occ::handle<Geom_Surface>& bspline)
{
occ::handle<Geom_BSplineCurve> bspl = occ::down_cast<Geom_BSplineCurve>(C);
int nbPoles = bspl->NbPoles();
const NCollection_Array1<gp_Pnt>& poles = bspl->Poles();
const NCollection_Array1<double>& weights = bspl->WeightsArray();
const NCollection_Array1<double>& knots = bspl->Knots();
const NCollection_Array1<int>& mults = bspl->Multiplicities();
NCollection_Array2<gp_Pnt> resPoles(1, nbPoles, 1, 2);
NCollection_Array2<double> resWeigth(1, nbPoles, 1, 2);
for (int j = 1; j <= nbPoles; j++)
{
resPoles(j, 1) = poles(j).Transformed(shiftF);
resPoles(j, 2) = poles(j).Transformed(shiftL);
resWeigth(j, 1) = weights(j);
resWeigth(j, 2) = weights(j);
}
NCollection_Array1<double> vknots(1, 2);
NCollection_Array1<int> vmults(1, 2);
vknots(1) = VF;
vknots(2) = VL;
vmults(1) = vmults(2) = 2;
bspline = new Geom_BSplineSurface(resPoles,
resWeigth,
knots,
vknots,
mults,
vmults,
bspl->Degree(),
1,
bspl->IsPeriodic(),
false);
}
bool ShapeCustom_BSplineRestriction::ConvertSurface(const occ::handle<Geom_Surface>& aSurface,
occ::handle<Geom_Surface>& S,
const double UF,
const double UL,
const double VF,
const double VL,
const bool IsOf)
{
if (!IsConvertSurface(aSurface, myMaxDegree, myNbMaxSeg, myRational, myParameters))
{
return false;
}
occ::handle<Geom_Surface> aSurf = aSurface;
if (aSurf->IsKind(STANDARD_TYPE(Geom_Plane)) && myParameters->ConvertPlane())
{
occ::handle<Geom_Plane> pln = occ::down_cast<Geom_Plane>(aSurf);
NCollection_Array2<gp_Pnt> poles(1, 2, 1, 2);
NCollection_Array1<double> uknots(1, 2);
NCollection_Array1<int> umults(1, 2);
NCollection_Array1<double> vknots(1, 2);
NCollection_Array1<int> vmults(1, 2);
poles(1, 1) = pln->Value(UF, VF);
poles(1, 2) = pln->Value(UF, VL);
poles(2, 1) = pln->Value(UL, VF);
poles(2, 2) = pln->Value(UL, VL);
uknots(1) = UF;
uknots(2) = UL;
vknots(1) = VF;
vknots(2) = VL;
umults(1) = umults(2) = vmults(1) = vmults(2) = 2;
S = new Geom_BSplineSurface(poles, uknots, vknots, umults, vmults, 1, 1, false, false);
return true;
}
if (aSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
{
occ::handle<Geom_SurfaceOfRevolution> Surface = occ::down_cast<Geom_SurfaceOfRevolution>(aSurf);
occ::handle<Geom_Curve> BasCurve = Surface->BasisCurve();
occ::handle<Geom_Curve> ResCurve;
double TolS = Precision::Confusion();
if (myParameters->ConvertRevolutionSurf())
{
if (BasCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
{
GeomAbs_Shape cnt = BasCurve->Continuity();
cnt = (cnt > GeomAbs_C2 ? GeomAbs_C2 : cnt);
if (ConvertCurve(BasCurve,
ResCurve,
false,
std::max(VF, BasCurve->FirstParameter()),
std::min(VL, BasCurve->LastParameter()),
TolS,
false))
{
occ::handle<Geom_SurfaceOfRevolution> newRevol =
new Geom_SurfaceOfRevolution(ResCurve, Surface->Axis());
aSurf = newRevol;
#ifdef OCCT_DEBUG
std::cout << " Revolution on offset converted" << std::endl;
#endif
}
}
}
else
{
if (ConvertCurve(BasCurve,
ResCurve,
false,
std::max(VF, BasCurve->FirstParameter()),
std::min(VL, BasCurve->LastParameter()),
TolS,
IsOf))
{
S = new Geom_SurfaceOfRevolution(ResCurve, Surface->Axis());
return true;
}
else
{
return false;
}
}
}
if (aSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))
{
occ::handle<Geom_SurfaceOfLinearExtrusion> Surface =
occ::down_cast<Geom_SurfaceOfLinearExtrusion>(aSurf);
occ::handle<Geom_Curve> BasCurve = Surface->BasisCurve();
occ::handle<Geom_Curve> ResCurve;
double TolS = Precision::Confusion();
if (myParameters->ConvertExtrusionSurf())
{
GeomAbs_Shape cnt = Surface->Continuity();
cnt = (cnt > GeomAbs_C2 ? GeomAbs_C2 : cnt);
occ::handle<Geom_BSplineCurve> bspl =
ShapeConstruct::ConvertCurveToBSpline(BasCurve, UF, UL, TolS, cnt, myNbMaxSeg, myMaxDegree);
BasCurve = bspl;
ConvertCurve(BasCurve,
ResCurve,
true,
std::max(UF, BasCurve->FirstParameter()),
std::min(UL, BasCurve->LastParameter()),
TolS,
IsOf);
gp_Trsf shiftF, shiftL;
shiftF.SetTranslation(Surface->Value(UF, 0), Surface->Value(UF, VF));
shiftL.SetTranslation(Surface->Value(UF, 0), Surface->Value(UF, VL));
ConvertExtrusion(ResCurve, /*Surface->Direction(),*/ shiftF, shiftL, VF, VL, S);
return true;
}
else
{
if (ConvertCurve(BasCurve,
ResCurve,
false,
std::max(UF, BasCurve->FirstParameter()),
std::min(UL, BasCurve->LastParameter()),
TolS,
IsOf))
{
S = new Geom_SurfaceOfLinearExtrusion(ResCurve, Surface->Direction());
return true;
}
else
{
return false;
}
}
}
if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
{
occ::handle<Geom_RectangularTrimmedSurface> tmp =
occ::down_cast<Geom_RectangularTrimmedSurface>(aSurf);
double U1, U2, V1, V2;
tmp->Bounds(U1, U2, V1, V2);
occ::handle<Geom_Surface> theSurf = tmp->BasisSurface();
occ::handle<Geom_Surface> ResSurface;
if (ConvertSurface(theSurf, ResSurface, U1, U2, V1, V2, IsOf))
{
// S = new Geom_RectangularTrimmedSurface(ResSurface,U1,U2,V1,V2);
S = ResSurface;
return true;
}
else
{
return false;
}
}
if (aSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)) && IsOf)
{
occ::handle<Geom_OffsetSurface> tmp = occ::down_cast<Geom_OffsetSurface>(aSurf);
occ::handle<Geom_Surface> theSurf = tmp->BasisSurface();
occ::handle<Geom_Surface> ResSurface;
if (ConvertSurface(theSurf, ResSurface, UF, UL, VF, VL))
{
if (ResSurface->Continuity() != GeomAbs_C0)
{
S = new Geom_OffsetSurface(ResSurface, tmp->Offset());
return true;
}
else if (ConvertSurface(aSurf, S, UF, UL, VF, VL, false))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
if (aSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)) && myParameters->ConvertBezierSurf())
{
occ::handle<Geom_BezierSurface> bezier = occ::down_cast<Geom_BezierSurface>(aSurf);
int uDegree = bezier->UDegree();
int vDegree = bezier->VDegree();
const NCollection_Array2<gp_Pnt>& aPoles = bezier->Poles();
const NCollection_Array2<double>& aWeights = bezier->WeightsArray();
NCollection_Array1<double> uKnots(1, 2), vKnots(1, 2);
uKnots(1) = 0;
uKnots(2) = 1;
vKnots(1) = 0;
vKnots(2) = 1;
NCollection_Array1<int> uMults(1, 2), vMults(1, 2);
uMults.Init(uDegree + 1);
vMults.Init(vDegree + 1);
occ::handle<Geom_BSplineSurface> bspline =
new Geom_BSplineSurface(aPoles, aWeights, uKnots, vKnots, uMults, vMults, uDegree, vDegree);
if (!ConvertSurface(bspline, S, UF, UL, VF, VL, IsOf))
{
S = bspline;
}
return true;
}
int NbSeg = 1;
bool URat = false;
bool VRat = false;
// if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) ||
// aSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)) ||
// (aSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)) && !IsOf) ||
// aSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)) ||
// aSurface->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))) {
int UDeg = 1, VDeg = 1;
if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)))
{
occ::handle<Geom_BSplineSurface> BsS = occ::down_cast<Geom_BSplineSurface>(aSurf);
UDeg = BsS->UDegree();
VDeg = BsS->VDegree();
NbSeg = (BsS->NbUKnots() - 1) * (BsS->NbVKnots() - 1);
URat = BsS->IsURational();
VRat = BsS->IsVRational();
bool IsR = (myRational && (URat || VRat));
if (UDeg <= myMaxDegree && VDeg <= myMaxDegree && NbSeg <= myNbMaxSeg && !IsR)
{
return false;
}
}
if (aSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)))
{
occ::handle<Geom_BezierSurface> BsZ = occ::down_cast<Geom_BezierSurface>(aSurf);
UDeg = BsZ->UDegree();
VDeg = BsZ->VDegree();
NbSeg = 1;
URat = BsZ->IsURational();
VRat = BsZ->IsVRational();
bool IsR = (myRational && (URat || VRat));
if (UDeg <= myMaxDegree && VDeg <= myMaxDegree && NbSeg <= myNbMaxSeg && !IsR)
{
return false;
}
}
GeomAbs_Shape Cont = myContinuity3d;
if (aSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))
{
Cont = GeomAbs_C0;
}
/* bool IsR = (myRational && (URat || VRat));
if( UDeg <= myMaxDegree && VDeg <= myMaxDegree && NbSeg <= myNbMaxSeg && !IsR ) {
return false;
}*/
double aTol3d;
int nbOfSpan, imax = 10;
int MaxSeg = myNbMaxSeg;
int MaxDeg = myMaxDegree;
double u1, u2, v1, v2;
aSurf->Bounds(u1, u2, v1, v2);
double ShiftU = 0, ShiftV = 0;
if (std::abs(u1 - UF) > Precision::PConfusion() || std::abs(u2 - UL) > Precision::PConfusion()
|| std::abs(v1 - VF) > Precision::PConfusion() || std::abs(v2 - VL) > Precision::PConfusion())
{
/*if(aSurf->IsUPeriodic() ) {
double aDelta = (UL > UF ? UL - UF : UF - UL );
u1 = (aDelta > 2.*M_PI ? 0. : UF + ShapeAnalysis::AdjustByPeriod(UF,0.5*(UL+UF),2*M_PI));
u2 = (aDelta > 2.*M_PI ? 2.*M_PI : u1 + aDelta);
}*/
bool isTrim = false;
if (!aSurf->IsUPeriodic())
{ // else {
u1 = std::max(u1, UF);
u2 = std::min(u2, UL);
isTrim = true;
}
/*if(aSurf->IsVPeriodic()) {
double aDelta = (VL > VF ? VL - VF : VF - VL );
v1 = (aDelta > 2.*M_PI ? 0. : VF + ShapeAnalysis::AdjustByPeriod(VF,0.5*(UL+UF),2*M_PI));
v2 = (aDelta > 2.*M_PI ? 2.* M_PI : v1 + aDelta);
}*/
if (!aSurf->IsVPeriodic())
{ // else
v1 = std::max(v1, VF);
v2 = std::min(v2, VL);
isTrim = true;
}
if (isTrim && (u1 != u2) && (v1 != v2))
{
occ::handle<Geom_RectangularTrimmedSurface> trSurface =
new Geom_RectangularTrimmedSurface(aSurf, u1, u2, v1, v2);
double ur1, ur2, vr1, vr2;
trSurface->Bounds(ur1, ur2, vr1, vr2);
ShiftU = u1 - ur1;
ShiftV = v1 - vr1;
aSurf = trSurface;
}
}
int aCU = std::min(ContToInteger(Cont), ContToInteger(aSurf->Continuity()));
int aCV = std::min(ContToInteger(Cont), ContToInteger(aSurf->Continuity()));
if (!aCU)
{
aCU = ContToInteger(Cont);
}
if (!aCV)
{
aCV = ContToInteger(Cont);
}
for (;;)
{
double prevTol = RealLast(), newTol = 0;
for (int i = 1; i <= imax; i++)
{
aTol3d = myTol3d * i / 2;
while (aCU >= 0 || aCV >= 0)
{
try
{
OCC_CATCH_SIGNALS
GeomAbs_Shape aContV = IntegerToGeomAbsShape(aCV);
GeomAbs_Shape aContU = IntegerToGeomAbsShape(aCU);
GeomConvert_ApproxSurface
anApprox(aSurf, aTol3d, aContU, aContV, MaxDeg, MaxDeg, MaxSeg, 0);
bool Done = anApprox.IsDone();
newTol = anApprox.MaxError();
if (anApprox.MaxError() <= myTol3d && Done)
{
nbOfSpan = (anApprox.Surface()->NbUKnots() - 1) * (anApprox.Surface()->NbVKnots() - 1);
#ifdef OCCT_DEBUG
if ((imax - i + 1) != 1)
{
std::cout << " iteration = " << i << "\terror = " << anApprox.MaxError()
<< "\tspans = " << nbOfSpan << std::endl;
std::cout << " Surface is approximated with continuity "
<< IntegerToGeomAbsShape(std::min(aCU, aCV)) << std::endl;
}
#endif
S = anApprox.Surface();
occ::handle<Geom_BSplineSurface> Bsc = occ::down_cast<Geom_BSplineSurface>(S);
if (aSurface->IsUPeriodic())
{
Bsc->SetUPeriodic();
}
if (aSurface->IsVPeriodic())
{
Bsc->SetVPeriodic();
}
// int DegU = Bsc->UDegree(); // DegU not used (skl)
// int DegV = Bsc->VDegree(); // DegV not used (skl)
// int nbVK = Bsc->NbVKnots(); // nbVK not used (skl)
// int nbUK = Bsc->NbUKnots(); // nbUK not used (skl)
myConvert = true;
myNbOfSpan = myNbOfSpan + nbOfSpan;
mySurfaceError = std::max(mySurfaceError, anApprox.MaxError());
if (std::abs(ShiftU) > Precision::PConfusion())
{
NCollection_Array1<double> uknots(Bsc->UKnots());
for (int j = 1; j <= uknots.Length(); j++)
{
uknots(j) += ShiftU;
}
Bsc->SetUKnots(uknots);
}
if (std::abs(ShiftV) > Precision::PConfusion())
{
NCollection_Array1<double> vknots(Bsc->VKnots());
for (int j = 1; j <= vknots.Length(); j++)
{
vknots(j) += ShiftV;
}
Bsc->SetVKnots(vknots);
}
return true;
}
else
{
break;
}
}
catch (Standard_Failure const& anException)
{
#ifdef OCCT_DEBUG
std::cout << "Warning: GeomConvert_ApproxSurface Exception: try to decrease continuity ";
anException.Print(std::cout);
std::cout << std::endl;
#endif
(void)anException;
// szv: protection against loop
if (aCU == 0 && aCV == 0)
{
break;
}
if (aCU > 0)
{
aCU--;
}
if (aCV > 0)
{
aCV--;
}
}
}
if (prevTol <= newTol)
{
break;
}
else
{
prevTol = newTol;
}
}
// int GMaxDegree = 15;//Geom_BSplineSurface::MaxDegree();
if (myDeg)
{
if (MaxSeg < myParameters->GMaxSeg())
{
if (aCV != 0 || aCU != 0)
{
if (aCV > 0)
{
aCV--;
}
if (aCU > 0)
{
aCU--;
}
}
else
{
MaxSeg = 2 * MaxSeg; // myGMaxSeg;
}
if (MaxSeg > myParameters->GMaxSeg())
{
MaxSeg = myParameters->GMaxSeg();
}
else
{
continue;
}
}
else
{
#ifdef OCCT_DEBUG
std::cout << " Approximation iteration out. Surface is not approximated." << std::endl;
#endif
return false;
}
}
else
{
if (MaxDeg < myParameters->GMaxDegree())
{
MaxDeg = myParameters->GMaxDegree();
continue;
}
else
{
#ifdef OCCT_DEBUG
std::cout << " Approximation iteration out. Surface is not approximated." << std::endl;
#endif
return false;
}
}
}
//}
// else
// Surface is not BSpline or Bezier
// return false;
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::NewCurve(const TopoDS_Edge& E,
occ::handle<Geom_Curve>& C,
TopLoc_Location& L,
double& Tol)
{
if (!myApproxCurve3dFlag)
{
return false;
}
double First, Last;
occ::handle<Geom_Curve> aCurve = BRep_Tool::Curve(E, L, First, Last);
double TolCur = BRep_Tool::Tolerance(E);
// if(aCurve.IsNull()) return false;
bool IsConvert = false;
occ::handle<BRep_TEdge>& TE = *((occ::handle<BRep_TEdge>*)&E.TShape());
// iterate on pcurves
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
for (; itcr.More(); itcr.Next())
{
occ::handle<BRep_GCurve> GC = occ::down_cast<BRep_GCurve>(itcr.Value());
if (GC.IsNull() || !GC->IsCurveOnSurface())
{
continue;
}
occ::handle<Geom_Surface> aSurface = GC->Surface();
occ::handle<Geom2d_Curve> aCurve2d = GC->PCurve();
if ((myApproxSurfaceFlag
&& IsConvertSurface(aSurface, myMaxDegree, myNbMaxSeg, myRational, myParameters))
|| (myApproxCurve2dFlag
&& IsConvertCurve2d(aCurve2d, myMaxDegree, myNbMaxSeg, myRational, myParameters)))
{
IsConvert = true;
break;
}
}
if (aCurve.IsNull())
{
if (IsConvert)
{
C = aCurve;
Tol = TolCur;
return true;
}
else
{
return false;
}
}
bool IsOf = true;
if (myParameters->ConvertOffsetCurv3d())
{
IsOf = false;
}
bool IsConv = ConvertCurve(aCurve, C, IsConvert, First, Last, TolCur, IsOf);
Tol = BRep_Tool::Tolerance(E); // TolCur;
if (IsConv)
{
bool wasBSpline = aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
occ::handle<Geom_TrimmedCurve> tc = occ::down_cast<Geom_TrimmedCurve>(aCurve);
if (!tc.IsNull())
{
wasBSpline = tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
}
if (wasBSpline)
{
SendMsg(E, Message_Msg("BSplineRestriction.NewCurve.MSG1"));
}
else
{
SendMsg(E, Message_Msg("BSplineRestriction.NewCurve.MSG0"));
}
}
return IsConv;
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::ConvertCurve(const occ::handle<Geom_Curve>& aCurve,
occ::handle<Geom_Curve>& C,
const bool IsConvert,
const double First,
const double Last,
double& TolCur,
const bool IsOf)
{
// TolCur = Precision::Confusion();
if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
{
occ::handle<Geom_TrimmedCurve> tmp = occ::down_cast<Geom_TrimmedCurve>(aCurve);
// double pf =tmp->FirstParameter(), pl = tmp->LastParameter(); // pf,pl not used - see
// below (skl)
occ::handle<Geom_Curve> BasCurve = tmp->BasisCurve();
occ::handle<Geom_Curve> ResCurve;
if (ConvertCurve(BasCurve, ResCurve, IsConvert, First, Last, TolCur, IsOf))
{
// Stanadrd_Real F = std::max(pf,First), L = std::min(pl,Last);
// if(First != Last)
// C = new
// Geom_TrimmedCurve(ResCurve,Max(First,ResCurve->FirstParameter()),Min(Last,ResCurve->LastParameter()));
// else
C = ResCurve;
return true;
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
return false;
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)) && myParameters->ConvertCurve3d())
{
occ::handle<Geom_Line> aLine = occ::down_cast<Geom_Line>(aCurve);
NCollection_Array1<gp_Pnt> poles(1, 2);
poles(1) = aLine->Value(First);
poles(2) = aLine->Value(Last);
NCollection_Array1<double> knots(1, 2);
knots(1) = First;
knots(2) = Last;
NCollection_Array1<int> mults(1, 2);
mults.Init(2);
occ::handle<Geom_BSplineCurve> res = new Geom_BSplineCurve(poles, knots, mults, 1);
C = res;
return true;
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_Conic)) && myParameters->ConvertCurve3d())
{
occ::handle<Geom_BSplineCurve> aBSpline;
// clang-format off
occ::handle<Geom_Curve> tcurve = new Geom_TrimmedCurve(aCurve,First,Last); //protection against parabols ets
// clang-format on
GeomConvert_ApproxCurve approx(tcurve,
myTol3d /*Precision::Approximation()*/,
myContinuity2d,
myNbMaxSeg,
6);
if (approx.HasResult())
{
aBSpline = approx.Curve();
}
else
{
aBSpline = GeomConvert::CurveToBSplineCurve(tcurve, Convert_QuasiAngular);
}
double Shift = First - aBSpline->FirstParameter();
if (std::abs(Shift) > Precision::PConfusion())
{
NCollection_Array1<double> newKnots(aBSpline->Knots());
for (int i = 1; i <= newKnots.Length(); i++)
{
newKnots(i) += Shift;
}
aBSpline->SetKnots(newKnots);
}
occ::handle<Geom_Curve> ResCurve;
if (ConvertCurve(aBSpline, ResCurve, IsConvert, First, Last, TolCur, false))
{
C = ResCurve;
return true;
}
else
{
C = aBSpline;
TolCur = Precision::PConfusion();
return true;
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)) && myParameters->ConvertCurve3d())
{
occ::handle<Geom_Curve> aBSpline =
GeomConvert::CurveToBSplineCurve(aCurve, Convert_QuasiAngular);
occ::handle<Geom_Curve> ResCurve;
if (ConvertCurve(aBSpline, ResCurve, IsConvert, First, Last, TolCur, false))
{
C = ResCurve;
return true;
}
else
{
C = aBSpline;
TolCur = Precision::PConfusion();
return true;
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)) && IsOf)
{
occ::handle<Geom_OffsetCurve> tmp = occ::down_cast<Geom_OffsetCurve>(aCurve);
occ::handle<Geom_Curve> BasCurve = tmp->BasisCurve();
occ::handle<Geom_Curve> ResCurve;
if (ConvertCurve(BasCurve, ResCurve, IsConvert, First, Last, TolCur))
{
if (ResCurve->Continuity() != GeomAbs_C0)
{
C = new Geom_OffsetCurve(ResCurve, tmp->Offset(), tmp->Direction());
return true;
}
else if (ConvertCurve(aCurve, C, IsConvert, First, Last, TolCur, false))
{
return true;
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
return false;
}
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
return false;
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))
|| aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve))
|| (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)) && !IsOf))
{
int Deg = 1;
if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
occ::handle<Geom_BSplineCurve> BsC = occ::down_cast<Geom_BSplineCurve>(aCurve);
Deg = BsC->Degree();
bool IsR = (myRational && BsC->IsRational());
if (!IsR && Deg <= myMaxDegree && (BsC->NbKnots() - 1) <= myNbMaxSeg)
{
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
else
{
return false;
}
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)))
{
occ::handle<Geom_BezierCurve> BzC = occ::down_cast<Geom_BezierCurve>(aCurve);
Deg = BzC->Degree();
bool IsR = (myRational && BzC->IsRational());
if (!IsR && Deg <= myMaxDegree)
{
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
else
{
return false;
}
}
}
occ::handle<Geom_Curve> aCurve1;
double pf = aCurve->FirstParameter(), pl = aCurve->LastParameter();
// 15.11.2002 PTV OCC966
if (ShapeAnalysis_Curve::IsPeriodic(aCurve) && (First != Last))
{
aCurve1 = new Geom_TrimmedCurve(aCurve, First, Last);
}
else if (pf < (First - Precision::PConfusion()) || pl > (Last + Precision::PConfusion()))
{
double F = std::max(First, pf), L = std::min(Last, pl);
if (F != L)
{
aCurve1 = new Geom_TrimmedCurve(aCurve, F, L);
}
else
{
aCurve1 = aCurve;
}
}
else
{
aCurve1 = aCurve;
}
int aC = std::min(ContToInteger(myContinuity3d), ContToInteger(aCurve->Continuity()));
if (!aC)
{
aC = ContToInteger(myContinuity3d);
}
// aC = std::min(aC,(Deg -1));
int MaxSeg = myNbMaxSeg;
int MaxDeg = myMaxDegree;
// GeomAbs_Shape aCont = IntegerToGeomAbsShape(aC);
int aC1 = aC;
// int GMaxDegree = 15; //Geom_BSplineCurve::MaxDegree();
for (; aC >= 0; aC--)
{
try
{
OCC_CATCH_SIGNALS
for (int j = 1; j <= 2; j++)
{
GeomAbs_Shape aCont = IntegerToGeomAbsShape(aC);
GeomConvert_ApproxCurve anApprox(aCurve1, myTol3d, aCont, MaxSeg, MaxDeg);
bool Done = anApprox.IsDone();
C = anApprox.Curve();
int Nbseg = occ::down_cast<Geom_BSplineCurve>(C)->NbKnots() - 1;
int DegC = occ::down_cast<Geom_BSplineCurve>(C)->Degree();
if (myDeg
&& ((DegC > MaxDeg) || !Done || (anApprox.MaxError() >= std::max(TolCur, myTol3d))))
{
if (MaxSeg < myParameters->GMaxSeg())
{
MaxSeg = myParameters->GMaxSeg();
aC = aC1;
continue;
}
else
{
#ifdef OCCT_DEBUG
std::cout << "Curve is not aproxed with continuity " << aCont << std::endl;
#endif
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
}
}
if (!myDeg
&& ((Nbseg > myParameters->GMaxSeg()) || !Done
|| (anApprox.MaxError() >= std::max(TolCur, myTol3d))))
{
if (MaxDeg < myParameters->GMaxDegree())
{
MaxDeg = myParameters->GMaxDegree();
aC = aC1;
continue;
}
else
{
#ifdef OCCT_DEBUG
std::cout << "Curve is not aproxed with continuity " << aCont << std::endl;
#endif
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
}
}
myConvert = true;
TolCur = anApprox.MaxError();
myCurve3dError = std::max(myCurve3dError, anApprox.MaxError());
return true;
}
}
catch (Standard_Failure const& anException)
{
#ifdef OCCT_DEBUG
std::cout << "Warning: GeomConvert_ApproxCurve Exception: Wrong Coefficient : Decrease "
"continuity ";
anException.Print(std::cout);
std::cout << std::endl;
#endif
(void)anException;
continue;
}
}
return false;
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom_Curve>(aCurve->Copy());
TolCur = Precision::Confusion();
return true;
}
return false;
}
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::NewCurve2d(const TopoDS_Edge& E,
const TopoDS_Face& F,
const TopoDS_Edge& NewE,
const TopoDS_Face& /*NewF*/,
occ::handle<Geom2d_Curve>& C,
double& Tol)
{
if (!myApproxCurve2dFlag && !myApproxSurfaceFlag)
{
return false;
}
double First, Last, F1, L1;
TopLoc_Location L, Loc1;
occ::handle<Geom_Surface> aSurface = BRep_Tool::Surface(F, L);
GeomAdaptor_Surface AdS(aSurface);
double TolCur =
std::min(AdS.UResolution(BRep_Tool::Tolerance(E)), AdS.VResolution(BRep_Tool::Tolerance(E)));
occ::handle<Geom2d_Curve> aCurve = BRep_Tool::CurveOnSurface(E, F, First, Last);
if (aCurve.IsNull())
{
return false;
}
occ::handle<Geom_Curve> aCur3d = BRep_Tool::Curve(E, Loc1, F1, L1);
// bool IsConvert = (IsConvertSurface(aSurface,myMaxDegree,myNbMaxSeg) ||
// !E.IsSame(NewE));
bool IsConvert =
((myApproxSurfaceFlag
&& IsConvertSurface(aSurface, myMaxDegree, myNbMaxSeg, myRational, myParameters))
|| (myApproxCurve3dFlag
&& IsConvertCurve3d(aCur3d, myMaxDegree, myNbMaxSeg, myRational, myParameters)));
if (!IsConvert)
{
occ::handle<BRep_TEdge>& TE = *((occ::handle<BRep_TEdge>*)&E.TShape());
// iterate on pcurves
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
for (; itcr.More(); itcr.Next())
{
occ::handle<BRep_GCurve> GC = occ::down_cast<BRep_GCurve>(itcr.Value());
if (GC.IsNull() || !GC->IsCurveOnSurface())
{
continue;
}
occ::handle<Geom_Surface> aSurf = GC->Surface();
occ::handle<Geom2d_Curve> aCur2d = GC->PCurve();
if ((myApproxSurfaceFlag
&& IsConvertSurface(aSurf, myMaxDegree, myNbMaxSeg, myRational, myParameters))
|| (myApproxCurve2dFlag
&& IsConvertCurve2d(aCur2d, myMaxDegree, myNbMaxSeg, myRational, myParameters)))
{
IsConvert = true;
break;
}
}
}
if (!myApproxCurve2dFlag)
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
return true;
}
else
{
return false;
}
}
bool IsOf = true;
if (myParameters->ConvertOffsetCurv2d())
{
IsOf = false;
}
bool IsConv = ConvertCurve2d(aCurve, C, IsConvert, First, Last, TolCur, IsOf);
Tol = BRep_Tool::Tolerance(E); // TolCur;
BRep_Builder B;
if (!IsConv && !NewE.IsSame(E))
{
B.Range(NewE, First, Last);
}
return IsConv;
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::ConvertCurve2d(const occ::handle<Geom2d_Curve>& aCurve,
occ::handle<Geom2d_Curve>& C,
const bool IsConvert,
const double First,
const double Last,
double& TolCur,
const bool IsOf)
{
// TolCur = Precision::PConfusion();
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
{
occ::handle<Geom2d_TrimmedCurve> tmp = occ::down_cast<Geom2d_TrimmedCurve>(aCurve);
// double pf =tmp->FirstParameter(), pl = tmp->LastParameter();
occ::handle<Geom2d_Curve> BasCurve = tmp->BasisCurve();
occ::handle<Geom2d_Curve> ResCurve;
if (ConvertCurve2d(BasCurve, ResCurve, IsConvert, First, Last, TolCur, IsOf))
{
// double F = std::max(ResCurve->FirstParameter(),First), L =
// std::min(ResCurve->LastParameter(),Last); if(F != Last)
// C = new
// Geom2d_TrimmedCurve(ResCurve,Max(First,ResCurve->FirstParameter()),Min(Last,ResCurve->LastParameter()));
// else
C = ResCurve;
return true;
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
else
{
return false;
}
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_Line)) && myParameters->ConvertCurve2d())
{
occ::handle<Geom2d_Line> aLine2d = occ::down_cast<Geom2d_Line>(aCurve);
NCollection_Array1<gp_Pnt2d> poles(1, 2);
poles(1) = aLine2d->Value(First);
poles(2) = aLine2d->Value(Last);
NCollection_Array1<double> knots(1, 2);
knots(1) = First;
knots(2) = Last;
NCollection_Array1<int> mults(1, 2);
mults.Init(2);
occ::handle<Geom2d_BSplineCurve> res = new Geom2d_BSplineCurve(poles, knots, mults, 1);
C = res;
return true;
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_Conic)) && myParameters->ConvertCurve2d())
{
occ::handle<Geom2d_BSplineCurve> aBSpline2d;
// clang-format off
occ::handle<Geom2d_Curve> tcurve = new Geom2d_TrimmedCurve(aCurve,First,Last); //protection against parabols ets
// clang-format on
Geom2dConvert_ApproxCurve approx(tcurve, myTol2d, myContinuity2d, myNbMaxSeg, 6);
if (approx.HasResult())
{
aBSpline2d = approx.Curve();
}
else
{
aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve, Convert_QuasiAngular);
}
double Shift = First - aBSpline2d->FirstParameter();
if (std::abs(Shift) > Precision::PConfusion())
{
NCollection_Array1<double> newKnots(aBSpline2d->Knots());
for (int i = 1; i <= newKnots.Length(); i++)
{
newKnots(i) += Shift;
}
aBSpline2d->SetKnots(newKnots);
}
occ::handle<Geom2d_Curve> ResCurve;
if (ConvertCurve2d(aBSpline2d, ResCurve, IsConvert, First, Last, TolCur, false))
{
C = ResCurve;
return true;
}
else
{
C = aBSpline2d;
TolCur = Precision::PConfusion();
return true;
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) && myParameters->ConvertCurve2d())
{
occ::handle<Geom2d_Curve> aBSpline2d =
Geom2dConvert::CurveToBSplineCurve(aCurve, Convert_QuasiAngular);
occ::handle<Geom2d_Curve> ResCurve;
if (ConvertCurve2d(aBSpline2d, ResCurve, IsConvert, First, Last, TolCur, false))
{
C = ResCurve;
return true;
}
else
{
C = aBSpline2d;
TolCur = Precision::PConfusion();
return true;
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)) && IsOf)
{
occ::handle<Geom2d_OffsetCurve> tmp = occ::down_cast<Geom2d_OffsetCurve>(aCurve);
occ::handle<Geom2d_Curve> BasCurve = tmp->BasisCurve();
occ::handle<Geom2d_Curve> ResCurve;
if (ConvertCurve2d(BasCurve, ResCurve, IsConvert, First, Last, TolCur))
{
if (ResCurve->Continuity() != GeomAbs_C0)
{
C = new Geom2d_OffsetCurve(ResCurve, tmp->Offset());
return true;
}
else if (ConvertCurve2d(aCurve, ResCurve, IsConvert, First, Last, TolCur, false))
{
return true;
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
else
{
return false;
}
}
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
else
{
return false;
}
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))
|| aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))
|| ((aCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) && !IsOf))
{
int Deg = 1;
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
{
occ::handle<Geom2d_BSplineCurve> BsC = occ::down_cast<Geom2d_BSplineCurve>(aCurve);
Deg = BsC->Degree();
bool IsR = (myRational && BsC->IsRational());
if (!IsR && Deg <= myMaxDegree && (BsC->NbKnots() - 1) <= myNbMaxSeg)
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
else
{
return false;
}
}
}
if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)))
{
occ::handle<Geom2d_BezierCurve> BzC = occ::down_cast<Geom2d_BezierCurve>(aCurve);
Deg = BzC->Degree();
bool IsR = (myRational && BzC->IsRational());
if (!IsR && Deg <= myMaxDegree)
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
else
{
return false;
}
}
}
occ::handle<Geom2d_Curve> aCurve1;
double pf = aCurve->FirstParameter(), pl = aCurve->LastParameter();
// 15.11.2002 PTV OCC966
if (ShapeAnalysis_Curve::IsPeriodic(aCurve) && (First != Last))
{
aCurve1 = new Geom2d_TrimmedCurve(aCurve, First, Last);
}
else if (aCurve->FirstParameter() < (First - Precision::PConfusion())
|| aCurve->LastParameter() > (Last + Precision::PConfusion()))
{
double F = std::max(First, pf), L = std::min(Last, pl);
if (F != L)
{
aCurve1 = new Geom2d_TrimmedCurve(aCurve, F, L);
}
else
{
aCurve1 = aCurve;
}
}
else
{
aCurve1 = aCurve;
}
int aC = std::min(ContToInteger(myContinuity2d), ContToInteger(aCurve->Continuity()));
if (!aC)
{
aC = ContToInteger(myContinuity2d);
}
// aC = std::min(aC,(Deg -1));
int aC1 = aC;
// GeomAbs_Shape aCont =IntegerToGeomAbsShape(aC);
int MaxSeg = myNbMaxSeg;
int MaxDeg = myMaxDegree;
// int GMaxDegree = 15;//Geom2d_BSplineCurve::MaxDegree();
for (; aC >= 0; aC--)
{
try
{
OCC_CATCH_SIGNALS
GeomAbs_Shape aCont = IntegerToGeomAbsShape(aC);
for (int j = 1; j <= 2; j++)
{
Geom2dConvert_ApproxCurve anApprox(aCurve1, myTol2d, aCont, MaxSeg, MaxDeg);
bool Done = anApprox.IsDone();
C = anApprox.Curve();
int Nbseg = occ::down_cast<Geom2d_BSplineCurve>(C)->NbKnots() - 1;
int DegC = occ::down_cast<Geom2d_BSplineCurve>(C)->Degree();
if (myDeg
&& ((DegC > MaxDeg) || !Done || (anApprox.MaxError() >= std::max(myTol2d, TolCur))))
{
if (MaxSeg < myParameters->GMaxSeg())
{
MaxSeg = myParameters->GMaxSeg();
aC = aC1;
continue;
}
else
{
#ifdef OCCT_DEBUG
std::cout << "Curve is not aproxed with continuity " << aCont << std::endl;
#endif
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
}
}
if (!myDeg
&& ((Nbseg >= MaxSeg) || !Done || (anApprox.MaxError() >= std::max(myTol2d, TolCur))))
{
if (MaxDeg < myParameters->GMaxDegree())
{
MaxDeg = myParameters->GMaxDegree();
aC = aC1;
continue;
}
else
{
#ifdef OCCT_DEBUG
std::cout << "Curve is not aproxed with continuity " << aCont << std::endl;
#endif
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
}
}
myConvert = true;
TolCur = anApprox.MaxError();
myCurve2dError = std::max(myCurve2dError, anApprox.MaxError());
return true;
}
}
catch (Standard_Failure const& anException)
{
#ifdef OCCT_DEBUG
std::cout << "Warning: Geom2dConvert_ApproxCurve Exception: Wrong Coefficient :Decrease "
"Continuity ";
anException.Print(std::cout);
std::cout << std::endl;
#endif
(void)anException;
continue;
}
}
return false;
}
else
{
if (IsConvert)
{
C = occ::down_cast<Geom2d_Curve>(aCurve->Copy());
TolCur = Precision::PConfusion();
return true;
}
else
{
return false;
}
}
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::NewPoint(const TopoDS_Vertex& V, gp_Pnt& P, double& Tol)
{
Tol = BRep_Tool::Tolerance(V);
if (myConvert)
{
gp_Pnt p1(BRep_Tool::Pnt(V).XYZ());
P = p1;
return true;
}
else
{
return false;
}
}
//=================================================================================================
bool ShapeCustom_BSplineRestriction::NewParameter(const TopoDS_Vertex& /*V*/,
const TopoDS_Edge& /*E*/,
double& /*P*/,
double& /*Tol*/)
{
return false;
}
//=================================================================================================
GeomAbs_Shape ShapeCustom_BSplineRestriction::Continuity(const TopoDS_Edge& E,
const TopoDS_Face& F1,
const TopoDS_Face& F2,
const TopoDS_Edge& /*NewE*/,
const TopoDS_Face& /*NewF1*/,
const TopoDS_Face& /*NewF2*/)
{
return BRep_Tool::Continuity(E, F1, F2);
}
//=================================================================================================
double ShapeCustom_BSplineRestriction::MaxErrors(double& aCurve3dErr, double& aCurve2dErr) const
{
aCurve3dErr = myCurve3dError;
aCurve2dErr = myCurve2dError;
return mySurfaceError;
}
//=================================================================================================
int ShapeCustom_BSplineRestriction::NbOfSpan() const
{
return myNbOfSpan;
}
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.