Fraxinus  17.12
An IGT application
cxMetricNamesRep.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 #include "cxMetricNamesRep.h"
33 
34 #include <vtkRenderer.h>
35 #include <vtkActor2D.h>
36 #include <vtkTextProperty.h>
37 #include <vtkTextMapper.h>
38 #include <QTimer>
39 
40 #include "cxView.h"
41 #include "cxVtkHelperClasses.h"
42 #include "cxTypeConversions.h"
43 #include "cxDataMetric.h"
44 #include "cxLogger.h"
45 
46 
47 namespace cx
48 {
49 
51  RepImpl()
52 {
53  mFontSize = 20;
54 }
55 
57 {
58 }
59 
61 {
62  return wrap_new(new MetricNamesRep(), uid);
63 }
64 
66 {
67  for(unsigned i =0; i<mDisplayText.size(); ++i)
68  {
69  mDisplayText[i]->setRenderer(view->getRenderer());
70  }
71 }
72 
74 {
75  for(unsigned i =0; i<mDisplayText.size(); ++i)
76  {
77  mDisplayText[i]->setRenderer(NULL);
78  }
79 }
80 
81 void MetricNamesRep::setData(std::vector<DataPtr> data)
82 {
83  std::vector<DataMetricPtr> metrics = this->convertToMetrics(data);
84 
85  if (this->equal(metrics, mMetrics))
86  return;
87 
88  for (unsigned i=0; i<mMetrics.size(); ++i)
89  {
90  disconnect(mMetrics[i].get(), SIGNAL(transformChanged()), this, SLOT(setModified()));
91  disconnect(mMetrics[i].get(), SIGNAL(propertiesChanged()), this, SLOT(setModified()));
92  }
93 
94  mMetrics = metrics;
95 
96  for (unsigned i=0; i<mMetrics.size(); ++i)
97  {
98  connect(mMetrics[i].get(), SIGNAL(transformChanged()), this, SLOT(setModified()));
99  connect(mMetrics[i].get(), SIGNAL(propertiesChanged()), this, SLOT(setModified()));
100  }
101 
102  this->callSetColoredTextListSlot();
103  // Call again with a small delay, as the view might not be ready yet. I.e. the bounding box of the corner text is not properly initialized.
104  // Need the second call to avoid some assertion.
105  QTimer::singleShot(500, this, &MetricNamesRep::callSetColoredTextListSlot);
106 }
107 
108 void MetricNamesRep::callSetColoredTextListSlot()
109 {
110  this->setColoredTextList(this->getAllMetricTexts(), Eigen::Array2d(0.98, 0.98));
111 }
112 
113 std::vector<DataMetricPtr> MetricNamesRep::convertToMetrics(std::vector<DataPtr> data)
114 {
115  std::vector<DataMetricPtr> metrics;
116  for (unsigned i=0; i<data.size(); ++i)
117  {
118  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data[i]);
119  if (metric)
120  metrics.push_back(metric);
121  }
122  return metrics;
123 }
124 
125 bool MetricNamesRep::equal(std::vector<DataMetricPtr> a, std::vector<DataMetricPtr> b) const
126 {
127  if (a.size()!=b.size())
128  return false;
129  for (unsigned i=0; i<a.size(); ++i)
130  if (a[i] != b[i])
131  return false;
132  return true;
133 }
134 
136 {
137  std::vector<std::pair<QColor, QString> > text;
138  text = this->getAllMetricTexts();
139  CX_ASSERT(text.size()==mDisplayText.size());
140 
141  for (unsigned i=0; i<mDisplayText.size(); ++i)
142  {
143  mDisplayText[i]->updateText(text[i].second);
144  mDisplayText[i]->setColor(text[i].first);
145  }
146 
147 }
148 
149 void MetricNamesRep::setColoredTextList(std::vector<std::pair<QColor, QString> > text, Eigen::Array2d pos, vtkViewport *vp)
150 {
151  mDisplayText.clear();
152 
153  if (vp==0)
154  {
155  vp = this->getRenderer();
156  }
157 // if (vp==0)
158 // {
159 // return;
160 // }
161 
163  bb = this->findNormalizedBoundingBoxAroundText(text, pos, vp);
164  double meanHeight = bb.range()[1]/text.size();
165 
166  for (unsigned i=0; i<text.size(); ++i)
167  {
168  TextDisplayPtr rep;
169  rep.reset( new TextDisplay( text[i].second, text[i].first, mFontSize) );
170  rep->textProperty()->SetJustificationToLeft();
171  rep->getActor()->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();
172 
173  Vector3D currentPos = bb.bottomLeft() + (meanHeight*i)*Eigen::Vector3d::UnitY();
174  rep->setPosition(currentPos);
175  rep->setRenderer(this->getRenderer());
176 
177  mDisplayText.push_back(rep);
178  }
179 }
180 
181 DoubleBoundingBox3D MetricNamesRep::findNormalizedBoundingBoxAroundText(std::vector<std::pair<QColor, QString> > text, Eigen::Array2d pos, vtkViewport *vp)
182 {
183  QStringList fullText;
184  for (unsigned i=0; i<text.size(); ++i)
185  fullText << text[i].second;
186  TextDisplay test(fullText.join("\n"), QColor(Qt::red), mFontSize);
187  test.textProperty()->SetJustificationToLeft();
188  double width_p = test.getMapper()->GetWidth(vp);
189  double height_p = test.getMapper()->GetHeight(vp);
190  height_p *= 1.1; // increase spacing
191 
192  Eigen::Array2i size_vp(vp->GetSize());
193  Eigen::Array2d normsize_box(width_p/size_vp[0], height_p/size_vp[1]);
194 
195  // move box into viewport:
196  double border = 0.02;
197  DoubleBoundingBox3D bb_vp(border, 1.0-border, border, 1.0-border, 0, 0);
198  DoubleBoundingBox3D bb_box(pos[0], pos[0]+normsize_box[0], pos[1], pos[1]+normsize_box[1], 0, 0);
199  bb_box = this->moveBoxIntoAnother(bb_box, bb_vp);
200 
201  return bb_box;
202 }
203 
205 {
206  // move negative direction
207  for (unsigned i=0; i<2; ++i)
208  {
209  double shift = another[2*i+1] - box[2*i+1];
210  if (shift < 0)
211  {
212  box[2*i] += shift;
213  box[2*i+1] += shift;
214  }
215  }
216 
217  // move positive direction
218  for (unsigned i=0; i<3; ++i)
219  {
220  double shift = another[2*i] - box[2*i];
221  if (shift > 0)
222  {
223  box[2*i] -= shift;
224  box[2*i+1] -= shift;
225  }
226  }
227 
228  return box;
229 }
230 
232 {
233  mFontSize = size;
234 }
235 
236 QString MetricNamesRep::getText(DataMetricPtr metric, bool showLabel) const
237 {
238  QStringList text;
239  if (showLabel)
240  text << metric->getName();
241  if (metric->showValueInGraphics())
242  text << metric->getValueAsString();
243  return text.join(" = ");
244 }
245 
246 std::vector<std::pair<QColor, QString> > MetricNamesRep::getAllMetricTexts() const
247 {
248  std::vector<std::pair<QColor, QString> > retval;
249 
250  for (unsigned i = 0; i < mMetrics.size(); ++i)
251  {
252  DataMetricPtr metric = mMetrics[i];
253  QString line = metric->getName();
254 
255  if (!metric->showValueInGraphics())
256  continue;
257 
258  QString text = this->getText(metric, true);
259  retval.push_back(std::make_pair(metric->getColor(), text));
260  }
261  std::reverse(retval.begin(), retval.end());
262  return retval;
263 }
264 
265 
266 } // namespace cx
267 
vtkTextProperty * textProperty()
vtkRendererPtr getRenderer()
Definition: cxRepImpl.cpp:109
#define CX_ASSERT(statement)
Definition: cxLogger.h:137
boost::shared_ptr< DataMetric > DataMetricPtr
Definition: cxDataMetric.h:94
std::vector< DataMetricPtr > convertToMetrics(std::vector< DataPtr > data)
void setFontSize(int size)
must be set before setting data
Vector3D bottomLeft() const
static boost::shared_ptr< REP > wrap_new(REP *object, QString uid)
Definition: cxRepImpl.h:83
boost::shared_ptr< class View > ViewPtr
void setColoredTextList(std::vector< std::pair< QColor, QString > > text, Eigen::Array2d pos, vtkViewport *vp=0)
boost::shared_ptr< class MetricNamesRep > MetricNamesRepPtr
static MetricNamesRepPtr New(const QString &uid="")
void setData(std::vector< DataPtr > data)
virtual void addRepActorsToViewRenderer(ViewPtr view)
Helper for drawing text in 2D.
boost::shared_ptr< class TextDisplay > TextDisplayPtr
Default implementation of Rep.
Definition: cxRepImpl.h:63
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.
virtual void onModifiedStartRender()
DoubleBoundingBox3D moveBoxIntoAnother(DoubleBoundingBox3D box, DoubleBoundingBox3D another)
std::vector< std::pair< QColor, QString > > getAllMetricTexts() const
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
std::vector< TextDisplayPtr > mDisplayText
QString getText(DataMetricPtr metric, bool showLabel) const
virtual void removeRepActorsFromViewRenderer(ViewPtr view)
Base class for all Data Metrics.
Definition: cxDataMetric.h:64
bool equal(std::vector< DataMetricPtr > a, std::vector< DataMetricPtr > b) const
void setModified()
Definition: cxRepImpl.cpp:133
DoubleBoundingBox3D findNormalizedBoundingBoxAroundText(std::vector< std::pair< QColor, QString > > text, Eigen::Array2d pos, vtkViewport *vp)
std::vector< DataMetricPtr > mMetrics
Namespace for all CustusX production code.