Mercurial > hg > orthanc-stone
changeset 804:61ba4b504e9a
PolylineSceneLayer now has one color per chain
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Color.h Tue May 28 15:58:21 2019 +0200 @@ -0,0 +1,82 @@ +/** + * 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 <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <stdint.h> + +namespace OrthancStone +{ + class Color + { + private: + uint8_t red_; + uint8_t green_; + uint8_t blue_; + + public: + Color() : + red_(255), + green_(255), + blue_(255) + { + } + + Color(uint8_t red, + uint8_t green, + uint8_t blue) : + red_(red), + green_(green), + blue_(blue) + { + } + + uint8_t GetRed() const + { + return red_; + } + + uint8_t GetGreen() const + { + return green_; + } + + uint8_t GetBlue() const + { + return blue_; + } + + float GetRedAsFloat() const + { + return static_cast<float>(red_) / 255.0f; + } + + float GetGreenAsFloat() const + { + return static_cast<float>(green_) / 255.0f; + } + + float GetBlueAsFloat() const + { + return static_cast<float>(blue_) / 255.0f; + } + }; +}
--- a/Framework/Scene2D/ColorSceneLayer.h Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/ColorSceneLayer.h Tue May 28 15:58:21 2019 +0200 @@ -22,18 +22,17 @@ #pragma once #include "ISceneLayer.h" -#include <Core/Enumerations.h> +#include "Color.h" -#include <stdint.h> +#include <Core/Enumerations.h> // For ORTHANC_OVERRIDE namespace OrthancStone { + // TODO - Is this needed? class ColorSceneLayer : public ISceneLayer { private: - uint8_t red_; - uint8_t green_; - uint8_t blue_; + Color color_; uint64_t revision_; protected: @@ -45,9 +44,6 @@ public: ColorSceneLayer() : - red_(255), - green_(255), - blue_(255), revision_(0) { } @@ -61,40 +57,19 @@ uint8_t green, uint8_t blue) { - red_ = red; - green_ = green; - blue_ = blue; + color_ = Color(red, green, blue); BumpRevision(); } - uint8_t GetRed() const + void SetColor(const Color& color) { - return red_; - } - - uint8_t GetGreen() const - { - return green_; + color_ = color; + BumpRevision(); } - uint8_t GetBlue() const - { - return blue_; - } - - float GetRedAsFloat() const + const Color& GetColor() const { - return static_cast<float>(red_) / 255.0f; - } - - float GetGreenAsFloat() const - { - return static_cast<float>(green_) / 255.0f; - } - - float GetBlueAsFloat() const - { - return static_cast<float>(blue_) / 255.0f; + return color_; } }; }
--- a/Framework/Scene2D/Internals/CairoPolylineRenderer.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoPolylineRenderer.cpp Tue May 28 15:58:21 2019 +0200 @@ -33,11 +33,15 @@ cairo_t* cr = GetCairoContext(); - cairo_set_source_rgb(cr, layer.GetRedAsFloat(), layer.GetGreenAsFloat(), layer.GetBlueAsFloat()); cairo_set_line_width(cr, layer.GetThickness()); for (size_t i = 0; i < layer.GetChainsCount(); i++) { + const Color& color = layer.GetColor(i); + cairo_set_source_rgb(cr, color.GetRedAsFloat(), + color.GetGreenAsFloat(), + color.GetBlueAsFloat()); + const PolylineSceneLayer::Chain& chain = layer.GetChain(i); if (!chain.empty()) @@ -62,9 +66,9 @@ cairo_line_to(cr, p.GetX(), p.GetY()); } } + + cairo_stroke(cr); } - - cairo_stroke(cr); } } }
--- a/Framework/Scene2D/Internals/CairoTextRenderer.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoTextRenderer.cpp Tue May 28 15:58:21 2019 +0200 @@ -48,9 +48,7 @@ } const unsigned int width = source->GetWidth(); - const unsigned int red = layer.GetRed(); - const unsigned int green = layer.GetGreen(); - const unsigned int blue = layer.GetBlue(); + const Color& color = layer.GetColor(); for (unsigned int y = 0; y < source->GetHeight(); y++) { @@ -62,9 +60,9 @@ unsigned int alpha = *p; // Premultiplied alpha - q[0] = static_cast<uint8_t>((blue * alpha) / 255); - q[1] = static_cast<uint8_t>((green * alpha) / 255); - q[2] = static_cast<uint8_t>((red * alpha) / 255); + q[0] = static_cast<uint8_t>((color.GetBlue() * alpha) / 255); + q[1] = static_cast<uint8_t>((color.GetGreen() * alpha) / 255); + q[2] = static_cast<uint8_t>((color.GetRed() * alpha) / 255); q[3] = *p; p++; @@ -85,7 +83,9 @@ const TextSceneLayer& layer = GetLayer<TextSceneLayer>(); cairo_t* cr = GetCairoContext(); - cairo_set_source_rgb(cr, layer.GetRedAsFloat(), layer.GetGreenAsFloat(), layer.GetBlueAsFloat()); + cairo_set_source_rgb(cr, layer.GetColor().GetRedAsFloat(), + layer.GetColor().GetGreenAsFloat(), + layer.GetColor().GetBlueAsFloat()); double dx, dy; // In pixels ComputeAnchorTranslation(dx, dy, layer.GetAnchor(), text_.GetWidth(),
--- a/Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.cpp Tue May 28 15:58:21 2019 +0200 @@ -28,7 +28,7 @@ namespace Internals { OpenGLBasicPolylineRenderer::OpenGLBasicPolylineRenderer(OpenGL::IOpenGLContext& context, - const PolylineSceneLayer& layer) : + const PolylineSceneLayer& layer) : context_(context) { layer_.Copy(layer); @@ -42,12 +42,14 @@ transform); glUseProgram(0); - glColor3ub(layer_.GetRed(), layer_.GetGreen(), layer_.GetBlue()); glBegin(GL_LINES); for (size_t i = 0; i < layer_.GetChainsCount(); i++) { + const Color& color = layer_.GetColor(i); + glColor3ub(color.GetRed(), color.GetGreen(), color.GetBlue()); + const PolylineSceneLayer::Chain& chain = layer_.GetChain(i); if (chain.size() > 1)
--- a/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp Tue May 28 15:58:21 2019 +0200 @@ -26,6 +26,7 @@ static const unsigned int COMPONENTS_POSITION = 3; +static const unsigned int COMPONENTS_COLOR = 3; static const unsigned int COMPONENTS_MITER = 2; @@ -33,12 +34,15 @@ ORTHANC_STONE_OPENGL_SHADER_VERSION_DIRECTIVE "attribute vec2 a_miter_direction; \n" "attribute vec4 a_position; \n" + "attribute vec3 a_color; \n" "uniform float u_thickness; \n" "uniform mat4 u_matrix; \n" "varying float v_distance; \n" + "varying vec3 v_color; \n" "void main() \n" "{ \n" " v_distance = a_position.z; \n" + " v_color = a_color; \n" " gl_Position = u_matrix * vec4(a_position.xy + a_position.z * a_miter_direction * u_thickness, 0, 1); \n" "}"; @@ -47,20 +51,20 @@ ORTHANC_STONE_OPENGL_SHADER_VERSION_DIRECTIVE "uniform bool u_antialiasing; \n" "uniform float u_antialiasing_start; \n" - "uniform vec3 u_color; \n" "varying float v_distance; \n" // Distance of the point to the segment + "varying vec3 v_color; \n" "void main() \n" "{ \n" " float d = abs(v_distance); \n" " if (!u_antialiasing || \n" " d <= u_antialiasing_start) \n" - " gl_FragColor = vec4(u_color, 1); \n" + " gl_FragColor = vec4(v_color, 1); \n" " else if (d >= 1.0) \n" " gl_FragColor = vec4(0, 0, 0, 0); \n" " else \n" " { \n" " float alpha = 1.0 - smoothstep(u_antialiasing_start, 1.0, d); \n" - " gl_FragColor = vec4(u_color * alpha, alpha); \n" + " gl_FragColor = vec4(v_color * alpha, alpha); \n" " } \n" "}"; @@ -197,7 +201,9 @@ } void AddTriangles(std::vector<float>& coords, - std::vector<float>& miterDirections) + std::vector<float>& miterDirections, + std::vector<float>& colors, + const Color& color) { if (isEmpty_) { @@ -239,6 +245,14 @@ miterDirections.push_back(static_cast<float>(miterY1_)); miterDirections.push_back(static_cast<float>(miterX2_)); miterDirections.push_back(static_cast<float>(miterY2_)); + + // Add the colors of the 2 triangles (leading to 2 * 3 values) + for (unsigned int i = 0; i < 6; i++) + { + colors.push_back(color.GetRedAsFloat()); + colors.push_back(color.GetGreenAsFloat()); + colors.push_back(color.GetBlueAsFloat()); + } } }; @@ -247,10 +261,7 @@ const PolylineSceneLayer& layer) : context_(context), verticesCount_(0), - thickness_(static_cast<float>(layer.GetThickness())), - red_(layer.GetRedAsFloat()), - green_(layer.GetGreenAsFloat()), - blue_(layer.GetBlueAsFloat()) + thickness_(static_cast<float>(layer.GetThickness())) { // High-level reference: // https://mattdesl.svbtle.com/drawing-lines-is-hard @@ -271,8 +282,9 @@ countVertices += countSegments * 2 * 3; } - std::vector<float> coords, miterDirections; + std::vector<float> coords, colors, miterDirections; coords.reserve(countVertices * COMPONENTS_POSITION); + colors.reserve(countVertices * COMPONENTS_COLOR); miterDirections.reserve(countVertices * COMPONENTS_MITER); for (size_t i = 0; i < layer.GetChainsCount(); i++) @@ -307,24 +319,29 @@ { if (!segments[j].IsEmpty()) { - segments[j].AddTriangles(coords, miterDirections); + segments[j].AddTriangles(coords, miterDirections, colors, layer.GetColor(i)); } } } } + assert(coords.size() == colors.size()); + if (!coords.empty()) { verticesCount_ = coords.size() / COMPONENTS_POSITION; context_.MakeCurrent(); - glGenBuffers(2, buffers_); + glGenBuffers(3, buffers_); glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coords.size(), &coords[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * miterDirections.size(), &miterDirections[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, buffers_[2]); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colors.size(), &colors[0], GL_STATIC_DRAW); } } @@ -334,7 +351,7 @@ if (!IsEmpty()) { context_.MakeCurrent(); - glDeleteBuffers(2, buffers_); + glDeleteBuffers(3, buffers_); } } @@ -365,10 +382,22 @@ } + GLuint OpenGLLinesProgram::Data::GetColorsBuffer() const + { + if (IsEmpty()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return buffers_[2]; + } + } + + OpenGLLinesProgram::OpenGLLinesProgram(OpenGL::IOpenGLContext& context) : context_(context) { - context_.MakeCurrent(); program_.reset(new OpenGL::OpenGLProgram); @@ -388,13 +417,12 @@ GLint locationPosition = program_->GetAttributeLocation("a_position"); GLint locationMiterDirection = program_->GetAttributeLocation("a_miter_direction"); + GLint locationColor = program_->GetAttributeLocation("a_color"); float m[16]; transform.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); - glUniform3f(program_->GetUniformLocation("u_color"), - data.GetRed(), data.GetGreen(), data.GetBlue()); glBindBuffer(GL_ARRAY_BUFFER, data.GetVerticesBuffer()); glEnableVertexAttribArray(locationPosition); @@ -404,6 +432,10 @@ glEnableVertexAttribArray(locationMiterDirection); glVertexAttribPointer(locationMiterDirection, COMPONENTS_MITER, GL_FLOAT, GL_FALSE, 0, 0); + glBindBuffer(GL_ARRAY_BUFFER, data.GetColorsBuffer()); + glEnableVertexAttribArray(locationColor); + glVertexAttribPointer(locationColor, COMPONENTS_COLOR, GL_FLOAT, GL_FALSE, 0, 0); + glUniform1i(program_->GetUniformLocation("u_antialiasing"), (antialiasing ? 1 : 0)); const double zoom = transform.ComputeZoom(); @@ -464,6 +496,7 @@ glDisableVertexAttribArray(locationPosition); glDisableVertexAttribArray(locationMiterDirection); + glDisableVertexAttribArray(locationColor); } } }
--- a/Framework/Scene2D/Internals/OpenGLLinesProgram.h Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLLinesProgram.h Tue May 28 15:58:21 2019 +0200 @@ -39,12 +39,9 @@ class Segment; OpenGL::IOpenGLContext& context_; - GLuint buffers_[2]; + GLuint buffers_[3]; size_t verticesCount_; float thickness_; - float red_; - float green_; - float blue_; public: Data(OpenGL::IOpenGLContext& context, @@ -66,25 +63,12 @@ GLuint GetMiterDirectionsBuffer() const; + GLuint GetColorsBuffer() const; + float GetThickness() const { return thickness_; } - - float GetRed() const - { - return red_; - } - - float GetGreen() const - { - return green_; - } - - float GetBlue() const - { - return blue_; - } }; private:
--- a/Framework/Scene2D/Internals/OpenGLTextProgram.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLTextProgram.cpp Tue May 28 15:58:21 2019 +0200 @@ -75,9 +75,9 @@ const GlyphTextureAlphabet& alphabet, const TextSceneLayer& layer) : context_(context), - red_(layer.GetRedAsFloat()), - green_(layer.GetGreenAsFloat()), - blue_(layer.GetBlueAsFloat()), + red_(layer.GetColor().GetRedAsFloat()), + green_(layer.GetColor().GetGreenAsFloat()), + blue_(layer.GetColor().GetBlueAsFloat()), x_(layer.GetX()), y_(layer.GetY()), border_(layer.GetBorder()),
--- a/Framework/Scene2D/PolylineSceneLayer.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/PolylineSceneLayer.cpp Tue May 28 15:58:21 2019 +0200 @@ -25,6 +25,14 @@ namespace OrthancStone { + void PolylineSceneLayer::Copy(const PolylineSceneLayer& other) + { + items_ = other.items_; + thickness_ = other.thickness_; + revision_ ++; + } + + ISceneLayer* PolylineSceneLayer::Clone() const { std::auto_ptr<PolylineSceneLayer> cloned(new PolylineSceneLayer); @@ -42,52 +50,40 @@ else { thickness_ = thickness; - BumpRevision(); + revision_++; } } - void PolylineSceneLayer::Copy(const PolylineSceneLayer& from) - { - SetColor(from.GetRed(), from.GetGreen(), from.GetBlue()); - chains_ = from.chains_; - closed_ = from.closed_; - thickness_ = from.thickness_; - BumpRevision(); - } - - - void PolylineSceneLayer::Reserve(size_t countChains) - { - chains_.reserve(countChains); - closed_.reserve(countChains); - } - - void PolylineSceneLayer::AddChain(const Chain& chain, - bool isClosed) + bool isClosed, + uint8_t red, + uint8_t green, + uint8_t blue) { if (!chain.empty()) { - chains_.push_back(chain); - closed_.push_back(isClosed); - BumpRevision(); + items_.push_back(Item()); + items_.back().chain_ = chain; + items_.back().closed_ = isClosed; + items_.back().color_ = Color(red, green, blue); + + revision_++; } } void PolylineSceneLayer::ClearAllChains() { - chains_.clear(); - closed_.clear(); - BumpRevision(); + items_.clear(); + revision_++; } - const PolylineSceneLayer::Chain& PolylineSceneLayer::GetChain(size_t i) const + const PolylineSceneLayer::Item& PolylineSceneLayer::GetItem(size_t i) const { - if (i < chains_.size()) + if (i < items_.size()) { - return chains_[i]; + return items_[i]; } else { @@ -96,28 +92,15 @@ } - bool PolylineSceneLayer::IsClosedChain(size_t i) const - { - if (i < closed_.size()) - { - return closed_[i]; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - } - - bool PolylineSceneLayer::GetBoundingBox(Extent2D& target) const { target.Reset(); - for (size_t i = 0; i < chains_.size(); i++) + for (size_t i = 0; i < items_.size(); i++) { - for (size_t j = 0; j < chains_[i].size(); j++) + for (size_t j = 0; j < items_[i].chain_.size(); j++) { - const ScenePoint2D& p = chains_[i][j]; + const ScenePoint2D& p = items_[i].chain_[j]; target.AddPoint(p.GetX(), p.GetY()); } }
--- a/Framework/Scene2D/PolylineSceneLayer.h Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/PolylineSceneLayer.h Tue May 28 15:58:21 2019 +0200 @@ -21,29 +21,47 @@ #pragma once -#include "ColorSceneLayer.h" +#include "Color.h" #include "ScenePoint2D.h" +#include "ISceneLayer.h" #include <vector> namespace OrthancStone { - class PolylineSceneLayer : public ColorSceneLayer + class PolylineSceneLayer : public ISceneLayer { public: typedef std::vector<ScenePoint2D> Chain; private: - std::vector<Chain> chains_; - std::vector<bool> closed_; - double thickness_; + struct Item + { + Chain chain_; + bool closed_; + Color color_; + }; + + std::vector<Item> items_; + double thickness_; + uint64_t revision_; + + const Item& GetItem(size_t i) const; public: PolylineSceneLayer() : - thickness_(1.0) + thickness_(1.0), + revision_(0) { } + void Copy(const PolylineSceneLayer& other); + + virtual uint64_t GetRevision() const + { + return revision_; + } + virtual ISceneLayer* Clone() const; void SetThickness(double thickness); @@ -53,23 +71,45 @@ return thickness_; } - void Copy(const PolylineSceneLayer& from); - - void Reserve(size_t countChains); + void Reserve(size_t countChains) + { + items_.reserve(countChains); + } void AddChain(const Chain& chain, - bool isClosed); + bool isClosed, + uint8_t red, + uint8_t green, + uint8_t blue); + + void AddChain(const Chain& chain, + bool isClosed, + const Color& color) + { + AddChain(chain, isClosed, color.GetRed(), color.GetGreen(), color.GetBlue()); + } void ClearAllChains(); size_t GetChainsCount() const { - return chains_.size(); + return items_.size(); + } + + const Chain& GetChain(size_t i) const + { + return GetItem(i).chain_; } - const Chain& GetChain(size_t i) const; + bool IsClosedChain(size_t i) const + { + return GetItem(i).closed_; + } - bool IsClosedChain(size_t i) const; + const Color& GetColor(size_t i) const + { + return GetItem(i).color_; + } virtual Type GetType() const {
--- a/Framework/Scene2D/TextSceneLayer.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2D/TextSceneLayer.cpp Tue May 28 15:58:21 2019 +0200 @@ -37,7 +37,7 @@ ISceneLayer* TextSceneLayer::Clone() const { std::auto_ptr<TextSceneLayer> cloned(new TextSceneLayer); - cloned->SetColor(GetRed(), GetGreen(), GetBlue()); + cloned->SetColor(GetColor()); cloned->x_ = x_; cloned->y_ = y_; cloned->utf8_ = utf8_;
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp Tue May 28 15:58:21 2019 +0200 @@ -100,8 +100,8 @@ // Fill the polyline layer with the measurement lines PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); polylineLayer->ClearAllChains(); - polylineLayer->SetColor(0, 183, 17); + const Color color(0, 183, 17); // sides { @@ -109,13 +109,13 @@ PolylineSceneLayer::Chain chain; chain.push_back(side1End_); chain.push_back(center_); - polylineLayer->AddChain(chain, false); + polylineLayer->AddChain(chain, false, color); } { PolylineSceneLayer::Chain chain; chain.push_back(side2End_); chain.push_back(center_); - polylineLayer->AddChain(chain, false); + polylineLayer->AddChain(chain, false, color); } } @@ -126,14 +126,14 @@ //TODO: take DPI into account AddSquare(chain, GetScene(), side1End_, GetController()->GetHandleSideLengthS()); - polylineLayer->AddChain(chain, true); + polylineLayer->AddChain(chain, true, color); } { PolylineSceneLayer::Chain chain; //TODO: take DPI into account AddSquare(chain, GetScene(), side2End_, GetController()->GetHandleSideLengthS()); - polylineLayer->AddChain(chain, true); + polylineLayer->AddChain(chain, true, color); } } @@ -143,7 +143,7 @@ AddShortestArc(chain, side1End_, center_, side2End_, controller->GetAngleToolArcRadiusS()); - polylineLayer->AddChain(chain, false); + polylineLayer->AddChain(chain, false, color); } } {
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.cpp Tue May 28 15:58:21 2019 +0200 @@ -107,16 +107,16 @@ PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); polylineLayer->ClearAllChains(); - polylineLayer->SetColor( - TOOL_LINES_COLOR_RED, - TOOL_LINES_COLOR_GREEN, - TOOL_LINES_COLOR_BLUE); + + const Color color(TOOL_LINES_COLOR_RED, + TOOL_LINES_COLOR_GREEN, + TOOL_LINES_COLOR_BLUE); { PolylineSceneLayer::Chain chain; chain.push_back(start_); chain.push_back(end_); - polylineLayer->AddChain(chain, false); + polylineLayer->AddChain(chain, false, color); } // handles @@ -128,7 +128,7 @@ AddSquare(chain, GetScene(), start_, GetController()->GetHandleSideLengthS()); - polylineLayer->AddChain(chain, true); + polylineLayer->AddChain(chain, true, color); } { @@ -138,7 +138,7 @@ AddSquare(chain, GetScene(), end_, GetController()->GetHandleSideLengthS()); - polylineLayer->AddChain(chain, true); + polylineLayer->AddChain(chain, true, color); } }
--- a/Framework/StoneInitialization.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/StoneInitialization.cpp Tue May 28 15:58:21 2019 +0200 @@ -64,6 +64,10 @@ OrthancStone::SdlWindow::GlobalFinalize(); #endif +#if ORTHANC_ENABLE_CURL == 1 + Orthanc::HttpClient::GlobalFinalize(); +#endif + Orthanc::Logging::Finalize(); } }
--- a/Framework/Toolbox/DicomStructureSet.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Toolbox/DicomStructureSet.cpp Tue May 28 15:58:21 2019 +0200 @@ -540,6 +540,13 @@ } + Color DicomStructureSet::GetStructureColor(size_t index) const + { + const Structure& s = GetStructure(index); + return Color(s.red_, s.green_, s.blue_); + } + + void DicomStructureSet::GetStructureColor(uint8_t& red, uint8_t& green, uint8_t& blue,
--- a/Framework/Toolbox/DicomStructureSet.h Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Toolbox/DicomStructureSet.h Tue May 28 15:58:21 2019 +0200 @@ -23,6 +23,7 @@ #include "CoordinateSystem3D.h" #include "Extent2D.h" +#include "../Scene2D/Color.h" #include <Plugins/Samples/Common/FullOrthancDataset.h> @@ -152,6 +153,9 @@ const std::string& GetStructureInterpretation(size_t index) const; + Color GetStructureColor(size_t index) const; + + // TODO - remove void GetStructureColor(uint8_t& red, uint8_t& green, uint8_t& blue,
--- a/Framework/Toolbox/LinearAlgebra.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Framework/Toolbox/LinearAlgebra.cpp Tue May 28 15:58:21 2019 +0200 @@ -26,6 +26,7 @@ #include <Core/Toolbox.h> #include <stdio.h> +#include <boost/lexical_cast.hpp> #include <boost/numeric/ublas/lu.hpp> namespace OrthancStone @@ -68,15 +69,16 @@ for (size_t i = 0; i < items.size(); i++) { + /** + * We try and avoid the use of "boost::lexical_cast<>" here, + * as it is very slow. As we are parsing many doubles, we + * prefer to use the standard "std::stod" function if + * available: http://www.cplusplus.com/reference/string/stod/ + **/ + +#if __cplusplus >= 201103L // Is C++11 enabled? try { - /** - * We don't use "boost::lexical_cast<>" here, as it is very - * slow. As we are parsing many doubles, we prefer to use - * the standard "std::stod" function: - * http://www.cplusplus.com/reference/string/stod/ - **/ - target[i] = std::stod(items[i]); } catch (std::exception&) @@ -84,6 +86,17 @@ target.clear(); return false; } +#else // Fallback implementation using Boost + try + { + target[i] = boost::lexical_cast<double>(items[i]); + } + catch (boost::bad_lexical_cast&) + { + target.clear(); + return false; + } +#endif } return true;
--- a/Samples/Sdl/BasicScene.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Samples/Sdl/BasicScene.cpp Tue May 28 15:58:21 2019 +0200 @@ -104,21 +104,21 @@ { std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer); - layer->SetThickness(1); + layer->SetThickness(10); PolylineSceneLayer::Chain chain; chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5)); chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5)); chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5)); chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5)); - layer->AddChain(chain, true); + layer->AddChain(chain, true, 255, 0, 0); chain.clear(); chain.push_back(ScenePoint2D(-5, -5)); chain.push_back(ScenePoint2D(5, -5)); chain.push_back(ScenePoint2D(5, 5)); chain.push_back(ScenePoint2D(-5, 5)); - layer->AddChain(chain, true); + layer->AddChain(chain, true, 0, 255, 0); double dy = 1.01; chain.clear(); @@ -126,9 +126,8 @@ chain.push_back(ScenePoint2D(4, -4 + dy)); chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); chain.push_back(ScenePoint2D(4, 2)); - layer->AddChain(chain, false); + layer->AddChain(chain, false, 0, 0, 255); - layer->SetColor(0,255, 255); scene.SetLayer(50, layer.release()); }
--- a/Samples/Sdl/Loader.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Samples/Sdl/Loader.cpp Tue May 28 15:58:21 2019 +0200 @@ -1794,8 +1794,6 @@ command->SetBody(*it); command->SetPayload(new LookupInstance(loader, *it)); Schedule(command.release()); - - printf("[%s]\n", it->c_str()); } } }; @@ -1852,12 +1850,12 @@ for (size_t i = 0; i < content_.GetStructuresCount(); i++) { + const Color& color = content_.GetStructureColor(i); + std::vector< std::vector<DicomStructureSet::PolygonPoint> > polygons; if (content_.ProjectStructure(polygons, i, cuttingPlane)) { - printf(">> %d\n", static_cast<int>(polygons.size())); - for (size_t j = 0; j < polygons.size(); j++) { PolylineSceneLayer::Chain chain; @@ -1868,7 +1866,7 @@ chain[k] = ScenePoint2D(polygons[j][k].first, polygons[j][k].second); } - layer->AddChain(chain, true /* closed */); + layer->AddChain(chain, true /* closed */, color); } } } @@ -2492,6 +2490,8 @@ OrthancStone::StoneInitialize(); //Orthanc::Logging::EnableInfoLevel(true); + printf("%d\n", __cplusplus); + try { OrthancStone::NativeApplicationContext context;
--- a/Samples/Sdl/TrackerSampleApp.cpp Tue May 28 14:18:46 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.cpp Tue May 28 15:58:21 2019 +0200 @@ -533,14 +533,14 @@ chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5)); chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5)); chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5)); - layer->AddChain(chain, true); + layer->AddChain(chain, true, 255, 0, 0); chain.clear(); chain.push_back(ScenePoint2D(-5, -5)); chain.push_back(ScenePoint2D(5, -5)); chain.push_back(ScenePoint2D(5, 5)); chain.push_back(ScenePoint2D(-5, 5)); - layer->AddChain(chain, true); + layer->AddChain(chain, true, 0, 255, 0); double dy = 1.01; chain.clear(); @@ -548,9 +548,8 @@ chain.push_back(ScenePoint2D(4, -4 + dy)); chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); chain.push_back(ScenePoint2D(4, 2)); - layer->AddChain(chain, false); + layer->AddChain(chain, false, 0, 0, 255); - layer->SetColor(0, 255, 255); GetScene()->SetLayer(LINESET_1_ZINDEX, layer.release()); }