OpenWalnut  1.5.0dev
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 "../callbacks/WGEFunctorCallback.h"
31 #include "../WGEGeodeUtils.h"
32 #include "WGEGridNode.h"
33 
35  m_boundaryGeode( new osg::Geode() ),
36  m_innerGridGeode( new osg::Geode() ),
37  m_labelGeode( new osg::Geode() ),
38  m_gridUpdate( true ),
39  m_gridGeometryUpdate( true ),
40  m_showLabels( true ),
41  m_bbColor( WColor( 0.3, 0.3, 0.3, 1.0 ) ),
42  m_gridColor( WColor( 0.1, 0.1, 0.1, 1.0 ) ),
43  m_gridLineWidth( 1 ),
44  m_boxLineWidth( 4 )
45 {
46  m_grid.getWriteTicket()->get() = grid;
47 
48  // init the boundary geometry
50 
51  // init labels
52  // Therefore: create prototype
53  WGELabel::SPtr label = new WGELabel();
54  label->setAlignment( osgText::Text::CENTER_TOP );
55  label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
56 
57  // add several copies and set position accordingly
58 
59  // Front face ( z = 0 )
60  // bottom left
61  label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) );
62  label->setCharacterSize( 6 );
63  m_labelGeode->addDrawable( label );
64  m_borderLabels[0] = label;
65 
66  // bottom right
67  label = new WGELabel( *label );
68  label->setPosition( osg::Vec3( 1.0, 0.0, 0.0 ) );
69  m_labelGeode->addDrawable( label );
70  m_borderLabels[1] = label;
71 
72  // top right
73  label = new WGELabel( *label );
74  label->setPosition( osg::Vec3( 1.0, 1.0, 0.0 ) );
75  m_labelGeode->addDrawable( label );
76  m_borderLabels[2] = label;
77 
78  // top left
79  label = new WGELabel( *label );
80  label->setPosition( osg::Vec3( 0.0, 1.0, 0.0 ) );
81  m_labelGeode->addDrawable( label );
82  m_borderLabels[3] = label;
83 
84  // Back face ( z = 1 )
85  // bottom left
86  label = new WGELabel( *label );
87  label->setPosition( osg::Vec3( 0.0, 0.0, 1.0 ) );
88  m_labelGeode->addDrawable( label );
89  m_borderLabels[4] = label;
90 
91  // bottom right
92  label = new WGELabel( *label );
93  label->setPosition( osg::Vec3( 1.0, 0.0, 1.0 ) );
94  m_labelGeode->addDrawable( label );
95  m_borderLabels[5] = label;
96 
97  // top right
98  label = new WGELabel( *label );
99  label->setPosition( osg::Vec3( 1.0, 1.0, 1.0 ) );
100  m_labelGeode->addDrawable( label );
101  m_borderLabels[6] = label;
102 
103  // top left
104  label = new WGELabel( *label );
105  label->setPosition( osg::Vec3( 0.0, 1.0, 1.0 ) );
106  m_labelGeode->addDrawable( label );
107  m_borderLabels[7] = label;
108 
109  // add the others too
110  addChild( m_boundaryGeode );
111  addChild( m_innerGridGeode );
112  addChild( m_labelGeode );
113 
114  m_boundaryGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( m_boxLineWidth ), osg::StateAttribute::ON );
115  m_innerGridGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( m_gridLineWidth ), osg::StateAttribute::ON );
116 
117  addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WGEGridNode::callback, this, boost::placeholders::_1 ) ) );
118 
119  // no blending
120  getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::OFF );
121  // disable light for this node
122  getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
123 }
124 
126 {
127  // cleanup
128 }
129 
131 {
132  m_grid.getWriteTicket()->get() = grid;
133  m_gridUpdate = true;
134  m_gridGeometryUpdate = true;
135 }
136 
138 {
139  return m_grid.getReadTicket()->get();
140 }
141 
143 {
144  return m_showLabels;
145 }
146 
147 void WGEGridNode::setEnableLabels( bool enable )
148 {
149  m_showLabels = enable;
150  m_gridUpdate = true;
151 }
152 
154 {
155  return m_showBBox;
156 }
157 
158 void WGEGridNode::setEnableBBox( bool enable )
159 {
160  m_showBBox = enable;
161  m_gridUpdate = true;
162 }
163 
165 {
166  return m_showGrid;
167 }
168 
169 void WGEGridNode::setEnableGrid( bool enable )
170 {
171  m_showGrid = enable;
172  m_gridUpdate = true;
173 }
174 
175 const WColor& WGEGridNode::getBBoxColor() const
176 {
177  return m_bbColor;
178 }
179 
180 void WGEGridNode::setBBoxColor( const WColor& color )
181 {
182  m_bbColor = color;
183  m_gridUpdate = true;
184 }
185 
186 const WColor& WGEGridNode::getGridColor() const
187 {
188  return m_gridColor;
189 }
190 
191 void WGEGridNode::setGridColor( const WColor& color )
192 {
193  m_gridColor = color;
194  m_gridUpdate = true;
195 }
196 
197 void WGEGridNode::setGridLineWidth( int linewidth )
198 {
199  m_gridLineWidth = linewidth;
200  m_gridUpdate = true;
201 }
202 
203 void WGEGridNode::setBoxLineWidth( int linewidth )
204 {
205  m_boxLineWidth = linewidth;
206  m_gridUpdate = true;
207 }
208 
210 {
211  return m_gridLineWidth;
212 }
213 
215 {
216  return m_boxLineWidth;
217 }
218 
219 /**
220  * Simply converts the vector to an string.
221  *
222  * \param vec the vector
223  *
224  * \return string representation
225  */
226 std::string vec2str( osg::Vec3 vec )
227 {
228  std::ostringstream os;
229  os.precision( 5 );
230  os << "(" << vec[0] << "," << vec[1] << "," << vec[2] << ")";
231  return os.str();
232 }
233 
234 void WGEGridNode::callback( osg::Node* /*node*/ )
235 {
236  if( m_gridUpdate )
237  {
238  // grab the grid
240 
241  // apply the grid transformation
242  osg::Matrix m = osg::Matrix::scale( grid->getNbCoordsX() - 1, grid->getNbCoordsY() - 1, grid->getNbCoordsZ() - 1 ) *
243  static_cast< osg::Matrixd >( static_cast< WMatrix4d >( grid->getTransform() ) );
244  setMatrix( m );
245 
246  // set the labels correspondingly
247  for( size_t i = 0; i < 8; ++i )
248  {
249  m_borderLabels[i]->setText( vec2str( m_borderLabels[i]->getPosition() * m ) );
250  }
251 
252  // set node mask of labels, bbox and grid
253  m_labelGeode->setNodeMask( 0xFFFFFFFF * m_showLabels );
254  m_boundaryGeode->setNodeMask( 0xFFFFFFFF * m_showBBox );
255  m_innerGridGeode->setNodeMask( 0xFFFFFFFF * m_showGrid );
256 
257  // color
258  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
259  colors->push_back( m_bbColor );
260  m_boundaryGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors );
261  m_boundaryGeode->getDrawable( 0 )->asGeometry()->setColorBinding( osg::Geometry::BIND_OVERALL );
262 
263  // set color for grid too
264  if( m_innerGridGeode->getNumDrawables() )
265  {
266  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
267  colors->push_back( m_gridColor );
268  m_innerGridGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors );
269  m_innerGridGeode->getDrawable( 0 )->asGeometry()->setColorBinding( osg::Geometry::BIND_OVERALL );
270  }
271 
272  m_innerGridGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( m_gridLineWidth ), osg::StateAttribute::ON );
273  m_boundaryGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( m_boxLineWidth ), osg::StateAttribute::ON );
274 
275  m_gridUpdate = false;
276  }
277 
278  // recreate grid?
280  {
281  // grab the grid
283 
284  osg::Geometry* gridGeometry = new osg::Geometry();
285  osg::ref_ptr< osg::Vec3Array > vertArray = new osg::Vec3Array( grid->size() );
286 
287  osg::DrawElementsUInt* gridElement = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
288  gridElement->reserve( grid->size() * 2 );
289 
290  size_t sx = grid->getNbCoordsX();
291  size_t sy = grid->getNbCoordsY();
292  size_t sz = grid->getNbCoordsZ();
293  for( unsigned int vertIdX = 0; vertIdX < sx; ++vertIdX )
294  {
295  for( unsigned int vertIdY = 0; vertIdY < sy; ++vertIdY )
296  {
297  for( unsigned int vertIdZ = 0; vertIdZ < sz; ++vertIdZ )
298  {
299  size_t id = vertIdX + vertIdY * sx + vertIdZ * sx * sy;
300 
301  ( *vertArray )[id][0] = static_cast< float >( vertIdX ) / static_cast< float >( sx - 1 );
302  ( *vertArray )[id][1] = static_cast< float >( vertIdY ) / static_cast< float >( sy - 1 );
303  ( *vertArray )[id][2] = static_cast< float >( vertIdZ ) / static_cast< float >( sz - 1 );
304 
305  if( vertIdX < sx - 1 )
306  {
307  gridElement->push_back( id );
308  gridElement->push_back( id + 1 );
309  }
310 
311  if( vertIdY < sy - 1 )
312  {
313  gridElement->push_back( id );
314  gridElement->push_back( id + sx );
315  }
316 
317  if( vertIdZ < sz - 1 )
318  {
319  gridElement->push_back( id );
320  gridElement->push_back( id + sx * sy );
321  }
322  }
323  }
324  }
325 
326  // done. Add it
327  gridGeometry->setVertexArray( vertArray );
328  gridGeometry->addPrimitiveSet( gridElement );
329 
330  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
331  // finally, the colors
332  colors->push_back( m_gridColor );
333  gridGeometry->setColorArray( colors );
334  gridGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
335 
336  if( m_innerGridGeode->getNumDrawables() )
337  {
338  m_innerGridGeode->setDrawable( 0, gridGeometry );
339  }
340  else
341  {
342  m_innerGridGeode->addDrawable( gridGeometry );
343  }
344 
345  m_innerGridGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( m_gridLineWidth ), osg::StateAttribute::ON );
346  m_boundaryGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( m_boxLineWidth ), osg::StateAttribute::ON );
347 
348  // we create a unit cube here as the transformation matrix already contains the proper scaling.
349  m_gridGeometryUpdate = false;
350  }
351 }
352 
This callback allows you a simple usage of callbacks in your module.
osg::ref_ptr< osg::Geode > m_boundaryGeode
The geometry for the boundary.
Definition: WGEGridNode.h:187
WGELabel::SPtr m_borderLabels[8]
The labels at the corner.
Definition: WGEGridNode.h:197
bool m_gridUpdate
If true, the labels and geometry gets adapted properly.
Definition: WGEGridNode.h:214
osg::ref_ptr< osg::Geode > m_labelGeode
The geode keeping the labels.
Definition: WGEGridNode.h:202
virtual ~WGEGridNode()
Destructor.
void setGridLineWidth(int linewidth=1)
Set the line width of the gird.
void setEnableLabels(bool enable=true)
En- or disable labels on the boundary corners.
void setGridColor(const WColor &color)
Sets the color of the rendered grid.
bool m_showLabels
If true, labels get used.
Definition: WGEGridNode.h:224
int getGridLineWidth() const
Get the line width of the gird.
void callback(osg::Node *node)
The actual callback handling changes in the grid.
WColor m_bbColor
The color of bbox/grid.
Definition: WGEGridNode.h:239
WGridRegular3D::ConstSPtr getGrid() const
Returns the currently set grid.
bool m_showGrid
True if the grid should be rendered.
Definition: WGEGridNode.h:234
bool m_gridGeometryUpdate
If true, the inner grid geometry gets recreated.
Definition: WGEGridNode.h:219
WSharedObject< WGridRegular3D::ConstSPtr > m_grid
The actual grid which should be represented by this node.
Definition: WGEGridNode.h:182
bool m_showBBox
True if the bbox should be rendered.
Definition: WGEGridNode.h:229
void setEnableGrid(bool enable=true)
En- or disable grid mode.
osg::ref_ptr< osg::Geode > m_innerGridGeode
The geometry for the whole grid.
Definition: WGEGridNode.h:192
bool getEnableBBox() const
Returns whether bbox mode is enabled or not.
int m_boxLineWidth
The line width of the box.
Definition: WGEGridNode.h:254
void setBoxLineWidth(int linewidth=4)
Set the line width of the bounding box.
bool getEnableGrid() const
Returns whether grid mode is enabled or not.
void setBBoxColor(const WColor &color)
Sets the color of the rendered bbox.
WColor m_gridColor
The color of the grid.
Definition: WGEGridNode.h:244
void setGrid(WGridRegular3D::ConstSPtr grid)
Updates the node to use the new specified grid.
int getBoxLineWidth() const
get the line width of the bounding box.
WGEGridNode(WGridRegular3D::ConstSPtr grid)
Creates a node representing the specified grid.
Definition: WGEGridNode.cpp:34
void setEnableBBox(bool enable=true)
En- or disable bbox mode.
bool getEnableLabels() const
Returns whether labels on the corners are enabled or not.
const WColor & getBBoxColor() const
The currently set color used for rendering the bbox.
const WColor & getGridColor() const
The currently set color used for rendering the grid.
int m_gridLineWidth
Line width used for the grid.
Definition: WGEGridNode.h:249
Label layout-item.
Definition: WGELabel.h:39
osg::ref_ptr< WGELabel > SPtr
Convenience typedef for a osg::ref_ptr< WGELabel >.
Definition: WGELabel.h:44
std::shared_ptr< const WGridRegular3DTemplate > ConstSPtr
Convenience typedef for a std::shared_ptr< const WGridRegular3DTemplate >.
ReadTicket getReadTicket() const
Returns a ticket to get read access to the contained data.
WriteTicket getWriteTicket(bool suppressNotify=false) const
Returns a ticket to get write access to the contained data.
osg::ref_ptr< osg::Geometry > createUnitCubeAsLines(const WColor &color, bool asLines=false)
Creates a osg::Geometry containing an unit cube as line-strips, having 3D texture coordinates.