]> Creatis software - cpPlugins.git/blob - appli/examples/example_ContourWidget.cxx
c3b405cde3c3d59440d9bd94831d66771f1a5746
[cpPlugins.git] / appli / examples / example_ContourWidget.cxx
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>
11 #include <vtkPlane.h>
12 #include <vtkPolyData.h>
13 #include <vtkCellArray.h>
14 #include <vtkPoints.h>
15 #include <vtkMath.h>
16 #include <vtkWidgetEvent.h>
17 #include <vtkWidgetEventTranslator.h>
18 #include <vtkInteractorStyleTrackballCamera.h>
19 #include <vtkInteractorStyleImage.h>
20
21 #include <vtkPNGReader.h>
22 #include <vtkImageViewer2.h> 
23 #include <vtkObjectFactory.h>
24 #include <vtkPolyDataMapper.h>
25 #include <vtkPolyData.h>
26 #include <vtkActor.h>
27 #include <vtkPlaneSource.h>
28 #include <vtkInteractorObserver.h>
29 #include <cmath>
30
31 vtkSmartPointer<vtkContourWidget> contourWidget;
32 vtkSmartPointer<vtkPolyData> pd;
33 vtkSmartPointer<vtkRenderWindowInteractor> interactor;
34 vtkSmartPointer<vtkOrientedGlyphContourRepresentation> contourRep;
35
36 // class for handling interaction on/off
37 class KeyPressInteractorStyle : public vtkInteractorStyleImage//vtkInteractorStyleTrackballCamera
38 {
39 public:
40         static KeyPressInteractorStyle* New();
41         vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera);
42
43         
44
45         virtual void OnKeyPress()
46         {
47                 // Get the keypress
48                 vtkRenderWindowInteractor *rwi = this->Interactor;
49                 std::string key = rwi->GetKeySym();
50
51                 int ctrlKeyInd = rwi->GetControlKey();
52
53                 int altKeyInd = rwi->GetAltKey();
54
55                 int shiftKeyInd = rwi->GetShiftKey();
56
57                 // Output the key that was pressed
58                 std::cout << "Pressed " << key << std::endl;
59
60                 // Handle an arrow key
61                 if (key == "Up")
62                 {       
63
64                         std::cout << "UP" << std::endl;
65                         
66                 }
67
68                 // Handle a "normal" key
69                 if (key == "Down")
70                 {
71                         std::cout << "DOWN" << std::endl;               
72                         
73                 }
74
75                 if (ctrlKeyInd != 0)
76                 {
77                         if (key == "z" || key == "Z")
78                         {
79                                 std::cout << "undo" << std::endl;
80
81                         }
82
83                         if (key == "y" || key == "Y")
84                         {
85                                 std::cout << "redo" << std::endl;
86
87                         }
88                 }
89
90                 // Forward events
91                 vtkInteractorStyleTrackballCamera::OnKeyPress();
92         }
93
94 };
95 vtkStandardNewMacro(KeyPressInteractorStyle);
96
97 double* GetClosesstPointToPlane(double * n, double * p)
98 {
99         double* closest = new double[2]();
100                 
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];
105
106         return closest;
107 }
108
109 double* normal;
110 double* center;
111
112 // class for handling click over the contour
113 class ContourCallBack : public vtkCommand
114 {
115 public:
116         static ContourCallBack *New()
117         {
118                 return new ContourCallBack;
119         }
120         ContourCallBack(){}
121
122         virtual void Execute(vtkObject *caller, unsigned long eid, void* clientData)
123         {
124                 
125
126                 vtkContourWidget *contourWidget =
127                         reinterpret_cast<vtkContourWidget*>(caller);
128
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] 
133                         << std::endl;
134
135                 // get the node postiion (the world position)
136                 vtkContourRepresentation * rep=contourWidget->GetContourRepresentation();
137                 double* worldclick = new double[2]();
138                 rep->GetActiveNodeWorldPosition(worldclick);
139                 
140                 std::cout << "worldclick click " << worldclick[0] << " " << worldclick[1] << " " << worldclick[2] << std::endl;
141
142                 // change position
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
147
148                 projection = GetClosesstPointToPlane(normal, worldclick);
149
150                 std::cout << "projection click " << projection[0] << " " << projection[1] << " " << projection[2] << std::endl;
151
152                 rep->SetActiveNodeToWorldPosition(projection);
153                 //delete(nodepos);
154         }
155
156 };
157
158 int main(int argc, char *argv[])
159 {
160         normal = new double[2]();
161         normal[0] = 1;
162         normal[1] = 1;
163         normal[2] = 1;
164         center = new double[2]();
165
166         // Create the RenderWindow, Renderer and both Actors
167         //
168         vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
169         vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
170         renderWindow->AddRenderer(renderer);
171
172         vtkSmartPointer<vtkRenderWindowInteractor> interactor =
173                 vtkSmartPointer<vtkRenderWindowInteractor>::New();
174         interactor->SetRenderWindow(renderWindow);
175
176         renderer->SetBackground(0.1, 0.2, 0.4);
177         renderWindow->SetSize(600, 600);
178
179         // visual reference
180         // Create a plane
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();
186
187         vtkPolyData* plane = planeSource->GetOutput();
188
189         // Create a mapper and actor
190         vtkSmartPointer<vtkPolyDataMapper> mapper =
191                 vtkSmartPointer<vtkPolyDataMapper>::New();
192         mapper->SetInputData(plane);
193
194         vtkSmartPointer<vtkActor> planeActor =
195                 vtkSmartPointer<vtkActor>::New();
196         planeActor->SetMapper(mapper);
197
198         vtkSmartPointer<KeyPressInteractorStyle> style =
199                 vtkSmartPointer<KeyPressInteractorStyle>::New();
200         interactor->SetInteractorStyle(style);
201
202         // create the contour stuff
203         vtkSmartPointer<vtkOrientedGlyphContourRepresentation> contourRep =
204                 vtkSmartPointer<vtkOrientedGlyphContourRepresentation>::New();
205         contourRep->GetLinesProperty()->SetColor(0, 0, 1); //set color to red
206
207         vtkSmartPointer<vtkContourWidget> contourWidget =
208                 vtkSmartPointer<vtkContourWidget>::New();
209         contourWidget->SetInteractor(interactor);
210         contourWidget->SetRepresentation(contourRep);
211         
212         contourWidget->On();
213
214         for (int i = 0; i < argc; i++)
215         {
216                 if (strcmp("-Shift", argv[i]) == 0)
217                 {
218                         contourWidget->GetEventTranslator()->RemoveTranslation(
219                                 vtkCommand::LeftButtonPressEvent);
220                         contourWidget->GetEventTranslator()->SetTranslation(
221                                 vtkCommand::LeftButtonPressEvent,
222                                 vtkWidgetEvent::Translate);
223                 }
224                 else if (strcmp("-Scale", argv[i]) == 0)
225                 {
226                         contourWidget->GetEventTranslator()->RemoveTranslation(
227                                 vtkCommand::LeftButtonPressEvent);
228                         contourWidget->GetEventTranslator()->SetTranslation(
229                                 vtkCommand::LeftButtonPressEvent,
230                                 vtkWidgetEvent::Scale);
231                 }
232         }
233
234         //Add an observer to contour widget
235         vtkSmartPointer<ContourCallBack> contourCallBack =
236                 vtkSmartPointer<ContourCallBack>::New();
237         contourWidget->AddObserver(vtkCommand::InteractionEvent, contourCallBack);
238
239         // quick points for representation
240         vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New();
241
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++)
246         {
247                 const double angle = 2.0*vtkMath::Pi()*i / 20.0;
248                 double* closest = new double[2]();
249                 double* p = new double[2]();
250
251                 p[0] = 0.2*cos(angle);
252                 p[1] = 0.2*sin(angle);
253                 p[2] = 0.0;
254
255                 closest = GetClosesstPointToPlane(normal, p);
256                 points->InsertPoint(static_cast<vtkIdType>(i), closest);
257                 lineIndices[i] = static_cast<vtkIdType>(i);
258         }
259
260         lineIndices[20] = 0;
261         lines->InsertNextCell(21, lineIndices);
262         delete[] lineIndices;
263         pd->SetPoints(points);
264         pd->SetLines(lines);
265
266         contourWidget->Initialize(pd);  
267         
268         contourWidget->Render();
269         renderer->GetActiveCamera()->SetPosition(0, 0, 2.1);
270         renderer->AddActor(planeActor);
271         renderWindow->Render();
272
273         interactor->Initialize();
274         interactor->Start();
275
276         contourWidget->Off();
277
278         return EXIT_SUCCESS;
279 }