1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0025405: STL reader doesn't keep shared nodes

An improved RWSTL::ReadFile() method + a draw-command returning the number of nodes and triangles for a MeshVS_Mesh object based on STL mesh data source.

An indexed map of points is replaced by a CellFilter of XYZ objects already implemented in BRepBuilderAPI.
Also, BRepBuilderAPI_VertexInspector became exported for TKTopAlgo library (Standard_EXPORT is added for the methods of this class).

Standard_EXPORT is removed for in-line methods of BRepBuilderAPI_VertexInspector

Test-case for issue #25405

Update of test-cases, according to new behavior
This commit is contained in:
vro 2014-10-30 12:18:22 +03:00 committed by bugmaster
parent 4084fb643c
commit fcc61cc4c9
5 changed files with 110 additions and 12 deletions

View File

@ -37,8 +37,7 @@ class BRepBuilderAPI_VertexInspector : public NCollection_CellFilter_InspectorXY
public:
typedef Standard_Integer Target;
//! Constructor; remembers the tolerance
BRepBuilderAPI_VertexInspector (const Standard_Real theTol)
: myTol(theTol*theTol)
BRepBuilderAPI_VertexInspector (const Standard_Real theTol):myTol(theTol*theTol)
{}
//! Keep the points used for comparison
@ -66,7 +65,7 @@ public:
}
//! Implementation of inspection method
NCollection_CellFilter_Action Inspect (const Standard_Integer theTarget);
Standard_EXPORT NCollection_CellFilter_Action Inspect (const Standard_Integer theTarget);
private:
Standard_Real myTol;

View File

@ -30,6 +30,35 @@
#include <stdio.h>
#include <gp_Vec.hxx>
#include <BRepBuilderAPI_CellFilter.hxx>
#include <BRepBuilderAPI_VertexInspector.hxx>
// A static method adding nodes to a mesh and keeping coincident (sharing) nodes.
static Standard_Integer AddVertex(Handle(StlMesh_Mesh)& mesh,
BRepBuilderAPI_CellFilter& filter,
BRepBuilderAPI_VertexInspector& inspector,
const gp_XYZ& p)
{
Standard_Integer index;
inspector.SetCurrent(p);
gp_XYZ minp = inspector.Shift(p, -Precision::Confusion());
gp_XYZ maxp = inspector.Shift(p, +Precision::Confusion());
filter.Inspect(minp, maxp, inspector);
const TColStd_ListOfInteger& indices = inspector.ResInd();
if (indices.IsEmpty() == Standard_False)
{
index = indices.First(); // it should be only one
inspector.ClearResList();
}
else
{
index = mesh->AddVertex(p.X(), p.Y(), p.Z());
filter.Add(index, p);
inspector.Add(p);
}
return index;
}
// constants
static const size_t HEADER_SIZE = 84;
static const size_t SIZEOF_STL_FACET = 50;
@ -357,6 +386,10 @@ Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath,
Handle(StlMesh_Mesh) ReadMesh = new StlMesh_Mesh ();
ReadMesh->AddDomain ();
// Filter unique vertices to share the nodes of the mesh.
BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion());
BRepBuilderAPI_VertexInspector inspector(Precision::Confusion());
for (ifacet=1; ifacet<=NBFACET; ++ifacet) {
// read normal coordinates
fx = ReadFloat2Double(theFile);
@ -378,9 +411,12 @@ Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath,
fy3 = ReadFloat2Double(theFile);
fz3 = ReadFloat2Double(theFile);
i1 = ReadMesh->AddOnlyNewVertex (fx1,fy1,fz1);
i2 = ReadMesh->AddOnlyNewVertex (fx2,fy2,fz2);
i3 = ReadMesh->AddOnlyNewVertex (fx3,fy3,fz3);
// Add vertices.
i1 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx1, fy1, fz1));
i2 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx2, fy2, fz2));
i3 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx3, fy3, fz3));
// Add triangle.
ReadMesh->AddTriangle (i1,i2,i3,fx,fy,fz);
// skip extra bytes
@ -389,8 +425,8 @@ Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath,
theFile.Close ();
return ReadMesh;
}
//=======================================================================
//function : ReadAscii
//Design :
@ -442,6 +478,10 @@ Handle(StlMesh_Mesh) RWStl::ReadAscii (const OSD_Path& thePath,
ReadMesh = new StlMesh_Mesh();
ReadMesh->AddDomain();
// Filter unique vertices to share the nodes of the mesh.
BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion());
BRepBuilderAPI_VertexInspector inspector(Precision::Confusion());
// main reading
Message_ProgressSentry aPS (theProgInd, "Triangles", 0, (nbTris - 1) * 1.0 / IND_THRESHOLD, 1);
for (iTri = 0; iTri < nbTris && aPS.More();)
@ -469,9 +509,9 @@ Handle(StlMesh_Mesh) RWStl::ReadAscii (const OSD_Path& thePath,
// here the facet must be built and put in the mesh datastructure
i1 = ReadMesh->AddOnlyNewVertex (aV1.X(), aV1.Y(), aV1.Z());
i2 = ReadMesh->AddOnlyNewVertex (aV2.X(), aV2.Y(), aV2.Z());
i3 = ReadMesh->AddOnlyNewVertex (aV3.X(), aV3.Y(), aV3.Z());
i1 = AddVertex(ReadMesh, uniqueVertices, inspector, aV1);
i2 = AddVertex(ReadMesh, uniqueVertices, inspector, aV2);
i3 = AddVertex(ReadMesh, uniqueVertices, inspector, aV3);
ReadMesh->AddTriangle (i1, i2, i3, aN.X(), aN.Y(), aN.Z());
// skip the keywords "endloop"

View File

@ -1185,6 +1185,38 @@ static Standard_Integer tovrml(Draw_Interpretor& di, Standard_Integer argc, cons
//-----------------------------------------------------------------------------
static Standard_Integer meshinfo(Draw_Interpretor& di,
Standard_Integer argc,
const char** argv)
{
if ( argc != 2 )
{
di << "Wrong number of parameters. Use : meshinfo mesh" << "\n";
return 0;
}
Handle(MeshVS_Mesh) aMesh = getMesh(argv[ 1 ], di);
if ( aMesh.IsNull() )
{
di << "Mesh not found" << "\n";
return 0;
}
Handle(XSDRAWSTLVRML_DataSource) stlMeshSource = Handle(XSDRAWSTLVRML_DataSource)::DownCast(aMesh->GetDataSource());
if (!stlMeshSource.IsNull())
{
const TColStd_PackedMapOfInteger& nodes = stlMeshSource->GetAllNodes();
const TColStd_PackedMapOfInteger& tris = stlMeshSource->GetAllElements();
di << "Nb nodes = " << nodes.Extent() << "\n";
di << "Nb triangles = " << tris.Extent() << "\n";
}
return 0;
}
//-----------------------------------------------------------------------------
void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
{
const char* g = "XSTEP-STL/VRML"; // Step transfer file commands
@ -1213,6 +1245,7 @@ void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
theCommands.Add ("meshtext", "display text labels", __FILE__, meshtext, g );
theCommands.Add ("meshdeform", "display deformed mesh", __FILE__, meshdeform, g );
theCommands.Add ("mesh_edge_width", "set width of edges", __FILE__, mesh_edge_width, g );
theCommands.Add ("meshinfo", "displays the number of nodes and triangles", __FILE__, meshinfo, g );
}
//==============================================================================

View File

@ -36,7 +36,8 @@ checkcolor $x_coord $y_coord 0 0 0.36
meshcolors m nodal 0
puts "\nDisplay nodal color presentation"
checkcolor $x_coord $y_coord 0.46 0.12 0.37
#checkcolor $x_coord $y_coord 0.46 0.12 0.37
checkcolor $x_coord $y_coord 0.72 0.72 0.70
set only_screen 1

25
tests/bugs/xde/bug25405 Normal file
View File

@ -0,0 +1,25 @@
puts "========"
puts "OCC25405"
puts "========"
puts ""
########################################
# STL reader doesn't keep shared nodes
########################################
set GoodNodesNB 64215
set GoodTrianglesNB 117694
vinit
meshfromstl s [locate_data_file head.stl]
set bug_info [meshinfo s]
if {$GoodNodesNB != [lindex $bug_info 3]} {
puts "ERROR: Number of nodes is incorrect: [lindex $bug_info 3] (should be $GoodNodesNB)"
}
if {$GoodTrianglesNB != [lindex $bug_info 7]} {
puts "ERROR: Number of triangles is incorrect: [lindex $bug_info 7] (should be $GoodTrianglesNB)"
}
set only_screen 1