Mercurial > hg > orthanc-stone
changeset 1554:6d14ed6163b1
flip x/y in Stone Web viewer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 17 Aug 2020 16:10:00 +0200 |
parents | bf02a90ca9ca |
children | b894072b9e2f |
files | Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebApplication/index.html Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.cpp OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.h OrthancStone/Sources/Toolbox/AffineTransform2D.cpp OrthancStone/Sources/Toolbox/AffineTransform2D.h |
diffstat | 7 files changed, 185 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebApplication/app.js Mon Aug 17 13:25:54 2020 +0200 +++ b/Applications/StoneWebViewer/WebApplication/app.js Mon Aug 17 16:10:00 2020 +0200 @@ -466,6 +466,20 @@ } }, + FlipX() { + var canvas = this.GetActiveCanvas(); + if (canvas != '') { + stone.FlipX(canvas); + } + }, + + FlipY() { + var canvas = this.GetActiveCanvas(); + if (canvas != '') { + stone.FlipY(canvas); + } + }, + ApplyPreferences() { this.modalPreferences = false;
--- a/Applications/StoneWebViewer/WebApplication/index.html Mon Aug 17 13:25:54 2020 +0200 +++ b/Applications/StoneWebViewer/WebApplication/index.html Mon Aug 17 16:10:00 2020 +0200 @@ -315,6 +315,18 @@ </div> <div class="ng-scope inline-object"> + <button class="wvButton--underline text-center" v-on:click="FlipX()"> + <i class="fas fa-exchange-alt"></i>X + </button> + </div> + + <div class="ng-scope inline-object"> + <button class="wvButton--underline text-center" v-on:click="FlipY()"> + <i class="fa fa-exchange-alt fa-rotate-90"></i>Y + </button> + </div> + + <div class="ng-scope inline-object"> <button class="wvButton--underline text-center" v-bind:class="{ 'active' : showInfo }" v-on:click="showInfo = !showInfo">
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Aug 17 13:25:54 2020 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Aug 17 16:10:00 2020 +0200 @@ -1234,6 +1234,8 @@ float defaultWindowingCenter_; float defaultWindowingWidth_; bool inverted_; + bool flipX_; + bool flipY_; bool fitNextContent_; bool isCtrlDown_; FrameGeometry currentFrameGeometry_; @@ -1425,6 +1427,8 @@ } layer->SetLinearInterpolation(true); + layer->SetFlipX(flipX_); + layer->SetFlipY(flipY_); double pixelSpacingX, pixelSpacingY; OrthancStone::GeometryToolbox::GetPixelSpacing( @@ -1519,6 +1523,34 @@ } } + void UpdateCurrentTextureParameters() + { + std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); + + if (lock->GetController().GetScene().HasLayer(LAYER_TEXTURE)) + { + if (lock->GetController().GetScene().GetLayer(LAYER_TEXTURE).GetType() == + OrthancStone::ISceneLayer::Type_FloatTexture) + { + dynamic_cast<OrthancStone::FloatTextureSceneLayer&>( + lock->GetController().GetScene().GetLayer(LAYER_TEXTURE)). + SetCustomWindowing(windowingCenter_, windowingWidth_); + } + + { + OrthancStone::TextureBaseSceneLayer& layer = + dynamic_cast<OrthancStone::TextureBaseSceneLayer&>( + lock->GetController().GetScene().GetLayer(LAYER_TEXTURE)); + + layer.SetFlipX(flipX_); + layer.SetFlipY(flipY_); + } + + lock->Invalidate(); + } + } + + ViewerViewport(OrthancStone::ILoadersContext& context, const OrthancStone::DicomSource& source, const std::string& canvas, @@ -1528,7 +1560,9 @@ source_(source), cache_(cache), fitNextContent_(true), - isCtrlDown_(false) + isCtrlDown_(false), + flipX_(false), + flipY_(false) { if (!cache_) { @@ -1551,6 +1585,29 @@ emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, OnKey); ResetDefaultWindowing(); + + /*{ + std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); + std::unique_ptr<OrthancStone::PolylineSceneLayer> layer(new OrthancStone::PolylineSceneLayer); + OrthancStone::PolylineSceneLayer::Chain chain; + chain.push_back(OrthancStone::ScenePoint2D(-10, 0)); + chain.push_back(OrthancStone::ScenePoint2D(10, 0)); + layer->AddChain(chain, false, 255, 0, 0); + chain.clear(); + chain.push_back(OrthancStone::ScenePoint2D(0, -10)); + chain.push_back(OrthancStone::ScenePoint2D(0, 10)); + layer->AddChain(chain, false, 255, 0, 0); + chain.clear(); + chain.push_back(OrthancStone::ScenePoint2D(40, 30)); + chain.push_back(OrthancStone::ScenePoint2D(40, 50)); + layer->AddChain(chain, false, 255, 0, 0); + chain.clear(); + chain.push_back(OrthancStone::ScenePoint2D(30, 40)); + chain.push_back(OrthancStone::ScenePoint2D(50, 40)); + layer->AddChain(chain, false, 255, 0, 0); + lock->GetController().GetScene().SetLayer(1000, layer.release()); + lock->Invalidate(); + }*/ } static EM_BOOL OnKey(int eventType, @@ -1634,6 +1691,8 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } + flipX_ = false; + flipY_ = false; fitNextContent_ = true; frames_.reset(frames); @@ -1776,20 +1835,19 @@ { windowingCenter_ = windowingCenter; windowingWidth_ = windowingWidth; - - { - std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); + UpdateCurrentTextureParameters(); + } - if (lock->GetController().GetScene().HasLayer(LAYER_TEXTURE) && - lock->GetController().GetScene().GetLayer(LAYER_TEXTURE).GetType() == - OrthancStone::ISceneLayer::Type_FloatTexture) - { - dynamic_cast<OrthancStone::FloatTextureSceneLayer&>( - lock->GetController().GetScene().GetLayer(LAYER_TEXTURE)). - SetCustomWindowing(windowingCenter_, windowingWidth_); - lock->Invalidate(); - } - } + void FlipX() + { + flipX_ = !flipX_; + UpdateCurrentTextureParameters(); + } + + void FlipY() + { + flipY_ = !flipY_; + UpdateCurrentTextureParameters(); } void Invert() @@ -2285,6 +2343,28 @@ EMSCRIPTEN_KEEPALIVE + void FlipX(const char* canvas) + { + try + { + GetViewport(canvas)->FlipX(); + } + EXTERN_CATCH_EXCEPTIONS; + } + + + EMSCRIPTEN_KEEPALIVE + void FlipY(const char* canvas) + { + try + { + GetViewport(canvas)->FlipY(); + } + EXTERN_CATCH_EXCEPTIONS; + } + + + EMSCRIPTEN_KEEPALIVE void SetSoftwareRendering(int softwareRendering) { softwareRendering_ = softwareRendering;
--- a/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.cpp Mon Aug 17 13:25:54 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.cpp Mon Aug 17 16:10:00 2020 +0200 @@ -47,6 +47,8 @@ pixelSpacingY_ = other.pixelSpacingY_; angle_ = other.angle_; isLinearInterpolation_ = other.isLinearInterpolation_; + flipX_ = other.flipX_; + flipY_ = other.flipY_; } @@ -57,6 +59,8 @@ pixelSpacingY_(1), angle_(0), isLinearInterpolation_(false), + flipX_(false), + flipY_(false), revision_(0) { if (pixelSpacingX_ <= 0 || @@ -107,6 +111,20 @@ } + void TextureBaseSceneLayer::SetFlipX(bool flip) + { + flipX_ = flip; + IncrementRevision(); + } + + + void TextureBaseSceneLayer::SetFlipY(bool flip) + { + flipY_ = flip; + IncrementRevision(); + } + + const Orthanc::ImageAccessor& TextureBaseSceneLayer::GetTexture() const { if (!HasTexture()) @@ -123,11 +141,21 @@ AffineTransform2D TextureBaseSceneLayer::GetTransform() const { + unsigned int width = 0; + unsigned int height = 0; + + if (texture_.get() != NULL) + { + width = texture_->GetWidth(); + height = texture_->GetHeight(); + } + return AffineTransform2D::Combine( AffineTransform2D::CreateOffset(originX_, originY_), AffineTransform2D::CreateRotation(angle_), AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_), - AffineTransform2D::CreateOffset(-0.5, -0.5)); + AffineTransform2D::CreateOffset(-0.5, -0.5), + AffineTransform2D::CreateFlip(flipX_, flipY_, width, height)); }
--- a/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.h Mon Aug 17 13:25:54 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/TextureBaseSceneLayer.h Mon Aug 17 16:10:00 2020 +0200 @@ -39,6 +39,8 @@ double pixelSpacingY_; double angle_; bool isLinearInterpolation_; + bool flipX_; + bool flipY_; uint64_t revision_; protected: @@ -65,6 +67,10 @@ void SetAngle(double angle); void SetLinearInterpolation(bool isLinearInterpolation); + + void SetFlipX(bool flip); + + void SetFlipY(bool flip); double GetOriginX() const { @@ -101,6 +107,16 @@ return (texture_.get() != NULL); } + bool IsFlipX() const + { + return flipX_; + } + + bool IsFlipY() const + { + return flipY_; + } + const Orthanc::ImageAccessor& GetTexture() const; AffineTransform2D GetTransform() const;
--- a/OrthancStone/Sources/Toolbox/AffineTransform2D.cpp Mon Aug 17 13:25:54 2020 +0200 +++ b/OrthancStone/Sources/Toolbox/AffineTransform2D.cpp Mon Aug 17 16:10:00 2020 +0200 @@ -268,4 +268,19 @@ return t; } + + + AffineTransform2D AffineTransform2D::CreateFlip(bool flipX, + bool flipY, + unsigned int width, + unsigned int height) + { + AffineTransform2D t; + t.matrix_(0, 0) = (flipX ? -1 : 1); + t.matrix_(0, 2) = (flipX ? width : 0); + t.matrix_(1, 1) = (flipY ? -1 : 1); + t.matrix_(1, 2) = (flipY ? height : 0); + + return t; + } }
--- a/OrthancStone/Sources/Toolbox/AffineTransform2D.h Mon Aug 17 13:25:54 2020 +0200 +++ b/OrthancStone/Sources/Toolbox/AffineTransform2D.h Mon Aug 17 16:10:00 2020 +0200 @@ -99,5 +99,10 @@ static AffineTransform2D CreateOpenGLClipspace(unsigned int canvasWidth, unsigned int canvasHeight); + + static AffineTransform2D CreateFlip(bool flipX, + bool flipY, + unsigned int width, + unsigned int height); }; }