Fraxinus  17.12-rc2
An IGT application
cxCustomMetricRep.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxCustomMetricRep.h"
34 
35 #include <boost/shared_ptr.hpp>
36 #include <vtkRenderer.h>
37 #include <vtkCamera.h>
38 #include <vtkImageActor.h>
39 #include <vtkSelectVisiblePoints.h>
40 #include "cxTypeConversions.h"
41 #include "cxCustomMetric.h"
42 #include "cxLogger.h"
43 #include "cxBoundingBox3D.h"
44 #include "cxGeometricRep.h"
45 #include "cxMesh.h"
46 #include "cxImage.h"
47 #include "cxImage2DRep3D.h"
48 #include "cxGraphicalPrimitives.h"
49 
50 
51 namespace cx
52 {
53 
55 {
56  return wrap_new(new CustomMetricRep(), uid);
57 }
58 
59 CustomMetricRep::CustomMetricRep()
60 {
61 }
62 
64 {
66  mMeshGeometry.clear();
67  for(int i = 0; i < mImageGeometryProxy.size(); ++i)
68  {
69  this->getRenderer()->RemoveActor(mImageGeometryProxy[i]->getActor());
70  }
71  mImageGeometryProxy.clear();
72 }
73 
74 CustomMetricPtr CustomMetricRep::getCustomMetric()
75 {
76  return boost::dynamic_pointer_cast<CustomMetric>(mMetric);
77 }
78 
80 {
81  if (!mMetric)
82  return;
83 
84  this->updateModel();
85  this->drawText();
86 }
87 
89 {
90  this->hideDistanceMetrics();
91 }
92 
93 void CustomMetricRep::updateModel()
94 {
95  this->clear();
96  CustomMetricPtr custom = this->getCustomMetric();
97 
98  if (!this->getView() || !custom)
99  return;
100 
101  DataPtr model = custom->getModel();
102 
103  if(custom->modelIsImage())
104  this->updateImageModel(model);
105  else
106  this->updateMeshModel(model);
107  this->createDistanceMarkers();
108 }
109 
110 void CustomMetricRep::updateImageModel(DataPtr model)
111 {
112  ImagePtr imageModel = boost::dynamic_pointer_cast<Image>(model);
113 
114  if(!imageModel && !imageModel->is2D())
115  return;
116 
117  CustomMetricPtr custom = this->getCustomMetric();
118  std::vector<Transform3D> pos = custom->calculateOrientations();
119 
120  mImageGeometryProxy.resize(pos.size());
121 
122  for(unsigned i = 0; i < mImageGeometryProxy.size(); ++i)
123  {
124  if(!mImageGeometryProxy[i])
125  mImageGeometryProxy[i] = cx::Image2DProxy::New();
126 
127  mImageGeometryProxy[i]->setImage(imageModel);
128  this->getRenderer()->AddActor(mImageGeometryProxy[i]->getActor());
129 
130  mImageGeometryProxy[i]->setTransformOffset(pos[i]);
131  }
132 }
133 
134 void CustomMetricRep::updateMeshModel(DataPtr model)
135 {
136  MeshPtr meshModel = boost::dynamic_pointer_cast<Mesh>(model);
137 
138  CustomMetricPtr custom = this->getCustomMetric();
139  std::vector<Transform3D> pos = custom->calculateOrientations();
140 
141  mMeshGeometry.resize(pos.size());
142 
143  for (unsigned i=0; i<mMeshGeometry.size(); ++i)
144  {
145  if (!mMeshGeometry[i])
146  {
147  mMeshGeometry[i].reset(new GraphicalGeometric);
148  mMeshGeometry[i]->setRenderer(this->getRenderer());
149  }
150 
151  mMeshGeometry[i]->setMesh(meshModel);
152 
153  mMeshGeometry[i]->setTransformOffset(pos[i]);
154 
155  custom->updateTexture(meshModel, pos[i]);
156  }
157 
158 }
159 
160 void CustomMetricRep::createDistanceMarkers()
161 {
162  mDistanceText.clear();
163  CustomMetricPtr custom = this->getCustomMetric();
164  if(!custom->getModel() || !custom->getShowDistanceMarkers())
165  return;
166  std::vector<Transform3D> pos = custom->calculateOrientations();
167 
168  if(pos.size() < 2)
169  return;
170 
171  DoubleBoundingBox3D bounds = custom->getModel()->boundingBox();
172 
173 
174  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
175  points->SetNumberOfPoints(pos.size());
176 
177  mDistanceText.resize(pos.size());
178  Vector3D pos_0 = custom->getZeroPosition();
179  for(unsigned i = 0; i < mDistanceText.size(); ++i)
180  {
181  Vector3D pos_i = pos[i].coord(Vector3D(0,0,0));
182  double distance = (pos_i - pos_0).length();
183  Vector3D textpos = bounds.center();
184  textpos[2] = bounds.bottomLeft()[2];
185  mDistanceText[i] = this->createDistanceText(pos[i].coord(textpos), distance);
186 
187  Vector3D point = pos[i].coord(textpos);
188  vtkIdType pointId = i;
189  points->SetPoint(pointId, point.data());
190  }
191 }
192 
193 CaptionText3DPtr CustomMetricRep::createDistanceText(Vector3D pos, double distance)
194 {
196  text->setColor(mMetric->getColor());
197  text->setText(QString("%1").arg(distance));
198 
199  text->setPosition(pos);
200  text->placeAboveCenter();
201  text->setSize(mLabelSize / 100);
202 
203  return text;
204 }
205 
206 //Hide the distance metrics if outside the view port, obscured by other structures, or of too far from the camera
207 void CustomMetricRep::hideDistanceMetrics()
208 {
209  if(mDistanceText.empty())
210  return;
211  static vtkSmartPointer<vtkSelectVisiblePoints> visPts = vtkSmartPointer<vtkSelectVisiblePoints>::New();
212  visPts->SetRenderer(this->getRenderer());
213  float * zbuffer = visPts->Initialize(true);
214 
215  for(unsigned i = 0; i < mDistanceText.size(); ++i)
216  {
217  Vector3D pos = mDistanceText[i]->getPosition();
218  bool visible = visPts->IsPointOccluded(pos.data(), zbuffer);
219  bool closeToCamera = this->isCloseToCamera(pos);
220  mDistanceText[i]->setVisibility(visible && closeToCamera);
221  }
222  delete zbuffer;
223 }
224 
225 bool CustomMetricRep::isCloseToCamera(Vector3D pos)
226 {
227  double distanceThreshold = this->getCustomMetric()->getDistanceMarkerVisibility();
228  Vector3D cameraPos(this->getRenderer()->GetActiveCamera()->GetPosition());
229  Vector3D diff = cameraPos - pos;
230  double distance = diff.norm();
231  if(distance < distanceThreshold)
232  return true;
233  return false;
234 }
235 
236 }
ViewPtr getView() const
Definition: cxRepImpl.cpp:104
vtkRendererPtr getRenderer()
Definition: cxRepImpl.cpp:109
A mesh data set.
Definition: cxMesh.h:66
virtual void onModifiedStartRender()
virtual void onEveryRender()
Display one Mesh in 3D.
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
Vector3D bottomLeft() const
virtual void clear()
static boost::shared_ptr< REP > wrap_new(REP *object, QString uid)
Definition: cxRepImpl.h:83
boost::shared_ptr< class Data > DataPtr
A volumetric data set.
Definition: cxImage.h:66
Data class that represents a custom.
boost::shared_ptr< class CustomMetricRep > CustomMetricRepPtr
Helper for rendering 3D text that faces the camera and has a constant viewed size, always on top.
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Vector3D center() const
RealScalar length() const
boost::shared_ptr< class Mesh > MeshPtr
DataMetricPtr mMetric
boost::shared_ptr< CaptionText3D > CaptionText3DPtr
static Image2DProxyPtr New()
boost::shared_ptr< class CustomMetric > CustomMetricPtr
static CustomMetricRepPtr New(const QString &uid="")
Namespace for all CustusX production code.