ctkVTKRenderView.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) 2010 Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QTimer>
  16. #include <QVBoxLayout>
  17. // CTK includes
  18. #include "ctkVTKRenderView.h"
  19. #include "ctkVTKRenderView_p.h"
  20. #include "ctkLogger.h"
  21. // VTK includes
  22. #include <vtkRendererCollection.h>
  23. #include <vtkRenderWindowInteractor.h>
  24. #include <vtkTextProperty.h>
  25. #include <vtkCamera.h>
  26. //--------------------------------------------------------------------------
  27. static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkVTKRenderView");
  28. //--------------------------------------------------------------------------
  29. // --------------------------------------------------------------------------
  30. // ctkVTKRenderViewPrivate methods
  31. // --------------------------------------------------------------------------
  32. ctkVTKRenderViewPrivate::ctkVTKRenderViewPrivate()
  33. {
  34. this->Renderer = vtkSmartPointer<vtkRenderer>::New();
  35. this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  36. this->Axes = vtkSmartPointer<vtkAxesActor>::New();
  37. this->Orientation = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
  38. this->CornerAnnotation = vtkSmartPointer<vtkCornerAnnotation>::New();
  39. this->RenderPending = false;
  40. this->RenderEnabled = false;
  41. this->ZoomFactor = 0.05;
  42. this->RotateDegrees = 5;
  43. this->PitchDirection = ctkVTKRenderView::PitchUp;
  44. this->RollDirection = ctkVTKRenderView::RollRight;
  45. this->YawDirection = ctkVTKRenderView::YawLeft;
  46. }
  47. // --------------------------------------------------------------------------
  48. void ctkVTKRenderViewPrivate::setupCornerAnnotation()
  49. {
  50. logger.trace("setupCornerAnnotation");
  51. if (!this->Renderer->HasViewProp(this->CornerAnnotation))
  52. {
  53. this->Renderer->AddViewProp(this->CornerAnnotation);
  54. this->CornerAnnotation->SetMaximumLineHeight(0.07);
  55. vtkTextProperty *tprop = this->CornerAnnotation->GetTextProperty();
  56. tprop->ShadowOn();
  57. }
  58. this->CornerAnnotation->ClearAllTexts();
  59. }
  60. //---------------------------------------------------------------------------
  61. void ctkVTKRenderViewPrivate::setupRendering()
  62. {
  63. logger.trace("setupRendering");
  64. Q_ASSERT(this->RenderWindow);
  65. this->RenderWindow->SetAlphaBitPlanes(1);
  66. this->RenderWindow->SetMultiSamples(0);
  67. this->RenderWindow->StereoCapableWindowOn();
  68. this->RenderWindow->GetRenderers()->RemoveAllItems();
  69. // Add renderer
  70. this->RenderWindow->AddRenderer(this->Renderer);
  71. // Setup the corner annotation
  72. this->setupCornerAnnotation();
  73. this->VTKWidget->SetRenderWindow(this->RenderWindow);
  74. }
  75. //---------------------------------------------------------------------------
  76. void ctkVTKRenderViewPrivate::setupDefaultInteractor()
  77. {
  78. logger.trace("setupDefaultInteractor");
  79. CTK_P(ctkVTKRenderView);
  80. p->setInteractor(this->RenderWindow->GetInteractor());
  81. }
  82. //----------------------------------------------------------------------------
  83. void ctkVTKRenderViewPrivate::zoom(double zoomFactor)
  84. {
  85. Q_ASSERT(this->Renderer->IsActiveCameraCreated());
  86. vtkCamera * camera = this->Renderer->GetActiveCamera();
  87. if (camera->GetParallelProjection())
  88. {
  89. camera->SetParallelScale(camera->GetParallelScale() / (1 + zoomFactor));
  90. }
  91. else
  92. {
  93. camera->Dolly(1 + zoomFactor);
  94. this->Renderer->ResetCameraClippingRange();
  95. this->Renderer->UpdateLightsGeometryToFollowCamera();
  96. }
  97. }
  98. //---------------------------------------------------------------------------
  99. // ctkVTKRenderView methods
  100. // --------------------------------------------------------------------------
  101. ctkVTKRenderView::ctkVTKRenderView(QWidget* _parent) : Superclass(_parent)
  102. {
  103. CTK_INIT_PRIVATE(ctkVTKRenderView);
  104. CTK_D(ctkVTKRenderView);
  105. d->VTKWidget = new QVTKWidget(this);
  106. this->setLayout(new QVBoxLayout);
  107. this->layout()->setMargin(0);
  108. this->layout()->setSpacing(0);
  109. this->layout()->addWidget(d->VTKWidget);
  110. d->setupRendering();
  111. d->setupDefaultInteractor();
  112. }
  113. //----------------------------------------------------------------------------
  114. void ctkVTKRenderView::scheduleRender()
  115. {
  116. CTK_D(ctkVTKRenderView);
  117. logger.trace(QString("scheduleRender - RenderEnabled: %1 - RenderPending: %2").
  118. arg(d->RenderEnabled ? "true" : "false")
  119. .arg(d->RenderPending ? "true:" : "false"));
  120. if (!d->RenderEnabled)
  121. {
  122. return;
  123. }
  124. if (!d->RenderPending)
  125. {
  126. d->RenderPending = true;
  127. QTimer::singleShot(0, this, SLOT(forceRender()));
  128. }
  129. }
  130. //----------------------------------------------------------------------------
  131. void ctkVTKRenderView::forceRender()
  132. {
  133. CTK_D(ctkVTKRenderView);
  134. logger.trace(QString("forceRender - RenderEnabled: %1")
  135. .arg(d->RenderEnabled ? "true" : "false"));
  136. if (!d->RenderEnabled)
  137. {
  138. return;
  139. }
  140. d->RenderWindow->Render();
  141. d->RenderPending = false;
  142. }
  143. //----------------------------------------------------------------------------
  144. CTK_GET_CXX(ctkVTKRenderView, vtkRenderWindow*, renderWindow, RenderWindow);
  145. //----------------------------------------------------------------------------
  146. CTK_GET_CXX(ctkVTKRenderView, vtkRenderWindowInteractor*, interactor, CurrentInteractor);
  147. //----------------------------------------------------------------------------
  148. void ctkVTKRenderView::setInteractor(vtkRenderWindowInteractor* newInteractor)
  149. {
  150. CTK_D(ctkVTKRenderView);
  151. logger.trace("setInteractor");
  152. d->RenderWindow->SetInteractor(newInteractor);
  153. d->Orientation->SetOrientationMarker(d->Axes);
  154. d->Orientation->SetInteractor(newInteractor);
  155. d->Orientation->SetEnabled(1);
  156. d->Orientation->InteractiveOff();
  157. d->CurrentInteractor = newInteractor;
  158. }
  159. //----------------------------------------------------------------------------
  160. vtkInteractorObserver* ctkVTKRenderView::interactorStyle()
  161. {
  162. CTK_D(ctkVTKRenderView);
  163. if (d->CurrentInteractor)
  164. {
  165. return d->CurrentInteractor->GetInteractorStyle();
  166. }
  167. else
  168. {
  169. return 0;
  170. }
  171. }
  172. //----------------------------------------------------------------------------
  173. void ctkVTKRenderView::setCornerAnnotationText(const QString& text)
  174. {
  175. CTK_D(ctkVTKRenderView);
  176. logger.trace(QString("setCornerAnnotationText: %1").arg(text));
  177. d->CornerAnnotation->ClearAllTexts();
  178. d->CornerAnnotation->SetText(2, text.toLatin1());
  179. }
  180. //----------------------------------------------------------------------------
  181. QString ctkVTKRenderView::cornerAnnotationText() const
  182. {
  183. CTK_D(const ctkVTKRenderView);
  184. return QLatin1String(d->CornerAnnotation->GetText(2));
  185. }
  186. // --------------------------------------------------------------------------
  187. void ctkVTKRenderView::setBackgroundColor(const QColor& newBackgroundColor)
  188. {
  189. CTK_D(ctkVTKRenderView);
  190. logger.trace(QString("setBackgroundColor: %1").arg(newBackgroundColor.name()));
  191. d->Renderer->SetBackground(newBackgroundColor.redF(),
  192. newBackgroundColor.greenF(),
  193. newBackgroundColor.blueF());
  194. }
  195. //----------------------------------------------------------------------------
  196. QColor ctkVTKRenderView::backgroundColor() const
  197. {
  198. CTK_D(const ctkVTKRenderView);
  199. double color[3] = {0, 0, 0};
  200. d->Renderer->GetBackground(color);
  201. return QColor::fromRgbF(color[0], color[1], color[2]);
  202. }
  203. //----------------------------------------------------------------------------
  204. void ctkVTKRenderView::setOrientationWidgetVisible(bool visible)
  205. {
  206. CTK_D(ctkVTKRenderView);
  207. d->Orientation->SetEnabled(visible);
  208. }
  209. //----------------------------------------------------------------------------
  210. bool ctkVTKRenderView::orientationWidgetVisible()
  211. {
  212. CTK_D(ctkVTKRenderView);
  213. return d->Orientation->GetEnabled();
  214. }
  215. //----------------------------------------------------------------------------
  216. vtkCamera* ctkVTKRenderView::activeCamera()
  217. {
  218. CTK_D(ctkVTKRenderView);
  219. if (d->Renderer->IsActiveCameraCreated())
  220. {
  221. return d->Renderer->GetActiveCamera();
  222. }
  223. else
  224. {
  225. return 0;
  226. }
  227. }
  228. //----------------------------------------------------------------------------
  229. void ctkVTKRenderView::resetCamera()
  230. {
  231. CTK_D(ctkVTKRenderView);
  232. logger.trace("resetCamera");
  233. d->Renderer->ResetCamera();
  234. }
  235. //----------------------------------------------------------------------------
  236. CTK_GET_CXX(ctkVTKRenderView, vtkRenderer*, renderer, Renderer);
  237. //----------------------------------------------------------------------------
  238. CTK_SET_CXX(ctkVTKRenderView, bool, setRenderEnabled, RenderEnabled);
  239. CTK_GET_CXX(ctkVTKRenderView, bool, renderEnabled, RenderEnabled);
  240. //----------------------------------------------------------------------------
  241. CTK_GET_CXX(ctkVTKRenderView, int, rotateDegrees, RotateDegrees);
  242. //----------------------------------------------------------------------------
  243. void ctkVTKRenderView::setRotateDegrees(int newRotateDegrees)
  244. {
  245. CTK_D(ctkVTKRenderView);
  246. d->RotateDegrees = qAbs(newRotateDegrees);
  247. }
  248. //----------------------------------------------------------------------------
  249. CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::PitchDirection, pitchDirection, PitchDirection);
  250. CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::PitchDirection, setPitchDirection, PitchDirection);
  251. //----------------------------------------------------------------------------
  252. CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::RollDirection, rollDirection, RollDirection);
  253. CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::RollDirection, setRollDirection, RollDirection);
  254. //----------------------------------------------------------------------------
  255. CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::YawDirection, yawDirection, YawDirection);
  256. CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::YawDirection, setYawDirection, YawDirection);
  257. //----------------------------------------------------------------------------
  258. void ctkVTKRenderView::pitch()
  259. {
  260. CTK_D(ctkVTKRenderView);
  261. if (!d->Renderer->IsActiveCameraCreated())
  262. {
  263. return;
  264. }
  265. vtkCamera *cam = d->Renderer->GetActiveCamera();
  266. cam->Elevation(d->PitchDirection == Self::PitchDown ? d->RotateDegrees : -d->RotateDegrees);
  267. cam->OrthogonalizeViewUp();
  268. d->Renderer->UpdateLightsGeometryToFollowCamera();
  269. }
  270. //----------------------------------------------------------------------------
  271. void ctkVTKRenderView::roll()
  272. {
  273. CTK_D(ctkVTKRenderView);
  274. if (!d->Renderer->IsActiveCameraCreated())
  275. {
  276. return;
  277. }
  278. vtkCamera *cam = d->Renderer->GetActiveCamera();
  279. cam->Roll(d->RollDirection == Self::RollLeft ? d->RotateDegrees : -d->RotateDegrees);
  280. cam->OrthogonalizeViewUp();
  281. d->Renderer->UpdateLightsGeometryToFollowCamera();
  282. }
  283. //----------------------------------------------------------------------------
  284. void ctkVTKRenderView::yaw()
  285. {
  286. CTK_D(ctkVTKRenderView);
  287. if (!d->Renderer->IsActiveCameraCreated())
  288. {
  289. return;
  290. }
  291. vtkCamera *cam = d->Renderer->GetActiveCamera();
  292. cam->Azimuth(d->YawDirection == Self::YawLeft ? d->RotateDegrees : -d->RotateDegrees);
  293. cam->OrthogonalizeViewUp();
  294. d->Renderer->UpdateLightsGeometryToFollowCamera();
  295. }
  296. //----------------------------------------------------------------------------
  297. void ctkVTKRenderView::setZoomFactor(double newZoomFactor)
  298. {
  299. CTK_D(ctkVTKRenderView);
  300. d->ZoomFactor = qBound(0.0, qAbs(newZoomFactor), 1.0);
  301. }
  302. //----------------------------------------------------------------------------
  303. CTK_GET_CXX(ctkVTKRenderView, double, zoomFactor, ZoomFactor);
  304. //----------------------------------------------------------------------------
  305. void ctkVTKRenderView::zoomIn()
  306. {
  307. CTK_D(ctkVTKRenderView);
  308. if (!d->Renderer->IsActiveCameraCreated())
  309. {
  310. return;
  311. }
  312. d->zoom(d->ZoomFactor);
  313. }
  314. //----------------------------------------------------------------------------
  315. void ctkVTKRenderView::zoomOut()
  316. {
  317. CTK_D(ctkVTKRenderView);
  318. if (!d->Renderer->IsActiveCameraCreated())
  319. {
  320. return;
  321. }
  322. d->zoom(-d->ZoomFactor);
  323. }
  324. //----------------------------------------------------------------------------
  325. void ctkVTKRenderView::setFocalPoint(int x, int y, int z)
  326. {
  327. CTK_D(ctkVTKRenderView);
  328. if (!d->Renderer->IsActiveCameraCreated())
  329. {
  330. return;
  331. }
  332. vtkCamera * camera = d->Renderer->GetActiveCamera();
  333. camera->SetFocalPoint(x, y, z);
  334. camera->ComputeViewPlaneNormal();
  335. camera->OrthogonalizeViewUp();
  336. d->Renderer->UpdateLightsGeometryToFollowCamera();
  337. }
  338. //----------------------------------------------------------------------------
  339. void ctkVTKRenderView::resetFocalPoint()
  340. {
  341. CTK_D(ctkVTKRenderView);
  342. double bounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
  343. d->Renderer->ComputeVisiblePropBounds(bounds);
  344. double x_center = (bounds[1] + bounds[0]) / 2.0;
  345. double y_center = (bounds[3] + bounds[2]) / 2.0;
  346. double z_center = (bounds[5] + bounds[4]) / 2.0;
  347. this->setFocalPoint(x_center, y_center, z_center);
  348. }