Mercurial > hg > orthanc-stone
diff Applications/Samples/SingleFrameEditorApplication.h @ 415:c0589c3173fd
finished reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 13 Nov 2018 10:36:53 +0100 |
parents | f7616c010056 |
children | aee3d7941c9b |
line wrap: on
line diff
--- a/Applications/Samples/SingleFrameEditorApplication.h Mon Nov 12 18:00:48 2018 +0100 +++ b/Applications/Samples/SingleFrameEditorApplication.h Tue Nov 13 10:36:53 2018 +0100 @@ -23,25 +23,18 @@ #include "SampleApplicationBase.h" +#include "../../Framework/Radiography/RadiographyLayerCropTracker.h" #include "../../Framework/Radiography/RadiographyLayerMoveTracker.h" +#include "../../Framework/Radiography/RadiographyLayerResizeTracker.h" #include "../../Framework/Radiography/RadiographyLayerRotateTracker.h" #include "../../Framework/Radiography/RadiographyScene.h" #include "../../Framework/Radiography/RadiographySceneCommand.h" #include "../../Framework/Radiography/RadiographyWidget.h" - -#include "../../Framework/Toolbox/UndoRedoStack.h" +#include "../../Framework/Radiography/RadiographyWindowingTracker.h" #include <Core/Images/FontRegistry.h> -#include <Core/Images/Image.h> -#include <Core/Images/ImageProcessing.h> -#include <Core/Images/PamReader.h> -#include <Core/Images/PamWriter.h> -#include <Core/Images/PngWriter.h> #include <Core/Logging.h> #include <Core/OrthancException.h> -#include <Core/Toolbox.h> -#include <Plugins/Samples/Common/DicomDatasetReader.h> -#include <Plugins/Samples/Common/FullOrthancDataset.h> // Export using PAM is faster than using PNG, but requires Orthanc @@ -49,515 +42,8 @@ #define EXPORT_USING_PAM 1 -#include <boost/math/special_functions/round.hpp> - - namespace OrthancStone { - class RadiographyLayerCropTracker : public IWorldSceneMouseTracker - { - private: - UndoRedoStack& undoRedoStack_; - RadiographyScene::LayerAccessor accessor_; - Corner corner_; - unsigned int cropX_; - unsigned int cropY_; - unsigned int cropWidth_; - unsigned int cropHeight_; - - class UndoRedoCommand : public RadiographySceneCommand - { - private: - unsigned int sourceCropX_; - unsigned int sourceCropY_; - unsigned int sourceCropWidth_; - unsigned int sourceCropHeight_; - unsigned int targetCropX_; - unsigned int targetCropY_; - unsigned int targetCropWidth_; - unsigned int targetCropHeight_; - - protected: - virtual void UndoInternal(RadiographyLayer& layer) const - { - layer.SetCrop(sourceCropX_, sourceCropY_, sourceCropWidth_, sourceCropHeight_); - } - - virtual void RedoInternal(RadiographyLayer& layer) const - { - layer.SetCrop(targetCropX_, targetCropY_, targetCropWidth_, targetCropHeight_); - } - - public: - UndoRedoCommand(const RadiographyLayerCropTracker& tracker) : - RadiographySceneCommand(tracker.accessor_), - sourceCropX_(tracker.cropX_), - sourceCropY_(tracker.cropY_), - sourceCropWidth_(tracker.cropWidth_), - sourceCropHeight_(tracker.cropHeight_) - { - tracker.accessor_.GetLayer().GetCrop(targetCropX_, targetCropY_, - targetCropWidth_, targetCropHeight_); - } - }; - - - public: - RadiographyLayerCropTracker(UndoRedoStack& undoRedoStack, - RadiographyScene& scene, - const ViewportGeometry& view, - size_t layer, - double x, - double y, - Corner corner) : - undoRedoStack_(undoRedoStack), - accessor_(scene, layer), - corner_(corner) - { - if (accessor_.IsValid()) - { - accessor_.GetLayer().GetCrop(cropX_, cropY_, cropWidth_, cropHeight_); - } - } - - virtual bool HasRender() const - { - return false; - } - - virtual void Render(CairoContext& context, - double zoom) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - virtual void MouseUp() - { - if (accessor_.IsValid()) - { - undoRedoStack_.Add(new UndoRedoCommand(*this)); - } - } - - virtual void MouseMove(int displayX, - int displayY, - double sceneX, - double sceneY) - { - if (accessor_.IsValid()) - { - unsigned int x, y; - - RadiographyLayer& layer = accessor_.GetLayer(); - if (layer.GetPixel(x, y, sceneX, sceneY)) - { - unsigned int targetX, targetWidth; - - if (corner_ == Corner_TopLeft || - corner_ == Corner_BottomLeft) - { - targetX = std::min(x, cropX_ + cropWidth_); - targetWidth = cropX_ + cropWidth_ - targetX; - } - else - { - targetX = cropX_; - targetWidth = std::max(x, cropX_) - cropX_; - } - - unsigned int targetY, targetHeight; - - if (corner_ == Corner_TopLeft || - corner_ == Corner_TopRight) - { - targetY = std::min(y, cropY_ + cropHeight_); - targetHeight = cropY_ + cropHeight_ - targetY; - } - else - { - targetY = cropY_; - targetHeight = std::max(y, cropY_) - cropY_; - } - - layer.SetCrop(targetX, targetY, targetWidth, targetHeight); - } - } - } - }; - - - class RadiographyLayerResizeTracker : public IWorldSceneMouseTracker - { - private: - UndoRedoStack& undoRedoStack_; - RadiographyScene::LayerAccessor accessor_; - bool roundScaling_; - double originalSpacingX_; - double originalSpacingY_; - double originalPanX_; - double originalPanY_; - Corner oppositeCorner_; - double oppositeX_; - double oppositeY_; - double baseScaling_; - - static double ComputeDistance(double x1, - double y1, - double x2, - double y2) - { - double dx = x1 - x2; - double dy = y1 - y2; - return sqrt(dx * dx + dy * dy); - } - - class UndoRedoCommand : public RadiographySceneCommand - { - private: - double sourceSpacingX_; - double sourceSpacingY_; - double sourcePanX_; - double sourcePanY_; - double targetSpacingX_; - double targetSpacingY_; - double targetPanX_; - double targetPanY_; - - protected: - virtual void UndoInternal(RadiographyLayer& layer) const - { - layer.SetPixelSpacing(sourceSpacingX_, sourceSpacingY_); - layer.SetPan(sourcePanX_, sourcePanY_); - } - - virtual void RedoInternal(RadiographyLayer& layer) const - { - layer.SetPixelSpacing(targetSpacingX_, targetSpacingY_); - layer.SetPan(targetPanX_, targetPanY_); - } - - public: - UndoRedoCommand(const RadiographyLayerResizeTracker& tracker) : - RadiographySceneCommand(tracker.accessor_), - sourceSpacingX_(tracker.originalSpacingX_), - sourceSpacingY_(tracker.originalSpacingY_), - sourcePanX_(tracker.originalPanX_), - sourcePanY_(tracker.originalPanY_), - targetSpacingX_(tracker.accessor_.GetLayer().GetPixelSpacingX()), - targetSpacingY_(tracker.accessor_.GetLayer().GetPixelSpacingY()), - targetPanX_(tracker.accessor_.GetLayer().GetPanX()), - targetPanY_(tracker.accessor_.GetLayer().GetPanY()) - { - } - }; - - - public: - RadiographyLayerResizeTracker(UndoRedoStack& undoRedoStack, - RadiographyScene& scene, - size_t layer, - double x, - double y, - Corner corner, - bool roundScaling) : - undoRedoStack_(undoRedoStack), - accessor_(scene, layer), - roundScaling_(roundScaling) - { - if (accessor_.IsValid() && - accessor_.GetLayer().IsResizeable()) - { - originalSpacingX_ = accessor_.GetLayer().GetPixelSpacingX(); - originalSpacingY_ = accessor_.GetLayer().GetPixelSpacingY(); - originalPanX_ = accessor_.GetLayer().GetPanX(); - originalPanY_ = accessor_.GetLayer().GetPanY(); - - switch (corner) - { - case Corner_TopLeft: - oppositeCorner_ = Corner_BottomRight; - break; - - case Corner_TopRight: - oppositeCorner_ = Corner_BottomLeft; - break; - - case Corner_BottomLeft: - oppositeCorner_ = Corner_TopRight; - break; - - case Corner_BottomRight: - oppositeCorner_ = Corner_TopLeft; - break; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - accessor_.GetLayer().GetCorner(oppositeX_, oppositeY_, oppositeCorner_); - - double d = ComputeDistance(x, y, oppositeX_, oppositeY_); - if (d >= std::numeric_limits<float>::epsilon()) - { - baseScaling_ = 1.0 / d; - } - else - { - // Avoid division by zero in extreme cases - accessor_.Invalidate(); - } - } - } - - virtual bool HasRender() const - { - return false; - } - - virtual void Render(CairoContext& context, - double zoom) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - virtual void MouseUp() - { - if (accessor_.IsValid() && - accessor_.GetLayer().IsResizeable()) - { - undoRedoStack_.Add(new UndoRedoCommand(*this)); - } - } - - virtual void MouseMove(int displayX, - int displayY, - double sceneX, - double sceneY) - { - static const double ROUND_SCALING = 0.1; - - if (accessor_.IsValid() && - accessor_.GetLayer().IsResizeable()) - { - double scaling = ComputeDistance(oppositeX_, oppositeY_, sceneX, sceneY) * baseScaling_; - - if (roundScaling_) - { - scaling = boost::math::round<double>((scaling / ROUND_SCALING) * ROUND_SCALING); - } - - RadiographyLayer& layer = accessor_.GetLayer(); - layer.SetPixelSpacing(scaling * originalSpacingX_, - scaling * originalSpacingY_); - - // Keep the opposite corner at a fixed location - double ox, oy; - layer.GetCorner(ox, oy, oppositeCorner_); - layer.SetPan(layer.GetPanX() + oppositeX_ - ox, - layer.GetPanY() + oppositeY_ - oy); - } - } - }; - - - class RadiographyWindowingTracker : public IWorldSceneMouseTracker - { - public: - enum Action - { - Action_IncreaseWidth, - Action_DecreaseWidth, - Action_IncreaseCenter, - Action_DecreaseCenter - }; - - private: - UndoRedoStack& undoRedoStack_; - RadiographyScene& scene_; - int clickX_; - int clickY_; - Action leftAction_; - Action rightAction_; - Action upAction_; - Action downAction_; - float strength_; - float sourceCenter_; - float sourceWidth_; - - static void ComputeAxisEffect(int& deltaCenter, - int& deltaWidth, - int delta, - Action actionNegative, - Action actionPositive) - { - if (delta < 0) - { - switch (actionNegative) - { - case Action_IncreaseWidth: - deltaWidth = -delta; - break; - - case Action_DecreaseWidth: - deltaWidth = delta; - break; - - case Action_IncreaseCenter: - deltaCenter = -delta; - break; - - case Action_DecreaseCenter: - deltaCenter = delta; - break; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - else if (delta > 0) - { - switch (actionPositive) - { - case Action_IncreaseWidth: - deltaWidth = delta; - break; - - case Action_DecreaseWidth: - deltaWidth = -delta; - break; - - case Action_IncreaseCenter: - deltaCenter = delta; - break; - - case Action_DecreaseCenter: - deltaCenter = -delta; - break; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - } - - - class UndoRedoCommand : public UndoRedoStack::ICommand - { - private: - RadiographyScene& scene_; - float sourceCenter_; - float sourceWidth_; - float targetCenter_; - float targetWidth_; - - public: - UndoRedoCommand(const RadiographyWindowingTracker& tracker) : - scene_(tracker.scene_), - sourceCenter_(tracker.sourceCenter_), - sourceWidth_(tracker.sourceWidth_) - { - scene_.GetWindowingWithDefault(targetCenter_, targetWidth_); - } - - virtual void Undo() const - { - scene_.SetWindowing(sourceCenter_, sourceWidth_); - } - - virtual void Redo() const - { - scene_.SetWindowing(targetCenter_, targetWidth_); - } - }; - - - public: - RadiographyWindowingTracker(UndoRedoStack& undoRedoStack, - RadiographyScene& scene, - int x, - int y, - Action leftAction, - Action rightAction, - Action upAction, - Action downAction) : - undoRedoStack_(undoRedoStack), - scene_(scene), - clickX_(x), - clickY_(y), - leftAction_(leftAction), - rightAction_(rightAction), - upAction_(upAction), - downAction_(downAction) - { - scene_.GetWindowingWithDefault(sourceCenter_, sourceWidth_); - - float minValue, maxValue; - scene.GetRange(minValue, maxValue); - - assert(minValue <= maxValue); - - float tmp; - - float delta = (maxValue - minValue); - if (delta <= 1) - { - tmp = 0; - } - else - { - // NB: Visual Studio 2008 does not provide "log2f()", so we - // implement it by ourselves - tmp = logf(delta) / logf(2.0f); - } - - strength_ = tmp - 7; - if (strength_ < 1) - { - strength_ = 1; - } - } - - virtual bool HasRender() const - { - return false; - } - - virtual void Render(CairoContext& context, - double zoom) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - virtual void MouseUp() - { - undoRedoStack_.Add(new UndoRedoCommand(*this)); - } - - - virtual void MouseMove(int displayX, - int displayY, - double sceneX, - double sceneY) - { - // https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/src/app/viewport/image-plugins/windowing-viewport-tool.class.js - - static const float SCALE = 1.0; - - int deltaCenter = 0; - int deltaWidth = 0; - - ComputeAxisEffect(deltaCenter, deltaWidth, displayX - clickX_, leftAction_, rightAction_); - ComputeAxisEffect(deltaCenter, deltaWidth, displayY - clickY_, upAction_, downAction_); - - float newCenter = sourceCenter_ + (deltaCenter / SCALE * strength_); - float newWidth = sourceWidth_ + (deltaWidth / SCALE * strength_); - scene_.SetWindowing(newCenter, newWidth); - } - }; - - - - namespace Samples { class RadiographyEditorInteractor :