Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
c970c1a4
Commit
c970c1a4
authored
Jul 12, 2012
by
Alexander Wiebel
Browse files
[MERGE]
parents
56e4fa53
648a548c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
720 additions
and
0 deletions
+720
-0
src/modules/modules-others.toolbox
src/modules/modules-others.toolbox
+1
-0
src/modules/surfaceIllustrator/WMSurfaceIllustrator.cpp
src/modules/surfaceIllustrator/WMSurfaceIllustrator.cpp
+343
-0
src/modules/surfaceIllustrator/WMSurfaceIllustrator.h
src/modules/surfaceIllustrator/WMSurfaceIllustrator.h
+224
-0
src/modules/surfaceIllustrator/WMSurfaceIllustrator.xpm
src/modules/surfaceIllustrator/WMSurfaceIllustrator.xpm
+38
-0
src/modules/surfaceIllustrator/shaders/WMSurfaceIllustrator-fragment.glsl
...aceIllustrator/shaders/WMSurfaceIllustrator-fragment.glsl
+71
-0
src/modules/surfaceIllustrator/shaders/WMSurfaceIllustrator-vertex.glsl
...rfaceIllustrator/shaders/WMSurfaceIllustrator-vertex.glsl
+43
-0
No files found.
src/modules/modules-others.toolbox
View file @
c970c1a4
...
...
@@ -35,6 +35,7 @@ ADD_MODULE( schmahmannPandyaSlices )
ADD_MODULE( splineSurface )
ADD_MODULE( surfaceParameterAnimator )
ADD_MODULE( webglSupport )
ADD_MODULE( surfaceIllustrator )
IF( Teem_FOUND )
ADD_MODULE( teemGlyphs ${Teem_LIBRARIES} )
...
...
src/modules/surfaceIllustrator/WMSurfaceIllustrator.cpp
0 → 100644
View file @
c970c1a4
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <algorithm>
#include <list>
#include <limits>
#include <map>
#include <string>
#include <vector>
#include <osg/Geode>
#include <osg/LightModel>
#include "core/common/math/WMath.h"
#include "core/common/WLimits.h"
#include "core/graphicsEngine/shaders/WGEPropertyUniform.h"
#include "core/graphicsEngine/shaders/WGEShader.h"
#include "core/graphicsEngine/shaders/WGEShaderPropertyDefineOptions.h"
#include "core/graphicsEngine/WGEColormapping.h"
#include "core/graphicsEngine/WGEGeodeUtils.h"
#include "core/graphicsEngine/WGEManagedGroupNode.h"
#include "core/graphicsEngine/WGEUtils.h"
#include "core/graphicsEngine/WTriangleMesh.h"
#include "core/kernel/WKernel.h"
#include "WMSurfaceIllustrator.h"
#include "WMSurfaceIllustrator.xpm"
// This line is needed by the module loader to actually find your module.
W_LOADABLE_MODULE
(
WMSurfaceIllustrator
)
WMSurfaceIllustrator
::
WMSurfaceIllustrator
()
:
WModule
()
{
}
WMSurfaceIllustrator
::~
WMSurfaceIllustrator
()
{
// Cleanup!
}
boost
::
shared_ptr
<
WModule
>
WMSurfaceIllustrator
::
factory
()
const
{
// See "src/modules/template/" for an extensively documented example.
return
boost
::
shared_ptr
<
WModule
>
(
new
WMSurfaceIllustrator
()
);
}
const
char
**
WMSurfaceIllustrator
::
getXPMIcon
()
const
{
return
WMSurfaceIllustrator_xpm
;
}
const
std
::
string
WMSurfaceIllustrator
::
getName
()
const
{
return
"Surface Illustrator"
;
}
const
std
::
string
WMSurfaceIllustrator
::
getDescription
()
const
{
return
"Takes a (parameterized) triangle mesh as input and renders it as a shaded surface with serverall illustration options."
;
}
void
WMSurfaceIllustrator
::
updateMinMax
(
double
&
minX
,
double
&
maxX
,
// NOLINT
double
&
minY
,
double
&
maxY
,
// NOLINT
double
&
minZ
,
double
&
maxZ
,
const
osg
::
Vec3d
&
vector
)
const
// NOLINT
{
minX
=
std
::
min
(
minX
,
vector
.
x
()
);
minY
=
std
::
min
(
minY
,
vector
.
y
()
);
minZ
=
std
::
min
(
minZ
,
vector
.
z
()
);
maxX
=
std
::
max
(
maxX
,
vector
.
x
()
);
maxY
=
std
::
max
(
maxY
,
vector
.
y
()
);
maxZ
=
std
::
max
(
maxZ
,
vector
.
z
()
);
}
double
WMSurfaceIllustrator
::
getMedian
(
double
x
,
double
y
,
double
z
)
const
{
if
(
(
y
<
x
&&
z
>
x
)
||
(
z
<
x
&&
y
>
x
)
)
{
return
x
;
}
if
(
(
x
<
y
&&
z
>
y
)
||
(
x
<
y
&&
z
>
y
)
)
{
return
y
;
}
if
(
(
y
<
z
&&
x
>
z
)
||
(
x
<
z
&&
y
>
z
)
)
{
return
z
;
}
if
(
x
==
y
)
{
return
x
;
}
if
(
x
==
z
)
{
return
x
;
}
if
(
y
==
z
)
{
return
z
;
}
if
(
x
==
y
&&
y
==
z
&&
x
==
z
)
{
return
x
;
}
return
0
;
}
void
WMSurfaceIllustrator
::
connectors
()
{
// this input contains the triangle data
m_meshInput
=
WModuleInputData
<
WTriangleMesh
>::
createAndAdd
(
shared_from_this
(),
"mesh"
,
"The mesh to display"
);
// this input provides an additional map from vertex ID to color. This is especially useful for using the trimesh renderer in conjunction
// with clustering mechanisms and so on
m_colorMapInput
=
WModuleInputData
<
WColoredVertices
>::
createAndAdd
(
shared_from_this
(),
"colorMap"
,
"The special colors"
);
// call WModule's initialization
WModule
::
connectors
();
}
void
WMSurfaceIllustrator
::
properties
()
{
m_nbTriangles
=
m_infoProperties
->
addProperty
(
"Triangles"
,
"The number of triangles in the mesh."
,
0
);
m_nbTriangles
->
setMax
(
std
::
numeric_limits
<
int
>::
max
()
);
m_nbVertices
=
m_infoProperties
->
addProperty
(
"Vertices"
,
"The number of vertices in the mesh."
,
0
);
m_nbVertices
->
setMax
(
std
::
numeric_limits
<
int
>::
max
()
);
// some properties need to trigger an update
m_propCondition
=
boost
::
shared_ptr
<
WCondition
>
(
new
WCondition
()
);
// setup all the properties. See header file for their meaning and purpose.
m_showOutline
=
m_properties
->
addProperty
(
"Outline"
,
"Show all edges of the trinagulation as lines."
,
false
,
m_propCondition
);
m_coloringGroup
=
m_properties
->
addPropertyGroup
(
"Coloring"
,
"Coloring options and colormap options."
);
m_opacity
=
m_coloringGroup
->
addProperty
(
"Opacity %"
,
"Opaqueness of surface."
,
100.0
);
m_opacity
->
setMin
(
0.0
);
m_opacity
->
setMax
(
100.0
);
// Allow the user to select different colormodes
boost
::
shared_ptr
<
WItemSelection
>
colorModes
(
boost
::
shared_ptr
<
WItemSelection
>
(
new
WItemSelection
()
)
);
colorModes
->
addItem
(
"Single Color"
,
"The whole surface is colored using the default color."
);
colorModes
->
addItem
(
"From Mesh"
,
"The surface is colored according to the mesh."
);
colorModes
->
addItem
(
"From colormap connector"
,
"The surface is colored using the colormap on colorMap connector."
);
m_colorMode
=
m_coloringGroup
->
addProperty
(
"Color mode"
,
"Choose one of the available colorings."
,
colorModes
->
getSelectorFirst
(),
m_propCondition
);
WPropertyHelper
::
PC_SELECTONLYONE
::
addTo
(
m_colorMode
);
// this is the color used if single color is selected
m_color
=
m_coloringGroup
->
addProperty
(
"Default color"
,
"The color of of the surface."
,
WColor
(
.9
f
,
.9
f
,
0.9
f
,
1.0
f
),
m_propCondition
);
m_colormap
=
m_coloringGroup
->
addProperty
(
"Enable colormapping"
,
"Turn colormapping on"
,
false
);
m_parameterCenter
=
m_coloringGroup
->
addProperty
(
"Parameter center"
,
"Parameter center selection"
,
0.5
);
m_parameterCenter
->
setMin
(
-
1.0
);
m_parameterCenter
->
setMax
(
1.0
);
m_parameterWidth
=
m_coloringGroup
->
addProperty
(
"Parameter width"
,
"Parameter width selection"
,
0.1
);
m_parameterWidth
->
setMin
(
0.0
);
m_parameterWidth
->
setMax
(
2.0
);
// call WModule's initialization
WModule
::
properties
();
}
void
WMSurfaceIllustrator
::
moduleMain
()
{
// let the main loop awake if the data changes.
m_moduleState
.
setResetable
(
true
,
true
);
m_moduleState
.
add
(
m_meshInput
->
getDataChangedCondition
()
);
m_moduleState
.
add
(
m_colorMapInput
->
getDataChangedCondition
()
);
m_moduleState
.
add
(
m_propCondition
);
// signal ready state. The module is now ready to be used.
ready
();
////////////////////////////////////////////////////////////////////////////////////////////////////
// setup the main graphics-node:
////////////////////////////////////////////////////////////////////////////////////////////////////
// create a OSG node, which will contain the triangle data and allows easy transformations:
m_moduleNode
=
new
WGEManagedGroupNode
(
m_active
);
osg
::
ref_ptr
<
osg
::
LightModel
>
lightModel
(
new
osg
::
LightModel
()
);
osg
::
ref_ptr
<
osg
::
StateSet
>
moduleNodeState
=
m_moduleNode
->
getOrCreateStateSet
();
lightModel
->
setTwoSided
(
true
);
moduleNodeState
->
setAttributeAndModes
(
lightModel
.
get
(),
osg
::
StateAttribute
::
ON
);
WKernel
::
getRunningKernel
()
->
getGraphicsEngine
()
->
getScene
()
->
insert
(
m_moduleNode
);
// load the GLSL shader:
m_shader
=
new
WGEShader
(
"WMSurfaceIllustrator"
,
m_localPath
);
m_colorMapTransformation
=
new
osg
::
Uniform
(
"u_colorMapTransformation"
,
osg
::
Matrixd
::
identity
()
);
m_shader
->
addPreprocessor
(
WGEShaderPreprocessor
::
SPtr
(
new
WGEShaderPropertyDefineOptions
<
WPropBool
>
(
m_colormap
,
"COLORMAPPING_DISABLED"
,
"COLORMAPPING_ENABLED"
)
)
);
// set the opacity and material color property as GLSL uniforms:
moduleNodeState
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_opacity"
,
m_opacity
)
);
// loop until the module container requests the module to quit
while
(
!
m_shutdownFlag
()
)
{
// Now, the moduleState variable comes into play. The module can wait for the condition, which gets fired whenever the input receives data
// or an property changes. The main loop now waits until something happens.
debugLog
()
<<
"Waiting ..."
;
m_moduleState
.
wait
();
// woke up since the module is requested to finish
if
(
m_shutdownFlag
()
)
{
break
;
}
// Get data and check for invalid data.
boost
::
shared_ptr
<
WTriangleMesh
>
mesh
=
m_meshInput
->
getData
();
if
(
!
mesh
)
{
debugLog
()
<<
"Invalid Data. Disabling."
;
continue
;
}
renderMesh
(
mesh
);
}
// it is important to always remove the modules again
WKernel
::
getRunningKernel
()
->
getGraphicsEngine
()
->
getScene
()
->
remove
(
m_moduleNode
);
}
void
WMSurfaceIllustrator
::
renderMesh
(
boost
::
shared_ptr
<
WTriangleMesh
>
mesh
)
{
boost
::
shared_ptr
<
WColoredVertices
>
colorMap
=
m_colorMapInput
->
getData
();
m_nbTriangles
->
set
(
mesh
->
triangleSize
()
);
m_nbVertices
->
set
(
mesh
->
vertSize
()
);
// prepare the geometry node
debugLog
()
<<
"Start rendering Mesh"
;
osg
::
ref_ptr
<
osg
::
Geometry
>
geometry
;
osg
::
ref_ptr
<
osg
::
Geode
>
geode
(
new
osg
::
Geode
);
geode
->
getOrCreateStateSet
()
->
addUniform
(
m_colorMapTransformation
);
geode
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_parameterCenter"
,
m_parameterCenter
)
);
geode
->
getOrCreateStateSet
()
->
addUniform
(
new
WGEPropertyUniform
<
WPropDouble
>
(
"u_parameterWidth"
,
m_parameterWidth
)
);
// apply shader only to mesh
m_shader
->
apply
(
geode
);
// get the middle point of the mesh
std
::
vector
<
size_t
>
triangles
=
mesh
->
getTriangles
();
std
::
vector
<
size_t
>::
const_iterator
trianglesIterator
;
double
minX
=
wlimits
::
MAX_DOUBLE
;
double
minY
=
wlimits
::
MAX_DOUBLE
;
double
minZ
=
wlimits
::
MAX_DOUBLE
;
double
maxX
=
wlimits
::
MIN_DOUBLE
;
double
maxY
=
wlimits
::
MIN_DOUBLE
;
double
maxZ
=
wlimits
::
MIN_DOUBLE
;
for
(
trianglesIterator
=
triangles
.
begin
();
trianglesIterator
!=
triangles
.
end
();
trianglesIterator
++
)
{
osg
::
Vec3d
vectorX
=
mesh
->
getVertex
(
*
trianglesIterator
);
updateMinMax
(
minX
,
maxX
,
minY
,
maxY
,
minZ
,
maxZ
,
vectorX
);
}
// start rendering
boost
::
shared_ptr
<
WProgress
>
progress
=
boost
::
shared_ptr
<
WProgress
>
(
new
WProgress
(
"Rendering"
,
3
)
);
m_progress
->
addSubProgress
(
progress
);
++*
progress
;
// now create the mesh but handle the color mode properly
if
(
m_showOutline
->
get
(
true
)
)
{
geometry
=
wge
::
convertToOsgGeometryLines
(
mesh
,
m_color
->
get
(),
false
);
}
else
{
WItemSelector
colorModeSelector
=
m_colorMode
->
get
(
true
);
if
(
colorModeSelector
.
getItemIndexOfSelected
(
0
)
==
0
)
{
// use single color
geometry
=
wge
::
convertToOsgGeometry
(
mesh
,
m_color
->
get
(),
true
,
true
,
false
);
}
else
if
(
colorModeSelector
.
getItemIndexOfSelected
(
0
)
==
1
)
{
// take color from mesh
geometry
=
wge
::
convertToOsgGeometry
(
mesh
,
m_color
->
get
(),
true
,
true
,
true
);
}
else
{
// take color from map
if
(
colorMap
)
{
geometry
=
wge
::
convertToOsgGeometry
(
mesh
,
*
colorMap
,
m_color
->
get
(),
true
,
true
);
}
else
{
warnLog
()
<<
"External colormap not connected. Using default color."
;
geometry
=
wge
::
convertToOsgGeometry
(
mesh
,
m_color
->
get
(),
true
,
true
,
false
);
}
}
}
WGEColormapping
::
apply
(
geode
,
m_shader
);
// done. Set the new drawable
geode
->
addDrawable
(
geometry
);
m_moduleNode
->
clear
();
m_moduleNode
->
insert
(
geode
);
debugLog
()
<<
"Rendering Mesh done"
;
progress
->
finish
();
}
src/modules/surfaceIllustrator/WMSurfaceIllustrator.h
0 → 100644
View file @
c970c1a4
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMSURFACEILLUSTRATOR_H
#define WMSURFACEILLUSTRATOR_H
#include <string>
#include <osg/Uniform>
#include "core/common/datastructures/WColoredVertices.h"
#include "core/common/math/linearAlgebra/WVectorFixed.h"
#include "core/kernel/WModule.h"
#include "core/kernel/WModuleInputData.h"
#include "core/kernel/WModuleOutputData.h"
class
WTriangleMesh
;
class
WGEShader
;
class
WGEManagedGroupNode
;
/**
* This module renders the triangle mesh given at its input connector
* as a surface.
*
* \ingroup modules
*/
class
WMSurfaceIllustrator
:
public
WModule
{
public:
/**
* Constructor. Creates the module skeleton.
*/
WMSurfaceIllustrator
();
/**
* Destructor.
*/
virtual
~
WMSurfaceIllustrator
();
/**
* Gives back the name of this module.
* \return the module's name.
*/
virtual
const
std
::
string
getName
()
const
;
/**
* Gives back a description of this module.
* \return description to module.
*/
virtual
const
std
::
string
getDescription
()
const
;
/**
* Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
* should never be initialized or modified in some other way. A simple new instance is required.
*
* \return the prototype used to create every module in OpenWalnut.
*/
virtual
boost
::
shared_ptr
<
WModule
>
factory
()
const
;
/**
* Get the icon for this module in XPM format.
* \return The icon.
*/
virtual
const
char
**
getXPMIcon
()
const
;
protected:
/**
* Entry point after loading the module. Runs in separate thread.
*/
virtual
void
moduleMain
();
/**
* Initialize the connectors this module is using.
*/
virtual
void
connectors
();
/**
* Initialize the properties for this module.
*/
virtual
void
properties
();
private:
/**
* Calculates the bounding box of a vector and increases the specified one if needed.
*
* \param minX old maximum X and gets overwritten by new one
* \param maxX old maximum Y and gets overwritten by new one
* \param minY old minimum Z and gets overwritten by new one
* \param maxY old maximum X and gets overwritten by new one
* \param minZ old maximum Y and gets overwritten by new one
* \param maxZ old maximum Z and gets overwritten by new one
* \param vector the new vector to include in bbox calculation.
*/
void
updateMinMax
(
double
&
minX
,
double
&
maxX
,
double
&
minY
,
double
&
maxY
,
double
&
minZ
,
double
&
maxZ
,
const
osg
::
Vec3d
&
vector
)
const
;
/**
* Gets the median of three values.
*
* \param x first value
* \param y second value
* \param z third value
*
* \return the median of x,y,z
*/
double
getMedian
(
double
x
,
double
y
,
double
z
)
const
;
/**
* Center of the mesh. Needed for applying transformation with the mesh in (0,0,0).
*/
WVector3d
m_meshCenter
;
/**
* Group for all color and colormapping options.
*/
WPropGroup
m_coloringGroup
;
/**
* Turn Colormapping on/off
*/
WPropBool
m_colormap
;
/**
* Set center of selected surface parameter
*/
WPropDouble
m_parameterCenter
;
/**
* Set width of selected surface parameter interval
*/
WPropDouble
m_parameterWidth
;
/**
* A condition used to notify about changes in several properties.
*/
boost
::
shared_ptr
<
WCondition
>
m_propCondition
;
/**
* An input connector used to get meshes from other modules. The connection management between connectors must not be handled by the module.
*/
boost
::
shared_ptr
<
WModuleInputData
<
WTriangleMesh
>
>
m_meshInput
;
/**
* A map for mapping each vertex to a color.
*/
boost
::
shared_ptr
<
WModuleInputData
<
WColoredVertices
>
>
m_colorMapInput
;
/**
* A group wich contains all transformation tools.
*/
WPropGroup
m_groupTransformation
;
/**
* Set the transformation tool to default
*/
WPropTrigger
m_setDefault
;
/**
* Render the mesh
*
* \param mesh The mesh to be rendered.
*/
void
renderMesh
(
boost
::
shared_ptr
<
WTriangleMesh
>
mesh
);
/**
* OSG Uniform for the transformation matrix which transforms the mesh. Needed for the colormapper
*/
osg
::
ref_ptr
<
osg
::
Uniform
>
m_colorMapTransformation
;
/**
* The mesh's opacity value.
*/
WPropDouble
m_opacity
;
/**
* Toggle showing outline instead fo surface.
*/
WPropBool
m_showOutline
;
/**
* The color of the mesh to be rendered.
*/
WPropColor
m_color
;
/**
* Which colormode should be used?
*/
WPropSelection
m_colorMode
;
WPropInt
m_nbTriangles
;
//!< Info-property showing the number of triangles in the mesh.
WPropInt
m_nbVertices
;
//!< Info-property showing the number of vertices in the mesh.
/**
* The node containing all geometry nodes.
*/
WGEManagedGroupNode
::
SPtr
m_moduleNode
;
/**
* The shader for the mesh
*/
osg
::
ref_ptr
<
WGEShader
>
m_shader
;
};
#endif // WMSURFACEILLUSTRATOR_H
src/modules/surfaceIllustrator/WMSurfaceIllustrator.xpm
0 → 100644
View file @
c970c1a4
/* XPM */
static const char * WMSurfaceIllustrator_xpm[] = {
"32 32 3 1",
" c None",
". c #000000",
"+ c #FFFF00",
" ",
" .. ",
" ...... ..... ",
" .......... ......+.. ",
" .....+++.............++++.. ",
" ..+...++++++.....++++++++.. ",
" .+++..+++++++...++++++++.. ",
" .++++..++++++....+++++++.. ",
" ..++++...++++..+...+++++.. ",
" ..+++++...+++..++...++++.. ",
" ..+++++++..++..+++...+++.. ",
" .++++++++..++.+++++..++.. ",
" .+++++++++....++++++..+.. ",
" ..+++++++++...+++++++.... ",
" ......................... ",
" ........+++...++++....... ",
" ..+++++++++...+++++++.... ",
" ..++++++++....++++++..+.. ",
" .+++++++...++.+++++..++.. ",
" ..++++++...+++.++++..+++.. ",