mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +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:
parent
2f690078d7
commit
cc77a38d94
@ -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())
|
||||
{
|
||||
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.;
|
||||
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; //Range of edge must not be modified
|
||||
First = f; Last = l;
|
||||
|
||||
// Transform curve and update parameters in account of scale factor
|
||||
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);
|
||||
const gp_Trsf& aTrsf = aCurveLocation.Transformation();
|
||||
C3D = Handle(Geom_Curve)::DownCast(C3D->Transformed(aTrsf));
|
||||
f = C3D->TransformedParameter(f, aTrsf);
|
||||
l = C3D->TransformedParameter(l, aTrsf);
|
||||
}
|
||||
GeomAdaptor_Surface& GAS = HS->ChangeSurface();
|
||||
GAS.Load(GP);
|
||||
|
||||
// Perform projection
|
||||
Handle(Geom_Curve) ProjOnPlane =
|
||||
GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l,Standard_True,Standard_False),
|
||||
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);
|
||||
Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(GP);
|
||||
Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(ProjOnPlane);
|
||||
|
||||
ProjLib_ProjectedCurve Proj(HS,HC);
|
||||
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);
|
||||
Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(pc);
|
||||
pc = TC->BasisCurve();
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
First = Last = 0.;
|
||||
return nullPCurve;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -438,36 +440,35 @@ 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)
|
||||
++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
|
||||
C = GC->PCurve();
|
||||
continue;
|
||||
|
||||
S = GC->Surface();
|
||||
L = E.Location() * GC->Location();
|
||||
GC->Range(First,Last);
|
||||
GC->Range(First, Last);
|
||||
return;
|
||||
}
|
||||
}
|
||||
itcr.Next();
|
||||
}
|
||||
|
||||
C.Nullify();
|
||||
S.Nullify();
|
||||
|
@ -104,6 +104,16 @@ public:
|
||||
//! <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
|
||||
//! if the edge has no curve on surface. Returns in
|
||||
|
@ -801,92 +801,111 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge
|
||||
|
||||
maxdev = 0;
|
||||
|
||||
// Get same parameter flag
|
||||
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
|
||||
Standard_Boolean SameParameter = TE->SameParameter();
|
||||
|
||||
GeomAdaptor_Curve AC3d;
|
||||
|
||||
// find 3d curve
|
||||
BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
|
||||
for ( ; itcr.More(); itcr.Next() ) {
|
||||
Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
|
||||
if ( GC.IsNull() || ! GC->IsCurve3D() ) continue;
|
||||
Handle(Geom_Curve) C3d = GC->Curve3D();
|
||||
if ( C3d.IsNull() ) continue; //:s1 abv 22 Apr 99: PRO7226 #489490
|
||||
TopLoc_Location loc = GC->Location();
|
||||
if ( ! loc.IsIdentity() )
|
||||
C3d = Handle(Geom_Curve)::DownCast ( C3d->Transformed ( loc ) );
|
||||
else C3d = Handle(Geom_Curve)::DownCast ( C3d->Copy() ); //:s4 abv 26 Apr 99: sim6049.igs 21677: necessary to get True SP (!!?)
|
||||
Standard_Real First, Last;
|
||||
GC->Range ( First, Last );
|
||||
AC3d.Load ( C3d, First, Last );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! itcr.More() ) {
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
|
||||
// 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;
|
||||
}
|
||||
|
||||
Handle(Geom_Surface) aFaceSurf;
|
||||
TopLoc_Location L;
|
||||
if ( !face.IsNull() )
|
||||
if (!aCurveLoc.IsIdentity())
|
||||
{
|
||||
aFaceSurf = BRep_Tool::Surface(face, L);
|
||||
const gp_Trsf& aTrsf = aCurveLoc.Transformation();
|
||||
aC3D = Handle(Geom_Curve)::DownCast(aC3D->Transformed(aTrsf));
|
||||
aFirst = aC3D->TransformedParameter(aFirst, aTrsf);
|
||||
aLast = aC3D->TransformedParameter(aLast, aTrsf);
|
||||
}
|
||||
|
||||
// iterate on pcurves
|
||||
itcr.Initialize ( TE->Curves() );
|
||||
for ( ; itcr.More(); itcr.Next() )
|
||||
{
|
||||
Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
|
||||
if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
|
||||
// Create adaptor for the curve
|
||||
GeomAdaptor_Curve aGAC(aC3D, aFirst, aLast);
|
||||
|
||||
if ( !(face.IsNull()) ) // Face is not null.
|
||||
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)
|
||||
{
|
||||
// Check for different surface.
|
||||
if (!GC->IsCurveOnSurface(aFaceSurf, GC->Location()))
|
||||
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_HCurve) GHPC = new Geom2dAdaptor_HCurve(aPC, f, l);
|
||||
Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aST);
|
||||
|
||||
Adaptor3d_CurveOnSurface ACS(GHPC, GAHS);
|
||||
if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1))
|
||||
{
|
||||
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;
|
||||
GC->Range ( f, l );
|
||||
Handle(Geom_Surface) Su = GC->Surface();
|
||||
TopLoc_Location loc = GC->Location();
|
||||
if (!loc.IsIdentity())
|
||||
Su = Handle(Geom_Surface)::DownCast ( Su->Transformed ( loc ) );
|
||||
Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Su);
|
||||
Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnPlane(edge, aFaceSurf, aFaceLoc, f, l);
|
||||
if (!aPC.IsNull())
|
||||
{
|
||||
Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(aPC, aFirst, aLast);
|
||||
|
||||
Handle(Geom2d_Curve) PC = GC->PCurve();
|
||||
Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
|
||||
//Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
|
||||
Adaptor3d_CurveOnSurface ACS;
|
||||
ACS.Load(GHPC, GAHS);
|
||||
if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) )
|
||||
{
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
|
||||
}
|
||||
Handle(Geom_Surface) aST =
|
||||
Handle(Geom_Surface)::DownCast(aFaceSurf->Transformed(aFaceLoc.Transformation()));
|
||||
Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aST);
|
||||
|
||||
if ( GC->IsCurveOnClosedSurface() )
|
||||
Adaptor3d_CurveOnSurface ACS(GHPC, GAHS);
|
||||
|
||||
if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1))
|
||||
{
|
||||
GHPC->ChangeCurve2d().Load ( GC->PCurve2(), f, l ); // same bounds
|
||||
ACS.Load(GHPC, GAHS); // sans doute inutile
|
||||
if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) )
|
||||
{
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
|
||||
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( maxdev > TE->Tolerance() )
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
|
||||
if ( ! SameParameter )
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
|
||||
if (maxdev > TE->Tolerance())
|
||||
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
|
||||
if (!SameParameter)
|
||||
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
|
||||
|
||||
return Status ( ShapeExtend_DONE );
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : IsOverlapPartEdges
|
||||
//purpose :
|
||||
|
@ -1,5 +1,3 @@
|
||||
puts "TODO OCC27004 ALL: Faulty shapes in variables faulty_1 to"
|
||||
|
||||
puts "========"
|
||||
puts "OCC27004"
|
||||
puts "========"
|
||||
@ -26,4 +24,7 @@ unifysamedom result r
|
||||
|
||||
checkshape result
|
||||
|
||||
checknbshapes result -vertex 12 -edge 18 -wire 8 -face 8 -solid 1
|
||||
checkprops result -s 223704 -v 3.27888e+006
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
||||
|
35
tests/bugs/modalg_7/bug28995
Normal file
35
tests/bugs/modalg_7/bug28995
Normal file
@ -0,0 +1,35 @@
|
||||
puts "======="
|
||||
puts "0028995"
|
||||
puts "======="
|
||||
puts ""
|
||||
##################################################
|
||||
# UnifySameDomain produces invalid shape
|
||||
##################################################
|
||||
|
||||
brestore [locate_data_file bug28995_s1.brep] s1
|
||||
brestore [locate_data_file bug28995_s2.brep] s2
|
||||
|
||||
# perform fuse operation
|
||||
bfuse rfuse s1 s2
|
||||
|
||||
# check the result of fuse
|
||||
checkshape rfuse
|
||||
|
||||
if {![regexp "This shape seems to be OK" [bopcheck rfuse]]} {
|
||||
puts "Error: The result of FUSE operation is a self-intersecting shape."
|
||||
}
|
||||
|
||||
# unify faces and edges in the fused shape
|
||||
unifysamedom result rfuse
|
||||
|
||||
# check unified result
|
||||
checkshape result
|
||||
|
||||
if {![regexp "This shape seems to be OK" [bopcheck result]]} {
|
||||
puts "Error: The result of UnifySameDomain algorithm is a self-intersecting shape."
|
||||
}
|
||||
|
||||
checknbshapes result -vertex 200 -edge 300 -wire 104 -face 103 -solid 1
|
||||
checkprops result -s 1.59154e+006 -v 1.1497e+007
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
@ -1,5 +1,3 @@
|
||||
# !!!! This file is generated automatically, do not edit manually! See end script
|
||||
puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
|
||||
puts "TODO CR23096 ALL: STATSHAPE : Faulty"
|
||||
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
puts "TODO OCC28995 ALL: Faulty shapes"
|
||||
|
||||
puts "======="
|
||||
puts "0028913"
|
||||
puts "======="
|
||||
|
@ -1,5 +1,3 @@
|
||||
puts "TODO OCC28995 ALL: Faulty shapes"
|
||||
|
||||
puts "======="
|
||||
puts "0028913"
|
||||
puts "======="
|
||||
|
Loading…
x
Reference in New Issue
Block a user