Fraxinus  16.5.0-fx-rc5
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
39 #include "cxView.h"
40 #include "cxVtkHelperClasses.h"
41 #include "cxTypeConversions.h"
42 #include "cxDataMetric.h"
43 #include "cxLogger.h"
44 
45 
46 namespace cx
47 {
48 
50  RepImpl()
51 {
52  mFontSize = 20;
53 }
54 
56 {
57 }
58 
60 {
61  return wrap_new(new MetricNamesRep(), uid);
62 }
63 
65 {
66  for(unsigned i =0; i<mDisplayText.size(); ++i)
67  {
68  mDisplayText[i]->setRenderer(view->getRenderer());
69  }
70 }
71 
73 {
74  for(unsigned i =0; i<mDisplayText.size(); ++i)
75  {
76  mDisplayText[i]->setRenderer(NULL);
77  }
78 }
79 
80 void MetricNamesRep::setData(std::vector<DataPtr> data)
81 {
82  std::vector<DataMetricPtr> metrics = this->convertToMetrics(data);
83 
84  if (this->equal(metrics, mMetrics))
85  return;
86 
87  for (unsigned i=0; i<mMetrics.size(); ++i)
88  {
89  disconnect(mMetrics[i].get(), SIGNAL(transformChanged()), this, SLOT(setModified()));
90  disconnect(mMetrics[i].get(), SIGNAL(propertiesChanged()), this, SLOT(setModified()));
91  }
92 
93  mMetrics = metrics;
94 
95  for (unsigned i=0; i<mMetrics.size(); ++i)
96  {
97  connect(mMetrics[i].get(), SIGNAL(transformChanged()), this, SLOT(setModified()));
98  connect(mMetrics[i].get(), SIGNAL(propertiesChanged()), this, SLOT(setModified()));
99  }
100 
101  this->setColoredTextList(this->getAllMetricTexts(), Eigen::Array2d(0.98, 0.98));
102 }
103 
104 std::vector<DataMetricPtr> MetricNamesRep::convertToMetrics(std::vector<DataPtr> data)
105 {
106  std::vector<DataMetricPtr> metrics;
107  for (unsigned i=0; i<data.size(); ++i)
108  {
109  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data[i]);
110  if (metric)
111  metrics.push_back(metric);
112  }
113  return metrics;
114 }
115 
116 bool MetricNamesRep::equal(std::vector<DataMetricPtr> a, std::vector<DataMetricPtr> b) const
117 {
118  if (a.size()!=b.size())
119  return false;
120  for (unsigned i=0; i<a.size(); ++i)
121  if (a[i] != b[i])
122  return false;
123  return true;
124 }
125 
127 {
128  std::vector<std::pair<QColor, QString> > text;
129  text = this->getAllMetricTexts();
130  CX_ASSERT(text.size()==mDisplayText.size());
131 
132  for (unsigned i=0; i<mDisplayText.size(); ++i)
133  {
134  mDisplayText[i]->updateText(text[i].second);
135  mDisplayText[i]->setColor(text[i].first);
136  }
137 
138 }
139 
140 void MetricNamesRep::setColoredTextList(std::vector<std::pair<QColor, QString> > text, Eigen::Array2d pos, vtkViewport *vp)
141 {
142  mDisplayText.clear();
143 
144  if (vp==0)
145  {
146  vp = this->getRenderer();
147  }
148 // if (vp==0)
149 // {
150 // return;
151 // }
152 
154  bb = this->findNormalizedBoundingBoxAroundText(text, pos, vp);
155  double meanHeight = bb.range()[1]/text.size();
156 
157  for (unsigned i=0; i<text.size(); ++i)
158  {
159  TextDisplayPtr rep;
160  rep.reset( new TextDisplay( text[i].second, text[i].first, mFontSize) );
161  rep->textProperty()->SetJustificationToLeft();
162  rep->getActor()->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();
163 
164  Vector3D currentPos = bb.bottomLeft() + (meanHeight*i)*Eigen::Vector3d::UnitY();
165  rep->setPosition(currentPos);
166  rep->setRenderer(this->getRenderer());
167 
168  mDisplayText.push_back(rep);
169  }
170 }
171 
172 DoubleBoundingBox3D MetricNamesRep::findNormalizedBoundingBoxAroundText(std::vector<std::pair<QColor, QString> > text, Eigen::Array2d pos, vtkViewport *vp)
173 {
174  QStringList fullText;
175  for (unsigned i=0; i<text.size(); ++i)
176  fullText << text[i].second;
177  TextDisplay test(fullText.join("\n"), QColor(Qt::red), mFontSize);
178  test.textProperty()->SetJustificationToLeft();
179  double width_p = test.getMapper()->GetWidth(vp);
180  double height_p = test.getMapper()->GetHeight(vp);
181  height_p *= 1.1; // increase spacing
182 
183  Eigen::Array2i size_vp(vp->GetSize());
184  Eigen::Array2d normsize_box(width_p/size_vp[0], height_p/size_vp[1]);
185 
186  // move box into viewport:
187  double border = 0.02;
188  DoubleBoundingBox3D bb_vp(border, 1.0-border, border, 1.0-border, 0, 0);
189  DoubleBoundingBox3D bb_box(pos[0], pos[0]+normsize_box[0], pos[1], pos[1]+normsize_box[1], 0, 0);
190  bb_box = this->moveBoxIntoAnother(bb_box, bb_vp);
191 
192  return bb_box;
193 }
194 
196 {
197  // move negative direction
198  for (unsigned i=0; i<2; ++i)
199  {
200  double shift = another[2*i+1] - box[2*i+1];
201  if (shift < 0)
202  {
203  box[2*i] += shift;
204  box[2*i+1] += shift;
205  }
206  }
207 
208  // move positive direction
209  for (unsigned i=0; i<3; ++i)
210  {
211  double shift = another[2*i] - box[2*i];
212  if (shift > 0)
213  {
214  box[2*i] -= shift;
215  box[2*i+1] -= shift;
216  }
217  }
218 
219  return box;
220 }
221 
223 {
224  mFontSize = size;
225 }
226 
227 QString MetricNamesRep::getText(DataMetricPtr metric, bool showLabel) const
228 {
229  QStringList text;
230  if (showLabel)
231  text << metric->getName();
232  if (metric->showValueInGraphics())
233  text << metric->getValueAsString();
234  return text.join(" = ");
235 }
236 
237 std::vector<std::pair<QColor, QString> > MetricNamesRep::getAllMetricTexts() const
238 {
239  std::vector<std::pair<QColor, QString> > retval;
240 
241  for (unsigned i = 0; i < mMetrics.size(); ++i)
242  {
243  DataMetricPtr metric = mMetrics[i];
244  QString line = metric->getName();
245 
246  if (!metric->showValueInGraphics())
247  continue;
248 
249  QString text = this->getText(metric, true);
250  retval.push_back(std::make_pair(metric->getColor(), text));
251  }
252  std::reverse(retval.begin(), retval.end());
253  return retval;
254 }
255 
256 
257 } // namespace cx
258 
vtkTextProperty * textProperty()
vtkRendererPtr getRenderer()
Definition: cxRepImpl.cpp:109
#define CX_ASSERT(statement)
Definition: cxLogger.h:131
boost::shared_ptr< DataMetric > DataMetricPtr
Definition: cxDataMetric.h:95
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:132
DoubleBoundingBox3D findNormalizedBoundingBoxAroundText(std::vector< std::pair< QColor, QString > > text, Eigen::Array2d pos, vtkViewport *vp)
std::vector< DataMetricPtr > mMetrics