From 13fbfb913fb8f0d42044f8fcfef1a6ee5d61256a Mon Sep 17 00:00:00 2001 From: Rostislav Khlebnikov Date: Wed, 19 Aug 2015 17:46:24 +0100 Subject: [PATCH 2/2] Own implementation of interval arithmetic needed. Signed-off-by: Rostislav Khlebnikov --- .../Rendering/mitkPlaneGeometryDataMapper2D.cpp | 107 +++++++++++++++++++-- 1 file changed, 100 insertions(+), 7 deletions(-) diff --git a/Modules/Core/src/Rendering/mitkPlaneGeometryDataMapper2D.cpp b/Modules/Core/src/Rendering/mitkPlaneGeometryDataMapper2D.cpp index 3b8c128..f776b98 100644 --- a/Modules/Core/src/Rendering/mitkPlaneGeometryDataMapper2D.cpp +++ b/Modules/Core/src/Rendering/mitkPlaneGeometryDataMapper2D.cpp @@ -40,8 +40,102 @@ See LICENSE.txt or http://www.mitk.org for details. #include #include -#include -#include +/// +#include +#include +#include +#include + +/// Some simple interval arithmetic +template +class SimpleInterval { +public: + SimpleInterval(T start = T(), T end = T()) + : _start{std::min(start, end)} + , _end{std::max(start, end)} + { + + } + + T start() const { return _start; } + T end() const { return _end; } + + bool empty() const { return _start == _end; } + + bool operator<(const SimpleInterval& r) const + { + return _end < r._start; + } + +private: + T _start, _end; +}; + +template +class IntervalSet { +public: + using IntervalType = SimpleInterval; + + IntervalSet(IntervalType startingInterval) + { + _intervals.emplace(std::move(startingInterval)); + } + + void operator-=(const IntervalType& interval) + { + // Check the intervals for intersection + auto range = _intervals.equal_range(interval); + + for (auto iter = range.first; iter != range.second;) { + auto intersectionResult = _intersectIntervals(*iter, interval); + + iter = _intervals.erase(iter); + for (auto&& interval : intersectionResult) { + if (!interval.empty()) { + iter = _intervals.emplace_hint(iter, std::move(interval)); + ++iter; + } + } + } + } + + IntervalSet operator-(const IntervalType& interval) + { + IntervalSet result = *this; + result -= interval; + return result; + } + + using IntervalsContainer = std::set; + + const IntervalsContainer& getIntervals() const + { + return _intervals; + } + +private: + IntervalsContainer _intervals; + + std::array _intersectIntervals(const IntervalType& from, const IntervalType& what) + { + assert(what.end() >= from.start() && from.end() >= what.start()); // Non-intersecting intervals should never reach here + + if (what.start() < from.start()) { + if (from.end() < what.end()) { + return {}; // Interval completely enclosed + } + return {IntervalType{from.end(), what.end()}, IntervalType{}}; + } + + if (from.end() < what.end()) { + return {IntervalType{from.start(), what.start()}, IntervalType{}}; + } + + return {IntervalType{from.start(), what.start()}, + IntervalType{what.end(), from.end()}}; + } +}; + mitk::PlaneGeometryDataMapper2D::AllInstancesContainer mitk::PlaneGeometryDataMapper2D::s_AllInstances; @@ -213,8 +307,7 @@ void mitk::PlaneGeometryDataMapper2D::CreateVtkCrosshair(mitk::BaseRenderer *ren this->GetDataNode()->GetPropertyValue("Crosshair.Gap Size", gapsize, NULL); - boost::icl::interval_set intervals; - intervals += boost::icl::interval::closed(0, 1); + auto intervals = IntervalSet{{0, 1}}; ScalarType lineLength = point1.EuclideanDistanceTo(point2); DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); @@ -240,14 +333,14 @@ void mitk::PlaneGeometryDataMapper2D::CreateVtkCrosshair(mitk::BaseRenderer *ren { double intersectionParam; if (otherPlane->IntersectionPointParam(crossLine, intersectionParam) && intersectionParam > 0 && intersectionParam < 1) { - intervals -= boost::icl::interval::open(intersectionParam - gapSizeParam, intersectionParam + gapSizeParam); + intervals -= SimpleInterval{intersectionParam - gapSizeParam, intersectionParam + gapSizeParam}; } } ++otherPlanesIt; } - for (const auto& interval : intervals) { - this->DrawLine(crossLine.GetPoint(interval.lower()), crossLine.GetPoint(interval.upper()), lines, points); + for (const auto& interval : intervals.getIntervals()) { + this->DrawLine(crossLine.GetPoint(interval.start()), crossLine.GetPoint(interval.end()), lines, points); } // Add the points to the dataset -- 1.8.4.msysgit.0