Commit 15174e5a authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge branch 'various-stuff' into 'development'

Various stuff

See merge request !103
parents b2307f63 8cf0c634
......@@ -32,6 +32,7 @@
#include "core/datastructures/datahandle.h"
#include "core/datastructures/renderdata.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/datastructures/facegeometry.h"
#include "core/datastructures/geometrydatafactory.h"
#include "core/classification/tfgeometry1d.h"
......@@ -224,7 +225,7 @@ namespace campvis {
return;
_paintShader->setIgnoreUniformLocationError(true);
if (texture->getDimensions().z == 1) {
if (texture->getType() == GL_TEXTURE_2D) {
unit2d.activate();
texture->bind();
_paintShader->setUniform("_is3d", false);
......@@ -233,7 +234,7 @@ namespace campvis {
_paintShader->setUniform("_2dTextureParams._sizeRCP", cgt::vec2(1.f) / cgt::vec2(texture->getDimensions().xy()));
_paintShader->setUniform("_2dTextureParams._numChannels", static_cast<int>(texture->getNumChannels()));
}
else {
else if (texture->getType() == GL_TEXTURE_3D) {
unit3d.activate();
texture->bind();
_paintShader->setUniform("_is3d", true);
......@@ -283,9 +284,10 @@ namespace campvis {
const ImageData* id = static_cast<const ImageData*>(_textures[texIndx].getData());
const cgt::Texture* tex = id->getRepresentation<ImageRepresentationGL>()->getTexture();
cgt::ivec2 imageSize = id->getSize().xy();
const ImageRepresentationLocal* localRep = id->getRepresentation<ImageRepresentationLocal>();
cgt::svec2 imageSize = id->getSize().xy();
cgt::vec2 lookupTexelFloat = cgt::vec2((e->coord() % _quadSize) * imageSize) / cgt::vec2(_quadSize);
cgt::vec2 lookupTexelFloat = cgt::vec2((e->coord() % _quadSize) * cgt::ivec2(imageSize)) / cgt::vec2(_quadSize);
// compute transformation matrices
float renderTargetRatio = static_cast<float>(_quadSize.x) / static_cast<float>(_quadSize.y);
......@@ -295,19 +297,28 @@ namespace campvis {
lookupTexelFloat /= (ratioRatio > 1) ? cgt::vec2(1.f, 1.f / ratioRatio) : cgt::vec2(ratioRatio, 1.f);
cgt::ivec2 lookupTexel(lookupTexelFloat);
cgt::svec3 lookupTexel(lookupTexelFloat.x, imageSize.y - lookupTexelFloat.y, 0);
if (lookupTexel.x >= 0 && lookupTexel.y >= 0 && lookupTexel.x < imageSize.x && lookupTexel.y < imageSize.y) {
if(tex->isDepthTexture()) {
emit s_depthChanged(tex->depthAsFloat(lookupTexel.x, imageSize.y - lookupTexel.y - 1));
if (tex->isDepthTexture()) {
emit s_depthChanged(localRep->getElementNormalized(lookupTexel, 0));
}
else {
if (tex->getDimensions().z != 1) {
if (p_currentSlice.getValue() >= 0 && p_currentSlice.getValue() < tex->getDimensions().z) {
emit s_colorChanged(tex->texelAsFloat(lookupTexel.x, imageSize.y - lookupTexel.y - 1, p_currentSlice.getValue()));
lookupTexel.z = static_cast<size_t>(p_currentSlice.getValue());
cgt::vec4 texel(0.f);
for (size_t i = 0; i < id->getNumChannels(); ++i) {
texel[i] = localRep->getElementNormalized(lookupTexel, i);
}
emit s_colorChanged(texel);
}
}
else if (tex->getDimensions().y != 1) {
emit s_colorChanged(tex->texelAsFloat(lookupTexel.x, imageSize.y - lookupTexel.y - 1));
cgt::vec4 texel(0.f);
for (size_t i = 0; i < id->getNumChannels(); ++i) {
texel[i] = localRep->getElementNormalized(lookupTexel, i);
}
emit s_colorChanged(texel);
}
}
}
......@@ -386,7 +397,6 @@ namespace campvis {
for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
imgGL->downloadTexture();
_textures.push_back(it->second);
maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
}
......@@ -395,14 +405,12 @@ namespace campvis {
for (size_t i = 0; i < rd->getNumColorTextures(); ++i) {
const ImageRepresentationGL* imgGL = rd->getColorTexture(i)->getRepresentation<ImageRepresentationGL>();
if (imgGL) {
imgGL->downloadTexture();
_textures.push_back(rd->getColorDataHandle(i));
}
}
if (rd->hasDepthTexture()) {
const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
if (imgGL) {
imgGL->downloadTexture();
_textures.push_back(rd->getDepthDataHandle());
}
......@@ -454,8 +462,6 @@ namespace campvis {
if (rd != nullptr && rd->getNumColorTextures() > 0) {
auto rep = rd->getColorTexture(0)->getRepresentation<ImageRepresentationGL>();
if (rep != nullptr) {
const_cast<cgt::Texture*>(rep->getTexture())->downloadTexture();
if (textureIndex < 0 || textureIndex >= static_cast<int>(_textures.size())) {
_textures.push_back(rd->getColorDataHandle(0));
}
......
......@@ -497,14 +497,9 @@ namespace campvis {
// extract the data
WeaklyTypedPointer wtp(WeaklyTypedPointer::UINT8, 1, 0);
const ImageRepresentationGL* repGL = id->getRepresentation<ImageRepresentationGL>(false);
if (repGL != 0) // if it's a GL texture, download it (we do not want to use the automatic conversion method here)
wtp = repGL->getWeaklyTypedPointer();
else {
const ImageRepresentationLocal* repLocal = id->getRepresentation<ImageRepresentationLocal>(true);
if (repLocal != 0)
wtp = repLocal->getWeaklyTypedPointer();
}
const ImageRepresentationLocal* repLocal = id->getRepresentation<ImageRepresentationLocal>(true);
if (repLocal != 0)
wtp = repLocal->getWeaklyTypedPointer();
if (wtp._pointer == 0) {
LERROR("Could not extract image to save.");
......
......@@ -31,6 +31,7 @@
#include "application/gui/qtdatahandle.h"
#include "core/datastructures/datacontainer.h"
#include "core/datastructures/abstractdata.h"
#include "core/datastructures/dataseries.h"
#include "core/datastructures/lightsourcedata.h"
#include "core/datastructures/facegeometry.h"
#include "core/datastructures/meshgeometry.h"
......@@ -130,6 +131,9 @@ namespace campvis {
return QVariant(QString("Render Data"));
}
else if (const DataSeries* tester = dynamic_cast<const DataSeries*>(data)) {
return QVariant(QString("Data Series"));
}
else if (const ImageSeries* tester = dynamic_cast<const ImageSeries*>(data)) {
return QVariant(QString("Image Series"));
}
......@@ -168,6 +172,11 @@ namespace campvis {
new DataHandleTreeItem(QtDataHandle(tester->getDepthDataHandle()), _name + "::DepthTexture", this);
}
}
else if (const DataSeries* tester = dynamic_cast<const DataSeries*>(data)) {
for (size_t i = 0; i < tester->getNumDatas(); ++i) {
new DataHandleTreeItem(QtDataHandle(tester->getData(i)), _name + "::Data" + StringUtils::toString(i), this);
}
}
else if (const ImageSeries* tester = dynamic_cast<const ImageSeries*>(data)) {
for (size_t i = 0; i < tester->getNumImages(); ++i) {
new DataHandleTreeItem(QtDataHandle(tester->getImage(i)), _name + "::Image" + StringUtils::toString(i), this);
......
......@@ -10,6 +10,7 @@
%{
#include "core/datastructures/abstractdata.h"
#include "core/datastructures/dataseries.h"
#include "core/datastructures/imagedata.h"
#include "core/properties/allproperties.h"
#include "core/pipeline/abstractprocessor.h"
......@@ -251,8 +252,40 @@ namespace campvis {
AbstractData();
virtual ~AbstractData();
virtual size_t getLocalMemoryFootprint() const = 0;
virtual size_t getVideoMemoryFootprint() const = 0;
virtual AbstractData* clone() const = 0;
};
/* DataHandle */
class DataHandle {
public:
explicit DataHandle(AbstractData* data = 0);
DataHandle(const DataHandle& rhs);
DataHandle& operator=(const DataHandle& rhs);
virtual ~DataHandle();
const AbstractData* getData() const;
};
/* DataSeries */
class DataSeries : public AbstractData {
public:
DataSeries();
virtual ~DataSeries();
virtual DataSeries* clone() const;
void addData(AbstractData* data);
void addData(DataHandle dh);
size_t getNumDatas() const;
DataHandle getData(size_t index) const;
protected:
std::vector<DataHandle> _data; ///< the images of this series
};
/* ImageData */
......@@ -268,18 +301,6 @@ namespace campvis {
/* Downcast the return value of DataHandle::getData to appropriate subclass */
%factory(AbstractData* campvis::DataHandle::getData, campvis::ImageData);
/* DataHandle */
class DataHandle {
public:
explicit DataHandle(AbstractData* data = 0);
DataHandle(const DataHandle& rhs);
DataHandle& operator=(const DataHandle& rhs);
virtual ~DataHandle();
const AbstractData* getData() const;
};
/* DataContainer */
class DataContainer {
......
......@@ -227,9 +227,21 @@ namespace campvis {
// create texture
GLenum dataType = GL_UNSIGNED_BYTE;
_texture = new cgt::Texture(_size, GL_RGBA, dataType, cgt::Texture::LINEAR);
GLenum type = GL_TEXTURE_1D;
switch (getDimensionality()) {
case 1:
type = GL_TEXTURE_1D;
break;
case 2:
type = GL_TEXTURE_2D;
break;
default:
cgtAssert(false, "This TF dimensionality is currently not supported - you have to implement it yourself!");
break;
}
_texture = new cgt::Texture(type, _size, GL_RGBA8, cgt::Texture::LINEAR);
_texture->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
_texture->uploadTexture();
LGL_ERROR;
// attach texture to FBO
......
......@@ -60,19 +60,20 @@ namespace campvis {
delete _texture;
GLenum dataType = GL_UNSIGNED_BYTE;
_texture = new cgt::Texture(_size, GL_RGBA, dataType, cgt::Texture::LINEAR);
_texture = new cgt::Texture(GL_TEXTURE_1D, _size, GL_RGBA8, cgt::Texture::LINEAR);
_texture->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
cgt::col4* texels = new cgt::col4[_size.x];
cgt::col4 diff = _rightColor - _leftColor;
for (size_t i = 0; i < _size.x; ++i) {
float multiplier = static_cast<float>(i) / (_size.x - 1);
cgt::col4& texel = _texture->texel<cgt::col4>(i);
cgt::col4& texel = texels[i];
for (size_t j = 0; j < 4; ++j) {
texel[j] = static_cast<uint8_t>(_leftColor[j] + (static_cast<float>(diff[j]) * multiplier));
}
}
_texture->uploadTexture();
_texture->uploadTexture(reinterpret_cast<GLubyte*>(texels), GL_RGBA, GL_UNSIGNED_BYTE);
_dirtyTexture = false;
}
......
// ================================================================================================
//
// 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 "dataseries.h"
#include "cgt/assert.h"
namespace campvis {
DataSeries::DataSeries()
: AbstractData()
{
}
DataSeries::~DataSeries() {
}
DataSeries* DataSeries::clone() const {
DataSeries* toReturn = new DataSeries();
for (size_t i = 0; i < _data.size(); ++i)
toReturn->_data.push_back(_data[i]);
return toReturn;
}
size_t DataSeries::getLocalMemoryFootprint() const {
size_t toReturn = sizeof(DataHandle) * _data.capacity();
for (size_t i = 0; i < _data.size(); ++i)
toReturn += _data[i].getData()->getLocalMemoryFootprint();
return toReturn;
}
size_t DataSeries::getVideoMemoryFootprint() const {
size_t toReturn = 0;
for (size_t i = 0; i < _data.size(); ++i)
toReturn += _data[i].getData()->getVideoMemoryFootprint();
return toReturn;
}
void DataSeries::addData(AbstractData* image) {
_data.push_back(DataHandle(image));
}
void DataSeries::addData(DataHandle dh) {
cgtAssert(dh.getData() != nullptr, "DataHandle must contain data!");
_data.push_back(dh);
}
size_t DataSeries::getNumDatas() const {
return _data.size();
}
DataHandle DataSeries::getData(size_t index) const {
cgtAssert(index < _data.size(), "Index out of bounds.");
return _data[index];
}
}
\ No newline at end of file
// ================================================================================================
//
// 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 DATASERIES_H__
#define DATASERIES_H__
#include "core/datastructures/abstractdata.h"
#include "core/datastructures/datahandle.h"
#include <vector>
namespace campvis {
/**
* Class encapsulating a series of AbstractData objects.
*/
class CAMPVIS_CORE_API DataSeries : public AbstractData {
public:
/**
* Constructor
*/
DataSeries();
/**
* Virtual destructor
*/
virtual ~DataSeries();
/**
* Prototype - clone method, some people call this virtual constructor...
* \return A copy of this object.
*/
virtual DataSeries* clone() const;
/**
* Returns the local memory footprint of the data in bytes.
* \return Number of bytes occupied in local memory by the data.
*/
virtual size_t getLocalMemoryFootprint() const;
/**
* Returns the video memory footprint of the data in bytes.
* \return Number of bytes occupied in video memory by the data.
*/
virtual size_t getVideoMemoryFootprint() const;
/**
* Appends the AbstractData instance \a data to the series.
* \param AbstractData Data to be added.
*/
void addData(AbstractData* data);
/**
* Appends the DataHandle \a dh to the series.
* \note The DataHandle must contain valid data.
* \param dh DataHandle with data to be added.
*/
void addData(DataHandle dh);
/**
* Returns the number of AbstractData instances in this series.
* \return _data.size()
*/
size_t getNumDatas() const;
/**
* Returns a DataHandle with the AbstractData instance number \a index of this series.
* \param index Index of the data to return
* \return _data[index]
*/
DataHandle getData(size_t index) const;
protected:
std::vector<DataHandle> _data; ///< the images of this series
};
}
#endif // DATASERIES_H__
\ No newline at end of file
......@@ -36,8 +36,6 @@ namespace campvis {
, _mappingInformation(size, cgt::vec3(0.f), cgt::vec3(1.f)) // TODO: get offset/voxel size as parameter or put default values into ImageMappingInformation ctor.
{
cgtAssert(numChannels > 0, "Number of channels must be greater than 0!");
cgtAssert(_dimensionality >= 3 || _size.z == 1, "Dimensionality and size mismatch: A 2D image must have size.z = 1!");
cgtAssert(_dimensionality >= 2 || _size.y == 1, "Dimensionality and size mismatch: A 1D image must have size.y = 1!");
}
ImageData::~ImageData() {
......
......@@ -98,7 +98,7 @@ namespace campvis {
// converting from GL representation
cgt::OpenGLJobProcessor::ScopedSynchronousGlJobExecution jobGuard;
if (tester->getTexture()->getDataType() != TypeTraits<BASETYPE, NUMCHANNELS>::glDataType)
if (cgt::Texture::calcMatchingDataType(tester->getTexture()->getInternalFormat()) != TypeTraits<BASETYPE, NUMCHANNELS>::glDataType)
LDEBUGC("CAMPVis.core.datastructures.GenericLocalConversion", "Performing conversion between data types, you may lose information or the resulting data may show other unexpected features.");
WeaklyTypedPointer wtp = tester->getWeaklyTypedPointerConvert(TypeTraits<BASETYPE, NUMCHANNELS>::glDataType);
......
......@@ -52,8 +52,6 @@ namespace campvis {
, _texture(texture)
{
cgtAssert(texture != 0, "Given texture must not be 0.");
cgtAssert(parent->getDimensionality() >= 3 || texture->getDimensions().z == 1, "Dimensionality of Parent and texture mismatch!");
cgtAssert(parent->getDimensionality() >= 2 || texture->getDimensions().y == 1, "Dimensionality of Parent and texture mismatch!");
cgtAssert(parent->getNumChannels() == texture->getNumChannels(), "Number of Channels of parent and texture mismatch!");
}
......@@ -69,46 +67,40 @@ namespace campvis {
}
ImageRepresentationGL* ImageRepresentationGL::clone(ImageData* newParent) const {
GLubyte* data = _texture->downloadTextureToBuffer();
WeaklyTypedPointer wtp(WeaklyTypedPointer::baseType(_texture->getDataType()), WeaklyTypedPointer::numChannels(_texture->getFormat()), data);
WeaklyTypedPointer wtp = getWeaklyTypedPointerCopy();
ImageRepresentationGL* toReturn = ImageRepresentationGL::create(newParent, wtp);
delete data;
delete static_cast<GLubyte*>(wtp._pointer);
return toReturn;
}
void ImageRepresentationGL::createTexture(const WeaklyTypedPointer& wtp) {
cgtAssert(wtp._pointer != 0, "Pointer to image data must not be 0!");
_texture = new cgt::Texture(reinterpret_cast<GLubyte*>(wtp._pointer), getSize(), wtp.getGlFormat(), wtp.getGlInternalFormat(), wtp.getGlDataType(), cgt::Texture::LINEAR);
setupAndUploadTexture(_texture, wtp.isInteger(), wtp.isSigned());
}
void ImageRepresentationGL::setupAndUploadTexture(cgt::Texture* texture, bool isInteger, bool isSigned) {
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
switch (getDimensionality()) {
GLenum type = GL_TEXTURE_1D;
switch (_parent->getDimensionality()) {
case 1:
_texture->setType(GL_TEXTURE_1D);
type = GL_TEXTURE_1D;
break;
case 2:
_texture->setType(GL_TEXTURE_2D);
type = GL_TEXTURE_2D;
break;
case 3:
_texture->setType(GL_TEXTURE_3D);
type = GL_TEXTURE_3D;
break;
default:
cgtAssert(false, "Unsupported dimensionality of image.");
cgtAssert(false, "This dimensionality is not supported!");
break;
}
_texture = new cgt::Texture(type, getSize(), wtp.getGlInternalFormat(), cgt::Texture::LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
cgt::TextureUnit tempUnit;
tempUnit.activate();
_texture->bind();
// map signed integer types from [-1.0:1.0] to [0.0:1.0] in order to avoid clamping of negative values
if (isInteger && isSigned) {
if (wtp.isInteger() && wtp.isSigned()) {
glPixelTransferf(GL_RED_SCALE, 0.5f);
glPixelTransferf(GL_GREEN_SCALE, 0.5f);
glPixelTransferf(GL_BLUE_SCALE, 0.5f);
......@@ -122,10 +114,10 @@ namespace campvis {
//_mappingInformation.setRealWorldMapping(LinearMapping<float>(.5f, .5f));
}
_texture->uploadTexture();
_texture->uploadTexture(reinterpret_cast<GLubyte*>(wtp._pointer), wtp.getGlFormat(), wtp.getGlDataType());
_texture->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
if (isInteger && isSigned) {
if (wtp.isInteger() && wtp.isSigned()) {
// restore default
glPixelTransferf(GL_RED_SCALE, 1.0f);
glPixelTransferf(GL_GREEN_SCALE, 1.0f);
......@@ -138,9 +130,6 @@ namespace campvis {
glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
}
// revoke ownership of local pixel data from the texture
_texture->setPixelData(0);
cgt::TextureUnit::setZeroUnit();
LGL_ERROR;
}
......@@ -191,12 +180,7 @@ namespace campvis {
LGL_ERROR;
}
void ImageRepresentationGL::downloadTexture() const {
_texture->downloadTexture();
}
const cgt::Texture* ImageRepresentationGL::getTexture() const {
return _texture;
}
......@@ -204,9 +188,6 @@ namespace campvis {
size_t sum = 0;
if (_texture != 0) {
sum += sizeof(cgt::Texture);
if (_texture->getPixelData() != 0) {
sum += _texture->getBpp() + _texture->getArraySize();
}
}
return sizeof(*this) + sum;
......@@ -216,25 +197,23 @@ namespace campvis {
return _texture->getSizeOnGPU();
}
const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointer() const {
if (_texture->getPixelData() == 0) {
_texture->downloadTexture();
}
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(_texture->getDataType()), _texture->getNumChannels(), _texture->getPixelData());
}
void ImageRepresentationGL::unbind() const {