#include <MeshTest_CheckTopology.hxx>
#include <BRep_Tool.hxx>
-#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_PackedMapOfInteger.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Edge.hxx>
#endif
continue;
}
+
// remember boundary nodes
- TColStd_MapOfInteger aMapBndNodes;
+ TColStd_PackedMapOfInteger aMapBndNodes;
TopExp_Explorer ex(aFace, TopAbs_EDGE);
for (; ex.More(); ex.Next()) {
const TopoDS_Edge& aEdge = TopoDS::Edge(ex.Current());
aMapBndNodes.Add(aNodes(i));
}
+ TColStd_PackedMapOfInteger aUsedNodes;
+
+ // check of free links and nodes
Poly_Connect aConn(aT);
const Poly_Array1OfTriangle& aTriangles = aT->Triangles();
Standard_Integer nbTri = aT->NbTriangles(), i, j, n[3], t[3];
for (i = 1; i <= nbTri; i++) {
aTriangles(i).Get(n[0], n[1], n[2]);
+
+ aUsedNodes.Add (n[0]);
+ aUsedNodes.Add (n[1]);
+ aUsedNodes.Add (n[2]);
+
aConn.Triangles(i, t[0], t[1], t[2]);
for (j = 0; j < 3; j++) {
if (t[j] == 0) {
}
}
}
+
+ // check of free nodes
+ Standard_Integer aNbNodes = aT->NbNodes();
+ for (Standard_Integer i = 1; i <= aNbNodes; i++)
+ if ( ! aUsedNodes.Contains(i) )
+ {
+ myFreeNodeFaces.Append (iF);
+ myFreeNodeNums.Append (i);
+ }
}
}
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx>
-// This class checks topology of the mesh presented by
-// triangulations of faces.
-//
-// The following error are reported:
-// - free links. A link is considered free if it has only one
-// neighboring triangle and at least one of its nodes belongs to
-// interior of the face rather than to its boundary.
-// - cross face errors. It is a situation when a point on a common
-// boundary between two faces has different 3d coordinates on each
-// triangulation. The error is reported if the distance is greater
-// than a deflection written in triangulations.
-// - asynchronous edges. It is an edge having polygons on two neighboring
-// triangulations with different number of points in the polygons
+//! This class checks topology of the mesh presented by
+//! triangulations of faces.
+//!
+//! The following error are reported:
+//! - free links. A link is considered free if it has only one
+//! neighboring triangle and at least one of its nodes belongs to
+//! interior of the face rather than to its boundary.
+//! - cross face errors. It is a situation when a point on a common
+//! boundary between two faces has different 3d coordinates on each
+//! triangulation. The error is reported if the distance is greater
+//! than a deflection written in triangulations.
+//! - asynchronous edges. It is an edge having polygons on two neighboring
+//! triangulations with different number of points in the polygons.
+//! - free nodes -- nodes not shared by any triangle.
class MeshTest_CheckTopology
{
public:
+ //! constructor
MeshTest_CheckTopology(const TopoDS_Shape& theShape)
: myShape(theShape) {}
- // constructor
+ //! performs checking
Standard_EXPORT void Perform();
- // performs checking
+ //! returns the number of faces with free links
Standard_Integer NbFacesWithFL() const
{ return myMapFaceLinks.Extent(); }
- // returns the number of faces with free links
+ //! returns the number (in the shape) of a face with free links
+ //! with the given index
Standard_Integer GetFaceNumWithFL(const Standard_Integer theIndex) const
{ return myMapFaceLinks.FindKey(theIndex); }
- // returns the number (in the shape) of a face with free links
- // with the given index
+ //! returns the number free links on a face with the given index
Standard_Integer NbFreeLinks(const Standard_Integer theIndex) const
{ return myMapFaceLinks(theIndex).Length() / 2; }
- // returns the number free links on a face with the given index
+ //! gets the numbers of nodes of a free link with the given index
+ //! in the face with the given index
Standard_EXPORT void GetFreeLink(const Standard_Integer theFaceIndex,
const Standard_Integer theLinkIndex,
Standard_Integer& theNode1,
Standard_Integer& theNode2) const;
- // gets the numbers of nodes of a free link with the given index
- // in the face with the given index
+ //! returns the number of cross face errors
Standard_Integer NbCrossFaceErrors() const
{ return myErrorsVal.Length(); }
- // returns the number of cross face errors
+ //! gets the attributes of a cross face error with the given index
Standard_EXPORT void GetCrossFaceError(const Standard_Integer theIndex,
Standard_Integer& theFace1,
Standard_Integer& theNode1,
Standard_Integer& theFace2,
Standard_Integer& theNode2,
Standard_Real& theValue) const;
- // gets the attributes of a cross face error with the given index
+ //! returns the number of async edges
Standard_Integer NbAsyncEdges() const
{ return myAsyncEdges.Length(); }
- // returns the number of async edges
+ //! returns the number (in the shape) of an async edge with the given index
Standard_Integer GetAsyncEdgeNum(const Standard_Integer theIndex) const
{ return myAsyncEdges(theIndex); }
- // returns the number (in the shape) of an async edge with the given index
+
+ //! returns the number of free nodes
+ Standard_Integer NbFreeNodes() const
+ { return myFreeNodeFaces.Length(); }
+
+ //! returns the number of face containing the Index-th detected free node,
+ //! and number of this node in the triangulation of that face
+ void GetFreeNodeNum (const Standard_Integer theIndex,
+ Standard_Integer& theFaceNum,
+ Standard_Integer& theNodeNum) const
+ {
+ theFaceNum = myFreeNodeFaces(theIndex);
+ theNodeNum = myFreeNodeNums(theIndex);
+ }
private:
TopoDS_Shape myShape;
NCollection_IndexedDataMap<Standard_Integer,TColStd_SequenceOfInteger>
myMapFaceLinks;
+
TColStd_SequenceOfInteger myErrors;
TColStd_SequenceOfReal myErrorsVal;
+
TColStd_SequenceOfInteger myAsyncEdges;
+ TColStd_SequenceOfInteger myFreeNodeFaces;
+ TColStd_SequenceOfInteger myFreeNodeNums;
};
#endif
TopExp::MapShapes (shape, TopAbs_FACE, aMapF);
Standard_CString name = ".";
+ // execute check
MeshTest_CheckTopology aCheck(shape);
aCheck.Perform();
+
+ // dump info on free links inside the triangulation
Standard_Integer nbFree = 0;
Standard_Integer nbFac = aCheck.NbFacesWithFL(), i, k;
if (nbFac > 0) {
}
}
+ // dump info on cross face errors
Standard_Integer nbErr = aCheck.NbCrossFaceErrors();
if (nbErr > 0) {
cout<<"cross face errors: {face1, node1, face2, node2, distance}"<<endl;
cout<<endl;
}
+ // dump info on edges
Standard_Integer nbAsync = aCheck.NbAsyncEdges();
if (nbAsync > 0) {
cout<<"async edges:"<<endl;
cout<<endl;
}
- if (nbFree > 0 || nbErr > 0 || nbAsync > 0)
- di<<"Free_links "<<nbFree
- <<" Cross_face_errors "<<nbErr
- <<" Async_edges "<<nbAsync << " ";
+ // dump info on free nodes
+ Standard_Integer nbFreeNodes = aCheck.NbFreeNodes();
+ if (nbFreeNodes > 0) {
+ cout << "free nodes (in pairs: face / node): " << endl;
+ for (i=1; i <= nbFreeNodes; i++) {
+ Standard_Integer iface, inode;
+ aCheck.GetFreeNodeNum(i, iface, inode);
+ cout << "{" << iface << " " << inode << "} ";
+ }
+ cout << endl;
+ }
+
+ // output errors summary to DRAW
+ if ( nbFree > 0 || nbErr > 0 || nbAsync > 0 || nbFreeNodes > 0 )
+ di << "Free_links " << nbFree
+ << " Cross_face_errors " << nbErr
+ << " Async_edges " << nbAsync
+ << " Free_nodes " << nbFreeNodes << " ";
return 0;
}