VolumeSpace.h
#ifndef __VOLUME_SPACE_H__
#define __VOLUME_SPACE_H__
/*LICENSE_START*/
/*
* Copyright (c) 2014, Washington University School of Medicine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Common/Vector3D.h"
#include "Common/XmlAdapter.h"
#include "stdint.h"
#include <vector>
namespace cifti
{
class VolumeSpace
{
int64_t m_dims[3];
std::vector<std::vector<float> > m_sform, m_inverse;
void computeInverse();
public:
enum OrientTypes
{
LEFT_TO_RIGHT = 0,
RIGHT_TO_LEFT = 4,
POSTERIOR_TO_ANTERIOR = 1,
ANTERIOR_TO_POSTERIOR = 5,
INFERIOR_TO_SUPERIOR = 2,
SUPERIOR_TO_INFERIOR = 6
};
VolumeSpace();
VolumeSpace(const int64_t dims[3], const std::vector<std::vector<float> >& sform);
VolumeSpace(const int64_t dims[3], const float sform[12]);
void setSpace(const int64_t dims[3], const std::vector<std::vector<float> >& sform);
void setSpace(const int64_t dims[3], const float sform[12]);
const int64_t* getDims() const { return m_dims; }
const std::vector<std::vector<float> >& getSform() const { return m_sform; }
void getSpacingVectors(Vector3D& iStep, Vector3D& jStep, Vector3D& kStep, Vector3D& origin) const;
bool matchesVolumeSpace(const VolumeSpace& right) const;//allows slight mismatches
bool operator==(const VolumeSpace& right) const;//requires that it be exact
bool operator!=(const VolumeSpace& right) const { return !(*this == right); }
bool isPlumb() const;
void getOrientAndSpacingForPlumb(OrientTypes* orientOut, float* spacingOut, float* originOut) const;
void getOrientation(OrientTypes orientOut[3]) const;
template <typename T>
inline void indexToSpace(const T* indexIn, float* coordOut) const
{ indexToSpace<T>(indexIn[0], indexIn[1], indexIn[2], coordOut[0], coordOut[1], coordOut[2]); }
template <typename T>
inline void indexToSpace(const T& indexIn1, const T& indexIn2, const T& indexIn3, float* coordOut) const
{ indexToSpace<T>(indexIn1, indexIn2, indexIn3, coordOut[0], coordOut[1], coordOut[2]); }
template <typename T>
inline void indexToSpace(const T* indexIn, float& coordOut1, float& coordOut2, float& coordOut3) const
{ indexToSpace<T>(indexIn[0], indexIn[1], indexIn[2], coordOut1, coordOut2, coordOut3); }
template <typename T>
void indexToSpace(const T& indexIn1, const T& indexIn2, const T& indexIn3, float& coordOut1, float& coordOut2, float& coordOut3) const;
inline void spaceToIndex(const float* coordIn, float* indexOut) const { spaceToIndex(coordIn[0], coordIn[1], coordIn[2], indexOut[0], indexOut[1], indexOut[2]); }
inline void spaceToIndex(const float& coordIn1, const float& coordIn2, const float& coordIn3, float* indexOut) const { spaceToIndex(coordIn1, coordIn2, coordIn3, indexOut[0], indexOut[1], indexOut[2]); }
inline void spaceToIndex(const float* coordIn, float& indexOut1, float& indexOut2, float& indexOut3) const { spaceToIndex(coordIn[0], coordIn[1], coordIn[2], indexOut1, indexOut2, indexOut3); }
void spaceToIndex(const float& coordIn1, const float& coordIn2, const float& coordIn3, float& indexOut1, float& indexOut2, float& indexOut3) const;
inline void enclosingVoxel(const float* coordIn, int64_t* indexOut) const { enclosingVoxel(coordIn[0], coordIn[1], coordIn[2], indexOut[0], indexOut[1], indexOut[2]); }
inline void enclosingVoxel(const float& coordIn1, const float& coordIn2, const float& coordIn3, int64_t* indexOut) const { enclosingVoxel(coordIn1, coordIn2, coordIn3, indexOut[0], indexOut[1], indexOut[2]); }
inline void enclosingVoxel(const float* coordIn, int64_t& indexOut1, int64_t& indexOut2, int64_t& indexOut3) const { enclosingVoxel(coordIn[0], coordIn[1], coordIn[2], indexOut1, indexOut2, indexOut3); }
void enclosingVoxel(const float& coordIn1, const float& coordIn2, const float& coordIn3, int64_t& indexOut1, int64_t& indexOut2, int64_t& indexOut3) const;
template <typename T>
inline bool indexValid(const T* indexIn) const
{
return indexValid(indexIn[0], indexIn[1], indexIn[2]);//implicit cast to int64_t
}
inline bool indexValid(const int64_t& indexIn1, const int64_t& indexIn2, const int64_t& indexIn3) const
{
if (indexIn1 < 0 || indexIn1 >= m_dims[0]) return false;
if (indexIn2 < 0 || indexIn2 >= m_dims[1]) return false;
if (indexIn3 < 0 || indexIn3 >= m_dims[2]) return false;
return true;
}
inline int64_t getIndex(const int64_t& indexIn1, const int64_t& indexIn2, const int64_t& indexIn3) const
{
return indexIn1 + m_dims[0] * (indexIn2 + m_dims[1] * indexIn3);
}
template <typename T>
inline int64_t getIndex(const T* indexIn) const
{
return getIndex(indexIn[0], indexIn[1], indexIn[2]);//implicit cast to int64_t
}
void readCiftiXML1(XmlReader& xml);//xml functions
void readCiftiXML2(XmlReader& xml);
void writeCiftiXML1(XmlWriter& xml) const;
void writeCiftiXML2(XmlWriter& xml) const;
};
template <typename T>
void VolumeSpace::indexToSpace(const T& indexIn1, const T& indexIn2, const T& indexIn3, float& coordOut1, float& coordOut2, float& coordOut3) const
{
coordOut1 = indexIn1 * m_sform[0][0] + indexIn2 * m_sform[0][1] + indexIn3 * m_sform[0][2] + m_sform[0][3];
coordOut2 = indexIn1 * m_sform[1][0] + indexIn2 * m_sform[1][1] + indexIn3 * m_sform[1][2] + m_sform[1][3];
coordOut3 = indexIn1 * m_sform[2][0] + indexIn2 * m_sform[2][1] + indexIn3 * m_sform[2][2] + m_sform[2][3];
}
}
#endif //__VOLUME_SPACE_H__
cifti::Vector3D
Definition Vector3D.h:37
cifti::VolumeSpace::isPlumb
bool isPlumb() const
returns true if volume space is not skew, and each axis and index is separate
Definition VolumeSpace.cxx:291
cifti::VolumeSpace::indexToSpace
void indexToSpace(const T *indexIn, float &coordOut1, float &coordOut2, float &coordOut3) const
returns three coordinates of an index triplet
Definition VolumeSpace.h:89
cifti::VolumeSpace::enclosingVoxel
void enclosingVoxel(const float *coordIn, int64_t &indexOut1, int64_t &indexOut2, int64_t &indexOut3) const
returns integer indexes of voxel whose center is closest to the coordinate triplet
Definition VolumeSpace.h:110
cifti::VolumeSpace::spaceToIndex
void spaceToIndex(const float *coordIn, float &indexOut1, float &indexOut2, float &indexOut3) const
returns three floating point indexes of a given coordinate triplet
Definition VolumeSpace.h:101
cifti::VolumeSpace::enclosingVoxel
void enclosingVoxel(const float &coordIn1, const float &coordIn2, const float &coordIn3, int64_t *indexOut) const
returns integer index triplet of voxel whose center is closest to the three coordinates
Definition VolumeSpace.h:108
cifti::VolumeSpace::getOrientAndSpacingForPlumb
void getOrientAndSpacingForPlumb(OrientTypes *orientOut, float *spacingOut, float *originOut) const
returns orientation, spacing, and center (spacing/center can be negative, spacing/center is LPI rearr...
Definition VolumeSpace.cxx:187
cifti::VolumeSpace::getOrientation
void getOrientation(OrientTypes orientOut[3]) const
get just orientation, even for non-plumb volumes
Definition VolumeSpace.cxx:226
cifti::VolumeSpace::indexValid
bool indexValid(const int64_t &indexIn1, const int64_t &indexIn2, const int64_t &indexIn3) const
checks if an index is within array dimensions
Definition VolumeSpace.h:121
cifti::VolumeSpace::enclosingVoxel
void enclosingVoxel(const float *coordIn, int64_t *indexOut) const
returns integer index triplet of voxel whose center is closest to the coordinate triplet
Definition VolumeSpace.h:106
cifti::VolumeSpace::spaceToIndex
void spaceToIndex(const float *coordIn, float *indexOut) const
returns floating point index triplet of a given coordinate triplet
Definition VolumeSpace.h:97
cifti::VolumeSpace::indexToSpace
void indexToSpace(const T *indexIn, float *coordOut) const
returns coordinate triplet of an index triplet
Definition VolumeSpace.h:79
cifti::VolumeSpace::spaceToIndex
void spaceToIndex(const float &coordIn1, const float &coordIn2, const float &coordIn3, float *indexOut) const
returns floating point index triplet of three given coordinates
Definition VolumeSpace.h:99
cifti::VolumeSpace::indexToSpace
void indexToSpace(const T &indexIn1, const T &indexIn2, const T &indexIn3, float *coordOut) const
returns coordinate triplet of three indices
Definition VolumeSpace.h:84
cifti
namespace for all CiftiLib functionality
Definition CiftiBrainModelsMap.h:42