Okay, I'm in the home stretch here... I've changed the code slightly to output a XMLImageData file and take an input surface. CMake runs fine on it, but it dies in the make process with this error:<br><br>CMakeFiles/SurfaceToImage.dir/SurfaceToImage.cxx.o: In function `vtkSmartPointer<vtkPolyDataToImageStencil>::New()':<br>
/usr/local/include/vtk-5.7/vtkSmartPointer.h:113: undefined reference to `vtkPolyDataToImageStencil::New()'<br><br>The smart pointer line is fundamentally no different than any other line of code. ??? Here's my code:<br>
____________________________________________________________________________________________________________________<br>#include <vtkSmartPointer.h><br>#include <vtkPolyData.h><br>#include <vtkImageData.h><br>
#include <vtkPolyDataReader.h><br>#include <vtkXMLImageDataWriter.h><br>#include <vtkPolyDataToImageStencil.h><br>#include <vtkImageStencil.h><br>#include <vtkPointData.h><br> <br>/**<br> * This program generates a sphere (closed surface, vtkPolyData) and converts it into volume<br>
* representation (vtkImageData) where the foreground voxels are 1 and the background voxels are<br> * 0. Internally vtkPolyDataToImageStencil is utilized. The resultant image is saved to disk <br> * in XML image data format.<br>
*/<br>int main (int argc, char *argv[])<br>{ <br> if( argc < 3 )<br> {<br> std::cerr << "Usage: " << argv[0];<br> std::cerr << " inputImageFile outputImageFile " << std::endl; <br>
return EXIT_FAILURE;<br> }<br><br> vtkSmartPointer<vtkPolyDataReader> surfaceSource = vtkSmartPointer<vtkPolyDataReader>::New();<br> surfaceSource->SetFileName( argv[1] );<br> vtkSmartPointer<vtkPolyData> pd = surfaceSource->GetOutput();<br>
surfaceSource->Update();<br> <br> vtkSmartPointer<vtkImageData> whiteImage = vtkSmartPointer<vtkImageData>::New(); <br> double bounds[6];<br> pd->GetBounds(bounds);<br> double spacing[3]; // desired volume spacing<br>
spacing[0] = 0.5;<br> spacing[1] = 0.5;<br> spacing[2] = 0.5;<br> whiteImage->SetSpacing(spacing);<br> <br> // compute dimensions<br> int dim[3];<br> for (int i = 0; i < 3; i++)<br> {<br> dim[i] = static_cast<int>(ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]));<br>
}<br> whiteImage->SetDimensions(dim);<br> whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);<br> <br> double origin[3];<br> // NOTE: I am not sure whether or not we had to add some offset!<br>
origin[0] = bounds[0];// + spacing[0] / 2;<br> origin[1] = bounds[2];// + spacing[1] / 2;<br> origin[2] = bounds[4];// + spacing[2] / 2;<br> whiteImage->SetOrigin(origin);<br> <br> whiteImage->SetScalarTypeToUnsignedChar();<br>
whiteImage->AllocateScalars();<br> <br> // fill the image with foreground voxels:<br> unsigned char inval = 255;<br> unsigned char outval = 0;<br> vtkIdType count = whiteImage->GetNumberOfPoints();<br> for (vtkIdType i = 0; i < count; ++i)<br>
{<br> whiteImage->GetPointData()->GetScalars()->SetTuple1(i, inval);<br> }<br> <br> // polygonal data --> image stencil:<br> vtkSmartPointer<vtkPolyDataToImageStencil> pol2stenc = vtkSmartPointer<vtkPolyDataToImageStencil>::New(); //<---- This is the 'problem'???<br>
pol2stenc->SetInput(pd);<br> pol2stenc->SetOutputOrigin(origin);<br> pol2stenc->SetOutputSpacing(spacing);<br> pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());<br> pol2stenc->Update();<br>
<br> // cut the corresponding white image and set the background:<br> vtkSmartPointer<vtkImageStencil> imgstenc = vtkSmartPointer<vtkImageStencil>::New();<br> imgstenc->SetInput(whiteImage);<br> imgstenc->SetStencil(pol2stenc->GetOutput());<br>
imgstenc->ReverseStencilOff();<br> imgstenc->SetBackgroundValue(outval);<br> imgstenc->Update();<br> <br> vtkSmartPointer<vtkXMLImageDataWriter> writer = vtkSmartPointer<vtkXMLImageDataWriter>::New();<br>
writer->SetFileName( argv[2] ); //"SphereVolume.mhd");<br> writer->SetInput(imgstenc->GetOutput());<br> writer->Write(); <br> <br> return EXIT_SUCCESS;<br>}<br>____________________________________________________________________________________________________________________<br>
<br><br><br><div class="gmail_quote">On Tue, Apr 20, 2010 at 6:37 AM, David Doria <span dir="ltr"><<a href="mailto:daviddoria%2Bvtk@gmail.com">daviddoria+vtk@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div class="im">On Tue, Apr 20, 2010 at 3:34 AM, Lars Friedrich Lars <span dir="ltr"><<a href="mailto:lars-friedrich@gmx.net" target="_blank">lars-friedrich@gmx.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hello David Welch,<br>
<br>
referring to your original question "how to voxelize a simple surface" I added a VTK wiki example:<br>
<br>
<a href="http://www.cmake.org/Wiki/VTK/Examples/PolyDataToImageData" target="_blank">http://www.cmake.org/Wiki/VTK/Examples/PolyDataToImageData</a><br>
<br>
It shows how we could incorporate vtkPolyDataToImageStencil into voxelizing a *closed* surface.<br>
<br>
Please NOTE: as I wrote on the example page I'm not sure about the image origin. The visual agreement in the sphere-image-overlay (paraview) is not perfect and I'm not sure whether or not we had to introduce some spacing-dependent image origin offset to compensate that. If you use that code and find out something in this direction it would be great if you contributed it to that example!<br>
<br>
HTH,<br>
<br>
lars<br><br></blockquote><div class="gmail_quote"><br></div></div>David W -</div><div class="gmail_quote"><br></div><div class="gmail_quote">Yes, the normals are definitely necessary. With a mesh, you can simply run vtkPolyDataNormals. With a point set, you'd have to use my vtkPointSetNormalEstimation and vtkPointSetNormalOrientation filters (part of the same surface reconstruction journal submission). Unfortunately I don't know what it means by the missing ImageData element.</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">Lars -</div><div class="gmail_quote"><br>Looks great, thanks! Hopefully David W will play around with it and solve the mystery of the origin problem.</div><div class="gmail_quote">
<br clear="all">Thanks,<br><font color="#888888"><br><div>David </div></font></div>
</blockquote></div><br><br clear="all"><br>-- <br>David Welch<br>Graduate Student<br>Dept. of Biomedical Engineering<br>University of Iowa<br>Lab: (319) 335-5279<br>