Commit 893107d8 authored by Stefan Philips's avatar Stefan Philips
Browse files

[CHANGE] Allow to select the numerical type of WGridRegular3D and...

[CHANGE] Allow to select the numerical type of WGridRegular3D and WGridTransformOrtho by a template parameter
parent 048a6587
......@@ -22,388 +22,4 @@
//
//---------------------------------------------------------------------------
#include <cmath>
#include <string>
#include <vector>
#include "../common/exceptions/WOutOfBounds.h"
#include "../common/exceptions/WPreconditionNotMet.h"
#include "../common/math/WLinearAlgebraFunctions.h"
#include "../common/WBoundingBox.h"
#include "../common/WProperties.h"
#include "../common/math/linearAlgebra/WLinearAlgebra.h"
#include "WGridRegular3D.h"
WGridRegular3D::WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
WGridTransformOrtho const transform )
: WGrid( nbPosX * nbPosY * nbPosZ ),
m_nbPosX( nbPosX ),
m_nbPosY( nbPosY ),
m_nbPosZ( nbPosZ ),
m_transform( transform )
{
initInformationProperties();
}
void WGridRegular3D::initInformationProperties()
{
WPropInt xDim = m_infoProperties->addProperty( "X dimension: ", "The x dimension of the grid.", static_cast<int>( getNbCoordsX() ) );
WPropInt yDim = m_infoProperties->addProperty( "Y dimension: ", "The y dimension of the grid.", static_cast<int>( getNbCoordsY() ) );
WPropInt zDim = m_infoProperties->addProperty( "Z dimension: ", "The z dimension of the grid.", static_cast<int>( getNbCoordsZ() ) );
WPropDouble xOffset = m_infoProperties->addProperty( "X offset: ", "The distance between samples in x direction", getOffsetX() );
WPropDouble yOffset = m_infoProperties->addProperty( "Y offset: ", "The distance between samples in y direction", getOffsetY() );
WPropDouble zOffset = m_infoProperties->addProperty( "Z offset: ", "The distance between samples in z direction", getOffsetZ() );
WPropMatrix4X4 transformation = m_infoProperties->addProperty( "Transformation", "The transformation of this grid.",
static_cast< WMatrix4d >( getTransform() ) );
}
boost::shared_ptr< std::vector< WPosition > > WGridRegular3D::getVoxelVertices( const WPosition& point, const double margin ) const
{
typedef boost::shared_ptr< std::vector< WPosition > > ReturnType;
ReturnType result = ReturnType( new std::vector< WPosition > );
result->reserve( 8 );
double halfMarginX = getOffsetX() / 2.0 - std::abs( margin );
double halfMarginY = getOffsetY() / 2.0 - std::abs( margin );
double halfMarginZ = getOffsetZ() / 2.0 - std::abs( margin );
result->push_back( WPosition( point[0] - halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // a
result->push_back( WPosition( point[0] + halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // b
result->push_back( WPosition( point[0] + halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // c
result->push_back( WPosition( point[0] - halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // d
result->push_back( WPosition( point[0] - halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // e
result->push_back( WPosition( point[0] + halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // f
result->push_back( WPosition( point[0] + halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // g
result->push_back( WPosition( point[0] - halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // h
return result;
}
std::vector< size_t > WGridRegular3D::getNeighbours( size_t id ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// for every neighbour we must check if its not on the boundary, it will be skipped otherwise
if( x > 0 )
{
neighbours.push_back( id - 1 );
}
if( x < m_nbPosX - 1 )
{
neighbours.push_back( id + 1 );
}
if( y > 0 )
{
neighbours.push_back( id - m_nbPosX );
}
if( y < m_nbPosY - 1 )
{
neighbours.push_back( id + m_nbPosX );
}
if( z > 0 )
{
neighbours.push_back( id - ( m_nbPosX * m_nbPosY ) );
}
if( z < m_nbPosZ - 1 )
{
neighbours.push_back( id + ( m_nbPosX * m_nbPosY ) );
}
return neighbours;
}
std::vector< size_t > WGridRegular3D::getNeighbours27( size_t id ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// for every neighbour we must check if its not on the boundary, it will be skipped otherwise
std::vector< int >tempResult;
tempResult.push_back( getVoxelNum( x , y , z ) );
tempResult.push_back( getVoxelNum( x , y - 1, z ) );
tempResult.push_back( getVoxelNum( x , y + 1, z ) );
tempResult.push_back( getVoxelNum( x - 1, y , z ) );
tempResult.push_back( getVoxelNum( x - 1, y - 1, z ) );
tempResult.push_back( getVoxelNum( x - 1, y + 1, z ) );
tempResult.push_back( getVoxelNum( x + 1, y , z ) );
tempResult.push_back( getVoxelNum( x + 1, y - 1, z ) );
tempResult.push_back( getVoxelNum( x + 1, y + 1, z ) );
tempResult.push_back( getVoxelNum( x , y , z - 1 ) );
tempResult.push_back( getVoxelNum( x , y - 1, z - 1 ) );
tempResult.push_back( getVoxelNum( x , y + 1, z - 1 ) );
tempResult.push_back( getVoxelNum( x - 1, y , z - 1 ) );
tempResult.push_back( getVoxelNum( x - 1, y - 1, z - 1 ) );
tempResult.push_back( getVoxelNum( x - 1, y + 1, z - 1 ) );
tempResult.push_back( getVoxelNum( x + 1, y , z - 1 ) );
tempResult.push_back( getVoxelNum( x + 1, y - 1, z - 1 ) );
tempResult.push_back( getVoxelNum( x + 1, y + 1, z - 1 ) );
tempResult.push_back( getVoxelNum( x , y , z + 1 ) );
tempResult.push_back( getVoxelNum( x , y - 1, z + 1 ) );
tempResult.push_back( getVoxelNum( x , y + 1, z + 1 ) );
tempResult.push_back( getVoxelNum( x - 1, y , z + 1 ) );
tempResult.push_back( getVoxelNum( x - 1, y - 1, z + 1 ) );
tempResult.push_back( getVoxelNum( x - 1, y + 1, z + 1 ) );
tempResult.push_back( getVoxelNum( x + 1, y , z + 1 ) );
tempResult.push_back( getVoxelNum( x + 1, y - 1, z + 1 ) );
tempResult.push_back( getVoxelNum( x + 1, y + 1, z + 1 ) );
for( size_t k = 0; k < tempResult.size(); ++k )
{
if( tempResult[k] != -1 )
{
neighbours.push_back( tempResult[k] );
}
}
return neighbours;
}
std::vector< size_t > WGridRegular3D::getNeighboursRange( size_t id, size_t range ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// for every neighbour we must check if its not on the boundary, it will be skipped otherwise
std::vector< int >tempResult;
for( size_t xx = x - range; xx < x + range + 1; ++xx )
{
for( size_t yy = y - range; yy < y + range + 1; ++yy )
{
for( size_t zz = z - range; zz < z + range + 1; ++zz )
{
tempResult.push_back( getVoxelNum( xx, yy, zz ) );
}
}
}
for( size_t k = 0; k < tempResult.size(); ++k )
{
if( tempResult[k] != -1 )
{
neighbours.push_back( tempResult[k] );
}
}
return neighbours;
}
std::vector< size_t > WGridRegular3D::getNeighbours9XY( size_t id ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// boundary check now happens in the getVoxelNum function
int vNum;
vNum = getVoxelNum( x - 1, y, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x - 1, y - 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y - 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x + 1, y - 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x + 1, y, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x + 1, y + 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y + 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x - 1, y + 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
return neighbours;
}
std::vector< size_t > WGridRegular3D::getNeighbours9YZ( size_t id ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// boundary check now happens in the getVoxelNum function
int vNum;
vNum = getVoxelNum( x, y, z - 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y - 1, z - 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y - 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y - 1, z + 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y, z + 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y + 1, z + 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y + 1, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y + 1, z - 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
return neighbours;
}
std::vector< size_t > WGridRegular3D::getNeighbours9XZ( size_t id ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// boundary check now happens in the getVoxelNum function
int vNum;
vNum = getVoxelNum( x, y, z - 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x - 1, y, z - 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x - 1, y, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x - 1, y, z + 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x, y, z + 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x + 1, y, z + 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x + 1, y, z );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
vNum = getVoxelNum( x + 1, y, z - 1 );
if( vNum != -1 )
{
neighbours.push_back( vNum );
}
return neighbours;
}
This diff is collapsed.
......@@ -22,194 +22,4 @@
//
//---------------------------------------------------------------------------
#include "../common/exceptions/WPreconditionNotMet.h"
#include "WGridTransformOrtho.h"
WGridTransformOrtho::WGridTransformOrtho()
: m_unitDirectionX( 1.0, 0.0, 0.0 ),
m_unitDirectionY( 0.0, 1.0, 0.0 ),
m_unitDirectionZ( 0.0, 0.0, 1.0 ),
m_scaling( 1.0, 1.0, 1.0 ),
m_origin( 0.0, 0.0, 0.0 )
{
}
WGridTransformOrtho::WGridTransformOrtho( double scaleX, double scaleY, double scaleZ )
: m_unitDirectionX( ( scaleX > 0.0 ) - ( scaleX < 0.0 ), 0.0, 0.0 ),
m_unitDirectionY( 0.0, ( scaleY > 0.0 ) - ( scaleY < 0.0 ), 0.0 ),
m_unitDirectionZ( 0.0, 0.0, ( scaleZ > 0.0 ) - ( scaleZ < 0.0 ) ),
m_scaling( fabs( scaleX ), fabs( scaleY ), fabs( scaleZ ) ),
m_origin( 0.0, 0.0, 0.0 )
{
WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
}
WGridTransformOrtho::WGridTransformOrtho( WMatrix< double > const& mat )
{
WPrecond( mat.getNbRows() == 4 && mat.getNbCols() == 4, "" );
m_unitDirectionX = WVector3d( mat( 0, 0 ), mat( 1, 0 ), mat( 2, 0 ) );
m_unitDirectionY = WVector3d( mat( 0, 1 ), mat( 1, 1 ), mat( 2, 1 ) );
m_unitDirectionZ = WVector3d( mat( 0, 2 ), mat( 1, 2 ), mat( 2, 2 ) );
m_scaling = WVector3d( length( m_unitDirectionX ), length( m_unitDirectionY ), length( m_unitDirectionZ ) );
WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
m_unitDirectionX /= m_scaling[ 0 ];
m_unitDirectionY /= m_scaling[ 1 ];
m_unitDirectionZ /= m_scaling[ 2 ];
WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionY ) ), 0.0001 );
WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionZ ) ), 0.0001 );
WPrecondLess( fabs( dot( m_unitDirectionY, m_unitDirectionZ ) ), 0.0001 );
m_origin = WVector3d( mat( 0, 3 ), mat( 1, 3 ), mat( 2, 3 ) );
}
WGridTransformOrtho::~WGridTransformOrtho()
{
}
WVector3d WGridTransformOrtho::positionToWorldSpace( WVector3d const& position ) const
{
return WVector3d( m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 0 ] +
m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 0 ] +
m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 0 ] +
m_origin[ 0 ],
m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 1 ] +
m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 1 ] +
m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 1 ] +
m_origin[ 1 ],
m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 2 ] +
m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 2 ] +
m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 2 ] +
m_origin[ 2 ] );
}
WVector3d WGridTransformOrtho::positionToGridSpace( WVector3d const& position ) const
{
WVector3d p = position - m_origin;
p = WVector3d( dot( p, m_unitDirectionX ), dot( p, m_unitDirectionY ), dot( p, m_unitDirectionZ ) );
p[ 0 ] /= m_scaling[ 0 ];
p[ 1 ] /= m_scaling[ 1 ];
p[ 2 ] /= m_scaling[ 2 ];
return p;
}
WVector3d WGridTransformOrtho::directionToWorldSpace( WVector3d const& direction ) const
{
return WVector3d( m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 0 ] +
m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 0 ] +
m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 0 ],
m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 1 ] +
m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 1 ] +
m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 1 ],
m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 2 ] +
m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 2 ] +
m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 2 ] );
}
WVector3d WGridTransformOrtho::directionToGridSpace( WVector3d const& direction ) const
{
WVector3d p( dot( direction, m_unitDirectionX ), dot( direction, m_unitDirectionY ), dot( direction, m_unitDirectionZ ) );
p[ 0 ] /= m_scaling[ 0 ];
p[ 1 ] /= m_scaling[ 1 ];
p[ 2 ] /= m_scaling[ 2 ];
return p;
}
double WGridTransformOrtho::getOffsetX() const
{
return m_scaling[ 0 ];
}
double WGridTransformOrtho::getOffsetY() const
{
return m_scaling[ 1 ];
}
double WGridTransformOrtho::getOffsetZ() const
{
return m_scaling[ 2 ];
}
WVector3d WGridTransformOrtho::getUnitDirectionX() const
{
return m_unitDirectionX;
}
WVector3d WGridTransformOrtho::getUnitDirectionY() const
{
return m_unitDirectionY;
}
WVector3d WGridTransformOrtho::getUnitDirectionZ() const
{
return m_unitDirectionZ;
}
WVector3d WGridTransformOrtho::getDirectionX() const
{
return m_unitDirectionX * m_scaling[ 0 ];
}
WVector3d WGridTransformOrtho::getDirectionY() const
{
return m_unitDirectionY * m_scaling[ 1 ];
}
WVector3d WGridTransformOrtho::getDirectionZ() const
{
return m_unitDirectionZ * m_scaling[ 2 ];
}
WPosition WGridTransformOrtho::getOrigin() const
{
return m_origin;
}
WMatrix< double > WGridTransformOrtho::getTransformationMatrix() const
{
WMatrix< double > mat( 4, 4 );
mat.makeIdentity();
mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
mat( 1, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
mat( 2, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
mat( 0, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
mat( 2, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
mat( 0, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
mat( 1, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
mat( 0, 3 ) = m_origin[ 0 ];
mat( 1, 3 ) = m_origin[ 1 ];
mat( 2, 3 ) = m_origin[ 2 ];
return mat;
}
bool WGridTransformOrtho::isNotRotated() const
{
return m_unitDirectionX == WVector3d( 1.0, 0.0, 0.0 )
&& m_unitDirectionY == WVector3d( 0.0, 1.0, 0.0 )
&& m_unitDirectionZ == WVector3d( 0.0, 0.0, 1.0 );
}
WGridTransformOrtho::operator WMatrix4d() const
{
WMatrix4d mat = WMatrix4d::identity();
mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
mat( 0, 1 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
mat( 0, 2 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
mat( 1, 0 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
mat( 1, 2 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
mat( 2, 0 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
mat( 2