From 446e11f3c635f8aaf7127f724be02d7a8d706ad7 Mon Sep 17 00:00:00 2001 From: ABV <> Date: Thu, 19 May 2011 11:00:31 +0000 Subject: [PATCH] OCC22503 Face triangulation causes shading display of whole shape to fail --- src/MeshTest/MeshTest_CheckTopology.cxx | 22 +++++++- src/MeshTest/MeshTest_CheckTopology.hxx | 69 +++++++++++++++--------- src/MeshTest/MeshTest_PluginCommands.cxx | 27 ++++++++-- src/Poly/Poly_Connect.cxx | 18 ++++--- 4 files changed, 97 insertions(+), 39 deletions(-) diff --git a/src/MeshTest/MeshTest_CheckTopology.cxx b/src/MeshTest/MeshTest_CheckTopology.cxx index 53b4659a68..b73dac4350 100755 --- a/src/MeshTest/MeshTest_CheckTopology.cxx +++ b/src/MeshTest/MeshTest_CheckTopology.cxx @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -112,8 +112,9 @@ void MeshTest_CheckTopology::Perform () #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()); @@ -126,11 +127,19 @@ void MeshTest_CheckTopology::Perform () 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) { @@ -152,6 +161,15 @@ void MeshTest_CheckTopology::Perform () } } } + + // 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); + } } } diff --git a/src/MeshTest/MeshTest_CheckTopology.hxx b/src/MeshTest/MeshTest_CheckTopology.hxx index 2bf4f20660..86316340cc 100755 --- a/src/MeshTest/MeshTest_CheckTopology.hxx +++ b/src/MeshTest/MeshTest_CheckTopology.hxx @@ -11,77 +11,96 @@ #include #include -// 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 myMapFaceLinks; + TColStd_SequenceOfInteger myErrors; TColStd_SequenceOfReal myErrorsVal; + TColStd_SequenceOfInteger myAsyncEdges; + TColStd_SequenceOfInteger myFreeNodeFaces; + TColStd_SequenceOfInteger myFreeNodeNums; }; #endif diff --git a/src/MeshTest/MeshTest_PluginCommands.cxx b/src/MeshTest/MeshTest_PluginCommands.cxx index 5ec77a8011..7c9f0aa229 100755 --- a/src/MeshTest/MeshTest_PluginCommands.cxx +++ b/src/MeshTest/MeshTest_PluginCommands.cxx @@ -318,8 +318,11 @@ static Standard_Integer checktopo (Draw_Interpretor& di, int n, const char ** a) 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) { @@ -357,6 +360,7 @@ static Standard_Integer checktopo (Draw_Interpretor& di, int n, const char ** a) } } + // dump info on cross face errors Standard_Integer nbErr = aCheck.NbCrossFaceErrors(); if (nbErr > 0) { cout<<"cross face errors: {face1, node1, face2, node2, distance}"< 0) { cout<<"async edges:"< 0 || nbErr > 0 || nbAsync > 0) - di<<"Free_links "< 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; } diff --git a/src/Poly/Poly_Connect.cxx b/src/Poly/Poly_Connect.cxx index e43f21f72d..83fcfbb847 100755 --- a/src/Poly/Poly_Connect.cxx +++ b/src/Poly/Poly_Connect.cxx @@ -204,15 +204,17 @@ void Poly_Connect::Initialize(const Standard_Integer N) mynode = N; myfirst = Triangle(N); mytr = myfirst; - - Standard_Integer i, no[3]; - const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles(); - triangles(myfirst).Get(no[0], no[1], no[2]); - for (i = 0; i < 3; i++) - if (no[i] == mynode) break; - myothernode = no[(i+2)%3]; mysense = Standard_True; - mymore = Standard_True; + mymore = (myfirst != 0); + if (mymore) + { + Standard_Integer i, no[3]; + const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles(); + triangles(myfirst).Get(no[0], no[1], no[2]); + for (i = 0; i < 3; i++) + if (no[i] == mynode) break; + myothernode = no[(i+2)%3]; + } } //=======================================================================