1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0032922: Data Exchange, STEP - The torus is stored incorrectly in STEP format

Problem: the complete surface of the torus is not stored correctly in STEP format due to the fact that the edges are not properly ordered.
Change: added a mode for reordering edges in the wire with simultaneous use of 2d and 3d information (ShapeAnalysis_WireOrder). The new mode is used for torus-like surfaces before saving to STEP format.
 Result: Torus correctly stored.
This commit is contained in:
atereshi 2022-04-08 14:16:01 +03:00 committed by afokin
parent 86d6c284c2
commit 9b9aac4a7b
9 changed files with 1058 additions and 608 deletions

View File

@ -260,7 +260,7 @@ void ShapeAnalysis_Wire::SetSurface (const Handle(Geom_Surface)& surface,
const Standard_Boolean mode3d) const Standard_Boolean mode3d)
{ {
ShapeAnalysis_WireOrder sawo; ShapeAnalysis_WireOrder sawo;
CheckOrder (sawo, isClosed, mode3d); CheckOrder (sawo, isClosed, mode3d, Standard_False);
myStatusOrder = myStatus; myStatusOrder = myStatus;
return StatusOrder (ShapeExtend_DONE); return StatusOrder (ShapeExtend_DONE);
} }
@ -550,54 +550,94 @@ void ShapeAnalysis_Wire::SetSurface (const Handle(Geom_Surface)& surface,
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean ShapeAnalysis_Wire::CheckOrder(ShapeAnalysis_WireOrder& sawo, Standard_Boolean ShapeAnalysis_Wire::CheckOrder(ShapeAnalysis_WireOrder &sawo,
const Standard_Boolean isClosed, const Standard_Boolean isClosed,
const Standard_Boolean mode3d) const Standard_Boolean theMode3D,
const Standard_Boolean theModeBoth)
{ {
if ( ! mode3d && myFace.IsNull() ) { if ((!theMode3D || theModeBoth) && myFace.IsNull())
{
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2); myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
return Standard_False; return Standard_False;
} }
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
sawo.SetMode ( mode3d, ( mode3d ? myPrecision : ::Precision::PConfusion() ) ); sawo.SetMode(theMode3D, 0.0, theModeBoth);
Standard_Integer i, nb = myWire->NbEdges(); Standard_Integer nb = myWire->NbEdges();
ShapeAnalysis_Edge EA; ShapeAnalysis_Edge EA;
for (i = 1; i <= nb; i ++) { Standard_Boolean isAll2dEdgesOk = Standard_True;
for (Standard_Integer i = 1; i <= nb; i++)
{
TopoDS_Edge E = myWire->Edge(i); TopoDS_Edge E = myWire->Edge(i);
if ( mode3d ) { gp_XYZ aP1XYZ, aP2XYZ;
TopoDS_Vertex V1 = EA.FirstVertex (E); gp_XY aP1XY, aP2XY;
TopoDS_Vertex V2 = EA.LastVertex (E); if (theMode3D || theModeBoth)
{
TopoDS_Vertex V1 = EA.FirstVertex(E);
TopoDS_Vertex V2 = EA.LastVertex(E);
if (V1.IsNull() || V2.IsNull()) if (V1.IsNull() || V2.IsNull())
{ {
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2); myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
return Standard_False; return Standard_False;
} }
gp_Pnt p1 = BRep_Tool::Pnt (V1); else
gp_Pnt p2 = BRep_Tool::Pnt (V2); {
sawo.Add (p1.XYZ(),p2.XYZ()); aP1XYZ = BRep_Tool::Pnt(V1).XYZ();
} aP2XYZ = BRep_Tool::Pnt(V2).XYZ();
else {
Standard_Real f,l;
Handle(Geom2d_Curve) c2d;
TopoDS_Shape tmpF = myFace.Oriented(TopAbs_FORWARD);
if ( ! EA.PCurve(E,TopoDS::Face(tmpF),c2d,f,l) ) {
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
return Standard_False;
} }
sawo.Add(c2d->Value(f).XY(),c2d->Value(l).XY()); }
if (!theMode3D || theModeBoth)
{
Standard_Real f, l;
Handle(Geom2d_Curve) c2d;
TopoDS_Shape tmpF = myFace.Oriented (TopAbs_FORWARD);
if (!EA.PCurve(E, TopoDS::Face (tmpF), c2d, f, l))
{
// if mode is 2d, then we can nothing to do, else we can switch to 3d mode
if (!theMode3D && !theModeBoth)
{
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
return Standard_False;
}
else
{
isAll2dEdgesOk = Standard_False;
}
}
else
{
aP1XY = c2d->Value(f).XY();
aP2XY = c2d->Value(l).XY();
}
}
if (theMode3D && !theModeBoth)
{
sawo.Add (aP1XYZ, aP2XYZ);
}
else if (!theMode3D && !theModeBoth)
{
sawo.Add (aP1XY, aP2XY);
}
else
{
sawo.Add (aP1XYZ, aP2XYZ, aP1XY, aP2XY);
} }
} }
sawo.Perform(isClosed); // need to switch to 3d mode
if (theModeBoth && !isAll2dEdgesOk)
{
sawo.SetMode (Standard_True, 0.0, Standard_False);
}
sawo.Perform (isClosed);
Standard_Integer stat = sawo.Status(); Standard_Integer stat = sawo.Status();
switch (stat) { switch (stat)
{
case 0: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); break; case 0: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); break;
case 1: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); break; case 1: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); break;
case 2: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2); break; case 2: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2); break; // this value is not returned
case -1: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE3); break; case -1: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE3); break;
case -2: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE4); break; case -2: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE4); break; // this value is not returned
case 3: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE5); break;//only shifted case 3: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE5); break; // only shifted
case -10: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); break; case -10: myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); break; // this value is not returned
} }
return LastCheckStatus (ShapeExtend_DONE); return LastCheckStatus (ShapeExtend_DONE);
} }

View File

@ -232,7 +232,8 @@ public:
//! Analyzes the order of the edges in the wire, //! Analyzes the order of the edges in the wire,
//! uses class WireOrder for that purpose. //! uses class WireOrder for that purpose.
//! Flag <isClosed> defines if the wire is closed or not //! Flag <isClosed> defines if the wire is closed or not
//! Flag <mode3d> defines which mode is used (3d or 2d) //! Flag <theMode3D> defines 3D or 2d mode.
//! Flag <theModeBoth> defines miscible mode and the flag <theMode3D> is ignored.
//! Returns False if wire is already ordered (tail-to-head), //! Returns False if wire is already ordered (tail-to-head),
//! True otherwise. //! True otherwise.
//! Use returned WireOrder object for deeper analysis. //! Use returned WireOrder object for deeper analysis.
@ -243,7 +244,10 @@ public:
//! DONE3: not the same edges orientation (some need to be reversed) //! DONE3: not the same edges orientation (some need to be reversed)
//! DONE4: as DONE3 and gaps more than myPrecision //! DONE4: as DONE3 and gaps more than myPrecision
//! FAIL : algorithm failed (could not detect order) //! FAIL : algorithm failed (could not detect order)
Standard_EXPORT Standard_Boolean CheckOrder (ShapeAnalysis_WireOrder& sawo, const Standard_Boolean isClosed = Standard_True, const Standard_Boolean mode3d = Standard_True); Standard_EXPORT Standard_Boolean CheckOrder(ShapeAnalysis_WireOrder &sawo,
Standard_Boolean isClosed = Standard_True,
Standard_Boolean theMode3D = Standard_True,
Standard_Boolean theModeBoth = Standard_False);
//! Checks connected edges (num-th and preceding). //! Checks connected edges (num-th and preceding).
//! Tests with starting preci from <SBWD> or with <prec> if //! Tests with starting preci from <SBWD> or with <prec> if

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include <Standard_Boolean.hxx> #include <Standard_Boolean.hxx>
#include <TColStd_HArray1OfInteger.hxx> #include <TColStd_HArray1OfInteger.hxx>
#include <TColgp_HSequenceOfXY.hxx>
#include <TColgp_HSequenceOfXYZ.hxx> #include <TColgp_HSequenceOfXYZ.hxx>
#include <Standard_Real.hxx> #include <Standard_Real.hxx>
#include <Standard_Integer.hxx> #include <Standard_Integer.hxx>
@ -41,12 +42,10 @@ class gp_XY;
//! This allows to use this tool, either on existing wire, or on //! This allows to use this tool, either on existing wire, or on
//! data just taken from a file (coordinates are easy to get) //! data just taken from a file (coordinates are easy to get)
//! //!
//! It can work, either in 2D, or in 3D, but not miscible //! It can work, either in 2D, or in 3D, or miscible mode
//! Warning about tolerance : according to the mode (2D/3D), it //! The tolerance for each mode is fixed
//! must be given as 2D or 3D (i.e. metric) tolerance, uniform
//! on the whole list
//! //!
//! Two phases : firstly add the couples (start,end) //! Two phases : firstly add the couples (start, end)
//! secondly perform then get the result //! secondly perform then get the result
class ShapeAnalysis_WireOrder class ShapeAnalysis_WireOrder
{ {
@ -54,17 +53,24 @@ public:
DEFINE_STANDARD_ALLOC DEFINE_STANDARD_ALLOC
//! Empty constructor //! Empty constructor
Standard_EXPORT ShapeAnalysis_WireOrder(); Standard_EXPORT ShapeAnalysis_WireOrder();
//! Creates a WireOrder in 3D (if mode3d is True) or 2D (if False) //! Creates a WireOrder.
//! with a tolerance //! Flag <theMode3D> defines 3D or 2d mode.
Standard_EXPORT ShapeAnalysis_WireOrder(const Standard_Boolean mode3d, const Standard_Real tol); //! Flag <theModeBoth> defines miscible mode and the flag <theMode3D> is ignored.
//! Warning: Parameter <theTolerance> is not used in algorithm.
Standard_EXPORT ShapeAnalysis_WireOrder (const Standard_Boolean theMode3D,
const Standard_Real theTolerance,
const Standard_Boolean theModeBoth = Standard_False);
//! Sets new values. Clears the connexion list //! Sets new values.
//! If <mode3d> changes, also clears the edge list (else, doesn't) //! Clears the edge list if the mode (<theMode3D> or <theModeBoth> ) changes.
Standard_EXPORT void SetMode (const Standard_Boolean mode3d, const Standard_Real tol); //! Clears the connexion list.
//! Warning: Parameter <theTolerance> is not used in algorithm.
Standard_EXPORT void SetMode (const Standard_Boolean theMode3D,
const Standard_Real theTolerance,
const Standard_Boolean theModeBoth = Standard_False);
//! Returns the working tolerance //! Returns the working tolerance
Standard_EXPORT Standard_Real Tolerance() const; Standard_EXPORT Standard_Real Tolerance() const;
@ -72,11 +78,17 @@ public:
//! Clears the list of edges, but not mode and tol //! Clears the list of edges, but not mode and tol
Standard_EXPORT void Clear(); Standard_EXPORT void Clear();
//! Adds a couple of points 3D (start,end) //! Adds a couple of points 3D (start, end)
Standard_EXPORT void Add (const gp_XYZ& start3d, const gp_XYZ& end3d); Standard_EXPORT void Add (const gp_XYZ& theStart3d, const gp_XYZ& theEnd3d);
//! Adds a couple of points 2D (start,end) //! Adds a couple of points 2D (start, end)
Standard_EXPORT void Add (const gp_XY& start2d, const gp_XY& end2d); Standard_EXPORT void Add (const gp_XY& theStart2d, const gp_XY& theEnd2d);
//! Adds a couple of points 3D and 2D (start, end)
Standard_EXPORT void Add (const gp_XYZ& theStart3d,
const gp_XYZ& theEnd3d,
const gp_XY& theStart2d,
const gp_XY& theEnd2d);
//! Returns the count of added couples of points (one per edges) //! Returns the count of added couples of points (one per edges)
Standard_EXPORT Standard_Integer NbEdges() const; Standard_EXPORT Standard_Integer NbEdges() const;
@ -87,12 +99,11 @@ public:
Standard_EXPORT Standard_Boolean& KeepLoopsMode(); Standard_EXPORT Standard_Boolean& KeepLoopsMode();
//! Computes the better order //! Computes the better order
//! If <closed> is True (D) considers also closure
//! Optimised if the couples were already in order //! Optimised if the couples were already in order
//! The criterium is : two couples in order if distance between //! The criterium is : two couples in order if distance between
//! end-prec and start-cur is less then starting tolerance <tol> //! end-prec and start-cur is less then starting tolerance <tol>
//! Else, the smallest distance is reached //! Else, the smallest distance is reached
//! Gap corresponds to a smallest distance greater than <tol> //! Warning: Parameter <closed> not used
Standard_EXPORT void Perform (const Standard_Boolean closed = Standard_True); Standard_EXPORT void Perform (const Standard_Boolean closed = Standard_True);
//! Tells if Perform has been done //! Tells if Perform has been done
@ -102,23 +113,20 @@ public:
//! Returns the status of the order (0 if not done) : //! Returns the status of the order (0 if not done) :
//! 0 : all edges are direct and in sequence //! 0 : all edges are direct and in sequence
//! 1 : all edges are direct but some are not in sequence //! 1 : all edges are direct but some are not in sequence
//! 2 : in addition, unresolved gaps remain
//! -1 : some edges are reversed, but no gap remain //! -1 : some edges are reversed, but no gap remain
//! -2 : some edges are reversed and some gaps remain //! 3 : edges in sequence are just shifted in forward or reverse manner
//! -10 : COULD NOT BE RESOLVED, Failure on Reorder
//! gap : regarding starting <tol>
Standard_EXPORT Standard_Integer Status() const; Standard_EXPORT Standard_Integer Status() const;
//! Returns the number of original edge which correspond to the //! Returns the number of original edge which correspond to the
//! newly ordered number <n> //! newly ordered number <n>
//! Warning : the returned value is NEGATIVE if edge should be reversed //! Warning : the returned value is NEGATIVE if edge should be reversed
Standard_EXPORT Standard_Integer Ordered (const Standard_Integer n) const; Standard_EXPORT Standard_Integer Ordered (const Standard_Integer theIdx) const;
//! Returns the values of the couple <num>, as 3D values //! Returns the values of the couple <num>, as 3D values
Standard_EXPORT void XYZ (const Standard_Integer num, gp_XYZ& start3d, gp_XYZ& end3d) const; Standard_EXPORT void XYZ (const Standard_Integer theIdx, gp_XYZ& theStart3D, gp_XYZ& theEnd3D) const;
//! Returns the values of the couple <num>, as 2D values //! Returns the values of the couple <num>, as 2D values
Standard_EXPORT void XY (const Standard_Integer num, gp_XY& start2d, gp_XY& end2d) const; Standard_EXPORT void XY (const Standard_Integer theIdx, gp_XY& theStart2D, gp_XY& theEnd2D) const;
//! Returns the gap between a couple and its preceding //! Returns the gap between a couple and its preceding
//! <num> is considered ordered //! <num> is considered ordered
@ -138,6 +146,7 @@ public:
//! Determines the couples of edges for which end and start fit //! Determines the couples of edges for which end and start fit
//! inside a given gap. Queried by NbCouples and Couple //! inside a given gap. Queried by NbCouples and Couple
//! Warning: function isn't implemented
Standard_EXPORT void SetCouples (const Standard_Real gap); Standard_EXPORT void SetCouples (const Standard_Real gap);
//! Returns the count of computed couples //! Returns the count of computed couples
@ -147,36 +156,27 @@ public:
//! In the list of ordered edges //! In the list of ordered edges
Standard_EXPORT void Couple (const Standard_Integer num, Standard_Integer& n1, Standard_Integer& n2) const; Standard_EXPORT void Couple (const Standard_Integer num, Standard_Integer& n1, Standard_Integer& n2) const;
protected: protected:
private: private:
// the mode in which the algorithm works
enum ModeType
{
Mode2D,
Mode3D,
ModeBoth
};
Standard_Boolean myKeepLoops;
Handle(TColStd_HArray1OfInteger) myOrd; Handle(TColStd_HArray1OfInteger) myOrd;
Handle(TColStd_HArray1OfInteger) myChains; Handle(TColStd_HArray1OfInteger) myChains;
Handle(TColStd_HArray1OfInteger) myCouples; Handle(TColStd_HArray1OfInteger) myCouples;
Handle(TColgp_HSequenceOfXYZ) myXYZ; Handle(TColgp_HSequenceOfXYZ) myXYZ;
Handle(TColgp_HSequenceOfXY) myXY;
Standard_Real myTol; Standard_Real myTol;
Standard_Real myGap; Standard_Real myGap;
Standard_Integer myStat; Standard_Integer myStat;
Standard_Boolean myMode; Standard_Boolean myKeepLoops;
ModeType myMode;
}; };
#endif // _ShapeAnalysis_WireOrder_HeaderFile #endif // _ShapeAnalysis_WireOrder_HeaderFile

View File

@ -349,7 +349,7 @@ Standard_Boolean ShapeFix_Wire::Perform()
// status even if FixReorder should not be called (if it is forbidden) // status even if FixReorder should not be called (if it is forbidden)
ShapeAnalysis_WireOrder sawo; ShapeAnalysis_WireOrder sawo;
Standard_Boolean ReorderOK = ( myAnalyzer->CheckOrder ( sawo, myClosedMode ) ==0 ); Standard_Boolean ReorderOK = (myAnalyzer->CheckOrder( sawo, myClosedMode ) == 0 );
if ( NeedFix ( myFixReorderMode, ! ReorderOK ) ) { if ( NeedFix ( myFixReorderMode, ! ReorderOK ) ) {
if(FixReorder()) Fixed = Standard_True; if(FixReorder()) Fixed = Standard_True;
ReorderOK = ! StatusReorder ( ShapeExtend_FAIL ); ReorderOK = ! StatusReorder ( ShapeExtend_FAIL );
@ -433,51 +433,53 @@ Standard_Boolean ShapeFix_Wire::Perform()
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean ShapeFix_Wire::FixReorder() Standard_Boolean ShapeFix_Wire::FixReorder(Standard_Boolean theModeBoth)
{ {
myStatusReorder = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); myStatusReorder = ShapeExtend::EncodeStatus(ShapeExtend_OK);
if ( ! IsLoaded() ) return Standard_False; if (!IsLoaded())
{
// fix in 3d return Standard_False;
ShapeAnalysis_WireOrder sawo;
myAnalyzer->CheckOrder ( sawo, myClosedMode, Standard_True );
//:abv revolCuts.sat -23: in case of bi-periodic surface check case
// of reversed wire specifically. This is necessary because degenerated
// cases are possible when direct evaluation will give bad result.
Standard_Boolean isReorder = Standard_False;
if ( sawo.Status() != 0 &&
! myAnalyzer->Surface().IsNull() &&
myAnalyzer->Surface()->Surface()->IsUPeriodic() &&
myAnalyzer->Surface()->Surface()->IsVPeriodic() ) {
Handle(ShapeExtend_WireData) sbwd2 = new ShapeExtend_WireData;
for ( Standard_Integer i=WireData()->NbEdges(); i >=1; i-- )
sbwd2->Add ( WireData()->Edge(i) );
ShapeAnalysis_WireOrder sawo2;
ShapeAnalysis_Wire analyzer2 ( sbwd2, myAnalyzer->Face(), Precision() );
analyzer2.CheckOrder ( sawo2, myClosedMode, Standard_True );
if ( ( sawo2.Status() >=0 && sawo2.Status() < sawo.Status() ) ||
( sawo.Status() <0 && sawo2.Status() > sawo.Status() ) ) {
WireData()->Init ( sbwd2 );
sawo = sawo2;
isReorder = Standard_True;
}
} }
FixReorder ( sawo ); // fix in Both mode for bi-periodic surface
ShapeAnalysis_WireOrder sawo;
if (!myAnalyzer->Surface().IsNull() &&
myAnalyzer->Surface()->Surface()->IsUPeriodic() &&
myAnalyzer->Surface()->Surface()->IsVPeriodic() &&
theModeBoth)
{
myAnalyzer->CheckOrder(sawo, myClosedMode, Standard_True, Standard_True);
}
else
{
myAnalyzer->CheckOrder(sawo, myClosedMode, Standard_True, Standard_False);
}
if ( LastFixStatus ( ShapeExtend_FAIL ) ) FixReorder(sawo);
myStatusReorder |= ShapeExtend::EncodeStatus ( LastFixStatus ( ShapeExtend_FAIL1 ) ?
ShapeExtend_FAIL1 : ShapeExtend_FAIL2 );
if ( ! LastFixStatus ( ShapeExtend_DONE )&& !isReorder ) return Standard_False;
myStatusReorder |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); if (LastFixStatus(ShapeExtend_FAIL))
if ( sawo.Status() ==2 || sawo.Status() ==-2 ) {
myStatusReorder |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); myStatusReorder |= ShapeExtend::EncodeStatus(LastFixStatus(ShapeExtend_FAIL1) ? ShapeExtend_FAIL1 : ShapeExtend_FAIL2);
if ( sawo.Status() <0 ) }
myStatusReorder |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 ); if (!LastFixStatus(ShapeExtend_DONE))
if ( sawo.Status() == 3) {
myStatusReorder |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );//only shifted return Standard_False;
}
myStatusReorder |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
if (sawo.Status() == 2 || sawo.Status() == -2)
{
myStatusReorder |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
}
if (sawo.Status() < 0)
{
myStatusReorder |= ShapeExtend::EncodeStatus(ShapeExtend_DONE3);
}
if (sawo.Status() == 3)
{
// only shifted
myStatusReorder |= ShapeExtend::EncodeStatus(ShapeExtend_DONE5);
}
return Standard_True; return Standard_True;
} }

View File

@ -267,9 +267,9 @@ public:
//! FixLacking (if wire is ordered) //! FixLacking (if wire is ordered)
Standard_EXPORT Standard_Boolean Perform(); Standard_EXPORT Standard_Boolean Perform();
//! Performs an analysis and reorders edges in the wire using //! Performs an analysis and reorders edges in the wire using class WireOrder.
//! class WireOrder //! Flag <theModeBoth> determines the use of miscible mode if necessary.
Standard_EXPORT Standard_Boolean FixReorder(); Standard_EXPORT Standard_Boolean FixReorder(Standard_Boolean theModeBoth = Standard_False);
//! Applies FixSmall(num) to all edges in the wire //! Applies FixSmall(num) to all edges in the wire
Standard_EXPORT Standard_Integer FixSmall (const Standard_Boolean lockvtx, const Standard_Real precsmall = 0.0); Standard_EXPORT Standard_Integer FixSmall (const Standard_Boolean lockvtx, const Standard_Real precsmall = 0.0);

View File

@ -72,250 +72,230 @@ TopoDSToStep_MakeStepWire::TopoDSToStep_MakeStepWire
// Purpose : // Purpose :
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void TopoDSToStep_MakeStepWire::Init(const TopoDS_Wire& aWire, void TopoDSToStep_MakeStepWire::Init (const TopoDS_Wire& aWire,
TopoDSToStep_Tool& aTool, TopoDSToStep_Tool& aTool,
const Handle(Transfer_FinderProcess)& FP) const Handle(Transfer_FinderProcess)& FP)
{ {
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// The Wire is given in its relative orientation (i.e. in the face) // The Wire is given in its relative orientation (i.e. in the face)
// ---------------------------------------------------------------- // ----------------------------------------------------------------
aTool.SetCurrentWire (aWire);
aTool.SetCurrentWire(aWire); if (aTool.IsBound (aWire))
{
if (aTool.IsBound(aWire)) { myError = TopoDSToStep_WireDone;
myError = TopoDSToStep_WireDone; done = Standard_True;
done = Standard_True; myResult = aTool.Find (aWire);
myResult = aTool.Find(aWire);
return; return;
} }
Standard_Integer i; if (aWire.Orientation() == TopAbs_INTERNAL || aWire.Orientation() == TopAbs_EXTERNAL)
{
if (aWire.Orientation() == TopAbs_INTERNAL || Handle(TransferBRep_ShapeMapper) errShape = new TransferBRep_ShapeMapper (aWire);
aWire.Orientation() == TopAbs_EXTERNAL ) { FP->AddWarning (errShape, " Wire(internal/external) from Non Manifold Topology");
Handle(TransferBRep_ShapeMapper) errShape =
new TransferBRep_ShapeMapper(aWire);
FP->AddWarning(errShape, " Wire(internal/external) from Non Manifold Topology");
myError = TopoDSToStep_NonManifoldWire; myError = TopoDSToStep_NonManifoldWire;
done = Standard_False; done = Standard_False;
return; return;
} }
BRepTools_WireExplorer ItW;
TopoDS_Edge CurrentEdge;
TColStd_SequenceOfTransient mySeq; TColStd_SequenceOfTransient mySeq;
// -------- // --------
// Polyloop // Polyloop
// -------- // --------
if (aTool.Faceted())
if (aTool.Faceted()) { {
Handle(StepShape_VertexPoint) VertexPoint; Handle(StepShape_VertexPoint) VertexPoint;
Handle(StepGeom_Point) Point; Handle(StepGeom_Point) Point;
Handle(StepShape_TopologicalRepresentationItem) Gpms; Handle(StepShape_TopologicalRepresentationItem) Gpms;
TopoDS_Vertex TopoDSVertex1, TopoDSVertex2; TopoDS_Vertex TopoDSVertex1, TopoDSVertex2;
TopoDSToStep_MakeStepVertex MkVertex; TopoDSToStep_MakeStepVertex MkVertex;
// TopoDS_Wire ForwardWire = TopoDS::Wire(aWire.Oriented(TopAbs_FORWARD));
for (ItW.Init(aWire, aTool.CurrentFace()); for (BRepTools_WireExplorer ItW (aWire, aTool.CurrentFace()); ItW.More(); ItW.Next())
ItW.More();ItW.Next()) { {
CurrentEdge = ItW.Current(); const TopoDS_Edge& CurrentEdge = ItW.Current();
if (CurrentEdge.Orientation() == TopAbs_FORWARD) if (CurrentEdge.Orientation() == TopAbs_FORWARD)
TopExp::Vertices(CurrentEdge, TopoDSVertex1, TopoDSVertex2); {
else TopExp::Vertices (CurrentEdge, TopoDSVertex1, TopoDSVertex2);
TopExp::Vertices(CurrentEdge, TopoDSVertex2, TopoDSVertex1);
MkVertex.Init(TopoDSVertex1, aTool, FP);
if (MkVertex.IsDone()) {
VertexPoint = Handle(StepShape_VertexPoint)::DownCast(MkVertex.Value());
Point = VertexPoint->VertexGeometry();
mySeq.Append(Point);
} }
else { else
Handle(TransferBRep_ShapeMapper) errShape = {
new TransferBRep_ShapeMapper(aWire); TopExp::Vertices (CurrentEdge, TopoDSVertex2, TopoDSVertex1);
FP->AddWarning(errShape, " a Vertex Point not mapped"); }
myError = TopoDSToStep_WireOther;
done = Standard_False; MkVertex.Init (TopoDSVertex1, aTool, FP);
return; if (MkVertex.IsDone())
{
VertexPoint = Handle(StepShape_VertexPoint)::DownCast (MkVertex.Value());
Point = VertexPoint->VertexGeometry();
mySeq.Append (Point);
}
else
{
Handle(TransferBRep_ShapeMapper) errShape = new TransferBRep_ShapeMapper (aWire);
FP->AddWarning (errShape, " a Vertex Point not mapped");
myError = TopoDSToStep_WireOther;
done = Standard_False;
return;
} }
} }
Standard_Integer nbPoints = mySeq.Length(); Standard_Integer nbPoints = mySeq.Length();
if (nbPoints>=3) { if (nbPoints >= 3)
Handle(StepGeom_HArray1OfCartesianPoint) aPolygon = {
new StepGeom_HArray1OfCartesianPoint(1,nbPoints); Handle(StepGeom_HArray1OfCartesianPoint) aPolygon = new StepGeom_HArray1OfCartesianPoint (1, nbPoints);
for ( i=1; i<=nbPoints; i++) { for (Standard_Integer i = 1; i <= nbPoints; i++)
aPolygon->SetValue(i, Handle(StepGeom_CartesianPoint):: {
DownCast(mySeq.Value(i))); aPolygon->SetValue (i, Handle(StepGeom_CartesianPoint)::DownCast (mySeq.Value (i)));
} }
Handle(StepShape_PolyLoop) PL = new StepShape_PolyLoop(); Handle(StepShape_PolyLoop) PL = new StepShape_PolyLoop();
Handle(TCollection_HAsciiString) aName = Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString ("");
new TCollection_HAsciiString(""); PL->Init (aName, aPolygon);
PL->Init(aName, aPolygon);
aTool.Bind(aWire, PL); aTool.Bind (aWire, PL);
myError = TopoDSToStep_WireDone; myError = TopoDSToStep_WireDone;
done = Standard_True; done = Standard_True;
myResult = PL; myResult = PL;
return; return;
} }
else { else
Handle(TransferBRep_ShapeMapper) errShape = {
new TransferBRep_ShapeMapper(aWire); Handle(TransferBRep_ShapeMapper) errShape = new TransferBRep_ShapeMapper (aWire);
FP->AddWarning(errShape, " PolyLoop: Wire has less than 3 points"); FP->AddWarning (errShape, " PolyLoop: Wire has less than 3 points");
myError = TopoDSToStep_WireOther; myError = TopoDSToStep_WireOther;
done = Standard_False; done = Standard_False;
return; return;
} }
} }
// --------
// -------- // EdgeLoop
// EdgeLoop // --------
// -------- else
{
else {
Handle(StepShape_TopologicalRepresentationItem) Gpms; Handle(StepShape_TopologicalRepresentationItem) Gpms;
Handle(StepShape_Edge) Epms; Handle(StepShape_Edge) Epms;
Handle(StepShape_OrientedEdge) OrientedEdge; Handle(StepShape_OrientedEdge) OrientedEdge;
TopoDSToStep_MakeStepEdge MkEdge; TopoDSToStep_MakeStepEdge MkEdge;
//szv#4:S4163:12Mar99 SGI warns const TopoDS_Wire ForwardWire = TopoDS::Wire (aWire.Oriented (TopAbs_FORWARD));
TopoDS_Shape sh = aWire.Oriented(TopAbs_FORWARD); Handle(ShapeFix_Wire) STW = new ShapeFix_Wire (ForwardWire, aTool.CurrentFace(), Precision::Confusion());
const TopoDS_Wire ForwardWire = TopoDS::Wire(sh); // for toroidal like surfaces we need to use both (3d and 2d) mode to correctly reorder the edges
// test 25-01-96 FMA supprime CKY 2-JUN-1997, cf MakeStepFace->Face FWD] STW->FixReorder (Standard_True);
// remis CKY 9-DEC-1997 : chaque niveau se traite en FWD Handle(ShapeExtend_WireData) anExtWire = STW->WireData();
//#11 rln 16/03/98
//TestRally8 file carter2.rle face#333 (wire is not sorted, not sorted edges are seam and iso-curve):
//aWire is REVERSED but ForwardWire is FORWARD, when exploding not connected seams their pcurves are
//returned in incorrect order (because of mismatched orientation)
//As a result not sorted edges are lost (not returned by BRepTools_WireExplorer)
//By the way, in the case of aTool.Faceted() aWire is used
//#11 ItW.Init(ForwardWire, aTool.CurrentFace());
//#11 for (;ItW.More();ItW.Next()) {
Handle(ShapeFix_Wire) STW =
new ShapeFix_Wire(ForwardWire, aTool.CurrentFace(), Precision::Confusion());
STW->FixReorder();
Handle(ShapeExtend_WireData) sbwd = STW->WireData();
Standard_Integer nb = sbwd->NbEdges();
//:abv 04.05.00: CAX-IF TRJ4: writing complete sphere with single vertex_loop //:abv 04.05.00: CAX-IF TRJ4: writing complete sphere with single vertex_loop
// check that whole wire is one seam (perhaps made of several seam edges) // check that whole wire is one seam (perhaps made of several seam edges)
//pdn remove degenerated pcurves //pdn remove degenerated pcurves
Handle(ShapeExtend_WireData) cwd = new ShapeExtend_WireData;
Standard_Integer ie;
for (ie = 1; ie <=nb; ie++) {
TopoDS_Edge edge = sbwd->Edge(ie);
if (!BRep_Tool::Degenerated(edge))
cwd->Add(edge);
}
nb = cwd->NbEdges(); // collect not degenerated edges
if(nb%2 == 0 ) { Handle(ShapeExtend_WireData) anExtWire2 = new ShapeExtend_WireData;
for ( ie = 1; ie < nb; ie++) { for (Standard_Integer ie = 1; ie <= anExtWire->NbEdges(); ie++)
if ( cwd->Edge(ie).IsSame(cwd->Edge(ie+1)) ) break; {
} TopoDS_Edge anEdge = anExtWire->Edge (ie);
if ( ie < nb ) { if (!BRep_Tool::Degenerated (anEdge))
cwd->SetLast(ie); {
for ( ie=nb/2+1; ie <= nb; ie++ ) { anExtWire2->Add (anEdge);
if ( ! cwd->Edge(ie).IsSame(cwd->Edge(nb-ie+1)) ) break; }
} }
if ( ie > nb ) { // make vertex_loop // check for seam edges
ShapeAnalysis_Edge sae; Standard_Integer nb = anExtWire2->NbEdges();
TopoDS_Vertex V = sae.FirstVertex(cwd->Edge(1)); if (nb % 2 == 0)
TopoDSToStep_MakeStepVertex mkV ( V, aTool, FP ); {
Handle(StepShape_VertexLoop) vloop = new StepShape_VertexLoop; Standard_Integer ie;
Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString ( "" ); // check if two adjacent edges are the same
vloop->Init ( name, Handle(StepShape_Vertex)::DownCast ( mkV.Value() ) ); for (ie = 1; ie < nb; ie++)
aTool.Bind(aWire, vloop); {
myError = TopoDSToStep_WireDone; if (anExtWire2->Edge (ie).IsSame (anExtWire2->Edge (ie + 1)))
done = Standard_True; {
myResult = vloop; break;
return; }
} }
// if found seam edges
if (ie < nb)
{
// make the first edge from pair last
anExtWire2->SetLast (ie);
for (ie = nb / 2 + 1; ie <= nb; ie++)
{
if (!anExtWire2->Edge (ie).IsSame (anExtWire2->Edge (nb - ie + 1)))
{
break;
}
}
if (ie > nb)
{
// make vertex_loop
ShapeAnalysis_Edge sae;
TopoDS_Vertex V = sae.FirstVertex (anExtWire2->Edge (1));
TopoDSToStep_MakeStepVertex mkV (V, aTool, FP);
Handle(StepShape_VertexLoop) vloop = new StepShape_VertexLoop;
Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString ("");
vloop->Init (name, Handle(StepShape_Vertex)::DownCast (mkV.Value()));
aTool.Bind (aWire, vloop);
myError = TopoDSToStep_WireDone;
done = Standard_True;
myResult = vloop;
return;
}
} }
} }
nb = sbwd->NbEdges();
for (Standard_Integer nEdge = 1; nEdge <= sbwd->NbEdges(); nEdge++) {
CurrentEdge = sbwd->Edge(nEdge);
//#11 CurrentEdge = ItW.Current();
//if (ItW.Current().Orientation() != ItW.Orientation())
//std::cout << "DEBUG : Attention WireExplorer Orientation" << std::endl;
for (Standard_Integer nEdge = 1; nEdge <= anExtWire->NbEdges(); nEdge++)
{
const TopoDS_Edge anEdge = anExtWire->Edge (nEdge);
// --------------------------------- // ---------------------------------
// --- Is the edge Degenerated ? --- // --- Is the edge Degenerated ? ---
// --------------------------------- // ---------------------------------
Standard_Real cf, cl; Standard_Real cf, cl;
Handle(Geom2d_Curve) theC2d = Handle(Geom2d_Curve) theC2d = BRep_Tool::CurveOnSurface (anEdge, aTool.CurrentFace(), cf, cl);
BRep_Tool::CurveOnSurface(CurrentEdge, aTool.CurrentFace(), cf, cl); if (BRep_Tool::Degenerated (anEdge))
//BRepAdaptor_Curve CA; {
//CA = BRepAdaptor_Curve(CurrentEdge, Handle(TransferBRep_ShapeMapper) errShape = new TransferBRep_ShapeMapper (aWire);
//aTool.CurrentFace()); FP->AddWarning (errShape, " EdgeLoop: Degenerated Pcurve not mapped");
//GeomAbs_CurveType typC = CA.CurveOnSurface().GetCurve().GetType(); continue;
//if (typC == GeomAbs_Line && BRep_Tool::Degenerated(CurrentEdge)) {
//Handle(TransferBRep_ShapeMapper) errShape =
//new TransferBRep_ShapeMapper(aWire);
//FP->AddWarning(errShape, " EdgeLoop: Degenerated Pcurve not mapped");
//}
if ( //:abv 26Jan00, CAX-IF TRJ3: ! theC2d.IsNull() && theC2d->IsKind(STANDARD_TYPE(Geom2d_Line)) &&
BRep_Tool::Degenerated(CurrentEdge)) {
Handle(TransferBRep_ShapeMapper) errShape =
new TransferBRep_ShapeMapper(aWire);
FP->AddWarning(errShape, " EdgeLoop: Degenerated Pcurve not mapped");
continue;
} }
else { else
//szv#4:S4163:12Mar99 SGI warns {
//TopoDS_Shape ssh = CurrentEdge.Oriented(TopAbs_FORWARD); MkEdge.Init (anEdge, aTool, FP);
//const TopoDS_Edge ForwardEdge = TopoDS::Edge(ssh); if (MkEdge.IsDone())
{
MkEdge.Init(CurrentEdge, aTool, FP); OrientedEdge = new StepShape_OrientedEdge();
if (MkEdge.IsDone()) { Epms = Handle(StepShape_Edge)::DownCast (MkEdge.Value());
OrientedEdge = new StepShape_OrientedEdge(); Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString ("");
Epms = Handle(StepShape_Edge)::DownCast(MkEdge.Value()); OrientedEdge->Init (aName, Epms, (anEdge.Orientation() == TopAbs_FORWARD));
Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString(""); mySeq.Append (OrientedEdge);
OrientedEdge->Init(aName, Epms, (CurrentEdge.Orientation() == TopAbs_FORWARD)); }
mySeq.Append(OrientedEdge); else
} {
else { Handle(TransferBRep_ShapeMapper) errShape = new TransferBRep_ShapeMapper (aWire);
Handle(TransferBRep_ShapeMapper) errShape = FP->AddWarning (errShape, " EdgeLoop: an Edge not mapped");
new TransferBRep_ShapeMapper(aWire); myError = TopoDSToStep_WireOther;
FP->AddWarning(errShape, " EdgeLoop: an Edge not mapped"); done = Standard_False;
myError = TopoDSToStep_WireOther; return;
done = Standard_False; }
return;
}
} }
} }
Standard_Integer nbEdges = mySeq.Length(); Standard_Integer nbEdges = mySeq.Length();
if ( nbEdges >0 ) { if (nbEdges > 0)
Handle(StepShape_HArray1OfOrientedEdge) aList = {
new StepShape_HArray1OfOrientedEdge(1,nbEdges); Handle(StepShape_HArray1OfOrientedEdge) aList = new StepShape_HArray1OfOrientedEdge (1, nbEdges);
for ( i=1; i<=nbEdges; i++ ) { for (Standard_Integer i = 1; i <= nbEdges; i++)
aList->SetValue(i, Handle(StepShape_OrientedEdge):: {
DownCast(mySeq.Value(i))); aList->SetValue (i, Handle(StepShape_OrientedEdge)::
DownCast (mySeq.Value (i)));
} }
Handle(StepShape_EdgeLoop) Epmsl = new StepShape_EdgeLoop; Handle(StepShape_EdgeLoop) Epmsl = new StepShape_EdgeLoop;
Handle(TCollection_HAsciiString) aName = Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString ("");
new TCollection_HAsciiString(""); Epmsl->Init (aName, aList);
Epmsl->Init(aName, aList); aTool.Bind (aWire, Epmsl);
aTool.Bind(aWire, Epmsl);
done = Standard_True; done = Standard_True;
myResult = Epmsl; myResult = Epmsl;
return; return;
} }
else { else
Handle(TransferBRep_ShapeMapper) errShape = {
new TransferBRep_ShapeMapper(aWire); Handle(TransferBRep_ShapeMapper) errShape = new TransferBRep_ShapeMapper (aWire);
FP->AddWarning(errShape, " No Edges of this Wire were mapped"); FP->AddWarning (errShape, " No Edges of this Wire were mapped");
myError = TopoDSToStep_WireOther; myError = TopoDSToStep_WireOther;
done = Standard_False; done = Standard_False;
return; return;

View File

@ -13,7 +13,7 @@ checkprops result -s 1.8e+101
set nbshapes_expected " set nbshapes_expected "
Number of shapes in shape Number of shapes in shape
VERTEX : 56881 VERTEX : 56883
EDGE : 85310 EDGE : 85310
WIRE : 37795 WIRE : 37795
FACE : 32992 FACE : 32992
@ -21,7 +21,7 @@ Number of shapes in shape
SOLID : 1308 SOLID : 1308
COMPSOLID : 0 COMPSOLID : 0
COMPOUND : 1 COMPOUND : 1
SHAPE : 215605 SHAPE : 215607
" "
checknbshapes result -ref ${nbshapes_expected} -t -m "importing file" checknbshapes result -ref ${nbshapes_expected} -t -m "importing file"
checkview -display result -3d -path ${imagedir}/${test_image}.png checkview -display result -3d -path ${imagedir}/${test_image}.png

111
tests/bugs/step/bug32922 Normal file
View File

@ -0,0 +1,111 @@
puts "============"
puts "OCC32922 Data Exchange, STEP - The torus is stored incorrectly in STEP format"
puts "============"
puts ""
#####################################################
# STEP testing the case when a torus is saved in STEP
# format with an incorrect edge order
#####################################################
pload MODELING XDE
if { [info exists imagedir] == 0 } {
set imagedir ../bug32922
if {![file exists ${imagedir}]} {
file mkdir ${imagedir}
}
}
# Generating resource file where all shape healing is off
set fdata {
ToSTEP.exec.op : SplitCommonVertex,DirectFaces
FromSTEP.exec.op : FixShape
FromSTEP.FixShape.Tolerance3d : &Runtime.Tolerance
FromSTEP.FixShape.MaxTolerance3d : &Runtime.MaxTolerance
FromSTEP.FixShape.MinTolerance3d : 1.e-7
FromSTEP.FixShape.FixFreeShellMode : 0
FromSTEP.FixShape.FixFreeFaceMode : 0
FromSTEP.FixShape.FixFreeWireMode : 0
FromSTEP.FixShape.FixSameParameterMode : 0
FromSTEP.FixShape.FixSolidMode : 0
FromSTEP.FixShape.FixShellOrientationMode : 0
FromSTEP.FixShape.CreateOpenSolidMode : 0
FromSTEP.FixShape.FixShellMode : 0
FromSTEP.FixShape.FixFaceOrientationMode : 0
FromSTEP.FixShape.FixFaceMode : 0
FromSTEP.FixShape.FixWireMode : 0
FromSTEP.FixShape.FixOrientationMode : 0
FromSTEP.FixShape.FixAddNaturalBoundMode : 0
FromSTEP.FixShape.FixMissingSeamMode : 0
FromSTEP.FixShape.FixSmallAreaWireMode : 0
FromSTEP.FixShape.RemoveSmallAreaFaceMode : 0
FromSTEP.FixShape.FixIntersectingWiresMode : 0
FromSTEP.FixShape.FixLoopWiresMode : 0
FromSTEP.FixShape.FixSplitFaceMode : 0
FromSTEP.FixShape.AutoCorrectPrecisionMode : 0
FromSTEP.FixShape.ModifyTopologyMode : 0
FromSTEP.FixShape.ModifyGeometryMode : 0
FromSTEP.FixShape.ClosedWireMode : 0
FromSTEP.FixShape.PreferencePCurveMode : 0
FromSTEP.FixShape.FixReorderMode : 0
FromSTEP.FixShape.FixSmallMode : 0
FromSTEP.FixShape.FixConnectedMode : 0
FromSTEP.FixShape.FixEdgeCurvesMode : 0
FromSTEP.FixShape.FixDegeneratedMode : 0
FromSTEP.FixShape.FixLackingMode : 0
FromSTEP.FixShape.FixSelfIntersectionMode : 0
FromSTEP.FixShape.RemoveLoopMode : 0
FromSTEP.FixShape.FixReversed2dMode : 0
FromSTEP.FixShape.FixRemovePCurveMode : 0
FromSTEP.FixShape.FixRemoveCurve3dMode : 0
FromSTEP.FixShape.FixAddPCurveMode : 0
FromSTEP.FixShape.FixAddCurve3dMode : 0
FromSTEP.FixShape.FixSeamMode : 0
FromSTEP.FixShape.FixShiftedMode : 0
FromSTEP.FixShape.FixEdgeSameParameterMode : 0
FromSTEP.FixShape.FixNotchedEdgesMode : 0
FromSTEP.FixShape.FixTailMode : 0
FromSTEP.FixShape.MaxTailAngle : 0
FromSTEP.FixShape.MaxTailWidth : 0
FromSTEP.FixShape.FixSelfIntersectingEdgeMode : 0
FromSTEP.FixShape.FixIntersectingEdgesMode : 0
FromSTEP.FixShape.FixNonAdjacentIntersectingEdgesMode : 0
FromSTEP.FixShape.FixVertexPositionMode : 0
FromSTEP.FixShape.FixVertexToleranceMode : 0
}
set new_resource_path ${imagedir}
set resource_file STEP
set fo [open "${new_resource_path}/${resource_file}" "wb"]
puts -nonewline $fo $fdata
close $fo
# Changing the path to the resource file
set old_resource_path $::env(CSF_STEPDefaults)
set env(CSF_STEPDefaults) ${new_resource_path}
# Generating, writing and reading the torus
ptorus tor 20 5
set step_file ${imagedir}/torus.stp
testwritestep ${step_file} tor
stepread ${step_file} a *
# Cheking the face of the torus
explode a_1 f
renamevar a_1_1 result
checkshape result
# Making screenshort
pcurve result
view 1 -2D- 728 20 400 400
2dfit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
# Restoring the path to the old resource file
set env(CSF_STEPDefaults) ${old_resource_path}