* Introducing OrientationOverlay processor to render an orientation overlay into an image.

* Added TextureReaderTga::loadTextureArray().
* Added OrientationOverlay to VolumeRenderer.
parent f9428f6f
......@@ -190,4 +190,60 @@ Texture* TextureReaderTga::loadTexture(const std::string& filename, Texture::Fil
return t;
}
Texture* TextureReaderTga::loadTextureArray(const std::vector<std::string>& filenames, Texture::Filter filter) {
GLubyte* data = nullptr;
GLint format;
GLint internalFormat;
GLenum dataType = GL_UNSIGNED_BYTE;
size_t numBytesPerTexture = 0;
cgt::ivec3 dimensions;
// quick and dirty hack with bad performance (unnecessary copies)
for (size_t i = 0; i < filenames.size(); ++i) {
Texture* tmp = loadTexture(filenames[i], filter);
if (data == nullptr) {
switch (tmp->getNumChannels()) {
case 1:
format = GL_RED;
LDEBUG("GL_RED");
break;
case 3:
format = GL_RGB;
LDEBUG("RGB");
break;
case 4:
format = GL_RGBA;
LDEBUG("RGBA");
break;
default:
cgtAssert(false, "Should not reach this! Wrong number of channels.");
break;
}
internalFormat = tmp->getInternalFormat();
dimensions = tmp->getDimensions();
numBytesPerTexture = cgt::hmul(dimensions) * tmp->getNumChannels();
data = new GLubyte[filenames.size() * numBytesPerTexture];
}
else {
if (dimensions != tmp->getDimensions() || internalFormat != tmp->getInternalFormat()) {
LERROR("Dimensions of texture array textures or internal formats mismatch, aborting!");
delete [] data;
delete tmp;
return nullptr;
}
}
GLubyte* buffer = tmp->downloadTextureToBuffer(format, dataType);
memcpy(data + (i * numBytesPerTexture), buffer, numBytesPerTexture);
delete [] buffer;
delete tmp;
}
Texture* toReturn = new Texture(GL_TEXTURE_2D_ARRAY, cgt::ivec3(dimensions.xy(), int(filenames.size())), internalFormat, data, format, dataType, filter);
delete data;
return toReturn;
}
} // namespace cgt
......@@ -41,6 +41,8 @@ public:
TextureReaderTga();
virtual Texture* loadTexture(const std::string& filename, Texture::Filter filter, bool compress = false,
bool keepPixels = false, bool createOGLTex = true, bool textureRectangle = false);
Texture* loadTextureArray(const std::vector<std::string>& filenames, Texture::Filter filter);
};
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, 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.
//
// ================================================================================================
in vec3 ex_TexCoord;
in vec4 ex_Color;
out vec4 out_Color;
uniform sampler2DArray _cubeTexture;
uniform bool _enableTexturing;
void main() {
if (_enableTexturing)
out_Color = texture(_cubeTexture, ex_TexCoord);
else
out_Color = ex_Color;
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, 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 "orientationoverlay.h"
#include "cgt/logmanager.h"
#include "cgt/shadermanager.h"
#include "cgt/textureunit.h"
#include "cgt/texturereadertga.h"
#include "core/datastructures/cameradata.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/meshgeometry.h"
#include "core/datastructures/renderdata.h"
#include "core/tools/quadrenderer.h"
namespace campvis {
const std::string OrientationOverlay::loggerCat_ = "CAMPVis.modules.vis.OrientationOverlay";
OrientationOverlay::OrientationOverlay(IVec2Property* viewportSizeProp)
: VisualizationProcessor(viewportSizeProp)
, p_camera("Camera", "Camera", "camera", DataNameProperty::READ)
, p_sourceImageId("SourceImageId", "Source Image ID", "", DataNameProperty::READ)
, p_targetImageId("TargetImageId", "Output Image", "OrientationOverlay", DataNameProperty::WRITE)
, p_passThroughImageId("PassThroughImageId", "Passthrough Image ID (optional)", "", DataNameProperty::READ)
, p_cubeSize("CubeSize", "Cube Size", .1f, .01f, .5f, .1f, 2)
, p_cubePosition("CubePosition", "Cube Position", cgt::vec2(.85f, .15f), cgt::vec2(0.f), cgt::vec2(1.f), cgt::vec2(.1f), cgt::ivec2(2))
, p_enableTexturing("EnableTexturing", "Enable Texturing", true)
, p_flipMatrix("FlipMatrix", "Flip Matrix for Alignment (optional)", cgt::mat4::identity)
, _cubeGeometry(nullptr)
, _shader(nullptr)
, _textures(nullptr)
{
addProperty(p_camera);
addProperty(p_sourceImageId);
addProperty(p_targetImageId);
addProperty(p_passThroughImageId);
addProperty(p_cubeSize, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_cubePosition);
addProperty(p_enableTexturing);
addProperty(p_flipMatrix);
p_flipMatrix.setVisible(false);
}
OrientationOverlay::~OrientationOverlay() {
}
void OrientationOverlay::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.load("core/glsl/passthrough.vert", "modules/vis/glsl/orientationoverlay.frag", "");
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
_passthroughShader = ShdrMgr.load("core/glsl/passthrough.vert", "modules/vis/glsl/quadview.frag", "");
_passthroughShader->setAttributeLocation(0, "in_Position");
_passthroughShader->setAttributeLocation(1, "in_TexCoord");
createCube();
std::vector<std::string> textureFileNames;
textureFileNames.push_back(ShdrMgr.completePath("/modules/vis/textures/front.tga"));
textureFileNames.push_back(ShdrMgr.completePath("/modules/vis/textures/back.tga"));
textureFileNames.push_back(ShdrMgr.completePath("/modules/vis/textures/top.tga"));
textureFileNames.push_back(ShdrMgr.completePath("/modules/vis/textures/bottom.tga"));
textureFileNames.push_back(ShdrMgr.completePath("/modules/vis/textures/left.tga"));
textureFileNames.push_back(ShdrMgr.completePath("/modules/vis/textures/right.tga"));
cgt::TextureReaderTga tgaReader;
_textures = tgaReader.loadTextureArray(textureFileNames, cgt::Texture::LINEAR);
}
void OrientationOverlay::deinit() {
VisualizationProcessor::deinit();
delete _cubeGeometry;
ShdrMgr.dispose(_shader);
ShdrMgr.dispose(_passthroughShader);
delete _textures;
}
void OrientationOverlay::updateResult(DataContainer& data) {
ScopedTypedData<CameraData> camera(data, p_camera.getValue());
ScopedTypedData<ImageData> sourceImage(data, p_sourceImageId.getValue());
ScopedTypedData<RenderData> passthroughImage(data, p_passThroughImageId.getValue());
if (camera && sourceImage) {
FramebufferActivationGuard fag(this);
createAndAttachColorTexture();
createAndAttachDepthTexture();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (passthroughImage) {
_passthroughShader->activate();
cgt::TextureUnit colorUnit, depthUnit;
passthroughImage->bind(_passthroughShader, colorUnit, depthUnit);
QuadRdr.renderQuad11();
_passthroughShader->deactivate();
}
_shader->activate();
cgt::TextureUnit textureUnit;
textureUnit.activate();
_textures->bind();
_shader->setUniform("_cubeTexture", textureUnit.getUnitNumber());
_shader->setUniform("_enableTexturing", p_enableTexturing.getValue());
_shader->setUniform("_projectionMatrix", cgt::mat4::createOrtho(-1,1,1,-1,-2,2));
const cgt::mat4 viewMatrix = cgt::mat4::createTranslation(cgt::vec3(p_cubePosition.getValue().x * 2.f - 1.f, p_cubePosition.getValue().y * 2.f - 1.f, 0.f))
* cgt::mat4::createScale(cgt::vec3(float(getEffectiveViewportSize().y) / float(getEffectiveViewportSize().x), 1.f, 1.f))
* camera->getCamera().getViewMatrix().getRotationalPart();
_shader->setUniform("_viewMatrix", viewMatrix);
_shader->setUniform("_modelMatrix", p_flipMatrix.getValue());
_cubeGeometry->render(GL_TRIANGLE_FAN);
glDepthFunc(GL_LESS);
glDisable(GL_DEPTH_TEST);
_shader->deactivate();
cgt::TextureUnit::setZeroUnit();
LGL_ERROR;
data.addData(p_targetImageId.getValue(), new RenderData(_fbo));
}
else {
LDEBUG("No suitable input images found.");
}
}
void OrientationOverlay::createCube() {
const float& cs = p_cubeSize.getValue();
std::vector<cgt::vec3> vertices, texCoords;
std::vector<FaceGeometry> faces;
// bottom
texCoords.push_back(cgt::vec3(0.f, 0.f, 3.f));
vertices.push_back(cgt::vec3(-cs, -cs, cs));
texCoords.push_back(cgt::vec3(1.f, 0.f, 3.f));
vertices.push_back(cgt::vec3( cs, -cs, cs));
texCoords.push_back(cgt::vec3(1.f, 1.f, 3.f));
vertices.push_back(cgt::vec3( cs, cs, cs));
texCoords.push_back(cgt::vec3(0.f, 1.f, 3.f));
vertices.push_back(cgt::vec3(-cs, cs, cs));
faces.push_back(FaceGeometry(vertices, texCoords, std::vector<cgt::vec4>(4, cgt::vec4(0.f, 0.f, 1.f, 1.f)), std::vector<cgt::vec3>(4, cgt::vec3(0.f, 0.f, 1.f))));
vertices.clear();
texCoords.clear();
// top
texCoords.push_back(cgt::vec3(0.f, 0.f, 2.f));
vertices.push_back(cgt::vec3( cs, -cs, -cs));
texCoords.push_back(cgt::vec3(1.f, 0.f, 2.f));
vertices.push_back(cgt::vec3(-cs, -cs, -cs));
texCoords.push_back(cgt::vec3(1.f, 1.f, 2.f));
vertices.push_back(cgt::vec3(-cs, cs, -cs));
texCoords.push_back(cgt::vec3(0.f, 1.f, 2.f));
vertices.push_back(cgt::vec3( cs, cs, -cs));
faces.push_back(FaceGeometry(vertices, texCoords, std::vector<cgt::vec4>(4, cgt::vec4(0.f, 0.f, 1.f, 1.f)), std::vector<cgt::vec3>(4, cgt::vec3(0.f, 0.f, 1.f))));
vertices.clear();
texCoords.clear();
// front
texCoords.push_back(cgt::vec3(0.f, 0.f, 0.f));
vertices.push_back(cgt::vec3(-cs, cs, cs));
texCoords.push_back(cgt::vec3(1.f, 0.f, 0.f));
vertices.push_back(cgt::vec3( cs, cs, cs));
texCoords.push_back(cgt::vec3(1.f, 1.f, 0.f));
vertices.push_back(cgt::vec3( cs, cs, -cs));
texCoords.push_back(cgt::vec3(0.f, 1.f, 0.f));
vertices.push_back(cgt::vec3(-cs, cs, -cs));
faces.push_back(FaceGeometry(vertices, texCoords, std::vector<cgt::vec4>(4, cgt::vec4(0.f, 1.f, 0.f, 1.f)), std::vector<cgt::vec3>(4, cgt::vec3(0.f, 0.f, 1.f))));
vertices.clear();
texCoords.clear();
// back
texCoords.push_back(cgt::vec3(0.f, 0.f, 1.f));
vertices.push_back(cgt::vec3( cs, -cs, cs));
texCoords.push_back(cgt::vec3(1.f, 0.f, 1.f));
vertices.push_back(cgt::vec3(-cs, -cs, cs));
texCoords.push_back(cgt::vec3(1.f, 1.f, 1.f));
vertices.push_back(cgt::vec3(-cs, -cs, -cs));
texCoords.push_back(cgt::vec3(0.f, 1.f, 1.f));
vertices.push_back(cgt::vec3( cs, -cs, -cs));
faces.push_back(FaceGeometry(vertices, texCoords, std::vector<cgt::vec4>(4, cgt::vec4(0.f, 1.f, 0.f, 1.f)), std::vector<cgt::vec3>(4, cgt::vec3(0.f, 0.f, 1.f))));
vertices.clear();
texCoords.clear();
// right
texCoords.push_back(cgt::vec3(0.f, 0.f, 5.f));
vertices.push_back(cgt::vec3(-cs, -cs, cs));
texCoords.push_back(cgt::vec3(1.f, 0.f, 5.f));
vertices.push_back(cgt::vec3(-cs, cs, cs));
texCoords.push_back(cgt::vec3(1.f, 1.f, 5.f));
vertices.push_back(cgt::vec3(-cs, cs, -cs));
texCoords.push_back(cgt::vec3(0.f, 1.f, 5.f));
vertices.push_back(cgt::vec3(-cs, -cs, -cs));
faces.push_back(FaceGeometry(vertices, texCoords, std::vector<cgt::vec4>(4, cgt::vec4(1.f, 0.f, 0.f, 1.f)), std::vector<cgt::vec3>(4, cgt::vec3(0.f, 0.f, 1.f))));
vertices.clear();
texCoords.clear();
// left
texCoords.push_back(cgt::vec3(0.f, 0.f, 4.f));
vertices.push_back(cgt::vec3( cs, cs, cs));
texCoords.push_back(cgt::vec3(1.f, 0.f, 4.f));
vertices.push_back(cgt::vec3( cs, -cs, cs));
texCoords.push_back(cgt::vec3(1.f, 1.f, 4.f));
vertices.push_back(cgt::vec3( cs, -cs, -cs));
texCoords.push_back(cgt::vec3(0.f, 1.f, 4.f));
vertices.push_back(cgt::vec3( cs, cs, -cs));
faces.push_back(FaceGeometry(vertices, texCoords, std::vector<cgt::vec4>(4, cgt::vec4(1.f, 0.f, 0.f, 1.f)), std::vector<cgt::vec3>(4, cgt::vec3(0.f, 0.f, 1.f))));
vertices.clear();
texCoords.clear();
delete _cubeGeometry;
_cubeGeometry = new MeshGeometry(faces);
}
void OrientationOverlay::updateProperties(DataContainer& dataContainer) {
createCube();
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, 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 ORIENTATIONOVERLAY_H__
#define ORIENTATIONOVERLAY_H__
#include <string>
#include "cgt/matrix.h"
#include "core/pipeline/abstractprocessordecorator.h"
#include "core/pipeline/processordecoratorbackground.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/floatingpointproperty.h"
#include "core/properties/optionproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
class Texture;
}
namespace campvis {
class ImageData;
class MeshGeometry;
/**
* Performs the composition of a multiple render targets
*/
class CAMPVIS_MODULES_API OrientationOverlay : public VisualizationProcessor {
public:
/**
* Constructs a new OrientationOverlay Processor
**/
OrientationOverlay(IVec2Property* viewportSizeProp);
/**
* Destructor
**/
virtual ~OrientationOverlay();
/// \see AbstractProcessor::init
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "OrientationOverlay"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Renders a small cube to indicate the orientation of a data set with respect to the world coordinate system."; };
/// \see AbstractProcessor::getAuthor()
virtual const std::string getAuthor() const { return "Christian Schulte zu Berge <christian.szb@in.tum.de>"; };
/// \see AbstractProcessor::getProcessorState()
virtual ProcessorState getProcessorState() const { return AbstractProcessor::TESTING; };
DataNameProperty p_camera; ///< data ID for the camera data
DataNameProperty p_sourceImageId; ///< image ID of the image to indicate orientation for
DataNameProperty p_targetImageId; ///< image ID for rendered output image
DataNameProperty p_passThroughImageId; ///< image ID for for optional passthrough image
FloatProperty p_cubeSize;
Vec2Property p_cubePosition;
BoolProperty p_enableTexturing;
GenericProperty<cgt::mat4> p_flipMatrix; ///< additional flip matrix to align the orientation overlay (optional)
protected:
virtual void updateResult(DataContainer& dataContainer);
virtual void updateProperties(DataContainer& dataContainer);
void createCube();
MeshGeometry* _cubeGeometry; ///< MeshGeometry used for rendering the cube
cgt::Shader* _shader; ///< Shader for rendering
cgt::Shader* _passthroughShader; ///< Shader for rendering
cgt::Texture* _textures; ///< 2D array Texture for faces (order: front, back, top, bottom, left, right)
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<OrientationOverlay>;
}
#endif // ORIENTATIONOVERLAY_H__
......@@ -46,9 +46,11 @@ namespace campvis {
, p_pgProps("PGGProps", "Proxy Geometry Generator")
, p_eepProps("EEPProps", "Entry/Exit Points Generator")
, p_raycasterProps("RaycasterProps", "Raycaster")
, p_orientationOverlayProps("OrientationOverlayProps", "Orientation Overlay")
, _pgGenerator()
, _eepGenerator(viewportSizeProp)
, _raycaster(raycaster)
, _orientationOverlay(viewportSizeProp)
{
_raycaster->setViewportSizeProperty(viewportSizeProp);
......@@ -79,15 +81,20 @@ namespace campvis {
_raycaster->p_targetImageID.setVisible(false);
addProperty(p_raycasterProps, AbstractProcessor::VALID);
p_orientationOverlayProps.addPropertyCollection(_orientationOverlay);
addProperty(p_orientationOverlayProps, VALID);
// setup shared properties
p_inputVolume.addSharedProperty(&_pgGenerator.p_sourceImageID);
p_inputVolume.addSharedProperty(&_eepGenerator.p_sourceImageID);
p_inputVolume.addSharedProperty(&_raycaster->p_sourceImageID);
p_inputVolume.addSharedProperty(&_orientationOverlay.p_sourceImageId);
p_camera.addSharedProperty(&_eepGenerator.p_camera);
p_camera.addSharedProperty(&_raycaster->p_camera);
p_camera.addSharedProperty(&_orientationOverlay.p_camera);
p_outputImage.addSharedProperty(&_raycaster->p_targetImageID);
p_outputImage.addSharedProperty(&_orientationOverlay.p_targetImageId);
}
VolumeRenderer::~VolumeRenderer() {
......@@ -98,6 +105,7 @@ namespace campvis {
VisualizationProcessor::init();
_pgGenerator.init();
_eepGenerator.init();
_orientationOverlay.init();
_raycaster->init();
p_lqMode.addSharedProperty(&_raycaster->p_lqMode);
......@@ -105,6 +113,7 @@ namespace campvis {
_pgGenerator.s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
_eepGenerator.s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
_raycaster->s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
_orientationOverlay.s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
glGenQueries(1, &_timerQueryRaycaster);
}
......@@ -115,10 +124,12 @@ namespace campvis {
_pgGenerator.s_invalidated.disconnect(this);
_eepGenerator.s_invalidated.disconnect(this);
_raycaster->s_invalidated.disconnect(this);
_orientationOverlay.s_invalidated.disconnect(this);
_pgGenerator.deinit();
_eepGenerator.deinit();
_raycaster->deinit();
_orientationOverlay.deinit();
VisualizationProcessor::deinit();
}
......@@ -145,6 +156,8 @@ namespace campvis {
}
}
_orientationOverlay.process(data);
validate(INVALID_RESULT | PG_INVALID | EEP_INVALID | RAYCASTER_INVALID);
}
......@@ -172,6 +185,9 @@ namespace campvis {
_eepGenerator.p_exitImageID.setValue(p_outputImage.getValue() + ".exitpoints");
_raycaster->p_exitImageID.setValue(p_outputImage.getValue() + ".exitpoints");
_raycaster->p_targetImageID.setValue(p_outputImage.getValue() + ".raycasted");
_orientationOverlay.p_passThroughImageId.setValue(p_outputImage.getValue() + ".raycasted");
}
VisualizationProcessor::onPropertyChanged(prop);
}
......@@ -179,6 +195,7 @@ namespace campvis {
void VolumeRenderer::setViewportSizeProperty(IVec2Property* viewportSizeProp) {
_eepGenerator.setViewportSizeProperty(viewportSizeProp);
_raycaster->setViewportSizeProperty(viewportSizeProp);
_orientationOverlay.setViewportSizeProperty(viewportSizeProp);
VisualizationProcessor::setViewportSizeProperty(viewportSizeProp);
}
......
......@@ -32,6 +32,7 @@
#include "modules/modulesapi.h"
#include "modules/vis/processors/eepgenerator.h"
#include "modules/vis/processors/proxygeometrygenerator.h"
#include "modules/vis/processors/orientationoverlay.h"
#include "modules/vis/processors/simpleraycaster.h"
#include "modules/processorfactory.h"
......@@ -104,6 +105,7 @@ namespace campvis {
MetaProperty p_pgProps; ///< MetaProperty for properties of the ProxyGeometryGenerator processor
MetaProperty p_eepProps; ///< MetaProperty for properties of the EEPGenerator processor
MetaProperty p_raycasterProps; ///< MetaProperty for properties of the raycasting processor
MetaProperty p_orientationOverlayProps; ///< MetaProperty for properties of the OrientationOverlay processor
protected:
/// \see AbstractProcessor::updateResult
......@@ -127,6 +129,8 @@ namespace campvis {
EEPGenerator _eepGenerator;
RaycastingProcessor* _raycaster;
OrientationOverlay _orientationOverlay;
static const std::string loggerCat_;
};