CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxDistanceMetric.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 
12 
13 #include "cxDistanceMetric.h"
14 #include "cxBoundingBox3D.h"
15 #include "cxTypeConversions.h"
16 #include "cxPlaneMetric.h"
17 #include "cxPointMetric.h"
18 
19 #include "cxPatientModelService.h"
20 
21 namespace cx
22 {
23 
24 DistanceMetric::DistanceMetric(const QString& uid, const QString& name, PatientModelServicePtr dataManager, SpaceProviderPtr spaceProvider) :
25  DataMetric(uid, name, dataManager, spaceProvider)
26 {
27  mArguments.reset(new MetricReferenceArgumentList(QStringList() << "line endpoint 0" << "line endpoint 1"));
28  mArguments->setValidArgumentTypes(QStringList() << PointMetric::getTypeName() << PlaneMetric::getTypeName());
29 
30  connect(mArguments.get(), SIGNAL(argumentsChanged()), this, SLOT(resetCachedValues()));
31  connect(mArguments.get(), SIGNAL(argumentsChanged()), this, SIGNAL(transformChanged()));
32 }
33 
34 DistanceMetricPtr DistanceMetric::create(QString uid, QString name, PatientModelServicePtr dataManager, SpaceProviderPtr spaceProvider)
35 {
36  return DistanceMetricPtr(new DistanceMetric(uid, name, dataManager, spaceProvider));
37 }
38 
40 {
41 }
42 
44 {
45  return this->boundingBox().center();
46 }
47 
49 {
50  return this->getEndpoints().size()==2;
51 }
52 
53 void DistanceMetric::addXml(QDomNode& dataNode)
54 {
55  DataMetric::addXml(dataNode);
56  mArguments->addXml(dataNode);
57 }
58 
59 void DistanceMetric::parseXml(QDomNode& dataNode)
60 {
61  DataMetric::parseXml(dataNode);
62 
63  mArguments->parseXml(dataNode, mDataManager->getDatas());
64  this->resetCachedValues();
65 }
66 
67 void DistanceMetric::resetCachedValues()
68 {
69  mCachedEndPoints.reset();
70 }
71 
72 std::vector<Vector3D> DistanceMetric::getEndpoints() const
73 {
74  this->updateCache();
75  return mCachedEndPoints.get();
76 }
77 
78 void DistanceMetric::updateCache() const
79 {
80  if (!mCachedEndPoints.isValid())
81  {
82  std::vector<Vector3D> endpoints;
83  Vector3D direction;
84  this->getEndpointsUncached(&endpoints, &direction);
85  mCachedEndPoints.set(endpoints);
86  mCachedDirection.set(direction);
87  }
88 }
89 
90 void DistanceMetric::getEndpointsUncached(std::vector<Vector3D> *endpoints, Vector3D* direction) const
91 {
92  DataPtr a0 = mArguments->get(0);
93  DataPtr a1 = mArguments->get(1);
94 
95  if (!a0 || !a1)
96  {
97  endpoints->clear();
98  return;
99  }
100  std::vector<Vector3D> retval(2);
101  Vector3D dir;
102 
103  // case I: point-point
104  // case II: point-plane
105  // case III: plane-plane (not implemented)
106 
107  if ((a0->getType() == PointMetric::getTypeName()) && (a1->getType() == PointMetric::getTypeName()))
108  {
109  retval[0] = boost::dynamic_pointer_cast<PointMetric>(a0)->getRefCoord();
110  retval[1] = boost::dynamic_pointer_cast<PointMetric>(a1)->getRefCoord();
111  dir = (retval[1] - retval[0]).normal();
112  }
113  else if ((a0->getType() == PlaneMetric::getTypeName()) && (a1->getType() == PointMetric::getTypeName()))
114  {
115  Plane3D plane = boost::dynamic_pointer_cast<PlaneMetric>(a0)->getRefPlane();
116  Vector3D p = boost::dynamic_pointer_cast<PointMetric>(a1)->getRefCoord();
117 
118  retval[0] = plane.projection(p);
119  retval[1] = p;
120  dir = plane.normal();
121  }
122  else if ((a0->getType() == PointMetric::getTypeName()) && (a1->getType() == PlaneMetric::getTypeName()))
123  {
124  Plane3D plane = boost::dynamic_pointer_cast<PlaneMetric>(a1)->getRefPlane();
125  Vector3D p = boost::dynamic_pointer_cast<PointMetric>(a0)->getRefCoord();
126 
127  retval[1] = plane.projection(p);
128  retval[0] = p;
129  dir = plane.normal();
130  }
131  else
132  {
133  endpoints->clear();
134  }
135 
136  *endpoints = retval;
137  *direction = dir;
138 }
139 
141 {
142  std::vector<Vector3D> endpoints = this->getEndpoints();
143  if (endpoints.size() != 2)
144  return -1;
145 
146  Vector3D dir = this->getDirection();
147 
148  return dot(endpoints[1] - endpoints[0], dir);
149 }
150 
152 {
153  this->updateCache();
154  return mCachedDirection.get();
155 }
156 
158 {
159  return QString("%1 mm").arg(this->getDistance(), 0, 'f', 1);
160 }
161 
163 {
165 }
166 
167 
168 }
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
static QString getTypeName()
Definition: cxPlaneMetric.h:62
Vector3D getDirection() const
bool isValid() const
boost::shared_ptr< class DistanceMetric > DistanceMetricPtr
static DistanceMetricPtr create(QString uid, QString name, PatientModelServicePtr dataManager, SpaceProviderPtr spaceProvider)
void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
PlainObject normal() const
virtual DoubleBoundingBox3D boundingBox() const
Data class representing a plane.
Definition: cxPlaneMetric.h:48
PatientModelServicePtr mDataManager
Definition: cxDataMetric.h:67
virtual QString getValueAsString() const
static DoubleBoundingBox3D fromCloud(std::vector< Vector3D > cloud)
boost::shared_ptr< class Data > DataPtr
void parseXml(QDomNode &dataNode)
Use a XML node to load data.
void set(const T &val)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
virtual Vector3D getRefCoord() const
double dot(const Vector3D &a, const Vector3D &b)
compute inner product (or dot product) of a and b.
Definition: cxVector3D.cpp:46
Data class that represents a distance between two points, or a point and a plane. ...
double getDistance() const
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::Hyperplane< double, 3 > Plane3D
Definition: cxPlaneMetric.h:26
std::vector< Vector3D > getEndpoints() const
return the two endpoints in reference space. None if invalid.
Data class that represents a single point.
Definition: cxPointMetric.h:42
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
Vector3D center() const
static QString getTypeName()
Definition: cxPointMetric.h:58
virtual void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
const T & get() const
virtual bool isValid() const
Namespace for all CustusX production code.