OpenWalnut  1.5.0dev
WMWebglSupport.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 <memory>
26 #include <string>
27 
28 #include <boost/filesystem.hpp>
29 #include <osg/Image>
30 #include <osgDB/WriteFile>
31 
32 #include "WMWebglSupport.h"
33 #include "WMWebglSupport.xpm"
34 #include "core/common/WPathHelper.h"
35 #include "core/common/WStringUtils.h"
36 #include "core/kernel/WKernel.h"
37 
38 // This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
39 W_LOADABLE_MODULE( WMWebglSupport )
40 
42  WModule()
43 {
44 }
45 
47 {
48  // Cleanup!
49 }
50 
51 std::shared_ptr< WModule > WMWebglSupport::factory() const
52 {
53  // See "src/modules/template/" for an extensively documented example.
54  return std::shared_ptr< WModule >( new WMWebglSupport() );
55 }
56 
57 const char** WMWebglSupport::getXPMIcon() const
58 {
59  return WMWebglSupport_xpm; // Please put a real icon here.
60 }
61 const std::string WMWebglSupport::getName() const
62 {
63  return "WebGL Support";
64 }
65 
66 const std::string WMWebglSupport::getDescription() const
67 {
68  // Specify your module description here. Be detailed. This text is read by the user.
69  // See "src/modules/template/" for an extensively documented example.
70  return "Someone should add some documentation here. "
71  "Probably the best person would be the modules's creator, i.e. \"ralph\"";
72 }
73 
75 {
76  m_meshInput = std::shared_ptr< WModuleInputData < WTriangleMesh > >(
77  new WModuleInputData< WTriangleMesh >( shared_from_this(), "mesh", "The input mesh" )
78  );
80 
81  m_meshOutput = std::shared_ptr< WModuleOutputData< WTriangleMesh > >(
82  new WModuleOutputData< WTriangleMesh >( shared_from_this(), "surface mesh", "The output mesh" ) );
84 
85  m_datasetInputScalar = std::shared_ptr< WModuleInputData < WDataSetScalar > >(
86  new WModuleInputData< WDataSetScalar >( shared_from_this(), "values scalar", "Dataset to color the mesh with" )
87  );
88 
89  // add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
91 
92  m_datasetInputVector = std::shared_ptr< WModuleInputData < WDataSetVector > >(
93  new WModuleInputData< WDataSetVector >( shared_from_this(), "values vector", "Dataset to color the mesh with" )
94  );
95 
96  // add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
98 
99 
101 }
102 
104 {
105  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
106  m_propTriggerSaveGray = m_properties->addProperty( "Do Save gray", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
107  m_propTriggerSaveRGB = m_properties->addProperty( "Do Save RGB", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
108  m_fileName = m_properties->addProperty( "file name", "", WPathHelper::getAppPath() );
109 
110  m_propTriggerUpdateOutputGray = m_properties->addProperty( "Update output gray", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
111  m_propTriggerUpdateOutputRGB = m_properties->addProperty( "Update output rgb", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
112 
114 }
115 
117 {
118  // Put the code for your requirements here. See "src/modules/template/" for an extensively documented example.
119 }
120 
122 {
123  m_moduleState.add( m_meshInput->getDataChangedCondition() );
124  m_moduleState.add( m_datasetInputScalar->getDataChangedCondition() );
125  m_moduleState.add( m_datasetInputVector->getDataChangedCondition() );
127 
128  // signal ready state
129  ready();
130 
131  // loop until the module container requests the module to quit
132  while( !m_shutdownFlag() )
133  {
134  // this waits for m_moduleState to fire. By default, this is only the m_shutdownFlag condition.
135  // NOTE: you can add your own conditions to m_moduleState using m_moduleState.add( ... )
137 
138  if( m_triMesh != m_meshInput->getData() )
139  {
140  m_triMesh = m_meshInput->getData();
141  debugLog() << "new triangle mesh conected";
142  }
143 
144  if( m_datasetScalar != m_datasetInputScalar->getData() )
145  {
147  debugLog() << "new scalar dataset connected";
148  }
149 
150  if( m_datasetVector != m_datasetInputVector->getData() )
151  {
153  debugLog() << "new vector dataset connected";
154  }
155 
157  {
158  debugLog() << "Save pressed";
159  saveSlicesGray();
161  }
163  {
164  debugLog() << "Save RGB pressed";
165  saveSlicesRGB();
167  }
169  {
170  debugLog() << "Update pressed Gray";
172  m_meshOutput->updateData( m_triMesh );
174  }
176  {
177  debugLog() << "Update pressed RGB";
178  colorTriMeshRGB();
179  m_meshOutput->updateData( m_triMesh );
181  }
182  }
183 }
184 
186 {
187  //std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( ( *m_datasetScalar ).getGrid() );
188  //bool success;
189 
190  for( size_t i = 0; i < m_triMesh->vertSize(); ++i )
191  {
192  // get vertex position
193  WPosition pos = m_triMesh->getVertex( i );
194 
195  // get color value for that vertex from texture
196  //double value = m_datasetScalar->interpolate( pos, &success );
197  double value = m_datasetScalar->getValueAt( pos.x(), pos.y(), pos.z() );
198  //if( !success )
199  //{
200  // debugLog() << "error at getting value from datatset";
201  //}
202 
203  // write color into tri mesh
204  float c = value / 255.0;
205  osg::Vec4 color( c, c, c, 1.0 );
206  m_triMesh->setVertexColor( i, color );
207  }
208 }
209 
211 {
212  //std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( ( *m_datasetScalar ).getGrid() );
213  bool success;
214 
215  for( size_t i = 0; i < m_triMesh->vertSize(); ++i )
216  {
217  // get vertex position
218  WPosition pos = m_triMesh->getVertex( i );
219 
220  // get color value for that vertex from texture
221  WVector3d value = m_datasetVector->interpolate( pos, &success );
222  //double value = m_datasetScalar->getValueAt( pos.x(), pos.y(), pos.z() );
223  if( !success )
224  {
225  debugLog() << "error at getting value from datatset";
226  }
227 
228  // write color into tri mesh
229  //float c = value / 255.0 ;
230  value /= 255.0;
231  osg::Vec4 color( value[0], value[1], value[2], 1.0 );
232  m_triMesh->setVertexColor( i, color );
233  }
234 }
235 
237 {
238  using namespace boost::filesystem; //NOLINT
239 
240  std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( ( *m_datasetScalar ).getGrid() );
241  debugLog() << grid->getNbCoordsX() << " " << grid->getNbCoordsY() << " " << grid->getNbCoordsZ();
242 
243  osg::ref_ptr< osg::Image > ima = new osg::Image;
244  ima->allocateImage( 256, 256, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE );
245  unsigned char* data = ima->data();
246 
247  for( size_t y = 0; y < 200; ++y )
248  {
249  for( size_t i = 0; i < 256; ++i )
250  {
251  for( size_t j = 0; j < 256; ++j )
252  {
253  data[256 * i + j] = 0;
254  }
255  }
256 
257  for( size_t x = 0; x < 160; ++x )
258  {
259  for( size_t z = 0; z < 160; ++z )
260  {
261  uint8_t value = static_cast<uint8_t>( m_datasetScalar->getValueAt( x, y, z ) );
262  data[ 256 * ( 48 + z ) + x + 48 ] = value;
263  }
264  }
265  path fileName = m_fileName->get();
266  fileName.remove_filename().string();
267  std::string fn( std::string( "coronal_" ) + string_utils::toString( y ) + std::string( ".bmp" ) );
268  osgDB::writeImageFile( *ima, ( fileName.string() + fn ).c_str() );
269  }
270 
271  osg::ref_ptr< osg::Image > ima1 = new osg::Image;
272  ima1->allocateImage( 256, 256, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE );
273  data = ima1->data();
274 
275  for( size_t x = 0; x < 160; ++x )
276  {
277  for( size_t i = 0; i < 256; ++i )
278  {
279  for( size_t j = 0; j < 256; ++j )
280  {
281  data[256 * i + j] = 0;
282  }
283  }
284  for( size_t y = 0; y < 200; ++y )
285  {
286  for( size_t z = 0; z < 160; ++z )
287  {
288  uint8_t value = static_cast<uint8_t>( m_datasetScalar->getValueAt( x, y, z ) );
289  data[ 256 * ( 48 + z ) + y + 28 ] = value;
290  }
291  }
292  path fileName = m_fileName->get();
293  fileName.remove_filename().string();
294  std::string fn( std::string( "sagittal_" ) + string_utils::toString( x ) + std::string( ".bmp" ) );
295  osgDB::writeImageFile( *ima1, ( fileName.string() + fn ).c_str() );
296  }
297 
298  osg::ref_ptr< osg::Image > ima2 = new osg::Image;
299  ima2->allocateImage( 256, 256, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE );
300  data = ima2->data();
301 
302  for( size_t z = 0; z < 160; ++z )
303  {
304  for( size_t i = 0; i < 256; ++i )
305  {
306  for( size_t j = 0; j < 256; ++j )
307  {
308  data[256 * i + j] = 0;
309  }
310  }
311  for( size_t x = 0; x < 160; ++x )
312  {
313  for( size_t y = 0; y < 200; ++y )
314  {
315  uint8_t value = static_cast<uint8_t>( m_datasetScalar->getValueAt( x, y, z ) );
316  data[ 256 * ( y + 28 ) + x + 48 ] = value;
317  }
318  }
319  path fileName = m_fileName->get();
320  fileName.remove_filename().string();
321  std::string fn( std::string( "axial_" ) + string_utils::toString( z ) + std::string( ".bmp" ) );
322  osgDB::writeImageFile( *ima2, ( fileName.string() + fn ).c_str() );
323  }
324 }
325 
327 {
328  using namespace boost::filesystem; //NOLINT
329 
330 // std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( ( *m_datasetScalar ).getGrid() );
331 // debugLog() << grid->getNbCoordsX() << " " << grid->getNbCoordsY() << " " << grid->getNbCoordsZ();
332 
333  osg::ref_ptr< osg::Image > ima = new osg::Image;
334  ima->allocateImage( 256, 256, 1, GL_RGB, GL_UNSIGNED_BYTE );
335  unsigned char* data = ima->data();
336  bool success = false;
337  for( size_t y = 0; y < 200; ++y )
338  {
339  for( size_t i = 0; i < 256; ++i )
340  {
341  for( size_t j = 0; j < 256; ++j )
342  {
343  data[256 * i * 3 + j * 3 ] = 0;
344  data[256 * i * 3 + j * 3 + 1 ] = 0;
345  data[256 * i * 3 + j * 3 + 2 ] = 0;
346  }
347  }
348 
349  for( size_t x = 0; x < 160; ++x )
350  {
351  for( size_t z = 0; z < 160; ++z )
352  {
353  WPosition pos( x, y, z );
354  WVector3d value = m_datasetVector->interpolate( pos, &success );
355  data[ 256 * ( 48 + z ) * 3 + ( x + 48 ) * 3 ] = static_cast<uint8_t>( value[0] );
356  data[ 256 * ( 48 + z ) * 3 + ( x + 48 ) * 3 + 1 ] = static_cast<uint8_t>( value[1] );
357  data[ 256 * ( 48 + z ) * 3 + ( x + 48 ) * 3 + 2 ] = static_cast<uint8_t>( value[2] );
358  }
359  }
360  path fileName = m_fileName->get();
361  fileName.remove_filename().string();
362  std::string fn( std::string( "coronal_" ) + string_utils::toString( y ) + std::string( ".bmp" ) );
363  osgDB::writeImageFile( *ima, ( fileName.string() + fn ).c_str() );
364  }
365 
366  osg::ref_ptr< osg::Image > ima1 = new osg::Image;
367  ima1->allocateImage( 256, 256, 1, GL_RGB, GL_UNSIGNED_BYTE );
368  data = ima1->data();
369 
370  for( size_t x = 0; x < 160; ++x )
371  {
372  for( size_t i = 0; i < 256; ++i )
373  {
374  for( size_t j = 0; j < 256; ++j )
375  {
376  data[256 * i * 3 + j * 3 ] = 0;
377  data[256 * i * 3 + j * 3 + 1 ] = 0;
378  data[256 * i * 3 + j * 3 + 2 ] = 0;
379  }
380  }
381 
382  for( size_t y = 0; y < 200; ++y )
383  {
384  for( size_t z = 0; z < 160; ++z )
385  {
386  WPosition pos( x, y, z );
387  WVector3d value = m_datasetVector->interpolate( pos, &success );
388  data[ 256 * ( 48 + z ) * 3 + ( y + 28 ) * 3 ] = static_cast<uint8_t>( value[0] );
389  data[ 256 * ( 48 + z ) * 3 + ( y + 28 ) * 3 + 1 ] = static_cast<uint8_t>( value[1] );
390  data[ 256 * ( 48 + z ) * 3 + ( y + 28 ) * 3 + 2 ] = static_cast<uint8_t>( value[2] );
391  }
392  }
393  path fileName = m_fileName->get();
394  fileName.remove_filename().string();
395  std::string fn( std::string( "sagittal_" ) + string_utils::toString( x ) + std::string( ".bmp" ) );
396  osgDB::writeImageFile( *ima1, ( fileName.string() + fn ).c_str() );
397  }
398 
399  osg::ref_ptr< osg::Image > ima2 = new osg::Image;
400  ima2->allocateImage( 256, 256, 1, GL_RGB, GL_UNSIGNED_BYTE );
401  data = ima2->data();
402 
403  for( size_t z = 0; z < 160; ++z )
404  {
405  for( size_t i = 0; i < 256; ++i )
406  {
407  for( size_t j = 0; j < 256; ++j )
408  {
409  data[256 * i * 3 + j * 3 ] = 0;
410  data[256 * i * 3 + j * 3 + 1 ] = 0;
411  data[256 * i * 3 + j * 3 + 2 ] = 0;
412  }
413  }
414 
415  for( size_t x = 0; x < 160; ++x )
416  {
417  for( size_t y = 0; y < 200; ++y )
418  {
419  WPosition pos( x, y, z );
420  WVector3d value = m_datasetVector->interpolate( pos, &success );
421  //256 * ( y + 28 ) + x + 48
422  data[ 256 * ( y + 28 ) * 3 + ( x + 48 ) * 3 ] = static_cast<uint8_t>( value[0] );
423  data[ 256 * ( y + 28 ) * 3 + ( x + 48 ) * 3 + 1 ] = static_cast<uint8_t>( value[1] );
424  data[ 256 * ( y + 28 ) * 3 + ( x + 48 ) * 3 + 2 ] = static_cast<uint8_t>( value[2] );
425  }
426  }
427  path fileName = m_fileName->get();
428  fileName.remove_filename().string();
429  std::string fn( std::string( "axial_" ) + string_utils::toString( z ) + std::string( ".bmp" ) );
430  osgDB::writeImageFile( *ima2, ( fileName.string() + fn ).c_str() );
431  }
432 }
virtual void wait() const
Wait for the condition.
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
Someone should add some documentation here.
std::shared_ptr< WModuleInputData< WTriangleMesh > > m_meshInput
Input connector for a mesh.
WPropTrigger m_propTriggerSaveRGB
This property triggers the actual writing,.
std::shared_ptr< WDataSetScalar > m_datasetScalar
A pointer to the currently processed dataset.
std::shared_ptr< WDataSetVector > m_datasetVector
A pointer to the currently processed dataset.
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_datasetInputScalar
Input connector required by this module.
WPropTrigger m_propTriggerSaveGray
This property triggers the actual writing,.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
virtual void connectors()
Initialize the connectors this module is using.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
virtual void properties()
Initialize the properties for this module.
void colorTriMeshGray()
colors a connected triangle mesh with the connected gray scale texture
virtual ~WMWebglSupport()
destructor
std::shared_ptr< WTriangleMesh > m_triMesh
A pointer to the currently processed tri mesh.
virtual void moduleMain()
Entry point after loading the module.
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.
virtual void requirements()
Initialize requirements for this module.
void saveSlicesRGB()
saves a connected rgb 3D texture as set of 2D textures
WPropTrigger m_propTriggerUpdateOutputGray
This property triggers the actual writing,.
WPropTrigger m_propTriggerUpdateOutputRGB
This property triggers the actual writing,.
std::shared_ptr< WModuleOutputData< WTriangleMesh > > m_meshOutput
Input connector required by this module.
void saveSlicesGray()
saves a connected gray scale 3D texture as set of 2D textures
void colorTriMeshRGB()
colors a connected triangle mesh with the connected rgb texture
std::shared_ptr< WModuleInputData< WDataSetVector > > m_datasetInputVector
Input connector required by this module.
virtual const std::string getName() const
Gives back the name of this module.
WPropFilename m_fileName
The mesh will be written to this file.
WMWebglSupport()
constructor
Class offering an instantiate-able data connection between modules.
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 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
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
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
static boost::filesystem::path getAppPath()
The path where the binary file resides in.
Definition: WPathHelper.cpp:93
This only is a 3d double vector.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)
std::string toString(const T &value)
Convert a given value to a string.
Definition: WStringUtils.h:120