OpenWalnut  1.4.0
WDataSetFibers.cpp
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 <algorithm>
00026 #include <string>
00027 #include <utility>
00028 #include <vector>
00029 
00030 #include "../common/datastructures/WFiber.h"
00031 #include "../common/WBoundingBox.h"
00032 #include "../common/WColor.h"
00033 #include "../common/WLogger.h"
00034 #include "../common/WPredicateHelper.h"
00035 #include "../common/WPropertyHelper.h"
00036 #include "../graphicsEngine/WGEUtils.h"
00037 #include "exceptions/WDHNoSuchDataSet.h"
00038 #include "WCreateColorArraysThread.h"
00039 #include "WDataSet.h"
00040 #include "WDataSetFibers.h"
00041 
00042 // prototype instance as singleton
00043 boost::shared_ptr< WPrototyped > WDataSetFibers::m_prototype = boost::shared_ptr< WPrototyped >();
00044 
00045 WDataSetFibers::WDataSetFibers()
00046     : WDataSet()
00047 {
00048     // default constructor used by the prototype mechanism
00049 }
00050 
00051 WDataSetFibers::WDataSetFibers( WDataSetFibers::VertexArray vertices,
00052                 WDataSetFibers::IndexArray lineStartIndexes,
00053                 WDataSetFibers::LengthArray lineLengths,
00054                 WDataSetFibers::IndexArray verticesReverse,
00055                 WBoundingBox boundingBox )
00056     : WDataSet(),
00057       m_vertices( vertices ),
00058       m_lineStartIndexes( lineStartIndexes ),
00059       m_lineLengths( lineLengths ),
00060       m_verticesReverse( verticesReverse ),
00061       m_bb( boundingBox )
00062 {
00063     WAssert( m_vertices->size() % 3 == 0,  "Invalid vertex array."  );
00064     init();
00065 }
00066 
00067 WDataSetFibers::WDataSetFibers( WDataSetFibers::VertexArray vertices,
00068                 WDataSetFibers::IndexArray lineStartIndexes,
00069                 WDataSetFibers::LengthArray lineLengths,
00070                 WDataSetFibers::IndexArray verticesReverse )
00071     : WDataSet(),
00072       m_vertices( vertices ),
00073       m_lineStartIndexes( lineStartIndexes ),
00074       m_lineLengths( lineLengths ),
00075       m_verticesReverse( verticesReverse )
00076 {
00077     WAssert( m_vertices->size() % 3 == 0,  "Invalid vertex array."  );
00078     // determine bounding box
00079     for( size_t i = 0; i < vertices->size()/3; ++i )
00080     {
00081         m_bb.expandBy( (*vertices)[ 3 * i + 0 ], (*vertices)[ 3 * i + 1 ], (*vertices)[ 3 * i + 2 ] );
00082     }
00083     // remaining initilisation
00084     init();
00085 }
00086 
00087 WDataSetFibers::WDataSetFibers( WDataSetFibers::VertexArray vertices,
00088                 WDataSetFibers::IndexArray lineStartIndexes,
00089                 WDataSetFibers::LengthArray lineLengths,
00090                 WDataSetFibers::IndexArray verticesReverse,
00091                 WBoundingBox boundingBox,
00092                 WDataSetFibers::VertexParemeterArray vertexParameters )
00093     : WDataSet(),
00094       m_vertices( vertices ),
00095       m_lineStartIndexes( lineStartIndexes ),
00096       m_lineLengths( lineLengths ),
00097       m_verticesReverse( verticesReverse ),
00098       m_bb( boundingBox ),
00099       m_vertexParameters( vertexParameters )
00100 {
00101     WAssert( m_vertices->size() % 3 == 0,  "Invalid vertex array."  );
00102     init();
00103 }
00104 
00105 WDataSetFibers::WDataSetFibers( WDataSetFibers::VertexArray vertices,
00106                 WDataSetFibers::IndexArray lineStartIndexes,
00107                 WDataSetFibers::LengthArray lineLengths,
00108                 WDataSetFibers::IndexArray verticesReverse,
00109                 WDataSetFibers::VertexParemeterArray vertexParameters )
00110     : WDataSet(),
00111       m_vertices( vertices ),
00112       m_lineStartIndexes( lineStartIndexes ),
00113       m_lineLengths( lineLengths ),
00114       m_verticesReverse( verticesReverse ),
00115       m_vertexParameters( vertexParameters )
00116 {
00117     WAssert( m_vertices->size() % 3 == 0,  "Invalid vertex array."  );
00118     // determine bounding box
00119     for( size_t i = 0; i < vertices->size()/3; ++i )
00120     {
00121         m_bb.expandBy( (*vertices)[ 3 * i + 0 ], (*vertices)[ 3 * i + 1 ], (*vertices)[ 3 * i + 2 ] );
00122     }
00123     // remaining initilisation
00124     init();
00125 }
00126 
00127 void WDataSetFibers::init()
00128 {
00129     size_t size = m_vertices->size();
00130     m_tangents = boost::shared_ptr< std::vector< float > >( new std::vector<float>( size ) );
00131 
00132     boost::shared_ptr< std::vector< float > > globalColors( new std::vector<float>( size ) );
00133     boost::shared_ptr< std::vector< float > > localColors( new std::vector<float>( size ) );
00134     boost::shared_ptr< std::vector< float > > customColors( new std::vector<float>( size ) );
00135 
00136     // TODO(all): use the new WThreadedJobs functionality
00137     WCreateColorArraysThread* t1 = new WCreateColorArraysThread( 0, m_lineLengths->size()/4, m_vertices,
00138             m_lineLengths, globalColors, localColors, m_tangents );
00139     WCreateColorArraysThread* t2 = new WCreateColorArraysThread( m_lineLengths->size()/4+1, m_lineLengths->size()/2, m_vertices,
00140             m_lineLengths, globalColors, localColors, m_tangents );
00141     WCreateColorArraysThread* t3 = new WCreateColorArraysThread( m_lineLengths->size()/2+1, m_lineLengths->size()/4*3, m_vertices,
00142             m_lineLengths, globalColors, localColors, m_tangents );
00143     WCreateColorArraysThread* t4 = new WCreateColorArraysThread( m_lineLengths->size()/4*3+1, m_lineLengths->size()-1, m_vertices,
00144             m_lineLengths, globalColors, localColors, m_tangents );
00145     t1->run();
00146     t2->run();
00147     t3->run();
00148     t4->run();
00149 
00150     t1->wait();
00151     t2->wait();
00152     t3->wait();
00153     t4->wait();
00154 
00155     delete t1;
00156     delete t2;
00157     delete t3;
00158     delete t4;
00159 
00160     // add both arrays to m_colors
00161     m_colors = boost::shared_ptr< WItemSelection >( new WItemSelection() );
00162     m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00163             new ColorScheme( "Global Color", "Colors direction by using start and end vertex per fiber.", NULL, globalColors, ColorScheme::RGB )
00164         )
00165     );
00166     m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00167             new ColorScheme( "Local Color", "Colors direction by using start and end vertex per segment.", NULL, localColors, ColorScheme::RGB )
00168         )
00169     );
00170 
00171     for( size_t i = 0; i < size; ++i )
00172     {
00173         ( *customColors )[i] = ( *globalColors )[i];
00174     }
00175     m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00176             new ColorScheme( "Custom Color", "Colors copied from the global colors, will be used for bundle coloring.",
00177                     NULL, customColors, ColorScheme::RGB )
00178         )
00179     );
00180 
00181     // the colors can be selected by properties
00182     m_colorProp = m_properties->addProperty( "Color Scheme", "Determines the coloring scheme to use for this data.", m_colors->getSelectorFirst() );
00183     WPropertyHelper::PC_SELECTONLYONE::addTo( m_colorProp );
00184     WPropertyHelper::PC_NOTEMPTY::addTo( m_colorProp );
00185     m_infoProperties->addProperty( "#Fibers", "The number of fibers", static_cast< WPVBaseTypes::PV_INT >( m_lineLengths->size() ) );
00186     m_infoProperties->addProperty( "#Vertices", "The number of vertices", static_cast< WPVBaseTypes::PV_INT >( m_vertices->size() ) );
00187 }
00188 
00189 bool WDataSetFibers::isTexture() const
00190 {
00191     return false;
00192 }
00193 
00194 size_t WDataSetFibers::size() const
00195 {
00196     return m_lineStartIndexes->size();
00197 }
00198 
00199 const std::string WDataSetFibers::getName() const
00200 {
00201     return "WDataSetFibers";
00202 }
00203 
00204 const std::string WDataSetFibers::getDescription() const
00205 {
00206     return "Contains tracked fiber data.";
00207 }
00208 
00209 boost::shared_ptr< WPrototyped > WDataSetFibers::getPrototype()
00210 {
00211     if( !m_prototype )
00212     {
00213         m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetFibers() );
00214     }
00215 
00216     return m_prototype;
00217 }
00218 
00219 WDataSetFibers::VertexArray WDataSetFibers::getVertices() const
00220 {
00221     return m_vertices;
00222 }
00223 
00224 WDataSetFibers::IndexArray WDataSetFibers::getLineStartIndexes() const
00225 {
00226     return m_lineStartIndexes;
00227 }
00228 
00229 WDataSetFibers::LengthArray WDataSetFibers::getLineLengths() const
00230 {
00231     return m_lineLengths;
00232 }
00233 
00234 WDataSetFibers::IndexArray WDataSetFibers::getVerticesReverse() const
00235 {
00236     return m_verticesReverse;
00237 }
00238 
00239 WDataSetFibers::TangentArray WDataSetFibers::getTangents() const
00240 {
00241     return m_tangents;
00242 }
00243 
00244 void WDataSetFibers::addColorScheme( WDataSetFibers::ColorArray colors, std::string name, std::string description )
00245 {
00246     ColorScheme::ColorMode mode = ColorScheme::GRAY;
00247 
00248     // number of verts is needed to distinguish color mode.
00249     size_t verts = m_vertices->size() / 3;
00250     size_t cols  = colors->size();
00251     if( cols / verts == 3 )
00252     {
00253         mode = ColorScheme::RGB;
00254     }
00255     else if( cols / verts == 4 )
00256     {
00257         mode = ColorScheme::RGBA;
00258     }
00259 
00260     m_colors->push_back( boost::shared_ptr< WItemSelectionItem >(
00261         new ColorScheme( name, description, NULL, colors, mode )
00262         )
00263     );
00264 }
00265 
00266 void WDataSetFibers::removeColorScheme( WDataSetFibers::ColorArray colors )
00267 {
00268     // this is nearly the same like std::remove_if
00269     WItemSelection::WriteTicket l = m_colors->getWriteTicket();
00270 
00271     WItemSelection::Iterator i = l->get().begin();
00272     while( i != l->get().end() )
00273     {
00274         if( boost::static_pointer_cast< const ColorScheme >( *i )->getColor() == colors )
00275         {
00276             i = l->get().erase( i );
00277         }
00278         else
00279         {
00280             ++i;
00281         }
00282     }
00283 }
00284 
00285 void WDataSetFibers::replaceColorScheme( WDataSetFibers::ColorArray oldColors, WDataSetFibers::ColorArray newColors )
00286 {
00287     // this is nearly the same as std::replace_if
00288     WItemSelection::WriteTicket l = m_colors->getWriteTicket();
00289     for( WItemSelection::Iterator i = l->get().begin(); i != l->get().end(); ++i )
00290     {
00291         boost::shared_ptr< ColorScheme > ci = boost::static_pointer_cast< ColorScheme >( *i );
00292         if(ci->getColor() == oldColors )
00293         {
00294             ci->setColor( newColors );
00295         }
00296     }
00297 }
00298 
00299 const boost::shared_ptr< WDataSetFibers::ColorScheme > WDataSetFibers::getColorScheme( std::string name ) const
00300 {
00301     WItemSelection::ReadTicket l = m_colors->getReadTicket();
00302     WItemSelection::ConstIterator i = std::find_if( l->get().begin(), l->get().end(),
00303             WPredicateHelper::Name< boost::shared_ptr< WItemSelectionItem > >( name )
00304     );
00305     if( i == l->get().end() )
00306     {
00307         throw WDHNoSuchDataSet( std::string( "Color scheme with specified name could not be found." ) );
00308     }
00309 
00310     return boost::static_pointer_cast< ColorScheme >( *i );
00311 }
00312 
00313 const boost::shared_ptr< WDataSetFibers::ColorScheme > WDataSetFibers::getColorScheme( size_t idx ) const
00314 {
00315     WItemSelection::ReadTicket l = m_colors->getReadTicket();
00316     return boost::static_pointer_cast< ColorScheme >( l->get()[ idx ] );
00317 }
00318 
00319 const boost::shared_ptr< WDataSetFibers::ColorScheme > WDataSetFibers::getColorScheme() const
00320 {
00321     return boost::static_pointer_cast< ColorScheme >( m_colorProp->get().at( 0 ) );
00322 }
00323 
00324 const WPropSelection WDataSetFibers::getColorSchemeProperty() const
00325 {
00326     return m_colorProp;
00327 }
00328 
00329 WDataSetFibers::VertexParemeterArray WDataSetFibers::getVertexParameters() const
00330 {
00331     return m_vertexParameters;
00332 }
00333 
00334 WPosition WDataSetFibers::getPosition( size_t fiber, size_t vertex ) const
00335 {
00336     size_t index = m_lineStartIndexes->at( fiber ) * 3;
00337     index += vertex * 3;
00338     return WPosition( m_vertices->at( index ), m_vertices->at( index + 1 ), m_vertices->at( index + 2 ) );
00339 }
00340 
00341 WPosition WDataSetFibers::getTangent( size_t fiber, size_t vertex ) const
00342 {
00343     WPosition point = getPosition( fiber, vertex );
00344     WPosition tangent;
00345 
00346     if( vertex == 0 ) // first point
00347     {
00348         WPosition pointNext = getPosition( fiber, vertex + 1 );
00349         tangent = point - pointNext;
00350     }
00351     else if( vertex == m_lineLengths->at( fiber ) - 1 ) // last point
00352     {
00353         WPosition pointBefore = getPosition( fiber, vertex - 1 );
00354         tangent = pointBefore - point;
00355     }
00356     else // somewhere in between
00357     {
00358         WPosition pointBefore = getPosition( fiber, vertex - 1 );
00359         WPosition pointNext = getPosition( fiber, vertex + 1 );
00360         tangent = pointBefore - pointNext;
00361     }
00362 
00363     return normalize( tangent );
00364 }
00365 
00366 WBoundingBox WDataSetFibers::getBoundingBox() const
00367 {
00368     return m_bb;
00369 }
00370 
00371 WFiber WDataSetFibers::operator[]( size_t numTract ) const
00372 {
00373     WAssert( numTract < m_lineLengths->size(), "WDataSetFibers: out of bounds - invalid tract number requested." );
00374     WFiber result;
00375     result.reserve( ( *m_lineLengths )[ numTract ] );
00376     size_t vIdx = ( *m_lineStartIndexes )[ numTract ] * 3;
00377     for( size_t vertexNum = 0; vertexNum < ( *m_lineLengths )[ numTract ]; ++vertexNum )
00378     {
00379         result.push_back( WPosition( ( *m_vertices )[vIdx], ( *m_vertices )[vIdx + 1], ( *m_vertices )[vIdx + 2]  ) );
00380         vIdx += 3;
00381     }
00382     return result;
00383 }
00384 
00385 WDataSetFibers::const_iterator WDataSetFibers::begin() const
00386 {
00387     return WFiberIterator( this, 0 );
00388 }
00389 
00390 WDataSetFibers::const_iterator WDataSetFibers::end() const
00391 {
00392     return WFiberIterator( this, m_lineLengths->size() );
00393 }
00394 
00395 WFiberIterator::WFiberIterator()
00396     : m_fibers( NULL ),
00397       m_index( 0 )
00398 {
00399 }
00400 
00401 WFiberIterator::WFiberIterator( WDataSetFibers const* fibers, std::size_t idx )
00402     : m_fibers( fibers ),
00403       m_index( idx )
00404 {
00405 }
00406 
00407 WFiberIterator::WFiberIterator( WFiberIterator const& iter )
00408     : m_fibers( iter.m_fibers ),
00409       m_index( iter.m_index )
00410 {
00411 }
00412 
00413 WFiberIterator::~WFiberIterator()
00414 {
00415 }
00416 
00417 WFiberIterator& WFiberIterator::operator= ( WFiberIterator const& iter )
00418 {
00419     if( this == &iter )
00420     {
00421         return *this;
00422     }
00423 
00424     m_fibers = iter.m_fibers;
00425     m_index = iter.m_index;
00426 
00427     return *this;
00428 }
00429 
00430 WFiberIterator& WFiberIterator::operator++()
00431 {
00432     ++m_index;
00433     return *this;
00434 }
00435 
00436 WFiberIterator WFiberIterator::operator++( int )
00437 {
00438     WFiberIterator t( m_fibers, m_index );
00439     ++m_index;
00440     return t;
00441 }
00442 
00443 WFiberIterator& WFiberIterator::operator--()
00444 {
00445     --m_index;
00446     return *this;
00447 }
00448 
00449 WFiberIterator WFiberIterator::operator--( int )
00450 {
00451     WFiberIterator t( m_fibers, m_index );
00452     --m_index;
00453     return t;
00454 }
00455 
00456 bool WFiberIterator::operator==( WFiberIterator const& rhs ) const
00457 {
00458     return m_fibers == rhs.m_fibers && m_index == rhs.m_index;
00459 }
00460 
00461 bool WFiberIterator::operator!=( WFiberIterator const& rhs ) const
00462 {
00463     return !( this->operator==( rhs ) );
00464 }
00465 
00466 std::size_t WFiberIterator::numPoints() const
00467 {
00468     WAssert( m_index < m_fibers->getLineLengths()->size(), "" );
00469 
00470     return m_fibers->getLineLengths()->operator[] ( m_index );
00471 }
00472 
00473 WFiberPointsIterator WFiberIterator::begin()
00474 {
00475     return WFiberPointsIterator( m_fibers, m_index, 0 );
00476 }
00477 
00478 WFiberPointsIterator WFiberIterator::end()
00479 {
00480     WAssert( numPoints() != 0, "" );
00481 
00482     return WFiberPointsIterator( m_fibers, m_index, numPoints() );
00483 }
00484 
00485 WFiberPointsIterator WFiberIterator::rbegin()
00486 {
00487     return WFiberPointsIterator( m_fibers, m_index, 0, true );
00488 }
00489 
00490 WFiberPointsIterator WFiberIterator::rend()
00491 {
00492     WAssert( numPoints() != 0, "" );
00493 
00494     return WFiberPointsIterator( m_fibers, m_index, numPoints(), true );
00495 }
00496 
00497 std::size_t WFiberIterator::getLineStartIndex() const
00498 {
00499     return m_fibers->getLineStartIndexes()->operator[]( getIndex() );
00500 }
00501 
00502 std::size_t WFiberIterator::getIndex() const
00503 {
00504     return m_index;
00505 }
00506 
00507 WFiberPointsIterator::WFiberPointsIterator()
00508     : m_fibers( NULL ),
00509       m_fiberIndex( 0 ),
00510       m_index( 0 ),
00511       m_reverse( false )
00512 {
00513 }
00514 
00515 WFiberPointsIterator::WFiberPointsIterator( WDataSetFibers const* fibers, std::size_t fbIdx, std::size_t idx, bool reverse )
00516     : m_fibers( fibers ),
00517       m_fiberIndex( fbIdx ),
00518       m_index( idx ),
00519       m_reverse( reverse )
00520 {
00521 }
00522 
00523 WFiberPointsIterator::WFiberPointsIterator( WFiberPointsIterator const& iter )
00524     : m_fibers( iter.m_fibers ),
00525       m_fiberIndex( iter.m_fiberIndex ),
00526       m_index( iter.m_index ),
00527       m_reverse( iter.m_reverse )
00528 {
00529 }
00530 
00531 WFiberPointsIterator::~WFiberPointsIterator()
00532 {
00533 }
00534 
00535 WFiberPointsIterator& WFiberPointsIterator::operator=( WFiberPointsIterator const& iter )
00536 {
00537     if( this == &iter )
00538     {
00539         return *this;
00540     }
00541 
00542     m_fibers = iter.m_fibers;
00543     m_fiberIndex = iter.m_fiberIndex;
00544     m_index = iter.m_index;
00545     m_reverse = iter.m_reverse;
00546 
00547     return *this;
00548 }
00549 
00550 WFiberPointsIterator& WFiberPointsIterator::operator++()
00551 {
00552     ++m_index;
00553     return *this;
00554 }
00555 
00556 WFiberPointsIterator WFiberPointsIterator::operator++( int )
00557 {
00558     WFiberPointsIterator t( m_fibers, m_fiberIndex, m_index, m_reverse );
00559     ++m_index;
00560     return t;
00561 }
00562 
00563 WFiberPointsIterator& WFiberPointsIterator::operator--()
00564 {
00565     --m_index;
00566     return *this;
00567 }
00568 
00569 WFiberPointsIterator WFiberPointsIterator::operator--( int )
00570 {
00571     WFiberPointsIterator t( m_fibers, m_fiberIndex, m_index, m_reverse );
00572     --m_index;
00573     return t;
00574 }
00575 
00576 std::size_t WFiberPointsIterator::getBaseIndex() const
00577 {
00578     WAssert( m_fibers, "" );
00579     WAssert( m_fiberIndex < m_fibers->getLineLengths()->size(), "" );
00580     WAssert( m_index < m_fibers->getLineLengths()->operator[] ( m_fiberIndex ), "" );
00581 
00582     std::size_t i = m_index;
00583     if( m_reverse )
00584     {
00585         i = m_fibers->getLineLengths()->operator[] ( m_fiberIndex ) - i - 1;
00586     }
00587     return m_fibers->getLineStartIndexes()->operator[] ( m_fiberIndex ) + i;
00588 }
00589 
00590 WPosition WFiberPointsIterator::operator*()
00591 {
00592     std::size_t v = getBaseIndex();
00593     return WPosition( m_fibers->getVertices()->operator[]( 3 * v + 0 ),
00594                       m_fibers->getVertices()->operator[]( 3 * v + 1 ),
00595                       m_fibers->getVertices()->operator[]( 3 * v + 2 ) );
00596 }
00597 
00598 bool WFiberPointsIterator::operator==( WFiberPointsIterator const& rhs ) const
00599 {
00600     if( m_reverse != rhs.m_reverse )
00601     {
00602         wlog::warn( "FiberPointsIterator" ) << "Comparing a reverse and a normal iterator!";
00603     }
00604 
00605     return m_fibers == rhs.m_fibers && m_fiberIndex == rhs.m_fiberIndex && m_index == rhs.m_index && m_reverse == rhs.m_reverse;
00606 }
00607 
00608 bool WFiberPointsIterator::operator!=( WFiberPointsIterator const& rhs ) const
00609 {
00610     return !( this->operator==( rhs ) );
00611 }
00612 
00613 double WFiberPointsIterator::getParameter( double def ) const
00614 {
00615     if( m_fibers->getVertexParameters() )
00616     {
00617         return m_fibers->getVertexParameters()->operator[]( getBaseIndex() );
00618     }
00619     return def;
00620 }
00621 
00622 WPosition WFiberPointsIterator::getTangent() const
00623 {
00624     std::size_t v = getBaseIndex();
00625     return WPosition( m_fibers->getTangents()->operator[]( 3 * v + 0 ),
00626                       m_fibers->getTangents()->operator[]( 3 * v + 1 ),
00627                       m_fibers->getTangents()->operator[]( 3 * v + 2 ) );
00628 }
00629 
00630 
00631 WColor WFiberPointsIterator::getColor( const boost::shared_ptr< WDataSetFibers::ColorScheme > scheme ) const
00632 {
00633     std::size_t v = getBaseIndex();
00634     WColor ret;
00635     switch( scheme->getMode() )
00636     {
00637         case WDataSetFibers::ColorScheme::GRAY:
00638             {
00639                 double r = scheme->getColor()->operator[]( 1 * v + 0 );
00640                 ret.set( r, r, r, 1.0 );
00641             }
00642             break;
00643         case WDataSetFibers::ColorScheme::RGB:
00644             {
00645                 double r = scheme->getColor()->operator[]( 3 * v + 0 );
00646                 double g = scheme->getColor()->operator[]( 3 * v + 1 );
00647                 double b = scheme->getColor()->operator[]( 3 * v + 2 );
00648                 ret.set( r, g, b, 1.0 );
00649             }
00650             break;
00651         case WDataSetFibers::ColorScheme::RGBA:
00652             {
00653                 double r = scheme->getColor()->operator[]( 4 * v + 0 );
00654                 double g = scheme->getColor()->operator[]( 4 * v + 1 );
00655                 double b = scheme->getColor()->operator[]( 4 * v + 2 );
00656                 double a = scheme->getColor()->operator[]( 4 * v + 3 );
00657                 ret.set( r, g, b, a );
00658             }
00659             break;
00660         default:
00661             ret.set( 1.0, 1.0, 1.0, 1.0 );
00662             break;
00663     }
00664     return ret;
00665 }
00666 
00667 WColor WFiberPointsIterator::getColor() const
00668 {
00669     return getColor( m_fibers->getColorScheme() );
00670 }
00671 
00672 WColor WFiberPointsIterator::getColor( std::size_t idx ) const
00673 {
00674     return getColor( m_fibers->getColorScheme( idx ) );
00675 }
00676 
00677 WColor WFiberPointsIterator::getColor( std::string name ) const
00678 {
00679     return getColor( m_fibers->getColorScheme( name ) );
00680 }
00681