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 #ifndef WFIBERCLUSTER_H 00026 #define WFIBERCLUSTER_H 00027 00028 #include <list> 00029 #include <string> 00030 #include <vector> 00031 00032 #include <boost/shared_ptr.hpp> 00033 #include <boost/thread.hpp> 00034 00035 #include "../../common/WColor.h" 00036 #include "../../common/WTransferable.h" 00037 #include "../WDataSetFiberVector.h" 00038 00039 00040 /** 00041 * Represents a cluster of indices of a WDataSetFiberVector. 00042 */ 00043 class WFiberCluster: public WTransferable // NOLINT 00044 { 00045 friend class WFiberClusterTest; 00046 public: 00047 /** 00048 * Shared pointer abbreviation. 00049 */ 00050 typedef boost::shared_ptr< WFiberCluster > SPtr; 00051 00052 /** 00053 * Const shared pointer abbreviation. 00054 */ 00055 typedef boost::shared_ptr< const WFiberCluster > ConstSPtr; 00056 00057 /** 00058 * This is the list of indices of fibers. 00059 */ 00060 typedef std::list< size_t > IndexList; 00061 00062 /** 00063 * Const iterator on the index list. 00064 */ 00065 typedef IndexList::const_iterator IndexListConstIterator; 00066 00067 /** 00068 * Constructs an cluster with one fiber and a reference to the fiber dataset 00069 * to compute the intercluster distance. 00070 * 00071 * \param index The index of the first fiber belonging to this cluster 00072 */ 00073 explicit WFiberCluster( size_t index ); 00074 00075 /** 00076 * Constructs a cluster with the specified set of indices and the given color. 00077 * 00078 * \param indices the indices initially used for this clustering 00079 * \param color the color of this cluster 00080 */ 00081 WFiberCluster( const IndexList& indices, const WColor& color = WColor() ); 00082 00083 /** 00084 * Constructs a clustering with the given set of indices. The indexlist is generated using the given iterators. It copies the elements in 00085 * [indicesBegin,indicesEnd). 00086 * 00087 * \param indicesBegin begin iterator in the predefined index set 00088 * \param indicesEnd end iterator in the predefined index set 00089 * \param color the color of this cluster 00090 */ 00091 WFiberCluster( IndexListConstIterator indicesBegin, 00092 IndexListConstIterator indicesEnd, const WColor& color = WColor() ); 00093 00094 /** 00095 * Copies the specified \ref WFiberCluster Instance. The copy does not contain a valid centerline or longest line. 00096 * 00097 * \param other the other instance to clone. 00098 */ 00099 WFiberCluster( const WFiberCluster& other ); 00100 00101 /** 00102 * Constructs an empty cluster. 00103 */ 00104 WFiberCluster(); 00105 00106 /** 00107 * Destructs. Frees used locks/mutex. 00108 */ 00109 virtual ~WFiberCluster(); 00110 00111 /** 00112 * Returns true if there are no fibers in that cluster, false otherwise. 00113 * 00114 * \return true if empty 00115 */ 00116 bool empty() const; 00117 00118 /** 00119 * Merge the fibers of the other cluster with the fibers of this cluster. 00120 * Afterwards the other cluster is empty. 00121 * 00122 * \param other The other WFiberCluster which should merged into this one 00123 */ 00124 void merge( WFiberCluster &other ); // NOLINT 00125 00126 /** 00127 * Copy the elements denoted by the two iterators to this cluster. In contrast to the other merge() methods, this will not clean the source 00128 * list. 00129 * 00130 * \param indicesBegin begin iterator in the predefined index set 00131 * \param indicesEnd end iterator in the predefined index set 00132 */ 00133 void merge( IndexListConstIterator indicesBegin, IndexListConstIterator indicesEnd ); 00134 00135 /** 00136 * Returns a const reference of all indices inside this cluster 00137 * 00138 * \return the index list 00139 */ 00140 const IndexList& getIndices() const; 00141 00142 /** 00143 * Reset the indices belonging to that cluster 00144 * 00145 * \param indices list of indices 00146 */ 00147 void setIndices( const IndexList& indices ); 00148 00149 /** 00150 * Sort the indices of fibers associated with this cluster in ascending 00151 * order. 00152 */ 00153 void sort(); 00154 00155 /** 00156 * \return Number of fibers associated with this cluster. 00157 */ 00158 size_t size() const; 00159 00160 /** 00161 * Make this cluster empty. Note: The real fibers from fiber dataset are 00162 * not deleted. 00163 */ 00164 void clear(); 00165 00166 /** 00167 * Sets the color of which all fibers of this clusters should be painted 00168 * with. 00169 * 00170 * \param color The color for all fibers of this cluster. 00171 */ 00172 void setColor( WColor color ); 00173 00174 /** 00175 * Gets the color of which all fibers of this clusters should be painted 00176 * with. 00177 * 00178 * \return cluster color. 00179 */ 00180 WColor getColor() const; 00181 00182 /** 00183 * Sets the main direction of the cluster 00184 * 00185 * \param mainDirection the cluster's main direction 00186 */ 00187 void setMainDirection( osg::Vec3 mainDirection ); 00188 00189 /** 00190 * Gets the main direction of the cluster ( if set ) 00191 * 00192 * \return the cluster's main direction 00193 */ 00194 osg::Vec3 getMainDirection() const; 00195 00196 /** 00197 * The name of this transferable. This is useful information for the users. 00198 * 00199 * \return the name. 00200 */ 00201 virtual const std::string getName() const; 00202 00203 /** 00204 * 00205 * The description of this transferable. This is useful information for the users. 00206 * 00207 * \return A description 00208 */ 00209 virtual const std::string getDescription() const; 00210 00211 /** 00212 * \param other The other fiber which should be compared 00213 * \return true If both clusters having same fibers IN SAME ORDER! 00214 */ 00215 bool operator==( const WFiberCluster& other ) const; 00216 00217 /** 00218 * The opposite of the operator== 00219 * 00220 * \param other The other fiber which should be compared 00221 * \return false If both clusters having same fibers IN SAME ORDER! 00222 */ 00223 bool operator!=( const WFiberCluster& other ) const; 00224 00225 /** 00226 * Copy assignment operator which does NOT copy the mutex's!!! 00227 * 00228 * \param other The instance to copy. 00229 * 00230 * \return itself 00231 */ 00232 WFiberCluster& operator=( const WFiberCluster& other ) 00233 { 00234 WTransferable::operator=( other ); 00235 m_memberIndices = other.m_memberIndices; 00236 m_fibs = other.m_fibs; 00237 m_color = other.m_color; 00238 m_centerLineCreationLock = new boost::shared_mutex(); 00239 m_longestLineCreationLock = new boost::shared_mutex(); 00240 // copy them only if they exist 00241 if( other.m_centerLine ) 00242 { 00243 m_centerLine = boost::shared_ptr< WFiber >( new WFiber( *other.m_centerLine.get() ) ); 00244 } 00245 if( other.m_longestLine ) 00246 { 00247 m_longestLine = boost::shared_ptr< WFiber >( new WFiber( *other.m_longestLine.get() ) ); 00248 } 00249 return *this; 00250 } 00251 00252 // TODO(math): The only reason why we store here a Reference to the fiber 00253 // dataset is, we need it in the WMVoxelizer module as well as the clustering 00254 // information. Since we don't have the possibility of multiple 00255 // InputConnectors we must agglomerate those into one object. Please remove this. 00256 // \cond Suppress_Doxygen 00257 void setDataSetReference( boost::shared_ptr< const WDataSetFiberVector > fibs ); 00258 boost::shared_ptr< const WDataSetFiberVector > getDataSetReference() const; 00259 // \endcond 00260 00261 /** 00262 * Returns a prototype instantiated with the true type of the deriving class. 00263 * 00264 * \return the prototype. 00265 */ 00266 static boost::shared_ptr< WPrototyped > getPrototype(); 00267 00268 /** 00269 * Returns the center line of this cluster. The centerline gets calculated during the first call of this method. 00270 * 00271 * \return Reference to the center line 00272 */ 00273 boost::shared_ptr< WFiber > getCenterLine() const; 00274 00275 /** 00276 * Returns the center line of this cluster. The longest line gets calculated during the first call if this method. 00277 * 00278 * \return Reference to the longest line 00279 */ 00280 boost::shared_ptr< WFiber > getLongestLine() const; 00281 00282 /** 00283 * Makes the hard work to compute the center line. 00284 */ 00285 void generateCenterLine() const; 00286 00287 /** 00288 * Makes the hard work to find the longest line. 00289 */ 00290 void generateLongestLine() const; 00291 00292 /** 00293 * Recomputes on every call the axis aligned bounding box incorporating all tracts in this cluster. 00294 * 00295 * \return AABB as WBoundingBox. 00296 */ 00297 WBoundingBox getBoundingBox() const; 00298 00299 protected: 00300 /** 00301 * Prototype for this dataset 00302 */ 00303 static boost::shared_ptr< WPrototyped > m_prototype; 00304 00305 /** 00306 * Alings all fibers within the given dataset to be in one main direction. But Alignment only may swap the ordering of the fibers 00307 * but not the positions or something similar. We need this only for the centerline generation. 00308 * 00309 * \param fibs The dataset 00310 */ 00311 void unifyDirection( boost::shared_ptr< WDataSetFiberVector > fibs ) const; 00312 00313 private: 00314 /** 00315 * The centerline may be shortened due to the averaging of outliers. To 00316 * nevertheless color almost the whole bundle surface we need a surface 00317 * parameterization (given via the centerline) upto the endings of the 00318 * bundle. Therefore the centerline is stepwise elongated with the last 00319 * known direction, until no perpendicular plane intersects any of the 00320 * tracts inside of the bundle. 00321 */ 00322 void elongateCenterLine() const; 00323 00324 /** 00325 * All indices in this set are members of this cluster 00326 */ 00327 IndexList m_memberIndices; 00328 00329 // TODO(math): The only reason why we store here a Reference to the fiber 00330 // dataset is, we need it in the WMVoxelizer module as well as the clustering 00331 // information. Since we don't have the possibility of multiple 00332 // InputConnectors we must agglomerate those into one object. Please remove this. 00333 /** 00334 * Reference to the real fibers of the brain this cluster belongs to. 00335 */ 00336 boost::shared_ptr< const WDataSetFiberVector > m_fibs; 00337 00338 /** 00339 * Color which is used to paint the members of this cluster. 00340 */ 00341 WColor m_color; 00342 00343 /** 00344 * The cluster's main direction 00345 */ 00346 osg::Vec3 m_mainDirection; 00347 00348 /** 00349 * Lock the modification in the m_centerLine mutable. The lock is stored as pointer to avoid copy construction problems. 00350 */ 00351 boost::shared_mutex* m_centerLineCreationLock; 00352 00353 /** 00354 * Lock the modification in the m_longestLine mutable. The lock is stored as pointer to avoid copy construction problems. 00355 */ 00356 boost::shared_mutex* m_longestLineCreationLock; 00357 00358 /** 00359 * Average fiber for this cluster representing the main direction and curvature of this cluster. 00360 * 00361 * \note This member is mutable as it needs to be modified during a const getter. 00362 */ 00363 mutable boost::shared_ptr< WFiber > m_centerLine; 00364 00365 /** 00366 * The longest fiber in the dataset. 00367 * 00368 * \note This member is mutable as it needs to be modified during a const getter. 00369 */ 00370 mutable boost::shared_ptr< WFiber > m_longestLine; 00371 }; 00372 00373 inline bool WFiberCluster::empty() const 00374 { 00375 return m_memberIndices.empty(); 00376 } 00377 00378 inline void WFiberCluster::sort() 00379 { 00380 m_memberIndices.sort(); 00381 } 00382 00383 inline size_t WFiberCluster::size() const 00384 { 00385 return m_memberIndices.size(); 00386 } 00387 00388 inline void WFiberCluster::clear() 00389 { 00390 m_memberIndices.clear(); 00391 } 00392 00393 inline void WFiberCluster::setColor( WColor color ) 00394 { 00395 m_color = color; 00396 } 00397 00398 inline WColor WFiberCluster::getColor() const 00399 { 00400 return m_color; 00401 } 00402 00403 inline void WFiberCluster::setMainDirection( osg::Vec3 mainDirection ) 00404 { 00405 m_mainDirection = mainDirection; 00406 } 00407 00408 inline osg::Vec3 WFiberCluster::getMainDirection() const 00409 { 00410 return m_mainDirection; 00411 } 00412 00413 inline const std::string WFiberCluster::getName() const 00414 { 00415 return "FiberCluster"; 00416 } 00417 00418 inline const std::string WFiberCluster::getDescription() const 00419 { 00420 return "A collection of indices for fibers representing a fiber cluster"; 00421 } 00422 00423 inline bool WFiberCluster::operator==( const WFiberCluster& other ) const 00424 { 00425 return m_memberIndices == other.m_memberIndices; 00426 } 00427 00428 inline bool WFiberCluster::operator!=( const WFiberCluster& other ) const 00429 { 00430 return m_memberIndices != other.m_memberIndices; 00431 } 00432 00433 inline const WFiberCluster::IndexList& WFiberCluster::getIndices() const 00434 { 00435 return m_memberIndices; 00436 } 00437 00438 inline void WFiberCluster::setIndices( const WFiberCluster::IndexList& indices ) 00439 { 00440 m_memberIndices = indices; 00441 } 00442 00443 inline std::ostream& operator<<( std::ostream& os, const WFiberCluster& c ) 00444 { 00445 using string_utils::operator<<; 00446 return os << c.getIndices(); 00447 } 00448 00449 #endif // WFIBERCLUSTER_H