From 53907a9cfee63abf99940bbffe5f1785d151e843 Mon Sep 17 00:00:00 2001 From: bubnikv <bubnikv@gmail.com> Date: Tue, 18 Oct 2016 16:44:05 +0200 Subject: [PATCH] Fix of a crash when setting a viewport over an empty platter. Exported bounding box 'empty' method to perl. --- lib/Slic3r/GUI/3DScene.pm | 21 ++++++++++++--------- xs/src/libslic3r/BoundingBox.hpp | 4 ++-- xs/src/libslic3r/libslic3r.h | 1 + xs/xsp/BoundingBox.xsp | 3 +++ 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index d72679b3e..2a39bc875 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -354,15 +354,18 @@ sub select_view { $dirvec = VIEW_REAR; } } - $self->_sphi($dirvec->[0]); - $self->_stheta($dirvec->[1]); - # Avoid gimball lock. - $self->_stheta(150) if $self->_stheta > 150; - $self->_stheta(0) if $self->_stheta < 0; - # View everything. - $self->zoom_to_volumes; - $self->on_viewport_changed->() if $self->on_viewport_changed; - $self->Refresh; + my $bb = $self->volumes_bounding_box; + if (! $bb->empty) { + $self->_sphi($dirvec->[0]); + $self->_stheta($dirvec->[1]); + # Avoid gimball lock. + $self->_stheta(150) if $self->_stheta > 150; + $self->_stheta(0) if $self->_stheta < 0; + # View everything. + $self->zoom_to_bounding_box($bb); + $self->on_viewport_changed->() if $self->on_viewport_changed; + $self->Refresh; + } } sub zoom_to_bounding_box { diff --git a/xs/src/libslic3r/BoundingBox.hpp b/xs/src/libslic3r/BoundingBox.hpp index 7746515cb..21c2e384e 100644 --- a/xs/src/libslic3r/BoundingBox.hpp +++ b/xs/src/libslic3r/BoundingBox.hpp @@ -102,13 +102,13 @@ inline bool operator!=(const BoundingBoxBase<VT> &bb1, const BoundingBoxBase<VT> template<typename VT> inline bool empty(const BoundingBoxBase<VT> &bb) { - return bb.min.x > bb.max.x || bb.min.y > bb.max.y; + return ! bb.defined || bb.min.x > bb.max.x || bb.min.y > bb.max.y; } template<typename VT> inline bool empty(const BoundingBox3Base<VT> &bb) { - return bb.min.x > bb.max.x || bb.min.y > bb.max.y || bb.min.z > bb.max.z; + return ! bb.defined || bb.min.x > bb.max.x || bb.min.y > bb.max.y || bb.min.z > bb.max.z; } } // namespace Slic3r diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index e92124536..fb37afcd0 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -17,6 +17,7 @@ // Scaling factor for a conversion from coord_t to coordf_t: 10e-6 // This scaling generates a following fixed point representation with for a 32bit integer: // 0..4294mm with 1nm resolution +// int32_t fits an interval of (-2147.48mm, +2147.48mm) #define SCALING_FACTOR 0.000001 // RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm. #define RESOLUTION 0.0125 diff --git a/xs/xsp/BoundingBox.xsp b/xs/xsp/BoundingBox.xsp index efb5dea3b..fd07713f2 100644 --- a/xs/xsp/BoundingBox.xsp +++ b/xs/xsp/BoundingBox.xsp @@ -21,6 +21,7 @@ Clone<Polygon> polygon(); Clone<Point> size(); Clone<Point> center(); + bool empty() %code{% RETVAL = empty(*THIS); %}; double radius(); Clone<Point> min_point() %code{% RETVAL = THIS->min; %}; Clone<Point> max_point() %code{% RETVAL = THIS->max; %}; @@ -56,6 +57,7 @@ new_from_points(CLASS, points) Clone<Pointf> size(); Clone<Pointf> center(); double radius(); + bool empty() %code{% RETVAL = empty(*THIS); %}; Clone<Pointf> min_point() %code{% RETVAL = THIS->min; %}; Clone<Pointf> max_point() %code{% RETVAL = THIS->max; %}; double x_min() %code{% RETVAL = THIS->min.x; %}; @@ -94,6 +96,7 @@ new_from_points(CLASS, points) Clone<Pointf3> size(); Clone<Pointf3> center(); double radius(); + bool empty() %code{% RETVAL = empty(*THIS); %}; Clone<Pointf3> min_point() %code{% RETVAL = THIS->min; %}; Clone<Pointf3> max_point() %code{% RETVAL = THIS->max; %}; double x_min() %code{% RETVAL = THIS->min.x; %};