Commit 0432d768 authored by ledig's avatar ledig
Browse files

Merge

parents 41049dfe 0ea1622f
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <algorithm>
#include "../exceptions/WOutOfBounds.h"
#include "WUnionFind.h"
WUnionFind::WUnionFind( size_t size )
: m_component( size )
{
for( size_t i = 0; i < size; ++i )
{
m_component[i] = i;
}
}
size_t WUnionFind::find( size_t x )
{
if( x >= m_component.size() )
{
throw WOutOfBounds( "Element index in UnionFind greater than overall elements!" );
}
if ( m_component[x] == x ) // we are the root
{
return x;
}
m_component[x] = find( m_component[x] ); // path compression otherwise
return m_component[x];
}
void WUnionFind::merge( size_t i, size_t j )
{
if( i >= m_component.size() || j >= m_component.size() )
{
throw WOutOfBounds( "Element index in UnionFind greater than overall elements!" );
}
if( i == j )
{
return;
}
size_t ci = find( i );
size_t cj = find( j );
if( ci == cj )
{
return;
}
m_component[ ci ] = cj;
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WUNIONFIND_H
#define WUNIONFIND_H
#include <vector>
/**
* Implements a very simple union-find datastructure aka disjoint_sets.
* \note I know there is a boost solution on that:
* http://www.boost.org/doc/libs/1_42_0/libs/disjoint_sets/disjoint_sets.html
*
* And you may use it like this:
\verbatim
typedef std::vector< SizeType > RankVector;
typedef RankVector::iterator RankRAIter;
typedef std::vector< VertexDescriptor > ParentVector;
typedef ParentVector::iterator ParentRAIter;
typedef boost::iterator_property_map< RankRAIter,
IndexMap,
std::iterator_traits< RankRAIter >::value_type,
std::iterator_traits< RankRAIter >::reference > RankMap;
typedef boost::iterator_property_map< ParentRAIter,
IndexMap,
std::iterator_traits< ParentRAIter >::value_type,
std::iterator_traits< ParentRAIter >::reference > ParentMap;
RankVector ranks( d_numOfVertices );
ParentVector parents( d_numOfVertices );
boost::disjoint_sets< RankMap, ParentMap > dset( boost::make_iterator_property_map( ranks.begin(),
boost::get( boost::vertex_index, g ),
ranks[0] ),
boost::make_iterator_property_map( parents.begin(),
boost::get( boost::vertex_index, g ),
parents[0] )
);
// After the disjoint set dset is construct, we can use
dset.make_set( u ); // make u a set
dset.link( u, v ); // u and v are belonging to the same set.
dset.find_set( u ); // find the set owning u. A representative of the set is returned
\endverbatim
*/
class WUnionFind
{
friend class WUnionFindTest;
public:
/**
* Creates a new union find datastructure with size elements where each
* element is initialized as a single set.
*
* \param size Number of elements
*/
explicit WUnionFind( size_t size );
/**
* Find the canonical element of the given element and do path compression
*
* http://en.wikipedia.org/wiki/Disjoint-set_data_structure
*
* depth of recursion is said to be small, therefore, recursion
* works fine for large dataset, too.
*
* \throw WOutOfBounds If x is bigger than the number of elements available
*
* \param x The x'th element
* \return The canonical element of that component which x is also member of
*/
size_t find( size_t x );
/**
* Merges two components (iow: makes a union) where the given elements are
* members of.
*
* \throw WOutOfBounds If i or j are bigger than the number of elements available
*
* \param i Element of some component
* \param j Element of some (maybe other) component
*/
void merge( size_t i, size_t j );
private:
std::vector< size_t > m_component; //!< Stores for each index its cluster ID
};
#endif // WUNIONFIND_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WUNIONFIND_TEST_H
#define WUNIONFIND_TEST_H
#include <vector>
#include <cxxtest/TestSuite.h>
#include "../WUnionFind.h"
/**
* Unit tests the WUnionFind datastructure.
*/
class WUnionFindTest : public CxxTest::TestSuite
{
public:
/**
* The union always ensure that the new canonical element is the biggest
* index.
*/
void testUnionMergesToBiggerIndex( void )
{
WUnionFind uf( 5 );
uf.merge( 4, 0 );
size_t data[] = { 0, 1, 2, 3, 0 }; // NOLINT
std::vector< size_t > expected( data, data + 5 );
TS_ASSERT_EQUALS( uf.m_component, expected );
uf.merge( 1, 3 );
expected[1] = 3;
TS_ASSERT_EQUALS( uf.m_component, expected );
}
};
#endif // WUNIONFIND_TEST_H
......@@ -49,6 +49,7 @@ WDataSetFibers::WDataSetFibers( boost::shared_ptr< std::vector< float > >vertice
m_lineLengths( lineLengths ),
m_verticesReverse( verticesReverse )
{
// TODO(schurade): replace this with a permanent solution
for ( size_t i = 0; i < m_vertices->size(); ++i )
{
m_vertices->at( i ) = 160 - m_vertices->at( i );
......@@ -57,6 +58,74 @@ WDataSetFibers::WDataSetFibers( boost::shared_ptr< std::vector< float > >vertice
++i;
//m_pointArray[i] = m_dh->frames - m_pointArray[i];
}
m_tangents = boost::shared_ptr< std::vector< float > >( new std::vector<float>() );
m_tangents->resize( m_vertices->size() );
m_colors = boost::shared_ptr< std::vector< float > >( new std::vector<float>() );
m_colors->resize( m_vertices->size() );
int pc = 0;
float r, g, b, rr, gg, bb;
float x1, x2, y1, y2, z1, z2;
float lastx, lasty, lastz;
for ( size_t i = 0; i < m_lineLengths->size(); ++i )
{
x1 = m_vertices->at( pc );
y1 = m_vertices->at( pc + 1 );
z1 = m_vertices->at( pc + 2 );
x2 = m_vertices->at( pc + m_lineLengths->at( i ) * 3 - 3 );
y2 = m_vertices->at( pc + m_lineLengths->at( i ) * 3 - 2 );
z2 = m_vertices->at( pc + m_lineLengths->at( i ) * 3 - 1 );
r = ( x1 ) - ( x2 );
g = ( y1 ) - ( y2 );
b = ( z1 ) - ( z2 );
if ( r < 0.0 )
r *= -1.0;
if ( g < 0.0 )
g *= -1.0;
if ( b < 0.0 )
b *= -1.0;
float norm = sqrt( r * r + g * g + b * b );
r *= 1.0 / norm;
g *= 1.0 / norm;
b *= 1.0 / norm;
lastx = m_vertices->at( pc ) + ( m_vertices->at( pc ) - m_vertices->at( pc + 3 ) );
lasty = m_vertices->at( pc + 1 ) + ( m_vertices->at( pc + 1 ) - m_vertices->at( pc + 4 ) );
lastz = m_vertices->at( pc + 2 ) + ( m_vertices->at( pc + 2 ) - m_vertices->at( pc + 5 ) );
for ( size_t j = 0; j < m_lineLengths->at( i ); ++j )
{
rr = lastx - m_vertices->at( pc );
gg = lasty - m_vertices->at( pc + 1 );
bb = lastz - m_vertices->at( pc + 2 );
lastx = m_vertices->at( pc );
lasty = m_vertices->at( pc + 1 );
lastz = m_vertices->at( pc + 2 );
// if ( rr < 0.0 )
// rr *= -1.0;
// if ( gg < 0.0 )
// gg *= -1.0;
// if ( bb < 0.0 )
// bb *= -1.0;
float norm = sqrt( rr * rr + gg * gg + bb * bb );
rr *= 1.0 / norm;
gg *= 1.0 / norm;
bb *= 1.0 / norm;
m_tangents->at( pc ) = rr;
m_tangents->at( pc + 1 ) = gg;
m_tangents->at( pc + 2 ) = bb;
m_colors->at( pc ) = r;
m_colors->at( pc + 1 ) = g;
m_colors->at( pc + 2 ) = b;
pc += 3;
}
}
}
void WDataSetFibers::sortDescLength()
......@@ -114,9 +183,46 @@ boost::shared_ptr< std::vector< size_t > > WDataSetFibers::getVerticesReverse()
return m_verticesReverse;
}
boost::shared_ptr< std::vector< float > > WDataSetFibers::getTangents() const
{
return m_tangents;
}
boost::shared_ptr< std::vector< float > > WDataSetFibers::getColors() const
{
return m_colors;
}
wmath::WPosition WDataSetFibers::getPosition( size_t fiber, size_t vertex ) const
{
size_t index = m_lineStartIndexes->at( fiber ) * 3;
index += vertex * 3;
return wmath::WPosition( m_vertices->at( index ), m_vertices->at( index + 1 ), m_vertices->at( index + 2 ) );
}
wmath::WPosition WDataSetFibers::getTangent( size_t fiber, size_t vertex ) const
{
wmath::WPosition point = getPosition( fiber, vertex );
wmath::WPosition tangent;
if ( vertex == 0 ) // first point
{
wmath::WPosition pointNext = getPosition( fiber, vertex + 1 );
tangent = point - pointNext;
}
else if ( vertex == m_lineLengths->at( fiber ) - 1 ) // last point
{
wmath::WPosition pointBefore = getPosition( fiber, vertex - 1 );
tangent = pointBefore - point;
}
else // somewhere in between
{
wmath::WPosition pointBefore = getPosition( fiber, vertex - 1 );
wmath::WPosition pointNext = getPosition( fiber, vertex + 1 );
tangent = pointBefore - pointNext;
}
tangent.normalize();
return tangent;
}
......@@ -117,6 +117,18 @@ public:
*/
boost::shared_ptr< std::vector< size_t > > getVerticesReverse() const;
/**
* Getter
*/
boost::shared_ptr< std::vector< float > > getTangents() const;
/**
* Getter
*/
boost::shared_ptr< std::vector< float > > getColors() const;
/**
* returns the position in space for a vertex of a given fiber
*
......@@ -125,6 +137,14 @@ public:
*/
wmath::WPosition getPosition( size_t fiber, size_t vertex ) const;
/**
* calculates the tangent for a point on the fiber
*
* \param fiber
* \param vertex
*/
wmath::WPosition getTangent( size_t fiber, size_t vertex ) const;
protected:
/**
......@@ -134,10 +154,20 @@ protected:
private:
/**
* Point vector for all fibers that is actually usable for what we want to do
* Point vector for all fibers
*/
boost::shared_ptr< std::vector< float > > m_vertices;
/**
* Point vector for tangents at each vertex, used for fake tubes
*/
boost::shared_ptr< std::vector< float > > m_tangents;
/**
* color vector for tangents at each vertex, used for fake tubes
*/
boost::shared_ptr< std::vector< float > > m_colors;
/**
* Line vector that contains the start index of its first point for each line.
* \warning The index returned cannot be used in the vertices array until
......
......@@ -34,8 +34,8 @@
// prototype instance as singleton
boost::shared_ptr< WPrototyped > WDataSetSingle::m_prototype = boost::shared_ptr< WPrototyped >();
WDataSetSingle::WDataSetSingle( boost::shared_ptr<WValueSetBase> newValueSet,
boost::shared_ptr<WGrid> newGrid )
WDataSetSingle::WDataSetSingle( boost::shared_ptr< WValueSetBase > newValueSet,
boost::shared_ptr< WGrid > newGrid )
: WDataSet()
{
assert( newValueSet );
......@@ -60,12 +60,12 @@ WDataSetSingle::~WDataSetSingle()
{
}
boost::shared_ptr<WValueSetBase> WDataSetSingle::getValueSet() const
boost::shared_ptr< WValueSetBase > WDataSetSingle::getValueSet() const
{
return m_valueSet;
}
boost::shared_ptr<WGrid> WDataSetSingle::getGrid() const
boost::shared_ptr< WGrid > WDataSetSingle::getGrid() const
{
return m_grid;
}
......
......@@ -80,7 +80,16 @@ public:
* \param y index in y direction
* \param z index in z direction
*/
template < typename T > T getValueAt( int x, int y, int z );
template< typename T > T getValueAt( int x, int y, int z );
/**
* Get the value stored at a certain grid position of the data set
*
* \param id The id'th value in the data set
*
* \return Scalar value for that given position
*/
template< typename T > T getValueAt( size_t id );
/**
* Determines whether this dataset can be used as a texture.
......@@ -141,7 +150,7 @@ private:
boost::shared_ptr< WDataTexture3D > m_texture3D;
};
template < typename T > T WDataSetSingle::getValueAt( int x, int y, int z )
template< typename T > T WDataSetSingle::getValueAt( int x, int y, int z )
{
boost::shared_ptr< WValueSet< T > > vs = boost::shared_dynamic_cast< WValueSet< T > >( m_valueSet );
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_grid );
......@@ -152,4 +161,9 @@ template < typename T > T WDataSetSingle::getValueAt( int x, int y, int z )
return v;
}
template< typename T > T WDataSetSingle::getValueAt( size_t id )
{
boost::shared_ptr< WValueSet< T > > vs = boost::shared_dynamic_cast< WValueSet< T > >( m_valueSet );
return vs->getScalar( id );
}
#endif // WDATASETSINGLE_H
......@@ -25,8 +25,9 @@
#include <cmath>
#include <vector>
#include "WGridRegular3D.h"
#include "../common/exceptions/WOutOfBounds.h"
#include "../math/WLinearAlgebraFunctions.h"
#include "WGridRegular3D.h"
using wmath::WVector3D;
using wmath::WPosition;
......@@ -300,3 +301,47 @@ boost::shared_ptr< std::vector< wmath::WPosition > > WGridRegular3D::getVoxelVer
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;
}
......@@ -341,6 +341,17 @@ public:
boost::shared_ptr< std::vector< wmath::WPosition > > getVoxelVertices( const wmath::WPosition& point,
const double margin = 0.0 ) const;
/**
* Return the list of neighbour voxels.
*
* \throw WOutOfBounds If the voxel id is outside of the grid.
*
* \param id Number of the voxel for which the neighbours should be computed
*
* \return Vector of voxel ids which are all neighboured
*/
std::vector< size_t > getNeighbours( size_t id ) const;
protected:
private:
/**
......
......@@ -91,7 +91,7 @@ boost::shared_ptr< WDataSet > WLoaderNIfTI::load()
unsigned int countVoxels = columns * rows * frames;
#ifdef DEBUG
nifti_image_infodump( header );
//nifti_image_infodump( header );
#endif
switch( header->datatype )
......
......@@ -28,11 +28,13 @@
#include <cstdio>
#include <sstream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <cxxtest/TestSuite.h>
#include "../../common/exceptions/WOutOfBounds.h"
#include "../../math/test/WVector3DTraits.h"
#include "../WGridRegular3D.h"
......@@ -412,21 +414,76 @@ public:
// | | |
// 0,0,0 1,0,0 2,0,0
using boost::shared_ptr;
shared_ptr< WGridRegular3D > g = shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 3, 3, 0, 0, 0, 1, 1, 1 ) );
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
// center point of the grid
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 1, 1, 1 ) ), 13 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 1, 1, 1 ) ), 13 );