OpenWalnut  1.5.0dev
WMGridRenderer.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 <cmath>
26 #include <fstream>
27 #include <iostream>
28 #include <memory>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
33 #include <osg/MatrixTransform>
34 #include <osg/PositionAttitudeTransform>
35 #include <osgText/Text>
36 
37 #include "WMGridRenderer.h"
38 #include "WMGridRenderer.xpm"
39 #include "WMGridRenderer_boundary.xpm"
40 #include "WMGridRenderer_grid.xpm"
41 #include "WMGridRenderer_label.xpm"
42 #include "core/common/WAssert.h"
43 #include "core/common/WBoundingBox.h"
44 #include "core/common/WStringUtils.h"
45 #include "core/common/math/linearAlgebra/WVectorFixed.h"
46 #include "core/dataHandler/WDataSetFibers.h"
47 #include "core/dataHandler/WDataSetPoints.h"
48 #include "core/dataHandler/WDataSetSingle.h"
49 #include "core/dataHandler/WGridRegular3D.h"
50 #include "core/graphicsEngine/WGEGeodeUtils.h"
51 #include "core/graphicsEngine/callbacks/WGENodeMaskCallback.h"
52 #include "core/kernel/WKernel.h"
53 
54 // This line is needed by the module loader to actually find your module.
55 W_LOADABLE_MODULE( WMGridRenderer )
56 
58  WModule(),
59  m_recompute( std::shared_ptr< WCondition >( new WCondition() ) )
60 {
61  // WARNING: initializing connectors inside the constructor will lead to an exception.
62  // Implement WModule::initializeConnectors instead.
63 }
64 
66 {
67  // cleanup
69 }
70 
71 std::shared_ptr< WModule > WMGridRenderer::factory() const
72 {
73  return std::shared_ptr< WModule >( new WMGridRenderer() );
74 }
75 
76 const char** WMGridRenderer::getXPMIcon() const
77 {
78  return WMGridRenderer_xpm;
79 }
80 
81 const std::string WMGridRenderer::getName() const
82 {
83  return "Grid Renderer";
84 }
85 
86 const std::string WMGridRenderer::getDescription() const
87 {
88  return "Shows the bounding box and grid of a data set.";
89 }
90 
92 {
93  // use the m_input "data changed" flag
94  m_moduleState.setResetable( true, true );
95  m_moduleState.add( m_input->getDataChangedCondition() );
97 
98  // signal ready state
99  ready();
100 
101  // loop until the module container requests the module to quit
102  while( !m_shutdownFlag() )
103  {
104  debugLog() << "Waiting for data ...";
106 
107  WDataSet::SPtr dataSet = m_input->getData();
108  bool dataValid = ( dataSet != NULL );
109  bool dataChanged = ( dataSet != m_dataSetOld );
110  m_dataSetOld = dataSet;
111 
112  if( !dataValid )
113  {
114  // OK, the output has not yet sent data
115  // NOTE: see comment at the end of this while loop for m_moduleState
116  WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_gridNode );
117  m_gridNode = NULL;
118  continue;
119  }
120 
121  // do nothing if these are still the same data
122  if( !dataChanged )
123  {
124  continue;
125  }
126 
127  m_infoProperties->removeProperty( currentDataInfoProperties );
128  currentDataInfoProperties = dataSet->getInformationProperties(); // update properties
130 
131  // the grid to show
132  WGridRegular3D::SPtr regGrid;
133 
134  // is this a DS with a regular grid?
135  WDataSetSingle::SPtr dsSingle = std::dynamic_pointer_cast< WDataSetSingle >( dataSet );
136  if( dsSingle )
137  {
138  regGrid = std::dynamic_pointer_cast< WGridRegular3D >( dsSingle->getGrid() );
139  }
140 
141  // is this a fiber dataset?
142  WDataSetFibers::SPtr dsFibers = std::dynamic_pointer_cast< WDataSetFibers >( dataSet );
143  if( dsFibers )
144  {
145  debugLog() << "Fiber Data.";
146 
147  WBoundingBox bb = dsFibers->getBoundingBox();
148  // this basically is a fake but we need a grid for WGEGridNode. So we construct one using the BBox
149  WGridTransformOrtho gridTransform( bb.xMax() - bb.xMin(), bb.yMax() - bb.yMin(), bb.zMax() - bb.zMin() );
150  gridTransform.translate( WVector3d( bb.xMin(), bb.yMin(), bb.zMin() ) );
151  regGrid = WGridRegular3D::SPtr( new WGridRegular3D( 2, 2, 2, gridTransform ) );
152  }
153 
154  // is this a point dataset?
155  WDataSetPoints::SPtr dsPoints = std::dynamic_pointer_cast< WDataSetPoints >( dataSet );
156  if( dsPoints )
157  {
158  debugLog() << "Points Data.";
159 
160  WBoundingBox bb = dsPoints->getBoundingBox();
161 
162  // this basically is a fake but we need a grid for WGEGridNode. So we construct one using the BBox
163  const double makeFakeNonZero = 0.000001;
164  WGridTransformOrtho gridTransform( bb.xMax() - bb.xMin() + makeFakeNonZero,
165  bb.yMax() - bb.yMin() + makeFakeNonZero,
166  bb.zMax() - bb.zMin() + makeFakeNonZero );
167  gridTransform.translate( WVector3d( bb.xMin(), bb.yMin(), bb.zMin() ) );
168  regGrid = WGridRegular3D::SPtr( new WGridRegular3D( 2, 2, 2, gridTransform ) );
169  }
170 
171  // create the new grid node if it not exists
172  if( !m_gridNode && regGrid )
173  {
174  debugLog() << "Creating grid geode.";
175  m_gridNode = new WGEGridNode( regGrid );
176  m_gridNode->addUpdateCallback( new WGENodeMaskCallback( m_active ) );
177  WGraphicsEngine::getGraphicsEngine()->getScene()->insert( m_gridNode );
178  }
179  else if( m_gridNode && !regGrid )
180  {
181  debugLog() << "Removing grid geode.";
182  // there is a grid node which needs to be removed as we do NOT have a valid regular grid.
183  WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_gridNode );
184  m_gridNode = NULL;
185  }
186 
187  if( m_gridNode )
188  {
189  m_gridNode->setBBoxColor( *m_bboxColor );
190  m_gridNode->setGridColor( *m_gridColor );
191  m_gridNode->setGridLineWidth( m_gridLineWidth->get() );
192  m_gridNode->setBoxLineWidth( m_boxLineWidth->get() );
193  updateNode( m_mode );
194  m_gridNode->setGrid( regGrid );
195  }
196  }
197 
198  WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_gridNode );
199 }
200 
202 {
203  // initialize connectors
204  m_input = std::shared_ptr< WModuleInputData < WDataSet > >(
205  new WModuleInputData< WDataSet >( shared_from_this(),
206  "in", "The dataset to show" )
207  );
208 
209  // add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
211 
212  // call WModules initialization
214 }
215 
217 {
218  WPropertyBase::PropertyChangeNotifierType notifier = boost::bind( &WMGridRenderer::updateNode, this, boost::placeholders::_1 );
219 
220  m_bboxColor = m_properties->addProperty( "Bounding box color", "The color of the bounding box.", WColor( 0.3, 0.3, 0.3, 1.0 ), notifier );
221  m_boxLineWidth = m_properties->addProperty( "Bounding box line width", "The width of the grid lines.", 4, notifier );
222  m_boxLineWidth->setMin( 1 );
223  m_boxLineWidth->setMax( 10 );
224 
225  m_gridColor = m_properties->addProperty( "Grid color", "The color of the grid.", WColor( 0.1, 0.1, 0.1, 1.0 ), notifier );
226  m_gridLineWidth = m_properties->addProperty( "Grid line width", "The width of the grid lines.", 1, notifier );
227  m_gridLineWidth->setMin( 1 );
228  m_gridLineWidth->setMax( 10 );
229 
231  m_possibleModes->addItem( "Labels", "Show the boundary labels.", WMGridRenderer_label_xpm ); // NOTE: you can add XPM images here.
232  m_possibleModes->addItem( "Bounding box", "Show the bounding box.", WMGridRenderer_boundary_xpm );
233  m_possibleModes->addItem( "Grid", "Show the inner grid.", WMGridRenderer_grid_xpm );
234 
235  // selecting all at once might be a bad idea since the grid rendering can be very very slow. So, by default, only show bbox and labels.
236  WItemSelector sel = m_possibleModes->getSelectorFirst();
237  m_mode = m_properties->addProperty( "Mode", "What should be rendered.", sel.newSelector( 1 ), notifier );
239 
241 }
242 
244 {
245  // only update if there is a grid node
246  if( !m_gridNode )
247  {
248  return;
249  }
250 
251  // color of bbox changed
252  if( property == m_bboxColor )
253  {
254  m_gridNode->setBBoxColor( *m_bboxColor );
255  }
256 
257  // color of grid changed
258  if( property == m_gridColor )
259  {
260  m_gridNode->setGridColor( *m_gridColor );
261  }
262 
263  if( property == m_gridLineWidth )
264  {
265  m_gridNode->setGridLineWidth( m_gridLineWidth->get() );
266  }
267 
268  if( property == m_boxLineWidth )
269  {
270  m_gridNode->setBoxLineWidth( m_boxLineWidth->get() );
271  }
272 
273  // mode changed
274  if( property == m_mode )
275  {
276  WItemSelector s = m_mode->get( true );
277 
278  bool labels = false;
279  bool bbox = false;
280  bool grid = false;
281 
282  // The multi property allows the selection of several items. So, iteration needs to be done here:
283  for( size_t i = 0; i < s.size(); ++i )
284  {
285  size_t idx = s.getItemIndexOfSelected( i );
286 
287  // check what was selected
288  labels = labels || ( idx == 0 );
289  bbox = bbox || ( idx == 1 );
290  grid = grid || ( idx == 2 );
291  }
292 
293  m_gridNode->setEnableLabels( labels );
294  m_gridNode->setEnableGrid( grid );
295  m_gridNode->setEnableBBox( bbox );
296  }
297 }
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
std::shared_ptr< WDataSetFibers > SPtr
Pointer to dataset.
std::shared_ptr< WDataSetPoints > SPtr
Pointer to dataset.
std::shared_ptr< WDataSetSingle > SPtr
Convenience typedef for a std::shared_ptr.
std::shared_ptr< WDataSet > SPtr
Shared pointer abbreviation to a instance of this class.
Definition: WDataSet.h:55
This node is able to represent a grid in certain ways.
Definition: WGEGridNode.h:41
This callback is useful to en-/disable nodes using the node mask based on properties.
static std::shared_ptr< WGraphicsEngine > getGraphicsEngine()
Returns instance of the graphics engine.
A grid that has parallelepiped cells which all have the same proportion.
std::shared_ptr< WGridRegular3DTemplate > SPtr
Convenience typedef for a std::shared_ptr< WGridRegular3DTemplate >.
Implements an orthogonal grid transformation.
void translate(VecType const &vec)
Translate by a vector.
A class containing a list of named items.
std::shared_ptr< WItemSelection > SPtr
Convenience typedef for a std::shared_ptr< WItemSelection >
This class represents a subset of a WItemSelection.
Definition: WItemSelector.h:53
WItemSelector newSelector(IndexList selected) const
Creates a new valid instance with the specified items selected.
virtual size_t size() const
The number of selected items.
virtual size_t getItemIndexOfSelected(size_t index) const
Helps to get the index of an selected item in the WItemSelection.
Show the bounding box and grid of a WDataSetSingle.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
virtual const std::string getDescription() const
Gives back a description of this module.
~WMGridRenderer()
Destructor.
WPropColor m_gridColor
the color of the grid
virtual void properties()
Initialize the properties for this module.
std::shared_ptr< WCondition > m_recompute
This condition denotes whether we need to recompute the surface.
WPropColor m_bboxColor
the color of the bounding box
std::shared_ptr< WModuleInputData< WDataSet > > m_input
Input connector required by this module.
WMGridRenderer()
Standard constructor.
virtual const std::string getName() const
Gives back the name of this module.
virtual void moduleMain()
Entry point after loading the module.
void updateNode(WPropertyBase::SPtr property)
Handles updates in properties.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
WDataSet::SPtr m_dataSetOld
The currently handled data.
WItemSelection::SPtr m_possibleModes
the modes available.
virtual void connectors()
Initialize the connectors this module is using.
WPropSelection m_mode
the mode (bbox, grid, both)
WGEGridNode::SPtr m_gridNode
The node actually drawing the grid.
WPropInt m_boxLineWidth
the width of the boundary lines
WPropInt m_gridLineWidth
the width of the grid lines
std::shared_ptr< WProperties > currentDataInfoProperties
Kept reference to current data infos as properties.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void removeConnectors()
Removes all connectors properly.
Definition: WModule.cpp:194
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
Definition: WModule.cpp:108
std::shared_ptr< WProperties > m_properties
The property object for the module.
Definition: WModule.h:640
std::shared_ptr< WProperties > m_infoProperties
The property object for the module containing only module whose purpose is "PV_PURPOSE_INFORMNATION".
Definition: WModule.h:647
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
WPropBool m_active
True whenever the module should be active.
Definition: WModule.h:723
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
boost::function< void(std::shared_ptr< WPropertyBase >)> PropertyChangeNotifierType
Signal signature emitted during set operations.
std::shared_ptr< WPropertyBase > SPtr
Convenience typedef for a std::shared_ptr< WPropertyBase >
Definition: WPropertyBase.h:53
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
void addTo(WPropSelection prop)
Add the PC_NOTEMPTY constraint to the property.