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 <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
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
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
00191
00192
00193
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
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
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
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
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 }