mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
OCC22503 Face triangulation causes shading display of whole shape to fail
This commit is contained in:
parent
587630c5be
commit
446e11f3c6
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,77 +11,96 @@
|
||||
#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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
Loading…
x
Reference in New Issue
Block a user