OpenWalnut  1.3.1
WGEGridNode.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 <sstream>
26 #include <string>
27 
28 #include <osg/LineWidth>
29 
30 #include "../../common/math/linearAlgebra/WLinearAlgebra.h"
31 #include "../callbacks/WGEFunctorCallback.h"
32 #include "../WGEGeodeUtils.h"
33 #include "WGEGridNode.h"
34 
36  m_boundaryGeode( new osg::Geode() ),
37  m_innerGridGeode( new osg::Geode() ),
38  m_labelGeode( new osg::Geode() ),
39  m_gridUpdate( true ),
40  m_gridGeometryUpdate( true ),
41  m_showLabels( true ),
42  m_bbColor( WColor( 0.3, 0.3, 0.3, 1.0 ) ),
43  m_gridColor( WColor( 0.1, 0.1, 0.1, 1.0 ) )
44 {
45  m_grid.getWriteTicket()->get() = grid;
46 
47  // init the boundary geometry
49 
50  // init labels
51  // Therefore: create prototype
52  WGELabel::SPtr label = new WGELabel();
53  label->setAlignment( osgText::Text::CENTER_TOP );
54  label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
55 
56  // add several copies and set position accordingly
57 
58  // Front face ( z = 0 )
59  // bottom left
60  label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) );
61  label->setCharacterSize( 6 );
62  m_labelGeode->addDrawable( label );
63  m_borderLabels[0] = label;
64 
65  // bottom right
66  label = new WGELabel( *label );
67  label->setPosition( osg::Vec3( 1.0, 0.0, 0.0 ) );
68  m_labelGeode->addDrawable( label );
69  m_borderLabels[1] = label;
70 
71  // top right
72  label = new WGELabel( *label );
73  label->setPosition( osg::Vec3( 1.0, 1.0, 0.0 ) );
74  m_labelGeode->addDrawable( label );
75  m_borderLabels[2] = label;
76 
77  // top left
78  label = new WGELabel( *label );
79  label->setPosition( osg::Vec3( 0.0, 1.0, 0.0 ) );
80  m_labelGeode->addDrawable( label );
81  m_borderLabels[3] = label;
82 
83  // Back face ( z = 1 )
84  // bottom left
85  label = new WGELabel( *label );
86  label->setPosition( osg::Vec3( 0.0, 0.0, 1.0 ) );
87  m_labelGeode->addDrawable( label );
88  m_borderLabels[4] = label;
89 
90  // bottom right
91  label = new WGELabel( *label );
92  label->setPosition( osg::Vec3( 1.0, 0.0, 1.0 ) );
93  m_labelGeode->addDrawable( label );
94  m_borderLabels[5] = label;
95 
96  // top right
97  label = new WGELabel( *label );
98  label->setPosition( osg::Vec3( 1.0, 1.0, 1.0 ) );
99  m_labelGeode->addDrawable( label );
100  m_borderLabels[6] = label;
101 
102  // top left
103  label = new WGELabel( *label );
104  label->setPosition( osg::Vec3( 0.0, 1.0, 1.0 ) );
105  m_labelGeode->addDrawable( label );
106  m_borderLabels[7] = label;
107 
108  // add the others too
109  addChild( m_boundaryGeode );
110  addChild( m_innerGridGeode );
111  addChild( m_labelGeode );
112 
113  m_boundaryGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( 4.0 ), osg::StateAttribute::ON );
114 
115  addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WGEGridNode::callback, this, _1 ) ) );
116 
117  // no blending
118  getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::OFF );
119  // disable light for this node
120  getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
121 }
122 
124 {
125  // cleanup
126 }
127 
129 {
130  m_grid.getWriteTicket()->get() = grid;
131  m_gridUpdate = true;
132  m_gridGeometryUpdate = true;
133 }
134 
136 {
137  return m_grid.getReadTicket()->get();
138 }
139 
141 {
142  return m_showLabels;
143 }
144 
145 void WGEGridNode::setEnableLabels( bool enable )
146 {
147  m_showLabels = enable;
148  m_gridUpdate = true;
149 }
150 
152 {
153  return m_showBBox;
154 }
155 
156 void WGEGridNode::setEnableBBox( bool enable )
157 {
158  m_showBBox = enable;
159  m_gridUpdate = true;
160 }
161 
163 {
164  return m_showGrid;
165 }
166 
167 void WGEGridNode::setEnableGrid( bool enable )
168 {
169  m_showGrid = enable;
170  m_gridUpdate = true;
171 }
172 
173 const WColor& WGEGridNode::getBBoxColor() const
174 {
175  return m_bbColor;
176 }
177 
178 void WGEGridNode::setBBoxColor( const WColor& color )
179 {
180  m_bbColor = color;
181  m_gridUpdate = true;
182 }
183 
184 const WColor& WGEGridNode::getGridColor() const
185 {
186  return m_gridColor;
187 }
188 
189 void WGEGridNode::setGridColor( const WColor& color )
190 {
191  m_gridColor = color;
192  m_gridUpdate = true;
193 }
194 
195 /**
196  * Simply converts the vector to an string.
197  *
198  * \param vec the vector
199  *
200  * \return string representation
201  */
202 std::string vec2str( osg::Vec3 vec )
203 {
204  std::ostringstream os;
205  os.precision( 5 );
206  os << "(" << vec[0] << "," << vec[1] << "," << vec[2] << ")";
207  return os.str();
208 }
209 
210 void WGEGridNode::callback( osg::Node* /*node*/ )
211 {
212  if( m_gridUpdate )
213  {
214  // grab the grid
216 
217  // apply the grid transformation
218  osg::Matrix m = osg::Matrix::scale( grid->getNbCoordsX() - 1, grid->getNbCoordsY() - 1, grid->getNbCoordsZ() - 1 ) *
219  static_cast< osg::Matrixd >( static_cast< WMatrix4d >( grid->getTransform() ) );
220  setMatrix( m );
221 
222  // set the labels correspondingly
223  for( size_t i = 0; i < 8; ++i )
224  {
225  m_borderLabels[i]->setText( vec2str( m_borderLabels[i]->getPosition() * m ) );
226  }
227 
228  // set node mask of labels, bbox and grid
229  m_labelGeode->setNodeMask( 0xFFFFFFFF * m_showLabels );
230  m_boundaryGeode->setNodeMask( 0xFFFFFFFF * m_showBBox );
231  m_innerGridGeode->setNodeMask( 0xFFFFFFFF * m_showGrid );
232 
233  // color
234  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
235  colors->push_back( m_bbColor );
236  m_boundaryGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors );
237 
238  // set color for grid too
239  if( m_innerGridGeode->getNumDrawables() )
240  {
241  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
242  colors->push_back( m_gridColor );
243  m_innerGridGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors );
244  }
245 
246  m_gridUpdate = false;
247  }
248 
249  // recreate grid?
251  {
252  // grab the grid
254 
255  osg::Geometry* gridGeometry = new osg::Geometry();
256  osg::ref_ptr< osg::Vec3Array > vertArray = new osg::Vec3Array( grid->size() );
257 
258  osg::DrawElementsUInt* gridElement = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
259  gridElement->reserve( grid->size() * 2 );
260 
261  size_t sx = grid->getNbCoordsX();
262  size_t sy = grid->getNbCoordsY();
263  size_t sz = grid->getNbCoordsZ();
264  for( unsigned int vertIdX = 0; vertIdX < sx; ++vertIdX )
265  {
266  for( unsigned int vertIdY = 0; vertIdY < sy; ++vertIdY )
267  {
268  for( unsigned int vertIdZ = 0; vertIdZ < sz; ++vertIdZ )
269  {
270  size_t id = vertIdX + vertIdY * sx + vertIdZ * sx * sy;
271 
272  ( *vertArray )[id][0] = static_cast< float >( vertIdX ) / static_cast< float >( sx - 1 );
273  ( *vertArray )[id][1] = static_cast< float >( vertIdY ) / static_cast< float >( sy - 1 );
274  ( *vertArray )[id][2] = static_cast< float >( vertIdZ ) / static_cast< float >( sz - 1 );
275 
276  if( vertIdX < sx - 1 )
277  {
278  gridElement->push_back( id );
279  gridElement->push_back( id + 1 );
280  }
281 
282  if( vertIdY < sy - 1 )
283  {
284  gridElement->push_back( id );
285  gridElement->push_back( id + sx );
286  }
287 
288  if( vertIdZ < sz - 1 )
289  {
290  gridElement->push_back( id );
291  gridElement->push_back( id + sx * sy );
292  }
293  }
294  }
295  }
296 
297  // done. Add it
298  gridGeometry->setVertexArray( vertArray );
299  gridGeometry->addPrimitiveSet( gridElement );
300 
301  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
302  // finally, the colors
303  colors->push_back( m_gridColor );
304  gridGeometry->setColorArray( colors );
305  gridGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
306 
307  if( m_innerGridGeode->getNumDrawables() )
308  {
309  m_innerGridGeode->setDrawable( 0, gridGeometry );
310  }
311  else
312  {
313  m_innerGridGeode->addDrawable( gridGeometry );
314  }
315 
316  // we create a unit cube here as the transformation matrix already contains the proper scaling.
317  m_gridGeometryUpdate = false;
318  }
319 }
320