OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WROIBox.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <string>
26 #include <utility>
27 
28 #include <osg/LineWidth>
29 #include <osg/LightModel>
30 
31 #include "WROIBox.h"
32 #include "WGraphicsEngine.h"
33 #include "WGEUtils.h"
34 
35 size_t WROIBox::maxBoxId = 0;
36 
37 void buildFacesFromPoints( osg::DrawElementsUInt* surfaceElements )
38 {
39  surfaceElements->push_back( 0 );
40  surfaceElements->push_back( 2 );
41  surfaceElements->push_back( 3 );
42  surfaceElements->push_back( 1 );
43 
44  surfaceElements->push_back( 2 );
45  surfaceElements->push_back( 6 );
46  surfaceElements->push_back( 7 );
47  surfaceElements->push_back( 3 );
48 
49  surfaceElements->push_back( 6 );
50  surfaceElements->push_back( 4 );
51  surfaceElements->push_back( 5 );
52  surfaceElements->push_back( 7 );
53 
54  surfaceElements->push_back( 4 );
55  surfaceElements->push_back( 0 );
56  surfaceElements->push_back( 1 );
57  surfaceElements->push_back( 5 );
58 
59  surfaceElements->push_back( 1 );
60  surfaceElements->push_back( 3 );
61  surfaceElements->push_back( 7 );
62  surfaceElements->push_back( 5 );
63 
64  surfaceElements->push_back( 0 );
65  surfaceElements->push_back( 4 );
66  surfaceElements->push_back( 6 );
67  surfaceElements->push_back( 2 );
68 }
69 
70 void buildLinesFromPoints( osg::DrawElementsUInt* surfaceElements )
71 {
72  surfaceElements->push_back( 0 );
73  surfaceElements->push_back( 2 );
74  surfaceElements->push_back( 2 );
75  surfaceElements->push_back( 3 );
76  surfaceElements->push_back( 3 );
77  surfaceElements->push_back( 1 );
78  surfaceElements->push_back( 1 );
79  surfaceElements->push_back( 0 );
80 
81  surfaceElements->push_back( 6 );
82  surfaceElements->push_back( 4 );
83  surfaceElements->push_back( 4 );
84  surfaceElements->push_back( 5 );
85  surfaceElements->push_back( 5 );
86  surfaceElements->push_back( 7 );
87  surfaceElements->push_back( 7 );
88  surfaceElements->push_back( 6 );
89 
90  surfaceElements->push_back( 2 );
91  surfaceElements->push_back( 6 );
92  surfaceElements->push_back( 7 );
93  surfaceElements->push_back( 3 );
94 
95  surfaceElements->push_back( 4 );
96  surfaceElements->push_back( 0 );
97  surfaceElements->push_back( 1 );
98  surfaceElements->push_back( 5 );
99 }
100 
101 void setVertices( osg::Vec3Array* vertices, WPosition minPos, WPosition maxPos )
102 {
103  vertices->push_back( osg::Vec3( minPos[0], minPos[1], minPos[2] ) );
104  vertices->push_back( osg::Vec3( minPos[0], minPos[1], maxPos[2] ) );
105  vertices->push_back( osg::Vec3( minPos[0], maxPos[1], minPos[2] ) );
106  vertices->push_back( osg::Vec3( minPos[0], maxPos[1], maxPos[2] ) );
107  vertices->push_back( osg::Vec3( maxPos[0], minPos[1], minPos[2] ) );
108  vertices->push_back( osg::Vec3( maxPos[0], minPos[1], maxPos[2] ) );
109  vertices->push_back( osg::Vec3( maxPos[0], maxPos[1], minPos[2] ) );
110  vertices->push_back( osg::Vec3( maxPos[0], maxPos[1], maxPos[2] ) );
111 }
112 
114  WROI(),
115  boxId( maxBoxId++ ),
116  m_pickNormal( WVector3d() ),
117  m_oldPixelPosition( WVector2d::zero() ),
118  m_color( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) ),
119  m_notColor( osg::Vec4( 1.0f, 0.0f, 0.0f, 0.4f ) )
120 {
121  m_minPos = minPos;
122  m_maxPos = maxPos;
123 
124  boost::shared_ptr< WGraphicsEngine > ge = WGraphicsEngine::getGraphicsEngine();
125  assert( ge );
126  boost::shared_ptr< WGEViewer > viewer = ge->getViewerByName( "main" );
127  assert( viewer );
128  m_viewer = viewer;
129  m_pickHandler = m_viewer->getPickHandler();
130  m_pickHandler->getPickSignal()->connect( boost::bind( &WROIBox::registerRedrawRequest, this, _1 ) );
131 
132  m_surfaceGeometry = osg::ref_ptr<osg::Geometry>( new osg::Geometry() );
133  m_surfaceGeometry->setDataVariance( osg::Object::DYNAMIC );
134 
135  //m_geode = osg::ref_ptr<osg::Geode>( new osg::Geode );
136  std::stringstream ss;
137  ss << "ROIBox" << boxId;
138 
139  setName( ss.str() );
140  m_surfaceGeometry->setName( ss.str() );
141 
142  osg::ref_ptr<osg::Vec3Array> vertices = osg::ref_ptr<osg::Vec3Array>( new osg::Vec3Array );
143  setVertices( vertices, minPos, maxPos );
144  m_surfaceGeometry->setVertexArray( vertices );
145 
146  osg::DrawElementsUInt* surfaceElements;
147  surfaceElements = new osg::DrawElementsUInt( osg::PrimitiveSet::QUADS, 0 );
148  buildFacesFromPoints( surfaceElements );
149 
150  osg::DrawElementsUInt* lineElements;
151  lineElements = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
152  buildLinesFromPoints( lineElements );
153 
154  m_surfaceGeometry->addPrimitiveSet( surfaceElements );
155  m_surfaceGeometry->addPrimitiveSet( lineElements );
156  addDrawable( m_surfaceGeometry );
157  osg::StateSet* state = getOrCreateStateSet();
158  state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
159 
160  osg::LineWidth* linewidth = new osg::LineWidth();
161  linewidth->setWidth( 2.f );
162  state->setAttributeAndModes( linewidth, osg::StateAttribute::ON );
163 
164  // ------------------------------------------------
165  // colors
166  osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
167 
168  colors->push_back( osg::Vec4( 0.0f, 0.0f, 1.0f, 0.5f ) );
169  m_surfaceGeometry->setColorArray( colors );
170  m_surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
171 
172  osg::ref_ptr< osg::LightModel > lightModel = new osg::LightModel();
173  lightModel->setTwoSided( true );
174  state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
175  state->setMode( GL_BLEND, osg::StateAttribute::ON );
176 
177  m_not->set( false );
178 
180  WGraphicsEngine::getGraphicsEngine()->getScene()->addChild( this );
181 
182  setUserData( this );
183  setUpdateCallback( osg::ref_ptr<ROIBoxNodeCallback>( new ROIBoxNodeCallback ) );
184 
185  setDirty();
186 }
187 
188 WROIBox::~WROIBox()
189 {
190 // std::cout << "destructor called" << std::endl;
191 // std::cout << "ref count geode: " << m_geode->referenceCount() << std::endl;
192 //
193 // WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_geode );
194 }
195 
197 {
198  return m_minPos;
199 }
200 
202 {
203  return m_maxPos;
204 }
205 
207 {
208  boost::unique_lock< boost::shared_mutex > lock;
209  lock = boost::unique_lock< boost::shared_mutex >( m_updateLock );
210 
211  m_pickInfo = pickInfo;
212 
213  lock.unlock();
214 }
215 
217 {
218  boost::unique_lock< boost::shared_mutex > lock;
219  lock = boost::unique_lock< boost::shared_mutex >( m_updateLock );
220 
221  std::stringstream ss;
222  ss << "ROIBox" << boxId << "";
223  if( m_pickInfo.getName() == ss.str() )
224  {
225  WVector2d newPixelPos( m_pickInfo.getPickPixel() );
226  if( m_isPicked )
227  {
228  osg::Vec3 in( newPixelPos.x(), newPixelPos.y(), 0.0 );
229  osg::Vec3 world = wge::unprojectFromScreen( in, m_viewer->getCamera() );
230 
231  WPosition newPixelWorldPos( world[0], world[1], world[2] );
232  WPosition oldPixelWorldPos;
233  if( m_oldPixelPosition.x() == 0 && m_oldPixelPosition.y() == 0 )
234  {
235  oldPixelWorldPos = newPixelWorldPos;
236  }
237  else
238  {
239  osg::Vec3 in( m_oldPixelPosition.x(), m_oldPixelPosition.y(), 0.0 );
240  osg::Vec3 world = wge::unprojectFromScreen( in, m_viewer->getCamera() );
241  oldPixelWorldPos = WPosition( world[0], world[1], world[2] );
242  }
243 
244  WVector3d moveVec = newPixelWorldPos - oldPixelWorldPos;
245 
246  osg::ref_ptr<osg::Vec3Array> vertices = osg::ref_ptr<osg::Vec3Array>( new osg::Vec3Array );
247 
248  // resize Box
249  if( m_pickInfo.getModifierKey() == WPickInfo::SHIFT )
250  {
251  if( m_pickNormal[0] <= 0 && m_pickNormal[1] <= 0 && m_pickNormal[2] <= 0 )
252  {
253  m_maxPos += m_pickNormal * dot( moveVec, m_pickNormal );
254  }
255  if( m_pickNormal[0] >= 0 && m_pickNormal[1] >= 0 && m_pickNormal[2] >= 0 )
256  {
257  m_minPos += m_pickNormal * dot( moveVec, m_pickNormal );
258  }
259 
260  setVertices( vertices, m_minPos, m_maxPos );
261  m_surfaceGeometry->setVertexArray( vertices );
262  }
263 
264  // move Box
265  if( m_pickInfo.getModifierKey() == WPickInfo::NONE )
266  {
267  m_minPos += moveVec;
268  m_maxPos += moveVec;
269  setVertices( vertices, m_minPos, m_maxPos );
270  m_surfaceGeometry->setVertexArray( vertices );
271  }
272  }
273  else
274  {
276  // color for moving box
277  if( m_pickInfo.getModifierKey() == WPickInfo::NONE )
278  {
279  osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
280  if( m_not->get() )
281  {
282  colors->push_back( m_notColor );
283  }
284  else
285  {
286  colors->push_back( m_color );
287  }
288  m_surfaceGeometry->setColorArray( colors );
289  }
290  if( m_pickInfo.getModifierKey() == WPickInfo::SHIFT )
291  {
292  osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
293  colors->push_back( osg::Vec4( 0.0f, 1.0f, 0.0f, 0.4f ) );
294  m_surfaceGeometry->setColorArray( colors );
295  }
296  }
297  m_oldPixelPosition = newPixelPos;
298  setDirty();
299  m_isPicked = true;
300 
301  signalRoiChange();
302  }
303  if( m_isPicked && m_pickInfo.getName() == "unpick" )
304  {
305  // Perform all actions necessary for finishing a pick
306 
307  osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
308  if( m_not->get() )
309  {
310  colors->push_back( m_notColor );
311  }
312  else
313  {
314  colors->push_back( m_color );
315  }
316  m_surfaceGeometry->setColorArray( colors );
318  m_isPicked = false;
319  }
320 
321  if( m_dirty->get() )
322  {
323  osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
324  if( m_not->get() )
325  {
326  colors->push_back( m_notColor );
327  }
328  else
329  {
330  colors->push_back( m_color );
331  }
332  m_surfaceGeometry->setColorArray( colors );
333  }
334 
335  lock.unlock();
336 }
337 
338 void WROIBox::setColor( osg::Vec4 color )
339 {
340  m_color = color;
341 }
342 
343 void WROIBox::setNotColor( osg::Vec4 color )
344 {
345  m_notColor = color;
346 }