We want to put points on the three-dimensional model sometimes, it’s better if these control points can be moved around the item and project generates a new interpolation line dynamically.
VTK provides a tool for us to do it easily. The following content shows two scenarios about point placer, both need vtkContourWidget and vtkContourRepresentation to draw points and the lines between these points and show them.
Let’s read the examples and learn it.
Put Points On Surface Of 3D Model
Create a cone, it’s a simple and clear model for our exmaple, use vtkPolygonalSurfacePointPlacer object to put control points on 3D model, vtkOrientedGlyphContourRepresentation which is derived class of vtkContourRepresentation can help us to adjust the properties of line, for example, set color of control points by rep->GetProperty()->SetColor(?, ?, ?);
, adjust the size of control points by rep->GetProperty()->SetPointSize( ? );
, and change the color of selected points by rep->GetActiveProperty()->SetColor( 0, 0, 1 );
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkContourWidget.h>
#include <vtkOrientedGlyphContourRepresentation.h>
#include <vtkPolygonalSurfacePointPlacer.h>
#include <vtkPolyDataCollection.h>
using namespace std;
int main()
{
vtkSmartPointer<vtkConeSource> cone =
vtkSmartPointer<vtkConeSource>::New();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection( cone->GetOutputPort() );
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper( mapper );
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground( 0, 0, 0 );
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow( renderWindow );
vtkSmartPointer<vtkContourWidget> contourWidget =
vtkSmartPointer<vtkContourWidget>::New();
contourWidget->SetInteractor(renderWindowInteractor);
vtkOrientedGlyphContourRepresentation* rep =
dynamic_cast<vtkOrientedGlyphContourRepresentation*>(contourWidget->GetRepresentation());
vtkSmartPointer<vtkPolygonalSurfacePointPlacer> pointPlacer =
vtkSmartPointer<vtkPolygonalSurfacePointPlacer>::New();
pointPlacer->AddProp(actor);
pointPlacer->GetPolys()->AddItem(cone->GetOutput());
rep->GetLinesProperty()->SetColor(1, 0, 0);
rep->GetLinesProperty()->SetLineWidth(2.0);
rep->SetPointPlacer(pointPlacer);
contourWidget->EnabledOn();
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
Put Points On An Image
In this scenario, we have to use vtkImageViewer2 to draw an image on a plane with 3D rendering, then the member ImageActor of vtkImageActorPointPlacer can work and vtkOrientedGlyphContourRepresentation object shows control points and lines between them based on the image placer.
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkContourWidget.h>
#include <vtkOrientedGlyphContourRepresentation.h>
#include <vtkPolygonalSurfacePointPlacer.h>
#include <vtkPolyDataCollection.h>
#include <vtkImageViewer2.h>
#include <vtkPNGReader.h>
#include <vtkImageActorPointPlacer.h>
using namespace std;
int main()
{
vtkSmartPointer<vtkPNGReader> reader =
vtkSmartPointer<vtkPNGReader>::New();
reader->SetFileName( "/Users/weiyang/Downloads/VTKData/Data/vtk.png" );
reader->Update();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkImageViewer2> imageViewer =
vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputData( reader->GetOutput() );
imageViewer->SetColorWindow( 256 );
imageViewer->SetColorLevel( 127.5 );
imageViewer->SetupInteractor( renderWindowInteractor );
vtkSmartPointer<vtkImageActorPointPlacer> imageActorPointPlacer =
vtkSmartPointer<vtkImageActorPointPlacer>::New();
imageActorPointPlacer->SetImageActor( imageViewer->GetImageActor() );
vtkSmartPointer<vtkOrientedGlyphContourRepresentation> rep =
vtkSmartPointer<vtkOrientedGlyphContourRepresentation>::New();
rep->SetLineColor( 0, 0, 1 );
rep->GetLinesProperty()->SetLineWidth( 2.0 );
rep->SetPointPlacer( imageActorPointPlacer );
vtkSmartPointer<vtkContourWidget> ContourWidget =
vtkSmartPointer<vtkContourWidget>::New();
ContourWidget->SetRepresentation(rep);
ContourWidget->SetInteractor( renderWindowInteractor );
ContourWidget->SetFollowCursor( true );
ContourWidget->SetEnabled( true );
ContourWidget->ProcessEventsOn();
imageViewer->GetRenderer()->ResetCamera();
imageViewer->Render();
renderWindowInteractor->Start();
return 0;
}