PageRenderTime 49ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Interaction/Widgets/vtkSeedWidget.cxx

https://github.com/aashish24/VTK-old
C++ | 413 lines | 293 code | 57 blank | 63 comment | 36 complexity | 856b1155dce8e33f5f228f3658e97f56 MD5 | raw file
  1. /*=========================================================================
  2. Program: Visualization Toolkit
  3. Module: vtkSeedWidget.cxx
  4. Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  5. All rights reserved.
  6. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  7. This software is distributed WITHOUT ANY WARRANTY; without even
  8. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  9. PURPOSE. See the above copyright notice for more information.
  10. =========================================================================*/
  11. #include "vtkSeedWidget.h"
  12. #include "vtkCallbackCommand.h"
  13. #include "vtkCommand.h"
  14. #include "vtkCoordinate.h"
  15. #include "vtkEvent.h"
  16. #include "vtkHandleRepresentation.h"
  17. #include "vtkHandleWidget.h"
  18. #include "vtkObjectFactory.h"
  19. #include "vtkRenderer.h"
  20. #include "vtkRenderWindow.h"
  21. #include "vtkRenderWindowInteractor.h"
  22. #include "vtkSeedRepresentation.h"
  23. #include "vtkWidgetCallbackMapper.h"
  24. #include "vtkWidgetEvent.h"
  25. #include <iterator>
  26. #include <list>
  27. vtkStandardNewMacro(vtkSeedWidget);
  28. // The vtkSeedList is a PIMPLed list<T>.
  29. class vtkSeedList : public std::list<vtkHandleWidget*> {};
  30. typedef std::list<vtkHandleWidget*>::iterator vtkSeedListIterator;
  31. //----------------------------------------------------------------------
  32. vtkSeedWidget::vtkSeedWidget()
  33. {
  34. this->ManagesCursor = 1;
  35. this->WidgetState = vtkSeedWidget::Start;
  36. // The widgets for moving the seeds.
  37. this->Seeds = new vtkSeedList;
  38. // These are the event callbacks supported by this widget
  39. this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
  40. vtkWidgetEvent::AddPoint,
  41. this, vtkSeedWidget::AddPointAction);
  42. this->CallbackMapper->SetCallbackMethod(vtkCommand::RightButtonPressEvent,
  43. vtkWidgetEvent::Completed,
  44. this, vtkSeedWidget::CompletedAction);
  45. this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
  46. vtkWidgetEvent::Move,
  47. this, vtkSeedWidget::MoveAction);
  48. this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent,
  49. vtkWidgetEvent::EndSelect,
  50. this, vtkSeedWidget::EndSelectAction);
  51. this->CallbackMapper->SetCallbackMethod(vtkCommand::KeyPressEvent,
  52. vtkEvent::NoModifier, 127, 1, "Delete",
  53. vtkWidgetEvent::Delete,
  54. this, vtkSeedWidget::DeleteAction);
  55. this->Defining = 1;
  56. }
  57. //----------------------------------------------------------------------
  58. void vtkSeedWidget::DeleteSeed(int i)
  59. {
  60. if( this->Seeds->size() <= static_cast< size_t >(i) )
  61. {
  62. return;
  63. }
  64. vtkSeedRepresentation *rep =
  65. static_cast<vtkSeedRepresentation*>(this->WidgetRep);
  66. if (rep)
  67. {
  68. rep->RemoveHandle( i );
  69. }
  70. vtkSeedListIterator iter = this->Seeds->begin();
  71. std::advance(iter,i);
  72. (*iter)->SetEnabled(0);
  73. (*iter)->RemoveObservers(vtkCommand::StartInteractionEvent);
  74. (*iter)->RemoveObservers(vtkCommand::InteractionEvent);
  75. (*iter)->RemoveObservers(vtkCommand::EndInteractionEvent);
  76. vtkHandleWidget * w = (*iter);
  77. this->Seeds->erase( iter );
  78. w->Delete();
  79. }
  80. //----------------------------------------------------------------------
  81. vtkSeedWidget::~vtkSeedWidget()
  82. {
  83. // Loop over all seeds releasing their observers and deleting them
  84. while( !this->Seeds->empty() )
  85. {
  86. this->DeleteSeed(static_cast<int>(this->Seeds->size())-1);
  87. }
  88. delete this->Seeds;
  89. }
  90. //----------------------------------------------------------------------
  91. vtkHandleWidget * vtkSeedWidget::GetSeed(int i)
  92. {
  93. if( this->Seeds->size() <= static_cast< size_t >(i) )
  94. {
  95. return NULL;
  96. }
  97. vtkSeedListIterator iter = this->Seeds->begin();
  98. std::advance(iter,i);
  99. return *iter;
  100. }
  101. //----------------------------------------------------------------------
  102. void vtkSeedWidget::CreateDefaultRepresentation()
  103. {
  104. if ( ! this->WidgetRep )
  105. {
  106. this->WidgetRep = vtkSeedRepresentation::New();
  107. }
  108. }
  109. //----------------------------------------------------------------------
  110. void vtkSeedWidget::SetEnabled(int enabling)
  111. {
  112. this->Superclass::SetEnabled( enabling );
  113. vtkSeedListIterator iter;
  114. for ( iter = this->Seeds->begin(); iter != this->Seeds->end(); ++iter )
  115. {
  116. (*iter)->SetEnabled( enabling );
  117. }
  118. if ( !enabling )
  119. {
  120. this->RequestCursorShape( VTK_CURSOR_DEFAULT );
  121. this->WidgetState = vtkSeedWidget::Start;
  122. }
  123. this->Render();
  124. }
  125. // The following methods are the callbacks that the seed widget responds to.
  126. //-------------------------------------------------------------------------
  127. void vtkSeedWidget::AddPointAction(vtkAbstractWidget *w)
  128. {
  129. vtkSeedWidget *self = reinterpret_cast<vtkSeedWidget*>(w);
  130. // Need to distinguish between placing handles and manipulating handles
  131. if ( self->WidgetState == vtkSeedWidget::MovingSeed )
  132. {
  133. return;
  134. }
  135. // compute some info we need for all cases
  136. int X = self->Interactor->GetEventPosition()[0];
  137. int Y = self->Interactor->GetEventPosition()[1];
  138. // When a seed is placed, a new handle widget must be created and enabled.
  139. int state = self->WidgetRep->ComputeInteractionState(X,Y);
  140. if ( state == vtkSeedRepresentation::NearSeed )
  141. {
  142. self->WidgetState = vtkSeedWidget::MovingSeed;
  143. // Invoke an event on ourself for the handles
  144. self->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
  145. self->Superclass::StartInteraction();
  146. self->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
  147. self->EventCallbackCommand->SetAbortFlag(1);
  148. self->Render();
  149. }
  150. else if ( self->WidgetState != vtkSeedWidget::PlacedSeeds)
  151. {
  152. // we are placing a new seed. Just make sure we aren't in a mode which
  153. // dictates we've placed all seeds.
  154. self->WidgetState = vtkSeedWidget::PlacingSeeds;
  155. double e[3]; e[2]=0.0;
  156. e[0] = static_cast<double>(X);
  157. e[1] = static_cast<double>(Y);
  158. vtkSeedRepresentation *rep =
  159. reinterpret_cast<vtkSeedRepresentation*>(self->WidgetRep);
  160. // if the handle representation is constrained, check to see if
  161. // the position follows the constraint.
  162. if ( !rep->GetHandleRepresentation()->CheckConstraint(
  163. self->GetCurrentRenderer(), e ) )
  164. {
  165. return ;
  166. }
  167. int currentHandleNumber = rep->CreateHandle(e);
  168. vtkHandleWidget *currentHandle = self->CreateNewHandle();
  169. rep->SetSeedDisplayPosition(currentHandleNumber,e);
  170. currentHandle->SetEnabled(1);
  171. self->InvokeEvent(vtkCommand::PlacePointEvent,&(currentHandleNumber));
  172. self->InvokeEvent(vtkCommand::InteractionEvent,&(currentHandleNumber));
  173. self->EventCallbackCommand->SetAbortFlag(1);
  174. self->Render();
  175. }
  176. }
  177. //-------------------------------------------------------------------------
  178. void vtkSeedWidget::CompletedAction(vtkAbstractWidget *w)
  179. {
  180. vtkSeedWidget *self = reinterpret_cast<vtkSeedWidget*>(w);
  181. // Do something only if we are in the middle of placing the seeds
  182. if ( self->WidgetState == vtkSeedWidget::PlacingSeeds )
  183. {
  184. self->CompleteInteraction();
  185. }
  186. }
  187. //-------------------------------------------------------------------------
  188. void vtkSeedWidget::CompleteInteraction()
  189. {
  190. this->WidgetState = vtkSeedWidget::PlacedSeeds;
  191. this->EventCallbackCommand->SetAbortFlag(1);
  192. this->Defining = 0;
  193. }
  194. //-------------------------------------------------------------------------
  195. void vtkSeedWidget::RestartInteraction()
  196. {
  197. this->WidgetState = vtkSeedWidget::Start;
  198. this->Defining = 1;
  199. }
  200. //-------------------------------------------------------------------------
  201. void vtkSeedWidget::MoveAction(vtkAbstractWidget *w)
  202. {
  203. vtkSeedWidget *self = reinterpret_cast<vtkSeedWidget*>(w);
  204. // Do nothing if outside
  205. if ( self->WidgetState == vtkSeedWidget::Start )
  206. {
  207. return;
  208. }
  209. // else we are moving a seed
  210. self->InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
  211. // set the cursor shape to a hand if we are near a seed.
  212. int X = self->Interactor->GetEventPosition()[0];
  213. int Y = self->Interactor->GetEventPosition()[1];
  214. int state = self->WidgetRep->ComputeInteractionState(X,Y);
  215. // Change the cursor shape to a hand and invoke an interaction event if we
  216. // are near the seed
  217. if (state == vtkSeedRepresentation::NearSeed)
  218. {
  219. self->RequestCursorShape( VTK_CURSOR_HAND );
  220. vtkSeedRepresentation *rep = static_cast<
  221. vtkSeedRepresentation * >(self->WidgetRep);
  222. int seedIdx = rep->GetActiveHandle();
  223. self->InvokeEvent( vtkCommand::InteractionEvent, &seedIdx );
  224. self->EventCallbackCommand->SetAbortFlag(1);
  225. }
  226. else
  227. {
  228. self->RequestCursorShape( VTK_CURSOR_DEFAULT );
  229. }
  230. self->Render();
  231. }
  232. //-------------------------------------------------------------------------
  233. void vtkSeedWidget::EndSelectAction(vtkAbstractWidget *w)
  234. {
  235. vtkSeedWidget *self = reinterpret_cast<vtkSeedWidget*>(w);
  236. // Do nothing if outside
  237. if ( self->WidgetState != vtkSeedWidget::MovingSeed )
  238. {
  239. return;
  240. }
  241. // Revert back to the mode we were in prior to selection.
  242. self->WidgetState = self->Defining ?
  243. vtkSeedWidget::PlacingSeeds : vtkSeedWidget::PlacedSeeds;
  244. // Invoke event for seed handle
  245. self->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,NULL);
  246. self->EventCallbackCommand->SetAbortFlag(1);
  247. self->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
  248. self->Superclass::EndInteraction();
  249. self->Render();
  250. }
  251. //-------------------------------------------------------------------------
  252. void vtkSeedWidget::DeleteAction(vtkAbstractWidget *w)
  253. {
  254. vtkSeedWidget *self = reinterpret_cast<vtkSeedWidget*>(w);
  255. // Do nothing if outside
  256. if ( self->WidgetState != vtkSeedWidget::PlacingSeeds )
  257. {
  258. return;
  259. }
  260. // Remove last seed
  261. vtkSeedRepresentation *rep =
  262. reinterpret_cast<vtkSeedRepresentation*>(self->WidgetRep);
  263. int removeId = rep->GetActiveHandle();
  264. if ( removeId != -1 )
  265. {
  266. rep->RemoveActiveHandle();
  267. }
  268. else
  269. {
  270. rep->RemoveLastHandle();
  271. removeId = static_cast<int>(self->Seeds->size())-1;
  272. }
  273. self->DeleteSeed(removeId);
  274. // Got this event, abort processing if it
  275. self->EventCallbackCommand->SetAbortFlag(1);
  276. self->Render();
  277. }
  278. //----------------------------------------------------------------------
  279. void vtkSeedWidget::SetProcessEvents(int pe)
  280. {
  281. this->Superclass::SetProcessEvents(pe);
  282. vtkSeedListIterator iter = this->Seeds->begin();
  283. for (; iter != this->Seeds->end(); ++iter )
  284. {
  285. (*iter)->SetProcessEvents(pe);
  286. }
  287. }
  288. //----------------------------------------------------------------------
  289. void vtkSeedWidget::SetInteractor( vtkRenderWindowInteractor *rwi )
  290. {
  291. this->Superclass::SetInteractor(rwi);
  292. vtkSeedListIterator iter = this->Seeds->begin();
  293. for (; iter != this->Seeds->end(); ++iter )
  294. {
  295. (*iter)->SetInteractor(rwi);
  296. }
  297. }
  298. //----------------------------------------------------------------------
  299. void vtkSeedWidget::SetCurrentRenderer( vtkRenderer *ren )
  300. {
  301. this->Superclass::SetCurrentRenderer(ren);
  302. vtkSeedListIterator iter = this->Seeds->begin();
  303. for (; iter != this->Seeds->end(); ++iter )
  304. {
  305. if (!ren)
  306. {
  307. // Disable widget if its being removed from the the renderer
  308. (*iter)->EnabledOff();
  309. }
  310. (*iter)->SetCurrentRenderer(ren);
  311. }
  312. }
  313. //----------------------------------------------------------------------
  314. // Programmatically create a new handle.
  315. vtkHandleWidget * vtkSeedWidget::CreateNewHandle()
  316. {
  317. vtkSeedRepresentation *rep =
  318. vtkSeedRepresentation::SafeDownCast(this->WidgetRep);
  319. if (!rep)
  320. {
  321. vtkErrorMacro( << "Please set, or create a default seed representation "
  322. << "before adding requesting creation of a new handle." );
  323. return NULL;
  324. }
  325. // Create the handle widget or reuse an old one
  326. int currentHandleNumber = static_cast<int>(this->Seeds->size());
  327. vtkHandleWidget *widget = vtkHandleWidget::New();
  328. // Configure the handle widget
  329. widget->SetParent(this);
  330. widget->SetInteractor(this->Interactor);
  331. vtkHandleRepresentation *handleRep = rep->GetHandleRepresentation(currentHandleNumber);
  332. if (!handleRep)
  333. {
  334. widget->Delete();
  335. return NULL;
  336. }
  337. else
  338. {
  339. handleRep->SetRenderer(this->CurrentRenderer);
  340. widget->SetRepresentation(handleRep);
  341. // Now place the widget into the list of handle widgets (if not already there)
  342. this->Seeds->push_back( widget );
  343. return widget;
  344. }
  345. }
  346. //----------------------------------------------------------------------
  347. void vtkSeedWidget::PrintSelf(ostream& os, vtkIndent indent)
  348. {
  349. //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
  350. this->Superclass::PrintSelf(os,indent);
  351. os << indent << "WidgetState: " << this->WidgetState << endl;
  352. }