Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxRegionOfInterestMetric.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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 
14 #include "cxBoundingBox3D.h"
15 #include "cxTypeConversions.h"
16 #include "cxPlaneMetric.h"
17 #include "cxPointMetric.h"
18 #include "cxXMLNodeWrapper.h"
19 #include "cxSpaceProvider.h"
20 #include "cxPatientModelService.h"
21 #include "cxSpaceListener.h"
22 #include "cxLogger.h"
23 
24 namespace cx
25 {
26 
28 {
29 
30 }
31 
33 {
34  DoubleBoundingBox3D bb = this->generateROIFromPointsAndMargin(this->transform(mPoints, qMd), mMargin);
35 
36  DoubleBoundingBox3D bb_max = this->generateROIFromPointsAndMargin(this->transform(mMaxBoundsPoints, qMd), mMargin);
37 
38  if (bb_max!=DoubleBoundingBox3D::zero())
39  bb = intersection(bb, bb_max);
40 
41  return bb;
42 }
43 
44 std::vector<Vector3D> RegionOfInterest::transform(const std::vector<Vector3D>& points, Transform3D M) const
45 {
46  std::vector<Vector3D> retval;
47  for (unsigned i=0; i<points.size(); ++i)
48  retval.push_back(M.coord(points[i]));
49  return retval;
50 }
51 
52 DoubleBoundingBox3D RegionOfInterest::generateROIFromPointsAndMargin(const std::vector<Vector3D>& points, double margin) const
53 {
54  if (points.empty())
56 
58  Vector3D vmargin(margin,margin, margin);
59  Vector3D bl = bb.bottomLeft() - vmargin;
60  Vector3D tr = bb.topRight() + vmargin;
61  bb = DoubleBoundingBox3D(bl, tr);
62 
63  return bb;
64 }
65 
66 //---------------------------------------------------------
67 //---------------------------------------------------------
68 //---------------------------------------------------------
69 
70 RegionOfInterestMetric::RegionOfInterestMetric(const QString& uid, const QString& name, PatientModelServicePtr dataManager, SpaceProviderPtr spaceProvider) :
71  DataMetric(uid, name, dataManager, spaceProvider)
72 {
73  mUseActiveTooltip = false;
74  mMargin = 20;
75 }
76 
78 {
79  return RegionOfInterestMetricPtr(new RegionOfInterestMetric(uid, name, dataManager, spaceProvider));
80 }
81 
83 {
84 }
85 
87 {
88  return this->boundingBox().center();
89 }
90 
92 {
93  return this->getROI().getBox() != DoubleBoundingBox3D::zero();
94 }
95 
96 void RegionOfInterestMetric::addXml(QDomNode& dataNode)
97 {
98  DataMetric::addXml(dataNode);
99 
100  XMLNodeAdder adder(dataNode);
101  for (unsigned i=0; i<mContainedData.size(); ++i)
102  adder.addTextToElement("content", mContainedData[i]);
103 
104  adder.addTextToElement("useActiveTooltip", QString::number(mUseActiveTooltip));
105  adder.addTextToElement("margin", QString::number(mMargin));
106  adder.addTextToElement("maxBoundsData", mMaxBoundsData);
107 }
108 
109 void RegionOfInterestMetric::parseXml(QDomNode& dataNode)
110 {
111  DataMetric::parseXml(dataNode);
112 
113  XMLNodeParser parser(dataNode);
114  mContainedData = parser.parseTextFromDuplicateElements("content");
115  mUseActiveTooltip = parser.parseTextFromElement("useActiveTooltip").toInt();
116  mMargin = parser.parseTextFromElement("margin").toDouble();
117  mMaxBoundsData = parser.parseTextFromElement("maxBoundsData");
118 
119  this->onContentChanged();
120 }
121 
123 {
124  return "bb";
125 }
126 
128 {
129  mContainedData = val;
130  this->onContentChanged();
131 }
132 
134 {
135  mUseActiveTooltip = val;
136 
137  this->onContentChanged();
138 }
139 
141 {
142  mMargin = val;
143  this->onContentChanged();
144 }
145 
147 {
148  mMaxBoundsData = val;
149  this->onContentChanged();
150 }
151 
152 void RegionOfInterestMetric::onContentChanged()
153 {
154  for (unsigned i=0; i<mListeners.size(); ++i)
155  {
156  disconnect(mListeners[i].get(), &SpaceListener::changed, this, &RegionOfInterestMetric::onContentTransformsChanged);
157  }
158  mListeners.clear();
159 
160  this->listenTo(CoordinateSystem(csTOOL_OFFSET, "active"));
161  for (unsigned i=0; i<mContainedData.size(); ++i)
162  {
163  this->listenTo(CoordinateSystem(csDATA, mContainedData[i]));
164  }
165  this->onContentTransformsChanged();
166 }
167 
168 void RegionOfInterestMetric::listenTo(CoordinateSystem space)
169 {
170  SpaceListenerPtr listener = mSpaceProvider->createListener();
171  listener->setSpace(space);
172  connect(listener.get(), &SpaceListener::changed, this, &RegionOfInterestMetric::onContentTransformsChanged);
173  mListeners.push_back(listener);
174 }
175 
176 void RegionOfInterestMetric::onContentTransformsChanged()
177 {
178  emit transformChanged();
179 }
180 
182 {
183  return this->getROI().getBox(this->get_rMd().inv());
184 }
185 
187 {
188  return "bb";
189 }
190 
191 template<class ITER>
193 {
194  for ( ; begin!=end; ++begin)
195  *begin = M.coord(*begin);
196 }
197 
199 {
200  RegionOfInterest retval;
201 
202  retval.mMargin = mMargin;
203 
204  if (mUseActiveTooltip)
205  {
206  retval.mPoints.push_back(this->getToolTip_r());
207  }
208 
209  std::map<QString, DataPtr> alldata = mDataManager->getDatas();
210  for (std::map<QString, DataPtr>::const_iterator i=alldata.begin(); i!=alldata.end(); ++i)
211  {
212  if (boost::dynamic_pointer_cast<RegionOfInterestMetric>(i->second))
213  continue;
214 
215  if (mContainedData.contains(i->first))
216  {
217  std::vector<Vector3D> c = i->second->getPointCloud();
218  transform_coord_range(c.begin(), c.end(), i->second->get_rMd());
219  std::copy(c.begin(), c.end(), back_inserter(retval.mPoints));
220  }
221 
222  if (mMaxBoundsData == i->first)
223  {
224  std::vector<Vector3D> c = i->second->getPointCloud();
225  transform_coord_range(c.begin(), c.end(), i->second->get_rMd());
226  retval.mMaxBoundsPoints = c;
227  }
228  }
229 
230  return retval;
231 }
232 
233 Vector3D RegionOfInterestMetric::getToolTip_r() const
234 {
235  Transform3D rMto = mSpaceProvider->get_toMfrom(CoordinateSystem(csTOOL_OFFSET, "active"),
237  Vector3D tp = rMto.coord(Vector3D(0, 0, 0));
238  return tp;
239 }
240 
241 }
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
Scalar * end()
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
Vector3D topRight() const
virtual QString getAsSingleLineString() const
void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
QStringList parseTextFromDuplicateElements(QString name)
Scalar * begin()
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Vector3D bottomLeft() const
virtual Vector3D getRefCoord() const
static CoordinateSystem reference()
DoubleBoundingBox3D getBox(Transform3D qMd=Transform3D::Identity())
virtual QString getValueAsString() const
csDATA
a datas space (d)
Definition: cxDefinitions.h:90
static DoubleBoundingBox3D fromCloud(std::vector< Vector3D > cloud)
virtual void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
void parseXml(QDomNode &dataNode)
Use a XML node to load data.
static DoubleBoundingBox3D zero()
static RegionOfInterestMetricPtr create(QString uid, QString name, PatientModelServicePtr dataManager, SpaceProviderPtr spaceProvider)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
QDomElement addTextToElement(QString name, QString text)
virtual DoubleBoundingBox3D boundingBox() const
Identification of a Coordinate system.
csTOOL_OFFSET
the tool space t with a virtual offset added along the z axis. (to)
Definition: cxDefinitions.h:90
boost::shared_ptr< class RegionOfInterestMetric > RegionOfInterestMetricPtr
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.
std::vector< Vector3D > mPoints
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
RegionOfInterest getROI() const
QString parseTextFromElement(QString name)
DoubleBoundingBox3D intersection(DoubleBoundingBox3D a, DoubleBoundingBox3D b)
boost::shared_ptr< class SpaceListener > SpaceListenerPtr
Base class for all Data Metrics.
Definition: cxDataMetric.h:43
void transform_coord_range(ITER begin, ITER end, Transform3D M)
std::vector< Vector3D > mMaxBoundsPoints
Namespace for all CustusX production code.