Commit e68b3980 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge

Merge branch 'raycasterupdate' into 'development'

Raycasterupdate

please do check DRRRaycaster, after rabasing, it yields a white screen !!

See merge request !113
parents 5fd1f6ab 6bc3bd94
......@@ -97,30 +97,40 @@ namespace campvis {
_containerWidget = new QWidget(this);
QGridLayout* _cwLayout = new QGridLayout(_containerWidget);
int rowPosition = 0;
_cbPipelineFactory = new QComboBox(_containerWidget);
std::vector<std::string> registeredPipelines = PipelineFactory::getRef().getRegisteredPipelines();
for (std::vector<std::string>::const_iterator it = registeredPipelines.begin(); it != registeredPipelines.end(); ++it)
_cbPipelineFactory->addItem(QString::fromStdString(*it));
_cwLayout->addWidget(_cbPipelineFactory, 0, 0);
_cwLayout->addWidget(_cbPipelineFactory, rowPosition, 0);
_btnPipelineFactory = new QPushButton("Add Pipeline", _containerWidget);
_cwLayout->addWidget(_btnPipelineFactory, 0, 1);
_cwLayout->addWidget(_btnPipelineFactory, rowPosition++, 1);
_pipelineWidget = new PipelineTreeWidget(this);
_containerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
_cwLayout->addWidget(_pipelineWidget, 1, 0, 1, 2);
_cwLayout->addWidget(_pipelineWidget, rowPosition++, 0, 1, 2);
_btnExecute = new QPushButton("Execute Selected Pipeline/Processor", _containerWidget);
_cwLayout->addWidget(_btnExecute, 2, 0, 1, 2);
_cwLayout->addWidget(_btnExecute, rowPosition++, 0, 1, 2);
_cbProcessorFactory = new QComboBox(_containerWidget);
std::vector<std::string> registeredProcessors = ProcessorFactory::getRef().getRegisteredProcessors();
for (std::vector<std::string>::const_iterator it = registeredProcessors.begin(); it != registeredProcessors.end(); ++it)
_cbProcessorFactory->addItem(QString::fromStdString(*it));
_cwLayout->addWidget(_cbProcessorFactory, rowPosition, 0);
_btnProcessorFactory = new QPushButton("Add Processor", _containerWidget);
_cwLayout->addWidget(_btnProcessorFactory, rowPosition++, 1);
_btnShowDataContainerInspector = new QPushButton("Inspect DataContainer of Selected Pipeline", _containerWidget);
_cwLayout->addWidget(_btnShowDataContainerInspector, 3, 0, 1, 2);
_cwLayout->addWidget(_btnShowDataContainerInspector, rowPosition++, 0, 1, 2);
#ifdef CAMPVIS_HAS_SCRIPTING
_btnLuaLoad = new QPushButton("Load Script", _containerWidget);
_cwLayout->addWidget(_btnLuaLoad, 4, 0, 1, 2);
_cwLayout->addWidget(_btnLuaLoad, rowPosition++, 0, 1, 2);
_btnLuaSave = new QPushButton("Save Script", _containerWidget);
_cwLayout->addWidget(_btnLuaSave, 5, 0, 1, 2);
_cwLayout->addWidget(_btnLuaSave, rowPosition++, 0, 1, 2);
connect(
_btnLuaLoad, SIGNAL(clicked()),
this, SLOT(onBtnLuaLoadClicked()));
......@@ -190,6 +200,9 @@ namespace campvis {
connect(
_btnPipelineFactory, SIGNAL(clicked()),
this, SLOT(onBtnPipelineFactoryClicked()));
connect(
_btnProcessorFactory, SIGNAL(clicked()),
this, SLOT(onBtnProcessorFactoryClicked()));
_application->s_PipelinesChanged.connect(this, &MainWindow::onPipelinesChanged);
_application->s_DataContainersChanged.connect(this, &MainWindow::onDataContainersChanged);
......@@ -235,7 +248,7 @@ namespace campvis {
void MainWindow::onDataContainersChanged() {
std::vector<AbstractPipeline*> pipelines;
std::for_each(_application->_pipelines.begin(), _application->_pipelines.end(), [&] (const CampVisApplication::PipelineRecord& pr) { pipelines.push_back(pr._pipeline); });
emit updatePipelineWidget(_application->_dataContainers, pipelines);
}
......@@ -410,6 +423,28 @@ namespace campvis {
_application->addPipeline(name, p);
}
void MainWindow::onBtnProcessorFactoryClicked() {
cgt::OpenGLJobProcessor::ScopedSynchronousGlJobExecution jobGuard;
std::string name = this->_cbProcessorFactory->currentText().toStdString();
if (_selectedPipeline == nullptr)
return;
IVec2Property temp = _selectedPipeline->getCanvasSize();
IVec2Property *viewPort = new IVec2Property(temp.getName(), temp.getTitle(), temp.getValue(), temp.getMinValue(), temp.getMaxValue(), temp.getStepValue());
AbstractProcessor* p = ProcessorFactory::getRef().createProcessor(name, viewPort);
if (p == nullptr)
return;
p->init();
_selectedPipeline->addProcessor(p);
std::vector<AbstractPipeline*> pipelines;
std::for_each(_application->_pipelines.begin(), _application->_pipelines.end(), [&] (const CampVisApplication::PipelineRecord& pr) { pipelines.push_back(pr._pipeline); });
emit updatePipelineWidget(_application->_dataContainers, pipelines);
}
void MainWindow::onRebuildShadersClicked() {
_application->rebuildAllShadersFromFiles();
}
......
......@@ -144,6 +144,9 @@ namespace campvis {
/// Slot to be called when _btnPipelineFactory was clicked;
void onBtnPipelineFactoryClicked();
/// Slot to be called when _btnProcessorFactory was clicked;
void onBtnProcessorFactoryClicked();
/// Slot to be called when all shaders shall be rebuilt.
void onRebuildShadersClicked();
......@@ -209,6 +212,9 @@ namespace campvis {
LogViewerWidget* _logViewer; ///< Widget displaying log messages
ScriptingWidget* _scriptingConsoleWidget; ///< Widget showing the scripting console (if available)
WorkflowControllerWidget* _workflowWidget; ///< Widget showing the workflow controller
QComboBox* _cbProcessorFactory; ///< Combobox for selecting the Processor from the ProcessorFactory
QPushButton* _btnProcessorFactory; ///< Button to add a Processor from the factory to the selected Pipeline
QPushButton* _btnLuaLoad;
QPushButton* _btnLuaSave;
......
......@@ -51,6 +51,9 @@ namespace campvis {
}
void AbstractTransferFunction::deinit() {
s_intensityDomainChanged.disconnect_all();
s_changed.disconnect_all();
delete _texture;
_texture = 0;
}
......
......@@ -194,6 +194,12 @@ namespace campvis {
* \return The DataHandle named _renderTargetID in the pipeline's DataContainer, 0 if no such handle exists.
*/
const std::string& getRenderTargetID() const;
/**
* Returns the canvas size
* \return The IVec2Property with current canvas size on it
*/
IVec2Property& getCanvasSize() {return _canvasSize;}
/// Signal emitted at the end of AbstractPipeline::init()
sigslot::signal0 s_init;
......
......@@ -44,12 +44,6 @@ namespace campvis {
void AutoEvaluationPipeline::init() {
AbstractPipeline::init();
// connect invalidation of each processor
for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
(*it)->s_invalidated.connect(this, &AutoEvaluationPipeline::onProcessorInvalidated);
}
_data->s_dataAdded.connect(this, &AutoEvaluationPipeline::onDataContainerDataAdded);
}
......@@ -75,6 +69,7 @@ namespace campvis {
findDataNamePropertiesAndAddToPortMap(processor);
AbstractPipeline::addProcessor(processor);
processor->s_invalidated.connect(this, &AutoEvaluationPipeline::onProcessorInvalidated);
}
void AutoEvaluationPipeline::executePipeline() {
......@@ -150,6 +145,10 @@ namespace campvis {
void AutoEvaluationPipeline::findDataNamePropertiesAndAddToPortMap(const HasPropertyCollection* hpc) {
const PropertyCollection& pc = hpc->getProperties();
// const_cast okay, since we're just connecting to signals
const_cast<HasPropertyCollection*>(hpc)->s_propertyAdded.connect(this, &AutoEvaluationPipeline::onPropertyCollectionPropertyAdded);
const_cast<HasPropertyCollection*>(hpc)->s_propertyRemoved.connect(this, &AutoEvaluationPipeline::onPropertyCollectionPropertyRemoved);
// traverse property collection
for (size_t i = 0; i < pc.size(); ++i) {
if (DataNameProperty* dnp = dynamic_cast<DataNameProperty*>(pc[i])) {
......@@ -171,4 +170,53 @@ namespace campvis {
}
}
void AutoEvaluationPipeline::onPropertyCollectionPropertyAdded(AbstractProperty* property) {
// check whether the incoming property is of the correct type (we only care about DataNameProperties)
if (DataNameProperty* dnp = dynamic_cast<DataNameProperty*>(property)) {
if (dnp->getAccessInfo() == DataNameProperty::READ) {
// check whether this property is already present in the port map
IteratorMapType::iterator it = _iteratorMap.find(dnp);
if (it == _iteratorMap.end()) {
// add to port map and register to changed signal
tbb::spin_rw_mutex::scoped_lock lock(_pmMutex, false);
std::pair<PortMapType::iterator, bool> result = _portMap.insert(std::make_pair(dnp->getValue(), dnp));
cgtAssert(result.second, "Could not insert Property into port map!");
if (result.second) {
_iteratorMap[dnp] = result.first;
dnp->s_changed.connect(this, &AutoEvaluationPipeline::onDataNamePropertyChanged);
}
}
else {
// this should not happen, otherwise we did something wrong before.
cgtAssert(false, "This property is already in iterator map!");
}
}
}
}
void AutoEvaluationPipeline::onPropertyCollectionPropertyRemoved(AbstractProperty* property) {
// check whether the incoming property is of the correct type (we only care about DataNameProperties)
if (DataNameProperty* dnp = dynamic_cast<DataNameProperty*>(property)) {
if (dnp->getAccessInfo() == DataNameProperty::READ) {
// find string-iterator pair for the given property
IteratorMapType::iterator it = _iteratorMap.find(dnp);
if (it != _iteratorMap.end()) {
// remove from port map and deregister from changed signal
dnp->s_changed.disconnect(this);
// acquire a write-lock since we erase the old value from our port map
tbb::spin_rw_mutex::scoped_lock lock(_pmMutex, true);
// remove the property from the port map
_portMap.unsafe_erase(it->second);
_iteratorMap.unsafe_erase(it);
}
else {
// this should not happen, otherwise we did something wrong before.
cgtAssert(false, "Could not find Property in iterator map!");
}
}
}
}
}
......@@ -92,6 +92,20 @@ namespace campvis {
*/
virtual void onDataContainerDataAdded(std::string name, DataHandle dh);
/**
* Callback when a property was added to one of the PropertyCollections.
* This property will be added to the port map.
* \param property Property that was added to the collection.
*/
virtual void onPropertyCollectionPropertyAdded(AbstractProperty* property);
/**
* Callback when a property was removed from one of the PropertyCollections.
* This property will be removed from the port map.
* \param property Property that was added removed from collection.
*/
virtual void onPropertyCollectionPropertyRemoved(AbstractProperty* property);
/**
* Recursively looks for all DataNameProperties in \a pc and adds them to the port map.
* If \a pc contains a MetaProperty, it will be seached recursively.
......
......@@ -122,7 +122,12 @@ namespace campvis {
* \param viewportSizeProp Pointer to the property defining the viewport size, must not be 0.
*/
virtual void setViewportSizeProperty(IVec2Property* viewportSizeProp);
/**
* Returns the effective viewport size considering LQ mode.
* \return lqMode ? _viewportSize/2 : _viewportSize
*/
cgt::ivec2 getEffectiveViewportSize() const;
BoolProperty p_lqMode; ///< Flag whether to enable LQ mode (halfsamples effective viewport size)
......@@ -155,12 +160,6 @@ namespace campvis {
*/
void createAndAttachDepthTexture();
/**
* Returns the effective viewport size considering LQ mode.
* \return lqMode ? _viewportSize/2 : _viewportSize
*/
cgt::ivec2 getEffectiveViewportSize() const;
/**
* Returns the current viewport size as ivec3.
* \return cgt::ivec3(getEffectiveViewportSize(), 1)
......
......@@ -226,11 +226,8 @@ namespace campvis {
campvis::GenericOptionProperty<T>::GenericOptionProperty(const std::string& name, const std::string& title, const GenericOption<T>* options, int count)
: AbstractOptionProperty(name, title)
{
cgtAssert(options != 0, "Pointer to options array must not be 0.")
cgtAssert(count > 0, "The number of options must be greater 0.");
_options.assign(options, options + count);
setMaxValue(count - 1);
setMaxValue(std::max(count - 1, 0));
setValue(0);
setMinValue(0);
}
......
......@@ -142,7 +142,7 @@ namespace campvis {
void HasPropertyCollection::clearProperties() {
for (auto it = _properties.begin(); it != _properties.end(); ++it) {
(*it)->s_changed.disconnect(this);
s_propertyRemoved.emitSignal(*it);
s_propertyRemoved.triggerSignal(*it);
}
_properties.clear();
......
......@@ -191,9 +191,12 @@ Texture* TextureReaderTga::loadTexture(const std::string& filename, Texture::Fil
}
Texture* TextureReaderTga::loadTextureArray(const std::vector<std::string>& filenames, Texture::Filter filter) {
if (filenames.empty())
return nullptr;
GLubyte* data = nullptr;
GLint format;
GLint internalFormat;
GLint format = 0;
GLint internalFormat = 0;
GLenum dataType = GL_UNSIGNED_BYTE;
size_t numBytesPerTexture = 0;
cgt::ivec3 dimensions;
......
......@@ -9,11 +9,11 @@ LIST(APPEND CampvisModulesHeaders
modulesapi.h
gen_pipelineregistration.h
pipelinefactory.h
processorfactory.h
processorfactory.h
)
LIST(APPEND CampvisModulesSources
pipelinefactory.cpp
processorfactory.cpp
processorfactory.cpp
)
......
......@@ -9,8 +9,8 @@ IF(${ModuleEnabled})
FIND_PACKAGE(DevIL REQUIRED)
LIST(APPEND CampvisGlobalIncludeDirs ${IL_INCLUDE_DIR})
LIST(APPEND CampvisGlobalExternalLibs ${IL_LIBRARIES} ${ILU_LIBRARIES})
IF(IL_FOUND)
MESSAGE(STATUS "** Found DevIL library")
IF(IL_LIBRARIES AND ILU_LIBRARIES)
MESSAGE(STATUS "** Found DevIL (IL and ILU) library")
ELSE()
MESSAGE(WARNING "Could not find DevIL library. Check your package manager to make sure DevIL is installed on your system.")
ENDIF()
......
......@@ -61,22 +61,26 @@ namespace campvis {
return toReturn;
}
std::vector<std::string> ProcessorFactory::getRegisteredRaycastingProcessors() const {
return _raycastingProcessors;
}
AbstractProcessor* ProcessorFactory::createProcessor(const std::string& id, IVec2Property* viewPortSizeProp) const {
tbb::spin_mutex::scoped_lock lock(_mutex);
if (viewPortSizeProp != nullptr) {
auto it = _processorMapWithIVec2Param.find(id);
if (it == _processorMapWithIVec2Param.end())
return nullptr;
else
auto it = _processorMapWithIVec2Param.find(id);
if (it != _processorMapWithIVec2Param.end()) {
if (viewPortSizeProp != nullptr)
return (it->second)(viewPortSizeProp);
} else {
auto it = _processorMapDefault.find(id);
if (it == _processorMapDefault.end())
return nullptr;
else
return (it->second)();
LDEBUGC("CAMPVis.modules.ProcessorFactory", "ViewPortSize should not be NULL");
return nullptr;
}
auto pos = _processorMapDefault.find(id);
if (pos != _processorMapDefault.end())
return (pos->second)();
return nullptr;
}
}
......@@ -41,6 +41,7 @@
#include <vector>
#include "core/pipeline/visualizationprocessor.h"
#include "core/pipeline/raycastingprocessor.h"
namespace campvis {
class AbstractProcessor;
......@@ -64,9 +65,26 @@ namespace campvis {
static void deinit();
/**
* Returns the list of all registered Processors.
* \return A std::vector of the string IDs of all registered processors.
*/
std::vector<std::string> getRegisteredProcessors() const;
AbstractProcessor* createProcessor(const std::string& id, IVec2Property* viewPortSizeProp = 0) const;
/**
* Returns the list of all registered raycasting processors (all registered processors
* inheriting from RaycastingProcessor).
* \return A std::vector of the string IDs of all registered raycasting processors.
*/
std::vector<std::string> getRegisteredRaycastingProcessors() const;
/**
* Factory method to create a processor from the given string ID.
* \param id String ID of the processor to create.
* \param viewPortSizeProp Pointer to the viewport size property that the created VisualizationProcessor should use. If the created processor is no VisualizationProcessor, then this argument is ignored. Defaults to nullptr.
* \return Pointer to the newly created processor, may be nullptr. Caller has to take ownership of the returned pointer.
*/
AbstractProcessor* createProcessor(const std::string& id, IVec2Property* viewPortSizeProp = nullptr) const;
/**
......@@ -79,6 +97,10 @@ namespace campvis {
size_t registerProcessorWithDefaultConstructor(std::function<AbstractProcessor*()> callee) {
tbb::spin_mutex::scoped_lock lock(_mutex);
// add to list of raycasting processors if needed
if (std::is_base_of<RaycastingProcessor, T>::value)
_raycastingProcessors.push_back(T::getId());
auto it = _processorTypeMap.find(T::getId());
if (it != _processorTypeMap.end()) {
// check, whether the type is the same, then a double registration is okay since it
......@@ -104,6 +126,10 @@ namespace campvis {
size_t registerProcessorWithIVec2PropParam(std::function<AbstractProcessor*(IVec2Property*)> callee) {
tbb::spin_mutex::scoped_lock lock(_mutex);
// add to list of raycasting processors if needed
if (std::is_base_of<RaycastingProcessor, T>::value)
_raycastingProcessors.push_back(T::getId());
auto it = _processorTypeMap.find(T::getId());
if (it != _processorTypeMap.end()) {
// check, whether the type is the same, then a double registration is okay since it
......@@ -126,6 +152,8 @@ namespace campvis {
std::map< std::string, std::type_index> _processorTypeMap;
std::map< std::string, std::function<AbstractProcessor*()> > _processorMapDefault;
std::map< std::string, std::function<AbstractProcessor*(IVec2Property*)> > _processorMapWithIVec2Param;
std::vector<std::string> _raycastingProcessors;
};
......
......@@ -37,7 +37,6 @@ namespace campvis {
OptimizedRaycaster::OptimizedRaycaster(IVec2Property* viewportSizeProp)
: RaycastingProcessor(viewportSizeProp, "modules/vis/glsl/optimizedraycaster.frag", true)
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_enableShading("EnableShading", "Enable Shading", true)
, p_lightId("LightId", "Input Light Source", "lightsource", DataNameProperty::READ)
, p_enableShadowing("EnableShadowing", "Enable Hard Shadows (Expensive!)", false)
......@@ -51,7 +50,6 @@ namespace campvis {
addProperty(p_enableShading, INVALID_RESULT | INVALID_PROPERTIES | INVALID_SHADER);
addProperty(p_lightId);
addProperty(p_targetImageID);
addProperty(p_enableIntersectionRefinement, INVALID_RESULT | INVALID_SHADER);
addProperty(p_useEmptySpaceSkipping, INVALID_RESULT | INVALID_BBV);
......
......@@ -78,8 +78,6 @@ namespace campvis {
/// \see AbstractProcessor::deinit
virtual void deinit();
DataNameProperty p_targetImageID; ///< image ID for output image
BoolProperty p_enableShading; ///< Flag whether to enable shading
DataNameProperty p_lightId; ///< Name/ID for the LightSource to use
BoolProperty p_enableShadowing;
......
......@@ -114,7 +114,6 @@ namespace campvis {
createAndAttachColorTexture();
createAndAttachDepthTexture();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (passthroughImage) {
......@@ -127,6 +126,7 @@ namespace campvis {
_passthroughShader->deactivate();
}
glEnable(GL_DEPTH_TEST);
_shader->activate();
cgt::TextureUnit textureUnit;
......@@ -144,7 +144,6 @@ namespace campvis {
_cubeGeometry->render(GL_TRIANGLE_FAN);
glDepthFunc(GL_LESS);
glDisable(GL_DEPTH_TEST);
_shader->deactivate();
......
......@@ -33,6 +33,9 @@
#include "core/classification/simpletransferfunction.h"
#include "cgt/opengljobprocessor.h"
#include "core/tools/stringutils.h"
namespace campvis {
const std::string VolumeRenderer::loggerCat_ = "CAMPVis.modules.vis.VolumeRenderer";
......@@ -47,6 +50,7 @@ namespace campvis {
, p_eepProps("EEPProps", "Entry/Exit Points Generator")
, p_raycasterProps("RaycasterProps", "Raycaster")
, p_orientationOverlayProps("OrientationOverlayProps", "Orientation Overlay")
, p_raycastingProcSelector("RaycasterSelector", "Select Raycaster to Use", nullptr, 0)
, _pgGenerator()
, _eepGenerator(viewportSizeProp)
, _raycaster(raycaster)
......@@ -72,6 +76,15 @@ namespace campvis {
_eepGenerator.p_exitImageID.setVisible(false);
addProperty(p_eepProps, AbstractProcessor::VALID);
const std::vector<std::string>& raycasters = ProcessorFactory::getRef().getRegisteredRaycastingProcessors();
for (size_t i = 0; i < raycasters.size(); i++) {
p_raycastingProcSelector.addOption(GenericOption<std::string>(raycasters[i], raycasters[i]));
}
if (_raycaster != nullptr) {
p_raycastingProcSelector.selectByOption(_raycaster->getName());
}
addProperty(p_raycastingProcSelector);
p_raycasterProps.addPropertyCollection(*_raycaster);
_raycaster->p_lqMode.setVisible(false);
_raycaster->p_camera.setVisible(false);
......@@ -189,6 +202,57 @@ namespace campvis {
_raycaster->p_targetImageID.setValue(p_outputImage.getValue() + ".raycasted");
_orientationOverlay.p_passThroughImageId.setValue(p_outputImage.getValue() + ".raycasted");
}
if (prop == &p_raycastingProcSelector) {
// lock this processor while we exchange the ray caster to make sure nobody
// will call process() in between.
AbstractProcessor::ScopedLock lockGuard(this);
RaycastingProcessor *currentRaycaster = _raycaster;
if (p_raycastingProcSelector.getOptionId() == currentRaycaster->getName()) {
return;
}
p_lqMode.removeSharedProperty(&currentRaycaster->p_lqMode);
p_inputVolume.removeSharedProperty(&currentRaycaster->p_sourceImageID);
p_camera.removeSharedProperty(&currentRaycaster->p_camera);
p_outputImage.removeSharedProperty(&currentRaycaster->p_targetImageID);
p_raycasterProps.clearProperties();
currentRaycaster->s_invalidated.disconnect(this);
_raycaster = dynamic_cast<RaycastingProcessor*>(ProcessorFactory::getRef().createProcessor(p_raycastingProcSelector.getOptionId(), _viewportSizeProperty));
cgtAssert(_raycaster != 0, "Raycaster must not be 0.");
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_lqMode.addSharedProperty(&_raycaster->p_lqMode);
p_inputVolume.addSharedProperty(&_raycaster->p_sourceImageID);
p_camera.addSharedProperty(&_raycaster->p_camera);
p_outputImage.addSharedProperty(&_raycaster->p_targetImageID);
_raycaster->s_invalidated.connect(this, &VolumeRenderer::onProcessorInvalidated);
cgt::OpenGLJobProcessor::ScopedSynchronousGlJobExecution jobGuard;
_raycaster->init();
_raycaster->p_sourceImageID.setValue(currentRaycaster->p_sourceImageID.getValue());
_raycaster->p_entryImageID.setValue(currentRaycaster->p_entryImageID.getValue());
_raycaster->p_exitImageID.setValue(currentRaycaster->p_exitImageID.getValue());
_raycaster->p_targetImageID.setValue(currentRaycaster->p_targetImageID.getValue());
_raycaster->p_camera.setValue(currentRaycaster->p_camera.getValue());
_raycaster->p_transferFunction.replaceTF(currentRaycaster->p_transferFunction.getTF()->clone());
_raycaster->p_jitterStepSizeMultiplier.setValue(currentRaycaster->p_jitterStepSizeMultiplier.getValue());
_raycaster->p_samplingRate.setValue(currentRaycaster->p_samplingRate.getValue());
currentRaycaster->deinit();
invalidate(PG_INVALID | EEP_INVALID | RAYCASTER_INVALID | AbstractProcessor::INVALID_RESULT);
delete currentRaycaster;
}
VisualizationProcessor::onPropertyChanged(prop);
}
......@@ -207,5 +271,6 @@ namespace campvis {
RaycastingProcessor* VolumeRenderer::getRaycastingProcessor() {
return _raycaster;
}
}
......@@ -25,6 +25,7 @@
#ifndef VOLUMERENDERER_H__
#define VOLUMERENDERER_H__
#include "sigslot/sigslot.h"