00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <algorithm>
00026 #include <iostream>
00027 #include <string>
00028 #include <utility>
00029 #include <vector>
00030
00031
00032 #ifndef BOOST_FILESYSTEM_VERSION
00033 #define BOOST_FILESYSTEM_VERSION 2
00034 #endif
00035 #include <boost/filesystem/fstream.hpp>
00036 #include <boost/lexical_cast.hpp>
00037
00038 #include "../common/datastructures/WFiber.h"
00039 #include "../common/WBoundingBox.h"
00040 #include "../common/WColor.h"
00041 #include "../common/WLogger.h"
00042 #include "../common/WPredicateHelper.h"
00043 #include "../common/WPropertyHelper.h"
00044 #include "../graphicsEngine/WGEUtils.h"
00045 #include "exceptions/WDHNoSuchDataSet.h"
00046 #include "WCreateColorArraysThread.h"
00047 #include "WDataSet.h"
00048 #include "WDataSetFibers.h"
00049
00050
00051 boost::shared_ptr< WPrototyped > WDataSetFibers::m_prototype = boost::shared_ptr< WPrototyped >();
00052
00053 WDataSetFibers::WDataSetFibers()
00054 : WDataSet()
00055 {
00056
00057 }
00058
00059 WDataSetFibers::WDataSetFibers( WDataSetFibers::VertexArray vertices,
00060 WDataSetFibers::IndexArray lineStartIndexes,
00061 WDataSetFibers::LengthArray lineLengths,
00062 WDataSetFibers::IndexArray verticesReverse,
00063 WBoundingBox boundingBox )
00064 : WDataSet(),
00065 m_vertices( vertices ),
00066 m_lineStartIndexes( lineStartIndexes ),
00067 m_lineLengths( lineLengths ),
00068 m_verticesReverse( verticesReverse ),
00069 m_bb( boundingBox )
00070 {
00071 WAssert( m_vertices->size() % 3 == 0, "Invalid vertex array." );
00072 init();
00073 }
00074
00075 WDataSetFibers::WDataSetFibers( WDataSetFibers::VertexArray vertices,
00076 WDataSetFibers::IndexArray lineStartIndexes,
00077 WDataSetFibers::LengthArray lineLengths,
00078 WDataSetFibers::IndexArray verticesReverse )
00079 : WDataSet(),
00080 m_vertices( vertices ),
00081 m_lineStartIndexes( lineStartIndexes ),
00082 m_lineLengths( lineLengths ),
00083 m_verticesReverse( verticesReverse )
00084 {
00085 WAssert( m_vertices->size() % 3 == 0, "Invalid vertex array." );
00086
00087 for( size_t i = 0; i < vertices->size()/3; ++i )
00088 {
00089 m_bb.expandBy( (*vertices)[ 3 * i + 0 ], (*vertices)[ 3 * i + 1 ], (*vertices)[ 3 * i + 2 ] );
00090 }
00091
00092 init();
00093 }
00094
00095 void WDataSetFibers::init()
00096 {
00097 size_t size = m_vertices->size();
00098 m_tangents = boost::shared_ptr< std::vector< float > >( new std::vector<float>( size ) );
00099
00100 boost::shared_ptr< std::vector< float > > globalColors = boost::shared_ptr< std::vector< float > >( new std::vector<float>( size ) );
00101 boost::shared_ptr< std::vector< float > > localColors = boost::shared_ptr< std::vector< float > >( new std::vector<float>( size ) );
00102 boost::shared_ptr< std::vector< float > > customColors = boost::shared_ptr< std::vector< float > >( new std::vector<float>( size ) );
00103
00104
00105
00106 WCreateColorArraysThread* t1 = new WCreateColorArraysThread( 0, m_lineLengths->size()/4, m_vertices,
00107 m_lineStartIndexes, m_lineLengths, globalColors, localColors, m_tangents );
00108 WCreateColorArraysThread* t2 = new WCreateColorArraysThread( m_lineLengths->size()/4+1, m_lineLengths->size()/2, m_vertices,
00109 m_lineStartIndexes, m_lineLengths, globalColors, localColors, m_tangents );
00110 WCreateColorArraysThread* t3 = new WCreateColorArraysThread( m_lineLengths->size()/2+1, m_lineLengths->size()/4*3, m_vertices,
00111 m_lineStartIndexes, m_lineLengths, globalColors, localColors, m_tangents );
00112 WCreateColorArraysThread* t4 = new WCreateColorArraysThread( m_lineLengths->size()/4*3+1, m_lineLengths->size()-1, m_vertices,
00113 m_lineStartIndexes, m_lineLengths, globalColors, localColors, m_tangents );
00114 t1->run();
00115 t2->run();
00116 t3->run();
00117 t4->run();
00118
00119 t1->wait();
00120 t2->wait();
00121 t3->wait();
00122 t4->wait();
00123
00124 delete t1;
00125 delete t2;
00126 delete t3;
00127 delete t4;
00128
00129
00130 m_colors = boost::shared_ptr< WItemSelection >( new WItemSelection() );
00131 m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00132 new ColorScheme( "Global Color", "Colors direction by using start and end vertex per fiber.", NULL, globalColors, ColorScheme::RGB )
00133 )
00134 );
00135 m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00136 new ColorScheme( "Local Color", "Colors direction by using start and end vertex per segment.", NULL, localColors, ColorScheme::RGB )
00137 )
00138 );
00139
00140 for( size_t i = 0; i < size; ++i )
00141 {
00142 ( *customColors )[i] = ( *globalColors )[i];
00143 }
00144 m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00145 new ColorScheme( "Custom Color", "Colors copied from the global colors, will be used for bundle coloring.",
00146 NULL, customColors, ColorScheme::RGB )
00147 )
00148 );
00149
00150
00151 m_colorProp = m_properties->addProperty( "Color Scheme", "Determines the coloring scheme to use for this data.", m_colors->getSelectorFirst() );
00152 WPropertyHelper::PC_SELECTONLYONE::addTo( m_colorProp );
00153 WPropertyHelper::PC_NOTEMPTY::addTo( m_colorProp );
00154 }
00155
00156 bool WDataSetFibers::isTexture() const
00157 {
00158 return false;
00159 }
00160
00161 size_t WDataSetFibers::size() const
00162 {
00163 return m_lineStartIndexes->size();
00164 }
00165
00166 const std::string WDataSetFibers::getName() const
00167 {
00168 return "WDataSetFibers";
00169 }
00170
00171 const std::string WDataSetFibers::getDescription() const
00172 {
00173 return "Contains tracked fiber data.";
00174 }
00175
00176 boost::shared_ptr< WPrototyped > WDataSetFibers::getPrototype()
00177 {
00178 if( !m_prototype )
00179 {
00180 m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetFibers() );
00181 }
00182
00183 return m_prototype;
00184 }
00185
00186 WDataSetFibers::VertexArray WDataSetFibers::getVertices() const
00187 {
00188 return m_vertices;
00189 }
00190
00191 WDataSetFibers::IndexArray WDataSetFibers::getLineStartIndexes() const
00192 {
00193 return m_lineStartIndexes;
00194 }
00195
00196 WDataSetFibers::LengthArray WDataSetFibers::getLineLengths() const
00197 {
00198 return m_lineLengths;
00199 }
00200
00201 WDataSetFibers::IndexArray WDataSetFibers::getVerticesReverse() const
00202 {
00203 return m_verticesReverse;
00204 }
00205
00206 WDataSetFibers::TangentArray WDataSetFibers::getTangents() const
00207 {
00208 return m_tangents;
00209 }
00210
00211 WDataSetFibers::ColorArray WDataSetFibers::getGlobalColors() const
00212 {
00213 return boost::shared_static_cast< const ColorScheme >( ( *m_colors )[0] )->getColor();
00214 }
00215
00216 WDataSetFibers::ColorArray WDataSetFibers::getLocalColors() const
00217 {
00218 return boost::shared_static_cast< const ColorScheme >( ( *m_colors )[1] )->getColor();
00219 }
00220
00221 void WDataSetFibers::addColorScheme( WDataSetFibers::ColorArray colors, std::string name, std::string description )
00222 {
00223 ColorScheme::ColorMode mode = ColorScheme::GRAY;
00224
00225
00226 size_t verts = m_vertices->size() / 3;
00227 size_t cols = colors->size();
00228 if( cols / verts == 3 )
00229 {
00230 mode = ColorScheme::RGB;
00231 }
00232 else if( cols / verts == 4 )
00233 {
00234 mode = ColorScheme::RGBA;
00235 }
00236
00237 m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00238 new ColorScheme( name, description, NULL, colors, mode )
00239 )
00240 );
00241 }
00242
00243 void WDataSetFibers::removeColorScheme( WDataSetFibers::ColorArray colors )
00244 {
00245
00246 WItemSelection::WriteTicket l = m_colors->getWriteTicket();
00247
00248 WItemSelection::Iterator i = l->get().begin();
00249 while( i != l->get().end() )
00250 {
00251 if( boost::shared_static_cast< const ColorScheme >( *i )->getColor() == colors )
00252 {
00253 i = l->get().erase( i );
00254 }
00255 else
00256 {
00257 ++i;
00258 }
00259 }
00260 }
00261
00262 void WDataSetFibers::replaceColorScheme( WDataSetFibers::ColorArray oldColors, WDataSetFibers::ColorArray newColors )
00263 {
00264
00265 WItemSelection::WriteTicket l = m_colors->getWriteTicket();
00266 for( WItemSelection::Iterator i = l->get().begin(); i != l->get().end(); ++i )
00267 {
00268 boost::shared_ptr< ColorScheme > ci = boost::shared_static_cast< ColorScheme >( *i );
00269 if(ci->getColor() == oldColors )
00270 {
00271 ci->setColor( newColors );
00272 }
00273 }
00274 }
00275
00276 const boost::shared_ptr< WDataSetFibers::ColorScheme > WDataSetFibers::getColorScheme( std::string name ) const
00277 {
00278 WItemSelection::ReadTicket l = m_colors->getReadTicket();
00279 WItemSelection::ConstIterator i = std::find_if( l->get().begin(), l->get().end(),
00280 WPredicateHelper::Name< boost::shared_ptr< WItemSelectionItem > >( name )
00281 );
00282 if( i == l->get().end() )
00283 {
00284 throw WDHNoSuchDataSet( std::string( "Color scheme with specified name could not be found." ) );
00285 }
00286
00287 return boost::shared_static_cast< ColorScheme >( *i );
00288 }
00289
00290 const boost::shared_ptr< WDataSetFibers::ColorScheme > WDataSetFibers::getColorScheme( size_t idx ) const
00291 {
00292 WItemSelection::ReadTicket l = m_colors->getReadTicket();
00293 return boost::shared_static_cast< ColorScheme >( l->get()[ idx ] );
00294 }
00295
00296 const boost::shared_ptr< WDataSetFibers::ColorScheme > WDataSetFibers::getColorScheme() const
00297 {
00298 return boost::shared_static_cast< ColorScheme >( m_colorProp->get().at( 0 ) );
00299 }
00300
00301 const WPropSelection WDataSetFibers::getColorSchemeProperty() const
00302 {
00303 return m_colorProp;
00304 }
00305
00306 WPosition WDataSetFibers::getPosition( size_t fiber, size_t vertex ) const
00307 {
00308 size_t index = m_lineStartIndexes->at( fiber ) * 3;
00309 index += vertex * 3;
00310 return WPosition( m_vertices->at( index ), m_vertices->at( index + 1 ), m_vertices->at( index + 2 ) );
00311 }
00312
00313 WPosition WDataSetFibers::getTangent( size_t fiber, size_t vertex ) const
00314 {
00315 WPosition point = getPosition( fiber, vertex );
00316 WPosition tangent;
00317
00318 if( vertex == 0 )
00319 {
00320 WPosition pointNext = getPosition( fiber, vertex + 1 );
00321 tangent = point - pointNext;
00322 }
00323 else if( vertex == m_lineLengths->at( fiber ) - 1 )
00324 {
00325 WPosition pointBefore = getPosition( fiber, vertex - 1 );
00326 tangent = pointBefore - point;
00327 }
00328 else
00329 {
00330 WPosition pointBefore = getPosition( fiber, vertex - 1 );
00331 WPosition pointNext = getPosition( fiber, vertex + 1 );
00332 tangent = pointBefore - pointNext;
00333 }
00334
00335 return normalize( tangent );
00336 }
00337
00338 WBoundingBox WDataSetFibers::getBoundingBox() const
00339 {
00340 return m_bb;
00341 }
00342
00343 WFiber WDataSetFibers::operator[]( size_t numTract ) const
00344 {
00345 WAssert( numTract < m_lineLengths->size(), "WDataSetFibers: out of bounds - invalid tract number requested." );
00346 WFiber result;
00347 result.reserve( ( *m_lineLengths )[ numTract ] );
00348 size_t vIdx = ( *m_lineStartIndexes )[ numTract ] * 3;
00349 for( size_t vertexNum = 0; vertexNum < ( *m_lineLengths )[ numTract ]; ++vertexNum )
00350 {
00351 result.push_back( WPosition( ( *m_vertices )[vIdx], ( *m_vertices )[vIdx + 1], ( *m_vertices )[vIdx + 2] ) );
00352 vIdx += 3;
00353 }
00354 return result;
00355 }