1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0028995: UnifySameDomain produces invalid shape

Synchronization of the ShapeAnalysis_Edge behavior with the BRepCheck_Edge by adding check for 2d curves on planes.

Implementation of the BRep_Tool::CurveOnPlane method to avoid code duplication for making PCurve of the edge on planar face.
This commit is contained in:
emv
2017-08-18 13:31:57 +03:00
committed by bugmaster
parent 2f690078d7
commit cc77a38d94
8 changed files with 207 additions and 147 deletions

View File

@@ -321,8 +321,23 @@ Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
itcr.Next();
}
// for planar surface and 3d curve try a projection
// modif 21-05-97 : for RectangularTrimmedSurface, try a projection
// Curve is not found. Try projection on plane
return CurveOnPlane(E, S, L, First, Last);
}
//=======================================================================
//function : CurveOnPlane
//purpose : For planar surface returns projection of the edge on the plane
//=======================================================================
Handle(Geom2d_Curve) BRep_Tool::CurveOnPlane(const TopoDS_Edge& E,
const Handle(Geom_Surface)& S,
const TopLoc_Location& L,
Standard_Real& First,
Standard_Real& Last)
{
First = Last = 0.;
// Check if the surface is planar
Handle(Geom_Plane) GP;
Handle(Geom_RectangularTrimmedSurface) GRTS;
GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
@@ -330,64 +345,51 @@ Handle(Geom2d_Curve) BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
else
GP = Handle(Geom_Plane)::DownCast(S);
//fin modif du 21-05-97
if (!GP.IsNull())
if (GP.IsNull())
// not a plane
return nullPCurve;
// Check existence of 3d curve in edge
Standard_Real f, l;
TopLoc_Location aCurveLocation;
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())
{
Handle(GeomAdaptor_HCurve) HC;
Handle(GeomAdaptor_HSurface) HS;
HC = new GeomAdaptor_HCurve();
HS = new GeomAdaptor_HSurface();
TopLoc_Location aCurveLocation;
Standard_Real f, l;// for those who call with (u,u).
Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, aCurveLocation, f, l);
if (C3d.IsNull())
{
First = Last = 0.;
return nullPCurve;
}
aCurveLocation = aCurveLocation.Predivided(L);
First = f; Last = l; //Range of edge must not be modified
if (!aCurveLocation.IsIdentity())
{
const gp_Trsf& T = aCurveLocation.Transformation();
Handle(Geom_Geometry) GC3d = C3d->Transformed(T);
C3d = Handle(Geom_Curve)::DownCast (GC3d);
f = C3d->TransformedParameter(f, T);
l = C3d->TransformedParameter(l, T);
}
GeomAdaptor_Surface& GAS = HS->ChangeSurface();
GAS.Load(GP);
Handle(Geom_Curve) ProjOnPlane =
GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l,Standard_True,Standard_False),
GP,
GP->Position().Direction(),
Standard_True);
GeomAdaptor_Curve& GAC = HC->ChangeCurve();
GAC.Load(ProjOnPlane);
ProjLib_ProjectedCurve Proj(HS,HC);
Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
Handle(Geom2d_TrimmedCurve) TC =
Handle(Geom2d_TrimmedCurve)::DownCast (pc);
pc = TC->BasisCurve();
}
return pc;
const gp_Trsf& aTrsf = aCurveLocation.Transformation();
C3D = Handle(Geom_Curve)::DownCast(C3D->Transformed(aTrsf));
f = C3D->TransformedParameter(f, aTrsf);
l = C3D->TransformedParameter(l, aTrsf);
}
First = Last = 0.;
return nullPCurve;
// Perform projection
Handle(Geom_Curve) ProjOnPlane =
GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3D, f, l, Standard_True, Standard_False),
GP,
GP->Position().Direction(),
Standard_True);
Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(GP);
Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(ProjOnPlane);
ProjLib_ProjectedCurve Proj(HS, HC);
Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(pc);
pc = TC->BasisCurve();
}
return pc;
}
//=======================================================================
@@ -438,35 +440,34 @@ void BRep_Tool::CurveOnSurface(const TopoDS_Edge& E,
Standard_Real& Last,
const Standard_Integer Index)
{
Standard_Integer i = 0;
Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
if (Index < 1)
return;
Standard_Integer i = 0;
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
while (itcr.More()) {
for (; itcr.More(); itcr.Next())
{
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
if (cr->IsCurveOnSurface()) {
if (cr->IsCurveOnSurface())
{
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
i++;
if (i > Index) break;
if (i == Index) {
// JMB le 21 Mai 1999
// it is done as in the other CurveOnSurface methods, ie. take into account
// the orientation in case of cut edges (return PCurve2)
// otherwise there is a risk to loop curves or to not get the prover one.
if (GC->IsCurveOnClosedSurface() && Eisreversed)
C = GC->PCurve2();
else
C = GC->PCurve();
S = GC->Surface();
L = E.Location() * GC->Location();
GC->Range(First,Last);
return;
}
++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;
}
itcr.Next();
}
C.Nullify();

View File

@@ -103,6 +103,16 @@ public:
//! handle if this curve does not exist. Returns in
//! <First> and <Last> the parameter range.
Standard_EXPORT static Handle(Geom2d_Curve) CurveOnSurface (const TopoDS_Edge& E, const Handle(Geom_Surface)& S, const TopLoc_Location& L, Standard_Real& First, Standard_Real& Last);
//! For the planar surface builds the 2d curve for the edge
//! by projection of the edge on plane.
//! Returns a NULL handle if the surface is not planar or
//! the projection failed.
Standard_EXPORT static Handle(Geom2d_Curve) CurveOnPlane (const TopoDS_Edge& E,
const Handle(Geom_Surface)& S,
const TopLoc_Location& L,
Standard_Real& First,
Standard_Real& Last);
//! Returns in <C>, <S>, <L> a 2d curve, a surface and
//! a location for the edge <E>. <C> and <S> are null