Mercurial > hg > orthanc-stone
changeset 860:238693c3bc51 am-dev
merge default -> am-dev
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Mon, 24 Jun 2019 14:35:00 +0200 |
parents | a6e17a5a39e7 (diff) 6845a05f9526 (current diff) |
children | 23701fbf228e |
files | .hgignore Applications/Qt/QCairoWidget.h Applications/Qt/QtStoneApplicationRunner.cpp Framework/Layers/CircleMeasureTracker.cpp Framework/Layers/CircleMeasureTracker.h Framework/Layers/ColorFrameRenderer.cpp Framework/Layers/ColorFrameRenderer.h Framework/Layers/DicomSeriesVolumeSlicer.cpp Framework/Layers/DicomSeriesVolumeSlicer.h Framework/Layers/DicomStructureSetSlicer.cpp Framework/Layers/DicomStructureSetSlicer.h Framework/Layers/FrameRenderer.cpp Framework/Layers/FrameRenderer.h Framework/Layers/GrayscaleFrameRenderer.cpp Framework/Layers/GrayscaleFrameRenderer.h Framework/Layers/ILayerRenderer.h Framework/Layers/IVolumeSlicer.h Framework/Layers/LineLayerRenderer.cpp Framework/Layers/LineLayerRenderer.h Framework/Layers/LineMeasureTracker.cpp Framework/Layers/LineMeasureTracker.h Framework/Layers/RenderStyle.cpp Framework/Layers/RenderStyle.h Framework/Layers/SeriesFrameRendererFactory.cpp Framework/Layers/SeriesFrameRendererFactory.h Framework/Layers/SingleFrameRendererFactory.cpp Framework/Layers/SingleFrameRendererFactory.h Framework/Layers/SliceOutlineRenderer.cpp Framework/Layers/SliceOutlineRenderer.h Framework/Radiography/RadiographySceneReader.cpp Framework/Scene2D/Internals/CairoFloatTextureRenderer.cpp Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Framework/Scene2DViewport/EditAngleMeasureTracker.h Framework/Scene2DViewport/EditCircleMeasureTracker.cpp Framework/Scene2DViewport/EditCircleMeasureTracker.h Framework/Scene2DViewport/EditLineMeasureTracker.cpp Framework/Scene2DViewport/EditLineMeasureTracker.h Framework/Scene2DViewport/MeasureTools.cpp Framework/Scene2DViewport/MeasureTools.h Framework/Scene2DViewport/PointerTypes.h Framework/SmartLoader.cpp Framework/SmartLoader.h Framework/Toolbox/BaseWebService.cpp Framework/Toolbox/BaseWebService.h Framework/Toolbox/DicomFrameConverter.cpp Framework/Toolbox/DicomFrameConverter.h Framework/Toolbox/DownloadStack.cpp Framework/Toolbox/DownloadStack.h Framework/Toolbox/IDelayedCallExecutor.h Framework/Toolbox/ISeriesLoader.h Framework/Toolbox/IWebService.cpp Framework/Toolbox/IWebService.h Framework/Toolbox/MessagingToolbox.cpp Framework/Toolbox/MessagingToolbox.h Framework/Toolbox/OrientedBoundingBox.cpp Framework/Toolbox/OrientedBoundingBox.h Framework/Toolbox/OrthancApiClient.cpp Framework/Toolbox/OrthancApiClient.h Framework/Toolbox/OrthancSlicesLoader.cpp Framework/Toolbox/OrthancSlicesLoader.h Framework/Toolbox/ParallelSlices.cpp Framework/Toolbox/ParallelSlices.h Framework/Toolbox/ParallelSlicesCursor.cpp Framework/Toolbox/ParallelSlicesCursor.h Framework/Toolbox/Slice.cpp Framework/Toolbox/Slice.h Framework/Toolbox/ViewportGeometry.cpp Framework/Toolbox/ViewportGeometry.h Framework/Toolbox/VolumeImageGeometry.cpp Framework/Toolbox/VolumeImageGeometry.h Framework/Viewport/CairoContext.cpp Framework/Viewport/CairoContext.h Framework/Viewport/CairoFont.cpp Framework/Viewport/CairoFont.h Framework/Viewport/CairoSurface.cpp Framework/Viewport/CairoSurface.h Framework/Viewport/IMouseTracker.h Framework/Viewport/IStatusBar.h Framework/Viewport/IViewport.h Framework/Viewport/WidgetViewport.cpp Framework/Viewport/WidgetViewport.h Framework/Volumes/ISlicedVolume.h Framework/Volumes/IVolumeLoader.h Framework/Volumes/StructureSetLoader.cpp Framework/Volumes/StructureSetLoader.h Framework/Widgets/CairoWidget.cpp Framework/Widgets/CairoWidget.h Framework/Widgets/EmptyWidget.cpp Framework/Widgets/EmptyWidget.h Framework/Widgets/IWidget.h Framework/Widgets/IWorldSceneInteractor.h Framework/Widgets/IWorldSceneMouseTracker.h Framework/Widgets/LayoutWidget.cpp Framework/Widgets/LayoutWidget.h Framework/Widgets/PanMouseTracker.cpp Framework/Widgets/PanMouseTracker.h Framework/Widgets/PanZoomMouseTracker.cpp Framework/Widgets/PanZoomMouseTracker.h Framework/Widgets/SliceViewerWidget.cpp Framework/Widgets/SliceViewerWidget.h Framework/Widgets/TestCairoWidget.cpp Framework/Widgets/TestCairoWidget.h Framework/Widgets/TestWorldSceneWidget.cpp Framework/Widgets/TestWorldSceneWidget.h Framework/Widgets/WidgetBase.cpp Framework/Widgets/WidgetBase.h Framework/Widgets/WorldSceneWidget.cpp Framework/Widgets/WorldSceneWidget.h Framework/Widgets/ZoomMouseTracker.cpp Framework/Widgets/ZoomMouseTracker.h Framework/dev.h Platforms/Wasm/Defaults.cpp Resources/CMake/OrthancStoneConfiguration.cmake |
diffstat | 16 files changed, 875 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Mon Jun 24 10:31:57 2019 +0200 +++ b/.hgignore Mon Jun 24 14:35:00 2019 +0200 @@ -33,6 +33,7 @@ Resources/CommandTool/protoc-tests/node_modules/ Samples/Sdl/ThirdPartyDownloads/ Samples/Sdl/CMakeLists.txt.orig +Samples/Qt/ThirdPartyDownloads/ Samples/WebAssembly/build/ Samples/WebAssembly/ThirdPartyDownloads/
--- a/Applications/Qt/QCairoWidget.h Mon Jun 24 10:31:57 2019 +0200 +++ b/Applications/Qt/QCairoWidget.h Mon Jun 24 14:35:00 2019 +0200 @@ -21,8 +21,8 @@ #pragma once #include "../../Applications/Generic/NativeStoneApplicationContext.h" -#include "../../Framework/Viewport/CairoSurface.h" -#include "../../Framework/Widgets/IWidget.h" +#include "../../Framework/Wrappers/CairoSurface.h" +#include "../../Framework/Deprecated/Widgets/IWidget.h" #include <QWidget> #include <memory>
--- a/Applications/Qt/QtStoneApplicationRunner.cpp Mon Jun 24 10:31:57 2019 +0200 +++ b/Applications/Qt/QtStoneApplicationRunner.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -27,7 +27,7 @@ #include <boost/program_options.hpp> #include <QApplication> -#include "../../Framework/Toolbox/MessagingToolbox.h" +#include "../../Framework/Deprecated/Toolbox/MessagingToolbox.h" #include <Core/Logging.h> #include <Core/HttpClient.h>
--- a/Framework/Radiography/RadiographySceneReader.cpp Mon Jun 24 10:31:57 2019 +0200 +++ b/Framework/Radiography/RadiographySceneReader.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -60,6 +60,11 @@ if (version != 1) throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + if (input.isMember("hasWindowing") && input["hasWindowing"].asBool()) + { + scene_.SetWindowing(input["windowCenter"].asFloat(), input["windowWidth"].asFloat()); + } + RadiographyDicomLayer* dicomLayer = NULL; for(size_t layerIndex = 0; layerIndex < input["layers"].size(); layerIndex++) { @@ -143,6 +148,11 @@ if (version != 1) throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + if (input.isMember("hasWindowing") && input["hasWindowing"].asBool()) + { + scene_.SetWindowing(input["windowCenter"].asFloat(), input["windowWidth"].asFloat()); + } + RadiographyDicomLayer* dicomLayer = NULL; for(size_t layerIndex = 0; layerIndex < input["layers"].size(); layerIndex++) {
--- a/Framework/Radiography/RadiographySceneWriter.cpp Mon Jun 24 10:31:57 2019 +0200 +++ b/Framework/Radiography/RadiographySceneWriter.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -30,6 +30,14 @@ void RadiographySceneWriter::Write(Json::Value& output, const RadiographyScene& scene) { output["version"] = 1; + float windowCenter, windowWidth; + bool hasWindowing = scene.GetWindowing(windowCenter, windowWidth); + output["hasWindowing"] = hasWindowing; + if (hasWindowing) + { + output["windowCenter"] = windowCenter; + output["windowWidth"] = windowWidth; + } output["layers"] = Json::arrayValue; std::vector<size_t> layersIndexes;
--- a/Platforms/Wasm/Defaults.cpp Mon Jun 24 10:31:57 2019 +0200 +++ b/Platforms/Wasm/Defaults.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -275,7 +275,7 @@ float x2, float y2) { - printf("touch start with %d touches\n", touchCount); + // printf("touch start with %d touches\n", touchCount); std::vector<Deprecated::Touch> touches; GetTouchVector(touches, touchCount, x0, y0, x1, y1, x2, y2); @@ -291,7 +291,7 @@ float x2, float y2) { - printf("touch move with %d touches\n", touchCount); + // printf("touch move with %d touches\n", touchCount); std::vector<Deprecated::Touch> touches; GetTouchVector(touches, touchCount, x0, y0, x1, y1, x2, y2); @@ -307,7 +307,7 @@ float x2, float y2) { - printf("touch end with %d touches remaining\n", touchCount); + // printf("touch end with %d touches remaining\n", touchCount); std::vector<Deprecated::Touch> touches; GetTouchVector(touches, touchCount, x0, y0, x1, y1, x2, y2); @@ -362,14 +362,14 @@ { static std::string output; // we don't want the string to be deallocated when we return to JS code so we always use the same string (this is fine since JS is single-thread) - printf("SendSerializedMessageToStoneApplication\n"); - printf("%s", message); + //printf("SendSerializedMessageToStoneApplication\n"); + //printf("%s", message); if (applicationWasmAdapter.get() != NULL) { applicationWasmAdapter->HandleSerializedMessageFromWeb(output, std::string(message)); return output.c_str(); } - printf("This Stone application does not have a Web Adapter"); + printf("This Stone application does not have a Web Adapter, unable to send messages"); return NULL; }
--- a/Platforms/Wasm/logger.ts Mon Jun 24 10:31:57 2019 +0200 +++ b/Platforms/Wasm/logger.ts Mon Jun 24 14:35:00 2019 +0200 @@ -73,7 +73,7 @@ private getOutput(source: LogSource, args: any[]): any[] { var prefix = this.getPrefix(); - var prefixAndSource = []; + var prefixAndSource = Array<string>(); if (prefix != null) { prefixAndSource = [prefix]; @@ -94,7 +94,7 @@ return [...prefixAndSource, ...args]; } - protected getPrefix(): string { + protected getPrefix(): string | null { return null; } }
--- a/Platforms/Wasm/wasm-application-runner.ts Mon Jun 24 10:31:57 2019 +0200 +++ b/Platforms/Wasm/wasm-application-runner.ts Mon Jun 24 14:35:00 2019 +0200 @@ -1,5 +1,5 @@ -import Stone = require('./stone-framework-loader'); -import StoneViewport = require('./wasm-viewport'); +import * as Stone from './stone-framework-loader' +import * as StoneViewport from './wasm-viewport' import * as Logger from './logger' if (!('WebAssembly' in window)) { @@ -130,11 +130,6 @@ Logger.defaultLogger.debug("Connecting C++ methods to JS methods - done"); - // Prevent scrolling - document.body.addEventListener('touchmove', function (event) { - event.preventDefault(); - }, { passive: false}); // must not be passive if calling event.preventDefault, ie to cancel scroll or zoom of the whole interface - _InitializeWasmApplication(orthancBaseUrl); }); }
--- a/Platforms/Wasm/wasm-viewport.ts Mon Jun 24 10:31:57 2019 +0200 +++ b/Platforms/Wasm/wasm-viewport.ts Mon Jun 24 14:35:00 2019 +0200 @@ -1,4 +1,4 @@ -import wasmApplicationRunner = require('./wasm-application-runner'); +import * as wasmApplicationRunner from './wasm-application-runner' import * as Logger from './logger' var isPendingRedraw = false; @@ -10,14 +10,17 @@ Logger.defaultLogger.debug('Scheduling a refresh of the viewport, as its content changed'); window.requestAnimationFrame(function() { isPendingRedraw = false; - WasmViewport.GetFromCppViewport(cppViewportHandle).Redraw(); + let viewport = WasmViewport.GetFromCppViewport(cppViewportHandle); + if (viewport) { + viewport.Redraw(); + } }); } } (<any>window).ScheduleWebViewportRedraw = ScheduleWebViewportRedraw; -declare function UTF8ToString(any): string; +declare function UTF8ToString(v: any): string; function CreateWasmViewport(htmlCanvasId: string) : any { var cppViewportHandle = wasmApplicationRunner.CreateCppViewport(); @@ -38,7 +41,7 @@ private module_ : any; private canvasId_ : string; private htmlCanvas_ : HTMLCanvasElement; - private context_ : CanvasRenderingContext2D; + private context_ : CanvasRenderingContext2D | null; private imageData_ : any = null; private renderingBuffer_ : any = null; @@ -96,20 +99,20 @@ return this.pimpl_; } - public static GetFromCppViewport(cppViewportHandle: number) : WasmViewport { + public static GetFromCppViewport(cppViewportHandle: number) : WasmViewport | null { if (WasmViewport.viewportsMapByCppHandle_[cppViewportHandle] !== undefined) { return WasmViewport.viewportsMapByCppHandle_[cppViewportHandle]; } Logger.defaultLogger.error("WasmViewport not found !"); - return undefined; + return null; } - public static GetFromCanvasId(canvasId: string) : WasmViewport { + public static GetFromCanvasId(canvasId: string) : WasmViewport | null { if (WasmViewport.viewportsMapByCanvasId_[canvasId] !== undefined) { return WasmViewport.viewportsMapByCanvasId_[canvasId]; } Logger.defaultLogger.error("WasmViewport not found !"); - return undefined; + return null; } public static ResizeAll() { @@ -135,7 +138,9 @@ this.renderingBuffer_, this.imageData_.width * this.imageData_.height * 4)); - this.context_.putImageData(this.imageData_, 0, 0); + if (this.context_) { + this.context_.putImageData(this.imageData_, 0, 0); + } } } @@ -147,25 +152,27 @@ } // width/height is defined by the parent width/height - this.htmlCanvas_.width = this.htmlCanvas_.parentElement.offsetWidth; - this.htmlCanvas_.height = this.htmlCanvas_.parentElement.offsetHeight; + if (this.htmlCanvas_.parentElement) { + this.htmlCanvas_.width = this.htmlCanvas_.parentElement.offsetWidth; + this.htmlCanvas_.height = this.htmlCanvas_.parentElement.offsetHeight; - Logger.defaultLogger.debug("resizing WasmViewport: ", this.htmlCanvas_.width, "x", this.htmlCanvas_.height); + Logger.defaultLogger.debug("resizing WasmViewport: ", this.htmlCanvas_.width, "x", this.htmlCanvas_.height); - if (this.imageData_ === null) { - this.imageData_ = this.context_.getImageData(0, 0, this.htmlCanvas_.width, this.htmlCanvas_.height); - this.ViewportSetSize(this.pimpl_, this.htmlCanvas_.width, this.htmlCanvas_.height); - - if (this.renderingBuffer_ != null) { - this.module_._free(this.renderingBuffer_); + if (this.imageData_ === null && this.context_) { + this.imageData_ = this.context_.getImageData(0, 0, this.htmlCanvas_.width, this.htmlCanvas_.height); + this.ViewportSetSize(this.pimpl_, this.htmlCanvas_.width, this.htmlCanvas_.height); + + if (this.renderingBuffer_ != null) { + this.module_._free(this.renderingBuffer_); + } + + this.renderingBuffer_ = this.module_._malloc(this.imageData_.width * this.imageData_.height * 4); + } else { + this.ViewportSetSize(this.pimpl_, this.htmlCanvas_.width, this.htmlCanvas_.height); } - this.renderingBuffer_ = this.module_._malloc(this.imageData_.width * this.imageData_.height * 4); - } else { - this.ViewportSetSize(this.pimpl_, this.htmlCanvas_.width, this.htmlCanvas_.height); + this.Redraw(); } - - this.Redraw(); } public Initialize() { @@ -211,7 +218,7 @@ }); window.addEventListener('keydown', function(event) { - var keyChar = event.key; + var keyChar: string | null = event.key; var keyCode = event.keyCode if (keyChar.length == 1) { keyCode = 0; // maps to OrthancStone::KeyboardKeys_Generic @@ -328,7 +335,7 @@ this.touchZoom_ = false; } - public GetTouchTranslation(event) { + public GetTouchTranslation(event: any) { var touch = event.targetTouches[0]; return [ touch.pageX, @@ -336,7 +343,7 @@ ]; } - public GetTouchZoom(event) { + public GetTouchZoom(event: any) { var touch1 = event.targetTouches[0]; var touch2 = event.targetTouches[1]; var dx = (touch1.pageX - touch2.pageX);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/BasicScene.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,455 @@ +/** + * 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/>. + **/ + +#define GLEW_STATIC 1 +// From Stone +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include "../../Applications/Sdl/SdlOpenGLWindow.h" +#include "../../Framework/Scene2D/CairoCompositor.h" +#include "../../Framework/Scene2D/ColorTextureSceneLayer.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" +#include "../../Framework/Scene2D/PanSceneTracker.h" +#include "../../Framework/Scene2D/RotateSceneTracker.h" +#include "../../Framework/Scene2D/Scene2D.h" +#include "../../Framework/Scene2D/ZoomSceneTracker.h" +#include "../../Framework/Scene2DViewport/ViewportController.h" + +#include "../../Framework/StoneInitialization.h" +#include "../../Framework/Messages/MessageBroker.h" + +// From Orthanc framework +#include <Core/Logging.h> +#include <Core/OrthancException.h> +#include <Core/Images/Image.h> +#include <Core/Images/ImageProcessing.h> +#include <Core/Images/PngWriter.h> + +#include <boost/make_shared.hpp> +#include <boost/ref.hpp> +#include "EmbeddedResources.h" + +//#include <SDL.h> +#include <stdio.h> +#include <QDebug> +#include <QWindow> + +static const unsigned int FONT_SIZE = 32; +static const int LAYER_POSITION = 150; + +using namespace OrthancStone; + +void PrepareScene(ViewportControllerPtr controller) +{ + Scene2D& scene(*controller->GetScene()); + // Texture of 2x2 size + { + Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); + + uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); + p[0] = 255; + p[1] = 0; + p[2] = 0; + + p[3] = 0; + p[4] = 255; + p[5] = 0; + + p = reinterpret_cast<uint8_t*>(i.GetRow(1)); + p[0] = 0; + p[1] = 0; + p[2] = 255; + + p[3] = 255; + p[4] = 0; + p[5] = 0; + + scene.SetLayer(12, new ColorTextureSceneLayer(i)); + + std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); + l->SetOrigin(-3, 2); + l->SetPixelSpacing(1.5, 1); + l->SetAngle(20.0 / 180.0 * 3.14); + scene.SetLayer(14, l.release()); + } + + // Texture of 1x1 size + { + Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false); + + uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); + p[0] = 255; + p[1] = 0; + p[2] = 0; + + std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); + l->SetOrigin(-2, 1); + l->SetAngle(20.0 / 180.0 * 3.14); + scene.SetLayer(13, l.release()); + } + + // Some lines + { + std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer); + + layer->SetThickness(1); + + 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); + + 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); + + double dy = 1.01; + chain.clear(); + chain.push_back(ScenePoint2D(-4, -4)); + 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->SetColor(0,255, 255); + scene.SetLayer(50, layer.release()); + } + + // Some text + { + std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); + layer->SetText("Hello"); + scene.SetLayer(100, layer.release()); + } +} + + +//void TakeScreenshot(const std::string& target, +// const Scene2D& scene, +// unsigned int canvasWidth, +// unsigned int canvasHeight) +//{ +// // Take a screenshot, then save it as PNG file +// CairoCompositor compositor(scene, canvasWidth, canvasHeight); +// compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); +// compositor.Refresh(); + +// Orthanc::ImageAccessor canvas; +// compositor.GetCanvas().GetReadOnlyAccessor(canvas); + +// Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false); +// Orthanc::ImageProcessing::Convert(png, canvas); + +// Orthanc::PngWriter writer; +// writer.WriteToFile(target, png); +//} + + +//void HandleApplicationEvent(ViewportControllerPtr controller, +// const OpenGLCompositor& compositor, +// const SDL_Event& event, +// FlexiblePointerTrackerPtr& activeTracker) +//{ +// Scene2D& scene(*controller->GetScene()); +// if (event.type == SDL_MOUSEMOTION) +// { +// int scancodeCount = 0; +// const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); + +// if (activeTracker.get() == NULL && +// SDL_SCANCODE_LCTRL < scancodeCount && +// keyboardState[SDL_SCANCODE_LCTRL]) +// { +// // The "left-ctrl" key is down, while no tracker is present + +// PointerEvent e; +// e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + +// ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); + +// char buf[64]; +// sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); + +// if (scene.HasLayer(LAYER_POSITION)) +// { +// TextSceneLayer& layer = +// dynamic_cast<TextSceneLayer&>(scene.GetLayer(LAYER_POSITION)); +// layer.SetText(buf); +// layer.SetPosition(p.GetX(), p.GetY()); +// } +// else +// { +// std::auto_ptr<TextSceneLayer> +// layer(new TextSceneLayer); +// layer->SetColor(0, 255, 0); +// layer->SetText(buf); +// layer->SetBorder(20); +// layer->SetAnchor(BitmapAnchor_BottomCenter); +// layer->SetPosition(p.GetX(), p.GetY()); +// scene.SetLayer(LAYER_POSITION, layer.release()); +// } +// } +// else +// { +// scene.DeleteLayer(LAYER_POSITION); +// } +// } +// else if (event.type == SDL_MOUSEBUTTONDOWN) +// { +// PointerEvent e; +// e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + +// switch (event.button.button) +// { +// case SDL_BUTTON_MIDDLE: +// activeTracker = boost::make_shared<PanSceneTracker>(controller, e); +// break; + +// case SDL_BUTTON_RIGHT: +// activeTracker = boost::make_shared<ZoomSceneTracker>(controller, +// e, compositor.GetCanvasHeight()); +// break; + +// case SDL_BUTTON_LEFT: +// activeTracker = boost::make_shared<RotateSceneTracker>(controller, e); +// break; + +// default: +// break; +// } +// } +// else if (event.type == SDL_KEYDOWN && +// event.key.repeat == 0 /* Ignore key bounce */) +// { +// switch (event.key.keysym.sym) +// { +// case SDLK_s: +// controller->FitContent(compositor.GetCanvasWidth(), +// compositor.GetCanvasHeight()); +// break; + +// case SDLK_c: +// TakeScreenshot("screenshot.png", scene, +// compositor.GetCanvasWidth(), +// compositor.GetCanvasHeight()); +// break; + +// default: +// break; +// } +// } +//} + + +static void GLAPIENTRY OpenGLMessageCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam ) +{ + if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) + { + fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), + type, severity, message ); + } +} + + +//void Run(ViewportControllerPtr controller) +//{ +// SdlOpenGLWindow window("Hello", 1024, 768); + +// controller->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); + +// glEnable(GL_DEBUG_OUTPUT); +// glDebugMessageCallback(OpenGLMessageCallback, 0); + +// OpenGLCompositor compositor(window, *controller->GetScene()); +// compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, +// FONT_SIZE, Orthanc::Encoding_Latin1); + +// FlexiblePointerTrackerPtr tracker; + +// bool stop = false; +// while (!stop) +// { +// compositor.Refresh(); + +// SDL_Event event; +// while (!stop && +// SDL_PollEvent(&event)) +// { +// if (event.type == SDL_QUIT) +// { +// stop = true; +// break; +// } +// else if (event.type == SDL_MOUSEMOTION) +// { +// if (tracker) +// { +// PointerEvent e; +// e.AddPosition(compositor.GetPixelCenterCoordinates( +// event.button.x, event.button.y)); +// tracker->PointerMove(e); +// } +// } +// else if (event.type == SDL_MOUSEBUTTONUP) +// { +// if (tracker) +// { +// PointerEvent e; +// e.AddPosition(compositor.GetPixelCenterCoordinates( +// event.button.x, event.button.y)); +// tracker->PointerUp(e); +// if(!tracker->IsAlive()) +// tracker.reset(); +// } +// } +// else if (event.type == SDL_WINDOWEVENT && +// event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) +// { +// tracker.reset(); +// compositor.UpdateSize(); +// } +// else if (event.type == SDL_KEYDOWN && +// event.key.repeat == 0 /* Ignore key bounce */) +// { +// switch (event.key.keysym.sym) +// { +// case SDLK_f: +// window.GetWindow().ToggleMaximize(); +// break; + +// case SDLK_q: +// stop = true; +// break; + +// default: +// break; +// } +// } + +// HandleApplicationEvent(controller, compositor, event, tracker); +// } + +// SDL_Delay(1); +// } +//} +#include <QApplication> +#include "BasicSceneWindow.h" +int main(int argc, char* argv[]) +{ + { + QGuiApplication a(argc, argv); + + QSurfaceFormat requestedFormat; + requestedFormat.setVersion( 2, 0 ); + + OrthancStone::Samples::BasicSceneWindow window; + //window->setFormat(requestedFormat); + window.setSurfaceType(QWindow::OpenGLSurface); + window.show(); + +// QWindow * window = new QWindow; +// window->setSurfaceType(QWindow::OpenGLSurface); +// window->setFormat( requestedFormat ); + +// window->show(); + + QOpenGLContext * context = new QOpenGLContext; + context->setFormat( requestedFormat ); + context->create(); + context->makeCurrent(&window); + + GLenum err = glewInit(); + if( GLEW_OK != err ){ + qDebug() << "[Error] GLEW failed to initialize. " << (const char*)glewGetErrorString(err); + } + + return a.exec(); + } + + + + + + + + + + + + +// StoneInitialize(); +// Orthanc::Logging::EnableInfoLevel(true); + +// QApplication app(argc, argv); + +// OrthancStone::Samples::BasicSceneWindow window; + +// QSurfaceFormat requestedFormat; +// requestedFormat.setVersion( 3, 3 ); + +// window.show(); + +// QOpenGLContext * context = new QOpenGLContext; +// context->setFormat( requestedFormat ); +// context->create(); + +// GLenum err = glewInit(); +// if( GLEW_OK != err ){ +// qDebug() << "[Error] GLEW failed to initialize. " << (const char*)glewGetErrorString(err); +// } + +// try +// { +// MessageBroker broker; +// ViewportControllerPtr controller = boost::make_shared<ViewportController>( +// boost::ref(broker)); +// PrepareScene(controller); + +// boost::shared_ptr<OpenGLCompositor> compositor(new OpenGLCompositor(window.GetOpenGlWidget(), *controller->GetScene())); + +// compositor->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, +// FONT_SIZE, Orthanc::Encoding_Latin1); + +// window.SetCompositor(compositor); + +// app.exec(); +// } +// catch (Orthanc::OrthancException& e) +// { +// LOG(ERROR) << "EXCEPTION: " << e.What(); +// } + + + +// StoneFinalize(); + +// return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/BasicSceneWindow.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,61 @@ +/** + * 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/>. + **/ +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include "BasicSceneWindow.h" + +/** + * Don't use "ui_MainWindow.h" instead of <ui_MainWindow.h> below, as + * this makes CMake unable to detect when the UI file changes. + **/ +#include <ui_BasicSceneWindow.h> +#include "../../Applications/Samples/SampleApplicationBase.h" + +namespace OrthancStone +{ + namespace Samples + { + + BasicSceneWindow::BasicSceneWindow( + QWidget *parent) : +// QStoneMainWindow(context, parent), + ui_(new Ui::BasicSceneWindow) + //stoneSampleApplication_(stoneSampleApplication) + { + ui_->setupUi(this); + //SetCentralStoneWidget(*ui_->cairoCentralWidget); + } + + BasicSceneWindow::~BasicSceneWindow() + { + delete ui_; + } + + QStoneOpenGlWidget& BasicSceneWindow::GetOpenGlWidget() + { + return *(ui_->centralWidget); + } + + void BasicSceneWindow::SetCompositor(boost::shared_ptr<OrthancStone::OpenGLCompositor> compositor) + { + ui_->centralWidget->SetCompositor(compositor); + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/BasicSceneWindow.h Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,55 @@ +/** + * 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 <QMainWindow> +#include <QStoneOpenGlWidget.h> +// #include "../../Qt/QCairoWidget.h" +// #include "../../Qt/QStoneMainWindow.h" + +namespace Ui +{ + class BasicSceneWindow; +} + +namespace OrthancStone +{ + namespace Samples + { + + //class SampleSingleCanvasApplicationBase; + + class BasicSceneWindow : public QMainWindow + { + Q_OBJECT + + private: + Ui::BasicSceneWindow* ui_; + //SampleSingleCanvasApplicationBase& stoneSampleApplication_; + + public: + explicit BasicSceneWindow(QWidget *parent = 0); + ~BasicSceneWindow(); + + QStoneOpenGlWidget& GetOpenGlWidget(); + + void SetCompositor(boost::shared_ptr<OpenGLCompositor> compositor); + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/BasicSceneWindow.ui Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>BasicSceneWindow</class> + <widget class="QMainWindow" name="BasicSceneWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>634</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>500</width> + <height>300</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>500</width> + <height>300</height> + </size> + </property> + <property name="windowTitle"> + <string>Stone of Orthanc</string> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <widget class="QWidget" name="centralwidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QStoneOpenGlWidget" name="centralWidget"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>500</height> + </size> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>21</height> + </rect> + </property> + <widget class="QMenu" name="menuTest"> + <property name="title"> + <string>Test</string> + </property> + </widget> + <addaction name="menuTest"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <customwidgets> + <customwidget> + <class>QStoneOpenGlWidget</class> + <extends>QStoneOpenGlWidget</extends> + <header location="global">QStoneOpenGlWidget.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/CMakeLists.txt Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,79 @@ +cmake_minimum_required(VERSION 2.8.3) + +##################################################################### +## Configuration of the Orthanc framework +##################################################################### + +# This CMake file defines the "ORTHANC_STONE_VERSION" macro, so it +# must be the first inclusion +include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/Version.cmake) + +if (ORTHANC_STONE_VERSION STREQUAL "mainline") + set(ORTHANC_FRAMEWORK_VERSION "mainline") + set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg") +else() + set(ORTHANC_FRAMEWORK_VERSION "1.5.7") + set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web") +endif() + +set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")") +set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"") +set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"") + + +##################################################################### +## Configuration of the Stone framework +##################################################################### + +include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneParameters.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake) + +DownloadPackage( + "a24b8136b8f3bb93f166baf97d9328de" + "http://orthanc.osimis.io/ThirdPartyDownloads/ubuntu-font-family-0.83.zip" + "${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83") + +set(ORTHANC_STONE_APPLICATION_RESOURCES + UBUNTU_FONT ${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83/Ubuntu-R.ttf + ) + +SET(ENABLE_GOOGLE_TEST OFF) +SET(ENABLE_LOCALE ON) +SET(ENABLE_QT ON) +SET(ENABLE_SDL OFF) +SET(ENABLE_WEB_CLIENT ON) +SET(ORTHANC_SANDBOXED OFF) +LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options) + +include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneConfiguration.cmake) + +##################################################################### +## Build the samples +##################################################################### + +add_library(OrthancStone STATIC + ${ORTHANC_STONE_SOURCES} + ) + +list(APPEND BASIC_SCENE_APPLICATIONS_SOURCES + BasicSceneWindow.cpp + ) + +ORTHANC_QT_WRAP_UI(BASIC_SCENE_APPLICATIONS_SOURCES + BasicSceneWindow.ui + ) + +ORTHANC_QT_WRAP_CPP(BASIC_SCENE_APPLICATIONS_SOURCES + BasicSceneWindow.h + QStoneOpenGlWidget.h + ) + +add_executable(BasicScene + BasicScene.cpp + QStoneOpenGlWidget.cpp + ${BASIC_SCENE_APPLICATIONS_SOURCES} + ) + +target_include_directories(BasicScene PUBLIC ${CMAKE_SOURCE_DIR}) + +target_link_libraries(BasicScene OrthancStone)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/QStoneOpenGlWidget.cpp Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,31 @@ +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include "QStoneOpenGlWidget.h" + +void QStoneOpenGlWidget::initializeGL() +{ + // Set up the rendering context, load shaders and other resources, etc.: + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); +} + +void QStoneOpenGlWidget::resizeGL(int w, int h) +{ + +} + +void QStoneOpenGlWidget::paintGL() +{ + makeCurrent(); + + // // Draw the scene: + // QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + // f->glClear(GL_COLOR_BUFFER_BIT); + // f->glClearColor(1.0f, 0.3f, 0.5f, 1.0f); + + if (compositor_) + { + compositor_->Refresh(); + } + doneCurrent(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Qt/QStoneOpenGlWidget.h Mon Jun 24 14:35:00 2019 +0200 @@ -0,0 +1,45 @@ +#pragma once +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include <QOpenGLWidget> +#include <QOpenGLFunctions> + +#include <boost/shared_ptr.hpp> +#include "../../Framework/OpenGL/IOpenGLContext.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" + + +class QStoneOpenGlWidget : public QOpenGLWidget, public OrthancStone::OpenGL::IOpenGLContext +{ + boost::shared_ptr<OrthancStone::OpenGLCompositor> compositor_; + +public: + QStoneOpenGlWidget(QWidget *parent) : QOpenGLWidget(parent) { } + +protected: + void initializeGL() override; + + void resizeGL(int w, int h) override; + + void paintGL() override; + + virtual void MakeCurrent() override {} + + virtual void SwapBuffer() override {} + + virtual unsigned int GetCanvasWidth() const override + { + return this->width(); + } + + virtual unsigned int GetCanvasHeight() const override + { + return this->height(); + } + +public: + void SetCompositor(boost::shared_ptr<OrthancStone::OpenGLCompositor> compositor) + { + compositor_ = compositor; + } + +};