PowercrustExtractSurface

VTKExamples/Cxx/Points/PowercrustExtractSurface


Description

The Powercrust, or Crust algorithm, reconstructs surfaces from unorganized points.

If the example is run without an argument, the example uses random points on a spherical shell. With a filename, the example uses the points on the vtkPolyData.

Cite

See The Power Crust for technical details.

Info

CompareExtractSurface compares three surface extraction algorithms.

Seealso

ExtractSurface reconstructs surfaces and is included with the VTK distribution. PoissonExtractSurface reconstructs surfaces and is implemented as a VTK remote module.

Danger

The code is covered by the GPL License and may restrict commercial use..

Info

The Power Crust is implemented as a VTK Remote Module.

To use the Power Crust in VTK:

  1. Download Powercrust.remote.cmake and place it in your VTK/Remote directory.
  2. Reconfigure your VTK build with cmake
  3. Enable the remote module by setting Module_Powercrust:BOOL=ON.
  4. make

Code

PowercrustExtractSurface.cxx

#include <vtkSmartPointer.h>

#include <vtkPLYReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkOBJReader.h>
#include <vtkSTLReader.h>
#include <vtkPointSource.h>

#include <vtkPowerCrustSurfaceReconstruction.h>

#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>

#include <vtkNamedColors.h>
#include <vtksys/SystemTools.hxx>

namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName);
}

int main (int argc, char *argv[])
{
  vtkSmartPointer<vtkPolyData> polyData = ReadPolyData(argc > 1 ? argv[1] : "");;
  std::cout << "# of points: " << polyData->GetNumberOfPoints() << std::endl;

  vtkSmartPointer<vtkPowerCrustSurfaceReconstruction> surface =
    vtkSmartPointer<vtkPowerCrustSurfaceReconstruction>::New();
  surface->SetInputData (polyData);

  vtkSmartPointer<vtkPolyDataMapper> surfaceMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  surfaceMapper->SetInputConnection(surface->GetOutputPort());

  vtkSmartPointer<vtkNamedColors> colors =
    vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkProperty> back =
    vtkSmartPointer<vtkProperty>::New();
  back->SetColor(colors->GetColor3d("banana").GetData());

  vtkSmartPointer<vtkActor> surfaceActor =
    vtkSmartPointer<vtkActor>::New();
  surfaceActor->SetMapper(surfaceMapper);
  surfaceActor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData());
  surfaceActor->SetBackfaceProperty(back);

  // Create graphics stuff
  //
  vtkSmartPointer<vtkRenderer> ren1 =
    vtkSmartPointer<vtkRenderer>::New();
  ren1->SetBackground(colors->GetColor3d("SlateGray").GetData());

  vtkSmartPointer<vtkRenderWindow> renWin =
    vtkSmartPointer<vtkRenderWindow>::New();
  renWin->AddRenderer(ren1);
  renWin->SetSize(512,512);

  vtkSmartPointer<vtkRenderWindowInteractor> iren =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  iren->SetRenderWindow(renWin);

  // Add the actors to the renderer, set the background and size
  //
  ren1->AddActor(surfaceActor);

  // Generate an interesting view
  //
  ren1->ResetCamera();
  ren1->GetActiveCamera()->Azimuth(120);
  ren1->GetActiveCamera()->Elevation(30);
  ren1->GetActiveCamera()->Dolly(1.0);
  ren1->ResetCameraClippingRange();

  iren->Initialize();
  iren->Start();

  return EXIT_SUCCESS;
}

namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName)
{
  vtkSmartPointer<vtkPolyData> polyData;
  std::string extension = vtksys::SystemTools::GetFilenameExtension(std::string(fileName));
  if (extension == ".ply")
  {
    vtkSmartPointer<vtkPLYReader> reader =
      vtkSmartPointer<vtkPLYReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".vtp")
  {
    vtkSmartPointer<vtkXMLPolyDataReader> reader =
      vtkSmartPointer<vtkXMLPolyDataReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".obj")
  {
    vtkSmartPointer<vtkOBJReader> reader =
      vtkSmartPointer<vtkOBJReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else if (extension == ".stl")
  {
    vtkSmartPointer<vtkSTLReader> reader =
      vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName (fileName);
    reader->Update();
    polyData = reader->GetOutput();
  }
  else
  {
    vtkSmartPointer<vtkPointSource> points =
      vtkSmartPointer<vtkPointSource>::New();
    points->SetNumberOfPoints(1000);
    points->SetRadius(1.0);
    points->SetCenter(vtkMath::Random(-1, 1),
                      vtkMath::Random(-1, 1),
                      vtkMath::Random(-1, 1));
    points->SetDistributionToShell();
    points->Update();
    polyData = points->GetOutput();
  }
  return polyData;
}
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

PROJECT(PowercrustExtractSurface)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

add_executable(PowercrustExtractSurface MACOSX_BUNDLE PowercrustExtractSurface.cxx )

target_link_libraries(PowercrustExtractSurface ${VTK_LIBRARIES})

Download and Build PowercrustExtractSurface

Click here to download PowercrustExtractSurface and its CMakeLists.txt file. Once the tarball PowercrustExtractSurface.tar has been downloaded and extracted,

cd PowercrustExtractSurface/build 

If VTK is installed:

cmake ..

If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:

cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

make

and run it:

./PowercrustExtractSurface

WINDOWS USERS

Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.