CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxMesh.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 
34 #include "cxMesh.h"
35 
36 #include <vtkCellArray.h>
37 #include <vtkPolyData.h>
38 #include <vtkPolyDataWriter.h>
39 #include <QDomDocument>
40 #include <QColor>
41 #include <QDir>
42 #include "cxTypeConversions.h"
44 #include "cxBoundingBox3D.h"
45 #include "cxDataReaderWriter.h"
46 
47 namespace cx
48 {
49 
50 MeshPtr Mesh::create(const QString& uid, const QString& name)
51 {
52  return MeshPtr(new Mesh(uid, name));
53 }
54 
55 Mesh::Mesh(const QString& uid, const QString& name) :
56  Data(uid, name), mVtkPolyData(vtkPolyDataPtr::New()), mWireframe(false), mBackfaceCulling(false), mFrontfaceCulling(false)
57 {
58  mColor = QColor(255, 0, 0, 255);
59  this->setAcquisitionTime(QDateTime::currentDateTime());
60 }
61 Mesh::Mesh(const QString& uid, const QString& name, const vtkPolyDataPtr& polyData) :
62  Data(uid, name), mVtkPolyData(polyData), mWireframe(false), mBackfaceCulling(false), mFrontfaceCulling(false)
63 {
64  mColor = QColor(255, 0, 0, 255);
65  this->setAcquisitionTime(QDateTime::currentDateTime());
66 }
68 {
69 }
70 
71 void Mesh::setIsWireframe(bool on)
72 {
73  mWireframe = on;
74  emit meshChanged();
75 }
77 {
78  return mWireframe;
79 }
80 
81 bool Mesh::load(QString path)
82 {
83  vtkPolyDataPtr raw;
84  raw = DataReaderWriter().loadVtkPolyData(path);
85  this->setVtkPolyData(raw);
86  if(raw)
87  {
88  this->setName(QFileInfo(path).baseName());
89  this->setFilename(path); // need path even when not set explicitly: nice for testing
90  }
91  return raw!=0;
92 }
93 
94 void Mesh::setVtkPolyData(const vtkPolyDataPtr& polyData)
95 {
96  mVtkPolyData = polyData;
97  emit meshChanged();
98 }
100 {
101  return mVtkPolyData;
102 }
103 void Mesh::addXml(QDomNode& dataNode)
104 {
105  Data::addXml(dataNode);
106  QDomDocument doc = dataNode.ownerDocument();
107 
108  QDomNode meshNode = dataNode;
109 
110  QDomElement colorNode = doc.createElement("color");
111  QDomElement subNode = doc.createElement("red");
112  subNode.appendChild(doc.createTextNode(string_cast(mColor.red()).c_str()));
113  colorNode.appendChild(subNode);
114  subNode = doc.createElement("green");
115  subNode.appendChild(doc.createTextNode(string_cast(mColor.green()).c_str()));
116  colorNode.appendChild(subNode);
117  subNode = doc.createElement("blue");
118  subNode.appendChild(doc.createTextNode(string_cast(mColor.blue()).c_str()));
119  colorNode.appendChild(subNode);
120  subNode = doc.createElement("alpha");
121  subNode.appendChild(doc.createTextNode(string_cast(mColor.alpha()).c_str()));
122  colorNode.appendChild(subNode);
123  meshNode.appendChild(colorNode);
124 
125  QDomElement cullingNode = doc.createElement("culling");
126  QDomElement elem = cullingNode.toElement();
127  elem.setAttribute("backfaceCulling", mBackfaceCulling);
128  elem.setAttribute("frontfaceCulling", mFrontfaceCulling);
129  meshNode.appendChild(cullingNode);
130 }
131 
132 void Mesh::parseXml(QDomNode& dataNode)
133 {
134  Data::parseXml(dataNode);
135 
136  // image node must be parsed in the data manager to create this Image object
137  // Only subnodes are parsed here
138 
139  if (dataNode.isNull())
140  return;
141 
142  // QDomNode registrationHistory = dataNode.namedItem("registrationHistory");
143  // m_rMd_History->parseXml(registrationHistory);
144 
145  QDomNode colorNode = dataNode.namedItem("color");
146  if (!colorNode.isNull())
147  {
148  int red = 255;
149  int green = 255;
150  int blue = 255;
151  int alpha = 255;
152 
153  QDomNode node = colorNode.namedItem("red");
154  if (!node.isNull())
155  red = node.toElement().text().toInt();
156 
157  node = colorNode.namedItem("green");
158  if (!node.isNull())
159  green = node.toElement().text().toInt();
160 
161  node = colorNode.namedItem("blue");
162  if (!node.isNull())
163  blue = node.toElement().text().toInt();
164 
165  node = colorNode.namedItem("alpha");
166  if (!node.isNull())
167  alpha = node.toElement().text().toInt();
168 
169  mColor = QColor(red, green, blue, alpha);
170  }
171 
172  QDomNode cullingNode = dataNode.namedItem("culling");
173  if (!cullingNode.isNull())
174  {
175  mBackfaceCulling = cullingNode.toElement().attribute("backfaceCulling").toInt();
176  mFrontfaceCulling = cullingNode.toElement().attribute("frontfaceCulling").toInt();
177  }
178  emit meshChanged();
179 }
180 
181 void Mesh::setColor(const QColor& color)
182 {
183  mColor = color;
184  emit meshChanged();
185 }
186 
188 {
189  return mColor;
190 }
191 
192 void Mesh::setBackfaceCullingSlot(bool backfaceCulling)
193 {
194  mBackfaceCulling = backfaceCulling;
195  emit meshChanged();
196 }
197 
199 {
200  return mBackfaceCulling;
201 }
202 
203 void Mesh::setFrontfaceCullingSlot(bool frontfaceCulling)
204 {
205  mFrontfaceCulling = frontfaceCulling;
206  emit meshChanged();
207 }
208 
210 {
211  return mFrontfaceCulling;
212 }
213 
215 {
216 // getVtkPolyData()->Update();
217  DoubleBoundingBox3D bounds(getVtkPolyData()->GetBounds());
218  return bounds;
219 }
220 
222 {
223  // if transform elements exists, create a copy with entire position inside the polydata:
224  if (similar(transform, Transform3D::Identity()))
225  return getVtkPolyData();
226 
227 // getVtkPolyData()->Update();
228  vtkPolyDataPtr poly = vtkPolyDataPtr::New();
229  poly->DeepCopy(getVtkPolyData());
230  vtkPointsPtr points = poly->GetPoints();
231 
232  vtkPointsPtr floatPoints = vtkPointsPtr::New();
233  floatPoints->DeepCopy(points);
234  floatPoints->SetDataTypeToFloat();
235  for (int i = 0; i < poly->GetNumberOfPoints(); ++i)
236  {
237  Vector3D p(points->GetPoint(i));
238  p = transform.coord(p);
239  floatPoints->SetPoint(i, p.begin());
240  }
241  poly->SetPoints(floatPoints.GetPointer());
242  poly->Modified();
243 // poly->Update();
244 
245  return poly;
246 }
247 
249 {
251  return poly->GetLines()->GetNumberOfCells() > 0 && poly->GetPolys()->GetNumberOfCells() == 0 && poly->GetStrips()->GetNumberOfCells() == 0;
252 }
253 
254 void Mesh::save(const QString& basePath)
255 {
256  vtkPolyDataWriterPtr writer = vtkPolyDataWriterPtr::New();
257  writer->SetInputData(this->getVtkPolyData());
258  QString filename = basePath + "/Images/" + this->getUid() + ".vtk";
259  this->setFilename(QDir(basePath).relativeFilePath(filename));
260  writer->SetFileName(cstring_cast(filename));
261 
262  writer->Update();
263  writer->Write();
264 }
265 
266 } // namespace cx
virtual DoubleBoundingBox3D boundingBox() const
Definition: cxMesh.cpp:214
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
vtkPolyDataPtr getTransformedPolyData(Transform3D tranform)
Create a new transformed polydata.
Definition: cxMesh.cpp:221
bool isFiberBundle() const
Definition: cxMesh.cpp:248
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
void setName(const QString &name)
Definition: cxData.cpp:72
virtual vtkPolyDataPtr getVtkPolyData() const
Definition: cxMesh.cpp:99
virtual bool load(QString path)
Definition: cxMesh.cpp:81
cstring_cast_Placeholder cstring_cast(const T &val)
static MeshPtr create(const QString &uid, const QString &name="")
Definition: cxMesh.cpp:50
void setFrontfaceCullingSlot(bool backfaceCulling)
Set frontface culling on/off in mesh visualization.
Definition: cxMesh.cpp:203
virtual void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
Definition: cxData.cpp:120
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
Definition: cxProbeSector.h:47
std::string string_cast(const T &val)
virtual QString getUid() const
Definition: cxData.cpp:78
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
vtkPolyDataPtr loadVtkPolyData(QString filename)
bool getIsWireframe() const
true=wireframe, false=surface
Definition: cxMesh.cpp:76
void setBackfaceCullingSlot(bool backfaceCulling)
Set backface culling on/off in mesh visualization.
Definition: cxMesh.cpp:192
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:94
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
Definition: cxData.cpp:146
bool getBackfaceCulling()
Get backface culling.
Definition: cxMesh.cpp:198
void setAcquisitionTime(QDateTime time)
Definition: cxData.cpp:181
void meshChanged()
vtkSmartPointer< class vtkPolyDataWriter > vtkPolyDataWriterPtr
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.
void setIsWireframe(bool on)
Set rep to wireframe, false means surface.
Definition: cxMesh.cpp:71
virtual void save(const QString &basePath)
Definition: cxMesh.cpp:254
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
Definition: cxMesh.cpp:132
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Superclass for all data objects.
Definition: cxData.h:69
void addXml(QDomNode &dataNode)
adds xml information about the image and its variabels
Definition: cxMesh.cpp:103
virtual ~Mesh()
Definition: cxMesh.cpp:67
Mesh(const QString &uid, const QString &name="")
Definition: cxMesh.cpp:55
bool getFrontfaceCulling()
Get frontface culling.
Definition: cxMesh.cpp:209
boost::shared_ptr< class Mesh > MeshPtr
virtual void setFilename(QString val)
Definition: cxData.cpp:92
vtkSmartPointer< class vtkPoints > vtkPointsPtr
void setColor(const QColor &color)
Set the color of the mesh.
Definition: cxMesh.cpp:181
QColor getColor()
Get the color of the mesh (Values are range 0 - 255)
Definition: cxMesh.cpp:187