[Insight-developers] Missing faces using Quad Edge Mesh
Dan Mueller
dan.muel at gmail.com
Sat Jul 3 03:15:09 EDT 2010
Hi Insight Developers,
I am implementing a new mesh source based on the "cuberille" method,
depicted visually here:
http://www2.imm.dtu.dk/~jab/gallery/polygonization.html
When using itk::Mesh, the new mesh source works as expected; when
using itk::QuadEdgeMesh the resultant mesh has missing faces.
I have put together a minimal example to demonstrate the issue. The
example creates a simple cube: 8 vertices, 6 quad faces comprised of
12 triangles.
The example takes the mesh type as a command line argument (0=Mesh,
1=QuadEdgeMesh) eg.
Cube 0 cube-mesh.vtk
Cube 1 cube-qemesh.vtk
The VTK mesh output and source code is shown below.
Debugging the code I see the issue is in
itkQuadEdgeMesh.txx::AddFace at 1188: some of the edges have a "left
face" and are therefore not added to the mesh.
What is a left face? What am I doing wrong?
I am using ITK 3.18, CMake 2.6, Visual Studio C++ 2008 Express
Edition, Windows XP SP3.
Thanks for any help.
Cheers, Dan
==== cube-mesh.vtk ====
# vtk DataFile Version 2.0
File written by itkVTKPolyDataWriter
ASCII
DATASET POLYDATA
POINTS 8 float
0 0 0
1 0 0
1 1 0
0 1 0
0 0 1
1 0 1
1 1 1
0 1 1
POLYGONS 12 48
3 0 3 7
3 0 7 4
3 0 1 5
3 0 5 4
3 1 2 6
3 1 6 5
3 3 2 6
3 3 6 7
3 0 1 2
3 0 2 3
3 4 5 6
3 4 6 7
=============================
==== cube-qemesh.vtk ====
# vtk DataFile Version 2.0
File written by itkVTKPolyDataWriter
ASCII
DATASET POLYDATA
POINTS 8 float
0 0 0
1 0 0
1 1 0
0 1 0
0 0 1
1 0 1
1 1 1
0 1 1
POLYGONS 8 32
3 0 3 7
3 0 7 4
3 0 1 5
3 1 2 6
3 1 6 5
3 3 6 7
3 0 2 3
3 4 5 6
=============================
==== CMakeLists.txt ====
PROJECT(Cube)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
FIND_PACKAGE(ITK REQUIRED)
INCLUDE(${ITK_USE_FILE})
INCLUDE_DIRECTORIES(
BEFORE
${SOURCE_PATH}
${TESTING_PATH}
)
ADD_EXECUTABLE(Cube cube.cxx)
TARGET_LINK_LIBRARIES(Cube ${ITK_LIBRARIES} ITKQuadEdgeMesh)
=============================
==== Cube.cxx ====
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#define _SCL_SECURE_NO_WARNINGS
#include "itkMesh.h"
#include "itkQuadEdgeMesh.h"
#include "itkVTKPolyDataWriter.h"
/** Add quadrilateral face (as two triangles) to the given mesh. */
template<class TMesh>
void
AddFace( typename TMesh::CellIdentifier &cid,
typename TMesh::PointIdentifier face[4],
typename TMesh* mesh )
{
typedef itk::CellInterface<unsigned char, TMesh::CellTraits>
CellInterfaceType;
typedef itk::TriangleCell<CellInterfaceType> TriangleCellType;
typedef typename TriangleCellType::SelfAutoPointer TriangleAutoPointer;
typedef typename TriangleCellType::CellAutoPointer TriangleCellAutoPointer;
// Triangle 1
TriangleCellAutoPointer newTri1;
newTri1.TakeOwnership( new TriangleCellType );
TMesh::PointIdentifier tri1[3];
tri1[0] = face[0]; tri1[1] = face[1]; tri1[2] = face[2];
newTri1->SetPointIds( tri1 );
mesh->SetCell( cid++, newTri1 );
// Triangle 2
TriangleCellAutoPointer newTri2;
newTri2.TakeOwnership( new TriangleCellType );
TMesh::PointIdentifier tri2[3];
tri2[0] = face[0]; tri2[1] = face[2]; tri2[2] = face[3];
newTri2->SetPointIds( tri2 );
mesh->SetCell( cid++, newTri2 );
}
/** Create cube mesh. */
template<class TMesh>
void
CreateCube( char * filenameMesh )
{
// Create mesh
TMesh::Pointer mesh = TMesh::New();
// Add vertices
TMesh::PointIdentifier vid = 0;
TMesh::PointType v[8];
v[0][0] = 0.0; v[0][1] = 0.0; v[0][2] = 0.0;
v[1][0] = 1.0; v[1][1] = 0.0; v[1][2] = 0.0;
v[2][0] = 1.0; v[2][1] = 1.0; v[2][2] = 0.0;
v[3][0] = 0.0; v[3][1] = 1.0; v[3][2] = 0.0;
v[4][0] = 0.0; v[4][1] = 0.0; v[4][2] = 1.0;
v[5][0] = 1.0; v[5][1] = 0.0; v[5][2] = 1.0;
v[6][0] = 1.0; v[6][1] = 1.0; v[6][2] = 1.0;
v[7][0] = 0.0; v[7][1] = 1.0; v[7][2] = 1.0;
for ( unsigned int i=0; i<8; i++)
mesh->GetPoints()->InsertElement( vid++, v[i] );
// Add faces
TMesh::CellIdentifier cid = 0;
TMesh::PointIdentifier f[4];
/*Face0*/ f[0]=0; f[1]=3; f[2]=7; f[3]=4; AddFace<TMesh>(cid, f, mesh);
/*Face1*/ f[0]=0; f[1]=1; f[2]=5; f[3]=4; AddFace<TMesh>(cid, f, mesh);
/*Face2*/ f[0]=1; f[1]=2; f[2]=6; f[3]=5; AddFace<TMesh>(cid, f, mesh);
/*Face3*/ f[0]=3; f[1]=2; f[2]=6; f[3]=7; AddFace<TMesh>(cid, f, mesh);
/*Face4*/ f[0]=0; f[1]=1; f[2]=2; f[3]=3; AddFace<TMesh>(cid, f, mesh);
/*Face5*/ f[0]=4; f[1]=5; f[2]=6; f[3]=7; AddFace<TMesh>(cid, f, mesh);
// Write mesh
typedef itk::VTKPolyDataWriter< TMesh > MeshFileWriterType;
std::cout << "Writing output mesh: " << filenameMesh << std::endl;
MeshFileWriterType::Pointer writer = MeshFileWriterType::New();
writer->SetInput( mesh );
writer->SetFileName( filenameMesh );
writer->Update();
}
int main(int argc, char * argv [])
{
try
{
// Typedefs
const unsigned int Dimension = 3;
typedef unsigned char PixelType;
typedef itk::Mesh< PixelType, Dimension > MeshType;
typedef itk::QuadEdgeMesh< PixelType, Dimension > QEMeshType;
// Read command-line parameters
if ( argc < 3 )
{
std::cout << "USAGE: " << argv[0] << " Type Filename" << std::endl;
return EXIT_FAILURE;
}
int type = atoi( argv[1] );
char * filename = argv[2];
// Create cube using normal mesh or quad-edge mesh
switch ( type )
{
case 0: CreateCube<MeshType>( filename );
break;
case 1: CreateCube<QEMeshType>( filename );
break;
default: std::cout << "Expected mesh type 0 or 1" << std::endl;
break;
}
return EXIT_SUCCESS;
}
catch (itk::ExceptionObject & err)
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return EXIT_FAILURE;
}
}
=============================
-------------- next part --------------
PROJECT(Cube)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
FIND_PACKAGE(ITK REQUIRED)
INCLUDE(${ITK_USE_FILE})
INCLUDE_DIRECTORIES(
BEFORE
${SOURCE_PATH}
${TESTING_PATH}
)
ADD_EXECUTABLE(Cube cube.cxx)
TARGET_LINK_LIBRARIES(Cube ${ITK_LIBRARIES} ITKQuadEdgeMesh)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Cube.cxx
Type: application/octet-stream
Size: 3859 bytes
Desc: not available
URL: <http://www.itk.org/mailman/private/insight-developers/attachments/20100703/07874e62/attachment.obj>
More information about the Insight-developers
mailing list