summaryrefslogtreecommitdiffstats
path: root/src/VolumeGeometry3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VolumeGeometry3D.cpp')
-rw-r--r--src/VolumeGeometry3D.cpp384
1 files changed, 384 insertions, 0 deletions
diff --git a/src/VolumeGeometry3D.cpp b/src/VolumeGeometry3D.cpp
new file mode 100644
index 0000000..86b8642
--- /dev/null
+++ b/src/VolumeGeometry3D.cpp
@@ -0,0 +1,384 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#include "astra/VolumeGeometry3D.h"
+
+#include <boost/lexical_cast.hpp>
+
+namespace astra
+{
+
+//----------------------------------------------------------------------------------------
+// Check all variable values
+bool CVolumeGeometry3D::_check()
+{
+ ASTRA_CONFIG_CHECK(m_iGridColCount > 0, "VolumeGeometry3D", "GridColCount must be strictly positive.");
+ ASTRA_CONFIG_CHECK(m_iGridRowCount > 0, "VolumeGeometry3D", "GridRowCount must be strictly positive.");
+ ASTRA_CONFIG_CHECK(m_iGridSliceCount > 0, "VolumeGeometry3D", "GridSliceCount must be strictly positive.");
+ ASTRA_CONFIG_CHECK(m_fWindowMinX < m_fWindowMaxX, "VolumeGeometry3D", "WindowMinX should be lower than WindowMaxX.");
+ ASTRA_CONFIG_CHECK(m_fWindowMinY < m_fWindowMaxY, "VolumeGeometry3D", "WindowMinY should be lower than WindowMaxY.");
+ ASTRA_CONFIG_CHECK(m_fWindowMinZ < m_fWindowMaxZ, "VolumeGeometry3D", "WindowMinZ should be lower than WindowMaxZ.");
+
+ ASTRA_CONFIG_CHECK(m_iGridTotCount == (m_iGridColCount * m_iGridRowCount * m_iGridSliceCount), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fWindowLengthX == (m_fWindowMaxX - m_fWindowMinX), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fWindowLengthY == (m_fWindowMaxY - m_fWindowMinY), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fWindowLengthZ == (m_fWindowMaxZ - m_fWindowMinZ), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fWindowArea == (m_fWindowLengthX * m_fWindowLengthY * m_fWindowLengthZ), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fPixelLengthX == (m_fWindowLengthX / (float32)m_iGridColCount), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fPixelLengthY == (m_fWindowLengthY / (float32)m_iGridRowCount), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fPixelLengthZ == (m_fWindowLengthZ / (float32)m_iGridSliceCount), "VolumeGeometry3D", "Internal configuration error.");
+
+ ASTRA_CONFIG_CHECK(m_fPixelArea == (m_fPixelLengthX * m_fPixelLengthY * m_fPixelLengthZ), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fDivPixelLengthX == (1.0f / m_fPixelLengthX), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fDivPixelLengthY == (1.0f / m_fPixelLengthY), "VolumeGeometry3D", "Internal configuration error.");
+ ASTRA_CONFIG_CHECK(m_fDivPixelLengthZ == (1.0f / m_fPixelLengthZ), "VolumeGeometry3D", "Internal configuration error.");
+
+ return true;
+}
+
+//----------------------------------------------------------------------------------------
+// Clear all member variables, setting all numeric variables to 0 and all pointers to NULL.
+void CVolumeGeometry3D::clear()
+{
+ m_iGridColCount = 0;
+ m_iGridRowCount = 0;
+ m_iGridSliceCount = 0;
+ m_iGridTotCount = 0;
+
+ m_fWindowLengthX = 0.0f;
+ m_fWindowLengthY = 0.0f;
+ m_fWindowLengthZ = 0.0f;
+ m_fWindowArea = 0.0f;
+
+ m_fPixelLengthX = 0.0f;
+ m_fPixelLengthY = 0.0f;
+ m_fPixelLengthZ = 0.0f;
+ m_fPixelArea = 0.0f;
+
+ m_fDivPixelLengthX = 0.0f;
+ m_fDivPixelLengthY = 0.0f;
+ m_fDivPixelLengthZ = 0.0f;
+
+ m_fWindowMinX = 0.0f;
+ m_fWindowMinY = 0.0f;
+ m_fWindowMinZ = 0.0f;
+ m_fWindowMaxX = 0.0f;
+ m_fWindowMaxY = 0.0f;
+ m_fWindowMaxZ = 0.0f;
+
+ m_bInitialized = false;
+}
+
+//----------------------------------------------------------------------------------------
+// Default constructor.
+CVolumeGeometry3D::CVolumeGeometry3D() : configCheckData(0)
+{
+ clear();
+ m_bInitialized = false;
+}
+
+//----------------------------------------------------------------------------------------
+// Default constructor
+CVolumeGeometry3D::CVolumeGeometry3D(int _iGridColCount, int _iGridRowCount, int _iGridSliceCount)
+ : configCheckData(0)
+{
+ clear();
+ initialize(_iGridColCount, _iGridRowCount, _iGridSliceCount);
+}
+
+//----------------------------------------------------------------------------------------
+// Constructor.
+CVolumeGeometry3D::CVolumeGeometry3D(int _iGridColCount,
+ int _iGridRowCount,
+ int _iGridSliceCount,
+ float32 _fWindowMinX,
+ float32 _fWindowMinY,
+ float32 _fWindowMinZ,
+ float32 _fWindowMaxX,
+ float32 _fWindowMaxY,
+ float32 _fWindowMaxZ)
+{
+ clear();
+ initialize(_iGridColCount,
+ _iGridRowCount,
+ _iGridSliceCount,
+ _fWindowMinX,
+ _fWindowMinY,
+ _fWindowMinZ,
+ _fWindowMaxX,
+ _fWindowMaxY,
+ _fWindowMaxZ);
+}
+
+CVolumeGeometry3D::CVolumeGeometry3D(const CVolumeGeometry3D& _other)
+{
+ *this = _other;
+}
+
+CVolumeGeometry3D& CVolumeGeometry3D::operator=(const CVolumeGeometry3D& _other)
+{
+ m_bInitialized = _other.m_bInitialized;
+ m_iGridColCount = _other.m_iGridColCount;
+ m_iGridRowCount = _other.m_iGridRowCount;
+ m_iGridSliceCount = _other.m_iGridSliceCount;
+ m_fWindowLengthX = _other.m_fWindowLengthX;
+ m_fWindowLengthY = _other.m_fWindowLengthY;
+ m_fWindowLengthZ = _other.m_fWindowLengthZ;
+ m_fWindowArea = _other.m_fWindowArea;
+ m_fPixelLengthX = _other.m_fPixelLengthX;
+ m_fPixelLengthY = _other.m_fPixelLengthY;
+ m_fPixelLengthZ = _other.m_fPixelLengthZ;
+ m_fDivPixelLengthX = _other.m_fDivPixelLengthX;
+ m_fDivPixelLengthY = _other.m_fDivPixelLengthY;
+ m_fDivPixelLengthZ = _other.m_fDivPixelLengthZ;
+ m_fWindowMinX = _other.m_fWindowMinX;
+ m_fWindowMinY = _other.m_fWindowMinY;
+ m_fWindowMinZ = _other.m_fWindowMinZ;
+ m_fWindowMaxX = _other.m_fWindowMaxX;
+ m_fWindowMaxY = _other.m_fWindowMaxY;
+ m_fWindowMaxZ = _other.m_fWindowMaxZ;
+
+ m_iGridTotCount = _other.m_iGridTotCount;
+ m_fPixelArea = _other.m_fPixelArea;
+
+ return *this;
+}
+
+//----------------------------------------------------------------------------------------
+// Destructor.
+CVolumeGeometry3D::~CVolumeGeometry3D()
+{
+ if (m_bInitialized) {
+ clear();
+ }
+}
+
+//----------------------------------------------------------------------------------------
+// Initialization with a Config object
+bool CVolumeGeometry3D::initialize(const Config& _cfg)
+{
+ ASTRA_ASSERT(_cfg.self);
+ ConfigStackCheck<CVolumeGeometry3D> CC("VolumeGeometry3D", this, _cfg);
+
+
+ // uninitialize if the object was initialized before
+ if (m_bInitialized) {
+ clear();
+ }
+
+ // Required: GridColCount
+ XMLNode* node = _cfg.self->getSingleNode("GridColCount");
+ ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified.");
+ m_iGridColCount = boost::lexical_cast<int>(node->getContent());
+ ASTRA_DELETE(node);
+ CC.markNodeParsed("GridColCount");
+
+ // Required: GridRowCount
+ node = _cfg.self->getSingleNode("GridRowCount");
+ ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified.");
+ m_iGridRowCount = boost::lexical_cast<int>(node->getContent());
+ ASTRA_DELETE(node);
+ CC.markNodeParsed("GridRowCount");
+
+ // Required: GridRowCount
+ node = _cfg.self->getSingleNode("GridSliceCount");
+ ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridSliceCount tag specified.");
+ m_iGridSliceCount = boost::lexical_cast<int>(node->getContent());
+ ASTRA_DELETE(node);
+ CC.markNodeParsed("GridSliceCount");
+
+ // Optional: Window minima and maxima
+ m_fWindowMinX = _cfg.self->getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f);
+ m_fWindowMaxX = _cfg.self->getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f);
+ m_fWindowMinY = _cfg.self->getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f);
+ m_fWindowMaxY = _cfg.self->getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f);
+ m_fWindowMinZ = _cfg.self->getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f);
+ m_fWindowMaxZ = _cfg.self->getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f);
+ CC.markOptionParsed("WindowMinX");
+ CC.markOptionParsed("WindowMaxX");
+ CC.markOptionParsed("WindowMinY");
+ CC.markOptionParsed("WindowMaxY");
+ CC.markOptionParsed("WindowMinZ");
+ CC.markOptionParsed("WindowMaxZ");
+
+ // calculate some other things
+ m_iGridTotCount = (m_iGridColCount * m_iGridRowCount * m_iGridSliceCount);
+ m_fWindowLengthX = (m_fWindowMaxX - m_fWindowMinX);
+ m_fWindowLengthY = (m_fWindowMaxY - m_fWindowMinY);
+ m_fWindowLengthZ = (m_fWindowMaxZ - m_fWindowMinZ);
+ m_fWindowArea = (m_fWindowLengthX * m_fWindowLengthY * m_fWindowLengthZ);
+ m_fPixelLengthX = (m_fWindowLengthX / (float32)m_iGridColCount);
+ m_fPixelLengthY = (m_fWindowLengthY / (float32)m_iGridRowCount);
+ m_fPixelLengthZ = (m_fWindowLengthZ / (float32)m_iGridSliceCount);
+
+ m_fPixelArea = (m_fPixelLengthX * m_fPixelLengthY * m_fPixelLengthZ);
+ m_fDivPixelLengthX = ((float32)m_iGridColCount / m_fWindowLengthX); // == (1.0f / m_fPixelLengthX);
+ m_fDivPixelLengthY = ((float32)m_iGridRowCount / m_fWindowLengthY); // == (1.0f / m_fPixelLengthY);
+ m_fDivPixelLengthZ = ((float32)m_iGridSliceCount / m_fWindowLengthZ); // == (1.0f / m_fPixelLengthZ);
+
+ // success
+ m_bInitialized = _check();
+ return m_bInitialized;
+}
+
+//----------------------------------------------------------------------------------------
+// Initialization.
+bool CVolumeGeometry3D::initialize(int _iGridColCount, int _iGridRowCount, int _iGridSliceCount)
+{
+ return initialize(_iGridColCount,
+ _iGridRowCount,
+ _iGridSliceCount,
+ -_iGridColCount/2.0f,
+ -_iGridRowCount/2.0f,
+ -_iGridSliceCount/2.0f,
+ _iGridColCount/2.0f,
+ _iGridRowCount/2.0f,
+ _iGridSliceCount/2.0f);
+}
+
+//----------------------------------------------------------------------------------------
+// Initialization.
+bool CVolumeGeometry3D::initialize(int _iGridColCount,
+ int _iGridRowCount,
+ int _iGridSliceCount,
+ float32 _fWindowMinX,
+ float32 _fWindowMinY,
+ float32 _fWindowMinZ,
+ float32 _fWindowMaxX,
+ float32 _fWindowMaxY,
+ float32 _fWindowMaxZ)
+{
+ if (m_bInitialized) {
+ clear();
+ }
+
+ m_iGridColCount = _iGridColCount;
+ m_iGridRowCount = _iGridRowCount;
+ m_iGridSliceCount = _iGridSliceCount;
+ m_iGridTotCount = (m_iGridColCount * m_iGridRowCount * m_iGridSliceCount);
+
+ m_fWindowMinX = _fWindowMinX;
+ m_fWindowMinY = _fWindowMinY;
+ m_fWindowMinZ = _fWindowMinZ;
+ m_fWindowMaxX = _fWindowMaxX;
+ m_fWindowMaxY = _fWindowMaxY;
+ m_fWindowMaxZ = _fWindowMaxZ;
+
+ m_fWindowLengthX = (m_fWindowMaxX - m_fWindowMinX);
+ m_fWindowLengthY = (m_fWindowMaxY - m_fWindowMinY);
+ m_fWindowLengthZ = (m_fWindowMaxZ - m_fWindowMinZ);
+ m_fWindowArea = (m_fWindowLengthX * m_fWindowLengthY * m_fWindowLengthZ);
+
+ m_fPixelLengthX = (m_fWindowLengthX / (float32)m_iGridColCount);
+ m_fPixelLengthY = (m_fWindowLengthY / (float32)m_iGridRowCount);
+ m_fPixelLengthZ = (m_fWindowLengthZ / (float32)m_iGridSliceCount);
+ m_fPixelArea = (m_fPixelLengthX * m_fPixelLengthY);
+
+ m_fDivPixelLengthX = ((float32)m_iGridColCount / m_fWindowLengthX); // == (1.0f / m_fPixelLengthX);
+ m_fDivPixelLengthY = ((float32)m_iGridRowCount / m_fWindowLengthY); // == (1.0f / m_fPixelLengthY);
+ m_fDivPixelLengthZ = ((float32)m_iGridSliceCount / m_fWindowLengthZ); // == (1.0f / m_fPixelLengthZ);
+
+ m_bInitialized = _check();
+ return m_bInitialized;
+}
+
+//----------------------------------------------------------------------------------------
+// Clone
+CVolumeGeometry3D* CVolumeGeometry3D::clone() const
+{
+ CVolumeGeometry3D* res = new CVolumeGeometry3D();
+ res->m_bInitialized = m_bInitialized;
+ res->m_iGridColCount = m_iGridColCount;
+ res->m_iGridRowCount = m_iGridRowCount;
+ res->m_iGridSliceCount = m_iGridSliceCount;
+ res->m_iGridTotCount = m_iGridTotCount;
+ res->m_fWindowLengthX = m_fWindowLengthX;
+ res->m_fWindowLengthY = m_fWindowLengthY;
+ res->m_fWindowLengthZ = m_fWindowLengthZ;
+ res->m_fWindowArea = m_fWindowArea;
+ res->m_fPixelLengthX = m_fPixelLengthX;
+ res->m_fPixelLengthY = m_fPixelLengthY;
+ res->m_fPixelLengthZ = m_fPixelLengthZ;
+ res->m_fPixelArea = m_fPixelArea;
+ res->m_fDivPixelLengthX = m_fDivPixelLengthX;
+ res->m_fDivPixelLengthY = m_fDivPixelLengthY;
+ res->m_fDivPixelLengthZ = m_fDivPixelLengthZ;
+ res->m_fWindowMinX = m_fWindowMinX;
+ res->m_fWindowMinY = m_fWindowMinY;
+ res->m_fWindowMinZ = m_fWindowMinZ;
+ res->m_fWindowMaxX = m_fWindowMaxX;
+ res->m_fWindowMaxY = m_fWindowMaxY;
+ res->m_fWindowMaxZ = m_fWindowMaxZ;
+ return res;
+}
+
+//----------------------------------------------------------------------------------------
+// is of type
+bool CVolumeGeometry3D::isEqual(const CVolumeGeometry3D* _pGeom2) const
+{
+ if (_pGeom2 == NULL) return false;
+
+ // both objects must be initialized
+ if (!m_bInitialized || !_pGeom2->m_bInitialized) return false;
+
+ // check all values
+ if (m_iGridColCount != _pGeom2->m_iGridColCount) return false;
+ if (m_iGridRowCount != _pGeom2->m_iGridRowCount) return false;
+ if (m_iGridSliceCount != _pGeom2->m_iGridSliceCount) return false;
+ if (m_iGridTotCount != _pGeom2->m_iGridTotCount) return false;
+ if (m_fWindowLengthX != _pGeom2->m_fWindowLengthX) return false;
+ if (m_fWindowLengthY != _pGeom2->m_fWindowLengthY) return false;
+ if (m_fWindowLengthZ != _pGeom2->m_fWindowLengthZ) return false;
+ if (m_fWindowArea != _pGeom2->m_fWindowArea) return false;
+ if (m_fPixelLengthX != _pGeom2->m_fPixelLengthX) return false;
+ if (m_fPixelLengthY != _pGeom2->m_fPixelLengthY) return false;
+ if (m_fPixelLengthZ != _pGeom2->m_fPixelLengthZ) return false;
+ if (m_fPixelArea != _pGeom2->m_fPixelArea) return false;
+ if (m_fDivPixelLengthX != _pGeom2->m_fDivPixelLengthX) return false;
+ if (m_fDivPixelLengthY != _pGeom2->m_fDivPixelLengthY) return false;
+ if (m_fDivPixelLengthZ != _pGeom2->m_fDivPixelLengthZ) return false;
+ if (m_fWindowMinX != _pGeom2->m_fWindowMinX) return false;
+ if (m_fWindowMinY != _pGeom2->m_fWindowMinY) return false;
+ if (m_fWindowMinZ != _pGeom2->m_fWindowMinZ) return false;
+ if (m_fWindowMaxX != _pGeom2->m_fWindowMaxX) return false;
+ if (m_fWindowMaxY != _pGeom2->m_fWindowMaxY) return false;
+ if (m_fWindowMaxZ != _pGeom2->m_fWindowMaxZ) return false;
+
+ return true;
+}
+
+CVolumeGeometry2D * CVolumeGeometry3D::createVolumeGeometry2D() const
+{
+ CVolumeGeometry2D * pOutput = new CVolumeGeometry2D();
+ pOutput->initialize(getGridColCount(), getGridRowCount());
+ return pOutput;
+}
+
+//----------------------------------------------------------------------------------------
+
+} // namespace astra