1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0033433: Shape Healing - Implement a new mode to keep initial types of curves. Some changes and fixes.

This commit is contained in:
jfa
2023-10-25 11:36:10 +01:00
parent 2d1ed9a4a2
commit fd90fd9c80
10 changed files with 78 additions and 52 deletions

View File

@@ -283,7 +283,7 @@ static Standard_Integer wire(Draw_Interpretor& di, Standard_Integer n, const cha
//======================================================================= //=======================================================================
// strongwire // strongwire
//======================================================================= //=======================================================================
static Standard_Integer strongwire(Draw_Interpretor& theDI, Standard_Integer theArgC, const char** theArgV) static Standard_Integer strongwire(Draw_Interpretor&, Standard_Integer theArgC, const char** theArgV)
{ {
enum StrongWireMode { enum StrongWireMode {
StrongWireMode_FixTolerance = 1, StrongWireMode_FixTolerance = 1,
@@ -379,8 +379,6 @@ static Standard_Integer strongwire(Draw_Interpretor& theDI, Standard_Integer the
} }
aFW->ClosedWireMode() = isClosed; aFW->ClosedWireMode() = isClosed;
aFW->FixConnected(aTolerance); aFW->FixConnected(aTolerance);
if (aMode == StrongWireMode_KeepCurveType)
aFW->FixCurves();
if (aFW->StatusConnected(ShapeExtend_FAIL)) if (aFW->StatusConnected(ShapeExtend_FAIL))
{ {
@@ -388,7 +386,16 @@ static Standard_Integer strongwire(Draw_Interpretor& theDI, Standard_Integer the
return 1; return 1;
} }
if (aFW->StatusConnected(ShapeExtend_DONE3)) if (aMode == StrongWireMode_KeepCurveType)
{
aFW->FixCurves();
if (aFW->StatusCurves(ShapeExtend_FAIL))
{
Message::SendFail() << "Wire construction failed: cannot rebuild curves through new points";
return 1;
}
}
else if (aFW->StatusConnected(ShapeExtend_DONE3))
{ {
if (aMode != StrongWireMode_Approximation) if (aMode != StrongWireMode_Approximation)
aFW->SetPrecision(aTolerance); aFW->SetPrecision(aTolerance);

View File

@@ -83,6 +83,7 @@
#include <GeomAPI_ProjectPointOnCurve.hxx> #include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx> #include <GeomAPI_ProjectPointOnSurf.hxx>
#include <GeomConvert_CompCurveToBSplineCurve.hxx> #include <GeomConvert_CompCurveToBSplineCurve.hxx>
#include <gp_Elips.hxx>
#include <gp_Pln.hxx> #include <gp_Pln.hxx>
#include <IntRes2d_IntersectionPoint.hxx> #include <IntRes2d_IntersectionPoint.hxx>
#include <IntRes2d_SequenceOfIntersectionPoint.hxx> #include <IntRes2d_SequenceOfIntersectionPoint.hxx>
@@ -248,6 +249,7 @@ void ShapeFix_Wire::ClearStatuses()
myStatusReorder = emptyStatus; myStatusReorder = emptyStatus;
myStatusSmall = emptyStatus; myStatusSmall = emptyStatus;
myStatusConnected = emptyStatus; myStatusConnected = emptyStatus;
myStatusCurves = emptyStatus;
myStatusEdgeCurves = emptyStatus; myStatusEdgeCurves = emptyStatus;
myStatusDegenerated = emptyStatus; myStatusDegenerated = emptyStatus;
myStatusSelfIntersection = emptyStatus; myStatusSelfIntersection = emptyStatus;
@@ -534,17 +536,15 @@ Standard_Boolean ShapeFix_Wire::FixConnected (const Standard_Real prec)
//======================================================================= //=======================================================================
Standard_Boolean ShapeFix_Wire::FixCurves() Standard_Boolean ShapeFix_Wire::FixCurves()
{ {
myStatusConnected = ShapeExtend::EncodeStatus(ShapeExtend_OK); myStatusCurves = ShapeExtend::EncodeStatus(ShapeExtend_OK);
if (!IsLoaded()) return Standard_False; if (!IsLoaded()) return Standard_False;
Standard_Integer stop = (myClosedMode ? 0 : 1); for (Standard_Integer anIdx = NbEdges(); anIdx > 0; anIdx--) {
for (Standard_Integer anIdx = NbEdges(); anIdx > stop; anIdx--)
{
FixCurves(anIdx); FixCurves(anIdx);
myStatusConnected |= myLastFixStatus; myStatusCurves |= myLastFixStatus;
} }
return StatusConnected(ShapeExtend_DONE); return StatusCurves(ShapeExtend_DONE);
} }
//======================================================================= //=======================================================================
@@ -1366,14 +1366,12 @@ Standard_Boolean ShapeFix_Wire::FixCurves(const Standard_Integer theIdx)
aCurve3d->D0(aCurBounds[0], aGeomEnds[0]); aCurve3d->D0(aCurBounds[0], aGeomEnds[0]);
aCurve3d->D0(aCurBounds[2], aGeomEnds[1]); aCurve3d->D0(aCurBounds[2], aGeomEnds[1]);
// TODO: precise, if IsReversed flag should be considered here
Standard_Real aGap0 = Min(anEnds[0].Distance(aGeomEnds[0]), anEnds[0].Distance(aGeomEnds[1])); Standard_Real aGap0 = Min(anEnds[0].Distance(aGeomEnds[0]), anEnds[0].Distance(aGeomEnds[1]));
Standard_Real aGap2 = Min(anEnds[2].Distance(aGeomEnds[0]), anEnds[2].Distance(aGeomEnds[1])); Standard_Real aGap2 = Min(anEnds[2].Distance(aGeomEnds[0]), anEnds[2].Distance(aGeomEnds[1]));
if (Max (aGap0, aGap2) < aPrec) // nothing to do if (Max (aGap0, aGap2) < Precision::Confusion()) // nothing to do
return true; return true;
if (aCurve3d->IsKind(STANDARD_TYPE(Geom_Circle))) if (aCurve3d->IsKind(STANDARD_TYPE(Geom_Circle))) {
{
Standard_Real anOldR = Handle(Geom_Circle)::DownCast(aCurve3d)->Circ().Radius(); Standard_Real anOldR = Handle(Geom_Circle)::DownCast(aCurve3d)->Circ().Radius();
gp_Vec anArcNorm = gp_Vec(anEnds[2], anEnds[0]) / 2; gp_Vec anArcNorm = gp_Vec(anEnds[2], anEnds[0]) / 2;
gp_Pnt aCenter(anEnds[0].XYZ() - anArcNorm.XYZ()); gp_Pnt aCenter(anEnds[0].XYZ() - anArcNorm.XYZ());
@@ -1390,8 +1388,13 @@ Standard_Boolean ShapeFix_Wire::FixCurves(const Standard_Integer theIdx)
anSbwd->Set(aNewEdge, theIdx); anSbwd->Set(aNewEdge, theIdx);
return true; return true;
} }
else if (aCurve3d->IsKind(STANDARD_TYPE(Geom_Ellipse))) else if (aCurve3d->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
{ /// aaajfa: BEGIN - to provide elliptic edge FORWARD orientation
gp_Pnt tmpPnt = anEnds[0];
anEnds[0] = anEnds[2];
anEnds[2] = tmpPnt;
/// aaajfa: END - to provide elliptic edge FORWARD orientation
Handle(Geom_Ellipse) anOld = Handle(Geom_Ellipse)::DownCast(aCurve3d); Handle(Geom_Ellipse) anOld = Handle(Geom_Ellipse)::DownCast(aCurve3d);
Handle(Geom_Plane) aPln = new Geom_Plane(anEnds[0], gp_Vec(anEnds[2], anEnds[0]).Crossed(gp_Vec(anEnds[1], anEnds[0]))); Handle(Geom_Plane) aPln = new Geom_Plane(anEnds[0], gp_Vec(anEnds[2], anEnds[0]).Crossed(gp_Vec(anEnds[1], anEnds[0])));
GeomAPI_ProjectPointOnSurf aProjector(anOld->Elips().Location(), aPln); GeomAPI_ProjectPointOnSurf aProjector(anOld->Elips().Location(), aPln);
@@ -1406,7 +1409,8 @@ Standard_Boolean ShapeFix_Wire::FixCurves(const Standard_Integer theIdx)
for (Standard_Integer anIdxI = -aSplNum; anIdxI < aSplNum; ++anIdxI) for (Standard_Integer anIdxI = -aSplNum; anIdxI < aSplNum; ++anIdxI)
{ {
Handle(Geom_Ellipse) anEll = new Geom_Ellipse(anAx, anOld->MajorRadius(), anOld->MinorRadius()); Handle(Geom_Ellipse) anEll = new Geom_Ellipse(anAx, anOld->MajorRadius(), anOld->MinorRadius());
anEll->Rotate(anAx.Axis(), aPrec*anIdxI / anEll->MajorRadius() / aSplNum); Standard_Real anAnglei = aPrec*anIdxI / anEll->MajorRadius() / aSplNum;
anEll->Rotate(anAx.Axis(), anAnglei);
GeomAPI_ProjectPointOnCurve aProjector1(anEnds[0], anEll); GeomAPI_ProjectPointOnCurve aProjector1(anEnds[0], anEll);
Standard_Real aDist = 0.; Standard_Real aDist = 0.;
for (Standard_Integer anIdxJ = 0; anIdxJ < 2; ++anIdxJ) for (Standard_Integer anIdxJ = 0; anIdxJ < 2; ++anIdxJ)
@@ -1417,7 +1421,7 @@ Standard_Boolean ShapeFix_Wire::FixCurves(const Standard_Integer theIdx)
if (aDist < aRec) if (aDist < aRec)
{ {
aRec = aDist; aRec = aDist;
anAngle = aPrec*anIdxI / anEll->MajorRadius() / aSplNum; anAngle = anAnglei;
} }
} }
gp_Elips aTemp(anAx, anOld->MajorRadius(), anOld->MinorRadius()); gp_Elips aTemp(anAx, anOld->MajorRadius(), anOld->MinorRadius());
@@ -1467,7 +1471,7 @@ Standard_Boolean ShapeFix_Wire::FixCurves(const Standard_Integer theIdx)
} }
else if (aCurve3d->IsKind(STANDARD_TYPE(Geom_Line))) else if (aCurve3d->IsKind(STANDARD_TYPE(Geom_Line)))
{ {
TopoDS_Edge aNewEdge = BRepBuilderAPI_MakeEdge(anEnds[2], anEnds[0]).Edge(); TopoDS_Edge aNewEdge = BRepBuilderAPI_MakeEdge(anEnds[0], anEnds[2]).Edge();
anSbwd->Set(aNewEdge, theIdx); anSbwd->Set(aNewEdge, theIdx);
return true; return true;
} }
@@ -1489,12 +1493,6 @@ Standard_Boolean ShapeFix_Wire::FixCurves(const Standard_Integer theIdx)
return true; return true;
} }
// TODO: question: the below code works only for other curve types (not line/arc/circle/ellipse/bspline)
// Is it really needed?
myAnalyzer->CheckConnected(theIdx, aPrec);
if (myAnalyzer->LastCheckStatus(ShapeExtend_FAIL))
myLastFixStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
return true; return true;
} }

View File

@@ -416,6 +416,8 @@ public:
Standard_Boolean StatusConnected (const ShapeExtend_Status status) const; Standard_Boolean StatusConnected (const ShapeExtend_Status status) const;
Standard_Boolean StatusCurves (const ShapeExtend_Status status) const;
Standard_Boolean StatusEdgeCurves (const ShapeExtend_Status status) const; Standard_Boolean StatusEdgeCurves (const ShapeExtend_Status status) const;
Standard_Boolean StatusDegenerated (const ShapeExtend_Status status) const; Standard_Boolean StatusDegenerated (const ShapeExtend_Status status) const;
@@ -501,6 +503,7 @@ protected:
Standard_Integer myStatusReorder; Standard_Integer myStatusReorder;
Standard_Integer myStatusSmall; Standard_Integer myStatusSmall;
Standard_Integer myStatusConnected; Standard_Integer myStatusConnected;
Standard_Integer myStatusCurves;
Standard_Integer myStatusEdgeCurves; Standard_Integer myStatusEdgeCurves;
Standard_Integer myStatusDegenerated; Standard_Integer myStatusDegenerated;
Standard_Integer myStatusClosed; Standard_Integer myStatusClosed;

View File

@@ -447,6 +447,16 @@ inline Standard_Boolean ShapeFix_Wire::StatusConnected(const ShapeExtend_Status
return ShapeExtend::DecodeStatus ( myStatusConnected, status ); return ShapeExtend::DecodeStatus ( myStatusConnected, status );
} }
//=======================================================================
//function : StatusCurves
//purpose :
//=======================================================================
inline Standard_Boolean ShapeFix_Wire::StatusCurves(const ShapeExtend_Status status) const
{
return ShapeExtend::DecodeStatus ( myStatusCurves, status );
}
//======================================================================= //=======================================================================
//function : StatusEdgeCurves //function : StatusEdgeCurves
//purpose : //purpose :

View File

@@ -11,6 +11,6 @@ translate c1 0 0 0.00000005
translate c2 0 0 -0.00000005 translate c2 0 0 -0.00000005
mkedge c1 c1 mkedge c1 c1
mkedge c2 c2 mkedge c2 c2
strongwire w c1 c2 strongwire result c1 c2
checkshape w checkshape result
whatis w whatis result

View File

@@ -11,6 +11,6 @@ translate e1 0 0 0.00000005
translate e2 0 0 -0.00000005 translate e2 0 0 -0.00000005
mkedge e1 e1 mkedge e1 e1
mkedge e2 e2 mkedge e2 e2
strongwire w e1 e2 strongwire result e1 e2
checkshape w checkshape result
whatis w whatis result

View File

@@ -11,8 +11,14 @@ vertex vx px
vertex vy py vertex vy py
edge exy vx vy edge exy vx vy
gcarc arc cir py pz px gcarc arc cir py pz px
# Here we have an error during automatic grid execution with test and testgrid:
# Tcl Exception: EMPTY
# But in line-by-line entering or script sourcing mode this line doesn't produce any error
mkedge earc arc mkedge earc arc
strongwire w exy earc strongwire result exy earc
whatis w whatis result

View File

@@ -7,9 +7,11 @@ point p1 0 0 0
point p2 100 0 0 point p2 100 0 0
point p4 100 110 0 point p4 100 110 0
gcarc arc cir p1 p2 p4 gcarc arc cir p1 p2 p4
# Here we have an error during automatic grid execution with test and testgrid:
# Tcl Exception: EMPTY
# But in line-by-line entering or script sourcing mode this line doesn't produce any error
mkedge arc1 arc mkedge arc1 arc
mkedge arc2 arc mkedge arc2 arc
@@ -17,7 +19,7 @@ mkedge arc2 arc
tmirror arc2 0 0 0 -110 100 0 -copy tmirror arc2 0 0 0 -110 100 0 -copy
ttranslate arc2 0 0 0.003 -copy ttranslate arc2 0 0 0.003 -copy
strongwire w1 arc1 arc2 -t 0.01 -m keepType strongwire result arc1 arc2 -t 0.01 -m keepType
checkshape w1 checkshape result
whatis w1 whatis result

View File

@@ -9,6 +9,6 @@ translate c1 0 0 0.00000005
translate c2 0 0 -0.00000005 translate c2 0 0 -0.00000005
mkedge c1 c1 mkedge c1 c1
mkedge c2 c2 mkedge c2 c2
strongwire w c1 c2 strongwire result c1 c2
checkshape w checkshape result
whatis w whatis result

View File

@@ -11,7 +11,7 @@ edge e1 v1 v2
edge e2 v2 v3 edge e2 v2 v3
edge e3 v3 v1 edge e3 v3 v1
strongwire w1 e1 e2 e3 strongwire result e1 e2 e3
checkshape w1 checkshape result
whatis w1 whatis result