In January 2021 we will introduce a 10 GB quota for project repositories. Higher limits for individual projects will be available on request. Please see https://doku.lrz.de/display/PUBLIC/GitLab for more information.

* Updated VolumeRenderer and VolumeExplorer to use user-defined RaycastingProcessor

* RaycastingProcessor now has the p_targetImageID property and optionally uses a custom GLSL version for the shader
* Introducing PropertyCollection::getNestedProperty allowing to get nested properties with a single method call
* Fixed StringUtils::split() methods being broken with multi-character delimiters
parent 56724724
......@@ -36,22 +36,25 @@
namespace campvis {
const std::string RaycastingProcessor::loggerCat_ = "CAMPVis.modules.vis.RaycastingProcessor";
RaycastingProcessor::RaycastingProcessor(IVec2Property* viewportSizeProp, const std::string& fragmentShaderFileName, bool bindEntryExitDepthTextures)
RaycastingProcessor::RaycastingProcessor(IVec2Property* viewportSizeProp, const std::string& fragmentShaderFileName, bool bindEntryExitDepthTextures, const std::string& customGlslVersion /*= ""*/)
: VisualizationProcessor(viewportSizeProp)
, p_sourceImageID("sourceImageID", "Input Image", "", DataNameProperty::READ, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES)
, p_entryImageID("entryImageID", "Input Entry Points Image", "", DataNameProperty::READ)
, p_exitImageID("exitImageID", "Input Exit Points Image", "", DataNameProperty::READ)
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_camera("camera", "Camera")
, p_transferFunction("TransferFunction", "Transfer Function", new SimpleTransferFunction(256))
, p_jitterStepSizeMultiplier("jitterStepSizeMultiplier", "Jitter Step Size Multiplier", 1.f, 0.f, 1.f)
, p_samplingRate("SamplingRate", "Sampling Rate", 2.f, 0.1f, 10.f, 0.1f)
, _fragmentShaderFilename(fragmentShaderFileName)
, _customGlslVersion(customGlslVersion)
, _shader(0)
, _bindEntryExitDepthTextures(bindEntryExitDepthTextures)
{
addProperty(&p_sourceImageID);
addProperty(&p_entryImageID);
addProperty(&p_exitImageID);
addProperty(&p_targetImageID);
addProperty(&p_camera);
addProperty(&p_transferFunction);
addProperty(&p_jitterStepSizeMultiplier);
......@@ -64,7 +67,7 @@ namespace campvis {
void RaycastingProcessor::init() {
VisualizationProcessor::init();
_shader = ShdrMgr.load("core/glsl/passthrough.vert", _fragmentShaderFilename, generateHeader());
_shader = ShdrMgr.loadWithCustomGlslVersion("core/glsl/passthrough.vert", "", _fragmentShaderFilename, generateHeader(), _customGlslVersion);
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
}
......
......@@ -62,8 +62,9 @@ namespace campvis {
* \param viewportSizeProp Pointer to the parent pipeline's render target size property.
* \param fragmentShaderFileName Filename for the fragment shader being automatically loaded.
* \param bindEntryExitDepthTextures Flag whether to also bind the depth textures of the entry-/exit points.
* \param customGlslVersion Custom GLSL version to pass to shader (Optional).
*/
RaycastingProcessor(IVec2Property* viewportSizeProp, const std::string& fragmentShaderFileName, bool bindEntryExitDepthTextures);
RaycastingProcessor(IVec2Property* viewportSizeProp, const std::string& fragmentShaderFileName, bool bindEntryExitDepthTextures, const std::string& customGlslVersion = "");
/**
* Destructor
......@@ -87,6 +88,7 @@ namespace campvis {
DataNameProperty p_sourceImageID; ///< image ID for input image
DataNameProperty p_entryImageID; ///< image ID for output entry points image
DataNameProperty p_exitImageID; ///< image ID for output exit points image
DataNameProperty p_targetImageID; ///< image ID for output image
CameraProperty p_camera; ///< Camera used for ray casting
TransferFunctionProperty p_transferFunction; ///< Transfer function
......@@ -131,6 +133,8 @@ namespace campvis {
virtual std::string generateHeader() const;
const std::string _fragmentShaderFilename; ///< Filename for the fragment shader being automatically loaded.
const std::string _customGlslVersion; ///< Custom GLSL version to pass to shader
tgt::Shader* _shader; ///< Shader for raycasting
bool _bindEntryExitDepthTextures; ///< Flag whether to also bind the depth textures of the entry-/exit points.
......
......@@ -169,7 +169,8 @@ namespace campvis {
void VisualizationProcessor::setViewportSizeProperty(IVec2Property* viewportSizeProp) {
tgtAssert(viewportSizeProp != 0, "Pointer must not be 0.");
_viewportSizeProperty->s_changed.disconnect(this);
if (_viewportSizeProperty != 0)
_viewportSizeProperty->s_changed.disconnect(this);
_viewportSizeProperty = viewportSizeProp;
_viewportSizeProperty->s_changed.connect<VisualizationProcessor>(this, &VisualizationProcessor::onPropertyChanged);
}
......
......@@ -23,7 +23,10 @@
// ================================================================================================
#include "propertycollection.h"
#include "core/properties/abstractproperty.h"
#include "core/properties/metaproperty.h"
#include "core/tools/stringutils.h"
namespace campvis {
HasPropertyCollection::HasPropertyCollection() {
......@@ -58,9 +61,28 @@ namespace campvis {
PropertyCollection::const_iterator it = findProperty(name);
if (it != _properties.end())
return *it;
return 0;
}
AbstractProperty* HasPropertyCollection::getNestedProperty(const std::string& name) const {
// try to find nested property (use :: as delimiter)
std::vector<std::string> levels = StringUtils::split(name, "::");
AbstractProperty* toReturn = getProperty(levels[0]);
size_t currentLevel = 1;
while (toReturn != 0 && currentLevel < levels.size()) {
if (MetaProperty* tester = dynamic_cast<MetaProperty*>(toReturn)) {
toReturn = tester->getProperty(levels[currentLevel]);
++currentLevel;
}
else {
toReturn = 0;
}
}
return toReturn;
}
const PropertyCollection& HasPropertyCollection::getProperties() const {
return _properties;
}
......
......@@ -68,6 +68,15 @@ namespace campvis {
* \return The property named \a name, 0 if no such property exists.
*/
AbstractProperty* getProperty(const std::string& name) const;
/**
* Returns the property with the given name \a name using nested syntax.
* You can search for nested properties in MetaProperties using "::" as delimiter.
* If no such property exists, the result will be 0.
* \param name Name of the property to return, use "::" as delimiter for nested properties.
* \return The property named \a name, 0 if no such property exists.
*/
AbstractProperty* getNestedProperty(const std::string& name) const;
/**
* Returns the PropertyCollection of this processor.
......
......@@ -87,7 +87,7 @@ namespace campvis {
while (endpos != std::string::npos) {
endpos = line.find_first_of(delimiter, linepos);
toReturn.push_back(line.substr(linepos, endpos - linepos));
linepos = endpos + 1;
linepos = endpos + delimiter.length();
}
return toReturn;
}
......@@ -124,7 +124,7 @@ namespace campvis {
endpos = str.find_first_of(delimiter, strpos);
toReturn.push_back(StringUtils::trim(str.substr(strpos, endpos - strpos), whitespace));
}
strpos = endpos + 1;
strpos = endpos + delimiter.length();
}
return toReturn;
}
......
......@@ -276,6 +276,7 @@ int Texture::calcNumChannels(GLint format) {
case GL_R16UI:
case GL_R32I:
case GL_R32UI:
case GL_RED_INTEGER:
return 1;
break;
......@@ -294,6 +295,7 @@ int Texture::calcNumChannels(GLint format) {
case GL_RG16UI:
case GL_RG32I:
case GL_RG32UI:
case GL_RG_INTEGER:
return 2;
break;
......@@ -318,6 +320,7 @@ int Texture::calcNumChannels(GLint format) {
case GL_RGB16UI:
case GL_RGB32I:
case GL_RGB32UI:
case GL_RGB_INTEGER:
return 3;
break;
......@@ -341,6 +344,7 @@ int Texture::calcNumChannels(GLint format) {
case GL_RGBA16UI:
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGBA_INTEGER:
return 4;
break;
......
......@@ -33,12 +33,10 @@ namespace campvis {
DRRRaycaster::DRRRaycaster(IVec2Property* viewportSizeProp)
: RaycastingProcessor(viewportSizeProp, "modules/vis/glsl/drrraycaster.frag", false)
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_shift("shift", "Normalization Shift", 0.f, -10.f, 10.f, 0.1f)
, p_scale("scale", "Normalization Scale", 1.f, 0.f, 1000.f, 0.1f)
, p_invertMapping("invertMapping", "Invert Mapping", false, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER)
{
addProperty(&p_targetImageID);
addProperty(&p_shift);
addProperty(&p_scale);
addProperty(&p_invertMapping);
......
......@@ -63,8 +63,6 @@ namespace campvis {
/// \see AbstractProcessor::getProcessorState()
virtual ProcessorState getProcessorState() const { return AbstractProcessor::EXPERIMENTAL; };
DataNameProperty p_targetImageID; ///< image ID for output image
FloatProperty p_shift;
FloatProperty p_scale;
BoolProperty p_invertMapping;
......
......@@ -35,13 +35,11 @@ namespace campvis {
SimpleRaycaster::SimpleRaycaster(IVec2Property* viewportSizeProp)
: RaycastingProcessor(viewportSizeProp, "modules/vis/glsl/simpleraycaster.frag", true)
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_enableShadowing("EnableShadowing", "Enable Hard Shadows (Expensive!)", false, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_PROPERTIES)
, p_shadowIntensity("ShadowIntensity", "Shadow Intensity", .5f, .0f, 1.f)
{
addDecorator(new ProcessorDecoratorShading());
addProperty(&p_targetImageID);
addProperty(&p_enableShadowing);
addProperty(&p_shadowIntensity);
p_shadowIntensity.setVisible(false);
......
......@@ -66,7 +66,6 @@ namespace campvis {
/// \see AbstractProcessor::deinit
virtual void deinit();
DataNameProperty p_targetImageID; ///< image ID for output image
BoolProperty p_enableShadowing;
FloatProperty p_shadowIntensity;
......
......@@ -37,13 +37,13 @@
namespace campvis {
const std::string VolumeExplorer::loggerCat_ = "CAMPVis.modules.vis.VolumeExplorer";
VolumeExplorer::VolumeExplorer(IVec2Property* viewportSizeProp)
VolumeExplorer::VolumeExplorer(IVec2Property* viewportSizeProp, RaycastingProcessor* raycaster)
: VisualizationProcessor(viewportSizeProp)
, p_inputVolume("InputVolume", "Input Volume", "", DataNameProperty::READ, AbstractProcessor::INVALID_PROPERTIES)
, p_outputImage("OutputImage", "Output Image", "ve.output", DataNameProperty::WRITE)
, p_seProperties("SliceExtractorProperties", "Slice Extractor Properties", AbstractProcessor::VALID)
, p_vrProperties("VolumeRendererProperties", "Volume Renderer Properties", AbstractProcessor::VALID)
, _raycaster(viewportSizeProp)
, _raycaster(viewportSizeProp, raycaster)
, _sliceExtractor(viewportSizeProp)
, p_sliceRenderSize("SliceRenderSize", "Slice Render Size", tgt::ivec2(32), tgt::ivec2(0), tgt::ivec2(10000), tgt::ivec2(1), AbstractProcessor::VALID)
, p_volumeRenderSize("VolumeRenderSize", "Volume Render Size", tgt::ivec2(32), tgt::ivec2(0), tgt::ivec2(10000), tgt::ivec2(1), AbstractProcessor::VALID)
......
......@@ -53,8 +53,10 @@ namespace campvis {
public:
/**
* Constructs a new VolumeExplorer Processor
* \param viewportSizeProp Pointer to the property defining the viewport size, must not be 0.
* \param raycaster Raycaster to use for rendering, must not be 0, VolumeRenderer will take ownership.
**/
VolumeExplorer(IVec2Property* viewportSizeProp);
VolumeExplorer(IVec2Property* viewportSizeProp, RaycastingProcessor* raycaster = new SimpleRaycaster(0));
/**
* Destructor
......
......@@ -35,7 +35,7 @@
namespace campvis {
const std::string VolumeRenderer::loggerCat_ = "CAMPVis.modules.vis.VolumeRenderer";
VolumeRenderer::VolumeRenderer(IVec2Property* viewportSizeProp)
VolumeRenderer::VolumeRenderer(IVec2Property* viewportSizeProp, RaycastingProcessor* raycaster)
: VisualizationProcessor(viewportSizeProp)
, p_inputVolume("InputVolume", "Input Volume", "", DataNameProperty::READ, AbstractProcessor::VALID)
, p_camera("Camera", "Camera", tgt::Camera(), AbstractProcessor::VALID)
......@@ -45,10 +45,12 @@ namespace campvis {
, p_raycasterProps("RaycasterProps", "Raycaster", AbstractProcessor::VALID)
, _pgGenerator()
, _eepGenerator(viewportSizeProp)
, _raycaster(viewportSizeProp)
, _raycaster(raycaster)
{
_raycaster->setViewportSizeProperty(viewportSizeProp);
addProperty(&p_inputVolume);
addProperty(&_raycaster.p_transferFunction);
addProperty(&_raycaster->p_transferFunction);
addProperty(&p_outputImage);
p_pgProps.addPropertyCollection(_pgGenerator);
......@@ -65,24 +67,24 @@ namespace campvis {
_eepGenerator.p_exitImageID.setVisible(false);
addProperty(&p_eepProps);
p_raycasterProps.addPropertyCollection(_raycaster);
_raycaster.p_lqMode.setVisible(false);
_raycaster.p_camera.setVisible(false);
_raycaster.p_sourceImageID.setVisible(false);
_raycaster.p_entryImageID.setVisible(false);
_raycaster.p_exitImageID.setVisible(false);
_raycaster.p_targetImageID.setVisible(false);
p_raycasterProps.addPropertyCollection(*_raycaster);
_raycaster->p_lqMode.setVisible(false);
_raycaster->p_camera.setVisible(false);
_raycaster->p_sourceImageID.setVisible(false);
_raycaster->p_entryImageID.setVisible(false);
_raycaster->p_exitImageID.setVisible(false);
_raycaster->p_targetImageID.setVisible(false);
addProperty(&p_raycasterProps);
// setup shared properties
p_inputVolume.addSharedProperty(&_pgGenerator.p_sourceImageID);
p_inputVolume.addSharedProperty(&_eepGenerator.p_sourceImageID);
p_inputVolume.addSharedProperty(&_raycaster.p_sourceImageID);
p_inputVolume.addSharedProperty(&_raycaster->p_sourceImageID);
p_camera.addSharedProperty(&_eepGenerator.p_camera);
p_camera.addSharedProperty(&_raycaster.p_camera);
p_camera.addSharedProperty(&_raycaster->p_camera);
p_outputImage.addSharedProperty(&_raycaster.p_targetImageID);
p_outputImage.addSharedProperty(&_raycaster->p_targetImageID);
p_inputVolume.s_changed.connect(this, &VolumeRenderer::onPropertyChanged);
}
......@@ -95,23 +97,23 @@ namespace campvis {
VisualizationProcessor::init();
_pgGenerator.init();
_eepGenerator.init();
_raycaster.init();
_raycaster->init();
p_lqMode.addSharedProperty(&_raycaster.p_lqMode);
p_lqMode.addSharedProperty(&_raycaster->p_lqMode);
_pgGenerator.s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
_eepGenerator.s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
_raycaster.s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
_raycaster->s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
}
void VolumeRenderer::deinit() {
_pgGenerator.s_invalidated.disconnect(this);
_eepGenerator.s_invalidated.disconnect(this);
_raycaster.s_invalidated.disconnect(this);
_raycaster->s_invalidated.disconnect(this);
_pgGenerator.deinit();
_eepGenerator.deinit();
_raycaster.deinit();
_raycaster->deinit();
VisualizationProcessor::deinit();
}
......@@ -124,7 +126,7 @@ namespace campvis {
_eepGenerator.process(data);
}
if (getInvalidationLevel() & RAYCASTER_INVALID) {
_raycaster.process(data);
_raycaster->process(data);
}
validate(INVALID_RESULT | PG_INVALID | EEP_INVALID | RAYCASTER_INVALID);
......@@ -137,7 +139,7 @@ namespace campvis {
else if (processor == &_eepGenerator) {
invalidate(EEP_INVALID | RAYCASTER_INVALID);
}
else if (processor == &_raycaster) {
else if (processor == _raycaster) {
invalidate(RAYCASTER_INVALID);
}
......@@ -150,17 +152,17 @@ namespace campvis {
_eepGenerator.p_geometryID.setValue(p_outputImage.getValue() + ".geometry");
_eepGenerator.p_entryImageID.setValue(p_outputImage.getValue() + ".entrypoints");
_raycaster.p_entryImageID.setValue(p_outputImage.getValue() + ".entrypoints");
_raycaster->p_entryImageID.setValue(p_outputImage.getValue() + ".entrypoints");
_eepGenerator.p_exitImageID.setValue(p_outputImage.getValue() + ".exitpoints");
_raycaster.p_exitImageID.setValue(p_outputImage.getValue() + ".exitpoints");
_raycaster->p_exitImageID.setValue(p_outputImage.getValue() + ".exitpoints");
}
VisualizationProcessor::onPropertyChanged(prop);
}
void VolumeRenderer::setViewportSizeProperty(IVec2Property* viewportSizeProp) {
_eepGenerator.setViewportSizeProperty(viewportSizeProp);
_raycaster.setViewportSizeProperty(viewportSizeProp);
_raycaster->setViewportSizeProperty(viewportSizeProp);
VisualizationProcessor::setViewportSizeProperty(viewportSizeProp);
}
......
......@@ -33,6 +33,7 @@
#include "modules/vis/processors/eepgenerator.h"
#include "modules/vis/processors/proxygeometrygenerator.h"
#include "modules/vis/processors/simpleraycaster.h"
#include "core/pipeline/raycastingprocessor.h"
namespace tgt {
class Shader;
......@@ -55,8 +56,10 @@ namespace campvis {
/**
* Constructs a new VolumeRenderer Processor
**/
VolumeRenderer(IVec2Property* viewportSizeProp);
* \param viewportSizeProp Pointer to the property defining the viewport size, must not be 0.
* \param raycaster Raycaster to use for rendering, must not be 0, VolumeRenderer will take ownership.
*/
VolumeRenderer(IVec2Property* viewportSizeProp, RaycastingProcessor* raycaster = new SimpleRaycaster(0));
/**
* Destructor
......@@ -109,7 +112,7 @@ namespace campvis {
ProxyGeometryGenerator _pgGenerator;
EEPGenerator _eepGenerator;
SimpleRaycaster _raycaster;
RaycastingProcessor* _raycaster;
static const std::string loggerCat_;
};
......
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