OCC22503 Face triangulation causes shading display of whole shape to fail
authorABV <>
Thu, 19 May 2011 11:00:31 +0000 (11:00 +0000)
committerbugmaster <bugmaster@opencascade.com>
Mon, 5 Mar 2012 15:28:54 +0000 (19:28 +0400)
src/MeshTest/MeshTest_CheckTopology.cxx
src/MeshTest/MeshTest_CheckTopology.hxx
src/MeshTest/MeshTest_PluginCommands.cxx
src/Poly/Poly_Connect.cxx

index 53b4659..b73dac4 100755 (executable)
@@ -4,7 +4,7 @@
 
 #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>
@@ -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);
+      }
   }
 }
 
index 2bf4f20..8631634 100755 (executable)
 #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
index 5ec77a8..7c9f0aa 100755 (executable)
@@ -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}"<<endl;
@@ -369,6 +373,7 @@ static Standard_Integer checktopo (Draw_Interpretor& di, int n, const char ** a)
     cout<<endl;
   }
 
+  // dump info on edges
   Standard_Integer nbAsync = aCheck.NbAsyncEdges();
   if (nbAsync > 0) {
     cout<<"async edges:"<<endl;
@@ -379,9 +384,23 @@ static Standard_Integer checktopo (Draw_Interpretor& di, int n, const char ** a)
     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;
 }
index e43f21f..83fcfbb 100755 (executable)
@@ -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];
+  }
 }
 
 //=======================================================================