Commit effa1ddd authored by Will Schroeder's avatar Will Schroeder
Browse files

Added new widget: vtkImplicitCylinderWidget

Added the widget and representation (vtkImplicitCylinderWidget and
vtkImplicitCylinderRepresentation). Modified the implicit function
vtkCylinder to support arbitrary center and rotation axis.
parent da668c35
......@@ -14,36 +14,98 @@
=========================================================================*/
#include "vtkCylinder.h"
#include "vtkObjectFactory.h"
#include "vtkMath.h"
vtkStandardNewMacro(vtkCylinder);
//----------------------------------------------------------------------------
// Construct cylinder radius of 0.5.
vtkCylinder::vtkCylinder()
{
this->Center[0] = this->Center[1] = this->Center[2] = 0.0;
this->Axis[0] = 0.0;
this->Axis[1] = 1.0;
this->Axis[2] = 0.0;
this->Radius = 0.5;
}
// Evaluate cylinder equation F(x,y,z) = (x-x0)^2 + (z-z0)^2 - R^2.
double vtkCylinder::EvaluateFunction(double xyz[3])
//----------------------------------------------------------------------------
// Evaluate cylinder equation F(x,y,z) along specified Axis. Note that this is
// basically a distance to line computation, compared to the cylinder radius.
double vtkCylinder::EvaluateFunction(double x[3])
{
double x = xyz[0] - this->Center[0];
double z = xyz[2] - this->Center[2];
// Determine distance^2 of point to axis. Note that cylinder Axis is
// always normalized and always non-zero.
double x2C[3];
x2C[0] = x[0] - this->Center[0];
x2C[1] = x[1] - this->Center[1];
x2C[2] = x[2] - this->Center[2];
return ( x * x + z * z - this->Radius*this->Radius );
// projection onto cylinder axis
double proj = vtkMath::Dot(this->Axis,x2C);
// return distance^2 - R^2
return ( (vtkMath::Dot(x2C,x2C) - proj*proj) - this->Radius*this->Radius );
}
//----------------------------------------------------------------------------
// Evaluate cylinder function gradient (along potentially oriented axis). The
// gradient is always in the radial direction, and thus must be projected
// onto the three x-y-z coordinate axes.
void vtkCylinder::EvaluateGradient(double x[3], double g[3])
{
// Determine the radial vector from the point x to the line. This
// means finding the closest point to the line. Get parametric
// location along cylinder axis. Remember Axis is normalized.
double t = this->Axis[0]*(x[0]-this->Center[0]) +
this->Axis[1]*(x[1]-this->Center[1]) + this->Axis[2]*(x[2]-this->Center[2]);
// Compute closest point
double cp[3];
cp[0] = this->Center[0] + t*this->Axis[0];
cp[1] = this->Center[1] + t*this->Axis[1];
cp[2] = this->Center[2] + t*this->Axis[2];
// Gradient is 2*r. Project onto x-y-z axes.
g[0] = 2.0 * (x[0] - cp[0]);
g[1] = 2.0 * (x[1] - cp[1]);
g[2] = 2.0 * (x[2] - cp[2]);
}
// Evaluate cylinder function gradient.
void vtkCylinder::EvaluateGradient(double xyz[3], double g[3])
//----------------------------------------------------------------------------
// Specify the cylinder axis. Normalize if necessary.
void vtkCylinder::SetAxis(double ax, double ay, double az)
{
double x = xyz[0] - this->Center[0];
double z = xyz[2] - this->Center[2];
double axis[3];
axis[0] = ax;
axis[1] = ay;
axis[2] = az;
this->SetAxis(axis);
}
g[0] = 2.0 * (x - this->Center[0]);
g[1] = 0.0;
g[2] = 2.0 * (z - this->Center[2]);
//----------------------------------------------------------------------------
// Specify the cylinder axis. Reject non-zero axis vectors. It normalizes the
// axis vector.
void vtkCylinder::SetAxis(double a[3])
{
// If axis length is zero, then don't change it
if ( vtkMath::Normalize(a) < DBL_EPSILON )
{
vtkErrorMacro("Attempt to define cylinder with zero-length axis");
return;
}
if ( a[0] != this->Axis[0] || a[1] != this->Axis[1] ||
a[2] != this->Axis[2] )
{
this->Modified();
this->Axis[0] = a[0];
this->Axis[1] = a[1];
this->Axis[2] = a[2];
}
}
//----------------------------------------------------------------------------
void vtkCylinder::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
......@@ -51,5 +113,8 @@ void vtkCylinder::PrintSelf(ostream& os, vtkIndent indent)
os << indent << "Center: " << "( " << this->Center[0] << ", " <<
this->Center[1] << ", " << this->Center[2] << " )";
os << indent << "Axis: " << "( " << this->Axis[0] << ", " <<
this->Axis[1] << ", " << this->Axis[2] << " )";
os << indent << "Radius: " << this->Radius << "\n";
}
......@@ -14,15 +14,20 @@
=========================================================================*/
// .NAME vtkCylinder - implicit function for a cylinder
// .SECTION Description
// vtkCylinder computes the implicit function and function gradient for a
// cylinder. vtkCylinder is a concrete implementation of vtkImplicitFunction.
// Cylinder is centered at Center and axes of rotation is along the
// y-axis. (Use the superclass' vtkImplicitFunction transformation matrix if
// necessary to reposition.)
// vtkCylinder computes the implicit function and function gradient
// for a cylinder using F(r)=r^2-Radius^2. vtkCylinder is a concrete
// implementation of vtkImplicitFunction. By default the Cylinder is
// centered at the origin and the axis of rotation is along the
// y-axis. You can redefine the center and axis of rotation by setting
// the Center and Axis data members. (Note that it is also possible to
// use the superclass' vtkImplicitFunction transformation matrix if
// necessary to reposition by using FunctionValue() and
// FunctionGradient().)
// .SECTION Caveats
// The cylinder is infinite in extent. To truncate the cylinder use the
// vtkImplicitBoolean in combination with clipping planes.
// The cylinder is infinite in extent. To truncate the cylinder in
// modeling operations use the vtkImplicitBoolean in combination with
// clipping planes.
#ifndef vtkCylinder_h
......@@ -38,11 +43,12 @@ public:
void PrintSelf(ostream& os, vtkIndent indent);
// Description
// Construct cylinder radius of 0.5.
// Construct cylinder radius of 0.5; centered at origin with axis
// along y coordinate axis.
static vtkCylinder *New();
// Description
// Evaluate cylinder equation F(x,y,z) = (x-x0)^2 + (z-z0)^2 - R^2.
// Evaluate cylinder equation F(r) = r^2 - Radius^2.
double EvaluateFunction(double x[3]);
double EvaluateFunction(double x, double y, double z)
{return this->vtkImplicitFunction::EvaluateFunction(x, y, z); } ;
......@@ -52,21 +58,30 @@ public:
void EvaluateGradient(double x[3], double g[3]);
// Description:
// Set/Get cylinder radius.
// Set/Get the cylinder radius.
vtkSetMacro(Radius,double);
vtkGetMacro(Radius,double);
// Description:
// Set/Get cylinder center
// Set/Get the cylinder center.
vtkSetVector3Macro(Center,double);
vtkGetVector3Macro(Center,double);
// Description:
// Set/Get the axis of the cylinder. If the axis is not specified as
// a unit vector, it will be normalized. If zero-length axis vector
// is used as input to this method, it will be ignored.
void SetAxis(double ax, double ay, double az);
void SetAxis(double a[3]);
vtkGetVector3Macro(Axis,double);
protected:
vtkCylinder();
~vtkCylinder() {}
double Radius;
double Center[3];
double Axis[3];
private:
vtkCylinder(const vtkCylinder&); // Not implemented.
......@@ -74,5 +89,3 @@ private:
};
#endif
......@@ -61,6 +61,8 @@ set(Module_SRCS
vtkImageOrthoPlanes.cxx
vtkImagePlaneWidget.cxx
vtkImageTracerWidget.cxx
vtkImplicitCylinderRepresentation.cxx
vtkImplicitCylinderWidget.cxx
vtkImplicitPlaneRepresentation.cxx
vtkImplicitPlaneWidget2.cxx
vtkImplicitPlaneWidget.cxx
......
......@@ -28,6 +28,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestHandleWidget.cxx
TestImageActorContourWidget.cxx
TestImageTracerWidget.cxx
TestImplicitCylinderWidget.cxx
TestImplicitPlaneWidget2b.cxx
TestImplicitPlaneWidget2.cxx
TestImplicitPlaneWidget2LockNormalToCamera.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestImplicitCylinderWidget.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkSmartPointer.h"
#include "vtkActor.h"
#include "vtkAppendPolyData.h"
#include "vtkClipPolyData.h"
#include "vtkCommand.h"
#include "vtkConeSource.h"
#include "vtkGlyph3D.h"
#include "vtkImplicitCylinderWidget.h"
#include "vtkImplicitCylinderRepresentation.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkLODActor.h"
#include "vtkCylinder.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkSphereSource.h"
const char eventLog2[] =
"# StreamVersion 1\n"
"CharEvent 108 202 0 0 105 1 i\n"
"KeyReleaseEvent 108 202 0 0 105 1 i\n"
"MouseMoveEvent 113 194 0 0 0 0 i\n"
"MouseMoveEvent 111 190 0 0 0 0 i\n"
"MouseMoveEvent 109 185 0 0 0 0 i\n"
"MouseMoveEvent 108 183 0 0 0 0 i\n"
"RenderEvent 108 183 0 0 0 0 i\n"
"MouseMoveEvent 105 175 0 0 0 0 i\n"
"RenderEvent 105 175 0 0 0 0 i\n"
"MouseMoveEvent 104 169 0 0 0 0 i\n"
"RenderEvent 104 169 0 0 0 0 i\n"
"MouseMoveEvent 103 169 0 0 0 0 i\n"
"RenderEvent 103 169 0 0 0 0 i\n"
"MouseMoveEvent 103 167 0 0 0 0 i\n"
"RenderEvent 103 167 0 0 0 0 i\n"
"MouseMoveEvent 103 167 0 0 0 0 i\n"
"RenderEvent 103 167 0 0 0 0 i\n"
"MouseMoveEvent 85 162 0 0 0 0 i\n"
"RenderEvent 85 162 0 0 0 0 i\n"
"MouseMoveEvent 68 158 0 0 0 0 i\n"
"RenderEvent 68 158 0 0 0 0 i\n"
"MouseMoveEvent 59 156 0 0 0 0 i\n"
"RenderEvent 59 156 0 0 0 0 i\n"
"MouseMoveEvent 41 149 0 0 0 0 i\n"
"RenderEvent 41 149 0 0 0 0 i\n"
"MouseMoveEvent 39 148 0 0 0 0 i\n"
"RenderEvent 39 148 0 0 0 0 i\n"
"LeftButtonPressEvent 39 148 0 0 0 0 i\n"
"RenderEvent 39 148 0 0 0 0 i\n"
"MouseMoveEvent 39 147 0 0 0 0 i\n"
"RenderEvent 39 147 0 0 0 0 i\n"
"MouseMoveEvent 39 146 0 0 0 0 i\n"
"RenderEvent 39 146 0 0 0 0 i\n"
"MouseMoveEvent 39 145 0 0 0 0 i\n"
"RenderEvent 39 145 0 0 0 0 i\n"
"MouseMoveEvent 39 143 0 0 0 0 i\n"
"RenderEvent 39 143 0 0 0 0 i\n"
"MouseMoveEvent 39 143 0 0 0 0 i\n"
"RenderEvent 39 143 0 0 0 0 i\n"
"MouseMoveEvent 39 142 0 0 0 0 i\n"
"RenderEvent 39 142 0 0 0 0 i\n"
"MouseMoveEvent 39 141 0 0 0 0 i\n"
"RenderEvent 39 141 0 0 0 0 i\n"
"MouseMoveEvent 39 140 0 0 0 0 i\n"
"RenderEvent 39 140 0 0 0 0 i\n"
"MouseMoveEvent 40 139 0 0 0 0 i\n"
"RenderEvent 40 139 0 0 0 0 i\n"
"MouseMoveEvent 43 134 0 0 0 0 i\n"
"RenderEvent 43 134 0 0 0 0 i\n"
"MouseMoveEvent 45 129 0 0 0 0 i\n"
"RenderEvent 45 129 0 0 0 0 i\n"
"MouseMoveEvent 45 123 0 0 0 0 i\n"
"RenderEvent 45 123 0 0 0 0 i\n"
"MouseMoveEvent 51 108 0 0 0 0 i\n"
"RenderEvent 51 108 0 0 0 0 i\n"
"MouseMoveEvent 53 101 0 0 0 0 i\n"
"RenderEvent 53 101 0 0 0 0 i\n"
"MouseMoveEvent 55 95 0 0 0 0 i\n"
"RenderEvent 55 95 0 0 0 0 i\n"
"MouseMoveEvent 58 89 0 0 0 0 i\n"
"RenderEvent 58 89 0 0 0 0 i\n"
"MouseMoveEvent 66 80 0 0 0 0 i\n"
"RenderEvent 66 80 0 0 0 0 i\n"
"MouseMoveEvent 89 73 0 0 0 0 i\n"
"RenderEvent 89 73 0 0 0 0 i\n"
"MouseMoveEvent 100 73 0 0 0 0 i\n"
"RenderEvent 100 73 0 0 0 0 i\n"
"MouseMoveEvent 120 72 0 0 0 0 i\n"
"RenderEvent 120 72 0 0 0 0 i\n"
"MouseMoveEvent 125 75 0 0 0 0 i\n"
"RenderEvent 125 75 0 0 0 0 i\n"
"MouseMoveEvent 139 81 0 0 0 0 i\n"
"RenderEvent 139 81 0 0 0 0 i\n"
"MouseMoveEvent 145 85 0 0 0 0 i\n"
"RenderEvent 145 85 0 0 0 0 i\n"
"MouseMoveEvent 149 87 0 0 0 0 i\n"
"RenderEvent 149 87 0 0 0 0 i\n"
"MouseMoveEvent 157 87 0 0 0 0 i\n"
"RenderEvent 157 87 0 0 0 0 i\n"
"MouseMoveEvent 163 87 0 0 0 0 i\n"
"RenderEvent 163 87 0 0 0 0 i\n"
"MouseMoveEvent 166 87 0 0 0 0 i\n"
"RenderEvent 166 87 0 0 0 0 i\n"
"MouseMoveEvent 170 85 0 0 0 0 i\n"
"RenderEvent 170 85 0 0 0 0 i\n"
"MouseMoveEvent 172 80 0 0 0 0 i\n"
"RenderEvent 172 80 0 0 0 0 i\n"
"MouseMoveEvent 173 76 0 0 0 0 i\n"
"RenderEvent 173 76 0 0 0 0 i\n"
"MouseMoveEvent 173 75 0 0 0 0 i\n"
"RenderEvent 173 75 0 0 0 0 i\n"
"MouseMoveEvent 174 71 0 0 0 0 i\n"
"RenderEvent 174 71 0 0 0 0 i\n"
"MouseMoveEvent 174 71 0 0 0 0 i\n"
"RenderEvent 174 71 0 0 0 0 i\n"
"MouseMoveEvent 174 70 0 0 0 0 i\n"
"RenderEvent 174 70 0 0 0 0 i\n"
"MouseMoveEvent 175 67 0 0 0 0 i\n"
"RenderEvent 175 67 0 0 0 0 i\n"
"MouseMoveEvent 175 66 0 0 0 0 i\n"
"RenderEvent 175 66 0 0 0 0 i\n"
"LeftButtonReleaseEvent 175 66 0 0 0 0 i\n"
"RenderEvent 175 66 0 0 0 0 i\n"
"MouseMoveEvent 175 69 0 0 0 0 i\n"
"RenderEvent 175 69 0 0 0 0 i\n"
"MouseMoveEvent 182 95 0 0 0 0 i\n"
"RenderEvent 182 95 0 0 0 0 i\n"
"MouseMoveEvent 187 119 0 0 0 0 i\n"
"RenderEvent 187 119 0 0 0 0 i\n"
"MouseMoveEvent 192 132 0 0 0 0 i\n"
"RenderEvent 192 132 0 0 0 0 i\n"
"MouseMoveEvent 192 133 0 0 0 0 i\n"
"RenderEvent 192 133 0 0 0 0 i\n"
"MouseMoveEvent 194 137 0 0 0 0 i\n"
"RenderEvent 194 137 0 0 0 0 i\n"
"MouseMoveEvent 194 138 0 0 0 0 i\n"
"RenderEvent 194 138 0 0 0 0 i\n"
"MouseMoveEvent 192 141 0 0 0 0 i\n"
"RenderEvent 192 141 0 0 0 0 i\n"
"MouseMoveEvent 191 143 0 0 0 0 i\n"
"RenderEvent 191 143 0 0 0 0 i\n"
"LeftButtonPressEvent 191 143 0 0 0 0 i\n"
"RenderEvent 191 143 0 0 0 0 i\n"
"MouseMoveEvent 191 144 0 0 0 0 i\n"
"RenderEvent 191 144 0 0 0 0 i\n"
"MouseMoveEvent 190 153 0 0 0 0 i\n"
"RenderEvent 190 153 0 0 0 0 i\n"
"MouseMoveEvent 190 155 0 0 0 0 i\n"
"RenderEvent 190 155 0 0 0 0 i\n"
"MouseMoveEvent 189 161 0 0 0 0 i\n"
"RenderEvent 189 161 0 0 0 0 i\n"
"MouseMoveEvent 189 166 0 0 0 0 i\n"
"RenderEvent 189 166 0 0 0 0 i\n"
"MouseMoveEvent 187 172 0 0 0 0 i\n"
"RenderEvent 187 172 0 0 0 0 i\n"
"MouseMoveEvent 185 177 0 0 0 0 i\n"
"RenderEvent 185 177 0 0 0 0 i\n"
"MouseMoveEvent 181 185 0 0 0 0 i\n"
"RenderEvent 181 185 0 0 0 0 i\n"
"MouseMoveEvent 180 187 0 0 0 0 i\n"
"RenderEvent 180 187 0 0 0 0 i\n"
"MouseMoveEvent 179 191 0 0 0 0 i\n"
"RenderEvent 179 191 0 0 0 0 i\n"
"MouseMoveEvent 177 197 0 0 0 0 i\n"
"RenderEvent 177 197 0 0 0 0 i\n"
"MouseMoveEvent 177 201 0 0 0 0 i\n"
"RenderEvent 177 201 0 0 0 0 i\n"
"MouseMoveEvent 175 205 0 0 0 0 i\n"
"RenderEvent 175 205 0 0 0 0 i\n"
"MouseMoveEvent 175 207 0 0 0 0 i\n"
"RenderEvent 175 207 0 0 0 0 i\n"
"MouseMoveEvent 175 209 0 0 0 0 i\n"
"RenderEvent 175 209 0 0 0 0 i\n"
"LeftButtonReleaseEvent 175 209 0 0 0 0 i\n"
"RenderEvent 175 209 0 0 0 0 i\n"
"MouseMoveEvent 175 209 0 0 0 0 i\n"
"RenderEvent 175 209 0 0 0 0 i\n"
"MouseMoveEvent 181 185 0 0 0 0 i\n"
"RenderEvent 181 185 0 0 0 0 i\n"
"MouseMoveEvent 198 155 0 0 0 0 i\n"
"MouseMoveEvent 199 152 0 0 0 0 i\n"
"MouseMoveEvent 200 147 0 0 0 0 i\n"
"MouseMoveEvent 200 141 0 0 0 0 i\n"
"MouseMoveEvent 200 135 0 0 0 0 i\n"
"MouseMoveEvent 200 133 0 0 0 0 i\n"
"MouseMoveEvent 201 131 0 0 0 0 i\n"
"MouseMoveEvent 201 128 0 0 0 0 i\n"
"MouseMoveEvent 201 125 0 0 0 0 i\n"
"MouseMoveEvent 201 121 0 0 0 0 i\n"
"MouseMoveEvent 201 117 0 0 0 0 i\n"
"RenderEvent 201 117 0 0 0 0 i\n"
"MouseMoveEvent 201 111 0 0 0 0 i\n"
"RenderEvent 201 111 0 0 0 0 i\n"
"MouseMoveEvent 201 110 0 0 0 0 i\n"
"RenderEvent 201 110 0 0 0 0 i\n"
"LeftButtonPressEvent 201 110 0 0 0 0 i\n"
"RenderEvent 201 110 0 0 0 0 i\n"
"MouseMoveEvent 199 109 0 0 0 0 i\n"
"RenderEvent 199 109 0 0 0 0 i\n"
"MouseMoveEvent 170 102 0 0 0 0 i\n"
"RenderEvent 170 102 0 0 0 0 i\n"
"MouseMoveEvent 153 98 0 0 0 0 i\n"
"RenderEvent 153 98 0 0 0 0 i\n"
"MouseMoveEvent 139 92 0 0 0 0 i\n"
"RenderEvent 139 92 0 0 0 0 i\n"
"MouseMoveEvent 113 81 0 0 0 0 i\n"
"RenderEvent 113 81 0 0 0 0 i\n"
"MouseMoveEvent 113 80 0 0 0 0 i\n"
"RenderEvent 113 80 0 0 0 0 i\n"
"MouseMoveEvent 113 73 0 0 0 0 i\n"
"RenderEvent 113 73 0 0 0 0 i\n"
"MouseMoveEvent 113 73 0 0 0 0 i\n"
"RenderEvent 113 73 0 0 0 0 i\n"
"MouseMoveEvent 114 73 0 0 0 0 i\n"
"RenderEvent 114 73 0 0 0 0 i\n"
"MouseMoveEvent 115 73 0 0 0 0 i\n"
"RenderEvent 115 73 0 0 0 0 i\n"
"MouseMoveEvent 121 75 0 0 0 0 i\n"
"RenderEvent 121 75 0 0 0 0 i\n"
"MouseMoveEvent 123 77 0 0 0 0 i\n"
"RenderEvent 123 77 0 0 0 0 i\n"
"MouseMoveEvent 124 77 0 0 0 0 i\n"
"RenderEvent 124 77 0 0 0 0 i\n"
"LeftButtonReleaseEvent 124 77 0 0 0 0 i\n"
"RenderEvent 124 77 0 0 0 0 i\n"
"MouseMoveEvent 124 77 0 0 0 0 i\n"
"RenderEvent 124 77 0 0 0 0 i\n"
"MouseMoveEvent 124 77 0 0 0 0 i\n"
"RenderEvent 124 77 0 0 0 0 i\n"
"MouseMoveEvent 124 79 0 0 0 0 i\n"
"RenderEvent 124 79 0 0 0 0 i\n"
;
// This does the actual work: updates the vtkCylinder implicit function.
// This in turn causes the pipeline to update and clip the object.
// Callback for the interaction
class vtkTICWCallback : public vtkCommand
{
public:
static vtkTICWCallback *New()
{ return new vtkTICWCallback; }
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkImplicitCylinderWidget *cylWidget =
reinterpret_cast<vtkImplicitCylinderWidget*>(caller);
vtkImplicitCylinderRepresentation *rep =
reinterpret_cast<vtkImplicitCylinderRepresentation*>(cylWidget->GetRepresentation());
rep->GetCylinder(this->Cylinder);
this->Actor->VisibilityOn();
}
vtkTICWCallback():Cylinder(0),Actor(0) {}
vtkCylinder *Cylinder;
vtkActor *Actor;
};
int TestImplicitCylinderWidget(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
{
// Create a mace out of filters.
//
vtkSmartPointer<vtkSphereSource> sphere =
vtkSmartPointer<vtkSphereSource>::New();
vtkSmartPointer<vtkConeSource> cone =
vtkSmartPointer<vtkConeSource>::New();
vtkSmartPointer<vtkGlyph3D> glyph =
vtkSmartPointer<vtkGlyph3D>::New();
glyph->SetInputConnection(sphere->GetOutputPort());
glyph->SetSourceConnection(cone->GetOutputPort());
glyph->SetVectorModeToUseNormal();
glyph->SetScaleModeToScaleByVector();
glyph->SetScaleFactor(0.25);
glyph->Update();
// The sphere and spikes are appended into a single polydata.
// This just makes things simpler to manage.
vtkSmartPointer<vtkAppendPolyData> apd =
vtkSmartPointer<vtkAppendPolyData>::New();
apd->AddInputConnection(glyph->GetOutputPort());
apd->AddInputConnection(sphere->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> maceMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
maceMapper->SetInputConnection(apd->GetOutputPort());
vtkSmartPointer<vtkLODActor> maceActor =
vtkSmartPointer<vtkLODActor>::New();
maceActor->SetMapper(maceMapper);
maceActor->VisibilityOn();
// This portion of the code clips the mace with the vtkCylinder
// implicit function. The clipped region is colored green.
vtkSmartPointer<vtkCylinder> cylinder =
vtkSmartPointer<vtkCylinder>::New();
vtkSmartPointer<vtkClipPolyData> clipper =
vtkSmartPointer<vtkClipPolyData>::New();
clipper->SetInputConnection(apd->GetOutputPort());
clipper->SetClipFunction(cylinder);
clipper->InsideOutOn();
vtkSmartPointer<vtkPolyDataMapper> selectMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
selectMapper->SetInputConnection(clipper->GetOutputPort());
vtkSmartPointer<vtkLODActor> selectActor =
vtkSmartPointer<vtkLODActor>::New();
selectActor->SetMapper(selectMapper);
selectActor->GetProperty()->SetColor(0,1,0);
selectActor->VisibilityOff();
selectActor->SetScale(1.01, 1.01, 1.01);
// Create the RenderWindow, Renderer and both Actors
//
vtkSmartPointer<vtkRenderer> ren1 =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(ren1);
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
// The SetInteractor method is how 3D widgets are associated with the render
// window interactor. Internally, SetInteractor sets up a bunch of callbacks
// using the Command/Observer mechanism (AddObserver()).
vtkSmartPointer<vtkTICWCallback> myCallback =
vtkSmartPointer<vtkTICWCallback>::New();
myCallback->Cylinder = cylinder;
myCallback->Actor = selectActor;
vtkSmartPointer<vtkImplicitCylinderRepresentation> rep =
vtkSmartPointer<vtkImplicitCylinderRepresentation>::New();
rep->SetPlaceFactor(1.25);
rep->PlaceWidget(glyph->GetOutput()->GetBounds());
rep->SetRadius(0.25);
rep->GetCylinderProperty()->SetOpacity(0.1);
vtkSmartPointer<vtkImplicitCylinderWidget> cylWidget =
vtkSmartPointer<vtkImplicitCylinderWidget>::New();
cylWidget->SetInteractor(iren);
cylWidget->SetRepresentation(rep);
cylWidget->AddObserver(vtkCommand::InteractionEvent,myCallback);
ren1->AddActor(maceActor);
ren1->AddActor(selectActor);
// Add the actors to the renderer, set the background and size
//
ren1->SetBackground(0.1, 0.2, 0.4);
renWin->SetSize(300, 300);
// record events
vtkSmartPointer<vtkInteractorEventRecorder> recorder =
vtkSmartPointer<vtkInteractorEventRecorder>::New();
recorder->SetInteractor(iren);
//recorder->SetFileName("record.log");
//recorder->Record();
recorder->ReadFromInputStringOn();
recorder->SetInputString(eventLog2);