# HG changeset patch # User Sebastien Jodogne # Date 1604075204 -3600 # Node ID f5d4bd7b5593a168bd8be387fc19cc05916b6fc9 # Parent ad9b425f27ae824f3d8c4a95a3902200d5664f26 new class: OsiriXLayerFactory diff -r ad9b425f27ae -r f5d4bd7b5593 Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Oct 30 16:26:39 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Oct 30 17:26:44 2020 +0100 @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -1518,104 +1519,33 @@ layer->SetPixelSpacing(pixelSpacingX, pixelSpacingY); - /**** - * BEGINNING OF EXPERIMENTAL CODE => TODO => Move this to class - * "CollectionOfAnnotations"? - ****/ - std::unique_ptr annotationsLayer; if (annotations_) { + const FrameGeometry& geometry = GetCurrentFrameGeometry(); + std::set a; annotations_->LookupSopInstanceUid(a, sopInstanceUid); - if (!a.empty()) + if (geometry.IsValid() && + !a.empty()) { annotationsLayer.reset(new OrthancStone::MacroSceneLayer); annotationsLayer->Reserve(a.size()); - - using namespace OrthancStone::OsiriX; + + OrthancStone::OsiriXLayerFactory factory; + factory.SetColor(0, 255, 0); + factory.SetArrowLength(100); + factory.SetArrowAngle(3.14159/4.0); for (std::set::const_iterator it = a.begin(); it != a.end(); ++it) { - const Annotation& annotation = annotations_->GetAnnotation(*it); - - switch (annotation.GetType()) - { - case Annotation::Type_Line: - { - const LineAnnotation& line = dynamic_cast(annotation); - double x1, y1, x2, y2; - if (GetCurrentFrameGeometry().ProjectPoint(x1, y1, line.GetPoint1()) && - GetCurrentFrameGeometry().ProjectPoint(x2, y2, line.GetPoint2())) - { - if (line.IsArrow()) - { - std::unique_ptr layer( - new OrthancStone::ArrowSceneLayer(OrthancStone::ScenePoint2D(x1, y1), - OrthancStone::ScenePoint2D(x2, y2))); - layer->SetColor(0, 255, 0); - annotationsLayer->AddLayer(layer.release()); - } - else - { - std::unique_ptr layer(new OrthancStone::PolylineSceneLayer); - OrthancStone::PolylineSceneLayer::Chain chain; - chain.push_back(OrthancStone::ScenePoint2D(x1, y1)); - chain.push_back(OrthancStone::ScenePoint2D(x2, y2)); - layer->AddChain(chain, false, 0, 255, 0); - annotationsLayer->AddLayer(layer.release()); - } - } - break; - } - - case Annotation::Type_Angle: - { - const AngleAnnotation& angle = dynamic_cast(annotation); - double x1, y1, x2, y2, x3, y3; - if (GetCurrentFrameGeometry().ProjectPoint(x1, y1, angle.GetA()) && - GetCurrentFrameGeometry().ProjectPoint(x2, y2, angle.GetCenter()) && - GetCurrentFrameGeometry().ProjectPoint(x3, y3, angle.GetB())) - { - std::unique_ptr layer(new OrthancStone::PolylineSceneLayer); - OrthancStone::PolylineSceneLayer::Chain chain; - chain.push_back(OrthancStone::ScenePoint2D(x1, y1)); - chain.push_back(OrthancStone::ScenePoint2D(x2, y2)); - chain.push_back(OrthancStone::ScenePoint2D(x3, y3)); - layer->AddChain(chain, false, 0, 255, 0); - annotationsLayer->AddLayer(layer.release()); - } - break; - } - - case Annotation::Type_Text: - { - const TextAnnotation& text = dynamic_cast(annotation); - double x, y; - if (GetCurrentFrameGeometry().ProjectPoint(x, y, text.GetCenter())) - { - std::unique_ptr layer(new OrthancStone::TextSceneLayer()); - layer->SetPosition(x, y); - layer->SetText(text.GetText()); - layer->SetAnchor(OrthancStone::BitmapAnchor_Center); - layer->SetColor(255, 0, 0); - annotationsLayer->AddLayer(layer.release()); - } - break; - } - - default: - LOG(ERROR) << "Annotation type not implemented: " << annotation.GetType(); - } + const OrthancStone::OsiriX::Annotation& annotation = annotations_->GetAnnotation(*it); + annotationsLayer->AddLayer(factory.Create(annotation, geometry.GetCoordinates())); } } } - /**** - * END OF EXPERIMENTAL CODE - ****/ - if (layer.get() == NULL) { diff -r ad9b425f27ae -r f5d4bd7b5593 OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake --- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Fri Oct 30 16:26:39 2020 +0100 +++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Fri Oct 30 17:26:44 2020 +0100 @@ -281,6 +281,8 @@ ${ORTHANC_STONE_ROOT}/Scene2D/MacroSceneLayer.cpp ${ORTHANC_STONE_ROOT}/Scene2D/MacroSceneLayer.h ${ORTHANC_STONE_ROOT}/Scene2D/NullLayer.h + ${ORTHANC_STONE_ROOT}/Scene2D/OsiriXLayerFactory.cpp + ${ORTHANC_STONE_ROOT}/Scene2D/OsiriXLayerFactory.h ${ORTHANC_STONE_ROOT}/Scene2D/PanSceneTracker.cpp ${ORTHANC_STONE_ROOT}/Scene2D/PanSceneTracker.h ${ORTHANC_STONE_ROOT}/Scene2D/PointerEvent.cpp diff -r ad9b425f27ae -r f5d4bd7b5593 OrthancStone/Sources/Scene2D/OsiriXLayerFactory.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Scene2D/OsiriXLayerFactory.cpp Fri Oct 30 17:26:44 2020 +0100 @@ -0,0 +1,126 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * . + **/ + + +#include "OsiriXLayerFactory.h" + +#include "../Toolbox/OsiriX/AngleAnnotation.h" +#include "../Toolbox/OsiriX/LineAnnotation.h" +#include "../Toolbox/OsiriX/TextAnnotation.h" + +#include "ArrowSceneLayer.h" +#include "PolylineSceneLayer.h" +#include "TextSceneLayer.h" + +#include + +#include + +namespace OrthancStone +{ + OsiriXLayerFactory::OsiriXLayerFactory() : + thickness_(1), + arrowLength_(10), // 10 pixels + arrowAngle_(boost::math::constants::pi() / 12.0), // 15 degrees + fontIndex_(0) + { + } + + + ISceneLayer* OsiriXLayerFactory::Create(const OsiriX::Annotation& annotation, + const CoordinateSystem3D& plane) const + { + switch (annotation.GetType()) + { + case OsiriX::Annotation::Type_Line: + { + const OsiriX::LineAnnotation& line = dynamic_cast(annotation); + + const ScenePoint2D p1 = plane.ProjectPoint(line.GetPoint1()); + const ScenePoint2D p2 = plane.ProjectPoint(line.GetPoint2()); + + if (line.IsArrow()) + { + std::unique_ptr layer(new ArrowSceneLayer(p1, p2)); + layer->SetColor(color_); + layer->SetThickness(thickness_); + layer->SetArrowAngle(arrowAngle_); + layer->SetArrowLength(arrowLength_); + return layer.release(); + } + else + { + std::unique_ptr layer(new PolylineSceneLayer); + PolylineSceneLayer::Chain chain; + chain.push_back(p1); + chain.push_back(p2); + layer->AddChain(chain, false, color_); + layer->SetThickness(thickness_); + return layer.release(); + } + + break; + } + + case OsiriX::Annotation::Type_Angle: + { + const OsiriX::AngleAnnotation& angle = dynamic_cast(annotation); + + const ScenePoint2D a = plane.ProjectPoint(angle.GetA()); + const ScenePoint2D center = plane.ProjectPoint(angle.GetCenter()); + const ScenePoint2D b = plane.ProjectPoint(angle.GetB()); + + std::unique_ptr layer(new PolylineSceneLayer); + PolylineSceneLayer::Chain chain; + chain.push_back(a); + chain.push_back(center); + chain.push_back(b); + layer->AddChain(chain, false, color_); + layer->SetThickness(thickness_); + + return layer.release(); + } + + case OsiriX::Annotation::Type_Text: + { + const OsiriX::TextAnnotation& text = dynamic_cast(annotation); + + const ScenePoint2D center = plane.ProjectPoint(text.GetCenter()); + + std::unique_ptr layer(new TextSceneLayer()); + layer->SetPosition(center.GetX(), center.GetY()); + layer->SetText(text.GetText()); + layer->SetAnchor(BitmapAnchor_Center); + layer->SetColor(color_); + layer->SetFontIndex(fontIndex_); + + return layer.release(); + } + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, + "Annotation type not implemented: " + + boost::lexical_cast(annotation.GetType())); + } + + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } +} diff -r ad9b425f27ae -r f5d4bd7b5593 OrthancStone/Sources/Scene2D/OsiriXLayerFactory.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Scene2D/OsiriXLayerFactory.h Fri Oct 30 17:26:44 2020 +0100 @@ -0,0 +1,104 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * . + **/ + + +#pragma once + +#include "../Toolbox/CoordinateSystem3D.h" +#include "../Toolbox/OsiriX/Annotation.h" +#include "Color.h" +#include "ISceneLayer.h" + +namespace OrthancStone +{ + class OsiriXLayerFactory : public boost::noncopyable + { + private: + Color color_; + double thickness_; + double arrowLength_; + double arrowAngle_; + size_t fontIndex_; + + public: + OsiriXLayerFactory(); + + void SetColor(const Color& color) + { + color_ = color; + } + + void SetColor(uint8_t red, + uint8_t green, + uint8_t blue) + { + color_ = Color(red, green, blue); + } + + const Color& GetColor() const + { + return color_; + } + + void SetThickness(double thickness) + { + thickness_ = thickness; + } + + double GetThickness() const + { + return thickness_; + } + + void SetArrowLength(double arrowLength) + { + arrowLength_ = arrowLength; + } + + double GetArrowLength() const + { + return arrowLength_; + } + + void SetArrowAngle(double arrowAngle) + { + arrowAngle_ = arrowAngle; + } + + double GetArrowAngle() const + { + return arrowAngle_; + } + + void SetFontIndex(double fontIndex) + { + fontIndex_ = fontIndex; + } + + double GetFontIndex() const + { + return fontIndex_; + } + + ISceneLayer* Create(const OsiriX::Annotation& annotation, + const CoordinateSystem3D& plane) const; + }; +}