Commit 2b03c390 authored by schultezub's avatar schultezub
Browse files

Further work on IxpvDemo, introducing SliceRenderer3D

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@390 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent ed72ad48
......@@ -86,7 +86,7 @@ namespace campvis {
* \param epsilon Clipping precision
* \return The clipped MeshGeometry
*/
MeshGeometry clipAgainstPlane(float p, const tgt::vec3& normal, bool close = true, float epsilon = 1e-8f) const;
MeshGeometry clipAgainstPlane(float p, const tgt::vec3& normal, bool close = true, float epsilon = 1e-4f) const;
/**
* Renders this MeshGeometry.
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, 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".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#version 330
in vec3 ex_TexCoord;
out vec4 out_Color;
#include "tools/texture2d.frag"
#include "tools/transferfunction.frag"
uniform Texture2D _texture;
uniform TransferFunction1D _transferFunction;
void main() {
float intensity = getElement2DNormalized(_texture, ex_TexCoord.xy).a;
out_Color = lookupTF(_transferFunction, intensity);
}
......@@ -47,24 +47,24 @@ namespace campvis {
, _ctFullDRR(_effectiveRenderTargetSize)
, _ctClippedDRR(_effectiveRenderTargetSize)
, _usReader()
, _usSliceExtractor(_effectiveRenderTargetSize)
, _usSliceRenderer(_effectiveRenderTargetSize)
, _compositor(_effectiveRenderTargetSize)
, _camera("camera", "Camera")
, _trackballHandler(0)
{
// addProcessor(&_xrayReader);
//
// addProcessor(&_ctReader);
// addProcessor(&_ctProxy);
// addProcessor(&_ctFullEEP);
// addProcessor(&_ctClippedEEP);
// addProcessor(&_ctFullDRR);
// addProcessor(&_ctClippedDRR);
addProcessor(&_xrayReader);
addProcessor(&_ctReader);
addProcessor(&_ctProxy);
addProcessor(&_ctFullEEP);
addProcessor(&_ctClippedEEP);
addProcessor(&_ctFullDRR);
addProcessor(&_ctClippedDRR);
addProcessor(&_usReader);
addProcessor(&_usSliceExtractor);
addProcessor(&_usSliceRenderer);
// addProcessor(&_compositor);
addProcessor(&_compositor);
addProperty(&_camera);
......@@ -85,6 +85,7 @@ namespace campvis {
_camera.addSharedProperty(&_ctClippedEEP.p_camera);
_camera.addSharedProperty(&_ctFullDRR.p_camera);
_camera.addSharedProperty(&_ctClippedDRR.p_camera);
_camera.addSharedProperty(&_usSliceRenderer.p_camera);
// = X-Ray Setup ==================================================================================
_xrayReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Cowleg_CarmXrayImages\\APView_1.jpg");
......@@ -126,11 +127,11 @@ namespace campvis {
_usReader.p_url.setValue("D:\\Medical Data\\XrayDepthPerception\\DataCowLeg\\Ultrasound\\gaussianSmoothedUS_UChar.mhd");
_usReader.p_targetImageID.setValue("us.image");
_usReader.p_targetImageID.connect(&_usSliceExtractor.p_sourceImageID);
_usReader.p_targetImageID.connect(&_usSliceRenderer.p_sourceImageID);
_usSliceExtractor.p_targetImageID.setValue("us.slice");
_usSliceRenderer.p_targetImageID.setValue("us.slice");
_usSliceExtractor.p_sliceNumber.setValue(0);
_usSliceRenderer.p_sliceNumber.setValue(0);
// = Compositing Setup ============================================================================
......@@ -193,20 +194,20 @@ namespace campvis {
if (img != 0) {
ImageDataLocal* local = ImageDataConverter::tryConvert<ImageDataLocal>(img);
if (local != 0) {
DataHandle dh = _data.addData("us.image", local);
DataHandle dh = _data.addData("us.image.local", local);
Interval<float> ii = local->getNormalizedIntensityRange();
_usSliceExtractor.p_transferFunction.getTF()->setImageHandle(dh);
_usSliceExtractor.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(ii.getLeft(), ii.getRight()));
_usSliceExtractor.p_sliceNumber.setValue(125);
_usSliceRenderer.p_transferFunction.getTF()->setImageHandle(dh);
_usSliceRenderer.p_transferFunction.getTF()->setIntensityDomain(tgt::vec2(ii.getLeft(), ii.getRight()));
_usSliceRenderer.p_sliceNumber.setValue(125);
{
tgt::GLContextScopedLock lock(_canvas->getContext());
ImageDataGL* gl = ImageDataConverter::tryConvert<ImageDataGL>(local);
if (gl != 0) {
_data.addData("foobar-test", gl);
_data.addData(_usSliceRenderer.p_sourceImageID.getValue(), gl);
}
}
CtxtMgr.releaseCurrentContext();
CtxtMgr.releaseCurrentContext();
}
}
}
......
......@@ -45,6 +45,7 @@
#include "modules/vis/processors/drrraycaster.h"
#include "modules/vis/processors/simpleraycaster.h"
#include "modules/vis/processors/rendertargetcompositor.h"
#include "modules/vis/processors/slicerenderer3d.h"
namespace campvis {
......@@ -85,7 +86,7 @@ namespace campvis {
DRRRaycaster _ctClippedDRR;
MhdImageReader _usReader;
SliceExtractor _usSliceExtractor;
SliceRenderer3D _usSliceRenderer;
RenderTargetCompositor _compositor;
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "slicerenderer3d.h"
#include "tgt/bounds.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagedatagl.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/datastructures/imagedataconverter.h"
#include "core/datastructures/meshgeometry.h"
#include "core/datastructures/facegeometry.h"
#include "core/classification/simpletransferfunction.h"
#include "core/tools/quadrenderer.h"
namespace campvis {
const std::string SliceRenderer3D::loggerCat_ = "CAMPVis.modules.vis.SliceRenderer3D";
SliceRenderer3D::SliceRenderer3D(GenericProperty<tgt::ivec2>& canvasSize)
: VisualizationProcessor(canvasSize)
, p_sourceImageID("sourceImageID", "Input Image", "", DataNameProperty::READ)
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_camera("Camera", "Camera")
, p_sliceNumber("sliceNumber", "Slice Number", 0, 0, 0)
, p_transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
, _shader(0)
{
addProperty(&p_sourceImageID);
addProperty(&p_targetImageID);
addProperty(&p_sliceNumber);
addProperty(&p_transferFunction);
}
SliceRenderer3D::~SliceRenderer3D() {
}
void SliceRenderer3D::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/glsl/slicerenderer3d.frag", "", false);
}
void SliceRenderer3D::deinit() {
VisualizationProcessor::deinit();
ShdrMgr.dispose(_shader);
}
void SliceRenderer3D::process(DataContainer& data) {
DataContainer::ScopedTypedData<ImageDataGL> img(data, p_sourceImageID.getValue());
if (img != 0) {
if (img->getDimensionality() == 3) {
updateProperties(img);
const tgt::Camera& cam = p_camera.getValue();
const tgt::svec3& imgSize = img->getSize();
// Creating the slice proxy geometry works as follows:
// Create the cube proxy geometry for the volume, then clip the cube against the slice plane.
// The closing face is the slice proxy geometry.
// This is probably not the fastest, but an elegant solution, which also supports arbitrary slice orientations. :)
tgt::Bounds volumeExtent = img->getWorldBounds();
MeshGeometry cube = MeshGeometry::createCube(volumeExtent, tgt::Bounds(tgt::vec3(0.f), tgt::vec3(1.f)));
tgt::vec3 normal(0.f, 0.f, 1.f);
float p = img->getMappingInformation().getOffset().z + (p_sliceNumber.getValue() * img->getMappingInformation().getVoxelSize().z);
MeshGeometry clipped = cube.clipAgainstPlane(p, normal, true);
FaceGeometry slice = clipped.getFaces().back(); // the last face is the closing face
ImageDataRenderTarget* rt = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
_shader->activate();
_shader->setIgnoreUniformLocationError(true);
_shader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(_renderTargetSize.getValue()));
_shader->setUniform("_projectionMatrix", cam.getProjectionMatrix());
_shader->setUniform("_viewMatrix", cam.getViewMatrix());
tgt::TextureUnit inputUnit, tfUnit;
img->bind(_shader, inputUnit);
p_transferFunction.getTF()->bind(_shader, tfUnit);
rt->activate();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
slice.render();
rt->deactivate();
_shader->deactivate();
tgt::TextureUnit::setZeroUnit();
data.addData(p_targetImageID.getValue(), rt);
p_targetImageID.issueWrite();
}
else {
LERROR("Input image must have dimensionality of 3.");
}
}
else {
LERROR("No suitable input image found.");
}
_invalidationLevel.setValid();
}
void SliceRenderer3D::updateProperties(const ImageData* img) {
const tgt::svec3& imgSize = img->getSize();
if (p_sliceNumber.getMaxValue() != imgSize.z - 1){
p_sliceNumber.setMaxValue(imgSize.z - 1);
}
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, 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".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef SLICERENDERER3D_H__
#define SLICERENDERER3D_H__
#include <string>
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/genericproperty.h"
#include "core/properties/numericproperty.h"
#include "core/properties/transferfunctionproperty.h"
#include "core/properties/cameraproperty.h"
namespace tgt {
class Shader;
}
namespace campvis {
class ImageData;
/**
* Extracts a slice from a 3D image and renders it into a rendertarget.
*/
class SliceRenderer3D : public VisualizationProcessor {
public:
/**
* Constructs a new SliceRenderer3D Processor
**/
SliceRenderer3D(GenericProperty<tgt::ivec2>& canvasSize);
/**
* Destructor
**/
virtual ~SliceRenderer3D();
/// \see AbstractProcessor::init
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "SliceRenderer3D"; };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Extracts a single slice from the input image and renders it using a transfer function."; };
/// \see AbstractProcessor::process()
virtual void process(DataContainer& data);
DataNameProperty p_sourceImageID; ///< image ID for input image
DataNameProperty p_targetImageID; ///< image ID for output image
CameraProperty p_camera;
IntProperty p_sliceNumber; ///< number of the slice to extract
TransferFunctionProperty p_transferFunction; ///< Transfer function
protected:
/// adapts the range of the p_sliceNumber property to the image
void updateProperties(const ImageData* img);
tgt::Shader* _shader; ///< Shader for slice rendering
static const std::string loggerCat_;
};
}
#endif // SLICERENDERER3D_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment