1 #include <vtkSmartPointer.h>
2 #include <vtkProperty.h>
3 #include <vtkContourWidget.h>
4 #include <vtkOrientedGlyphContourRepresentation.h>
5 #include <vtkRenderer.h>
6 #include <vtkRenderWindow.h>
7 #include <vtkRenderWindowInteractor.h>
8 #include <vtkCommand.h>
9 #include <vtkDebugLeaks.h>
10 #include <vtkCamera.h>
12 #include <vtkPolyData.h>
13 #include <vtkCellArray.h>
14 #include <vtkPoints.h>
16 #include <vtkWidgetEvent.h>
17 #include <vtkWidgetEventTranslator.h>
18 #include <vtkInteractorStyleTrackballCamera.h>
19 #include <vtkInteractorStyleImage.h>
21 #include <vtkPNGReader.h>
22 #include <vtkImageViewer2.h>
23 #include <vtkObjectFactory.h>
24 #include <vtkPolyDataMapper.h>
25 #include <vtkPolyData.h>
27 #include <vtkPlaneSource.h>
28 #include <vtkInteractorObserver.h>
31 vtkSmartPointer<vtkContourWidget> contourWidget;
32 vtkSmartPointer<vtkPolyData> pd;
33 vtkSmartPointer<vtkRenderWindowInteractor> interactor;
34 vtkSmartPointer<vtkOrientedGlyphContourRepresentation> contourRep;
36 // class for handling interaction on/off
37 class KeyPressInteractorStyle : public vtkInteractorStyleImage//vtkInteractorStyleTrackballCamera
40 static KeyPressInteractorStyle* New();
41 vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera);
45 virtual void OnKeyPress()
48 vtkRenderWindowInteractor *rwi = this->Interactor;
49 std::string key = rwi->GetKeySym();
51 int ctrlKeyInd = rwi->GetControlKey();
53 int altKeyInd = rwi->GetAltKey();
55 int shiftKeyInd = rwi->GetShiftKey();
57 // Output the key that was pressed
58 std::cout << "Pressed " << key << std::endl;
60 // Handle an arrow key
64 std::cout << "UP" << std::endl;
68 // Handle a "normal" key
71 std::cout << "DOWN" << std::endl;
77 if (key == "z" || key == "Z")
79 std::cout << "undo" << std::endl;
83 if (key == "y" || key == "Y")
85 std::cout << "redo" << std::endl;
91 vtkInteractorStyleTrackballCamera::OnKeyPress();
95 vtkStandardNewMacro(KeyPressInteractorStyle);
97 double* GetClosesstPointToPlane(double * n, double * p)
99 double* closest = new double[2]();
101 double c = -(n[0]*p[0] + n[1]*p[1] + n[2]*p[2]) / (n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
102 closest[0] = p[0] + c*n[0];
103 closest[1] = p[1] + c*n[1];
104 closest[2] = p[2] + c*n[2];
112 // class for handling click over the contour
113 class ContourCallBack : public vtkCommand
116 static ContourCallBack *New()
118 return new ContourCallBack;
122 virtual void Execute(vtkObject *caller, unsigned long eid, void* clientData)
126 vtkContourWidget *contourWidget =
127 reinterpret_cast<vtkContourWidget*>(caller);
129 // Retrieve the windows event x, y, z
130 std::cout << "window click " << contourWidget->GetInteractor()->GetEventPosition()[0] << " "
131 << contourWidget->GetInteractor()->GetEventPosition()[1] << " "
132 << contourWidget->GetInteractor()->GetEventPosition()[2]
135 // get the node postiion (the world position)
136 vtkContourRepresentation * rep=contourWidget->GetContourRepresentation();
137 double* worldclick = new double[2]();
138 rep->GetActiveNodeWorldPosition(worldclick);
140 std::cout << "worldclick click " << worldclick[0] << " " << worldclick[1] << " " << worldclick[2] << std::endl;
143 double* projection = new double[2]();
144 //restringedPosition[0] = nodepos[0];
145 //restringedPosition[1] = nodepos[1];
146 //restringedPosition[2] = 0; // ToDo: change is hard coded but must work for every plane/image
148 projection = GetClosesstPointToPlane(normal, worldclick);
150 std::cout << "projection click " << projection[0] << " " << projection[1] << " " << projection[2] << std::endl;
152 rep->SetActiveNodeToWorldPosition(projection);
158 int main(int argc, char *argv[])
160 normal = new double[2]();
164 center = new double[2]();
166 // Create the RenderWindow, Renderer and both Actors
168 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
169 vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
170 renderWindow->AddRenderer(renderer);
172 vtkSmartPointer<vtkRenderWindowInteractor> interactor =
173 vtkSmartPointer<vtkRenderWindowInteractor>::New();
174 interactor->SetRenderWindow(renderWindow);
176 renderer->SetBackground(0.1, 0.2, 0.4);
177 renderWindow->SetSize(600, 600);
181 vtkSmartPointer<vtkPlaneSource> planeSource =
182 vtkSmartPointer<vtkPlaneSource>::New();
183 planeSource->SetCenter(center); // 0.0, 0.0, 0.0);
184 planeSource->SetNormal(normal); //1.0, 0.0, 1.0);
185 planeSource->Update();
187 vtkPolyData* plane = planeSource->GetOutput();
189 // Create a mapper and actor
190 vtkSmartPointer<vtkPolyDataMapper> mapper =
191 vtkSmartPointer<vtkPolyDataMapper>::New();
192 mapper->SetInputData(plane);
194 vtkSmartPointer<vtkActor> planeActor =
195 vtkSmartPointer<vtkActor>::New();
196 planeActor->SetMapper(mapper);
198 vtkSmartPointer<KeyPressInteractorStyle> style =
199 vtkSmartPointer<KeyPressInteractorStyle>::New();
200 interactor->SetInteractorStyle(style);
202 // create the contour stuff
203 vtkSmartPointer<vtkOrientedGlyphContourRepresentation> contourRep =
204 vtkSmartPointer<vtkOrientedGlyphContourRepresentation>::New();
205 contourRep->GetLinesProperty()->SetColor(0, 0, 1); //set color to red
207 vtkSmartPointer<vtkContourWidget> contourWidget =
208 vtkSmartPointer<vtkContourWidget>::New();
209 contourWidget->SetInteractor(interactor);
210 contourWidget->SetRepresentation(contourRep);
214 for (int i = 0; i < argc; i++)
216 if (strcmp("-Shift", argv[i]) == 0)
218 contourWidget->GetEventTranslator()->RemoveTranslation(
219 vtkCommand::LeftButtonPressEvent);
220 contourWidget->GetEventTranslator()->SetTranslation(
221 vtkCommand::LeftButtonPressEvent,
222 vtkWidgetEvent::Translate);
224 else if (strcmp("-Scale", argv[i]) == 0)
226 contourWidget->GetEventTranslator()->RemoveTranslation(
227 vtkCommand::LeftButtonPressEvent);
228 contourWidget->GetEventTranslator()->SetTranslation(
229 vtkCommand::LeftButtonPressEvent,
230 vtkWidgetEvent::Scale);
234 //Add an observer to contour widget
235 vtkSmartPointer<ContourCallBack> contourCallBack =
236 vtkSmartPointer<ContourCallBack>::New();
237 contourWidget->AddObserver(vtkCommand::InteractionEvent, contourCallBack);
239 // quick points for representation
240 vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New();
242 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
243 vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
244 vtkIdType* lineIndices = new vtkIdType[21];
245 for (int i = 0; i< 20; i++)
247 const double angle = 2.0*vtkMath::Pi()*i / 20.0;
248 double* closest = new double[2]();
249 double* p = new double[2]();
251 p[0] = 0.2*cos(angle);
252 p[1] = 0.2*sin(angle);
255 closest = GetClosesstPointToPlane(normal, p);
256 points->InsertPoint(static_cast<vtkIdType>(i), closest);
257 lineIndices[i] = static_cast<vtkIdType>(i);
261 lines->InsertNextCell(21, lineIndices);
262 delete[] lineIndices;
263 pd->SetPoints(points);
266 contourWidget->Initialize(pd);
268 contourWidget->Render();
269 renderer->GetActiveCamera()->SetPosition(0, 0, 2.1);
270 renderer->AddActor(planeActor);
271 renderWindow->Render();
273 interactor->Initialize();
276 contourWidget->Off();