Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CAMP
campvis-public
Commits
f222dd65
Commit
f222dd65
authored
Jan 20, 2014
by
Christian Schulte zu Berge
Browse files
Merge branch 'tensorglyphrenderer' of /mnt/bigone/git/repositories/berge/campvis into development
parents
1b676808
2d96cece
Changes
10
Hide whitespace changes
Inline
Side-by-side
core/glsl/passthrough.vert
View file @
f222dd65
...
...
@@ -54,7 +54,7 @@ uniform mat4 _projectionMatrix = mat4(
void
main
()
{
gl_Position
=
_projectionMatrix
*
(
_viewMatrix
*
(
_modelMatrix
*
vec4
(
in_Position
,
1
.
0
)));
ex_Position
=
gl
_Position
;
ex_Position
=
vec4
(
in
_Position
,
1
.
0
)
;
ex_TexCoord
=
in_TexCoord
;
ex_Color
=
in_Color
;
...
...
modules/tensor/glsl/tensorglyphrenderer.frag
0 → 100644
View file @
f222dd65
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include
"tools/shading.frag"
in
vec3
ex_Position
;
///< incoming texture coordinate
in
vec3
ex_Normal
;
///< incoming texture coordinate
out
vec4
out_Color
;
///< outgoing fragment color
uniform
vec4
_color
;
uniform
LightSource
_lightSource
;
uniform
vec3
_cameraPosition
;
void
main
()
{
out_Color
=
_color
;
#ifdef ENABLE_SHADING
// compute gradient (needed for shading and normals)
vec3
gradient
=
ex_Normal
;
out_Color
.
rgb
=
calculatePhongShading
(
ex_Position
,
_lightSource
,
_cameraPosition
,
gradient
,
_color
.
rgb
,
_color
.
rgb
,
vec3
(
1
.
0
,
1
.
0
,
1
.
0
));
#endif
//out_Color = vec4(ex_Normal, 1.0);
}
modules/tensor/glsl/tensorglyphrenderer.vert
0 → 100644
View file @
f222dd65
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
layout
(
location
=
0
)
in
vec3
in_Position
;
///< incoming vertex position
layout
(
location
=
3
)
in
vec3
in_Normal
;
///< incoming normal direction
out
vec3
ex_Position
;
///< outgoing world coordinates
out
vec3
ex_Normal
;
///< outgoing normal direction
/// Matrix defining model-to-world transformation
uniform
mat4
_modelMatrix
=
mat4
(
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
);
/// Matrix defining view transformation
uniform
mat4
_viewMatrix
=
mat4
(
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
);
/// Matrix defining projection transformation
uniform
mat4
_projectionMatrix
=
mat4
(
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
,
1
.
0
);
void
main
()
{
gl_Position
=
_projectionMatrix
*
(
_viewMatrix
*
(
_modelMatrix
*
vec4
(
in_Position
,
1
.
0
)));
ex_Position
=
in_Position
;
mat4
normalMatrix
=
transpose
(
inverse
(
_modelMatrix
));
vec4
normalTmp
=
(
normalMatrix
*
vec4
(
in_Normal
,
0
.
0
));
ex_Normal
=
normalize
((
normalTmp
).
xyz
);
}
modules/tensor/pipelines/tensordemo.cpp
View file @
f222dd65
...
...
@@ -35,13 +35,25 @@ namespace campvis {
:
AutoEvaluationPipeline
(
dc
)
,
_imageReader
()
,
_ta
()
,
_sliceExtractor
(
&
_canvasSize
)
,
_wheelHandler
(
&
_sliceExtractor
.
p_zSliceNumber
)
,
_glyphRenderer
(
&
_canvasSize
)
,
_sliceRenderer
(
&
_canvasSize
)
,
_rtc
(
&
_canvasSize
)
,
p_camera
(
"Camera"
,
"Camera"
,
tgt
::
Camera
())
,
p_sliceNumber
(
"SliceNuber"
,
"Slice Number"
,
0
,
0
,
256
)
,
_trackballEH
(
0
)
{
addProperty
(
&
p_camera
);
addProperty
(
&
p_sliceNumber
);
_trackballEH
=
new
TrackballNavigationEventListener
(
&
p_camera
,
&
_canvasSize
);
addEventListenerToBack
(
_trackballEH
);
addProcessor
(
&
_imageReader
);
addProcessor
(
&
_ta
);
addProcessor
(
&
_sliceExtractor
);
addEventListenerToBack
(
&
_wheelHandler
);
addProcessor
(
&
_glyphRenderer
);
addProcessor
(
&
_sliceRenderer
);
addProcessor
(
&
_rtc
);
}
TensorDemo
::~
TensorDemo
()
{
...
...
@@ -50,21 +62,46 @@ namespace campvis {
void
TensorDemo
::
init
()
{
AutoEvaluationPipeline
::
init
();
p_camera
.
addSharedProperty
(
&
_glyphRenderer
.
p_camera
);
p_camera
.
addSharedProperty
(
&
_sliceRenderer
.
p_camera
);
p_sliceNumber
.
addSharedProperty
(
&
_glyphRenderer
.
p_sliceNumber
);
p_sliceNumber
.
addSharedProperty
(
&
_sliceRenderer
.
p_sliceNumber
);
_imageReader
.
p_url
.
setValue
(
CAMPVIS_SOURCE_DIR
"/modules/tensor/sampledata/planar_tensor.mhd"
);
_imageReader
.
p_targetImageID
.
setValue
(
"reader.output"
);
_imageReader
.
p_targetImageID
.
addSharedProperty
(
&
_ta
.
p_inputImage
);
_ta
.
p_outputProperties
[
0
]
->
_imageId
.
addSharedProperty
(
&
_sliceExtractor
.
p_sourceImageID
);
_ta
.
p_outputProperties
[
0
]
->
_imageType
.
selectById
(
"MainEigenvector"
);
_ta
.
p_outputProperties
[
0
]
->
_imageId
.
addSharedProperty
(
&
_sliceRenderer
.
p_sourceImageID
);
_ta
.
p_outputProperties
[
0
]
->
_imageType
.
selectById
(
"Trace"
);
_ta
.
p_evalsImage
.
addSharedProperty
(
&
_glyphRenderer
.
p_inputEigenvalues
);
_ta
.
p_evecsImage
.
addSharedProperty
(
&
_glyphRenderer
.
p_inputEigenvectors
);
_ta
.
s_validated
.
connect
(
this
,
&
TensorDemo
::
onProcessorValidated
);
_sliceExtractor
.
p_xSliceNumber
.
setValue
(
0
);
_glyphRenderer
.
p_renderOutput
.
setValue
(
"glyphs"
);
_glyphRenderer
.
p_renderOutput
.
addSharedProperty
(
&
_rtc
.
p_firstImageId
);
Geometry1DTransferFunction
*
tf
=
new
Geometry1DTransferFunction
(
128
,
tgt
::
vec2
(
0.
f
,
1.
f
));
tf
->
addGeometry
(
TFGeometry1D
::
createQuad
(
tgt
::
vec2
(
0.
f
,
1.
f
),
tgt
::
col4
(
0
,
0
,
0
,
0
),
tgt
::
col4
(
255
,
255
,
255
,
255
)));
_sliceExtractor
.
p_transferFunction
.
replaceTF
(
tf
);
_sliceRenderer
.
p_transferFunction
.
replaceTF
(
tf
);
_sliceRenderer
.
p_targetImageID
.
setValue
(
"slice"
);
_sliceRenderer
.
p_targetImageID
.
addSharedProperty
(
&
_rtc
.
p_secondImageId
);
_rtc
.
p_compositingMethod
.
selectById
(
"depth"
);
_rtc
.
p_targetImageId
.
setValue
(
"composed"
);
_renderTargetID
.
setValue
(
"composed"
);
}
_renderTargetID
.
setValue
(
"renderTarget"
);
_renderTargetID
.
addSharedProperty
(
&
(
_sliceExtractor
.
p_targetImageID
));
void
TensorDemo
::
onProcessorValidated
(
AbstractProcessor
*
processor
)
{
if
(
processor
==
&
_ta
)
{
// update camera
ScopedTypedData
<
IHasWorldBounds
>
img
(
*
_data
,
_ta
.
p_evalsImage
.
getValue
());
if
(
img
)
{
_trackballEH
->
reinitializeCamera
(
img
);
}
}
}
}
modules/tensor/pipelines/tensordemo.h
View file @
f222dd65
...
...
@@ -25,12 +25,16 @@
#ifndef TENSORDEMO_H__
#define TENSORDEMO_H__
#include
"core/eventhandlers/mwheeltonumericpropertyeventlistener.h"
#include
"core/pipeline/autoevaluationpipeline.h"
#include
"core/eventhandlers/mwheeltonumericpropertyeventlistener.h"
#include
"core/eventhandlers/trackballnavigationeventlistener.h"
#include
"modules/io/processors/mhdimagereader.h"
#include
"modules/tensor/processors/tensoranalyzer.h"
#include
"modules/vis/processors/sliceextractor.h"
#include
"modules/tensor/processors/tensorglyphrenderer.h"
#include
"modules/vis/processors/slicerenderer3d.h"
#include
"modules/vis/processors/rendertargetcompositor.h"
namespace
campvis
{
class
TensorDemo
:
public
AutoEvaluationPipeline
{
...
...
@@ -54,11 +58,22 @@ namespace campvis {
static
const
std
::
string
getId
()
{
return
"TensorDemo"
;
};
protected:
/**
* Slot getting called when one of the observed processors got validated.
* Updates the camera properties, when the input image has changed.
* \param processor The processor that emitted the signal
*/
virtual
void
onProcessorValidated
(
AbstractProcessor
*
processor
);
MhdImageReader
_imageReader
;
TensorAnalyzer
_ta
;
SliceExtractor
_sliceExtractor
;
TensorGlyphRenderer
_glyphRenderer
;
SliceRenderer3D
_sliceRenderer
;
RenderTargetCompositor
_rtc
;
MWheelToNumericPropertyEventListener
_wheelHandler
;
CameraProperty
p_camera
;
IntProperty
p_sliceNumber
;
TrackballNavigationEventListener
*
_trackballEH
;
};
}
...
...
modules/tensor/processors/tensoranalyzer.h
View file @
f222dd65
...
...
@@ -81,9 +81,14 @@ namespace campvis {
/// \see AbstractProcessor::deinit()
virtual
void
deinit
();
/**
* Adds another output for this processor (i.e. adds another OutputPropertyPair).
*/
void
addOutput
();
DataNameProperty
p_inputImage
;
///< ID for input volume
DataNameProperty
p_evalsImage
;
///< ID for output
gradient
volume
DataNameProperty
p_evecsImage
;
///< ID for output
gradient
volume
DataNameProperty
p_evalsImage
;
///< ID for output
eigenvalue
volume
DataNameProperty
p_evecsImage
;
///< ID for output
eigenvector
volume
GenericOptionProperty
<
DegeneratedEvHandling
>
p_degeneratedHandling
;
///< Handling of degenerated tensors
BoolProperty
p_maskMixedTensors
;
...
...
@@ -109,11 +114,6 @@ namespace campvis {
*/
void
computeOutput
(
DataContainer
&
data
,
size_t
index
);
/**
* Adds another output for this processor (i.e. adds another OutputPropertyPair).
*/
void
addOutput
();
DataHandle
_eigenvalues
;
///< Current eigenvalues cached
DataHandle
_eigenvectors
;
///< Current eigenvectors cached
...
...
modules/tensor/processors/tensorglyphrenderer.cpp
0 → 100644
View file @
f222dd65
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include
"TensorGlyphRenderer.h"
#include
"tgt/tgt_math.h"
#include
"tgt/logmanager.h"
#include
"tgt/shadermanager.h"
#include
"core/datastructures/imagedata.h"
#include
"core/datastructures/geometrydatafactory.h"
#include
"core/datastructures/renderdata.h"
#include
"core/pipeline/processordecoratorshading.h"
namespace
campvis
{
static
const
GenericOption
<
TensorGlyphRenderer
::
GlyphType
>
glyphTypes
[
3
]
=
{
GenericOption
<
TensorGlyphRenderer
::
GlyphType
>
(
"ellipsoid"
,
"Ellipsoid Glyph"
,
TensorGlyphRenderer
::
ELLIPSOID
),
GenericOption
<
TensorGlyphRenderer
::
GlyphType
>
(
"cuboid"
,
"Cuboid Glyph"
,
TensorGlyphRenderer
::
CUBOID
),
GenericOption
<
TensorGlyphRenderer
::
GlyphType
>
(
"multi"
,
"Multi Ellipsoid Glyph"
,
TensorGlyphRenderer
::
MULTI
)
};
static
const
GenericOption
<
TensorGlyphRenderer
::
SliceOrientation
>
sliceOrientationOptions
[
3
]
=
{
GenericOption
<
TensorGlyphRenderer
::
SliceOrientation
>
(
"z"
,
"XY Plane"
,
TensorGlyphRenderer
::
XY_PLANE
),
GenericOption
<
TensorGlyphRenderer
::
SliceOrientation
>
(
"y"
,
"XZ Plane"
,
TensorGlyphRenderer
::
XZ_PLANE
),
GenericOption
<
TensorGlyphRenderer
::
SliceOrientation
>
(
"x"
,
"YZ Plane"
,
TensorGlyphRenderer
::
YZ_PLANE
)
};
const
std
::
string
TensorGlyphRenderer
::
loggerCat_
=
"CAMPVis.modules.classification.TensorGlyphRenderer"
;
TensorGlyphRenderer
::
TensorGlyphRenderer
(
IVec2Property
*
viewportSizeProp
)
:
VisualizationProcessor
(
viewportSizeProp
)
,
p_inputEigenvalues
(
"InputEigenvalues"
,
"Input Eigenvalues Image"
,
"eigenvalues"
,
DataNameProperty
::
READ
,
INVALID_RESULT
|
INVALID_PROPERTIES
)
,
p_inputEigenvectors
(
"InputEigenvectors"
,
"Input Eigenvectors Image"
,
"eigenvectors"
,
DataNameProperty
::
READ
,
INVALID_RESULT
|
INVALID_PROPERTIES
)
,
p_renderOutput
(
"RenderOutput"
,
"Output Image"
,
"TensorGlyphRenderer.output"
,
DataNameProperty
::
WRITE
)
,
p_glyphType
(
"GlyphType"
,
"Glyph Type to Render"
,
glyphTypes
,
3
)
,
p_glyphSize
(
"GlyphSize"
,
"Glyph Size"
,
1.
f
,
.1
f
,
5.
f
)
,
p_camera
(
"Camera"
,
"Camera"
,
tgt
::
Camera
())
,
p_sliceOrientation
(
"SliceOrientation"
,
"Slice Orientation"
,
sliceOrientationOptions
,
3
,
INVALID_RESULT
|
INVALID_PROPERTIES
)
,
p_sliceNumber
(
"SliceNumber"
,
"Slice Number"
,
0
,
0
,
0
)
,
_ellipsoidGeometry
(
0
)
,
_cubeGeometry
(
0
)
{
addDecorator
(
new
ProcessorDecoratorShading
());
addProperty
(
&
p_inputEigenvalues
);
addProperty
(
&
p_inputEigenvectors
);
addProperty
(
&
p_renderOutput
);
addProperty
(
&
p_glyphType
);
addProperty
(
&
p_glyphSize
);
addProperty
(
&
p_camera
);
addProperty
(
&
p_sliceOrientation
);
addProperty
(
&
p_sliceNumber
);
decoratePropertyCollection
(
this
);
}
TensorGlyphRenderer
::~
TensorGlyphRenderer
()
{
}
void
TensorGlyphRenderer
::
init
()
{
VisualizationProcessor
::
init
();
_shader
=
ShdrMgr
.
load
(
"modules/tensor/glsl/tensorglyphrenderer.vert"
,
"modules/tensor/glsl/tensorglyphrenderer.frag"
,
generateGlslHeader
());
_cubeGeometry
=
GeometryDataFactory
::
createCube
(
tgt
::
Bounds
(
tgt
::
vec3
(
-
.5
f
),
tgt
::
vec3
(
.5
f
)),
tgt
::
Bounds
(
tgt
::
vec3
(
0.
f
),
tgt
::
vec3
(
1.
f
)));
_ellipsoidGeometry
=
GeometryDataFactory
::
createSphere
(
8
,
16
);
}
void
TensorGlyphRenderer
::
deinit
()
{
ShdrMgr
.
dispose
(
_shader
);
delete
_ellipsoidGeometry
;
_ellipsoidGeometry
=
0
;
delete
_cubeGeometry
;
_cubeGeometry
=
0
;
VisualizationProcessor
::
deinit
();
}
void
TensorGlyphRenderer
::
updateResult
(
DataContainer
&
dataContainer
)
{
if
(
_cubeGeometry
==
0
||
_ellipsoidGeometry
==
0
)
{
LERROR
(
"Error initializing glyph geometries."
);
return
;
}
GenericImageRepresentationLocal
<
float
,
3
>::
ScopedRepresentation
evals
(
dataContainer
,
p_inputEigenvalues
.
getValue
());
GenericImageRepresentationLocal
<
float
,
9
>::
ScopedRepresentation
evecs
(
dataContainer
,
p_inputEigenvectors
.
getValue
());
if
(
evals
&&
evecs
)
{
if
(
evals
->
getSize
()
==
evecs
->
getSize
())
{
const
tgt
::
Camera
&
cam
=
p_camera
.
getValue
();
const
tgt
::
svec3
&
imgSize
=
evals
->
getSize
();
glEnable
(
GL_DEPTH_TEST
);
_shader
->
activate
();
_shader
->
setIgnoreUniformLocationError
(
true
);
_shader
->
setUniform
(
"_viewportSizeRCP"
,
1.
f
/
tgt
::
vec2
(
getEffectiveViewportSize
()));
_shader
->
setUniform
(
"_projectionMatrix"
,
cam
.
getProjectionMatrix
());
_shader
->
setUniform
(
"_viewMatrix"
,
cam
.
getViewMatrix
());
decorateRenderProlog
(
dataContainer
,
_shader
);
FramebufferActivationGuard
fag
(
this
);
createAndAttachColorTexture
();
createAndAttachDepthTexture
();
glClear
(
GL_COLOR_BUFFER_BIT
|
GL_DEPTH_BUFFER_BIT
);
switch
(
p_sliceOrientation
.
getOptionValue
())
{
case
XY_PLANE
:
for
(
size_t
x
=
0
;
x
<
imgSize
.
x
;
++
x
)
{
for
(
size_t
y
=
0
;
y
<
imgSize
.
y
;
++
y
)
{
renderTensorGlyph
(
evals
,
evecs
,
tgt
::
ivec3
(
static_cast
<
int
>
(
x
),
static_cast
<
int
>
(
y
),
p_sliceNumber
.
getValue
()));
}
}
break
;
case
XZ_PLANE
:
for
(
size_t
x
=
0
;
x
<
imgSize
.
x
;
++
x
)
{
for
(
size_t
z
=
0
;
z
<
imgSize
.
z
;
++
z
)
{
renderTensorGlyph
(
evals
,
evecs
,
tgt
::
ivec3
(
static_cast
<
int
>
(
x
),
p_sliceNumber
.
getValue
(),
static_cast
<
int
>
(
z
)));
}
}
break
;
case
YZ_PLANE
:
for
(
size_t
y
=
0
;
y
<
imgSize
.
y
;
++
y
)
{
for
(
size_t
z
=
0
;
z
<
imgSize
.
z
;
++
z
)
{
renderTensorGlyph
(
evals
,
evecs
,
tgt
::
ivec3
(
p_sliceNumber
.
getValue
(),
static_cast
<
int
>
(
y
),
static_cast
<
int
>
(
z
)));
}
}
break
;
}
decorateRenderEpilog
(
_shader
);
_shader
->
deactivate
();
glDisable
(
GL_DEPTH_TEST
);
dataContainer
.
addData
(
p_renderOutput
.
getValue
(),
new
RenderData
(
_fbo
));
}
}
else
{
LERROR
(
"Could not find suitable input data."
);
}
validate
(
INVALID_RESULT
);
}
void
TensorGlyphRenderer
::
updateProperties
(
DataContainer
&
dataContainer
)
{
GenericImageRepresentationLocal
<
float
,
3
>::
ScopedRepresentation
evals
(
dataContainer
,
p_inputEigenvalues
.
getValue
());
GenericImageRepresentationLocal
<
float
,
9
>::
ScopedRepresentation
evecs
(
dataContainer
,
p_inputEigenvectors
.
getValue
());
if
(
evals
&&
evecs
)
{
if
(
evals
->
getSize
()
==
evecs
->
getSize
())
{
switch
(
p_sliceOrientation
.
getOptionValue
())
{
case
XY_PLANE
:
p_sliceNumber
.
setMaxValue
(
static_cast
<
int
>
(
evals
->
getSize
().
z
-
1
));
break
;
case
XZ_PLANE
:
p_sliceNumber
.
setMaxValue
(
static_cast
<
int
>
(
evals
->
getSize
().
y
-
1
));
break
;
case
YZ_PLANE
:
p_sliceNumber
.
setMaxValue
(
static_cast
<
int
>
(
evals
->
getSize
().
x
-
1
));
break
;
}
}
else
{
LERROR
(
"Size of eigenvalue image and eigenvector image mismatch!"
);
}
}
validate
(
INVALID_PROPERTIES
);
}
void
TensorGlyphRenderer
::
updateShader
()
{
_shader
->
setHeaders
(
generateGlslHeader
());
_shader
->
rebuild
();
validate
(
INVALID_SHADER
);
}
std
::
string
TensorGlyphRenderer
::
generateGlslHeader
()
const
{
std
::
string
toReturn
=
getDecoratedHeader
();
return
toReturn
;
}
void
TensorGlyphRenderer
::
renderTensorGlyph
(
const
GenericImageRepresentationLocal
<
float
,
3
>*
evals
,
const
GenericImageRepresentationLocal
<
float
,
9
>*
evecs
,
const
tgt
::
vec3
&
position
)
{
/// minimum scale factor
const
float
EPS
=
.1
f
;
// gather value
const
tgt
::
vec3
&
eigenvalues
=
evals
->
getElement
(
position
);
const
tgt
::
mat3
&
eigenvectors
=
evecs
->
getElement
(
position
);
if
(
eigenvalues
==
tgt
::
vec3
::
zero
||
eigenvectors
==
tgt
::
mat3
::
zero
)
return
;
// compute rotation matrix
tgt
::
vec3
rotx
=
tgt
::
normalize
(
eigenvectors
[
0
]);
tgt
::
vec3
roty
=
tgt
::
normalize
(
eigenvectors
[
1
]);
tgt
::
vec3
rotz
=
tgt
::
normalize
(
eigenvectors
[
2
]);
tgt
::
mat4
rotationMatrix
(
rotx
[
0
],
rotx
[
1
],
rotx
[
2
],
0.
f
,
roty
[
0
],
roty
[
1
],
roty
[
2
],
0.
f
,
rotz
[
0
],
rotz
[
1
],
rotz
[
2
],
0.
f
,
0.
f
,
0.
f
,
0.
f
,
1.
f
);
float
divScale
=
(
1.
f
-
2.
f
*
EPS
)
/
(
eigenvalues
[
0
]);
const
tgt
::
mat4
&
voxelToWorldMatrix
=
evals
->
getParent
()
->
getMappingInformation
().
getVoxelToWorldMatrix
();
// compute model matrix (without glyph-related transformation
tgt
::
mat4
modelMatrix
=
voxelToWorldMatrix
*
tgt
::
mat4
::
createTranslation
(
position
)
*
rotationMatrix
*
tgt
::
mat4
::
createScale
(
tgt
::
vec3
(
p_glyphSize
.
getValue
()));
// setup shader
_shader
->
setUniform
(
"_color"
,
tgt
::
vec4
(
rotx
,
1.
f
));
switch
(
p_glyphType
.
getOptionValue
())
{
case
CUBOID
:
// render single cuboid
_shader
->
setUniform
(
"_modelMatrix"
,
modelMatrix
*
tgt
::
mat4
::
createScale
(
tgt
::
vec3
((
1.
f
-
EPS
),
(
EPS
+
divScale
*
eigenvalues
[
1
]),
(
EPS
+
divScale
*
eigenvalues
[
2
]))));
_cubeGeometry
->
render
(
GL_POLYGON
);
break
;
case
ELLIPSOID
:
// render single ellipsoid
_shader
->
setUniform
(
"_modelMatrix"
,
modelMatrix
*
tgt
::
mat4
::
createScale
(
tgt
::
vec3
((
1.
f
-
EPS
),
(
EPS
+
divScale
*
eigenvalues
[
1
]),
(
EPS
+
divScale
*
eigenvalues
[
2
]))));
_ellipsoidGeometry
->
render
(
GL_TRIANGLE_STRIP
);
break
;
case
MULTI
:
// render three ellipsoids in different shapes
_shader
->
setUniform
(
"_modelMatrix"
,
modelMatrix
*
tgt
::
mat4
::
createScale
(
tgt
::
vec3
(
divScale
*
eigenvalues
[
2
],
divScale
*
eigenvalues
[
2
],
divScale
*
eigenvalues
[
2
])));
_ellipsoidGeometry
->
render
(
GL_TRIANGLE_STRIP
);
_shader
->
setUniform
(
"_modelMatrix"
,
modelMatrix
*
tgt
::
mat4
::
createScale
(
tgt
::
vec3
(
divScale
*
eigenvalues
[
1
],
divScale
*
eigenvalues
[
1
],
EPS
)));
_ellipsoidGeometry
->
render
(
GL_TRIANGLE_STRIP
);
_shader
->
setUniform
(
"_modelMatrix"
,
modelMatrix
*
tgt
::
mat4
::
createScale
(
tgt
::
vec3
(
divScale
*
eigenvalues
[
0
],
EPS
,
EPS
)));
_ellipsoidGeometry
->
render
(
GL_TRIANGLE_STRIP
);
break
;
}
}
}
modules/tensor/processors/tensorglyphrenderer.h
0 → 100644
View file @
f222dd65
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#ifndef TENSORGLYPHRENDERER_H__
#define TENSORGLYPHRENDERER_H__
#include
<string>
#include
"core/pipeline/visualizationprocessor.h"
#include
"core/pipeline/abstractprocessordecorator.h"
#include
"core/properties/cameraproperty.h"
#include
"core/properties/datanameproperty.h"
#include
"core/properties/floatingpointproperty.h"
#include
"core/properties/genericproperty.h"
#include
"core/properties/numericproperty.h"
#include
"core/properties/optionproperty.h"
#include
"core/datastructures/genericimagerepresentationlocal.h"
#include
"core/datastructures/geometrydata.h"
namespace
tgt
{
class
Shader
;
}
namespace
campvis
{
/**
* Renders axis-aligned slices with tensor glyphs.
*/
class
TensorGlyphRenderer
:
public
VisualizationProcessor
,
public
HasProcessorDecorators
{