WROIBox.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 <string>
00026 #include <utility>
00027 
00028 #include <osg/LineWidth>
00029 #include <osg/LightModel>
00030 
00031 #include "WROIBox.h"
00032 #include "WGraphicsEngine.h"
00033 #include "WGEUtils.h"
00034 
00035 size_t WROIBox::maxBoxId = 0;
00036 
00037 void buildFacesFromPoints( osg::DrawElementsUInt* surfaceElements )
00038 {
00039     surfaceElements->push_back( 0 );
00040     surfaceElements->push_back( 2 );
00041     surfaceElements->push_back( 3 );
00042     surfaceElements->push_back( 1 );
00043 
00044     surfaceElements->push_back( 2 );
00045     surfaceElements->push_back( 6 );
00046     surfaceElements->push_back( 7 );
00047     surfaceElements->push_back( 3 );
00048 
00049     surfaceElements->push_back( 6 );
00050     surfaceElements->push_back( 4 );
00051     surfaceElements->push_back( 5 );
00052     surfaceElements->push_back( 7 );
00053 
00054     surfaceElements->push_back( 4 );
00055     surfaceElements->push_back( 0 );
00056     surfaceElements->push_back( 1 );
00057     surfaceElements->push_back( 5 );
00058 
00059     surfaceElements->push_back( 1 );
00060     surfaceElements->push_back( 3 );
00061     surfaceElements->push_back( 7 );
00062     surfaceElements->push_back( 5 );
00063 
00064     surfaceElements->push_back( 0 );
00065     surfaceElements->push_back( 4 );
00066     surfaceElements->push_back( 6 );
00067     surfaceElements->push_back( 2 );
00068 }
00069 
00070 void buildLinesFromPoints( osg::DrawElementsUInt* surfaceElements )
00071 {
00072     surfaceElements->push_back( 0 );
00073     surfaceElements->push_back( 2 );
00074     surfaceElements->push_back( 2 );
00075     surfaceElements->push_back( 3 );
00076     surfaceElements->push_back( 3 );
00077     surfaceElements->push_back( 1 );
00078     surfaceElements->push_back( 1 );
00079     surfaceElements->push_back( 0 );
00080 
00081     surfaceElements->push_back( 6 );
00082     surfaceElements->push_back( 4 );
00083     surfaceElements->push_back( 4 );
00084     surfaceElements->push_back( 5 );
00085     surfaceElements->push_back( 5 );
00086     surfaceElements->push_back( 7 );
00087     surfaceElements->push_back( 7 );
00088     surfaceElements->push_back( 6 );
00089 
00090     surfaceElements->push_back( 2 );
00091     surfaceElements->push_back( 6 );
00092     surfaceElements->push_back( 7 );
00093     surfaceElements->push_back( 3 );
00094 
00095     surfaceElements->push_back( 4 );
00096     surfaceElements->push_back( 0 );
00097     surfaceElements->push_back( 1 );
00098     surfaceElements->push_back( 5 );
00099 }
00100 
00101 void setVertices( osg::Vec3Array* vertices, WPosition minPos, WPosition maxPos )
00102 {
00103     vertices->push_back( osg::Vec3( minPos[0], minPos[1], minPos[2] ) );
00104     vertices->push_back( osg::Vec3( minPos[0], minPos[1], maxPos[2] ) );
00105     vertices->push_back( osg::Vec3( minPos[0], maxPos[1], minPos[2] ) );
00106     vertices->push_back( osg::Vec3( minPos[0], maxPos[1], maxPos[2] ) );
00107     vertices->push_back( osg::Vec3( maxPos[0], minPos[1], minPos[2] ) );
00108     vertices->push_back( osg::Vec3( maxPos[0], minPos[1], maxPos[2] ) );
00109     vertices->push_back( osg::Vec3( maxPos[0], maxPos[1], minPos[2] ) );
00110     vertices->push_back( osg::Vec3( maxPos[0], maxPos[1], maxPos[2] ) );
00111 }
00112 
00113 WROIBox::WROIBox( WPosition minPos, WPosition maxPos ) :
00114     WROI(),
00115     boxId( maxBoxId++ ),
00116     m_pickNormal( WVector3d() ),
00117     m_oldPixelPosition( WVector2d::zero() ),
00118     m_color( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) ),
00119     m_notColor( osg::Vec4( 1.0f, 0.0f, 0.0f, 0.4f ) )
00120 {
00121     m_minPos = minPos;
00122     m_maxPos = maxPos;
00123 
00124     boost::shared_ptr< WGraphicsEngine > ge = WGraphicsEngine::getGraphicsEngine();
00125     assert( ge );
00126     boost::shared_ptr< WGEViewer > viewer = ge->getViewerByName( "main" );
00127     assert( viewer );
00128     m_viewer = viewer;
00129     m_pickHandler = m_viewer->getPickHandler();
00130     m_pickHandler->getPickSignal()->connect( boost::bind( &WROIBox::registerRedrawRequest, this, _1 ) );
00131 
00132     m_surfaceGeometry = osg::ref_ptr<osg::Geometry>( new osg::Geometry() );
00133     m_surfaceGeometry->setDataVariance( osg::Object::DYNAMIC );
00134 
00135     //m_geode = osg::ref_ptr<osg::Geode>( new osg::Geode );
00136     std::stringstream ss;
00137     ss << "ROIBox" << boxId;
00138 
00139     setName( ss.str() );
00140     m_surfaceGeometry->setName( ss.str() );
00141 
00142     osg::ref_ptr<osg::Vec3Array> vertices = osg::ref_ptr<osg::Vec3Array>( new osg::Vec3Array );
00143     setVertices( vertices, minPos, maxPos );
00144     m_surfaceGeometry->setVertexArray( vertices );
00145 
00146     osg::DrawElementsUInt* surfaceElements;
00147     surfaceElements = new osg::DrawElementsUInt( osg::PrimitiveSet::QUADS, 0 );
00148     buildFacesFromPoints( surfaceElements );
00149 
00150     osg::DrawElementsUInt* lineElements;
00151     lineElements = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
00152     buildLinesFromPoints( lineElements );
00153 
00154     m_surfaceGeometry->addPrimitiveSet( surfaceElements );
00155     m_surfaceGeometry->addPrimitiveSet( lineElements );
00156     addDrawable( m_surfaceGeometry );
00157     osg::StateSet* state = getOrCreateStateSet();
00158     state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
00159 
00160     osg::LineWidth* linewidth = new osg::LineWidth();
00161     linewidth->setWidth( 2.f );
00162     state->setAttributeAndModes( linewidth, osg::StateAttribute::ON );
00163 
00164     // ------------------------------------------------
00165     // colors
00166     osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
00167 
00168     colors->push_back( osg::Vec4( 0.0f, 0.0f, 1.0f, 0.5f ) );
00169     m_surfaceGeometry->setColorArray( colors );
00170     m_surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00171 
00172     osg::ref_ptr< osg::LightModel > lightModel = new osg::LightModel();
00173     lightModel->setTwoSided( true );
00174     state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
00175     state->setMode( GL_BLEND, osg::StateAttribute::ON );
00176 
00177     m_not->set( false );
00178 
00179     assert( WGraphicsEngine::getGraphicsEngine() );
00180     WGraphicsEngine::getGraphicsEngine()->getScene()->addChild( this );
00181 
00182     setUserData( this );
00183     setUpdateCallback( osg::ref_ptr<ROIBoxNodeCallback>( new ROIBoxNodeCallback ) );
00184 
00185     setDirty();
00186 }
00187 
00188 WROIBox::~WROIBox()
00189 {
00190 //    std::cout << "destructor called" << std::endl;
00191 //    std::cout << "ref count geode: " << m_geode->referenceCount() << std::endl;
00192 //
00193 //    WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_geode );
00194 }
00195 
00196 WPosition WROIBox::getMinPos() const
00197 {
00198     return m_minPos;
00199 }
00200 
00201 WPosition WROIBox::getMaxPos() const
00202 {
00203     return m_maxPos;
00204 }
00205 
00206 void WROIBox::registerRedrawRequest( WPickInfo pickInfo )
00207 {
00208     boost::unique_lock< boost::shared_mutex > lock;
00209     lock = boost::unique_lock< boost::shared_mutex >( m_updateLock );
00210 
00211     m_pickInfo = pickInfo;
00212 
00213     lock.unlock();
00214 }
00215 
00216 void WROIBox::updateGFX()
00217 {
00218     boost::unique_lock< boost::shared_mutex > lock;
00219     lock = boost::unique_lock< boost::shared_mutex >( m_updateLock );
00220 
00221     std::stringstream ss;
00222     ss << "ROIBox" << boxId << "";
00223     if( m_pickInfo.getName() == ss.str() )
00224     {
00225         WVector2d newPixelPos( m_pickInfo.getPickPixel() );
00226         if( m_isPicked )
00227         {
00228             osg::Vec3 in( newPixelPos.x(), newPixelPos.y(), 0.0 );
00229             osg::Vec3 world = wge::unprojectFromScreen( in, m_viewer->getCamera() );
00230 
00231             WPosition newPixelWorldPos( world[0], world[1], world[2] );
00232             WPosition oldPixelWorldPos;
00233             if(  m_oldPixelPosition.x() == 0 && m_oldPixelPosition.y() == 0 )
00234             {
00235                 oldPixelWorldPos = newPixelWorldPos;
00236             }
00237             else
00238             {
00239                 osg::Vec3 in( m_oldPixelPosition.x(), m_oldPixelPosition.y(), 0.0 );
00240                 osg::Vec3 world = wge::unprojectFromScreen( in, m_viewer->getCamera() );
00241                 oldPixelWorldPos = WPosition( world[0], world[1], world[2] );
00242             }
00243 
00244             WVector3d moveVec = newPixelWorldPos - oldPixelWorldPos;
00245 
00246             osg::ref_ptr<osg::Vec3Array> vertices = osg::ref_ptr<osg::Vec3Array>( new osg::Vec3Array );
00247 
00248             // resize Box
00249             if( m_pickInfo.getModifierKey() == WPickInfo::SHIFT )
00250             {
00251                 if( m_pickNormal[0] <= 0 && m_pickNormal[1] <= 0 && m_pickNormal[2] <= 0 )
00252                 {
00253                     m_maxPos += m_pickNormal * dot( moveVec, m_pickNormal );
00254                 }
00255                 if( m_pickNormal[0] >= 0 && m_pickNormal[1] >= 0 && m_pickNormal[2] >= 0 )
00256                 {
00257                     m_minPos += m_pickNormal * dot( moveVec, m_pickNormal );
00258                 }
00259 
00260                 setVertices( vertices, m_minPos, m_maxPos );
00261                 m_surfaceGeometry->setVertexArray( vertices );
00262             }
00263 
00264             // move Box
00265             if( m_pickInfo.getModifierKey() == WPickInfo::NONE )
00266             {
00267                 m_minPos += moveVec;
00268                 m_maxPos += moveVec;
00269                 setVertices( vertices, m_minPos, m_maxPos );
00270                 m_surfaceGeometry->setVertexArray( vertices );
00271             }
00272         }
00273         else
00274         {
00275             m_pickNormal = m_pickInfo.getPickNormal();
00276             // color for moving box
00277             if( m_pickInfo.getModifierKey() == WPickInfo::NONE )
00278             {
00279                 osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
00280                 if( m_not->get() )
00281                 {
00282                     colors->push_back( m_notColor );
00283                 }
00284                 else
00285                 {
00286                     colors->push_back( m_color );
00287                 }
00288                 m_surfaceGeometry->setColorArray( colors );
00289             }
00290             if( m_pickInfo.getModifierKey() == WPickInfo::SHIFT )
00291             {
00292                 osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
00293                 colors->push_back( osg::Vec4( 0.0f, 1.0f, 0.0f, 0.4f ) );
00294                 m_surfaceGeometry->setColorArray( colors );
00295             }
00296         }
00297         m_oldPixelPosition = newPixelPos;
00298         setDirty();
00299         m_isPicked = true;
00300 
00301         signalRoiChange();
00302     }
00303     if( m_isPicked && m_pickInfo.getName() == "unpick" )
00304     {
00305         // Perform all actions necessary for finishing a pick
00306 
00307         osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
00308         if( m_not->get() )
00309         {
00310             colors->push_back( m_notColor );
00311         }
00312         else
00313         {
00314             colors->push_back( m_color );
00315         }
00316         m_surfaceGeometry->setColorArray( colors );
00317         m_pickNormal = WVector3d();
00318         m_isPicked = false;
00319     }
00320 
00321     if( m_dirty->get() )
00322     {
00323         osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
00324         if( m_not->get() )
00325         {
00326             colors->push_back( m_notColor );
00327         }
00328         else
00329         {
00330             colors->push_back( m_color );
00331         }
00332         m_surfaceGeometry->setColorArray( colors );
00333     }
00334 
00335     lock.unlock();
00336 }
00337 
00338 void WROIBox::setColor( osg::Vec4 color )
00339 {
00340     m_color = color;
00341 }
00342 
00343 void WROIBox::setNotColor( osg::Vec4 color )
00344 {
00345     m_notColor = color;
00346 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends