# HG changeset patch # User Sebastien Jodogne # Date 1556271237 -7200 # Node ID 5430bcffba573a4dc681a723c3364147fd77686c # Parent 3080ec4ec6b9e5a53370f2917b3eb038eb597634 FloatTextureSceneLayer diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/ColorTextureSceneLayer.cpp --- a/Framework/Scene2D/ColorTextureSceneLayer.cpp Thu Apr 25 14:00:55 2019 +0200 +++ b/Framework/Scene2D/ColorTextureSceneLayer.cpp Fri Apr 26 11:33:57 2019 +0200 @@ -21,87 +21,29 @@ #include "ColorTextureSceneLayer.h" +#include #include -#include + namespace OrthancStone { - ColorTextureSceneLayer::ColorTextureSceneLayer(const Orthanc::ImageAccessor& texture, - double originX, // Center of the top-left pixel - double originY, - double pixelSpacingX, - double pixelSpacingY, - double angle, - bool isLinearInterpolation) : - texture_(Orthanc::Image::Clone(texture)), - originX_(originX), - originY_(originY), - pixelSpacingX_(pixelSpacingX), - pixelSpacingY_(pixelSpacingY), - angle_(angle), - isLinearInterpolation_(isLinearInterpolation) + ColorTextureSceneLayer::ColorTextureSceneLayer(const Orthanc::ImageAccessor& texture) { - if (texture_->GetFormat() != Orthanc::PixelFormat_Grayscale8 && - texture_->GetFormat() != Orthanc::PixelFormat_RGBA32 && - texture_->GetFormat() != Orthanc::PixelFormat_RGB24) + if (texture.GetFormat() != Orthanc::PixelFormat_Grayscale8 && + texture.GetFormat() != Orthanc::PixelFormat_RGBA32 && + texture.GetFormat() != Orthanc::PixelFormat_RGB24) { throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); } - - if (pixelSpacingX_ <= 0 || - pixelSpacingY_ <= 0) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } + + SetTexture(Orthanc::Image::Clone(texture)); } ISceneLayer* ColorTextureSceneLayer::Clone() const { - return new ColorTextureSceneLayer(*texture_, originX_, originY_, - pixelSpacingX_, pixelSpacingY_, angle_, - isLinearInterpolation_); - } - - - AffineTransform2D ColorTextureSceneLayer::GetTransform() const - { - return AffineTransform2D::Combine( - AffineTransform2D::CreateOffset(originX_, originY_), - AffineTransform2D::CreateRotation(angle_), - AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_), - AffineTransform2D::CreateOffset(-0.5, -0.5)); - } - - - bool ColorTextureSceneLayer::GetBoundingBox(Extent2D& target) const - { - const AffineTransform2D t = GetTransform(); - - target.Reset(); - - double x, y; - - x = 0; - y = 0; - t.Apply(x, y); - target.AddPoint(x, y); - - x = static_cast(texture_->GetWidth()); - y = 0; - t.Apply(x, y); - target.AddPoint(x, y); - - x = 0; - y = static_cast(texture_->GetHeight()); - t.Apply(x, y); - target.AddPoint(x, y); - - x = static_cast(texture_->GetWidth()); - y = static_cast(texture_->GetHeight()); - t.Apply(x, y); - target.AddPoint(x, y); - - return true; + std::auto_ptr cloned(new ColorTextureSceneLayer(GetTexture())); + cloned->CopyParameters(*this); + return cloned.release(); } } diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/ColorTextureSceneLayer.h --- a/Framework/Scene2D/ColorTextureSceneLayer.h Thu Apr 25 14:00:55 2019 +0200 +++ b/Framework/Scene2D/ColorTextureSceneLayer.h Fri Apr 26 11:33:57 2019 +0200 @@ -21,58 +21,20 @@ #pragma once -#include "ISceneLayer.h" -#include "../Toolbox/AffineTransform2D.h" - -#include -#include +#include "TextureBaseSceneLayer.h" namespace OrthancStone { - class ColorTextureSceneLayer : public ISceneLayer + class ColorTextureSceneLayer : public TextureBaseSceneLayer { - private: - std::auto_ptr texture_; - double originX_; - double originY_; - double pixelSpacingX_; - double pixelSpacingY_; - double angle_; - bool isLinearInterpolation_; - public: - ColorTextureSceneLayer(const Orthanc::ImageAccessor& texture, - double originX, // Center of the top-left pixel - double originY, - double pixelSpacingX, - double pixelSpacingY, - double angle, - bool isLinearInterpolation); + ColorTextureSceneLayer(const Orthanc::ImageAccessor& texture); virtual ISceneLayer* Clone() const; - const Orthanc::ImageAccessor& GetTexture() const - { - return *texture_; - } - - AffineTransform2D GetTransform() const; - - bool IsLinearInterpolation() const - { - return isLinearInterpolation_; - } - virtual Type GetType() const { return Type_ColorTexture; } - - virtual bool GetBoundingBox(Extent2D& target) const; - - virtual uint64_t GetRevision() const - { - return 0; - } }; } diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/FloatTextureSceneLayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/FloatTextureSceneLayer.cpp Fri Apr 26 11:33:57 2019 +0200 @@ -0,0 +1,122 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "FloatTextureSceneLayer.h" + +#include +#include +#include + +namespace OrthancStone +{ + FloatTextureSceneLayer::FloatTextureSceneLayer(const Orthanc::ImageAccessor& texture) + { + { + std::auto_ptr t( + new Orthanc::Image(Orthanc::PixelFormat_Float32, + texture.GetWidth(), + texture.GetHeight(), + false)); + + Orthanc::ImageProcessing::Convert(*t, texture); + SetTexture(t.release()); + } + + SetCustomWindowing(128, 256); + } + + + void FloatTextureSceneLayer::SetWindowing(ImageWindowing windowing) + { + if (windowing_ != windowing) + { + if (windowing == ImageWindowing_Custom) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + windowing_ = windowing; + IncrementRevision(); + } + } + } + + + void FloatTextureSceneLayer::SetCustomWindowing(float customCenter, + float customWidth) + { + if (customWidth <= 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + windowing_ = ImageWindowing_Custom; + customCenter_ = customCenter; + customWidth_ = customWidth; + IncrementRevision(); + } + } + + + void FloatTextureSceneLayer::GetWindowing(float& targetCenter, + float& targetWidth) const + { + ::OrthancStone::ComputeWindowing(targetCenter, targetWidth, + windowing_, customCenter_, customWidth_); + } + + + void FloatTextureSceneLayer::FitRange() + { + float minValue, maxValue; + Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue, maxValue, GetTexture()); + + float width; + + assert(minValue <= maxValue); + if (LinearAlgebra::IsCloseToZero(maxValue - minValue)) + { + width = 1; + } + else + { + width = maxValue - minValue; + } + + SetCustomWindowing((minValue + maxValue) / 2.0f, width); + } + + + ISceneLayer* FloatTextureSceneLayer::Clone() const + { + std::auto_ptr cloned + (new FloatTextureSceneLayer(GetTexture())); + + cloned->CopyParameters(*this); + cloned->windowing_ = windowing_; + cloned->customCenter_ = customCenter_; + cloned->customWidth_ = customWidth_; + + return cloned.release(); + } +} diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/FloatTextureSceneLayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/FloatTextureSceneLayer.h Fri Apr 26 11:33:57 2019 +0200 @@ -0,0 +1,60 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "TextureBaseSceneLayer.h" + +namespace OrthancStone +{ + class FloatTextureSceneLayer : public TextureBaseSceneLayer + { + private: + ImageWindowing windowing_; + float customCenter_; + float customWidth_; + + public: + FloatTextureSceneLayer(const Orthanc::ImageAccessor& texture); + + void SetWindowing(ImageWindowing windowing); + + void SetCustomWindowing(float customCenter, + float customWidth); + + void GetWindowing(float& targetCenter, + float& targetWidth) const; + + ImageWindowing GetWindowingType() const + { + return windowing_; + } + + void FitRange(); + + virtual ISceneLayer* Clone() const; + + virtual Type GetType() const + { + return Type_FloatTexture; + } + }; +} diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/ISceneLayer.h --- a/Framework/Scene2D/ISceneLayer.h Thu Apr 25 14:00:55 2019 +0200 +++ b/Framework/Scene2D/ISceneLayer.h Fri Apr 26 11:33:57 2019 +0200 @@ -36,7 +36,8 @@ Type_InfoPanel, Type_ColorTexture, Type_Polyline, - Type_Text + Type_Text, + Type_FloatTexture }; virtual ~ISceneLayer() diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/Internals/ColorTextureOpenGLProgram.cpp --- a/Framework/Scene2D/Internals/ColorTextureOpenGLProgram.cpp Thu Apr 25 14:00:55 2019 +0200 +++ b/Framework/Scene2D/Internals/ColorTextureOpenGLProgram.cpp Fri Apr 26 11:33:57 2019 +0200 @@ -110,7 +110,8 @@ if (useAlpha) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDrawArrays(GL_TRIANGLES, 0, COUNT); glDisable(GL_BLEND); } diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/TextureBaseSceneLayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/TextureBaseSceneLayer.cpp Fri Apr 26 11:33:57 2019 +0200 @@ -0,0 +1,170 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "TextureBaseSceneLayer.h" + +#include + +namespace OrthancStone +{ + void TextureBaseSceneLayer::SetTexture(Orthanc::ImageAccessor* texture) + { + if (texture == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + else + { + texture_.reset(texture); + IncrementRevision(); + } + } + + + void TextureBaseSceneLayer::CopyParameters(const TextureBaseSceneLayer& other) + { + originX_ = other.originX_; + originY_ = other.originY_; + pixelSpacingX_ = other.pixelSpacingX_; + pixelSpacingY_ = other.pixelSpacingY_; + angle_ = other.angle_; + isLinearInterpolation_ = other.isLinearInterpolation_; + } + + + TextureBaseSceneLayer::TextureBaseSceneLayer() : + originX_(0), + originY_(0), + pixelSpacingX_(1), + pixelSpacingY_(1), + angle_(0), + isLinearInterpolation_(false), + revision_(0) + { + if (pixelSpacingX_ <= 0 || + pixelSpacingY_ <= 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + void TextureBaseSceneLayer::SetOrigin(double x, + double y) + { + originX_ = x; + originY_ = y; + IncrementRevision(); + } + + + void TextureBaseSceneLayer::SetPixelSpacing(double sx, + double sy) + { + if (sx <= 0 || + sy <= 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + pixelSpacingX_ = sx; + pixelSpacingY_ = sy; + IncrementRevision(); + } + } + + + void TextureBaseSceneLayer::SetAngle(double angle) + { + angle_ = angle; + IncrementRevision(); + } + + + void TextureBaseSceneLayer::SetLinearInterpolation(bool isLinearInterpolation) + { + isLinearInterpolation_ = isLinearInterpolation; + IncrementRevision(); + } + + + const Orthanc::ImageAccessor& TextureBaseSceneLayer::GetTexture() const + { + if (!HasTexture()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return *texture_; + } + } + + + AffineTransform2D TextureBaseSceneLayer::GetTransform() const + { + return AffineTransform2D::Combine( + AffineTransform2D::CreateOffset(originX_, originY_), + AffineTransform2D::CreateRotation(angle_), + AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_), + AffineTransform2D::CreateOffset(-0.5, -0.5)); + } + + + bool TextureBaseSceneLayer::GetBoundingBox(Extent2D& target) const + { + if (texture_.get() == NULL) + { + return false; + } + else + { + const AffineTransform2D t = GetTransform(); + + target.Reset(); + + double x, y; + + x = 0; + y = 0; + t.Apply(x, y); + target.AddPoint(x, y); + + x = static_cast(texture_->GetWidth()); + y = 0; + t.Apply(x, y); + target.AddPoint(x, y); + + x = 0; + y = static_cast(texture_->GetHeight()); + t.Apply(x, y); + target.AddPoint(x, y); + + x = static_cast(texture_->GetWidth()); + y = static_cast(texture_->GetHeight()); + t.Apply(x, y); + target.AddPoint(x, y); + + return true; + } + } +} diff -r 3080ec4ec6b9 -r 5430bcffba57 Framework/Scene2D/TextureBaseSceneLayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/TextureBaseSceneLayer.h Fri Apr 26 11:33:57 2019 +0200 @@ -0,0 +1,114 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "ISceneLayer.h" +#include "../Toolbox/AffineTransform2D.h" + +#include + +namespace OrthancStone +{ + class TextureBaseSceneLayer : public ISceneLayer + { + private: + std::auto_ptr texture_; + double originX_; + double originY_; + double pixelSpacingX_; + double pixelSpacingY_; + double angle_; + bool isLinearInterpolation_; + uint64_t revision_; + + protected: + void SetTexture(Orthanc::ImageAccessor* texture); + + void IncrementRevision() + { + revision_++; + } + + void CopyParameters(const TextureBaseSceneLayer& other); + + public: + TextureBaseSceneLayer(); + + // Center of the top-left pixel + void SetOrigin(double x, + double y); + + void SetPixelSpacing(double sx, + double sy); + + // In radians + void SetAngle(double angle); + + void SetLinearInterpolation(bool isLinearInterpolation); + + double GetOriginX() const + { + return originX_; + } + + double GetOriginY() const + { + return originY_; + } + + double GetPixelSpacingX() const + { + return pixelSpacingX_; + } + + double GetPixelSpacingY() const + { + return pixelSpacingY_; + } + + double GetAngle() const + { + return angle_; + } + + bool IsLinearInterpolation() const + { + return isLinearInterpolation_; + } + + bool HasTexture() const + { + return (texture_.get() != NULL); + } + + const Orthanc::ImageAccessor& GetTexture() const; + + AffineTransform2D GetTransform() const; + + virtual bool GetBoundingBox(Extent2D& target) const; + + virtual uint64_t GetRevision() const + { + return revision_; + } + }; +} diff -r 3080ec4ec6b9 -r 5430bcffba57 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Thu Apr 25 14:00:55 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 26 11:33:57 2019 +0200 @@ -256,6 +256,15 @@ #${ORTHANC_STONE_ROOT}/Framework/Layers/SeriesFrameRendererFactory.cpp #${ORTHANC_STONE_ROOT}/Framework/Layers/SingleFrameRendererFactory.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ColorTextureSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/CompositorHelper.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/FloatTextureSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/InfoPanelSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/PolylineSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Scene2D.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/TextSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/TextureBaseSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Fonts/FontRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Fonts/Glyph.cpp ${ORTHANC_STONE_ROOT}/Framework/Fonts/GlyphAlphabet.cpp @@ -289,12 +298,6 @@ ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyTextLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyWidget.cpp ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyWindowingTracker.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/CompositorHelper.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/InfoPanelSceneLayer.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/PolylineSceneLayer.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Scene2D.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/TextSceneLayer.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ColorTextureSceneLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/SmartLoader.cpp ${ORTHANC_STONE_ROOT}/Framework/StoneEnumerations.cpp ${ORTHANC_STONE_ROOT}/Framework/StoneException.h