Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1993-07-07
// Created by: Remi LEQUETTE
// 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 <BRep_Curve3D.hxx>
#include <BRep_CurveOnClosedSurface.hxx>
#include <BRep_CurveOnSurface.hxx>
#include <BRep_CurveRepresentation.hxx>
#include <BRep_Polygon3D.hxx>
#include <BRep_PolygonOnSurface.hxx>
#include <BRep_PolygonOnTriangulation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_TFace.hxx>
#include <BRep_Tool.hxx>
#include <BRep_TVertex.hxx>
#include <ElSLib.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor.hxx>
#include <Geom_Curve.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomProjLib.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <NCollection_IncAllocator.hxx>
#include <Poly_Polygon2D.hxx>
#include <Poly_Polygon3D.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
#include <Precision.hxx>
#include <ProjLib_ProjectedCurve.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NullObject.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <NCollection_Map.hxx>
#include <BRep_GCurve.hxx>
// modified by NIZNHY-PKV Fri Oct 17 14:13:29 2008f
static bool IsPlane(const occ::handle<Geom_Surface>& aS);
namespace
{
//=================================================================================================
//! Checks trim range against the effective basis curve.
//! @param[in] theCurve curve to check
//! @param[in] theFirst first trim parameter
//! @param[in] theLast last trim parameter
//! @return true if the trim range is valid
bool isValidTrimRange(const occ::handle<Geom_Curve>& theCurve,
const double theFirst,
const double theLast)
{
const double aTrimFirst = std::min(theFirst, theLast);
const double aTrimLast = std::max(theFirst, theLast);
if (!(aTrimFirst < aTrimLast))
{
return false;
}
// Unwrap nested trims.
occ::handle<Geom_Curve> aBasisCurve = theCurve;
for (occ::handle<Geom_TrimmedCurve> aTrim = occ::down_cast<Geom_TrimmedCurve>(aBasisCurve);
!aTrim.IsNull();
aTrim = occ::down_cast<Geom_TrimmedCurve>(aBasisCurve))
{
aBasisCurve = aTrim->BasisCurve();
}
return aBasisCurve->IsPeriodic()
|| (aBasisCurve->FirstParameter() - aTrimFirst <= Precision::PConfusion()
&& aTrimLast - aBasisCurve->LastParameter() <= Precision::PConfusion());
}
} // namespace
// modified by NIZNHY-PKV Fri Oct 17 14:13:33 2008t
//
//=================================================================================================
// function : Surface
// purpose : Returns the geometric surface of the face. Returns
// in <L> the location for the surface.
//=================================================================================================
const occ::handle<Geom_Surface>& BRep_Tool::Surface(const TopoDS_Face& F, TopLoc_Location& L)
{
const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
L = F.Location() * TF->Location();
return TF->Surface();
}
//=================================================================================================
// function : Surface
// purpose : Returns the geometric surface of the face. It can
// be a copy if there is a Location.
//=================================================================================================
occ::handle<Geom_Surface> BRep_Tool::Surface(const TopoDS_Face& F)
{
const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
const occ::handle<Geom_Surface>& S = TF->Surface();
if (S.IsNull())
{
return S;
}
TopLoc_Location L = F.Location() * TF->Location();
if (!L.IsIdentity())
{
occ::handle<Geom_Geometry> aCopy = S->Transformed(L.Transformation());
Geom_Surface* aGS = static_cast<Geom_Surface*>(aCopy.get());
return occ::handle<Geom_Surface>(aGS);
}
return S;
}
//=================================================================================================
const occ::handle<Poly_Triangulation>& BRep_Tool::Triangulation(
const TopoDS_Face& theFace,
TopLoc_Location& theLocation,
const Poly_MeshPurpose theMeshPurpose)
{
theLocation = theFace.Location();
const BRep_TFace* aTFace = static_cast<const BRep_TFace*>(theFace.TShape().get());
return aTFace->Triangulation(theMeshPurpose);
}
//=================================================================================================
const NCollection_List<occ::handle<Poly_Triangulation>>& BRep_Tool::Triangulations(
const TopoDS_Face& theFace,
TopLoc_Location& theLocation)
{
theLocation = theFace.Location();
const BRep_TFace* aTFace = static_cast<const BRep_TFace*>(theFace.TShape().get());
return aTFace->Triangulations();
}
//=================================================================================================
// function : Tolerance
// purpose : Returns the tolerance of the face.
//=================================================================================================
double BRep_Tool::Tolerance(const TopoDS_Face& F)
{
const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
double p = TF->Tolerance();
constexpr double pMin = Precision::Confusion();
if (p > pMin)
{
return p;
}
else
{
return pMin;
}
}
//=================================================================================================
// function : NaturalRestriction
// purpose : Returns the NaturalRestriction flag of the face.
//=================================================================================================
bool BRep_Tool::NaturalRestriction(const TopoDS_Face& F)
{
const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
return TF->NaturalRestriction();
}
//=================================================================================================
// function : Curve
// purpose : Returns the 3D curve of the edge. May be a Null
// handle. Returns in <L> the location for the curve.
// In <First> and <Last> the parameter range.
//=================================================================================================
static const occ::handle<Geom_Curve> nullCurve;
const occ::handle<Geom_Curve>& BRep_Tool::Curve(const TopoDS_Edge& E,
TopLoc_Location& L,
double& First,
double& Last)
{
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurve3D())
{
const BRep_Curve3D* GC = static_cast<const BRep_Curve3D*>(cr.get());
L = E.Location() * GC->Location();
GC->Range(First, Last);
return GC->Curve3D();
}
itcr.Next();
}
L.Identity();
First = Last = 0.;
return nullCurve;
}
//=================================================================================================
// function : Curve
// purpose : Returns the 3D curve of the edge. May be a Null handle.
// In <First> and <Last> the parameter range.
// It can be a copy if there is a Location.
//=================================================================================================
occ::handle<Geom_Curve> BRep_Tool::Curve(const TopoDS_Edge& E, double& First, double& Last)
{
TopLoc_Location L;
const occ::handle<Geom_Curve>& C = Curve(E, L, First, Last);
if (!C.IsNull())
{
if (!L.IsIdentity())
{
occ::handle<Geom_Geometry> aCopy = C->Transformed(L.Transformation());
Geom_Curve* aGC = static_cast<Geom_Curve*>(aCopy.get());
return occ::handle<Geom_Curve>(aGC);
}
}
return C;
}
//=================================================================================================
// function : IsGeometric
// purpose : Returns True if <F> has a surface.
//=================================================================================================
bool BRep_Tool::IsGeometric(const TopoDS_Face& F)
{
const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
const occ::handle<Geom_Surface>& S = TF->Surface();
return !S.IsNull();
}
//=================================================================================================
// function : IsGeometric
// purpose : Returns True if <E> is a 3d curve or a curve on
// surface.
//=================================================================================================
bool BRep_Tool::IsGeometric(const TopoDS_Edge& E)
{
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurve3D())
{
occ::handle<BRep_Curve3D> GC(occ::down_cast<BRep_Curve3D>(cr));
if (!GC.IsNull() && !GC->Curve3D().IsNull())
{
return true;
}
}
else if (cr->IsCurveOnSurface())
{
return true;
}
itcr.Next();
}
return false;
}
//=================================================================================================
// function : Polygon3D
// purpose : Returns the 3D polygon of the edge. May be a Null
// handle. Returns in <L> the location for the polygon.
//=================================================================================================
static const occ::handle<Poly_Polygon3D> nullPolygon3D;
const occ::handle<Poly_Polygon3D>& BRep_Tool::Polygon3D(const TopoDS_Edge& E, TopLoc_Location& L)
{
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygon3D())
{
const BRep_Polygon3D* GC = static_cast<const BRep_Polygon3D*>(cr.get());
L = E.Location() * GC->Location();
return GC->Polygon3D();
}
itcr.Next();
}
L.Identity();
return nullPolygon3D;
}
//=================================================================================================
// function : CurveOnSurface
// purpose : Returns the curve associated to the edge in the
// parametric space of the face. Returns a NULL
// handle if this curve does not exist. Returns in
// <First> and <Last> the parameter range.
//=================================================================================================
occ::handle<Geom2d_Curve> BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
const TopoDS_Face& F,
double& First,
double& Last,
bool* theIsStored)
{
TopLoc_Location l;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, l);
TopoDS_Edge aLocalEdge = E;
if (F.Orientation() == TopAbs_REVERSED)
{
aLocalEdge.Reverse();
}
return CurveOnSurface(aLocalEdge, S, l, First, Last, theIsStored);
}
//=================================================================================================
// function : CurveOnSurface
// purpose : Returns the curve associated to the edge in the
// parametric space of the surface. Returns a NULL
// handle if this curve does not exist. Returns in
// <First> and <Last> the parameter range.
//=================================================================================================
static const occ::handle<Geom2d_Curve> nullPCurve;
occ::handle<Geom2d_Curve> BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L,
double& First,
double& Last,
bool* theIsStored)
{
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
if (theIsStored)
{
*theIsStored = true;
}
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
if (itcr.More())
{
const TopLoc_Location loc = L.Predivided(E.Location());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface(S, loc))
{
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
GC->Range(First, Last);
if (GC->IsCurveOnClosedSurface() && Eisreversed)
{
return GC->PCurve2();
}
else
{
return GC->PCurve();
}
}
itcr.Next();
}
}
// Curve is not found. Try projection on plane
if (theIsStored)
{
*theIsStored = false;
}
return CurveOnPlane(E, S, L, First, Last);
}
//=================================================================================================
// function : CurveOnPlane
// purpose : For planar surface returns projection of the edge on the plane
//=================================================================================================
occ::handle<Geom2d_Curve> BRep_Tool::CurveOnPlane(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L,
double& First,
double& Last)
{
First = Last = 0.;
// Check if the surface is planar
occ::handle<Geom_Plane> GP;
occ::handle<Geom_RectangularTrimmedSurface> GRTS;
GRTS = occ::down_cast<Geom_RectangularTrimmedSurface>(S);
if (!GRTS.IsNull())
{
GP = occ::down_cast<Geom_Plane>(GRTS->BasisSurface());
}
else
{
GP = occ::down_cast<Geom_Plane>(S);
}
if (GP.IsNull())
{
// not a plane
return nullPCurve;
}
// Check existence of 3d curve in edge
double f, l;
TopLoc_Location aCurveLocation;
occ::handle<Geom_Curve> C3D = BRep_Tool::Curve(E, aCurveLocation, f, l);
if (C3D.IsNull())
{
// no 3d curve
return nullPCurve;
}
aCurveLocation = aCurveLocation.Predivided(L);
First = f;
Last = l;
// Transform curve and update parameters in account of scale factor
if (!aCurveLocation.IsIdentity())
{
const gp_Trsf& aTrsf = aCurveLocation.Transformation();
C3D = occ::down_cast<Geom_Curve>(C3D->Transformed(aTrsf));
f = C3D->TransformedParameter(f, aTrsf);
l = C3D->TransformedParameter(l, aTrsf);
}
if (!isValidTrimRange(C3D, f, l))
{
return nullPCurve;
}
occ::handle<Geom_TrimmedCurve> aTrimmedCurve = new Geom_TrimmedCurve(C3D, f, l, true, false);
// Perform projection
occ::handle<Geom_Curve> ProjOnPlane =
GeomProjLib::ProjectOnPlane(aTrimmedCurve, GP, GP->Position().Direction(), true);
occ::handle<GeomAdaptor_Surface> HS = new GeomAdaptor_Surface(GP);
occ::handle<GeomAdaptor_Curve> HC = new GeomAdaptor_Curve(ProjOnPlane);
ProjLib_ProjectedCurve Proj(HS, HC);
occ::handle<Geom2d_Curve> pc = Geom2dAdaptor::MakeCurve(Proj);
if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
{
occ::handle<Geom2d_TrimmedCurve> TC = occ::down_cast<Geom2d_TrimmedCurve>(pc);
pc = TC->BasisCurve();
}
return pc;
}
//=================================================================================================
void BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
occ::handle<Geom2d_Curve>& C,
occ::handle<Geom_Surface>& S,
TopLoc_Location& L,
double& First,
double& Last)
{
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface())
{
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
C = GC->PCurve();
S = GC->Surface();
L = E.Location() * GC->Location();
GC->Range(First, Last);
return;
}
itcr.Next();
}
C.Nullify();
S.Nullify();
L.Identity();
First = Last = 0.;
}
//=================================================================================================
void BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
occ::handle<Geom2d_Curve>& C,
occ::handle<Geom_Surface>& S,
TopLoc_Location& L,
double& First,
double& Last,
const int Index)
{
if (Index < 1)
{
return;
}
int i = 0;
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
for (; itcr.More(); itcr.Next())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface())
{
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
++i;
// Compare index taking into account the fact that for the curves on
// closed surfaces there are two PCurves
if (i == Index)
{
C = GC->PCurve();
}
else if (GC->IsCurveOnClosedSurface() && (++i == Index))
{
C = GC->PCurve2();
}
else
{
continue;
}
S = GC->Surface();
L = E.Location() * GC->Location();
GC->Range(First, Last);
return;
}
}
C.Nullify();
S.Nullify();
L.Identity();
First = Last = 0.;
}
//=================================================================================================
// function : PolygonOnSurface
// purpose : Returns the polygon associated to the edge in the
// parametric space of the face. Returns a NULL
// handle if this polygon does not exist.
//=================================================================================================
occ::handle<Poly_Polygon2D> BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E, const TopoDS_Face& F)
{
TopLoc_Location l;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, l);
TopoDS_Edge aLocalEdge = E;
if (F.Orientation() == TopAbs_REVERSED)
{
aLocalEdge.Reverse();
// return PolygonOnSurface(E,S,l);
}
// return PolygonOnSurface(TopoDS::Edge(E.Reversed()),S,l);
// else
// return PolygonOnSurface(E,S,l);
return PolygonOnSurface(aLocalEdge, S, l);
}
//=================================================================================================
// function : PolygonOnSurface
// purpose : Returns the polygon associated to the edge in the
// parametric space of the surface. Returns a NULL
// handle if this polygon does not exist.
//=================================================================================================
static const occ::handle<Poly_Polygon2D> nullPolygon2D;
occ::handle<Poly_Polygon2D> BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L)
{
TopLoc_Location l = L.Predivided(E.Location());
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnSurface(S, l))
{
if (cr->IsPolygonOnClosedSurface() && Eisreversed)
{
return cr->Polygon2();
}
else
{
return cr->Polygon();
}
}
itcr.Next();
}
return nullPolygon2D;
}
//=================================================================================================
void BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E,
occ::handle<Poly_Polygon2D>& P,
occ::handle<Geom_Surface>& S,
TopLoc_Location& L)
{
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnSurface())
{
const BRep_PolygonOnSurface* PS = static_cast<const BRep_PolygonOnSurface*>(cr.get());
P = PS->Polygon();
S = PS->Surface();
L = E.Location() * PS->Location();
return;
}
itcr.Next();
}
L.Identity();
P.Nullify();
S.Nullify();
}
//=================================================================================================
void BRep_Tool::PolygonOnSurface(const TopoDS_Edge& E,
occ::handle<Poly_Polygon2D>& P,
occ::handle<Geom_Surface>& S,
TopLoc_Location& L,
const int Index)
{
int i = 0;
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnSurface())
{
const BRep_PolygonOnSurface* PS = static_cast<const BRep_PolygonOnSurface*>(cr.get());
i++;
if (i > Index)
{
break;
}
if (i == Index)
{
P = PS->Polygon();
S = PS->Surface();
L = E.Location() * PS->Location();
return;
}
}
itcr.Next();
}
L.Identity();
P.Nullify();
S.Nullify();
}
//=================================================================================================
// function : PolygonOnTriangulation
// purpose : Returns the polygon associated to the edge in the
// parametric space of the face. Returns a NULL
// handle if this polygon does not exist.
//=================================================================================================
static const occ::handle<Poly_PolygonOnTriangulation> nullArray;
const occ::handle<Poly_PolygonOnTriangulation>& BRep_Tool::PolygonOnTriangulation(
const TopoDS_Edge& E,
const occ::handle<Poly_Triangulation>& T,
const TopLoc_Location& L)
{
TopLoc_Location l = L.Predivided(E.Location());
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnTriangulation(T, l))
{
if (cr->IsPolygonOnClosedTriangulation() && Eisreversed)
{
return cr->PolygonOnTriangulation2();
}
else
{
return cr->PolygonOnTriangulation();
}
}
itcr.Next();
}
return nullArray;
}
//=================================================================================================
void BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge& E,
occ::handle<Poly_PolygonOnTriangulation>& P,
occ::handle<Poly_Triangulation>& T,
TopLoc_Location& L)
{
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnTriangulation())
{
const BRep_PolygonOnTriangulation* PT =
static_cast<const BRep_PolygonOnTriangulation*>(cr.get());
P = PT->PolygonOnTriangulation();
T = PT->Triangulation();
L = E.Location() * PT->Location();
return;
}
itcr.Next();
}
L.Identity();
P.Nullify();
T.Nullify();
}
//=================================================================================================
void BRep_Tool::PolygonOnTriangulation(const TopoDS_Edge& E,
occ::handle<Poly_PolygonOnTriangulation>& P,
occ::handle<Poly_Triangulation>& T,
TopLoc_Location& L,
const int Index)
{
int i = 0;
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnTriangulation())
{
const BRep_PolygonOnTriangulation* PT =
static_cast<const BRep_PolygonOnTriangulation*>(cr.get());
i++;
if (i > Index)
{
break;
}
if (i == Index)
{
T = PT->Triangulation();
P = PT->PolygonOnTriangulation();
L = E.Location() * PT->Location();
return;
}
}
itcr.Next();
}
L.Identity();
P.Nullify();
T.Nullify();
}
//=================================================================================================
// function : IsClosed
// purpose : Returns True if <E> has two PCurves in the
// parametric space of <F>. i.e. <F> is on a closed
// surface and <E> is on the closing curve.
//=================================================================================================
bool BRep_Tool::IsClosed(const TopoDS_Edge& E, const TopoDS_Face& F)
{
TopLoc_Location l;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, l);
if (IsClosed(E, S, l))
{
return true;
}
const occ::handle<Poly_Triangulation>& T = BRep_Tool::Triangulation(F, l);
return IsClosed(E, T, l);
}
//=================================================================================================
// function : IsClosed
// purpose : Returns True if <E> has two PCurves in the
// parametric space of <S>. i.e. <S> is a closed
// surface and <E> is on the closing curve.
//=================================================================================================
bool BRep_Tool::IsClosed(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L)
{
// modified by NIZNHY-PKV Fri Oct 17 12:16:58 2008f
if (IsPlane(S))
{
return false;
}
// modified by NIZNHY-PKV Fri Oct 17 12:16:54 2008t
//
TopLoc_Location l = L.Predivided(E.Location());
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface(S, l) && cr->IsCurveOnClosedSurface())
{
return true;
}
itcr.Next();
}
return false;
}
//=================================================================================================
// function : IsClosed
// purpose : Returns True if <E> has two arrays of indices in
// the triangulation <T>.
//=================================================================================================
bool BRep_Tool::IsClosed(const TopoDS_Edge& E,
const occ::handle<Poly_Triangulation>& T,
const TopLoc_Location& L)
{
if (T.IsNull())
{
return false;
}
TopLoc_Location l = L.Predivided(E.Location());
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsPolygonOnTriangulation(T, l) && cr->IsPolygonOnClosedTriangulation())
{
return true;
}
itcr.Next();
}
return false;
}
//=================================================================================================
// function : Tolerance
// purpose : Returns the tolerance for <E>.
//=================================================================================================
double BRep_Tool::Tolerance(const TopoDS_Edge& E)
{
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
double p = TE->Tolerance();
constexpr double pMin = Precision::Confusion();
if (p > pMin)
{
return p;
}
else
{
return pMin;
}
}
//=================================================================================================
// function : SameParameter
// purpose : Returns the SameParameter flag for the edge.
//=================================================================================================
bool BRep_Tool::SameParameter(const TopoDS_Edge& E)
{
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
return TE->SameParameter();
}
//=================================================================================================
// function : SameRange
// purpose : Returns the SameRange flag for the edge.
//=================================================================================================
bool BRep_Tool::SameRange(const TopoDS_Edge& E)
{
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
return TE->SameRange();
}
//=================================================================================================
// function : Degenerated
// purpose : Returns True if the edge is degenerated.
//=================================================================================================
bool BRep_Tool::Degenerated(const TopoDS_Edge& E)
{
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
return TE->Degenerated();
}
//=================================================================================================
void BRep_Tool::Range(const TopoDS_Edge& E, double& First, double& Last)
{
// set the range to all the representations
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurve3D())
{
const BRep_Curve3D* CR = static_cast<const BRep_Curve3D*>(cr.get());
if (!CR->Curve3D().IsNull())
{
First = CR->First();
Last = CR->Last();
return;
}
}
else if (cr->IsCurveOnSurface())
{
const BRep_GCurve* CR = static_cast<const BRep_GCurve*>(cr.get());
First = CR->First();
Last = CR->Last();
return;
}
itcr.Next();
}
First = Last = 0.;
}
//=================================================================================================
void BRep_Tool::Range(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L,
double& First,
double& Last)
{
TopLoc_Location l = L.Predivided(E.Location());
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface(S, l))
{
const BRep_CurveOnSurface* CR = static_cast<const BRep_CurveOnSurface*>(cr.get());
CR->Range(First, Last);
break;
}
itcr.Next();
}
if (!itcr.More())
{
Range(E, First, Last);
}
E.TShape()->Modified(true);
}
//=================================================================================================
void BRep_Tool::Range(const TopoDS_Edge& E, const TopoDS_Face& F, double& First, double& Last)
{
TopLoc_Location L;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, L);
Range(E, S, L, First, Last);
}
//=================================================================================================
void BRep_Tool::UVPoints(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L,
gp_Pnt2d& PFirst,
gp_Pnt2d& PLast)
{
TopLoc_Location l = L.Predivided(E.Location());
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsCurveOnSurface(S, l))
{
if (cr->IsCurveOnClosedSurface() && Eisreversed)
{
const BRep_CurveOnClosedSurface* CR =
static_cast<const BRep_CurveOnClosedSurface*>(cr.get());
CR->UVPoints2(PFirst, PLast);
}
else
{
const BRep_CurveOnSurface* CR = static_cast<const BRep_CurveOnSurface*>(cr.get());
CR->UVPoints(PFirst, PLast);
}
return;
}
itcr.Next();
}
// for planar surface project the vertices
// modif 21-05-97 : for RectangularTrimmedSurface, project the vertices
occ::handle<Geom_Plane> GP;
occ::handle<Geom_RectangularTrimmedSurface> GRTS;
GRTS = occ::down_cast<Geom_RectangularTrimmedSurface>(S);
if (!GRTS.IsNull())
{
GP = occ::down_cast<Geom_Plane>(GRTS->BasisSurface());
}
else
{
GP = occ::down_cast<Geom_Plane>(S);
}
// end of modification from 21-05-97
if (!GP.IsNull())
{
// get the two vertices
TopoDS_Vertex Vf, Vl;
TopExp::Vertices(E, Vf, Vl);
TopLoc_Location Linverted = L.Inverted();
Vf.Move(Linverted, false);
Vl.Move(Linverted, false);
double u, v;
gp_Pln pln = GP->Pln();
u = v = 0.;
if (!Vf.IsNull())
{
gp_Pnt PF = BRep_Tool::Pnt(Vf);
ElSLib::Parameters(pln, PF, u, v);
}
PFirst.SetCoord(u, v);
u = v = 0.;
if (!Vl.IsNull())
{
gp_Pnt PL = BRep_Tool::Pnt(Vl);
ElSLib::Parameters(pln, PL, u, v);
}
PLast.SetCoord(u, v);
}
else
{
PFirst.SetCoord(0., 0.);
PLast.SetCoord(0., 0.);
}
}
//=================================================================================================
void BRep_Tool::UVPoints(const TopoDS_Edge& E,
const TopoDS_Face& F,
gp_Pnt2d& PFirst,
gp_Pnt2d& PLast)
{
TopLoc_Location L;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, L);
TopoDS_Edge aLocalEdge = E;
if (F.Orientation() == TopAbs_REVERSED)
{
aLocalEdge.Reverse();
// UVPoints(E,S,L,PFirst,PLast);
}
// UVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
// else
// UVPoints(E,S,L,PFirst,PLast);
UVPoints(aLocalEdge, S, L, PFirst, PLast);
}
//=================================================================================================
void BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L,
const gp_Pnt2d& PFirst,
const gp_Pnt2d& PLast)
{
TopLoc_Location l = L.Predivided(E.Location());
bool Eisreversed = (E.Orientation() == TopAbs_REVERSED);
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
occ::handle<BRep_CurveRepresentation> cr = itcr.Value();
if (cr->IsCurveOnSurface(S, l))
{
if (cr->IsCurveOnClosedSurface() && Eisreversed)
{
BRep_CurveOnClosedSurface* CS = static_cast<BRep_CurveOnClosedSurface*>(cr.get());
CS->SetUVPoints2(PFirst, PLast);
}
else
{
BRep_CurveOnSurface* CS = static_cast<BRep_CurveOnSurface*>(cr.get());
CS->SetUVPoints(PFirst, PLast);
}
}
itcr.Next();
}
}
//=================================================================================================
void BRep_Tool::SetUVPoints(const TopoDS_Edge& E,
const TopoDS_Face& F,
const gp_Pnt2d& PFirst,
const gp_Pnt2d& PLast)
{
TopLoc_Location L;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, L);
TopoDS_Edge aLocalEdge = E;
if (F.Orientation() == TopAbs_REVERSED)
{
aLocalEdge.Reverse();
// SetUVPoints(TopoDS::Edge(E.Reversed()),S,L,PFirst,PLast);
}
// else
// SetUVPoints(E,S,L,PFirst,PLast);
SetUVPoints(aLocalEdge, S, L, PFirst, PLast);
}
//=================================================================================================
// function : HasContinuity
// purpose : Returns True if the edge is on the surfaces of the
// two faces.
//=================================================================================================
bool BRep_Tool::HasContinuity(const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2)
{
TopLoc_Location l1, l2;
const occ::handle<Geom_Surface>& S1 = BRep_Tool::Surface(F1, l1);
const occ::handle<Geom_Surface>& S2 = BRep_Tool::Surface(F2, l2);
return HasContinuity(E, S1, S2, l1, l2);
}
//=================================================================================================
GeomAbs_Shape BRep_Tool::Continuity(const TopoDS_Edge& E,
const TopoDS_Face& F1,
const TopoDS_Face& F2)
{
TopLoc_Location l1, l2;
const occ::handle<Geom_Surface>& S1 = BRep_Tool::Surface(F1, l1);
const occ::handle<Geom_Surface>& S2 = BRep_Tool::Surface(F2, l2);
return Continuity(E, S1, S2, l1, l2);
}
//=================================================================================================
// function : HasContinuity
// purpose : Returns True if the edge is on the surfaces.
//=================================================================================================
bool BRep_Tool::HasContinuity(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S1,
const occ::handle<Geom_Surface>& S2,
const TopLoc_Location& L1,
const TopLoc_Location& L2)
{
const TopLoc_Location& Eloc = E.Location();
TopLoc_Location l1 = L1.Predivided(Eloc);
TopLoc_Location l2 = L2.Predivided(Eloc);
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsRegularity(S1, S2, l1, l2))
{
return true;
}
itcr.Next();
}
return false;
}
//=================================================================================================
GeomAbs_Shape BRep_Tool::Continuity(const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S1,
const occ::handle<Geom_Surface>& S2,
const TopLoc_Location& L1,
const TopLoc_Location& L2)
{
TopLoc_Location l1 = L1.Predivided(E.Location());
TopLoc_Location l2 = L2.Predivided(E.Location());
// find the representation
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(
(*((occ::handle<BRep_TEdge>*)&E.TShape()))->ChangeCurves());
while (itcr.More())
{
const occ::handle<BRep_CurveRepresentation>& cr = itcr.Value();
if (cr->IsRegularity(S1, S2, l1, l2))
{
return cr->Continuity();
}
itcr.Next();
}
return GeomAbs_C0;
}
//=================================================================================================
// function : HasContinuity
// purpose : Returns True if the edge is on some two surfaces.
//=================================================================================================
bool BRep_Tool::HasContinuity(const TopoDS_Edge& E)
{
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator itcr(TE->Curves());
for (; itcr.More(); itcr.Next())
{
const occ::handle<BRep_CurveRepresentation>& CR = itcr.Value();
if (CR->IsRegularity())
{
return true;
}
}
return false;
}
//=================================================================================================
GeomAbs_Shape BRep_Tool::MaxContinuity(const TopoDS_Edge& theEdge)
{
GeomAbs_Shape aMaxCont = GeomAbs_C0;
for (NCollection_List<occ::handle<BRep_CurveRepresentation>>::Iterator aReprIter(
(*((occ::handle<BRep_TEdge>*)&theEdge.TShape()))->ChangeCurves());
aReprIter.More();
aReprIter.Next())
{
const occ::handle<BRep_CurveRepresentation>& aRepr = aReprIter.Value();
if (aRepr->IsRegularity())
{
const GeomAbs_Shape aCont = aRepr->Continuity();
if ((int)aCont > (int)aMaxCont)
{
aMaxCont = aCont;
}
}
}
return aMaxCont;
}
//=================================================================================================
gp_Pnt BRep_Tool::Pnt(const TopoDS_Vertex& V)
{
const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
if (TV == nullptr)
{
throw Standard_NullObject("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
}
const gp_Pnt& P = TV->Pnt();
if (V.Location().IsIdentity())
{
return P;
}
return P.Transformed(V.Location().Transformation());
}
//=================================================================================================
double BRep_Tool::Tolerance(const TopoDS_Vertex& V)
{
const BRep_TVertex* aTVert = static_cast<const BRep_TVertex*>(V.TShape().get());
if (aTVert == nullptr)
{
throw Standard_NullObject("BRep_Tool:: TopoDS_Vertex hasn't gp_Pnt");
}
double p = aTVert->Tolerance();
constexpr double pMin = Precision::Confusion();
if (p > pMin)
{
return p;
}
else
{
return pMin;
}
}
//=================================================================================================
// function : Parameter
// purpose : Returns the parameter of <V> on <E>.
//=================================================================================================
bool BRep_Tool::Parameter(const TopoDS_Vertex& theV, const TopoDS_Edge& theE, double& theParam)
{
// Search the vertex in the edge
bool rev = false;
TopoDS_Shape VF;
TopAbs_Orientation orient = TopAbs_INTERNAL;
TopoDS_Iterator itv(theE.Oriented(TopAbs_FORWARD));
// if the edge has no vertices
// and is degenerated use the vertex orientation
// RLE, june 94
if (!itv.More() && BRep_Tool::Degenerated(theE))
{
orient = theV.Orientation();
}
while (itv.More())
{
const TopoDS_Shape& Vcur = itv.Value();
if (theV.IsSame(Vcur))
{
if (VF.IsNull())
{
VF = Vcur;
}
else
{
rev = theE.Orientation() == TopAbs_REVERSED;
if (Vcur.Orientation() == theV.Orientation())
{
VF = Vcur;
}
}
}
itv.Next();
}
if (!VF.IsNull())
{
orient = VF.Orientation();
}
double f, l;
if (orient == TopAbs_FORWARD)
{
BRep_Tool::Range(theE, f, l);
theParam = (rev) ? l : f;
return true;
}
else if (orient == TopAbs_REVERSED)
{
BRep_Tool::Range(theE, f, l);
theParam = (rev) ? f : l;
return true;
}
else
{
TopLoc_Location L;
const occ::handle<Geom_Curve>& C = BRep_Tool::Curve(theE, L, f, l);
L = L.Predivided(theV.Location());
if (!C.IsNull() || BRep_Tool::Degenerated(theE))
{
const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(theV.TShape().get());
NCollection_List<occ::handle<BRep_PointRepresentation>>::Iterator itpr(TV->Points());
while (itpr.More())
{
const occ::handle<BRep_PointRepresentation>& pr = itpr.Value();
if (pr->IsPointOnCurve(C, L))
{
double p = pr->Parameter();
double res = p; // SVV 4 nov 99 - to avoid warnings on Linux
if (!C.IsNull())
{
// Closed curves RLE 16 june 94
if (Precision::IsNegativeInfinite(f))
{
theParam = pr->Parameter(); // p;
return true;
};
if (Precision::IsPositiveInfinite(l))
{
theParam = pr->Parameter(); // p;
return true;
}
gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
double tol = BRep_Tool::Tolerance(theV);
if (Pf.Distance(Pl) < tol)
{
if (Pf.Distance(BRep_Tool::Pnt(theV)) < tol)
{
if (theV.Orientation() == TopAbs_FORWARD)
{
res = f; // p = f;
}
else
{
res = l; // p = l;
}
}
}
}
theParam = res; // p;
return true;
}
itpr.Next();
}
}
else
{
// no 3d curve !!
// let us try with the first pcurve
occ::handle<Geom2d_Curve> PC;
occ::handle<Geom_Surface> S;
BRep_Tool::CurveOnSurface(theE, PC, S, L, f, l);
L = L.Predivided(theV.Location());
const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(theV.TShape().get());
NCollection_List<occ::handle<BRep_PointRepresentation>>::Iterator itpr(TV->Points());
while (itpr.More())
{
const occ::handle<BRep_PointRepresentation>& pr = itpr.Value();
if (pr->IsPointOnCurveOnSurface(PC, S, L))
{
double p = pr->Parameter();
// Closed curves RLE 16 june 94
if (PC->IsClosed())
{
if ((p == PC->FirstParameter()) || (p == PC->LastParameter()))
{
if (theV.Orientation() == TopAbs_FORWARD)
{
p = PC->FirstParameter();
}
else
{
p = PC->LastParameter();
}
}
}
theParam = p;
return true;
}
itpr.Next();
}
}
}
return false;
}
//=================================================================================================
// function : Parameter
// purpose : Returns the parameter of <V> on <E>.
//=================================================================================================
double BRep_Tool::Parameter(const TopoDS_Vertex& V, const TopoDS_Edge& E)
{
double p;
if (Parameter(V, E, p))
{
return p;
}
throw Standard_NoSuchObject("BRep_Tool:: no parameter on edge");
}
//=================================================================================================
// function : Parameter
// purpose : Returns the parameters of the vertex on the
// pcurve of the edge on the face.
//=================================================================================================
double BRep_Tool::Parameter(const TopoDS_Vertex& V, const TopoDS_Edge& E, const TopoDS_Face& F)
{
TopLoc_Location L;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, L);
return BRep_Tool::Parameter(V, E, S, L);
}
//=================================================================================================
// function : Parameter
// purpose : Returns the parameters of the vertex on the
// pcurve of the edge on the surface.
//=================================================================================================
double BRep_Tool::Parameter(const TopoDS_Vertex& V,
const TopoDS_Edge& E,
const occ::handle<Geom_Surface>& S,
const TopLoc_Location& L)
{
// Search the vertex in the edge
bool rev = false;
TopoDS_Shape VF;
TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
while (itv.More())
{
if (V.IsSame(itv.Value()))
{
if (VF.IsNull())
{
VF = itv.Value();
}
else
{
rev = E.Orientation() == TopAbs_REVERSED;
if (itv.Value().Orientation() == V.Orientation())
{
VF = itv.Value();
}
}
}
itv.Next();
}
TopAbs_Orientation orient = TopAbs_INTERNAL;
if (!VF.IsNull())
{
orient = VF.Orientation();
}
double f, l;
if (orient == TopAbs_FORWARD)
{
BRep_Tool::Range(E, S, L, f, l);
return (rev) ? l : f;
}
else if (orient == TopAbs_REVERSED)
{
BRep_Tool::Range(E, S, L, f, l);
return (rev) ? f : l;
}
else
{
occ::handle<Geom2d_Curve> PC = BRep_Tool::CurveOnSurface(E, S, L, f, l);
const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
NCollection_List<occ::handle<BRep_PointRepresentation>>::Iterator itpr(TV->Points());
while (itpr.More())
{
if (itpr.Value()->IsPointOnCurveOnSurface(PC, S, L))
{
return itpr.Value()->Parameter();
}
itpr.Next();
}
}
//----------------------------------------------------------
TopLoc_Location L1;
const occ::handle<Geom_Curve>& C = BRep_Tool::Curve(E, L1, f, l);
L1 = L1.Predivided(V.Location());
if (!C.IsNull() || Degenerated(E))
{
const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
NCollection_List<occ::handle<BRep_PointRepresentation>>::Iterator itpr(TV->Points());
while (itpr.More())
{
const occ::handle<BRep_PointRepresentation>& pr = itpr.Value();
if (pr->IsPointOnCurve(C, L1))
{
double p = pr->Parameter();
double res = p;
if (!C.IsNull())
{
// Closed curves RLE 16 june 94
if (Precision::IsNegativeInfinite(f))
{
return res;
}
if (Precision::IsPositiveInfinite(l))
{
return res;
}
gp_Pnt Pf = C->Value(f).Transformed(L1.Transformation());
gp_Pnt Pl = C->Value(l).Transformed(L1.Transformation());
double tol = BRep_Tool::Tolerance(V);
if (Pf.Distance(Pl) < tol)
{
if (Pf.Distance(BRep_Tool::Pnt(V)) < tol)
{
if (V.Orientation() == TopAbs_FORWARD)
{
res = f;
}
else
{
res = l;
}
}
}
}
return res;
}
itpr.Next();
}
}
//----------------------------------------------------------
throw Standard_NoSuchObject("BRep_Tool:: no parameter on edge");
}
//=================================================================================================
// function : Parameters
// purpose : Returns the parameters of the vertex on the face.
//=================================================================================================
gp_Pnt2d BRep_Tool::Parameters(const TopoDS_Vertex& V, const TopoDS_Face& F)
{
TopLoc_Location L;
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F, L);
L = L.Predivided(V.Location());
const BRep_TVertex* TV = static_cast<const BRep_TVertex*>(V.TShape().get());
NCollection_List<occ::handle<BRep_PointRepresentation>>::Iterator itpr(TV->Points());
// It is checked if there is PointRepresentation (case non Manifold)
while (itpr.More())
{
if (itpr.Value()->IsPointOnSurface(S, L))
{
return gp_Pnt2d(itpr.Value()->Parameter(), itpr.Value()->Parameter2());
}
itpr.Next();
}
TopoDS_Vertex Vf, Vl;
TopoDS_Edge E;
// Otherwise the edges are searched (PMN 4/06/97) It is not possible to succeed 999/1000!
// even if often there is a way to make more economically than above...
TopExp_Explorer exp;
for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next())
{
E = TopoDS::Edge(exp.Current());
TopExp::Vertices(E, Vf, Vl);
if ((V.IsSame(Vf)) || (V.IsSame(Vl)))
{
gp_Pnt2d Pf, Pl;
UVPoints(E, F, Pf, Pl);
if (V.IsSame(Vf))
{
return Pf;
}
else
{
return Pl; // Ambiguity (natural) for degenerated edges.
}
}
}
throw Standard_NoSuchObject("BRep_Tool:: no parameters on surface");
}
//=================================================================================================
bool BRep_Tool::IsClosed(const TopoDS_Shape& theShape)
{
if (theShape.ShapeType() == TopAbs_SHELL)
{
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap(101, new NCollection_IncAllocator);
TopExp_Explorer exp(theShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
bool hasBound = false;
for (; exp.More(); exp.Next())
{
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
if (BRep_Tool::Degenerated(E) || E.Orientation() == TopAbs_INTERNAL
|| E.Orientation() == TopAbs_EXTERNAL)
{
continue;
}
hasBound = true;
if (!aMap.Add(E))
{
aMap.Remove(E);
}
}
return hasBound && aMap.IsEmpty();
}
else if (theShape.ShapeType() == TopAbs_WIRE)
{
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap(101, new NCollection_IncAllocator);
TopExp_Explorer exp(theShape.Oriented(TopAbs_FORWARD), TopAbs_VERTEX);
bool hasBound = false;
for (; exp.More(); exp.Next())
{
const TopoDS_Shape& V = exp.Current();
if (V.Orientation() == TopAbs_INTERNAL || V.Orientation() == TopAbs_EXTERNAL)
{
continue;
}
hasBound = true;
if (!aMap.Add(V))
{
aMap.Remove(V);
}
}
return hasBound && aMap.IsEmpty();
}
else if (theShape.ShapeType() == TopAbs_EDGE)
{
TopoDS_Vertex aVFirst, aVLast;
TopExp::Vertices(TopoDS::Edge(theShape), aVFirst, aVLast);
return !aVFirst.IsNull() && aVFirst.IsSame(aVLast);
}
return theShape.Closed();
}
// modified by NIZNHY-PKV Fri Oct 17 14:09:58 2008 f
//=================================================================================================
bool IsPlane(const occ::handle<Geom_Surface>& aS)
{
bool bRet;
occ::handle<Geom_Plane> aGP;
occ::handle<Geom_RectangularTrimmedSurface> aGRTS;
occ::handle<Geom_OffsetSurface> aGOFS;
//
aGRTS = occ::down_cast<Geom_RectangularTrimmedSurface>(aS);
aGOFS = occ::down_cast<Geom_OffsetSurface>(aS);
//
if (!aGOFS.IsNull())
{
aGP = occ::down_cast<Geom_Plane>(aGOFS->BasisSurface());
}
else if (!aGRTS.IsNull())
{
aGP = occ::down_cast<Geom_Plane>(aGRTS->BasisSurface());
}
else
{
aGP = occ::down_cast<Geom_Plane>(aS);
}
//
bRet = !aGP.IsNull();
//
return bRet;
}
//=================================================================================================
double BRep_Tool::MaxTolerance(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theSubShape)
{
double aTol = 0.0;
// Explorer Shape-Subshape.
TopExp_Explorer anExpSS(theShape, theSubShape);
if (theSubShape == TopAbs_FACE)
{
for (; anExpSS.More(); anExpSS.Next())
{
const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
aTol = std::max(aTol, Tolerance(TopoDS::Face(aCurrentSubShape)));
}
}
else if (theSubShape == TopAbs_EDGE)
{
for (; anExpSS.More(); anExpSS.Next())
{
const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
aTol = std::max(aTol, Tolerance(TopoDS::Edge(aCurrentSubShape)));
}
}
else if (theSubShape == TopAbs_VERTEX)
{
for (; anExpSS.More(); anExpSS.Next())
{
const TopoDS_Shape& aCurrentSubShape = anExpSS.Current();
aTol = std::max(aTol, Tolerance(TopoDS::Vertex(aCurrentSubShape)));
}
}
return aTol;
}