# HG changeset patch # User Sebastien Jodogne # Date 1496146151 -7200 # Node ID d18dcc963930cc302ddb17f3851e2988946e043e # Parent f8bce1bebe01f887f3da757c70533732fe838c6a separation of the renderers vs. viewport slice diff -r f8bce1bebe01 -r d18dcc963930 Applications/Samples/SingleFrameApplication.h --- a/Applications/Samples/SingleFrameApplication.h Tue May 30 10:30:57 2017 +0200 +++ b/Applications/Samples/SingleFrameApplication.h Tue May 30 14:09:11 2017 +0200 @@ -103,7 +103,22 @@ if (frame.GetSliceCount() > 0) { +#if 1 + GeometryToolbox::Print(frame.GetSlice(0).GetGeometry().GetOrigin()); widget_->SetSlice(frame.GetSlice(0).GetGeometry()); +#else + // TEST for scene extents - Rotate the axes + double a = 15.0 / 180.0 * M_PI; + + Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0); + Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0); + GeometryToolbox::Print(frame.GetSlice(0).GetGeometry().GetOrigin()); + GeometryToolbox::Print(x); + GeometryToolbox::Print(y); + SliceGeometry s(frame.GetSlice(0).GetGeometry().GetOrigin(), x, y); + widget_->SetSlice(s); +#endif + widget_->SetDefaultView(); } } @@ -176,14 +191,18 @@ layer->Register(*this); widget->AddLayer(layer.release()); + RenderStyle s; + if (parameters["smooth"].as()) { - RenderStyle s; s.interpolation_ = ImageInterpolation_Linear; - widget->SetLayerStyle(0, s); } + + //s.drawGrid_ = true; + widget->SetLayerStyle(0, s); #else // 0178023P** + // Extent of the CT layer: (-35.068 -20.368) => (34.932 49.632) std::auto_ptr ct; ct.reset(new OrthancFrameLayerSource(context.GetWebService(), "c804a1a2-142545c9-33b32fe2-3df4cec0-a2bea6d6", 0)); //ct.reset(new OrthancFrameLayerSource(context.GetWebService(), "4bd4304f-47478948-71b24af2-51f4f1bc-275b6c1b", 0)); // BAD SLICE @@ -196,6 +215,7 @@ { RenderStyle s; + //s.drawGrid_ = true; s.alpha_ = 1; widget->SetLayerStyle(0, s); } diff -r f8bce1bebe01 -r d18dcc963930 Framework/Layers/FrameRenderer.cpp --- a/Framework/Layers/FrameRenderer.cpp Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Layers/FrameRenderer.cpp Tue May 30 14:09:11 2017 +0200 @@ -28,54 +28,6 @@ namespace OrthancStone { - static bool ComputePixelTransform(cairo_matrix_t& target, - const SliceGeometry& viewportSlice, - const SliceGeometry& frameSlice, - double pixelSpacingX, - double pixelSpacingY) - { - bool isOpposite; - if (!GeometryToolbox::IsParallelOrOpposite(isOpposite, - viewportSlice.GetNormal(), - frameSlice.GetNormal())) - { - return false; - } - else - { - double x0, y0, x1, y1, x2, y2; - viewportSlice.ProjectPoint(x0, y0, frameSlice.GetOrigin() - - 0.5 * pixelSpacingX * frameSlice.GetAxisX() - - 0.5 * pixelSpacingY * frameSlice.GetAxisY()); - viewportSlice.ProjectPoint(x1, y1, frameSlice.GetOrigin() - + 0.5 * pixelSpacingX * frameSlice.GetAxisX() - - 0.5 * pixelSpacingY * frameSlice.GetAxisY()); - viewportSlice.ProjectPoint(x2, y2, frameSlice.GetOrigin() - - 0.5 * pixelSpacingX * frameSlice.GetAxisX() - + 0.5 * pixelSpacingY * frameSlice.GetAxisY()); - - /** - * Now we solve the system of linear equations Ax + b = x', given: - * A [0 ; 0] + b = [x0 ; y0] - * A [1 ; 0] + b = [x1 ; y1] - * A [0 ; 1] + b = [x2 ; y2] - * <=> - * b = [x0 ; y0] - * A [1 ; 0] = [x1 ; y1] - b = [x1 - x0 ; y1 - y0] - * A [0 ; 1] = [x2 ; y2] - b = [x2 - x0 ; y2 - y0] - * <=> - * b = [x0 ; y0] - * [a11 ; a21] = [x1 - x0 ; y1 - y0] - * [a12 ; a22] = [x2 - x0 ; y2 - y0] - **/ - - cairo_matrix_init(&target, x1 - x0, y1 - y0, x2 - x0, y2 - y0, x0, y0); - - return true; - } - } - - FrameRenderer::FrameRenderer(const SliceGeometry& frameSlice, double pixelSpacingX, double pixelSpacingY, @@ -88,56 +40,8 @@ } - bool FrameRenderer::ComputeFrameExtent(double& x1, - double& y1, - double& x2, - double& y2, - const SliceGeometry& viewportSlice, - const SliceGeometry& frameSlice, - unsigned int frameWidth, - unsigned int frameHeight, - double pixelSpacingX, - double pixelSpacingY) - { - bool isOpposite; - if (!GeometryToolbox::IsParallelOrOpposite(isOpposite, viewportSlice.GetNormal(), frameSlice.GetNormal())) - { - return false; - } - else - { - cairo_matrix_t transform; - if (!ComputePixelTransform(transform, viewportSlice, frameSlice, pixelSpacingX, pixelSpacingY)) - { - return true; - } - - x1 = 0; - y1 = 0; - cairo_matrix_transform_point(&transform, &x1, &y1); - - x2 = frameWidth; - y2 = frameHeight; - cairo_matrix_transform_point(&transform, &x2, &y2); - - if (x1 > x2) - { - std::swap(x1, x2); - } - - if (y1 > y2) - { - std::swap(y1, y2); - } - - return true; - } - } - - bool FrameRenderer::RenderLayer(CairoContext& context, - const ViewportGeometry& view, - const SliceGeometry& viewportSlice) + const ViewportGeometry& view) { if (!style_.visible_) { @@ -146,12 +50,6 @@ if (display_.get() == NULL) { - if (!ComputePixelTransform(transform_, viewportSlice, frameSlice_, - pixelSpacingX_, pixelSpacingY_)) - { - return true; - } - display_.reset(GenerateDisplay(style_)); } @@ -161,7 +59,12 @@ cairo_save(cr); - cairo_transform(cr, &transform_); + cairo_matrix_t transform; + cairo_matrix_init_identity(&transform); + cairo_matrix_scale(&transform, pixelSpacingX_, pixelSpacingY_); + cairo_matrix_translate(&transform, -0.5, -0.5); + cairo_transform(cr, &transform); + //cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_source_surface(cr, display_->GetObject(), 0, 0); @@ -215,30 +118,6 @@ ILayerRenderer* FrameRenderer::CreateRenderer(Orthanc::ImageAccessor* frame, - const SliceGeometry& frameSlice, - const OrthancPlugins::IDicomDataset& dicom, - double pixelSpacingX, - double pixelSpacingY, - bool isFullQuality) - { - std::auto_ptr protect(frame); - - if (frame->GetFormat() == Orthanc::PixelFormat_RGB24) - { - return new ColorFrameRenderer(protect.release(), frameSlice, - pixelSpacingX, pixelSpacingY, isFullQuality); - } - else - { - DicomFrameConverter converter; - converter.ReadParameters(dicom); - return new GrayscaleFrameRenderer(protect.release(), converter, frameSlice, - pixelSpacingX, pixelSpacingY, isFullQuality); - } - } - - - ILayerRenderer* FrameRenderer::CreateRenderer(Orthanc::ImageAccessor* frame, const Slice& frameSlice, bool isFullQuality) { @@ -246,13 +125,18 @@ if (frame->GetFormat() == Orthanc::PixelFormat_RGB24) { - return new ColorFrameRenderer(protect.release(), frameSlice.GetGeometry(), - frameSlice.GetPixelSpacingX(), frameSlice.GetPixelSpacingY(), isFullQuality); + return new ColorFrameRenderer(protect.release(), + frameSlice.GetGeometry(), + frameSlice.GetPixelSpacingX(), + frameSlice.GetPixelSpacingY(), isFullQuality); } else { - return new GrayscaleFrameRenderer(protect.release(), frameSlice.GetConverter(), frameSlice.GetGeometry(), - frameSlice.GetPixelSpacingX(), frameSlice.GetPixelSpacingY(), isFullQuality); + return new GrayscaleFrameRenderer(protect.release(), + frameSlice.GetConverter(), + frameSlice.GetGeometry(), + frameSlice.GetPixelSpacingX(), + frameSlice.GetPixelSpacingY(), isFullQuality); } } } diff -r f8bce1bebe01 -r d18dcc963930 Framework/Layers/FrameRenderer.h --- a/Framework/Layers/FrameRenderer.h Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Layers/FrameRenderer.h Tue May 30 14:09:11 2017 +0200 @@ -35,9 +35,7 @@ double pixelSpacingY_; RenderStyle style_; bool isFullQuality_; - std::auto_ptr display_; - cairo_matrix_t transform_; protected: virtual CairoSurface* GenerateDisplay(const RenderStyle& style) = 0; @@ -48,34 +46,14 @@ double pixelSpacingY, bool isFullQuality); - // TODO Remove this overload - static bool ComputeFrameExtent(double& x1, - double& y1, - double& x2, - double& y2, - const SliceGeometry& viewportSlice, - const SliceGeometry& frameSlice, - unsigned int frameWidth, - unsigned int frameHeight, - double pixelSpacingX, - double pixelSpacingY); + virtual bool RenderLayer(CairoContext& context, + const ViewportGeometry& view); - static bool ComputeFrameExtent(double& x1, - double& y1, - double& x2, - double& y2, - const SliceGeometry& viewportSlice, - const Slice& frame) + virtual const SliceGeometry& GetLayerSlice() { - return ComputeFrameExtent(x1, y1, x2, y2, viewportSlice, - frame.GetGeometry(), frame.GetWidth(), frame.GetHeight(), - frame.GetPixelSpacingX(), frame.GetPixelSpacingY()); + return frameSlice_; } - virtual bool RenderLayer(CairoContext& context, - const ViewportGeometry& view, - const SliceGeometry& viewportSlice); - virtual void SetLayerStyle(const RenderStyle& style); virtual bool IsFullQuality() @@ -83,14 +61,6 @@ return isFullQuality_; } - // TODO Remove this overload - static ILayerRenderer* CreateRenderer(Orthanc::ImageAccessor* frame, - const SliceGeometry& frameSlice, - const OrthancPlugins::IDicomDataset& dicom, - double pixelSpacingX, - double pixelSpacingY, - bool isFullQuality); - static ILayerRenderer* CreateRenderer(Orthanc::ImageAccessor* frame, const Slice& frameSlice, bool isFullQuality); diff -r f8bce1bebe01 -r d18dcc963930 Framework/Layers/ILayerRenderer.h --- a/Framework/Layers/ILayerRenderer.h Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Layers/ILayerRenderer.h Tue May 30 14:09:11 2017 +0200 @@ -36,11 +36,12 @@ } virtual bool RenderLayer(CairoContext& context, - const ViewportGeometry& view, - const SliceGeometry& viewportSlice) = 0; + const ViewportGeometry& view) = 0; virtual void SetLayerStyle(const RenderStyle& style) = 0; + virtual const SliceGeometry& GetLayerSlice() = 0; + virtual bool IsFullQuality() = 0; }; } diff -r f8bce1bebe01 -r d18dcc963930 Framework/Layers/ILayerSource.h --- a/Framework/Layers/ILayerSource.h Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Layers/ILayerSource.h Tue May 30 14:09:11 2017 +0200 @@ -65,10 +65,7 @@ virtual void Register(IObserver& observer) = 0; - virtual bool GetExtent(double& x1, - double& y1, - double& x2, - double& y2, + virtual bool GetExtent(std::vector& points, const SliceGeometry& viewportSlice) = 0; virtual void ScheduleLayerCreation(const SliceGeometry& viewportSlice) = 0; diff -r f8bce1bebe01 -r d18dcc963930 Framework/Layers/OrthancFrameLayerSource.cpp --- a/Framework/Layers/OrthancFrameLayerSource.cpp Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Layers/OrthancFrameLayerSource.cpp Tue May 30 14:09:11 2017 +0200 @@ -77,43 +77,32 @@ } - bool OrthancFrameLayerSource::GetExtent(double& x1, - double& y1, - double& x2, - double& y2, + bool OrthancFrameLayerSource::GetExtent(std::vector& points, const SliceGeometry& viewportSlice) { - bool ok = false; + size_t index; + if (loader_.IsGeometryReady() && + loader_.LookupSlice(index, viewportSlice)) + { + const Slice& slice = loader_.GetSlice(index); + const SliceGeometry& plane = slice.GetGeometry(); - if (loader_.IsGeometryReady()) - { - double tx1, ty1, tx2, ty2; + double sx = slice.GetPixelSpacingX(); + double sy = slice.GetPixelSpacingY(); + double w = static_cast(slice.GetWidth()); + double h = static_cast(slice.GetHeight()); - for (size_t i = 0; i < loader_.GetSliceCount(); i++) - { - if (FrameRenderer::ComputeFrameExtent(tx1, ty1, tx2, ty2, viewportSlice, loader_.GetSlice(i))) - { - if (ok) - { - x1 = std::min(x1, tx1); - y1 = std::min(y1, ty1); - x2 = std::min(x2, tx2); - y2 = std::min(y2, ty2); - } - else - { - // This is the first slice parallel to the viewport - x1 = tx1; - y1 = ty1; - x2 = tx2; - y2 = ty2; - ok = true; - } - } - } + points.clear(); + points.push_back(plane.MapSliceToWorldCoordinates(-0.5 * sx, -0.5 * sy)); + points.push_back(plane.MapSliceToWorldCoordinates((w - 0.5) * sx, -0.5 * sy)); + points.push_back(plane.MapSliceToWorldCoordinates(-0.5 * sx, (h - 0.5) * sy)); + points.push_back(plane.MapSliceToWorldCoordinates((w - 0.5) * sx, (h - 0.5) * sy)); + return true; } - - return ok; + else + { + return false; + } } @@ -125,8 +114,8 @@ { if (loader_.LookupSlice(index, viewportSlice)) { - //loader_.ScheduleLoadSliceImage(index, SliceImageQuality_Full); - loader_.ScheduleLoadSliceImage(index, SliceImageQuality_Jpeg50); + loader_.ScheduleLoadSliceImage(index, SliceImageQuality_Full); + //loader_.ScheduleLoadSliceImage(index, SliceImageQuality_Jpeg50); } else { diff -r f8bce1bebe01 -r d18dcc963930 Framework/Layers/OrthancFrameLayerSource.h --- a/Framework/Layers/OrthancFrameLayerSource.h Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Layers/OrthancFrameLayerSource.h Tue May 30 14:09:11 2017 +0200 @@ -66,11 +66,8 @@ return loader_.GetSlice(slice); } - virtual bool GetExtent(double& x1, - double& y1, - double& x2, - double& y2, - const SliceGeometry& viewportSlice /* ignored */); + virtual bool GetExtent(std::vector& points, + const SliceGeometry& viewportSlice); virtual void ScheduleLayerCreation(const SliceGeometry& viewportSlice); }; diff -r f8bce1bebe01 -r d18dcc963930 Framework/Toolbox/Extent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Toolbox/Extent.cpp Tue May 30 14:09:11 2017 +0200 @@ -0,0 +1,86 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017 Osimis, 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 . + **/ + + +#include "Extent.h" + +#include +#include + +namespace OrthancStone +{ + void Extent::Reset() + { + empty_ = true; + x1_ = 0; + y1_ = 0; + x2_ = 0; + y2_ = 0; + } + + void Extent::AddPoint(double x, + double y) + { + if (empty_) + { + x1_ = x; + y1_ = y; + x2_ = x; + y2_ = y; + empty_ = false; + } + else + { + x1_ = std::min(x1_, x); + y1_ = std::min(y1_, y); + x2_ = std::max(x2_, x); + y2_ = std::max(y2_, y); + } + + assert(x1_ <= x2_ && + y1_ <= y2_); // This is the invariant of the structure + } + + + void Extent::Union(const Extent& other) + { + if (other.IsEmpty()) + { + return; + } + + if (IsEmpty()) + { + *this = other; + return; + } + + assert(!IsEmpty()); + + x1_ = std::min(x1_, other.x1_); + y1_ = std::min(y1_, other.y1_); + x2_ = std::min(x2_, other.x2_); + y2_ = std::min(y2_, other.y2_); + + assert(x1_ <= x2_ && + y1_ <= y2_); // This is the invariant of the structure + } + +} diff -r f8bce1bebe01 -r d18dcc963930 Framework/Toolbox/Extent.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Toolbox/Extent.h Tue May 30 14:09:11 2017 +0200 @@ -0,0 +1,83 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017 Osimis, 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 . + **/ + + +#pragma once + +namespace OrthancStone +{ + class Extent + { + private: + bool empty_; + double x1_; + double y1_; + double x2_; + double y2_; + + public: + Extent() + { + Reset(); + } + + void Reset(); + + void AddPoint(double x, + double y); + + void Union(const Extent& other); + + bool IsEmpty() const + { + return empty_; + } + + double GetX1() const + { + return x1_; + } + + double GetY1() const + { + return y1_; + } + + double GetX2() const + { + return x2_; + } + + double GetY2() const + { + return y2_; + } + + double GetWidth() const + { + return x2_ - x1_; + } + + double GetHeight() const + { + return y2_ - y1_; + } + }; +} diff -r f8bce1bebe01 -r d18dcc963930 Framework/Toolbox/OrthancSlicesLoader.cpp --- a/Framework/Toolbox/OrthancSlicesLoader.cpp Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Toolbox/OrthancSlicesLoader.cpp Tue May 30 14:09:11 2017 +0200 @@ -176,6 +176,7 @@ switch (operation->GetMode()) { + case Mode_InstanceGeometry: case Mode_SeriesGeometry: that_.userCallback_.NotifyGeometryError(that_); that_.state_ = State_Error; diff -r f8bce1bebe01 -r d18dcc963930 Framework/Widgets/LayerWidget.cpp --- a/Framework/Widgets/LayerWidget.cpp Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Widgets/LayerWidget.cpp Tue May 30 14:09:11 2017 +0200 @@ -105,16 +105,51 @@ } bool RenderScene(CairoContext& context, - const ViewportGeometry& view) + const ViewportGeometry& view, + const SliceGeometry& viewportSlice) { bool fullQuality = true; + cairo_t *cr = context.GetObject(); for (size_t i = 0; i < renderers_.size(); i++) { - if (renderers_[i] != NULL && - !renderers_[i]->RenderLayer(context, view, slice_)) + if (renderers_[i] != NULL) { - return false; + const SliceGeometry& frameSlice = renderers_[i]->GetLayerSlice(); + + double x0, y0, x1, y1, x2, y2; + viewportSlice.ProjectPoint(x0, y0, frameSlice.GetOrigin()); + viewportSlice.ProjectPoint(x1, y1, frameSlice.GetOrigin() + frameSlice.GetAxisX()); + viewportSlice.ProjectPoint(x2, y2, frameSlice.GetOrigin() + frameSlice.GetAxisY()); + + /** + * Now we solve the system of linear equations Ax + b = x', given: + * A [0 ; 0] + b = [x0 ; y0] + * A [1 ; 0] + b = [x1 ; y1] + * A [0 ; 1] + b = [x2 ; y2] + * <=> + * b = [x0 ; y0] + * A [1 ; 0] = [x1 ; y1] - b = [x1 - x0 ; y1 - y0] + * A [0 ; 1] = [x2 ; y2] - b = [x2 - x0 ; y2 - y0] + * <=> + * b = [x0 ; y0] + * [a11 ; a21] = [x1 - x0 ; y1 - y0] + * [a12 ; a22] = [x2 - x0 ; y2 - y0] + **/ + + cairo_matrix_t transform; + cairo_matrix_init(&transform, x1 - x0, y1 - y0, x2 - x0, y2 - y0, x0, y0); + + cairo_save(cr); + cairo_transform(cr, &transform); + + if (!renderers_[i]->RenderLayer(context, view)) + { + cairo_restore(cr); + return false; + } + + cairo_restore(cr); } if (renderers_[i] != NULL && @@ -129,7 +164,6 @@ double x, y; view.MapDisplayToScene(x, y, static_cast(view.GetDisplayWidth()) / 2.0, 10); - cairo_t *cr = context.GetObject(); cairo_translate(cr, x, y); #if 1 @@ -180,29 +214,20 @@ } - bool LayerWidget::GetAndFixExtent(double& x1, - double& y1, - double& x2, - double& y2, - ILayerSource& source) const + void LayerWidget::GetLayerExtent(Extent& extent, + ILayerSource& source) const { - if (source.GetExtent(x1, y1, x2, y2, slice_)) + extent.Reset(); + + std::vector points; + if (source.GetExtent(points, slice_)) { - if (x1 > x2) + for (size_t i = 0; i < points.size(); i++) { - std::swap(x1, x2); + double x, y; + slice_.ProjectPoint(x, y, points[i]); + extent.AddPoint(x, y); } - - if (y1 > y2) - { - std::swap(y1, y2); - } - - return true; - } - else - { - return false; } } @@ -212,37 +237,20 @@ double& x2, double& y2) { - bool first = true; + Extent sceneExtent; for (size_t i = 0; i < layers_.size(); i++) { double ax, ay, bx, by; assert(layers_[i] != NULL); - if (GetAndFixExtent(ax, ay, bx, by, *layers_[i])) - { - LOG(INFO) << "Extent of layer " << i << ": (" << ax << "," << ay - << ")->(" << bx << "," << by << ")"; + Extent layerExtent; + GetLayerExtent(layerExtent, *layers_[i]); - if (first) - { - x1 = ax; - y1 = ay; - x2 = bx; - y2 = by; - first = false; - } - else - { - x1 = std::min(x1, ax); - y1 = std::min(y1, ay); - x2 = std::max(x2, bx); - y2 = std::max(y2, by); - } - } + sceneExtent.Union(layerExtent); } - if (first) + if (sceneExtent.IsEmpty()) { // Set a default extent of (-1,-1) -> (0,0) x1 = -1; @@ -250,20 +258,27 @@ x2 = 1; y2 = 1; } - - // Ensure the extent is non-empty - if (x1 >= x2) + else { - double tmp = x1; - x1 = tmp - 0.5; - x2 = tmp + 0.5; - } + x1 = sceneExtent.GetX1(); + y1 = sceneExtent.GetY1(); + x2 = sceneExtent.GetX2(); + y2 = sceneExtent.GetY2(); - if (y1 >= y2) - { - double tmp = y1; - y1 = tmp - 0.5; - y2 = tmp + 0.5; + // Ensure the extent is non-empty + if (x1 >= x2) + { + double tmp = x1; + x1 = tmp - 0.5; + x2 = tmp + 0.5; + } + + if (y1 >= y2) + { + double tmp = y1; + y1 = tmp - 0.5; + y2 = tmp + 0.5; + } } } @@ -273,7 +288,7 @@ { if (currentScene_.get() != NULL) { - return currentScene_->RenderScene(context, view); + return currentScene_->RenderScene(context, view, slice_); } else { @@ -399,7 +414,7 @@ Slice displayedSlice(slice_, THIN_SLICE_THICKNESS); - if (!displayedSlice.ContainsPlane(slice)) + //if (!displayedSlice.ContainsPlane(slice)) { if (currentScene_.get() == NULL || (pendingScene_.get() != NULL && diff -r f8bce1bebe01 -r d18dcc963930 Framework/Widgets/LayerWidget.h --- a/Framework/Widgets/LayerWidget.h Tue May 30 10:30:57 2017 +0200 +++ b/Framework/Widgets/LayerWidget.h Tue May 30 14:09:11 2017 +0200 @@ -23,6 +23,7 @@ #include "WorldSceneWidget.h" #include "../Layers/ILayerSource.h" +#include "../Toolbox/Extent.h" #include @@ -49,11 +50,8 @@ bool LookupLayer(size_t& index /* out */, const ILayerSource& layer) const; - bool GetAndFixExtent(double& x1, - double& y1, - double& x2, - double& y2, - ILayerSource& source) const; + void GetLayerExtent(Extent& extent, + ILayerSource& source) const; virtual void NotifyGeometryReady(const ILayerSource& source); diff -r f8bce1bebe01 -r d18dcc963930 Resources/CMake/OrthancStone.cmake --- a/Resources/CMake/OrthancStone.cmake Tue May 30 10:30:57 2017 +0200 +++ b/Resources/CMake/OrthancStone.cmake Tue May 30 14:09:11 2017 +0200 @@ -188,22 +188,27 @@ ${ORTHANC_STONE_DIR}/Applications/Sdl/SdlSurface.cpp ${ORTHANC_STONE_DIR}/Applications/Sdl/SdlWindow.cpp + #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImage.cpp + #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImagePolicyBase.cpp + #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImageProgressivePolicy.cpp + #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImageSimplePolicy.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/CircleMeasureTracker.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/ColorFrameRenderer.cpp - ${ORTHANC_STONE_DIR}/Framework/Layers/DicomStructureSetRendererFactory.cpp + #${ORTHANC_STONE_DIR}/Framework/Layers/DicomStructureSetRendererFactory.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/FrameRenderer.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/GrayscaleFrameRenderer.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/LayerSourceBase.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/LineLayerRenderer.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/LineMeasureTracker.cpp + ${ORTHANC_STONE_DIR}/Framework/Layers/OrthancFrameLayerSource.cpp ${ORTHANC_STONE_DIR}/Framework/Layers/RenderStyle.cpp - ${ORTHANC_STONE_DIR}/Framework/Layers/SeriesFrameRendererFactory.cpp - ${ORTHANC_STONE_DIR}/Framework/Layers/SiblingSliceLocationFactory.cpp - ${ORTHANC_STONE_DIR}/Framework/Layers/SingleFrameRendererFactory.cpp - ${ORTHANC_STONE_DIR}/Framework/Layers/OrthancFrameLayerSource.cpp + #${ORTHANC_STONE_DIR}/Framework/Layers/SeriesFrameRendererFactory.cpp + #${ORTHANC_STONE_DIR}/Framework/Layers/SiblingSliceLocationFactory.cpp + #${ORTHANC_STONE_DIR}/Framework/Layers/SingleFrameRendererFactory.cpp ${ORTHANC_STONE_DIR}/Framework/Toolbox/DicomFrameConverter.cpp ${ORTHANC_STONE_DIR}/Framework/Toolbox/DicomStructureSet.cpp ${ORTHANC_STONE_DIR}/Framework/Toolbox/DownloadStack.cpp + ${ORTHANC_STONE_DIR}/Framework/Toolbox/Extent.cpp ${ORTHANC_STONE_DIR}/Framework/Toolbox/GeometryToolbox.cpp ${ORTHANC_STONE_DIR}/Framework/Toolbox/MessagingToolbox.cpp ${ORTHANC_STONE_DIR}/Framework/Toolbox/OrthancSeriesLoader.cpp @@ -220,18 +225,14 @@ ${ORTHANC_STONE_DIR}/Framework/Viewport/WidgetViewport.cpp ${ORTHANC_STONE_DIR}/Framework/Volumes/ImageBuffer3D.cpp ${ORTHANC_STONE_DIR}/Framework/Volumes/SlicedVolumeBase.cpp - #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImage.cpp - #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImagePolicyBase.cpp - #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImageProgressivePolicy.cpp - #${ORTHANC_STONE_DIR}/Framework/Volumes/VolumeImageSimplePolicy.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/CairoWidget.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/EmptyWidget.cpp - ${ORTHANC_STONE_DIR}/Framework/Widgets/LayeredSceneWidget.cpp + ${ORTHANC_STONE_DIR}/Framework/Widgets/LayerWidget.cpp + #${ORTHANC_STONE_DIR}/Framework/Widgets/LayeredSceneWidget.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/LayoutWidget.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/TestCairoWidget.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/TestWorldSceneWidget.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/WidgetBase.cpp - ${ORTHANC_STONE_DIR}/Framework/Widgets/LayerWidget.cpp ${ORTHANC_STONE_DIR}/Framework/Widgets/WorldSceneWidget.cpp ${PLATFORM_SOURCES}