Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 1995-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 <Adaptor2d_Curve2d.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <BRepTopAdaptor_HVertex.hxx>
#include <BRepTopAdaptor_TopolTool.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_Type.hxx>
#include <NCollection_Array2.hxx>
#include <TopoDS.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepTopAdaptor_TopolTool, Adaptor3d_TopolTool)
static void Analyse(const NCollection_Array2<gp_Pnt>& array2,
const int nbup,
const int nbvp,
int& myNbSamplesU,
int& myNbSamplesV);
//=================================================================================================
BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool()
: myFClass2d(nullptr),
myU0(0.0),
myV0(0.0),
myDU(0.0),
myDV(0.0)
{
myNbSamplesU = -1;
}
//=================================================================================================
BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool(const occ::handle<Adaptor3d_Surface>& S)
: myFClass2d(nullptr)
{
Initialize(S);
// myS = S;
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::Initialize()
{
throw Standard_NotImplemented("BRepTopAdaptor_TopolTool::Initialize()");
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::Initialize(const occ::handle<Adaptor3d_Surface>& S)
{
occ::handle<BRepAdaptor_Surface> brhs = occ::down_cast<BRepAdaptor_Surface>(S);
if (brhs.IsNull())
{
throw Standard_ConstructionError();
}
TopoDS_Shape s_wnt = brhs->Face();
s_wnt.Orientation(TopAbs_FORWARD);
myFace = TopoDS::Face(s_wnt);
delete (BRepTopAdaptor_FClass2d*)myFClass2d;
myFClass2d = nullptr;
myNbSamplesU = -1;
myS = S;
myCurves.Clear();
TopExp_Explorer ex(myFace, TopAbs_EDGE);
for (; ex.More(); ex.Next())
{
occ::handle<BRepAdaptor_Curve2d> aCurve =
new BRepAdaptor_Curve2d(BRepAdaptor_Curve2d(TopoDS::Edge(ex.Current()), myFace));
myCurves.Append(aCurve);
}
myCIterator = NCollection_List<occ::handle<Standard_Transient>>::Iterator();
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::Initialize(const occ::handle<Adaptor2d_Curve2d>& C)
{
myCurve = occ::down_cast<BRepAdaptor_Curve2d>(C);
if (myCurve.IsNull())
{
throw Standard_ConstructionError();
}
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::Init()
{
myCIterator.Initialize(myCurves);
}
//=================================================================================================
bool BRepTopAdaptor_TopolTool::More()
{
return myCIterator.More();
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::Next()
{
myCIterator.Next();
}
//=================================================================================================
occ::handle<Adaptor2d_Curve2d> BRepTopAdaptor_TopolTool::Value()
{
return occ::down_cast<Adaptor2d_Curve2d>(myCIterator.Value());
}
// modified by NIZNHY-PKV Tue Mar 27 14:23:40 2001 f
//=================================================================================================
void* BRepTopAdaptor_TopolTool::Edge() const
{
occ::handle<BRepAdaptor_Curve2d> aHCurve =
occ::down_cast<BRepAdaptor_Curve2d>(myCIterator.Value());
return (void*)(&aHCurve->Edge());
}
// modified by NIZNHY-PKV Tue Mar 27 14:23:43 2001 t
//=================================================================================================
void BRepTopAdaptor_TopolTool::InitVertexIterator()
{
myVIterator.Init(myCurve->Edge(), TopAbs_VERTEX);
}
//=================================================================================================
bool BRepTopAdaptor_TopolTool::MoreVertex()
{
return myVIterator.More();
}
void BRepTopAdaptor_TopolTool::NextVertex()
{
myVIterator.Next();
}
//=================================================================================================
occ::handle<Adaptor3d_HVertex> BRepTopAdaptor_TopolTool::Vertex()
{
return new BRepTopAdaptor_HVertex(TopoDS::Vertex(myVIterator.Current()), myCurve);
}
//=================================================================================================
TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
const double Tol,
const bool RecadreOnPeriodic)
{
if (myFace.IsNull())
{
return TopAbs_UNKNOWN;
}
if (myFClass2d == nullptr)
{
myFClass2d = (void*)new BRepTopAdaptor_FClass2d(myFace, Tol);
}
return (((BRepTopAdaptor_FClass2d*)myFClass2d)->Perform(P, RecadreOnPeriodic));
}
//=================================================================================================
bool BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
const double Tol,
const bool RecadreOnPeriodic)
{
if (myFClass2d == nullptr)
{
myFClass2d = (void*)new BRepTopAdaptor_FClass2d(myFace, Tol);
}
return (TopAbs_ON
== ((BRepTopAdaptor_FClass2d*)myFClass2d)->TestOnRestriction(P, Tol, RecadreOnPeriodic));
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::Destroy()
{
delete (BRepTopAdaptor_FClass2d*)myFClass2d;
myFClass2d = nullptr;
}
//=================================================================================================
TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation(const occ::handle<Adaptor2d_Curve2d>& C)
{
occ::handle<BRepAdaptor_Curve2d> brhc = occ::down_cast<BRepAdaptor_Curve2d>(C);
return brhc->Edge().Orientation();
}
//=================================================================================================
TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation(const occ::handle<Adaptor3d_HVertex>& C)
{
return Adaptor3d_TopolTool::Orientation(C);
}
//-- ============================================================
//-- methods used for samples
//-- ============================================================
//=================================================================================================
void Analyse(const NCollection_Array2<gp_Pnt>& array2,
const int nbup,
const int nbvp,
int& myNbSamplesU,
int& myNbSamplesV)
{
gp_Vec Vi, Vip1;
int sh, nbch, i, j;
sh = 1;
nbch = 0;
if (nbvp > 2)
{
for (i = 2; i < nbup; i++)
{
const gp_Pnt& A = array2.Value(i, 1);
const gp_Pnt& B = array2.Value(i, 2);
const gp_Pnt& C = array2.Value(i, 3);
Vi.SetCoord(C.X() - B.X() - B.X() + A.X(),
C.Y() - B.Y() - B.Y() + A.Y(),
C.Z() - B.Z() - B.Z() + A.Z());
int locnbch = 0;
for (j = 3; j < nbvp; j++)
{ //-- test
const gp_Pnt& Ax = array2.Value(i, j - 1);
const gp_Pnt& Bx = array2.Value(i, j);
const gp_Pnt& Cx = array2.Value(i, j + 1);
Vip1.SetCoord(Cx.X() - Bx.X() - Bx.X() + Ax.X(),
Cx.Y() - Bx.Y() - Bx.Y() + Ax.Y(),
Cx.Z() - Bx.Z() - Bx.Z() + Ax.Z());
double pd = Vi.Dot(Vip1);
Vi = Vip1;
if (pd > 1.0e-7 || pd < -1.0e-7)
{
if (pd > 0)
{
if (sh == -1)
{
sh = 1;
locnbch++;
}
}
else
{
if (sh == 1)
{
sh = -1;
locnbch++;
}
}
}
}
if (locnbch > nbch)
{
nbch = locnbch;
}
}
}
myNbSamplesV = nbch + 5;
nbch = 0;
if (nbup > 2)
{
for (j = 2; j < nbvp; j++)
{
const gp_Pnt& A = array2.Value(1, j);
const gp_Pnt& B = array2.Value(2, j);
const gp_Pnt& C = array2.Value(3, j);
Vi.SetCoord(C.X() - B.X() - B.X() + A.X(),
C.Y() - B.Y() - B.Y() + A.Y(),
C.Z() - B.Z() - B.Z() + A.Z());
int locnbch = 0;
for (i = 3; i < nbup; i++)
{ //-- test
const gp_Pnt& Ax = array2.Value(i - 1, j);
const gp_Pnt& Bx = array2.Value(i, j);
const gp_Pnt& Cx = array2.Value(i + 1, j);
Vip1.SetCoord(Cx.X() - Bx.X() - Bx.X() + Ax.X(),
Cx.Y() - Bx.Y() - Bx.Y() + Ax.Y(),
Cx.Z() - Bx.Z() - Bx.Z() + Ax.Z());
double pd = Vi.Dot(Vip1);
Vi = Vip1;
if (pd > 1.0e-7 || pd < -1.0e-7)
{
if (pd > 0)
{
if (sh == -1)
{
sh = 1;
locnbch++;
}
}
else
{
if (sh == 1)
{
sh = -1;
locnbch++;
}
}
}
}
if (locnbch > nbch)
{
nbch = locnbch;
}
}
}
myNbSamplesU = nbch + 5;
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
{
double uinf, usup, vinf, vsup;
uinf = myS->FirstUParameter();
usup = myS->LastUParameter();
vinf = myS->FirstVParameter();
vsup = myS->LastVParameter();
if (usup < uinf)
{
double temp = uinf;
uinf = usup;
usup = temp;
}
if (vsup < vinf)
{
double temp = vinf;
vinf = vsup;
vsup = temp;
}
if (uinf == RealFirst() && usup == RealLast())
{
uinf = -1.e5;
usup = 1.e5;
}
else if (uinf == RealFirst())
{
uinf = usup - 2.e5;
}
else if (usup == RealLast())
{
usup = uinf + 2.e5;
}
if (vinf == RealFirst() && vsup == RealLast())
{
vinf = -1.e5;
vsup = 1.e5;
}
else if (vinf == RealFirst())
{
vinf = vsup - 2.e5;
}
else if (vsup == RealLast())
{
vsup = vinf + 2.e5;
}
int nbsu, nbsv;
GeomAbs_SurfaceType typS = myS->GetType();
switch (typS)
{
case GeomAbs_Plane: {
nbsv = 2;
nbsu = 2;
}
break;
case GeomAbs_BezierSurface: {
nbsv = 3 + myS->NbVPoles();
nbsu = 3 + myS->NbUPoles();
}
break;
case GeomAbs_BSplineSurface: {
nbsv = myS->NbVKnots();
nbsv *= myS->VDegree();
if (nbsv < 4)
{
nbsv = 4;
}
nbsu = myS->NbUKnots();
nbsu *= myS->UDegree();
if (nbsu < 4)
{
nbsu = 4;
}
}
break;
case GeomAbs_Cylinder:
case GeomAbs_Cone:
case GeomAbs_Sphere:
case GeomAbs_Torus: {
//-- Set 15 for 2pi
//-- Not enough ->25 for 2pi
nbsu = (int)(8 * (usup - uinf));
nbsv = (int)(7 * (vsup - vinf));
if (nbsu < 5)
{
nbsu = 5;
}
if (nbsv < 5)
{
nbsv = 5;
}
if (nbsu > 30)
{
nbsu = 30; // modif HRT buc60462
}
if (nbsv > 15)
{
nbsv = 15;
}
//-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
}
break;
case GeomAbs_SurfaceOfRevolution:
case GeomAbs_SurfaceOfExtrusion: {
nbsv = 15;
nbsu = 25;
}
break;
default: {
nbsu = 10;
nbsv = 10;
}
break;
}
//-- If the number of points is too great, analyze
//--
//--
if (nbsu < 10)
{
nbsu = 10;
}
if (nbsv < 10)
{
nbsv = 10;
}
myNbSamplesU = nbsu;
myNbSamplesV = nbsv;
//-- printf("\n BRepTopAdaptor_TopolTool NbSu=%d NbSv=%d ",nbsu,nbsv);
if (nbsu > 10 || nbsv > 10)
{
if (typS == GeomAbs_BSplineSurface)
{
const occ::handle<Geom_BSplineSurface>& Bspl = myS->BSpline();
int nbup = Bspl->NbUPoles();
int nbvp = Bspl->NbVPoles();
const NCollection_Array2<gp_Pnt>& array2 = Bspl->Poles();
Analyse(array2, nbup, nbvp, myNbSamplesU, myNbSamplesV);
nbsu = myNbSamplesU;
nbsv = myNbSamplesV;
//-- printf("\n Apres analyse BSPline NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
}
else if (typS == GeomAbs_BezierSurface)
{
const occ::handle<Geom_BezierSurface>& Bez = myS->Bezier();
int nbup = Bez->NbUPoles();
int nbvp = Bez->NbVPoles();
const NCollection_Array2<gp_Pnt>& array2 = Bez->Poles();
Analyse(array2, nbup, nbvp, myNbSamplesU, myNbSamplesV);
nbsu = myNbSamplesU;
nbsv = myNbSamplesV;
//-- printf("\n Apres analyse Bezier NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
}
}
if (nbsu < 10)
{
nbsu = 10;
}
if (nbsv < 10)
{
nbsv = 10;
}
myNbSamplesU = nbsu;
myNbSamplesV = nbsv;
myU0 = uinf;
myV0 = vinf;
myDU = (usup - uinf) / (myNbSamplesU + 1);
myDV = (vsup - vinf) / (myNbSamplesV + 1);
}
//=================================================================================================
int BRepTopAdaptor_TopolTool::NbSamplesU()
{
if (myNbSamplesU < 0)
{
ComputeSamplePoints();
}
return (myNbSamplesU);
}
//=================================================================================================
int BRepTopAdaptor_TopolTool::NbSamplesV()
{
if (myNbSamplesU < 0)
{
ComputeSamplePoints();
}
return (myNbSamplesV);
}
//=================================================================================================
int BRepTopAdaptor_TopolTool::NbSamples()
{
if (myNbSamplesU < 0)
{
ComputeSamplePoints();
}
return (myNbSamplesU * myNbSamplesV);
}
//=================================================================================================
void BRepTopAdaptor_TopolTool::SamplePoint(const int i, gp_Pnt2d& P2d, gp_Pnt& P3d)
{
int iv = 1 + i / myNbSamplesU;
int iu = 1 + i - (iv - 1) * myNbSamplesU;
double u = myU0 + iu * myDU;
double v = myV0 + iv * myDV;
P2d.SetCoord(u, v);
P3d = myS->Value(u, v);
}
//=================================================================================================
bool BRepTopAdaptor_TopolTool::DomainIsInfinite()
{
double uinf, usup, vinf, vsup;
uinf = myS->FirstUParameter();
usup = myS->LastUParameter();
vinf = myS->FirstVParameter();
vsup = myS->LastVParameter();
if (Precision::IsNegativeInfinite(uinf))
{
return (true);
}
if (Precision::IsPositiveInfinite(usup))
{
return (true);
}
if (Precision::IsNegativeInfinite(vinf))
{
return (true);
}
if (Precision::IsPositiveInfinite(vsup))
{
return (true);
}
return (false);
}
//=================================================================================================
bool BRepTopAdaptor_TopolTool::Has3d() const
{
return true;
}
//=================================================================================================
double BRepTopAdaptor_TopolTool::Tol3d(const occ::handle<Adaptor2d_Curve2d>& C) const
{
occ::handle<BRepAdaptor_Curve2d> brhc = occ::down_cast<BRepAdaptor_Curve2d>(C);
if (brhc.IsNull())
{
throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
}
const TopoDS_Edge& edge = brhc->Edge();
if (edge.IsNull())
{
throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
}
return BRep_Tool::Tolerance(edge);
}
//=================================================================================================
double BRepTopAdaptor_TopolTool::Tol3d(const occ::handle<Adaptor3d_HVertex>& V) const
{
occ::handle<BRepTopAdaptor_HVertex> brhv = occ::down_cast<BRepTopAdaptor_HVertex>(V);
if (brhv.IsNull())
{
throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
}
const TopoDS_Vertex& ver = brhv->Vertex();
if (ver.IsNull())
{
throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
}
return BRep_Tool::Tolerance(ver);
}
//=================================================================================================
gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const occ::handle<Adaptor3d_HVertex>& V) const
{
occ::handle<BRepTopAdaptor_HVertex> brhv = occ::down_cast<BRepTopAdaptor_HVertex>(V);
if (brhv.IsNull())
{
throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
}
const TopoDS_Vertex& ver = brhv->Vertex();
if (ver.IsNull())
{
throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
}
return BRep_Tool::Pnt(ver);
}