OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #include <vector> 00026 00027 #include "../graphicsEngine/WROIBox.h" 00028 #include "../graphicsEngine/WROIArbitrary.h" 00029 #include "WKdTree.h" 00030 00031 #include "WSelectorRoi.h" 00032 00033 00034 WSelectorRoi::WSelectorRoi( osg::ref_ptr< WROI > roi, boost::shared_ptr< const WDataSetFibers > fibers, boost::shared_ptr< WKdTree> kdTree ) : 00035 m_roi( roi ), 00036 m_fibers( fibers ), 00037 m_kdTree( kdTree ), 00038 m_size( fibers->size() ), 00039 m_dirty( true ) 00040 { 00041 m_bitField = boost::shared_ptr< std::vector<bool> >( new std::vector<bool>( m_size, false ) ); 00042 00043 m_currentArray = m_fibers->getVertices(); 00044 m_currentReverse = m_fibers->getVerticesReverse(); 00045 00046 m_changeRoiSignal 00047 = boost::shared_ptr< boost::function< void() > >( new boost::function< void() >( boost::bind( &WSelectorRoi::setDirty, this ) ) ); 00048 m_roi->addROIChangeNotifier( m_changeRoiSignal ); 00049 } 00050 00051 WSelectorRoi::~WSelectorRoi() 00052 { 00053 m_roi->removeROIChangeNotifier( m_changeRoiSignal ); 00054 } 00055 00056 void WSelectorRoi::setDirty() 00057 { 00058 m_dirty = true; 00059 } 00060 00061 void WSelectorRoi::recalculate() 00062 { 00063 m_workerBitfield = boost::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_size, false ) ); 00064 00065 if( osg::dynamic_pointer_cast<WROIBox>( m_roi ).get() ) 00066 { 00067 m_boxMin.resize( 3 ); 00068 m_boxMax.resize( 3 ); 00069 00070 osg::ref_ptr<WROIBox> box = osg::dynamic_pointer_cast<WROIBox>( m_roi ); 00071 00072 m_boxMin[0] = box->getMinPos()[0]; 00073 m_boxMax[0] = box->getMaxPos()[0]; 00074 m_boxMin[1] = box->getMinPos()[1]; 00075 m_boxMax[1] = box->getMaxPos()[1]; 00076 m_boxMin[2] = box->getMinPos()[2]; 00077 m_boxMax[2] = box->getMaxPos()[2]; 00078 00079 boxTest( 0, m_currentArray->size() / 3 - 1, 0 ); 00080 } 00081 00082 if( osg::dynamic_pointer_cast<WROIArbitrary>( m_roi ).get() ) 00083 { 00084 osg::ref_ptr<WROIArbitrary>roi = osg::dynamic_pointer_cast<WROIArbitrary>( m_roi ); 00085 00086 float threshold = static_cast<float>( roi->getThreshold() ); 00087 00088 size_t nx = roi->getCoordDimensions()[0]; 00089 size_t ny = roi->getCoordDimensions()[1]; 00090 00091 double dx = roi->getCoordOffsets()[0]; 00092 double dy = roi->getCoordOffsets()[1]; 00093 double dz = roi->getCoordOffsets()[2]; 00094 00095 for( size_t i = 0; i < m_currentArray->size()/3; ++i ) 00096 { 00097 size_t x = static_cast<size_t>( ( *m_currentArray )[i * 3 ] / dx ); 00098 size_t y = static_cast<size_t>( ( *m_currentArray )[i * 3 + 1] / dy ); 00099 size_t z = static_cast<size_t>( ( *m_currentArray )[i * 3 + 2] / dz ); 00100 int index = x + y * nx + z * nx * ny; 00101 00102 if( static_cast<float>( roi->getValue( index ) ) - threshold > 0.1 ) 00103 { 00104 ( *m_workerBitfield )[getLineForPoint( i )] = 1; 00105 } 00106 } 00107 } 00108 m_dirty = false; 00109 m_bitField = m_workerBitfield; 00110 } 00111 00112 void WSelectorRoi::boxTest( int left, int right, int axis ) 00113 { 00114 // abort condition 00115 if( left > right ) 00116 return; 00117 00118 int root = left + ( ( right - left ) / 2 ); 00119 int axis1 = ( axis + 1 ) % 3; 00120 int pointIndex = m_kdTree->m_tree[root] * 3; 00121 00122 if( ( *m_currentArray )[pointIndex + axis] < m_boxMin[axis] ) 00123 { 00124 boxTest( root + 1, right, axis1 ); 00125 } 00126 else if( ( *m_currentArray )[pointIndex + axis] > m_boxMax[axis] ) 00127 { 00128 boxTest( left, root - 1, axis1 ); 00129 } 00130 else 00131 { 00132 int axis2 = ( axis + 2 ) % 3; 00133 if( ( *m_currentArray )[pointIndex + axis1] <= m_boxMax[axis1] && ( *m_currentArray )[pointIndex + axis1] 00134 >= m_boxMin[axis1] && ( *m_currentArray )[pointIndex + axis2] <= m_boxMax[axis2] 00135 && ( *m_currentArray )[pointIndex + axis2] >= m_boxMin[axis2] ) 00136 { 00137 ( *m_workerBitfield )[getLineForPoint( m_kdTree->m_tree[root] )] = 1; 00138 } 00139 boxTest( left, root - 1, axis1 ); 00140 boxTest( root + 1, right, axis1 ); 00141 } 00142 }