[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