]> Creatis software - clitk.git/blob - tools/clitkMeshViewer.cxx
Rolled back to middle slice on first load
[clitk.git] / tools / clitkMeshViewer.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================*/
18
19 #include "vtkOBJReader.h"
20 #include "vtkPolyDataMapper.h"
21 #include "vtkRenderer.h"
22 #include "vtkRenderWindow.h"
23 #include "vtkActor.h"
24 #include "vtkCamera.h"
25 #include "vtkRenderWindowInteractor.h"
26 #include "vtkSmartPointer.h"
27 #include "vtkCommand.h"
28 #include "vtkAnimationCue.h"
29 #include "vtkAnimationScene.h"
30 #include "vtkProperty.h"
31 #include "vtkInteractorStyle.h"
32
33 #include "clitkCommon.h"
34 #include "clitkMeshViewer_ggo.h"
35
36 #include <string>
37 #include <iostream>
38 #include <vector>
39
40 typedef vtkSmartPointer<vtkOBJReader> ObjReaderType;
41 typedef vtkSmartPointer<vtkPolyDataMapper> MapperType;
42 typedef vtkSmartPointer<vtkActor> ActorType;
43
44
45 long run(const args_info_clitkMeshViewer& argsInfo);
46
47 // Adapted from vtkAnimationCue example...
48 class CueAnimator
49 {
50 public:
51   CueAnimator(std::vector<ActorType>& rActors) : m_Fps(1), m_CurrentActor(0), m_rActors(rActors) {
52     m_rActors[0]->SetVisibility(1);
53     for (unsigned int i = 1; i < m_rActors.size(); i++) {
54       m_rActors[i]->SetVisibility(0);
55     }
56   }
57   
58   ~CueAnimator() {
59    }
60   
61   void SetFps(double fps) {
62     m_Fps = fps;
63   }
64   
65   void StartCue(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info),
66                 vtkRenderer *ren)
67     {
68       //std::cout << "StartCue" << std::endl;
69     }
70   
71   void Tick(vtkAnimationCue::AnimationCueInfo *info,
72             vtkRenderer *ren)
73     {
74       //std::cout << "Tick AT:" << info->AnimationTime << " DT:" << info->DeltaTime << " CT:" << info->ClockTime << std::endl;
75       
76       m_rActors[m_CurrentActor]->SetVisibility(0);
77       
78       int step = lrint(m_Fps * info->AnimationTime);
79       int actor = step % m_rActors.size();
80       
81       //if (actor != m_CurrentActor) std::cout << "Showing frame: " << m_CurrentActor << std::endl;
82       m_CurrentActor = actor;
83       m_rActors[m_CurrentActor]->SetVisibility(1);
84       
85       ren->Render();
86     }
87   
88   void EndCue(vtkAnimationCue::AnimationCueInfo *info,
89               vtkRenderer *ren)
90     {
91       //std::cout << "EndCue" << std::endl;
92     }
93   
94 protected:
95   
96   double m_Fps;
97   clock_t m_LastTick;
98   double m_TotalTicks;
99   int m_CurrentActor;
100   std::vector<ActorType>& m_rActors;
101 };
102
103 class vtkAnimationCueObserver : public vtkCommand
104 {
105 public:
106   static vtkAnimationCueObserver *New()
107     {
108       return new vtkAnimationCueObserver;
109     }
110   
111   virtual void Execute(vtkObject *vtkNotUsed(caller),
112                        unsigned long event,
113                        void *calldata)
114     {
115       if(this->Animator!=0 && this->Renderer!=0)
116         {
117         vtkAnimationCue::AnimationCueInfo *info=
118           static_cast<vtkAnimationCue::AnimationCueInfo *>(calldata);
119         switch(event)
120           {
121           case vtkCommand::StartAnimationCueEvent:
122             this->Animator->StartCue(info,this->Renderer);
123             break;
124           case vtkCommand::EndAnimationCueEvent:
125             this->Animator->EndCue(info,this->Renderer);
126             break;
127           case vtkCommand::AnimationCueTickEvent:
128             this->Animator->Tick(info,this->Renderer);
129             break;
130           }
131         }
132       if(this->RenWin!=0)
133         {
134         this->RenWin->Render();
135         }
136     }
137   
138   vtkRenderer *Renderer;
139   vtkRenderWindow *RenWin;
140   CueAnimator *Animator;
141   
142 protected:
143   vtkAnimationCueObserver()
144     {
145       this->Renderer=0;
146       this->Animator=0;
147       this->RenWin=0;
148     }
149 };
150
151 class vtkWindowObserver : public vtkCommand
152 {
153 public:
154   static vtkWindowObserver *New()
155     {
156       return new vtkWindowObserver;
157     }
158
159   virtual void Execute(vtkObject *caller,
160                        unsigned long event,
161                        void *calldata)
162     {
163       vtkRenderWindowInteractor *isi = dynamic_cast<vtkRenderWindowInteractor *>(caller);
164       //std::cout << "Execute" << std::endl;
165       switch (event)
166       {
167         case vtkCommand::KeyPressEvent:
168         {
169           std::string key = isi->GetKeySym();
170           //std::cout << key[0] << std::endl;
171           switch (key[0])
172           {
173             case 'P':
174             case 'p':
175               if (this->m_Scene)
176                 this->m_Scene->Play();
177               break;
178           
179             case 'M':
180             case 'm':
181               if (this->m_Scene)
182                 this->m_Scene->Stop();
183               break;
184           
185             default:
186               break;
187           }
188         }
189           
190         default:
191           break;
192           
193       }
194       
195     }
196     
197     vtkAnimationScene* m_Scene;
198     
199   protected:
200     
201     vtkWindowObserver() : m_Scene(0) {}
202 };
203
204 int main(int argc, char** argv)
205 {
206   GGO(clitkMeshViewer, args_info);
207
208   return run(args_info);
209 }
210
211 long run(const args_info_clitkMeshViewer& argsInfo)
212 {
213   std::vector<ObjReaderType> objs;
214   std::vector<MapperType> mappers;
215   std::vector<ActorType> actors;
216   
217   bool verbose = argsInfo.verbose_flag;
218
219   int nfiles = argsInfo.inputs_num;
220   if (nfiles == 0)
221   {
222     std::cout << "At leas one mesh (.OBJ) file must be given. See clitkMeshViewer -h." << std::endl;
223     return -1;
224   }
225   
226   if (verbose) 
227     std::cout << nfiles << " file(s) to be loaded..." << std::endl;
228   
229   vtkSmartPointer<vtkRenderer> aRenderer = vtkRenderer::New();
230   for (int i = 0; i < nfiles; i++) {    
231     std::string file = argsInfo.inputs[i];
232     if (verbose)
233       std::cout << "Reading " << file << std::endl;
234     
235     vtkSmartPointer<vtkOBJReader> preader = vtkOBJReader::New();
236     preader->SetFileName(file.c_str());
237     preader->Update();
238     objs.push_back(preader);
239     
240     vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkPolyDataMapper::New();
241     skinMapper->SetInputConnection(preader->GetOutputPort());
242     skinMapper->ScalarVisibilityOff();
243     mappers.push_back(skinMapper);
244
245     vtkSmartPointer<vtkActor> skin = vtkActor::New();
246     skin->SetMapper(skinMapper);
247     actors.push_back(skin);
248
249     aRenderer->AddActor(skin);
250   }
251
252   vtkSmartPointer<vtkCamera> aCamera = vtkCamera::New();
253   aCamera->SetViewUp (0, 0, -1);
254   aCamera->SetPosition (0, 1, 0);
255   aCamera->SetFocalPoint (0, 0, 0);
256   aCamera->ComputeViewPlaneNormal();
257   aCamera->Dolly(1.5);
258
259   aRenderer->SetActiveCamera(aCamera);
260   aRenderer->ResetCamera ();
261   aRenderer->SetBackground(0,0,0);
262   aRenderer->ResetCameraClippingRange ();
263
264   vtkSmartPointer<vtkRenderWindow> renWin = vtkRenderWindow::New();
265   renWin->AddRenderer(aRenderer);
266   renWin->SetSize(640, 480);
267   
268   vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkRenderWindowInteractor::New();
269   iren->SetRenderWindow(renWin);
270   iren->Initialize();
271   
272   vtkSmartPointer<vtkAnimationScene> scene;
273   vtkSmartPointer<vtkAnimationCue> cue1;
274   vtkSmartPointer<vtkAnimationCueObserver> anim_observer;
275   vtkSmartPointer<vtkWindowObserver> window_observer;
276   CueAnimator animator(actors);
277   
278   bool animate = argsInfo.animate_flag;
279   if (animate) {
280     double fps = argsInfo.fps_arg;
281     animator.SetFps(fps);
282
283     // Create an Animation Scene
284     scene=vtkAnimationScene::New();
285     scene->SetModeToRealTime();
286
287     scene->SetLoop(1);
288     scene->SetTimeModeToRelative();
289     scene->SetStartTime(0);
290     scene->SetEndTime(actors.size()/fps);
291     
292     // Create an Animation Cue.
293     cue1=vtkAnimationCue::New();
294     cue1->SetTimeModeToRelative();
295     cue1->SetStartTime(0);
296     cue1->SetEndTime(actors.size()/fps);
297     scene->AddCue(cue1);
298     
299     // Create Cue anim_observer.
300     anim_observer=vtkAnimationCueObserver::New();
301     anim_observer->Renderer=aRenderer;
302     anim_observer->Animator=&animator;
303     anim_observer->RenWin=renWin;
304     cue1->AddObserver(vtkCommand::StartAnimationCueEvent,anim_observer);
305     cue1->AddObserver(vtkCommand::EndAnimationCueEvent,anim_observer);
306     cue1->AddObserver(vtkCommand::AnimationCueTickEvent,anim_observer);
307
308     window_observer = vtkWindowObserver::New();
309     window_observer->m_Scene = scene;
310     iren->AddObserver(vtkCommand::KeyPressEvent, window_observer);
311     
312   }
313
314   iren->Start(); 
315   return 0;
316 }
317
318