1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-08 14:17:06 +03:00

Compare commits

...

2 Commits

Author SHA1 Message Date
jgv
26f0bc0d01 Next version 2022-05-20 11:12:40 +03:00
jgv
6b9da86201 0032833: Shape Healing - FixShape needs to be improved
First version
2022-05-16 16:12:04 +03:00
5 changed files with 325 additions and 86 deletions

View File

@@ -31,11 +31,13 @@
#include <BRepCheck_ListOfStatus.hxx> #include <BRepCheck_ListOfStatus.hxx>
#include <BRepCheck_Wire.hxx> #include <BRepCheck_Wire.hxx>
#include <BRepTools_WireExplorer.hxx> #include <BRepTools_WireExplorer.hxx>
#include <BRepTools.hxx>
#include <ElCLib.hxx> #include <ElCLib.hxx>
#include <Geom2d_Curve.hxx> #include <Geom2d_Curve.hxx>
#include <Geom2dAdaptor_Curve.hxx> #include <Geom2dAdaptor_Curve.hxx>
#include <Geom2dInt_GInter.hxx> #include <Geom2dInt_GInter.hxx>
#include <Geom_Curve.hxx> #include <Geom_Curve.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <gp_Lin.hxx> #include <gp_Lin.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx> #include <gp_Pnt2d.hxx>
@@ -114,6 +116,11 @@ static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
const TopoDS_Edge &theEdge, const TopoDS_Edge &theEdge,
const TopoDS_Face &theFace, const TopoDS_Face &theFace,
gp_Pnt2d &aPnt); gp_Pnt2d &aPnt);
static void DefinePeriods(const TopoDS_Face& theFace,
Standard_Real& theUperiod,
Standard_Real& theVperiod);
// Modified by Sergey KHROMOV - Wed May 22 10:44:08 2002 End // Modified by Sergey KHROMOV - Wed May 22 10:44:08 2002 End
//======================================================================= //=======================================================================
@@ -419,12 +426,24 @@ Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurfac
const gp_Pnt2d& thePnt, const gp_Pnt2d& thePnt,
const gp_Pnt2d& thePntRef, const gp_Pnt2d& thePntRef,
const Standard_Real aTol3d, const Standard_Real aTol3d,
const Standard_Boolean theIsOnSingularity,
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
const Standard_Boolean PrintWarnings = Standard_True) const Standard_Boolean PrintWarnings = Standard_True)
#else #else
const Standard_Boolean = Standard_True) const Standard_Boolean = Standard_True)
#endif #endif
{ {
gp_Pnt aP;
gp_Vec aDU, aDV;
Standard_Real um = (thePnt.X() + thePntRef.X()) / 2.;
Standard_Real vm = (thePnt.Y() + thePntRef.Y()) / 2.;
aFaceSurface.D1(um, vm, aP, aDU, aDV);
Standard_Real aMDU = aDU.Magnitude();
Standard_Real aMDV = aDV.Magnitude();
if (!theIsOnSingularity ||
(aMDU > Precision::Confusion() && aMDV > Precision::Confusion()))
return Standard_True; //we are not in singularity
Standard_Real dumax = 0.01 * (aFaceSurface.LastUParameter() - aFaceSurface.FirstUParameter()); Standard_Real dumax = 0.01 * (aFaceSurface.LastUParameter() - aFaceSurface.FirstUParameter());
Standard_Real dvmax = 0.01 * (aFaceSurface.LastVParameter() - aFaceSurface.FirstVParameter()); Standard_Real dvmax = 0.01 * (aFaceSurface.LastVParameter() - aFaceSurface.FirstVParameter());
Standard_Real dumin = Abs(thePnt.X() - thePntRef.X()); Standard_Real dumin = Abs(thePnt.X() - thePntRef.X());
@@ -453,17 +472,17 @@ Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurfac
#endif #endif
dumax = aFaceSurface.UResolution(aTol3d); dumax = aFaceSurface.UResolution(aTol3d);
dvmax = aFaceSurface.VResolution(aTol3d); dvmax = aFaceSurface.VResolution(aTol3d);
gp_Pnt aP; //gp_Pnt aP;
gp_Vec aDU, aDV; //gp_Vec aDU, aDV;
Standard_Real um = (thePnt.X() + thePntRef.X()) / 2.; //Standard_Real um = (thePnt.X() + thePntRef.X()) / 2.;
Standard_Real vm = (thePnt.Y() + thePntRef.Y()) / 2.; //Standard_Real vm = (thePnt.Y() + thePntRef.Y()) / 2.;
aFaceSurface.D1(um, vm, aP, aDU, aDV); //aFaceSurface.D1(um, vm, aP, aDU, aDV);
Standard_Real aMDU = aDU.Magnitude(); //Standard_Real aMDU = aDU.Magnitude();
if (aMDU > Precision::Confusion()) if (aMDU > Precision::Confusion())
{ {
dumax = Max((aTol3d / aMDU), dumax); dumax = Max((aTol3d / aMDU), dumax);
} }
Standard_Real aMDV = aDV.Magnitude(); //Standard_Real aMDV = aDV.Magnitude();
if (aMDV > Precision::Confusion()) if (aMDV > Precision::Confusion())
{ {
dvmax = Max((aTol3d / aMDV), dvmax); dvmax = Max((aTol3d / aMDV), dvmax);
@@ -676,7 +695,14 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
gp_Pnt aPntRef = BRep_Tool::Pnt(aFirstVertex); gp_Pnt aPntRef = BRep_Tool::Pnt(aFirstVertex);
gp_Pnt aPnt = BRep_Tool::Pnt(aWireExp.CurrentVertex()); gp_Pnt aPnt = BRep_Tool::Pnt(aWireExp.CurrentVertex());
if (!(IsDistanceIn2DTolerance(aFaceSurface, aP_first, aP_last, aTol3d))) Standard_Real aUperiod = 0., aVperiod = 0.;
DefinePeriods (theFace, aUperiod, aVperiod);
if ((aUperiod != 0. && Abs(aP_first.X() - aP_last.X()) > aUperiod/2) ||
(aVperiod != 0. && Abs(aP_first.Y() - aP_last.Y()) > aVperiod/2))
aClosedStat = BRepCheck_NotClosed;
if (!(IsDistanceIn2DTolerance(aFaceSurface, aP_first, aP_last, aTol3d, Standard_True)))
aClosedStat = BRepCheck_NotClosed; aClosedStat = BRepCheck_NotClosed;
if(!IsDistanceIn3DTolerance(aPntRef, aPnt, aTol3d)) if(!IsDistanceIn3DTolerance(aPntRef, aPnt, aTol3d))
@@ -1710,10 +1736,24 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
if (aVOrientation != anEdgOrientation) if (aVOrientation != anEdgOrientation)
aDerRef.Reverse(); aDerRef.Reverse();
//Check if there is a seam edge in the list
Standard_Real aUperiod = 0., aVperiod = 0.;
DefinePeriods (theFace, aUperiod, aVperiod);
Standard_Boolean anIsOnSingularity = Standard_False;
for (It.Initialize(theLOfShape); It.More(); It.Next())
{
TopoDS_Edge anEdge = TopoDS::Edge (It.Value());
if (BRep_Tool::Degenerated (anEdge))
{
anIsOnSingularity = Standard_True;
break;
}
}
It.Initialize(theLOfShape); It.Initialize(theLOfShape);
for (; It.More(); It.Next()) for (; It.More(); It.Next())
{ {
anIndex++; anIndex++;
const TopoDS_Edge& anE=TopoDS::Edge(It.Value()); const TopoDS_Edge& anE=TopoDS::Edge(It.Value());
C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam); C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
@@ -1724,7 +1764,11 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam; aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
aPnt = aCA.Value(aParam); aPnt = aCA.Value(aParam);
if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False)) if ((aUperiod != 0. && Abs(aPnt.X() - aPntRef.X()) > aUperiod/2) ||
(aVperiod != 0. && Abs(aPnt.Y() - aPntRef.Y()) > aVperiod/2))
continue;
if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, anIsOnSingularity, Standard_False))
continue; continue;
CurveDirForParameter(aCA, aParam, aPnt, aDer); CurveDirForParameter(aCA, aParam, aPnt, aDer);
@@ -1743,22 +1787,22 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
anAngle += 2.*M_PI; anAngle += 2.*M_PI;
if ( theFace.Orientation() == TopAbs_FORWARD ) if ( theFace.Orientation() == TopAbs_FORWARD )
{ {
if ( anAngle < aMinAngle ) if ( anAngle < aMinAngle )
{ {
anIndMin = anIndex; anIndMin = anIndex;
aMinAngle = anAngle; aMinAngle = anAngle;
}
} }
}
else //theFace.Orientation() != TopAbs_FORWARD else //theFace.Orientation() != TopAbs_FORWARD
{ {
if ( anAngle > aMaxAngle ) if ( anAngle > aMaxAngle )
{ {
anIndMin = anIndex; anIndMin = anIndex;
aMaxAngle = anAngle; aMaxAngle = anAngle;
}
} }
}//end of for }
}//end of for
// Update edge // Update edge
if (anIndMin == 0) if (anIndMin == 0)
@@ -1770,7 +1814,7 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
if(anEFound.IsNull() || BRep_Tool::Degenerated(theEdge) || if(anEFound.IsNull() || BRep_Tool::Degenerated(theEdge) ||
BRep_Tool::Degenerated(anEFound)) BRep_Tool::Degenerated(anEFound))
IsFound = Standard_False; //bad IsFound = Standard_False; //bad
else if (!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d)) else if (!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_True))
IsFound = Standard_False; //bad IsFound = Standard_False; //bad
else else
// clousureness in 3D // clousureness in 3D
@@ -1959,3 +2003,20 @@ static Standard_Boolean IsClosed2dForPeriodicFace
return Standard_True; return Standard_True;
} }
// Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End // Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
void DefinePeriods(const TopoDS_Face& theFace,
Standard_Real& theUperiod,
Standard_Real& theVperiod)
{
theUperiod = theVperiod = 0.;
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (theFace);
if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface();
Standard_Real aUmin, aUmax, aVmin, aVmax;
aSurf->Bounds (aUmin, aUmax, aVmin, aVmax);
if (aSurf->IsUClosed())
theUperiod = aUmax - aUmin;
if (aSurf->IsVClosed())
theVperiod = aVmax - aVmin;
}

View File

@@ -54,6 +54,29 @@ static Standard_Real GetNextParamOnPC(const Handle(Geom2d_Curve)& aPC,
const Standard_Real& tolV, const Standard_Real& tolV,
const Standard_Boolean& reverse); const Standard_Boolean& reverse);
static Standard_Real LocalUresol (const TopoDS_Vertex& theVertex,
const TopoDS_Face& theFace,
const gp_Pnt2d& theP2d1,
const gp_Pnt2d& theP2d2)
{
Standard_Real aResol = -1;
BRepAdaptor_Surface aBAsurf (theFace, Standard_False);
if (aBAsurf.GetType() == GeomAbs_Sphere)
{
Standard_Real aRadius = aBAsurf.Sphere().Radius();
Standard_Real aVmid = (theP2d1.Y() + theP2d2.Y())/2.;
Standard_Real aLocalRad = aRadius * Cos(aVmid);
if (aLocalRad > Precision::Confusion())
{
Standard_Real aTolVertex = BRep_Tool::Tolerance (theVertex);
aResol = aTolVertex / aLocalRad;
}
}
return aResol;
}
//======================================================================= //=======================================================================
//function : BRepTools_WireExplorer //function : BRepTools_WireExplorer
//purpose : //purpose :
@@ -536,54 +559,54 @@ void BRepTools_WireExplorer::Next()
it.Initialize(l); it.Initialize(l);
while( it.More() ) while( it.More() )
{ {
const TopoDS_Edge& E = TopoDS::Edge(it.Value()); const TopoDS_Edge& E = TopoDS::Edge(it.Value());
if( E.IsSame(myEdge) ) if( E.IsSame(myEdge) )
{
it.Next();
k++;
continue;
}
TopoDS_Vertex aVert1, aVert2;
TopExp::Vertices (E, aVert1, aVert2, Standard_True);
if( aVert1.IsNull() || aVert2.IsNull() )
{ {
it.Next(); it.Next();
k++; k++;
continue; continue;
} }
aPCurve = BRep_Tool::CurveOnSurface (E, myFace, dfFPar, dfLPar); TopoDS_Vertex aVert1, aVert2;
if( aPCurve.IsNull() ) TopExp::Vertices (E, aVert1, aVert2, Standard_True);
if( aVert1.IsNull() || aVert2.IsNull() )
{ {
it.Next(); it.Next();
k++; k++;
continue; continue;
} }
gp_Pnt2d aPEb, aPEe; aPCurve = BRep_Tool::CurveOnSurface (E, myFace, dfFPar, dfLPar);
if( aVert1.IsSame(aVert2) == isDegenerated ) if( aPCurve.IsNull() )
{ {
if( E.Orientation() == TopAbs_REVERSED ) it.Next();
aPCurve->D0(dfLPar, aPEb); k++;
else continue;
aPCurve->D0(dfFPar, aPEb); }
if( Abs(dfLPar-dfFPar) > Precision::PConfusion() ) gp_Pnt2d aPEb, aPEe;
{ if( aVert1.IsSame(aVert2) == isDegenerated )
isrevese = ( E.Orientation() == TopAbs_REVERSED ); {
isrevese = !isrevese; if( E.Orientation() == TopAbs_REVERSED )
Standard_Real aEPm = GetNextParamOnPC(aPCurve,aPEb,dfFPar,dfLPar,myTolU,myTolV,isrevese); aPCurve->D0(dfLPar, aPEb);
else
aPCurve->D0(dfFPar, aPEb);
aPCurve->D0 (aEPm, aPEe); if( Abs(dfLPar-dfFPar) > Precision::PConfusion() )
{
isrevese = ( E.Orientation() == TopAbs_REVERSED );
isrevese = !isrevese;
Standard_Real aEPm = GetNextParamOnPC(aPCurve,aPEb,dfFPar,dfLPar,myTolU,myTolV,isrevese);
aPCurve->D0 (aEPm, aPEe);
if(aPEb.SquareDistance(aPEe) <= gp::Resolution()) if(aPEb.SquareDistance(aPEe) <= gp::Resolution())
{ {
//seems to be very short curve //seems to be very short curve
gp_Vec2d aD; gp_Vec2d aD;
aPCurve->D1(aEPm, aPEe, aD); aPCurve->D1(aEPm, aPEe, aD);
if( E.Orientation() == TopAbs_REVERSED ) if( E.Orientation() == TopAbs_REVERSED )
aPEe.SetXY(aPEb.XY()-aD.XY()); aPEe.SetXY(aPEb.XY()-aD.XY());
else else
aPEe.SetXY(aPEb.XY()+aD.XY()); aPEe.SetXY(aPEb.XY()+aD.XY());
if(aPEb.SquareDistance(aPEe) <= gp::Resolution()) if(aPEb.SquareDistance(aPEe) <= gp::Resolution())
@@ -593,35 +616,39 @@ void BRepTools_WireExplorer::Next()
continue; continue;
} }
} }
gp_Vec2d anEDir(aPEb, aPEe); gp_Vec2d anEDir(aPEb, aPEe);
dfCurAngle = Abs( anEDir.Angle(anERefDir) ); dfCurAngle = Abs( anEDir.Angle(anERefDir) );
} }
if( dfCurAngle <= dfMinAngle ) if( dfCurAngle <= dfMinAngle )
{ {
Standard_Real d = PRef.SquareDistance(aPEb); Standard_Real d = PRef.SquareDistance(aPEb);
if( d <= Precision::PConfusion() ) if( d <= Precision::PConfusion() )
d = 0.; d = 0.;
if( Abs(aPEb.X()-PRef.X()) < myTolU && Abs(aPEb.Y()-PRef.Y()) < myTolV ) //jgv
{ Standard_Real aLocalUresol = LocalUresol (myVertex, myFace, PRef, aPEb);
if( d <= dmin ) aLocalUresol = Max (aLocalUresol, myTolU);
{ /////
dfMinAngle = dfCurAngle; if( Abs(aPEb.X()-PRef.X()) < aLocalUresol && Abs(aPEb.Y()-PRef.Y()) < myTolV )
kMin = k; {
dmin = d; if( d <= dmin )
} {
} dfMinAngle = dfCurAngle;
} kMin = k;
} dmin = d;
it.Next(); }
k++; }
}
}
it.Next();
k++;
}// while it }// while it
if( kMin == 0 ) if( kMin == 0 )
{ {
isDegenerated = Standard_False; isDegenerated = Standard_False;
k = 1; k = 1;
dmin = RealLast(); dmin = RealLast();
} }
else else
break; break;

View File

@@ -768,11 +768,15 @@ Standard_Boolean ShapeAnalysis_Wire::CheckSmall (const Standard_Integer num,
//======================================================================= //=======================================================================
Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer num, Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer num,
gp_Pnt2d& p2d1, gp_Pnt2d& p2d2) gp_Pnt2d& p2d1, gp_Pnt2d& p2d2,
Standard_Real& theTolerance)
{ {
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
if ( ! IsReady() || NbEdges() < 1 ) return Standard_False; if ( ! IsReady() || NbEdges() < 1 ) return Standard_False;
theTolerance = -1;
Standard_Real aTol1 = -1, aTol2 = -1;
Standard_Integer n2 = (num > 0)? num : NbEdges(); Standard_Integer n2 = (num > 0)? num : NbEdges();
Standard_Integer n1 = (n2 > 1)? n2-1 : NbEdges(); Standard_Integer n1 = (n2 > 1)? n2-1 : NbEdges();
Standard_Integer n3 = (n2 < NbEdges())? n2+1 : 1; Standard_Integer n3 = (n2 < NbEdges())? n2+1 : 1;
@@ -838,11 +842,19 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu
Standard_Boolean forward = ( E2.Orientation() == TopAbs_FORWARD ); Standard_Boolean forward = ( E2.Orientation() == TopAbs_FORWARD );
// FIX FEV 1998 : recompute singularity according precision // FIX FEV 1998 : recompute singularity according precision
//jgv
TopoDS_Vertex BeginVertex, EndVertex;
gp_Pnt p3d1, p3d2;
/////
if (p1.Distance(p2) <= precFirst) { // edge DGNR if (p1.Distance(p2) <= precFirst) { // edge DGNR
dgnr = mySurf->DegeneratedValues ( p1, precVtx, p2d1, p2d2, par1, par2, forward ); //smh#9 dgnr = mySurf->DegeneratedValues ( p1, precVtx, p2d1, p2d2, par1, par2, forward ); //smh#9
if ( dgnr ) { // abv 24 Feb 00: trj3_as1-ac-214.stp #6065: avoid making closed edge degenerated if ( dgnr ) { // abv 24 Feb 00: trj3_as1-ac-214.stp #6065: avoid making closed edge degenerated
Standard_Real a, b; Standard_Real a, b;
Handle(Geom_Curve) C3d = BRep_Tool::Curve ( E2, a, b ); Handle(Geom_Curve) C3d = BRep_Tool::Curve ( E2, a, b );
//jgv
theTolerance = BRep_Tool::Tolerance (E2);
/////
if ( ! C3d.IsNull() ) { if ( ! C3d.IsNull() ) {
gp_Pnt p = C3d->Value ( 0.5 * ( a + b ) ); gp_Pnt p = C3d->Value ( 0.5 * ( a + b ) );
if ( p.SquareDistance ( p1 ) > precVtx * precVtx ) dgnr = Standard_False; if ( p.SquareDistance ( p1 ) > precVtx * precVtx ) dgnr = Standard_False;
@@ -908,6 +920,12 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu
Handle(Geom2d_Curve) c2d; Handle(Geom2d_Curve) c2d;
if ( sae.PCurve ( E1, myFace, c2d, a, b, Standard_True ) ) { if ( sae.PCurve ( E1, myFace, c2d, a, b, Standard_True ) ) {
p2d1 = c2d->Value ( b ); p2d1 = c2d->Value ( b );
//jgv
p3d1 = mySurf->Value (p2d1);
BeginVertex = sae.LastVertex(E1);
aTol1 = BRep_Tool::Tolerance (BeginVertex);
/////
//#84 rln gp_Pnt2d p2d = c2d->Value ( b ); //#84 rln gp_Pnt2d p2d = c2d->Value ( b );
//#84 rln par1 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY(); //#84 rln par1 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY();
} }
@@ -915,6 +933,12 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu
//pdn pcurves (fixing regression in f0 in degenerated case) //pdn pcurves (fixing regression in f0 in degenerated case)
if ( sae.PCurve ( ( dgnr ? E3 : E2 ), myFace, c2d, a, b, Standard_True ) ) { if ( sae.PCurve ( ( dgnr ? E3 : E2 ), myFace, c2d, a, b, Standard_True ) ) {
p2d2 = c2d->Value ( a ); p2d2 = c2d->Value ( a );
//jgv
p3d2 = mySurf->Value (p2d2);
EndVertex = sae.FirstVertex (dgnr ? E3 : E2);
aTol2 = BRep_Tool::Tolerance (EndVertex);
/////
//#84 rln gp_Pnt2d p2d = c2d->Value ( a ); //#84 rln gp_Pnt2d p2d = c2d->Value ( a );
//#84 rln par2 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY(); //#84 rln par2 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY();
} }
@@ -928,6 +952,23 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu
} }
*/ */
//jgv
if (theTolerance == -1)
{
theTolerance = Max (aTol1, aTol2);
if (BeginVertex.IsSame(EndVertex))
{
if (precVtx > theTolerance)
theTolerance = precVtx;
/*
Standard_Real aDist = p3d1.Distance (p3d2);
if (aDist > theTolerance)
theTolerance = aDist;
*/
}
}
/////
//#84 rln 18.03.99 if pcurve is not degenerate anymore, the fix is postponned //#84 rln 18.03.99 if pcurve is not degenerate anymore, the fix is postponned
//to ShapeFix_Wire::FixLacking //to ShapeFix_Wire::FixLacking
if ( ! mySurf->IsDegenerated ( p2d1, p2d2, precVtx, 10. ) ) { //:s1 abv 22 Apr 99: PRO7226 #489490 //smh#9 if ( ! mySurf->IsDegenerated ( p2d1, p2d2, precVtx, 10. ) ) { //:s1 abv 22 Apr 99: PRO7226 #489490 //smh#9
@@ -959,7 +1000,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu
Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer num) Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer num)
{ {
gp_Pnt2d p2d1, p2d2; gp_Pnt2d p2d1, p2d2;
return CheckDegenerated ( num, p2d1, p2d2 ); Standard_Real aTol;
return CheckDegenerated (num, p2d1, p2d2, aTol);
} }
//======================================================================= //=======================================================================

View File

@@ -300,7 +300,9 @@ public:
//! no pcurve //! no pcurve
//! FAIL2: Edge marked as degenerated and has no pcurve //! FAIL2: Edge marked as degenerated and has no pcurve
//! but singularity is not detected //! but singularity is not detected
Standard_EXPORT Standard_Boolean CheckDegenerated (const Standard_Integer num, gp_Pnt2d& dgnr1, gp_Pnt2d& dgnr2); Standard_EXPORT Standard_Boolean CheckDegenerated (const Standard_Integer num,
gp_Pnt2d& dgnr1, gp_Pnt2d& dgnr2,
Standard_Real& theTolerance);
//! Checks for degenerated edge between two adjacent ones. //! Checks for degenerated edge between two adjacent ones.
//! Remark : Calls previous function //! Remark : Calls previous function

View File

@@ -57,6 +57,7 @@
#include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx> #include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepTools.hxx> #include <BRepTools.hxx>
#include <BRepLib.hxx>
#include <Geom2d_BSplineCurve.hxx> #include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx> #include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx> #include <Geom2d_Line.hxx>
@@ -1715,7 +1716,8 @@ Standard_Boolean ShapeFix_Wire::FixDegenerated (const Standard_Integer num)
// analysis // analysis
gp_Pnt2d p2d1, p2d2; gp_Pnt2d p2d1, p2d2;
myAnalyzer->CheckDegenerated ( num, p2d1, p2d2 ); Standard_Real aTol;
myAnalyzer->CheckDegenerated (num, p2d1, p2d2, aTol);
if ( myAnalyzer->LastCheckStatus ( ShapeExtend_FAIL1 ) ) { if ( myAnalyzer->LastCheckStatus ( ShapeExtend_FAIL1 ) ) {
myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
} }
@@ -1734,12 +1736,39 @@ Standard_Boolean ShapeFix_Wire::FixDegenerated (const Standard_Integer num)
gp_Dir2d dir2d ( vect2d ); gp_Dir2d dir2d ( vect2d );
Handle(Geom2d_Line) line2d = new Geom2d_Line ( p2d1, dir2d ); Handle(Geom2d_Line) line2d = new Geom2d_Line ( p2d1, dir2d );
//Temporary
TopoDS_Face aFace = Face();
///////////
gp_Pnt2d aP2dMid (0.5*(p2d1.XY() + p2d2.XY()));
gp_Pnt aPntMid;
gp_Vec aDU, aDV;
myAnalyzer->Surface()->TrueAdaptor3d()->D1 (aP2dMid.X(), aP2dMid.Y(), aPntMid, aDU, aDV);
Standard_Real aTolMagnitude = Precision::Confusion();
Standard_Boolean anIsOnSingularity = (aDU.Magnitude() <= aTolMagnitude ||
aDV.Magnitude() <= aTolMagnitude);
/*
TopoDS_Edge anEdge = WireData()->Edge ((num > 0)? num : NbEdges());
Standard_Real aTolEdge = BRep_Tool::Tolerance (anEdge);
*/
//Standard_Boolean anIsNearSingularity =
//myAnalyzer->Surface()->IsDegenerated (aPntMid, Precision::Confusion());
Standard_Real aTolDeg = Max (aTol, Precision::Confusion());
Standard_Boolean anIsNearSingularity =
myAnalyzer->Surface()->IsDegenerated (aPntMid, aTolDeg);
anIsOnSingularity |= anIsNearSingularity;
TopoDS_Edge degEdge; TopoDS_Edge degEdge;
BRep_Builder B; BRep_Builder B;
B.MakeEdge ( degEdge ); B.MakeEdge ( degEdge );
B.Degenerated ( degEdge, Standard_True );
B.UpdateEdge ( degEdge, line2d, Face(), ::Precision::Confusion() ); B.UpdateEdge ( degEdge, line2d, Face(), ::Precision::Confusion() );
B.Range ( degEdge, Face(), 0., vect2d.Magnitude() ); B.Range ( degEdge, Face(), 0., vect2d.Magnitude() );
/*
if (anIsOnSingularity)
B.Degenerated (degEdge, Standard_True);
else
BRepLib::BuildCurve3d (degEdge);
*/
B.Degenerated (degEdge, Standard_True);
Handle(ShapeExtend_WireData) sbwd = WireData(); Handle(ShapeExtend_WireData) sbwd = WireData();
Standard_Integer n2 = ( num >0 ? num : sbwd->NbEdges() ); Standard_Integer n2 = ( num >0 ? num : sbwd->NbEdges() );
@@ -3058,13 +3087,91 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num,
// else try to add either degenerated or closed edge // else try to add either degenerated or closed edge
if ( ! doAddLong ) { if ( ! doAddLong ) {
gp_Pnt pV = 0.5 * ( BRep_Tool::Pnt(V1).XYZ() + BRep_Tool::Pnt(V2).XYZ() ); gp_Pnt pV = 0.5 * ( BRep_Tool::Pnt(V1).XYZ() + BRep_Tool::Pnt(V2).XYZ() );
gp_Pnt pm = myAnalyzer->Surface()->Value ( 0.5 * ( p2d1.XY() + p2d2.XY() ) );
Standard_Real dist = pV.Distance ( pm ); //Temporary
if ( dist <= tol ) doAddDegen = Standard_True; TopoDS_Face aFace = Face();
else if ( myTopoMode ) doAddClosed = Standard_True; ///////////
gp_Pnt2d aP2dMid (0.5*(p2d1.XY() + p2d2.XY()));
gp_Pnt aPntMid;
gp_Vec aDU, aDV;
myAnalyzer->Surface()->TrueAdaptor3d()->D1 (aP2dMid.X(), aP2dMid.Y(), aPntMid, aDU, aDV);
Standard_Real aTolMagnitude = Precision::Confusion();
Standard_Boolean anIsOnSingularity = (aDU.Magnitude() <= aTolMagnitude ||
aDV.Magnitude() <= aTolMagnitude);
////////////////////////////////////
Standard_Real aCoeff = 0.9;
Standard_Real aUmin = myAnalyzer->Surface()->TrueAdaptor3d()->FirstUParameter();
Standard_Real aUmax = myAnalyzer->Surface()->TrueAdaptor3d()->LastUParameter();
Standard_Real aVmin = myAnalyzer->Surface()->TrueAdaptor3d()->FirstVParameter();
Standard_Real aVmax = myAnalyzer->Surface()->TrueAdaptor3d()->LastVParameter();
Standard_Real aDeltaU = Abs (p2d1.X() - p2d2.X());
Standard_Real aDeltaV = Abs (p2d1.Y() - p2d2.Y());
if (!anIsOnSingularity)
{
if (aDeltaU > aDeltaV)
{
anIsOnSingularity = (aDeltaU / (aUmax - aUmin) > aCoeff);
}
else
{
anIsOnSingularity = (aDeltaV / (aVmax - aVmin) > aCoeff);
}
}
////////////////////////////////////
if (!anIsOnSingularity)
{
Standard_Real aTolDeg = Precision::Confusion();
if (V1.IsSame(V2))
aTolDeg = BRep_Tool::Tolerance(V1);
////////////////////////////////////
gp_Pnt2d aPP1 = p2d1, aPP2 = p2d2;
if (aPP1.X() < aUmin)
aPP1.SetX (aUmin);
if (aPP1.X() > aUmax)
aPP1.SetX (aUmax);
if (aPP1.Y() < aVmin)
aPP1.SetY (aVmin);
if (aPP1.Y() > aVmax)
aPP1.SetY (aVmax);
if (aPP2.X() < aUmin)
aPP2.SetX (aUmin);
if (aPP2.X() > aUmax)
aPP2.SetX (aUmax);
if (aPP2.Y() < aVmin)
aPP2.SetY (aVmin);
if (aPP2.Y() > aVmax)
aPP2.SetY (aVmax);
gp_Pnt2d aPPmid((aPP1.XY() + aPP2.XY())/2);
gp_Pnt aP1 = myAnalyzer->Surface()->Value (aPP1);
gp_Pnt aP2 = myAnalyzer->Surface()->Value (aPP2);
gp_Pnt aPmid = myAnalyzer->Surface()->Value (aPPmid);
Standard_Real aDist = Max (aP1.Distance(aP2), Max (aP1.Distance(aPmid), aP2.Distance(aPmid)));
aDist *= 1.001;
if (aDist > aTolDeg)
aTolDeg = aDist;
////////////////////////////////////
anIsOnSingularity = myAnalyzer->Surface()->IsDegenerated (aPntMid, aTolDeg);
}
Standard_Real dist = pV.Distance ( aPntMid );
//Standard_Boolean anIsDistLessTol = Standard_False;
if (dist <= tol)
{
//anIsDistLessTol = Standard_True;
if (anIsOnSingularity)
doAddDegen = Standard_True;
}
else if (myTopoMode)
doAddClosed = Standard_True;
else if ( dist <= MaxTolerance() ) { //:r7 abv 12 Apr 99: t3d_opt.stp #14245 after S4136 else if ( dist <= MaxTolerance() ) { //:r7 abv 12 Apr 99: t3d_opt.stp #14245 after S4136
doAddDegen = Standard_True; if (anIsOnSingularity)
doAddDegen = Standard_True;
doIncrease = Standard_True; doIncrease = Standard_True;
inctol = dist; inctol = dist;
} }