OpenWalnut 1.2.5
|
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 }