mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-18 07:57:31 +08:00
Update empty method guards to new style with regex (see PR). Used clang-format 18.1.8. New actions to validate code formatting is added. Update .clang-format with disabling of include sorting. It is temporary changes, then include will be sorted. Apply formatting for /src and /tools folder. The files with .hxx,.cxx,.lxx,.h,.pxx,.hpp,*.cpp extensions.
964 lines
34 KiB
C++
964 lines
34 KiB
C++
// 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.
|
|
|
|
//: o8 abv 19.02.99: CTS18541.stp #18559: coeff 1.0001 added in CheckVertexTol
|
|
//: p1 abv 22.02.99: protection against edges with no vertices (infinite)
|
|
// szv#4 S4163
|
|
//: s1 abv 22.04.99: PRO7226 #489490: protect against Null 3d curve
|
|
//: s4 abv 26.04.99: sim6049.igs 21677: copy of curve is necessary to get True SP
|
|
// abv 06.05.99: S4137: adding methods GetTangent2d()
|
|
|
|
#include <Adaptor3d_Curve.hxx>
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_GCurve.hxx>
|
|
#include <BRepLib_ValidateEdge.hxx>
|
|
#include <BRep_TEdge.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepAdaptor_Curve.hxx>
|
|
#include <BRepExtrema_DistShapeShape.hxx>
|
|
#include <Extrema_LocateExtPC.hxx>
|
|
#include <GCPnts_AbscissaPoint.hxx>
|
|
#include <Geom2d_Curve.hxx>
|
|
#include <Geom2dAdaptor_Curve.hxx>
|
|
#include <Geom_Curve.hxx>
|
|
#include <Geom2d_TrimmedCurve.hxx>
|
|
#include <Geom_Plane.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
#include <GeomAdaptor_Curve.hxx>
|
|
#include <GeomAdaptor_Surface.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <Precision.hxx>
|
|
#include <ShapeAnalysis_Edge.hxx>
|
|
#include <ShapeExtend.hxx>
|
|
#include <Standard_ErrorHandler.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopLoc_Location.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
|
|
//=================================================================================================
|
|
|
|
ShapeAnalysis_Edge::ShapeAnalysis_Edge()
|
|
{
|
|
myStatus = 0; // ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::BoundUV(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
gp_Pnt2d& first,
|
|
gp_Pnt2d& last) const
|
|
{
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface) S = BRep_Tool::Surface(face, L);
|
|
return BoundUV(edge, S, L, first, last);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::BoundUV(const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& surface,
|
|
const TopLoc_Location& location,
|
|
gp_Pnt2d& first,
|
|
gp_Pnt2d& last) const
|
|
{
|
|
Handle(Geom2d_Curve) c2d;
|
|
Standard_Real uf, ul;
|
|
if (!PCurve(edge, surface, location, c2d, uf, ul))
|
|
return Standard_False;
|
|
first = c2d->Value(uf);
|
|
last = c2d->Value(ul);
|
|
return Standard_True;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::HasCurve3d(const TopoDS_Edge& edge) const
|
|
{
|
|
Standard_Real cf, cl;
|
|
Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, cf, cl);
|
|
return !c3d.IsNull();
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::Curve3d(const TopoDS_Edge& edge,
|
|
Handle(Geom_Curve)& C3d,
|
|
Standard_Real& cf,
|
|
Standard_Real& cl,
|
|
const Standard_Boolean orient) const
|
|
{
|
|
TopLoc_Location L;
|
|
C3d = BRep_Tool::Curve(edge, L, cf, cl);
|
|
if (!C3d.IsNull() && !L.IsIdentity())
|
|
{
|
|
C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L.Transformation()));
|
|
cf = C3d->TransformedParameter(cf, L.Transformation());
|
|
cl = C3d->TransformedParameter(cl, L.Transformation());
|
|
}
|
|
if (orient)
|
|
{
|
|
if (edge.Orientation() == TopAbs_REVERSED)
|
|
{
|
|
Standard_Real tmp = cf;
|
|
cf = cl;
|
|
cl = tmp;
|
|
}
|
|
}
|
|
return !C3d.IsNull();
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::IsClosed3d(const TopoDS_Edge& edge) const
|
|
{
|
|
Standard_Real cf, cl;
|
|
Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, cf, cl);
|
|
if (c3d.IsNull())
|
|
return Standard_False;
|
|
if (!c3d->IsClosed())
|
|
return Standard_False;
|
|
return FirstVertex(edge).IsSame(LastVertex(edge));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::HasPCurve(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face) const
|
|
{
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
return HasPCurve(edge, S, L);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::HasPCurve(const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& surface,
|
|
const TopLoc_Location& location) const
|
|
{
|
|
// try { //szv#4:S4163:12Mar99 waste try
|
|
Standard_Real cf, cl;
|
|
Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(edge, surface, location, cf, cl);
|
|
return !c2d.IsNull();
|
|
/* }
|
|
catch (Standard_Failure) {
|
|
}
|
|
return Standard_False; */
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::PCurve(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
Handle(Geom2d_Curve)& C2d,
|
|
Standard_Real& cf,
|
|
Standard_Real& cl,
|
|
const Standard_Boolean orient) const
|
|
{
|
|
//: abv 20.05.02: take into account face orientation
|
|
// COMMENTED BACK - NEEDS MORE CHANGES IN ALL SHAPEHEALING
|
|
// C2d = BRep_Tool::CurveOnSurface (edge, face, cf, cl);
|
|
// if (orient && edge.Orientation() == TopAbs_REVERSED) {
|
|
// Standard_Real tmp = cf; cf = cl; cl = tmp;
|
|
// }
|
|
// return !C2d.IsNull();
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
return PCurve(edge, S, L, C2d, cf, cl, orient);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::PCurve(const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& surface,
|
|
const TopLoc_Location& location,
|
|
Handle(Geom2d_Curve)& C2d,
|
|
Standard_Real& cf,
|
|
Standard_Real& cl,
|
|
const Standard_Boolean orient) const
|
|
{
|
|
C2d = BRep_Tool::CurveOnSurface(edge, surface, location, cf, cl);
|
|
if (orient && edge.Orientation() == TopAbs_REVERSED)
|
|
{
|
|
Standard_Real tmp = cf;
|
|
cf = cl;
|
|
cl = tmp;
|
|
}
|
|
return !C2d.IsNull();
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::IsSeam(const TopoDS_Edge& edge, const TopoDS_Face& face) const
|
|
{
|
|
return BRep_Tool::IsClosed(edge, face);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::IsSeam(const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& surface,
|
|
const TopLoc_Location& location) const
|
|
{
|
|
return BRep_Tool::IsClosed(edge, surface, location);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
TopoDS_Vertex ShapeAnalysis_Edge::FirstVertex(const TopoDS_Edge& edge) const
|
|
{
|
|
TopoDS_Vertex V;
|
|
if (edge.Orientation() == TopAbs_REVERSED)
|
|
{
|
|
V = TopExp::LastVertex(edge);
|
|
V.Reverse();
|
|
}
|
|
else
|
|
{
|
|
V = TopExp::FirstVertex(edge);
|
|
}
|
|
return V;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
TopoDS_Vertex ShapeAnalysis_Edge::LastVertex(const TopoDS_Edge& edge) const
|
|
{
|
|
TopoDS_Vertex V;
|
|
if (edge.Orientation() == TopAbs_REVERSED)
|
|
{
|
|
V = TopExp::FirstVertex(edge);
|
|
V.Reverse();
|
|
}
|
|
else
|
|
{
|
|
V = TopExp::LastVertex(edge);
|
|
}
|
|
return V;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::Status(const ShapeExtend_Status Status) const
|
|
{
|
|
return ShapeExtend::DecodeStatus(myStatus, Status);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d(
|
|
const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
const Standard_Boolean atend1, /* skl : change "atend" to "atend1" */
|
|
gp_Pnt2d& pnt,
|
|
gp_Vec2d& v,
|
|
const Standard_Real dparam) const
|
|
{
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface) S = BRep_Tool::Surface(face, L);
|
|
return GetEndTangent2d(edge, S, L, atend1, pnt, v, dparam);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d(
|
|
const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& S,
|
|
const TopLoc_Location& L,
|
|
const Standard_Boolean atend2, /* skl : change "atend" to "atend2" */
|
|
gp_Pnt2d& pnt,
|
|
gp_Vec2d& v,
|
|
const Standard_Real dparam) const
|
|
{
|
|
Standard_Real cf, cl;
|
|
Handle(Geom2d_Curve) c2d;
|
|
if (!PCurve(edge, S, L, c2d, cf, cl))
|
|
{
|
|
v = gp_Vec2d(0, 0);
|
|
return Standard_False;
|
|
}
|
|
Standard_Real dpnew = dparam;
|
|
|
|
if (dpnew > Precision::Confusion())
|
|
{
|
|
gp_Pnt2d ptmp;
|
|
Standard_Real par1, par2, delta = (cl - cf) * dpnew;
|
|
if (Abs(delta) < Precision::PConfusion())
|
|
{
|
|
dpnew = 0.0;
|
|
}
|
|
else
|
|
{
|
|
if (atend2)
|
|
{
|
|
par1 = cl;
|
|
par2 = cl - delta;
|
|
c2d->D0(par1, pnt);
|
|
c2d->D0(par2, ptmp);
|
|
v = pnt.XY() - ptmp.XY();
|
|
}
|
|
else
|
|
{
|
|
par1 = cf;
|
|
par2 = cf + delta;
|
|
c2d->D0(par1, pnt);
|
|
c2d->D0(par2, ptmp);
|
|
v = ptmp.XY() - pnt.XY();
|
|
}
|
|
if (v.SquareMagnitude() < Precision::PConfusion() * Precision::PConfusion())
|
|
{
|
|
dpnew = 0.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dpnew <= Precision::Confusion())
|
|
{
|
|
// get non-null tangency searching until 3rd derivative, or as straight btw ends
|
|
Standard_Real par = (atend2 ? cl : cf);
|
|
c2d->D1(par, pnt, v);
|
|
if (v.SquareMagnitude() < Precision::PConfusion() * Precision::PConfusion())
|
|
{
|
|
gp_Vec2d d1;
|
|
c2d->D2(par, pnt, d1, v);
|
|
if (v.SquareMagnitude() < Precision::PConfusion() * Precision::PConfusion())
|
|
{
|
|
gp_Vec2d d2;
|
|
c2d->D3(par, pnt, d1, d2, v);
|
|
if (v.SquareMagnitude() < Precision::PConfusion() * Precision::PConfusion())
|
|
{
|
|
gp_Pnt2d p2;
|
|
c2d->D0((atend2 ? cf : cl), p2);
|
|
v = p2.XY() - pnt.XY();
|
|
if (v.SquareMagnitude() < Precision::PConfusion() * Precision::PConfusion())
|
|
return Standard_False;
|
|
}
|
|
}
|
|
}
|
|
if (edge.Orientation() == TopAbs_REVERSED)
|
|
v.Reverse();
|
|
}
|
|
|
|
// if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
|
|
return Standard_True;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face)
|
|
{
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
return CheckCurve3dWithPCurve(edge, S, L);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve(const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& surface,
|
|
const TopLoc_Location& location)
|
|
{
|
|
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
|
|
|
if (surface->IsKind(STANDARD_TYPE(Geom_Plane)))
|
|
return Standard_False;
|
|
|
|
Handle(Geom2d_Curve) c2d;
|
|
Standard_Real f2d, l2d; // szv#4:S4163:12Mar99 moved down f3d, l3d
|
|
if (!PCurve(edge, surface, location, c2d, f2d, l2d, Standard_False))
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
|
return Standard_False;
|
|
}
|
|
|
|
Handle(Geom_Curve) c3d; // szv#4:S4163:12Mar99 moved
|
|
Standard_Real f3d, l3d; // szv#4:S4163:12Mar99 moved
|
|
if (!Curve3d(edge, c3d, f3d, l3d, Standard_False))
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
|
|
return Standard_False;
|
|
}
|
|
|
|
TopoDS_Vertex aFirstVert = FirstVertex(edge);
|
|
TopoDS_Vertex aLastVert = LastVertex(edge);
|
|
|
|
if (aFirstVert.IsNull() || aLastVert.IsNull())
|
|
return Standard_False;
|
|
|
|
Standard_Real preci1 = BRep_Tool::Tolerance(aFirstVert), preci2 = BRep_Tool::Tolerance(aLastVert);
|
|
|
|
gp_Pnt2d p2d1 = c2d->Value(f2d), p2d2 = c2d->Value(l2d);
|
|
|
|
// #39 rln 17.11.98 S4054, annie_surf.igs entity 39
|
|
return CheckPoints(c3d->Value(f3d) /*.Transformed (location.Transformation())*/,
|
|
c3d->Value(l3d) /*.Transformed (location.Transformation())*/,
|
|
surface->Value(p2d1.X(), p2d1.Y()).Transformed(location.Transformation()),
|
|
surface->Value(p2d2.X(), p2d2.Y()).Transformed(location.Transformation()),
|
|
preci1,
|
|
preci2);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckPoints(const gp_Pnt& P1A,
|
|
const gp_Pnt& P1B,
|
|
const gp_Pnt& P2A,
|
|
const gp_Pnt& P2B,
|
|
const Standard_Real preci1,
|
|
const Standard_Real preci2)
|
|
{
|
|
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
|
if (P1A.SquareDistance(P2A) <= preci1 * preci1 && P1B.SquareDistance(P2B) <= preci2 * preci2)
|
|
return Standard_False;
|
|
else if (P1A.Distance(P2B) + (P1B.Distance(P2A)) < P1A.Distance(P2A) + (P1B.Distance(P2B)))
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
|
|
return Standard_True;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithCurve3d(const TopoDS_Edge& edge,
|
|
const Standard_Real preci,
|
|
const Standard_Integer vtx)
|
|
{
|
|
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
|
|
|
TopoDS_Vertex V1 = FirstVertex(edge);
|
|
TopoDS_Vertex V2 = LastVertex(edge);
|
|
gp_Pnt p1v = BRep_Tool::Pnt(V1);
|
|
gp_Pnt p2v = BRep_Tool::Pnt(V2);
|
|
|
|
Standard_Real cf, cl;
|
|
Handle(Geom_Curve) c3d;
|
|
if (!Curve3d(edge, c3d, cf, cl))
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
|
return Standard_False;
|
|
}
|
|
|
|
// on va faire les checks ...
|
|
if (vtx != 2)
|
|
{
|
|
// 1er VTX
|
|
gp_Pnt p13d = c3d->Value(cf);
|
|
// szv#4:S4163:12Mar99 optimized
|
|
if (p1v.Distance(p13d) > (preci < 0 ? BRep_Tool::Tolerance(V1) : preci))
|
|
myStatus |= ShapeExtend_DONE1;
|
|
}
|
|
|
|
if (vtx != 1)
|
|
{
|
|
// 2me VTX
|
|
gp_Pnt p23d = c3d->Value(cl);
|
|
// szv#4:S4163:12Mar99 optimized
|
|
if (p2v.Distance(p23d) > (preci < 0 ? BRep_Tool::Tolerance(V2) : preci))
|
|
myStatus |= ShapeExtend_DONE2;
|
|
}
|
|
|
|
return Status(ShapeExtend_DONE);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
const Standard_Real preci,
|
|
const Standard_Integer vtx)
|
|
{
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
// clang-format off
|
|
return CheckVerticesWithPCurve (edge, S, L, preci, vtx); //szv#4:S4163:12Mar99 `vtx,preci` wrong parameters order
|
|
// clang-format on
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve(const TopoDS_Edge& edge,
|
|
const Handle(Geom_Surface)& surf,
|
|
const TopLoc_Location& loc,
|
|
const Standard_Real preci,
|
|
const Standard_Integer vtx)
|
|
{
|
|
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
|
|
|
TopoDS_Vertex V1 = FirstVertex(edge);
|
|
TopoDS_Vertex V2 = LastVertex(edge);
|
|
gp_Pnt p1v = BRep_Tool::Pnt(V1);
|
|
gp_Pnt p2v = BRep_Tool::Pnt(V2);
|
|
|
|
Standard_Real cf, cl;
|
|
Handle(Geom2d_Curve) c2d;
|
|
if (!PCurve(edge, surf, loc, c2d, cf, cl))
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
|
return Standard_False;
|
|
}
|
|
|
|
// on va faire les checks ...
|
|
if (vtx != 2)
|
|
{ // 1er VTX
|
|
gp_Pnt2d p1uv = c2d->Value(cf);
|
|
gp_Pnt p12d = surf->Value(p1uv.X(), p1uv.Y());
|
|
if (!loc.IsIdentity())
|
|
p12d.Transform(loc.Transformation());
|
|
// szv#4:S4163:12Mar99 optimized
|
|
if (p1v.Distance(p12d) > (preci < 0 ? BRep_Tool::Tolerance(V1) : preci))
|
|
myStatus |= ShapeExtend_DONE1;
|
|
}
|
|
|
|
if (vtx != 1)
|
|
{ // 2me VTX
|
|
gp_Pnt2d p2uv = c2d->Value(cl);
|
|
gp_Pnt p22d = surf->Value(p2uv.X(), p2uv.Y());
|
|
if (!loc.IsIdentity())
|
|
p22d.Transform(loc.Transformation());
|
|
// szv#4:S4163:12Mar99 optimized
|
|
if (p2v.Distance(p22d) > (preci < 0 ? BRep_Tool::Tolerance(V2) : preci))
|
|
myStatus |= ShapeExtend_DONE2;
|
|
}
|
|
|
|
return Status(ShapeExtend_DONE);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static Standard_Integer CheckVertexTolerance(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
const Standard_Boolean checkAll,
|
|
Standard_Real& toler1,
|
|
Standard_Real& toler2)
|
|
{
|
|
Standard_Integer Status = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
|
|
|
ShapeAnalysis_Edge sae;
|
|
TopoDS_Vertex V1 = sae.FirstVertex(edge);
|
|
TopoDS_Vertex V2 = sae.LastVertex(edge);
|
|
if (V1.IsNull() || V2.IsNull())
|
|
{ //: p1 abv 22 Feb 99: r76sy.stp
|
|
Status |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
|
return Status;
|
|
}
|
|
|
|
Standard_Real old1 = BRep_Tool::Tolerance(V1);
|
|
Standard_Real old2 = BRep_Tool::Tolerance(V2);
|
|
gp_Pnt pnt1 = BRep_Tool::Pnt(V1);
|
|
gp_Pnt pnt2 = BRep_Tool::Pnt(V2);
|
|
|
|
Standard_Real a, b;
|
|
Handle(Geom_Curve) c3d;
|
|
if (!sae.Curve3d(edge, c3d, a, b, Standard_True))
|
|
{
|
|
if (!BRep_Tool::Degenerated(edge))
|
|
Status |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
|
|
toler1 = toler2 = 0.;
|
|
// return Standard_False;
|
|
}
|
|
else
|
|
{
|
|
toler1 = pnt1.SquareDistance(c3d->Value(a));
|
|
toler2 = pnt2.SquareDistance(c3d->Value(b));
|
|
}
|
|
|
|
if (checkAll)
|
|
{
|
|
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
|
|
for (BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); itcr.More(); itcr.Next())
|
|
{
|
|
Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
|
|
if (GC.IsNull() || !GC->IsCurveOnSurface())
|
|
continue;
|
|
Handle(Geom2d_Curve) pcurve;
|
|
Handle(Geom_Surface) S = GC->Surface();
|
|
TopLoc_Location L = edge.Location() * GC->Location();
|
|
sae.PCurve(edge, S, L, pcurve, a, b, Standard_True);
|
|
gp_Pnt2d p1 = pcurve->Value(a);
|
|
gp_Pnt2d p2 = pcurve->Value(b);
|
|
gp_Pnt P1 = S->Value(p1.X(), p1.Y()).Transformed(L.Transformation());
|
|
gp_Pnt P2 = S->Value(p2.X(), p2.Y()).Transformed(L.Transformation());
|
|
toler1 = Max(toler1, pnt1.SquareDistance(P1));
|
|
toler2 = Max(toler2, pnt2.SquareDistance(P2));
|
|
}
|
|
}
|
|
//: abv 10.06.02: porting C40 -> dev (CC670-12608.stp)
|
|
// Check with given face is needed for plane surfaces (if no stored pcurves)
|
|
else if (!face.IsNull())
|
|
{
|
|
Handle(Geom2d_Curve) pcurve;
|
|
TopLoc_Location L;
|
|
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
|
if (sae.PCurve(edge, S, L, pcurve, a, b, Standard_True))
|
|
{
|
|
gp_Pnt2d p1 = pcurve->Value(a);
|
|
gp_Pnt2d p2 = pcurve->Value(b);
|
|
gp_Pnt P1 = S->Value(p1.X(), p1.Y()).Transformed(L.Transformation());
|
|
gp_Pnt P2 = S->Value(p2.X(), p2.Y()).Transformed(L.Transformation());
|
|
toler1 = Max(toler1, pnt1.SquareDistance(P1));
|
|
toler2 = Max(toler2, pnt2.SquareDistance(P2));
|
|
}
|
|
else
|
|
Status |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL3);
|
|
}
|
|
|
|
//: o8 abv 19 Feb 99: CTS18541.stp #18559: coeff 1.0001 added
|
|
// szv 18 Aug 99: edge tolerance is taken in consideration
|
|
Standard_Real tole = BRep_Tool::Tolerance(edge);
|
|
toler1 = Max(1.0000001 * Sqrt(toler1), tole);
|
|
toler2 = Max(1.0000001 * Sqrt(toler2), tole);
|
|
if (toler1 > old1)
|
|
Status |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
|
|
if (toler2 > old2)
|
|
Status |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
|
|
|
|
return Status;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
Standard_Real& toler1,
|
|
Standard_Real& toler2)
|
|
{
|
|
myStatus = ::CheckVertexTolerance(edge, face, Standard_False, toler1, toler2);
|
|
return Status(ShapeExtend_DONE);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
|
|
Standard_Real& toler1,
|
|
Standard_Real& toler2)
|
|
{
|
|
TopoDS_Face F;
|
|
myStatus = ::CheckVertexTolerance(edge, F, Standard_True, toler1, toler2);
|
|
return Status(ShapeExtend_DONE);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter(const TopoDS_Edge& edge,
|
|
Standard_Real& maxdev,
|
|
const Standard_Integer NbControl)
|
|
{
|
|
TopoDS_Face anEmptyFace;
|
|
return CheckSameParameter(edge, anEmptyFace, maxdev, NbControl);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter(const TopoDS_Edge& edge,
|
|
const TopoDS_Face& face,
|
|
Standard_Real& maxdev,
|
|
const Standard_Integer NbControl)
|
|
{
|
|
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
|
if (BRep_Tool::Degenerated(edge))
|
|
return Standard_False;
|
|
|
|
maxdev = 0;
|
|
|
|
// Get same parameter flag
|
|
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
|
|
Standard_Boolean SameParameter = TE->SameParameter();
|
|
|
|
// Get 3D curve of the edge
|
|
Standard_Real aFirst, aLast;
|
|
TopLoc_Location aCurveLoc;
|
|
Handle(Geom_Curve) aC3D = BRep_Tool::Curve(edge, aCurveLoc, aFirst, aLast);
|
|
if (aC3D.IsNull())
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
|
return Standard_False;
|
|
}
|
|
|
|
if (!aCurveLoc.IsIdentity())
|
|
{
|
|
const gp_Trsf& aTrsf = aCurveLoc.Transformation();
|
|
aC3D = Handle(Geom_Curve)::DownCast(aC3D->Transformed(aTrsf));
|
|
aFirst = aC3D->TransformedParameter(aFirst, aTrsf);
|
|
aLast = aC3D->TransformedParameter(aLast, aTrsf);
|
|
}
|
|
|
|
// Create adaptor for the curve
|
|
Handle(GeomAdaptor_Curve) aGAC = new GeomAdaptor_Curve(aC3D, aFirst, aLast);
|
|
|
|
Handle(Geom_Surface) aFaceSurf;
|
|
TopLoc_Location aFaceLoc;
|
|
if (!face.IsNull())
|
|
aFaceSurf = BRep_Tool::Surface(face, aFaceLoc);
|
|
|
|
Standard_Boolean IsPCurveFound = Standard_False;
|
|
Standard_Integer i = 1;
|
|
|
|
// Iterate on all curve representations
|
|
for (;;)
|
|
{
|
|
Handle(Geom2d_Curve) aPC;
|
|
Handle(Geom_Surface) aS;
|
|
TopLoc_Location aLoc;
|
|
Standard_Real f, l;
|
|
|
|
BRep_Tool::CurveOnSurface(edge, aPC, aS, aLoc, f, l, i);
|
|
|
|
if (aPC.IsNull())
|
|
// No more curves
|
|
break;
|
|
|
|
++i;
|
|
|
|
// If the input face is not null, check that the curve is on its surface
|
|
if (!aFaceSurf.IsNull())
|
|
{
|
|
if (aFaceSurf != aS || aFaceLoc != aLoc)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
IsPCurveFound = Standard_True;
|
|
|
|
// Apply transformations for the surface
|
|
Handle(Geom_Surface) aST =
|
|
Handle(Geom_Surface)::DownCast(aS->Transformed(aLoc.Transformation()));
|
|
|
|
// Compute deviation between curves
|
|
Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(aPC, f, l);
|
|
Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST);
|
|
|
|
Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS);
|
|
|
|
BRepLib_ValidateEdge aValidateEdge(aGAC, ACS, SameParameter);
|
|
aValidateEdge.SetControlPointsNumber(NbControl - 1);
|
|
aValidateEdge.Process();
|
|
aValidateEdge.UpdateTolerance(maxdev);
|
|
if (!aValidateEdge.IsDone())
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
|
|
}
|
|
}
|
|
|
|
// For the planar face and non-existing 2d curve
|
|
// check the deviation for the projection of the 3d curve on plane
|
|
if (!IsPCurveFound && !aFaceSurf.IsNull())
|
|
{
|
|
Standard_Real f, l;
|
|
Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnPlane(edge, aFaceSurf, aFaceLoc, f, l);
|
|
if (!aPC.IsNull())
|
|
{
|
|
Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(aPC, aFirst, aLast);
|
|
|
|
Handle(Geom_Surface) aST =
|
|
Handle(Geom_Surface)::DownCast(aFaceSurf->Transformed(aFaceLoc.Transformation()));
|
|
Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST);
|
|
|
|
Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS);
|
|
|
|
BRepLib_ValidateEdge aValidateEdgeOnPlane(aGAC, ACS, SameParameter);
|
|
aValidateEdgeOnPlane.SetControlPointsNumber(NbControl - 1);
|
|
aValidateEdgeOnPlane.Process();
|
|
aValidateEdgeOnPlane.UpdateTolerance(maxdev);
|
|
if (!aValidateEdgeOnPlane.IsDone())
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (maxdev > TE->Tolerance())
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
|
|
if (!SameParameter)
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
|
|
|
|
return Status(ShapeExtend_DONE);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge,
|
|
const TopoDS_Edge& theSecEdge,
|
|
const Standard_Real& theTolerance,
|
|
const Standard_Real& theStep,
|
|
const Standard_Real& theStartLength,
|
|
const Standard_Real& theEndLength)
|
|
{
|
|
TColStd_SequenceOfInteger aSeqIntervals;
|
|
BRepAdaptor_Curve aAdCurve1(theFirstEdge);
|
|
|
|
BRepExtrema_DistShapeShape aMinDist;
|
|
aMinDist.LoadS1(theSecEdge);
|
|
|
|
for (Standard_Real aS = theStartLength; aS <= theEndLength; aS += theStep / 2)
|
|
{
|
|
|
|
gp_Pnt aPoint;
|
|
if (aS <= Precision::Confusion())
|
|
{
|
|
TopoDS_Vertex V1 = TopExp::FirstVertex(theFirstEdge, Standard_True);
|
|
aPoint = BRep_Tool::Pnt(V1);
|
|
}
|
|
else
|
|
{
|
|
GCPnts_AbscissaPoint aAbsPoint(Precision::Confusion(),
|
|
aAdCurve1,
|
|
aS,
|
|
aAdCurve1.FirstParameter());
|
|
if (aAbsPoint.IsDone())
|
|
aAdCurve1.D0(aAbsPoint.Parameter(), aPoint);
|
|
else
|
|
continue;
|
|
}
|
|
BRep_Builder aB;
|
|
TopoDS_Vertex aV;
|
|
aB.MakeVertex(aV, aPoint, Precision::Confusion());
|
|
aMinDist.LoadS2(aV);
|
|
aMinDist.Perform();
|
|
if (aMinDist.IsDone() && aMinDist.Value() >= theTolerance)
|
|
return Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckOverlapping(const TopoDS_Edge& theEdge1,
|
|
const TopoDS_Edge& theEdge2,
|
|
Standard_Real& theTolOverlap,
|
|
const Standard_Real theDomainDist)
|
|
{
|
|
Standard_Boolean isOverlap = Standard_False;
|
|
BRepAdaptor_Curve aAdCurve1(theEdge1);
|
|
Standard_Real aLength1 = GCPnts_AbscissaPoint::Length(aAdCurve1);
|
|
BRepAdaptor_Curve aAdCurve2(theEdge2);
|
|
Standard_Real aLength2 = GCPnts_AbscissaPoint::Length(aAdCurve2);
|
|
TopoDS_Edge aFirstEdge = (aLength1 >= aLength2 ? theEdge2 : theEdge1);
|
|
TopoDS_Edge aSecEdge = (aLength1 >= aLength2 ? theEdge1 : theEdge2);
|
|
Standard_Real aLength = Min(aLength1, aLength2);
|
|
|
|
// check overalpping between edges on whole edges
|
|
Standard_Real aStep = Min(aLength1, aLength2) / 2;
|
|
isOverlap =
|
|
IsOverlapPartEdges(aFirstEdge, aSecEdge, theTolOverlap, aStep, 0., Min(aLength1, aLength2));
|
|
|
|
if (isOverlap)
|
|
{
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3);
|
|
return isOverlap;
|
|
}
|
|
if (theDomainDist == 0.0)
|
|
return isOverlap;
|
|
|
|
// check overalpping between edges on segment with length less than theDomainDist
|
|
|
|
Standard_Real aDomainTol =
|
|
(theDomainDist > Min(aLength1, aLength2) ? Min(aLength1, aLength2) : theDomainDist);
|
|
BRepExtrema_DistShapeShape aMinDist(aFirstEdge, aSecEdge, theTolOverlap);
|
|
Standard_Real aresTol = theTolOverlap;
|
|
if (aMinDist.IsDone())
|
|
{
|
|
aresTol = aMinDist.Value();
|
|
if (aresTol >= theTolOverlap)
|
|
return Standard_False;
|
|
Standard_Integer NbSol = aMinDist.NbSolution();
|
|
for (Standard_Integer i = 1; i <= NbSol && !isOverlap; i++)
|
|
{
|
|
BRepExtrema_SupportType aType1 = aMinDist.SupportTypeShape1(i);
|
|
Standard_Real aEndLength, aStartLength, aLengthP;
|
|
if (aType1 == BRepExtrema_IsVertex)
|
|
{
|
|
TopoDS_Shape aSupportShape1 = aMinDist.SupportOnShape1(i);
|
|
TopoDS_Vertex aV1, aV2;
|
|
TopExp::Vertices(aFirstEdge, aV1, aV2, Standard_True);
|
|
if (aV1.IsSame(aSupportShape1))
|
|
aLengthP = 0.0;
|
|
else
|
|
aLengthP = aLength;
|
|
}
|
|
else if (aType1 == BRepExtrema_IsOnEdge)
|
|
{
|
|
Standard_Real aParam1, aFirst, aLast;
|
|
aMinDist.ParOnEdgeS1(i, aParam1);
|
|
BRep_Tool::Range(aFirstEdge, aFirst, aLast);
|
|
BRepAdaptor_Curve anAdaptor(aFirstEdge);
|
|
aLengthP = GCPnts_AbscissaPoint::Length(anAdaptor, aFirst, aParam1);
|
|
}
|
|
else
|
|
continue;
|
|
aStartLength = aLengthP - aDomainTol / 2;
|
|
if (aStartLength < 0.0)
|
|
{
|
|
aStartLength = 0;
|
|
aEndLength = aDomainTol;
|
|
}
|
|
aEndLength = aLengthP + aDomainTol / 2;
|
|
if (aEndLength > aLength)
|
|
{
|
|
aEndLength = aLength;
|
|
aStartLength = aEndLength - aDomainTol;
|
|
}
|
|
aStep = (aEndLength - aStartLength) / 5;
|
|
isOverlap =
|
|
(IsOverlapPartEdges(aFirstEdge, aSecEdge, theTolOverlap, aStep, aStartLength, aEndLength));
|
|
}
|
|
}
|
|
if (isOverlap)
|
|
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE4);
|
|
|
|
theTolOverlap = aresTol;
|
|
return isOverlap;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean ShapeAnalysis_Edge::CheckPCurveRange(const Standard_Real theFirst,
|
|
const Standard_Real theLast,
|
|
const Handle(Geom2d_Curve)& thePC)
|
|
{
|
|
constexpr Standard_Real eps = Precision::PConfusion();
|
|
Standard_Boolean isValid = Standard_True;
|
|
Standard_Boolean IsPeriodic = thePC->IsPeriodic();
|
|
Standard_Real aPeriod = RealLast();
|
|
if (IsPeriodic)
|
|
{
|
|
aPeriod = thePC->Period();
|
|
}
|
|
Standard_Real fp = thePC->FirstParameter(), lp = thePC->LastParameter();
|
|
if (thePC->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
|
|
{
|
|
const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast(thePC)->BasisCurve();
|
|
fp = aC->FirstParameter();
|
|
lp = aC->LastParameter();
|
|
IsPeriodic = aC->IsPeriodic();
|
|
if (IsPeriodic)
|
|
{
|
|
aPeriod = aC->Period();
|
|
}
|
|
}
|
|
if (IsPeriodic && (theLast - theFirst > aPeriod + eps))
|
|
{
|
|
isValid = Standard_False;
|
|
}
|
|
else if (!IsPeriodic && (theFirst < fp - eps || theLast > lp + eps))
|
|
{
|
|
isValid = Standard_False;
|
|
}
|
|
|
|
return isValid;
|
|
}
|