KochanekSplineDemo
VTKExamples/Cxx/PolyData/KochanekSplineDemo
Description¶
The example provides vtkSliderWidget s to change tension, continuity and bias of the vtkKochanekSpline.
- tension - Changes the length of the tangent vector
- bias - Primarily changes the direction of the tangent vector
- continuity - Changes the sharpness in change between tangents
Seealso
This wikipedia article describes the controlsin detail.
Code¶
KochanekSplineDemo.cxx
#include <vtkSmartPointer.h> #include <vtkKochanekSpline.h> #include <vtkParametricSpline.h> #include <vtkParametricFunctionSource.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkProperty2D.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> #include <vtkTextProperty.h> #include <vtkTextMapper.h> #include <vtkActor2D.h> #include <vtkSliderRepresentation2D.h> #include <vtkGlyph3DMapper.h> #include <vtkSphereSource.h> #include <vtkNamedColors.h> #include <vtkCommand.h> #include <vtkSliderWidget.h> #include <vtkSliderRepresentation2D.h> namespace { void MakeTensionWidget(vtkSmartPointer<vtkSliderWidget> &, vtkSmartPointer<vtkParametricFunctionSource> &, vtkSmartPointer<vtkParametricSpline> &, vtkSmartPointer<vtkRenderer> &, vtkSmartPointer<vtkRenderWindowInteractor> &); void MakeContinuityWidget(vtkSmartPointer<vtkSliderWidget> &, vtkSmartPointer<vtkParametricFunctionSource> &, vtkSmartPointer<vtkParametricSpline> &, vtkSmartPointer<vtkRenderer> &, vtkSmartPointer<vtkRenderWindowInteractor> &); void MakeBiasWidget(vtkSmartPointer<vtkSliderWidget> &, vtkSmartPointer<vtkParametricFunctionSource> &, vtkSmartPointer<vtkParametricSpline> &, vtkSmartPointer<vtkRenderer> &, vtkSmartPointer<vtkRenderWindowInteractor> &); } int main(int, char *[]) { vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New(); int numberOfPoints = 7; vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->SetNumberOfPoints(numberOfPoints); double radius = 1.0; double delta = 2.0 * vtkMath::Pi() / double (numberOfPoints); for (int n = 0; n < numberOfPoints; ++n) { double theta = delta * n; double x = radius * std::cos(theta); double y = radius * std::sin(theta); double z = n * (vtkMath::Pi() / numberOfPoints); points->SetPoint(n, x, y, z); } vtkSmartPointer<vtkKochanekSpline> xSpline = vtkSmartPointer<vtkKochanekSpline>::New(); vtkSmartPointer<vtkKochanekSpline> ySpline = vtkSmartPointer<vtkKochanekSpline>::New(); vtkSmartPointer<vtkKochanekSpline> zSpline = vtkSmartPointer<vtkKochanekSpline>::New(); vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New(); spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(points); vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(50 * numberOfPoints); functionSource->SetVResolution(50 * numberOfPoints); functionSource->SetWResolution(50 * numberOfPoints); functionSource->Update(); // Setup actor and mapper vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(functionSource->GetOutputPort()); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); actor->GetProperty()->SetColor(colors->GetColor3d("DarkSlateGrey").GetData()); actor->GetProperty()->SetLineWidth(3.0); // Glyph the points vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New(); sphere->SetPhiResolution(21); sphere->SetThetaResolution(21); sphere->SetRadius(.1); // Create a polydata to store everything in vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(points); vtkSmartPointer<vtkGlyph3DMapper> pointMapper = vtkSmartPointer<vtkGlyph3DMapper>::New(); pointMapper->SetInputData(polyData); pointMapper->SetSourceConnection(sphere->GetOutputPort()); vtkSmartPointer<vtkActor> pointActor = vtkSmartPointer<vtkActor>::New(); pointActor->SetMapper(pointMapper); pointActor->GetProperty()->SetColor(colors->GetColor3d("Peacock").GetData()); pointActor->GetProperty()->SetOpacity(.5);; // Setup render window, renderer, and interactor vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetSize(640, 480); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetRenderWindow(renderWindow); renderer->AddActor(actor); renderer->AddActor(pointActor);; renderer->SetBackground(colors->GetColor3d("Silver").GetData()); renderWindow->Render(); vtkSmartPointer<vtkSliderWidget> tensionWidget = vtkSmartPointer<vtkSliderWidget>::New(); MakeTensionWidget(tensionWidget, functionSource, spline, renderer, renderWindowInteractor); vtkSmartPointer<vtkSliderWidget> continuityWidget = vtkSmartPointer<vtkSliderWidget>::New(); MakeContinuityWidget(continuityWidget, functionSource, spline, renderer, renderWindowInteractor); vtkSmartPointer<vtkSliderWidget> biasWidget = vtkSmartPointer<vtkSliderWidget>::New(); MakeBiasWidget(biasWidget, functionSource, spline, renderer, renderWindowInteractor); renderWindow->Render(); renderWindowInteractor->Start(); return EXIT_SUCCESS; } namespace { // These callbacks do the actual work. // Callbacks for the interactions class SliderCallbackTension : public vtkCommand { public: static SliderCallbackTension *New() { return new SliderCallbackTension; } virtual void Execute(vtkObject *caller, unsigned long, void*) { vtkSliderWidget *sliderWidget = reinterpret_cast<vtkSliderWidget*>(caller); double value = static_cast<vtkSliderRepresentation2D *>(sliderWidget->GetRepresentation())->GetValue(); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetXSpline())->SetDefaultTension(value); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetYSpline())->SetDefaultTension(value); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetZSpline())->SetDefaultTension(value); ParametricSource->Modified(); ParametricSource->Update(); } SliderCallbackTension():ParametricSource(0), ParametricSpline(0) {} vtkParametricSpline *ParametricSpline; vtkParametricFunctionSource *ParametricSource; }; void MakeTensionWidget(vtkSmartPointer<vtkSliderWidget> &widget, vtkSmartPointer<vtkParametricFunctionSource> ¶metricSource, vtkSmartPointer<vtkParametricSpline> ¶metricSpline, vtkSmartPointer<vtkRenderer> &renderer, vtkSmartPointer<vtkRenderWindowInteractor> &interactor) { // Setup a slider widget for each varying parameter double tubeWidth(.005); double sliderLength(.02); double titleHeight(.02); double labelHeight(.02); vtkSmartPointer<vtkSliderRepresentation2D> sliderRepTension = vtkSmartPointer<vtkSliderRepresentation2D>::New(); sliderRepTension->SetRenderer(renderer); sliderRepTension->SetMinimumValue(-1.0); sliderRepTension->SetMaximumValue(1.0); sliderRepTension->SetValue(vtkKochanekSpline::SafeDownCast(parametricSpline->GetXSpline())->GetDefaultTension()); sliderRepTension->SetTitleText("Tension"); sliderRepTension->SetRenderer(renderer); sliderRepTension->GetPoint1Coordinate()->SetValue(0.1, 0.1); sliderRepTension->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport(); sliderRepTension->GetPoint2Coordinate()->SetValue(0.3, 0.1); sliderRepTension->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport(); sliderRepTension->SetTubeWidth(tubeWidth); sliderRepTension->SetSliderLength(sliderLength); sliderRepTension->SetTitleHeight(titleHeight); sliderRepTension->SetLabelHeight(labelHeight); sliderRepTension->SetEndCapLength(tubeWidth*1.5); sliderRepTension->SetSliderWidth(tubeWidth*1.5); sliderRepTension->GetSliderProperty()->SetColor(0.0, 0.0, 0.0); sliderRepTension->BuildRepresentation(); widget->SetRepresentation(sliderRepTension); widget->SetAnimationModeToAnimate(); widget->SetNumberOfAnimationSteps(10); widget->SetInteractor(interactor); widget->EnabledOn(); vtkSmartPointer<SliderCallbackTension> callbackTension = vtkSmartPointer<SliderCallbackTension>::New(); callbackTension->ParametricSpline = parametricSpline; callbackTension->ParametricSource = parametricSource; widget->AddObserver(vtkCommand::InteractionEvent,callbackTension); } class SliderCallbackContinuity : public vtkCommand { public: static SliderCallbackContinuity *New() { return new SliderCallbackContinuity; } virtual void Execute(vtkObject *caller, unsigned long, void*) { vtkSliderWidget *sliderWidget = reinterpret_cast<vtkSliderWidget*>(caller); double value = static_cast<vtkSliderRepresentation2D *>(sliderWidget->GetRepresentation())->GetValue(); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetXSpline())->SetDefaultContinuity(value); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetYSpline())->SetDefaultContinuity(value); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetZSpline())->SetDefaultContinuity(value); ParametricSource->Modified(); ParametricSource->Update(); } SliderCallbackContinuity():ParametricSource(0), ParametricSpline(0) {} vtkParametricSpline *ParametricSpline; vtkParametricFunctionSource *ParametricSource; }; void MakeContinuityWidget(vtkSmartPointer<vtkSliderWidget> &widget, vtkSmartPointer<vtkParametricFunctionSource> ¶metricSource, vtkSmartPointer<vtkParametricSpline> ¶metricSpline, vtkSmartPointer<vtkRenderer> &renderer, vtkSmartPointer<vtkRenderWindowInteractor> &interactor) { // Setup a slider widget for each varying parameter double tubeWidth(.005); double sliderLength(.02); double titleHeight(.02); double labelHeight(.02); vtkSmartPointer<vtkSliderRepresentation2D> sliderRepContinuity = vtkSmartPointer<vtkSliderRepresentation2D>::New(); sliderRepContinuity->SetRenderer(renderer); sliderRepContinuity->SetMinimumValue(-1.0); sliderRepContinuity->SetMaximumValue(1.0); sliderRepContinuity->SetValue(vtkKochanekSpline::SafeDownCast(parametricSpline->GetXSpline())->GetDefaultContinuity()); sliderRepContinuity->SetTitleText("Continuity"); sliderRepContinuity->SetRenderer(renderer); sliderRepContinuity->GetPoint1Coordinate()->SetValue(0.4, 0.1); sliderRepContinuity->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport(); sliderRepContinuity->GetPoint2Coordinate()->SetValue(0.6, 0.1); sliderRepContinuity->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport(); sliderRepContinuity->SetTubeWidth(tubeWidth); sliderRepContinuity->SetSliderLength(sliderLength); sliderRepContinuity->SetTitleHeight(titleHeight); sliderRepContinuity->SetLabelHeight(labelHeight); sliderRepContinuity->SetEndCapLength(tubeWidth*1.5); sliderRepContinuity->SetSliderWidth(tubeWidth*1.5); sliderRepContinuity->GetSliderProperty()->SetColor(0.0, 0.0, 0.0); sliderRepContinuity->BuildRepresentation(); widget->SetRepresentation(sliderRepContinuity); widget->SetAnimationModeToAnimate(); widget->SetNumberOfAnimationSteps(10); widget->SetInteractor(interactor); widget->EnabledOn(); vtkSmartPointer<SliderCallbackContinuity> callbackContinuity = vtkSmartPointer<SliderCallbackContinuity>::New(); callbackContinuity->ParametricSpline = parametricSpline; callbackContinuity->ParametricSource = parametricSource; widget->AddObserver(vtkCommand::InteractionEvent,callbackContinuity); } class SliderCallbackBias : public vtkCommand { public: static SliderCallbackBias *New() { return new SliderCallbackBias; } virtual void Execute(vtkObject *caller, unsigned long, void*) { vtkSliderWidget *sliderWidget = reinterpret_cast<vtkSliderWidget*>(caller); double value = static_cast<vtkSliderRepresentation2D *>(sliderWidget->GetRepresentation())->GetValue(); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetXSpline())->SetDefaultBias(value); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetYSpline())->SetDefaultBias(value); vtkKochanekSpline::SafeDownCast(this->ParametricSpline->GetZSpline())->SetDefaultBias(value); ParametricSource->Modified(); ParametricSource->Update(); } SliderCallbackBias():ParametricSource(0), ParametricSpline(0) {} vtkParametricSpline *ParametricSpline; vtkParametricFunctionSource *ParametricSource; }; void MakeBiasWidget(vtkSmartPointer<vtkSliderWidget> &widget, vtkSmartPointer<vtkParametricFunctionSource> ¶metricSource, vtkSmartPointer<vtkParametricSpline> ¶metricSpline, vtkSmartPointer<vtkRenderer> &renderer, vtkSmartPointer<vtkRenderWindowInteractor> &interactor) { // Setup a slider widget for each varying parameter double tubeWidth(.005); double sliderLength(.02); double titleHeight(.02); double labelHeight(.02); vtkSmartPointer<vtkSliderRepresentation2D> sliderRepBias = vtkSmartPointer<vtkSliderRepresentation2D>::New(); sliderRepBias->SetRenderer(renderer); sliderRepBias->SetMinimumValue(-1.0); sliderRepBias->SetMaximumValue(1.0); sliderRepBias->SetValue(vtkKochanekSpline::SafeDownCast(parametricSpline->GetXSpline())->GetDefaultBias()); sliderRepBias->SetTitleText("Bias"); sliderRepBias->SetRenderer(renderer); sliderRepBias->GetPoint1Coordinate()->SetValue(0.7, 0.1); sliderRepBias->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport(); sliderRepBias->GetPoint2Coordinate()->SetValue(0.9, 0.1); sliderRepBias->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport(); sliderRepBias->SetTubeWidth(tubeWidth); sliderRepBias->SetSliderLength(sliderLength); sliderRepBias->SetTitleHeight(titleHeight); sliderRepBias->SetLabelHeight(labelHeight); sliderRepBias->SetEndCapLength(tubeWidth*1.5); sliderRepBias->SetSliderWidth(tubeWidth*1.5); sliderRepBias->GetSliderProperty()->SetColor(0.0, 0.0, 0.0); sliderRepBias->BuildRepresentation(); widget->SetRepresentation(sliderRepBias); widget->SetAnimationModeToAnimate(); widget->SetNumberOfAnimationSteps(10); widget->SetInteractor(interactor); widget->EnabledOn(); vtkSmartPointer<SliderCallbackBias> callbackBias = vtkSmartPointer<SliderCallbackBias>::New(); callbackBias->ParametricSpline = parametricSpline; callbackBias->ParametricSource = parametricSource; widget->AddObserver(vtkCommand::InteractionEvent,callbackBias); } }
CMakeLists.txt¶
cmake_minimum_required(VERSION 2.8) PROJECT(KochanekSplineDemo) find_package(VTK REQUIRED) include(${VTK_USE_FILE}) add_executable(KochanekSplineDemo MACOSX_BUNDLE KochanekSplineDemo.cxx ) target_link_libraries(KochanekSplineDemo ${VTK_LIBRARIES})
Download and Build KochanekSplineDemo¶
Click here to download KochanekSplineDemo and its CMakeLists.txt file. Once the tarball KochanekSplineDemo.tar has been downloaded and extracted,
cd KochanekSplineDemo/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:
./KochanekSplineDemo
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.