The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 662ce762 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge branch 'development' into 'master'

Development



See merge request !2
parents 9abcb3e4 cbd8ddaa
......@@ -36,7 +36,7 @@ vec3 computeGradientForwardDifferencesLod(in sampler3D tex, in TextureParameters
float dx = textureLodOffset(tex, texCoords, lod, ivec3(1, 0, 0)).r;
float dy = textureLodOffset(tex, texCoords, lod, ivec3(0, 1, 0)).r;
float dz = textureLodOffset(tex, texCoords, lod, ivec3(0, 0, 1)).r;
return vec3(v - dx, v - dy, v - dz) * texParams._voxelSize;
return vec3(dx - v, dy - v, dz - v) * texParams._voxelSize;
}
/**
......@@ -63,7 +63,7 @@ vec3 computeGradientCentralDifferencesLod(in sampler3D tex, in TextureParameters
float mdx = textureLodOffset(tex, texCoords, lod, ivec3(-1, 0, 0)).r;
float mdy = textureLodOffset(tex, texCoords, lod, ivec3(0, -1, 0)).r;
float mdz = textureLodOffset(tex, texCoords, lod, ivec3(0, 0, -1)).r;
return vec3(mdx - dx, mdy - dy, mdz - dz) * texParams._voxelSize * 0.5;
return vec3(dx - mdx, dy - mdy, dz - mdz) * texParams._voxelSize * 0.5;
}
/**
......@@ -200,7 +200,7 @@ vec3 computeGradientSobel(in sampler3D tex, in vec3 texCoords) {
sobel.y += value;
sobel.z += value;
return -sobelScale * sobel;
return sobelScale * sobel;
}
......
......@@ -155,6 +155,11 @@ namespace campvis {
}
}
void AbstractProcessor::forceProcess(DataContainer& dataContainer, int invalidationLevel) {
invalidate(invalidationLevel);
process(dataContainer);
}
void AbstractProcessor::updateShader() {
LDEBUG("Called non-overriden updateShader() in " << getName() << ". Did you forget to override your method?");
}
......@@ -163,11 +168,7 @@ namespace campvis {
LDEBUG("Called non-overriden updateProperties() in " << getName() << ". Did you forget to override your method?");
}
void AbstractProcessor::addProperty(AbstractProperty& prop) {
this->addProperty(prop, INVALID_RESULT);
}
void AbstractProcessor::addProperty(AbstractProperty& prop, int invalidationLevel) {
void AbstractProcessor::addProperty(AbstractProperty& prop, int invalidationLevel /* = INVALID_RESULT*/) {
HasPropertyCollection::addProperty(prop);
setPropertyInvalidationLevel(prop, invalidationLevel);
}
......
......@@ -149,13 +149,6 @@ namespace campvis {
*/
virtual ProcessorState getProcessorState() const = 0;
/**
* Registers \a prop as property with the default invalidation level of INVALID_RESULT.
* \see HasPropertyCollection::addProperty()
* \param prop Property to register
*/
virtual void addProperty(AbstractProperty& prop);
/**
* Registers \a prop as property with the provided invalidation level. Registered properties
* can be accessed from the outside, e.g. via getProperty(), and will automatically invalidate
......@@ -164,7 +157,7 @@ namespace campvis {
* \param prop Property to add
* \param invalidationLevel Invalidation level of this property
*/
void addProperty(AbstractProperty& prop, int invalidationLevel);
void addProperty(AbstractProperty& prop, int invalidationLevel = INVALID_RESULT);
/**
* Sets the property invalidation level to the specified value.
......@@ -183,6 +176,16 @@ namespace campvis {
**/
void process(DataContainer& data);
/**
* Forces the execution of this processor according to the given invalidation level and
* independent of its current invalidation level. Sets this processor's invalidation level
* to \a invalidationLevel and then calles process().
*
* \param dataContainer DataContainer to work on
* \param invalidationLevel Invalidation level to enforce prior to calling process.
*/
void forceProcess(DataContainer& dataContainer, int invalidationLevel);
/**
* Gets the flag whether this processor is currently enabled.
* \return _enabled
......
......@@ -26,12 +26,13 @@
#include "cgt/filesystem.h"
#include "cgt/glcontextmanager.h"
#include "cgt/shadermanager.h"
#include "cgt/event/keyevent.h"
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/renderdata.h"
#include "core/datastructures/facegeometry.h"
#ifdef CAMPVIS_HAS_MODULE_DEVIL
#include <IL/il.h>
......@@ -50,22 +51,27 @@ namespace campvis {
, _usBlurFilter(&_canvasSize)
, _usFusion(&_canvasSize)
, p_autoExecution("AutoExecution", "Automatic Execution", false)
, p_showFan("ShowFan", "Show Fan", true)
, p_sourcePath("SourcePath", "Source Files Path", "", StringProperty::DIRECTORY)
, p_targetPathCm("TargetPathCm", "Target Path Confidence Map Files", "", StringProperty::DIRECTORY)
, p_targetPathResampled("TargetPathResampled", "Target Path Resampled Files", "", StringProperty::DIRECTORY)
, p_targetPathCmCpu("TargetPathCm", "Target Path Confidence Map Files", "", StringProperty::DIRECTORY)
, p_targetPathColorOverlay("TargetPathColorOverlay", "Target Path Color Overlay Files", "", StringProperty::DIRECTORY)
, p_targetPathColor("TargetPathColor", "Target Path Color Files", "", StringProperty::DIRECTORY)
, p_targetPathFuzzy("TargetPathFuzzy", "Target Path Fuzzy Files", "", StringProperty::DIRECTORY)
, p_range("Range", "Files Range", cgt::ivec2(0, 1), cgt::ivec2(0, 0), cgt::ivec2(10000, 10000))
, p_execute("Execute", "Execute Batch Pipeline")
, _shader(nullptr)
{
addProcessor(&_usReader);
addProcessor(&_scanlineConverter);
addProcessor(&_confidenceGenerator);
addProcessor(&_usFusion);
addProcessor(&_usBlurFilter);
addProperty(p_autoExecution);
addProperty(p_sourcePath);
addProperty(p_targetPathCm);
addProperty(p_targetPathResampled);
addProperty(p_targetPathCmCpu);
addProperty(p_targetPathColorOverlay);
addProperty(p_targetPathColor);
addProperty(p_targetPathFuzzy);
......@@ -78,31 +84,37 @@ namespace campvis {
void CmBatchGeneration::init() {
AutoEvaluationPipeline::init();
_shader = ShdrMgr.load("core/glsl/passthrough.vert", "core/glsl/passthrough.frag", "");
_imageWriter.init();
p_sourcePath.setValue("D:\\cm_stuff\\original");
p_targetPathCm.setValue("D:\\cm_stuff\\cm");
p_targetPathResampled.setValue("D:\\cm_stuff\\resampled");
p_targetPathCmCpu.setValue("D:\\cm_stuff\\cm");
p_targetPathColorOverlay.setValue("D:\\cm_stuff\\colorOverlay");
p_targetPathColor.setValue("D:\\cm_stuff\\color");
p_targetPathFuzzy.setValue("D:\\cm_stuff\\fuzzy");
p_range.setValue(cgt::ivec2(0, 1));
p_execute.s_clicked.connect(this, &CmBatchGeneration::execute);
p_execute.s_clicked.connect(this, &CmBatchGeneration::startBatchProcess);
_usReader.p_url.setValue("D:\\cm_stuff\\original\\export0000.bmp");
_usReader.p_targetImageID.setValue("us.image");
_usReader.p_importType.selectById("localIntensity");
_usReader.p_targetImageID.addSharedProperty(&_confidenceGenerator.p_sourceImageID);
_usReader.p_targetImageID.addSharedProperty(&_usFusion.p_usImageId);
_usReader.p_targetImageID.addSharedProperty(&_usBlurFilter.p_inputImage);
_usReader.p_targetImageID.addSharedProperty(&_scanlineConverter.p_sourceImageID);
_scanlineConverter.p_targetImageID.setValue("us.resampled");
_scanlineConverter.p_targetImageID.addSharedProperty(&_confidenceGenerator.p_sourceImageID);
_scanlineConverter.p_targetImageID.addSharedProperty(&_usFusion.p_usImageId);
_scanlineConverter.p_targetImageID.addSharedProperty(&_usBlurFilter.p_inputImage);
_confidenceGenerator.p_targetImageID.setValue("confidence.image.generated");
_confidenceGenerator.p_targetImageID.addSharedProperty(&_usFusion.p_confidenceImageID);
_confidenceGenerator.p_curvilinear.setValue(true);
_confidenceGenerator.p_origin.setValue(cgt::vec2(340.f, 540.f));
_confidenceGenerator.p_angles.setValue(cgt::vec2(4.064f, 5.363f));
//_confidenceGenerator.p_angles.setValue(cgt::vec2(232.f / 180.f * cgt::PIf, 307.f / 180.f * cgt::PIf));
//_confidenceGenerator.p_origin.setValue(cgt::vec2(320.f, 35.f));
//_confidenceGenerator.p_angles.setValue(cgt::vec2(45.f / 180.f * cgt::PIf, 135.f / 180.f * cgt::PIf));
_confidenceGenerator.p_lengths.setValue(cgt::vec2(116.f, 543.f));
//_confidenceGenerator.p_curvilinear.setValue(true);
//_confidenceGenerator.p_origin.setValue(cgt::vec2(340.f, 540.f));
//_confidenceGenerator.p_angles.setValue(cgt::vec2(4.064f, 5.363f));
////_confidenceGenerator.p_angles.setValue(cgt::vec2(232.f / 180.f * cgt::PIf, 307.f / 180.f * cgt::PIf));
////_confidenceGenerator.p_origin.setValue(cgt::vec2(320.f, 35.f));
////_confidenceGenerator.p_angles.setValue(cgt::vec2(45.f / 180.f * cgt::PIf, 135.f / 180.f * cgt::PIf));
//_confidenceGenerator.p_lengths.setValue(cgt::vec2(116.f, 543.f));
_confidenceGenerator.p_alpha.setValue(2.f);
_confidenceGenerator.p_beta.setValue(80.f);
_confidenceGenerator.p_gamma.setValue(.05f);
......@@ -127,59 +139,103 @@ namespace campvis {
}
void CmBatchGeneration::deinit() {
_imageWriter.deinit();
ShdrMgr.dispose(_shader);
AutoEvaluationPipeline::deinit();
}
void CmBatchGeneration::execute() {
void CmBatchGeneration::paint() {
if (p_showFan.getValue()) {
ImageRepresentationLocal::ScopedRepresentation input(getDataContainer(), _usReader.p_targetImageID.getValue());
if (input) {
const cgt::ivec2 inputSize = input->getSize().xy();
auto vertices = _scanlineConverter.generateLookupVertices(input->getParent());
_shader->activate();
_shader->setUniform("_viewMatrix", cgt::mat4::createTranslation(cgt::vec3(-1.f, -1.f, -1.f)) * cgt::mat4::createScale(cgt::vec3(2.f, 2.f, 2.f)));
_shader->setUniform("_modelMatrix", cgt::mat4::createScale(cgt::vec3(1.f / float(inputSize.x), 1.f / float(inputSize.y), 1.f)));
glPointSize(3.f);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
std::vector<cgt::vec4> colors(vertices.size(), cgt::vec4(1.f, 0.7f, 0.f, 0.4f));
FaceGeometry face(vertices, std::vector<cgt::vec3>(), colors);
face.render(GL_POINTS);
glDisable(GL_BLEND);
glPointSize(1.f);
_shader->deactivate();
}
}
}
void CmBatchGeneration::onPropertyChanged(const AbstractProperty* p) {
if (p == &p_showFan)
setPipelineDirty();
else
AutoEvaluationPipeline::onPropertyChanged(p);
}
void CmBatchGeneration::onProcessorInvalidated(AbstractProcessor* processor) {
if (processor == &_scanlineConverter && p_showFan.getValue()) {
setPipelineDirty();
}
AutoEvaluationPipeline::onProcessorInvalidated(processor);
}
void CmBatchGeneration::startBatchProcess() {
if (p_range.getValue().x > p_range.getValue().y)
return;
p_autoExecution.setValue(false);
cgt::GLContextScopedLock lock(_canvas);
getDataContainer().removeData(_confidenceGenerator.p_targetImageID.getValue());
getDataContainer().removeData(_confidenceGenerator.p_targetImageID.getValue() + "velocities");
cgt::GLContextScopedLock lock(_canvas);
cgt::ivec2 originalCanvasSize = _canvasSize.getValue();
_canvasSize.setValue(_scanlineConverter.p_targetSize.getValue());
for (int i = p_range.getValue().x; i < p_range.getValue().y; ++i) {
executePass(i);
}
}
void CmBatchGeneration::onProcessorInvalidated(AbstractProcessor* processor) {
if (p_autoExecution.getValue())
AutoEvaluationPipeline::onProcessorInvalidated(processor);
_canvasSize.setValue(originalCanvasSize);
}
void CmBatchGeneration::executePass(int path) {
std::stringstream ss;
// set up processors:
ss << p_sourcePath.getValue() << "\\" << "export" << std::setfill('0') << std::setw(4) << path << ".bmp";
_usReader.p_url.setValue(ss.str());
std::stringstream ss;
ss << "export" << std::setfill('0') << std::setw(4) << path << ".bmp";
std::string fileName = ss.str();
// read image
_usReader.p_url.setValue(p_sourcePath.getValue() + "\\" + fileName);
forceExecuteProcessor(&_usReader);
DataHandle dh = _dataContainer->getData(_usReader.p_targetImageID.getValue());
if (dh.getData() != 0) {
if (const ImageData* tester = dynamic_cast<const ImageData*>(dh.getData())) {
_canvasSize.setValue(tester->getSize().xy());
}
}
forceExecuteProcessor(&_scanlineConverter);
forceExecuteProcessor(&_confidenceGenerator);
forceExecuteProcessor(&_usBlurFilter);
_usFusion.p_transferFunction.setAutoFitWindowToData(false);
_usFusion.p_transferFunction.getTF()->setIntensityDomain(cgt::vec2(0.f, 1.f));
{
// Confidence Map
// Resampled
Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(256);
tf->addGeometry(TFGeometry1D::createQuad(cgt::vec2(0.0f, 1.0f), cgt::col4(0, 0, 0, 255), cgt::col4(0, 0, 0, 0)));
_usFusion.p_confidenceTF.replaceTF(tf);
_usFusion.p_view.selectById("us");
forceExecuteProcessor(&_usFusion);
save(_usFusion.p_targetImageID.getValue(), p_targetPathResampled.getValue() + "\\" + fileName);
}
{
// Confidence Map
_usFusion.p_view.selectById("cm");
forceExecuteProcessor(&_usFusion);
save(path, p_targetPathCm.getValue());
save(_usFusion.p_targetImageID.getValue(), p_targetPathCmCpu.getValue() + "\\" + fileName);
}
{
......@@ -190,7 +246,7 @@ namespace campvis {
_usFusion.p_hue.setValue(0.15f);
_usFusion.p_view.selectById("colorOverlay");
forceExecuteProcessor(&_usFusion);
save(path, p_targetPathColorOverlay.getValue());
save(_usFusion.p_targetImageID.getValue(), p_targetPathColorOverlay.getValue() + "\\" + fileName);
}
{
......@@ -201,7 +257,7 @@ namespace campvis {
_usFusion.p_hue.setValue(0.23f);
_usFusion.p_view.selectById("mappingLAB");
forceExecuteProcessor(&_usFusion);
save(path, p_targetPathColor.getValue());
save(_usFusion.p_targetImageID.getValue(), p_targetPathColor.getValue() + "\\" + fileName);
}
{
......@@ -211,53 +267,15 @@ namespace campvis {
_usFusion.p_confidenceTF.replaceTF(tf);
_usFusion.p_view.selectById("mappingSharpness");
forceExecuteProcessor(&_usFusion);
save(path, p_targetPathFuzzy.getValue());
save(_usFusion.p_targetImageID.getValue(), p_targetPathFuzzy.getValue() + "\\" + fileName);
}
}
void CmBatchGeneration::save(int path, const std::string& basePath) {
// get result
ScopedTypedData<RenderData> rd(*_dataContainer, _usFusion.p_targetImageID.getValue());
const ImageRepresentationGL* rep = rd->getColorTexture()->getRepresentation<ImageRepresentationGL>(false);
if (rep != 0) {
#ifdef CAMPVIS_HAS_MODULE_DEVIL
if (! cgt::FileSystem::dirExists(basePath))
cgt::FileSystem::createDirectory(basePath);
std::stringstream sss;
sss << basePath << "\\" << "export" << std::setfill('0') << std::setw(4) << path << ".bmp";
std::string filename = sss.str();
if (cgt::FileSystem::fileExtension(filename).empty()) {
LERROR("Filename has no extension");
return;
}
// get color buffer content
GLubyte* colorBuffer = rep->getTexture()->downloadTextureToBuffer(GL_RGBA, GL_UNSIGNED_SHORT);
cgt::ivec2 size = rep->getSize().xy();
// create Devil image from image data and write it to file
ILuint img;
ilGenImages(1, &img);
ilBindImage(img);
// put pixels into IL-Image
ilTexImage(size.x, size.y, 1, 4, IL_RGBA, IL_UNSIGNED_SHORT, colorBuffer);
ilEnable(IL_FILE_OVERWRITE);
ilResetWrite();
ILboolean success = ilSaveImage(filename.c_str());
ilDeleteImages(1, &img);
delete[] colorBuffer;
if (!success) {
LERROR("Could not save image to file: " << ilGetError());
}
#else
return;
#endif
}
void CmBatchGeneration::save(const std::string& dataName, const std::string& fileName) {
_imageWriter.p_inputImage.setValue(dataName);
_imageWriter.p_url.setValue(fileName);
_imageWriter.p_writeDepthImage.setValue(false);
forceExecuteProcessor(&_imageWriter);
}
}
......@@ -31,11 +31,18 @@
#include "modules/modulesapi.h"
#include "modules/devil/processors/devilimagereader.h"
#include "modules/devil/processors/devilimagewriter.h"
#include "modules/advancedusvis/processors/advancedusfusion.h"
#include "modules/advancedusvis/processors/scanlineconverter.h"
#include "modules/preprocessing/processors/glgaussianfilter.h"
#include "modules/randomwalk/processors/confidencemapgenerator.h"
namespace cgt {
class Shader;
}
namespace campvis {
class CAMPVIS_MODULES_API CmBatchGeneration : public AutoEvaluationPipeline {
public:
/**
......@@ -57,37 +64,38 @@ namespace campvis {
static const std::string getId() { return "CmBatchGeneration"; };
/**
* Execute this pipeline.
**/
void execute();
virtual void paint() override;
protected:
/**
* Slot getting called when one of the observed processors got invalidated.
* Overwrites the default behaviour to do nothing.
*/
virtual void onProcessorInvalidated(AbstractProcessor* processor);
void onPropertyChanged(const AbstractProperty* p) override;
virtual void onProcessorInvalidated(AbstractProcessor* processor) override;
void startBatchProcess();
void executePass(int path);
void save(const std::string& dataName, const std::string& fileName);
void save(int path, const std::string& basePath);
DevilImageReader _usReader; ///< Reads the original image
ScanlineConverter _scanlineConverter; ///< Performs a scanline conversion
ConfidenceMapGenerator _confidenceGenerator; ///< Computes the CM using the original RandomWalks library
GlGaussianFilter _usBlurFilter; ///< Performs a Gaussian Blur
AdvancedUsFusion _usFusion; ///< Applies the Uncertainty Visualization
DevilImageReader _usReader;
ConfidenceMapGenerator _confidenceGenerator;
GlGaussianFilter _usBlurFilter;
AdvancedUsFusion _usFusion;
DevilImageWriter _imageWriter; ///< Used to write out images
BoolProperty p_autoExecution;
BoolProperty p_showFan;
StringProperty p_sourcePath; ///< Path for the input images
StringProperty p_targetPathResampled; ///< Path for the resampled images
StringProperty p_targetPathCmCpu; ///< Path for the CPU-computed Confidence Maps
StringProperty p_targetPathColorOverlay; ///< Path for the color overlay visualization
StringProperty p_targetPathColor; ///< Path for the color modulation visualization
StringProperty p_targetPathFuzzy; ///< Path for the fuzziness visualization
StringProperty p_sourcePath;
StringProperty p_targetPathCm;
StringProperty p_targetPathColorOverlay;
StringProperty p_targetPathColor;
StringProperty p_targetPathFuzzy;
IVec2Property p_range;
IVec2Property p_range; ///< Range for image iteration
ButtonProperty p_execute; ///< Button to start the batch process
ButtonProperty p_execute;
cgt::Shader* _shader;
};
}
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2015, 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 "scanlineconverter.h"
#include "cgt/logmanager.h"
#include "cgt/cgt_math.h"
#include "cgt/vector.h"
#include "core/tools/interval.h"
#include "core/datastructures/imagedata.h"
#include "core/datastructures/genericimagerepresentationlocal.h"
namespace campvis {
const std::string ScanlineConverter::loggerCat_ = "CAMPVis.modules.classification.ScanlineConverter";
ScanlineConverter::ScanlineConverter()
: AbstractProcessor()
, p_sourceImageID("InputImage", "Input Image ID", "image", DataNameProperty::READ)
, p_targetImageID("OutputConfidenceMap", "Output Confidence Map Image ID", "confidencemap", DataNameProperty::WRITE)
, p_targetSize("TargetSize", "Target Image Size", cgt::ivec2(512, 512), cgt::ivec2(16, 16), cgt::ivec2(2048, 2048))
, p_origin("PolarOrigin", "Polar Origin", cgt::vec2(340.f, 536.f), cgt::vec2(-1000.f), cgt::vec2(1000.f), cgt::vec2(0.1f))
, p_angles("PolarAngles", "Polar Angles", cgt::vec2(233.f, 308.f), cgt::vec2(0.f), cgt::vec2(360.f), cgt::vec2(0.1f))
, p_lengths("PolarLengths", "Polar Lengths", cgt::vec2(116.f, 540.f), cgt::vec2(0.f), cgt::vec2(1000.f), cgt::vec2(0.1f))
{
addProperty(p_sourceImageID);
addProperty(p_targetImageID);
addProperty(p_targetSize);
addProperty(p_origin);
addProperty(p_angles);
addProperty(p_lengths);
}
ScanlineConverter::~ScanlineConverter() {
}
std::vector<cgt::vec3> ScanlineConverter::generateLookupVertices(const ImageData* inputImage) const {
cgtAssert(inputImage != nullptr, "Input image must not be 0!");
std::vector<cgt::vec3> vertices;
const cgt::ivec2& outputSize = p_targetSize.getValue();
const float rarara = cgt::PIf / 180.f;
Interval<float> fanAngles(p_angles.getValue().x * rarara, p_angles.getValue().y * rarara);
Interval<float> fanSize(p_lengths.getValue().x, p_lengths.getValue().y);
for (int y = 0; y < outputSize.y; ++y) {
float r = fanSize.getLeft() + static_cast<float>(outputSize.y - 1 - y) / static_cast<float>(outputSize.y) * fanSize.size();
for (int x = 0; x < outputSize.x; ++x) {
float phi = fanAngles.getLeft() + (static_cast<float>(x) / static_cast<float>(outputSize.x) * fanAngles.size());
const cgt::vec3 cc(r * cos(phi) + p_origin.getValue().x, r * sin(phi) + p_origin.getValue().y, 0.f);
vertices.push_back(cc);
}
}
return vertices;
}
void ScanlineConverter::updateResult(DataContainer& dataContainer) {
ImageRepresentationLocal::ScopedRepresentation input(dataContainer, p_sourceImageID.getValue());
if (input != 0 && input->getDimensionality() == 2) {
// resample image
size_t numChannels = input->getParent()->getNumChannels();
auto outputImage = new ImageData(2, cgt::vec3(p_targetSize.getValue().x, p_targetSize.getValue().y, 1), numChannels);
auto wtp = input->getWeaklyTypedPointer();
wtp._pointer = nullptr;
auto outputRep = ImageRepresentationLocal::create(outputImage, wtp);
auto vertices = generateLookupVertices(input->getParent());
for (size_t i = 0; i < vertices.size(); ++i) {
for (size_t c = 0; c < numChannels; ++c) {
outputRep->setElementNormalized(i, c, input->getElementNormalizedLinear(vertices[i], c));
}
}
dataContainer.addData(p_targetImageID.getValue(), outputImage);
}
else {
LDEBUG("No suitable input image found.");
}
}
}
// ================================================================================================
//