Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/slic3r')
-rw-r--r--src/slic3r/GUI/3DBed.cpp179
-rw-r--r--src/slic3r/GUI/3DBed.hpp82
-rw-r--r--src/slic3r/GUI/3DScene.cpp181
-rw-r--r--src/slic3r/GUI/3DScene.hpp38
-rw-r--r--src/slic3r/GUI/BackgroundSlicingProcess.hpp4
-rw-r--r--src/slic3r/GUI/BedShapeDialog.cpp269
-rw-r--r--src/slic3r/GUI/BedShapeDialog.hpp40
-rw-r--r--src/slic3r/GUI/GCodeViewer.cpp99
-rw-r--r--src/slic3r/GUI/GCodeViewer.hpp14
-rw-r--r--src/slic3r/GUI/GLCanvas3D.cpp205
-rw-r--r--src/slic3r/GUI/GLCanvas3D.hpp40
-rw-r--r--src/slic3r/GUI/GUI_App.cpp5
-rw-r--r--src/slic3r/GUI/GUI_App.hpp1
-rw-r--r--src/slic3r/GUI/GUI_ObjectList.cpp9
-rw-r--r--src/slic3r/GUI/GUI_Preview.cpp18
-rw-r--r--src/slic3r/GUI/GUI_Preview.hpp12
-rw-r--r--src/slic3r/GUI/GalleryDialog.cpp6
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp1
-rw-r--r--src/slic3r/GUI/Jobs/ArrangeJob.cpp3
-rw-r--r--src/slic3r/GUI/MainFrame.cpp2
-rw-r--r--src/slic3r/GUI/Plater.cpp83
-rw-r--r--src/slic3r/GUI/Plater.hpp12
22 files changed, 334 insertions, 969 deletions
diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp
index ee2fb2e69..9a2107911 100644
--- a/src/slic3r/GUI/3DBed.cpp
+++ b/src/slic3r/GUI/3DBed.cpp
@@ -137,7 +137,7 @@ void Bed3D::Axes::render() const
glsafe(::glDisable(GL_DEPTH_TEST));
}
-bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
+bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
{
auto check_texture = [](const std::string& texture) {
boost::system::error_code ec; // so the exists call does not throw (e.g. after a permission problem)
@@ -149,17 +149,13 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c
return !model.empty() && boost::algorithm::iends_with(model, ".stl") && boost::filesystem::exists(model, ec);
};
- EType type;
+ Type type;
std::string model;
std::string texture;
if (force_as_custom)
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- type = EType::Custom;
-#else
- type = Custom;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ type = Type::Custom;
else {
- auto [new_type, system_model, system_texture] = detect_type(shape);
+ auto [new_type, system_model, system_texture] = detect_type(bed_shape);
type = new_type;
model = system_model;
texture = system_texture;
@@ -177,29 +173,18 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c
model_filename.clear();
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- EShapeType shape_type = detect_shape_type(shape);
- if (m_shape == shape && m_type == type && m_shape_type == shape_type && m_texture_filename == texture_filename && m_model_filename == model_filename)
-#else
- if (m_shape == shape && m_type == type && m_texture_filename == texture_filename && m_model_filename == model_filename)
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+
+ if (m_build_volume.bed_shape() == bed_shape && m_type == type && m_texture_filename == texture_filename && m_model_filename == model_filename)
// No change, no need to update the UI.
return false;
- m_shape = shape;
+ m_type = type;
+ m_build_volume = BuildVolume { bed_shape, max_print_height };
m_texture_filename = texture_filename;
m_model_filename = model_filename;
- m_type = type;
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- m_shape_type = shape_type;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ m_extended_bounding_box = this->calc_extended_bounding_box();
- calc_bounding_boxes();
-
- ExPolygon poly;
- for (const Vec2d& p : m_shape) {
- poly.contour.append({ scale_(p(0)), scale_(p(1)) });
- }
+ ExPolygon poly{ Polygon::new_scale(bed_shape) };
calc_triangles(poly);
@@ -208,13 +193,13 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c
m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5))[0];
- reset();
+ this->release_VBOs();
m_texture.reset();
m_model.reset();
// Set the origin and size for rendering the coordinate system axes.
m_axes.set_origin({ 0.0, 0.0, static_cast<double>(GROUND_Z) });
- m_axes.set_stem_length(0.1f * static_cast<float>(m_bounding_box.max_size()));
+ m_axes.set_stem_length(0.1f * static_cast<float>(m_build_volume.bounding_volume().max_size()));
// Let the calee to update the UI.
return true;
@@ -240,85 +225,6 @@ void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_fact
render_internal(canvas, bottom, scale_factor, false, false, true);
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-bool Bed3D::is_rectangle(const Pointfs& shape, Vec2d* min, Vec2d* max)
-{
- const Lines lines = Polygon::new_scale(shape).lines();
- bool ret = lines.size() == 4 && lines[0].parallel_to(lines[2]) && lines[1].parallel_to(lines[3]) && lines[0].perpendicular_to(lines[1]);
- if (ret) {
- if (min != nullptr) {
- *min = shape.front();
- for (const Vec2d& pt : shape) {
- min->x() = std::min(min->x(), pt.x());
- min->y() = std::min(min->y(), pt.y());
- }
- }
- if (max != nullptr) {
- *max = shape.front();
- for (const Vec2d& pt : shape) {
- max->x() = std::max(max->x(), pt.x());
- max->y() = std::max(max->y(), pt.y());
- }
- }
- }
- return ret;
-}
-
-bool Bed3D::is_circle(const Pointfs& shape, Vec2d* center, double* radius)
-{
- if (shape.size() < 3)
- return false;
-
- // Analyze the array of points.
- // Do they reside on a circle ?
- const Vec2d box_center = Geometry::circle_center_taubin_newton(shape);
-
- std::vector<double> vertex_distances;
- double avg_dist = 0.0;
- for (const Vec2d& pt : shape) {
- double distance = (pt - box_center).norm();
- vertex_distances.push_back(distance);
- avg_dist += distance;
- }
-
- avg_dist /= vertex_distances.size();
-
- double tolerance = avg_dist * 0.01;
-
- bool defined_value = true;
- for (double el : vertex_distances) {
- if (fabs(el - avg_dist) > tolerance)
- defined_value = false;
- break;
- }
-
- if (center != nullptr)
- *center = box_center;
-
- if (radius != nullptr)
- *radius = avg_dist;
-
- return defined_value;
-}
-
-bool Bed3D::is_convex(const Pointfs& shape)
-{
- return Polygon::new_scale(shape).convex_points().size() == shape.size();
-}
-
-Bed3D::EShapeType Bed3D::detect_shape_type(const Pointfs& shape)
-{
- if (shape.size() < 3)
- return EShapeType::Invalid;
- else if (is_rectangle(shape))
- return EShapeType::Rectangle;
- else if (is_circle(shape))
- return EShapeType::Circle;
- else
- return EShapeType::Custom;
-}
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking)
{
@@ -334,41 +240,31 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
switch (m_type)
{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- case EType::System: { render_system(canvas, bottom, show_texture); break; }
+ case Type::System: { render_system(canvas, bottom, show_texture); break; }
default:
- case EType::Custom: { render_custom(canvas, bottom, show_texture, picking); break; }
-#else
- case System: { render_system(canvas, bottom, show_texture); break; }
- default:
- case Custom: { render_custom(canvas, bottom, show_texture, picking); break; }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ case Type::Custom: { render_custom(canvas, bottom, show_texture, picking); break; }
}
glsafe(::glDisable(GL_DEPTH_TEST));
}
-void Bed3D::calc_bounding_boxes() const
+// Calculate an extended bounding box from axes and current model for visualization purposes.
+BoundingBoxf3 Bed3D::calc_extended_bounding_box() const
{
- BoundingBoxf3* bounding_box = const_cast<BoundingBoxf3*>(&m_bounding_box);
- *bounding_box = BoundingBoxf3();
- for (const Vec2d& p : m_shape) {
- bounding_box->merge({ p.x(), p.y(), 0.0 });
- }
-
- BoundingBoxf3* extended_bounding_box = const_cast<BoundingBoxf3*>(&m_extended_bounding_box);
- *extended_bounding_box = m_bounding_box;
-
+ BoundingBoxf3 out { m_build_volume.bounding_volume() };
+ // Reset the build volume Z, we don't want to zoom to the top of the build volume if it is empty.
+ out.min.z() = 0;
+ out.max.z() = 0;
// extend to contain axes
- extended_bounding_box->merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
- extended_bounding_box->merge(extended_bounding_box->min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, extended_bounding_box->max(2)));
-
+ out.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
+ out.merge(out.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, out.max(2)));
// extend to contain model, if any
BoundingBoxf3 model_bb = m_model.get_bounding_box();
if (model_bb.defined) {
model_bb.translate(m_model_offset);
- extended_bounding_box->merge(model_bb);
+ out.merge(model_bb);
}
+ return out;
}
void Bed3D::calc_triangles(const ExPolygon& poly)
@@ -404,8 +300,9 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n";
}
-
-std::tuple<Bed3D::EType, std::string, std::string> Bed3D::detect_type(const Pointfs& shape) const
+// Try to match the print bed shape with the shape of an active profile. If such a match exists,
+// return the print bed model.
+std::tuple<Bed3D::Type, std::string, std::string> Bed3D::detect_type(const Pointfs& shape)
{
auto bundle = wxGetApp().preset_bundle;
if (bundle != nullptr) {
@@ -416,11 +313,7 @@ std::tuple<Bed3D::EType, std::string, std::string> Bed3D::detect_type(const Poin
std::string model_filename = PresetUtils::system_printer_bed_model(*curr);
std::string texture_filename = PresetUtils::system_printer_bed_texture(*curr);
if (!model_filename.empty() && !texture_filename.empty())
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- return { EType::System, model_filename, texture_filename };
-#else
- return { System, model_filename, texture_filename };
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ return { Type::System, model_filename, texture_filename };
}
}
@@ -428,16 +321,12 @@ std::tuple<Bed3D::EType, std::string, std::string> Bed3D::detect_type(const Poin
}
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- return { EType::Custom, "", "" };
-#else
- return { Custom, "", "" };
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ return { Type::Custom, {}, {} };
}
void Bed3D::render_axes() const
{
- if (!m_shape.empty())
+ if (m_build_volume.valid())
m_axes.render();
}
@@ -596,12 +485,10 @@ void Bed3D::render_model() const
model->set_color(-1, DEFAULT_MODEL_COLOR);
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
- Vec3d shift = m_bounding_box.center();
- shift(2) = -0.03;
- *const_cast<Vec3d*>(&m_model_offset) = shift;
+ *const_cast<Vec3d*>(&m_model_offset) = to_3d(m_build_volume.bounding_volume2d().center(), -0.03);
// update extended bounding box
- calc_bounding_boxes();
+ const_cast<BoundingBoxf3&>(m_extended_bounding_box) = this->calc_extended_bounding_box();
}
if (!model->get_filename().empty()) {
@@ -673,7 +560,7 @@ void Bed3D::render_default(bool bottom, bool picking) const
}
}
-void Bed3D::reset()
+void Bed3D::release_VBOs()
{
if (m_vbo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_vbo_id));
diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp
index 07b9f1758..639dc6c16 100644
--- a/src/slic3r/GUI/3DBed.hpp
+++ b/src/slic3r/GUI/3DBed.hpp
@@ -5,6 +5,8 @@
#include "3DScene.hpp"
#include "GLModel.hpp"
+#include <libslic3r/BuildVolume.hpp>
+
#include <tuple>
#include <array>
@@ -62,41 +64,22 @@ class Bed3D
};
public:
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- enum class EType : unsigned char
+ enum class Type : unsigned char
{
+ // The print bed model and texture are available from some printer preset.
System,
+ // The print bed model is unknown, thus it is rendered procedurally.
Custom
};
- enum class EShapeType : unsigned char
- {
- Rectangle,
- Circle,
- Custom,
- Invalid
- };
-#else
- enum EType : unsigned char
- {
- System,
- Custom,
- Num_Types
- };
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
private:
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- EType m_type{ EType::Custom };
- EShapeType m_shape_type{ EShapeType::Invalid };
-#else
- EType m_type{ Custom };
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Pointfs m_shape;
+ BuildVolume m_build_volume;
+ Type m_type{ Type::Custom };
std::string m_texture_filename;
std::string m_model_filename;
- BoundingBoxf3 m_bounding_box;
+ // Print volume bounding box exteded with axes and model.
BoundingBoxf3 m_extended_bounding_box;
+ // Slightly expanded print bed polygon, for collision detection.
Polygon m_polygon;
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
@@ -112,42 +95,39 @@ private:
public:
Bed3D() = default;
- ~Bed3D() { reset(); }
-
- EType get_type() const { return m_type; }
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- EShapeType get_shape_type() const { return m_shape_type; }
- bool is_custom() const { return m_type == EType::Custom; }
-#else
- bool is_custom() const { return m_type == Custom; }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ ~Bed3D() { release_VBOs(); }
- const Pointfs& get_shape() const { return m_shape; }
+ // Update print bed model from configuration.
// Return true if the bed shape changed, so the calee will update the UI.
- bool set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
+ //FIXME if the build volume max print height is updated, this function still returns zero
+ // as this class does not use it, thus there is no need to update the UI.
+ bool set_shape(const Pointfs& bed_shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
+
+ // Build volume geometry for various collision detection tasks.
+ const BuildVolume& build_volume() const { return m_build_volume; }
- const BoundingBoxf3& get_bounding_box(bool extended) const { return extended ? m_extended_bounding_box : m_bounding_box; }
+ // Was the model provided, or was it generated procedurally?
+ Type get_type() const { return m_type; }
+ // Was the model generated procedurally?
+ bool is_custom() const { return m_type == Type::Custom; }
+ // Bounding box around the print bed, axes and model, for rendering.
+ const BoundingBoxf3& extended_bounding_box() const { return m_extended_bounding_box; }
+
+ // Check against an expanded 2d bounding box.
+ //FIXME shall one check against the real build volume?
bool contains(const Point& point) const;
Point point_projection(const Point& point) const;
- void render(GLCanvas3D& canvas, bool bottom, float scale_factor,
- bool show_axes, bool show_texture);
-
+ void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture);
void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- static bool is_rectangle(const Pointfs& shape, Vec2d* min = nullptr, Vec2d* max = nullptr);
- static bool is_circle(const Pointfs& shape, Vec2d* center = nullptr, double* radius = nullptr);
- static bool is_convex(const Pointfs& shape);
- static EShapeType detect_shape_type(const Pointfs& shape);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
private:
- void calc_bounding_boxes() const;
+ // Calculate an extended bounding box from axes and current model for visualization purposes.
+ BoundingBoxf3 calc_extended_bounding_box() const;
void calc_triangles(const ExPolygon& poly);
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
- std::tuple<EType, std::string, std::string> detect_type(const Pointfs& shape) const;
+ static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking);
void render_axes() const;
@@ -156,7 +136,7 @@ private:
void render_model() const;
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const;
void render_default(bool bottom, bool picking) const;
- void reset();
+ void release_VBOs();
};
} // GUI
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 6bceaec09..f377edafa 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -11,10 +11,8 @@
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "BitmapCache.hpp"
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-#include "3DBed.hpp"
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/ExtrusionEntity.hpp"
#include "libslic3r/ExtrusionEntityCollection.hpp"
#include "libslic3r/Geometry.hpp"
@@ -617,22 +615,6 @@ void GLVolume::render_sinking_contours()
m_sinking_contours.render();
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-void GLVolume::calc_convex_hull_3d()
-{
- const std::vector<float> &src = this->indexed_vertex_array.vertices_and_normals_interleaved;
- std::vector<Vec3f> pts;
- assert(src.size() % 6 == 0);
- pts.reserve(src.size() / 6);
- for (auto it = src.begin(); it != src.end(); ) {
- it += 3;
- pts.push_back({ *it, *(it + 1), *(it + 2) });
- it += 3;
- }
- this->set_convex_hull(TriangleMesh(its_convex_hull(pts)));
-}
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
std::vector<int> GLVolumeCollection::load_object(
const ModelObject *model_object,
int obj_idx,
@@ -959,136 +941,51 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
glsafe(::glDisable(GL_BLEND));
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state, bool as_toolpaths) const
-#else
-bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, ModelInstanceEPrintVolumeState *out_state) const
{
- if (config == nullptr)
- return false;
-
- const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
- if (opt == nullptr)
- return false;
-
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front();
- const float bed_height = config->opt_float("max_print_height");
- const BoundingBox bed_box_2D = get_extents(bed_poly);
- BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min.x()), unscale<double>(bed_box_2D.min.y()), -1e10 },
- { unscale<double>(bed_box_2D.max.x()), unscale<double>(bed_box_2D.max.y()), bed_height });
-
- auto check_against_rectangular_bed = [&print_volume](GLVolume& volume, ModelInstanceEPrintVolumeState& state) {
- const BoundingBoxf3* const bb = (volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1) ? &volume.transformed_non_sinking_bounding_box() : &volume.transformed_convex_hull_bounding_box();
- volume.is_outside = !print_volume.contains(*bb);
- if (volume.printable) {
- if (state == ModelInstancePVS_Inside && volume.is_outside)
- state = ModelInstancePVS_Fully_Outside;
- if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && print_volume.intersects(*bb))
- state = ModelInstancePVS_Partly_Outside;
- }
- };
-
- auto check_against_circular_bed = [bed_height](GLVolume& volume, ModelInstanceEPrintVolumeState& state, const Vec2d& center, double radius) {
- const TriangleMesh* mesh = (volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1) ? &GUI::wxGetApp().plater()->model().objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : volume.convex_hull();
- const double sq_radius = sqr(radius);
- size_t outside_count = 0;
- size_t valid_count = 0;
- for (const Vec3f& v : mesh->its.vertices) {
- const Vec3f world_v = volume.world_matrix().cast<float>() * v;
- if (0.0f <= world_v.z()) {
- ++valid_count;
- if (sq_radius < sqr(world_v.x() - center.x()) + sqr(world_v.y() - center.y()) || bed_height < world_v.z())
- ++outside_count;
- }
- }
- volume.is_outside = outside_count > 0;
- if (volume.printable) {
- if (state == ModelInstancePVS_Inside && volume.is_outside)
- state = ModelInstancePVS_Fully_Outside;
- if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && outside_count < valid_count)
- state = ModelInstancePVS_Partly_Outside;
- }
- };
-
- auto check_against_convex_bed = [&bed_poly, bed_height](GLVolume& volume, ModelInstanceEPrintVolumeState& state) {
- const TriangleMesh* mesh = (volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1) ? &GUI::wxGetApp().plater()->model().objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : volume.convex_hull();
- const Polygon volume_hull_2d = its_convex_hull_2d_above(mesh->its, volume.world_matrix().cast<float>(), 0.0f);
- const BoundingBoxf3* const bb = (volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1) ? &volume.transformed_non_sinking_bounding_box() : &volume.transformed_convex_hull_bounding_box();
- // Using rotating callipers to check for collision of two convex polygons.
- ModelInstanceEPrintVolumeState volume_state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb->min.z(), bb->max.z());
- bool contained = (volume_state == ModelInstancePVS_Inside);
- bool intersects = (volume_state == ModelInstancePVS_Partly_Outside);
-
- volume.is_outside = !contained;
- if (volume.printable) {
- if (state == ModelInstancePVS_Inside && volume.is_outside)
- state = ModelInstancePVS_Fully_Outside;
-
- if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && intersects)
- state = ModelInstancePVS_Partly_Outside;
- }
- };
-#else
- const BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
- BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min.x()), unscale<double>(bed_box_2D.min.y()), 0.0 },
- { unscale<double>(bed_box_2D.max.x()), unscale<double>(bed_box_2D.max.y()), config->opt_float("max_print_height") });
- // Allow the objects to protrude below the print bed
- print_volume.min.z() = -1e10;
- print_volume.min.x() -= BedEpsilon;
- print_volume.min.y() -= BedEpsilon;
- print_volume.max.x() += BedEpsilon;
- print_volume.max.y() += BedEpsilon;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ const Model& model = GUI::wxGetApp().plater()->model();
+ // Volume is partially below the print bed, thus a pre-calculated convex hull cannot be used.
+ auto volume_sinking = [](GLVolume& volume) -> bool
+ { return volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1; };
+ // Cached bounding box of a volume above the print bed.
+ auto volume_bbox = [volume_sinking](GLVolume& volume) -> BoundingBoxf3
+ { return volume_sinking(volume) ? volume.transformed_non_sinking_bounding_box() : volume.transformed_convex_hull_bounding_box(); };
+ // Cached 3D convex hull of a volume above the print bed.
+ auto volume_convex_mesh = [volume_sinking, &model](GLVolume& volume) -> const TriangleMesh&
+ { return volume_sinking(volume) ? model.objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : *volume.convex_hull(); };
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
bool contained_min_one = false;
- enum class BedShape { Rectangle, Circle, Convex, NonConvex };
- Vec2d center;
- double radius;
- BedShape bed_shape =
- GUI::Bed3D::is_rectangle(opt->values) ? BedShape::Rectangle :
- GUI::Bed3D::is_circle(opt->values, &center, &radius) ? BedShape::Circle :
- GUI::Bed3D::is_convex(opt->values) ? BedShape::Convex : BedShape::NonConvex;
-
- for (GLVolume* volume : this->volumes) {
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (as_toolpaths && !volume->is_extrusion_path)
- continue;
- else if (!as_toolpaths && (volume->is_modifier || (!volume->shader_outside_printer_detection_enabled && (volume->is_wipe_tower || volume->composite_id.volume_id < 0))))
- continue;
-
- switch (bed_shape) {
- case BedShape::Rectangle: check_against_rectangular_bed(*volume, overall_state); break;
- case BedShape::Circle: check_against_circular_bed(*volume, overall_state, center, radius); break;
- case BedShape::Convex: check_against_convex_bed(*volume, overall_state); break;
- default: break;
+ for (GLVolume* volume : this->volumes)
+ if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) {
+ BuildVolume::ObjectState state;
+ switch (build_volume.type()) {
+ case BuildVolume::Type::Rectangle:
+ //FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
+ state = build_volume.volume_state_bbox(volume_bbox(*volume));
+ break;
+ case BuildVolume::Type::Circle:
+ case BuildVolume::Type::Convex:
+ //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
+ case BuildVolume::Type::Custom:
+ state = build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
+ break;
+ default:
+ // Ignore, don't produce any collision.
+ state = BuildVolume::ObjectState::Inside;
+ break;
+ }
+ volume->is_outside = state != BuildVolume::ObjectState::Inside;
+ if (volume->printable) {
+ if (overall_state == ModelInstancePVS_Inside && volume->is_outside)
+ overall_state = ModelInstancePVS_Fully_Outside;
+ if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && state == BuildVolume::ObjectState::Colliding)
+ overall_state = ModelInstancePVS_Partly_Outside;
+ contained_min_one |= !volume->is_outside;
+ }
}
- contained_min_one |= !volume->is_outside;
-#else
- if (volume->is_modifier || (!volume->shader_outside_printer_detection_enabled && (volume->is_wipe_tower || volume->composite_id.volume_id < 0)))
- continue;
-
- const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
- bool contained = print_volume.contains(bb);
-
- volume->is_outside = !contained;
- if (!volume->printable)
- continue;
-
- contained_min_one |= contained;
-
- if (overall_state == ModelInstancePVS_Inside && volume->is_outside)
- overall_state = ModelInstancePVS_Fully_Outside;
-
- if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && print_volume.intersects(bb))
- overall_state = ModelInstancePVS_Partly_Outside;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- }
-
if (out_state != nullptr)
*out_state = overall_state;
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index abf66394d..6d82e3bb7 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -31,6 +31,7 @@
namespace Slic3r {
class SLAPrintObject;
enum SLAPrintObjectStep : unsigned int;
+class BuildVolume;
class DynamicPrintConfig;
class ExtrusionPath;
class ExtrusionMultiPath;
@@ -281,10 +282,8 @@ private:
std::shared_ptr<const TriangleMesh> m_convex_hull;
// Bounding box of this volume, in unscaled coordinates.
std::optional<BoundingBoxf3> m_transformed_convex_hull_bounding_box;
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// Bounding box of the non sinking part of this volume, in unscaled coordinates.
std::optional<BoundingBoxf3> m_transformed_non_sinking_bounding_box;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
class SinkingContours
{
@@ -475,12 +474,10 @@ public:
BoundingBoxf3 transformed_convex_hull_bounding_box(const Transform3d &trafo) const;
// caching variant
const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// non-caching variant
BoundingBoxf3 transformed_non_sinking_bounding_box(const Transform3d& trafo) const;
// caching variant
const BoundingBoxf3& transformed_non_sinking_bounding_box() const;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// convex hull
const TriangleMesh* convex_hull() const { return m_convex_hull.get(); }
@@ -493,15 +490,11 @@ public:
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
void set_bounding_boxes_as_dirty() {
m_transformed_bounding_box.reset();
m_transformed_convex_hull_bounding_box.reset();
m_transformed_non_sinking_bounding_box.reset();
}
-#else
- void set_bounding_boxes_as_dirty() { m_transformed_bounding_box.reset(); m_transformed_convex_hull_bounding_box.reset(); }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
bool is_sla_support() const;
bool is_sla_pad() const;
@@ -518,12 +511,6 @@ public:
// Return an estimate of the memory held by GPU vertex buffers.
size_t gpu_memory_used() const { return this->indexed_vertex_array.gpu_memory_used(); }
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
-
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- // calculates the 3D convex hull from indexed_vertex_array.vertices_and_normals_interleaved
- // must be called before calling indexed_vertex_array.finalize_geometry();
- void calc_convex_hull_3d();
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
};
typedef std::vector<GLVolume*> GLVolumePtrs;
@@ -540,7 +527,6 @@ public:
All
};
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
struct PrintVolume
{
// see: Bed3D::EShapeType
@@ -554,16 +540,9 @@ public:
// [0] = min z, [1] = max z
std::array<float, 2> zs;
};
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
private:
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
PrintVolume m_print_volume;
-#else
- // min and max vertex of the print box volume
- float m_print_box_min[3];
- float m_print_box_max[3];
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// z range for clipping in shaders
float m_z_range[2];
@@ -635,14 +614,7 @@ public:
bool empty() const { return volumes.empty(); }
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
void set_print_volume(const PrintVolume& print_volume) { m_print_volume = print_volume; }
-#else
- void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) {
- m_print_box_min[0] = min_x; m_print_box_min[1] = min_y; m_print_box_min[2] = min_z;
- m_print_box_max[0] = max_x; m_print_box_max[1] = max_y; m_print_box_max[2] = max_z;
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
void set_z_range(float min_z, float max_z) { m_z_range[0] = min_z; m_z_range[1] = max_z; }
void set_clipping_plane(const double* coeffs) { m_clipping_plane[0] = coeffs[0]; m_clipping_plane[1] = coeffs[1]; m_clipping_plane[2] = coeffs[2]; m_clipping_plane[3] = coeffs[3]; }
@@ -657,11 +629,7 @@ public:
// returns true if all the volumes are completely contained in the print volume
// returns the containment state in the given out_state, if non-null
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state, bool as_toolpaths = false) const;
-#else
- bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ bool check_outside_state(const Slic3r::BuildVolume& build_volume, ModelInstanceEPrintVolumeState* out_state) const;
void reset_outside_state();
void update_colors_by_extruder(const DynamicPrintConfig* config);
@@ -699,8 +667,6 @@ struct _3DScene
static void point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume);
};
-static constexpr float BedEpsilon = 3.f * float(EPSILON);
-
}
#endif
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp
index f87a58fd6..5fba237e3 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp
@@ -86,7 +86,7 @@ public:
void set_fff_print(Print *print) { m_fff_print = print; }
void set_sla_print(SLAPrint *print) { m_sla_print = print; m_sla_print->set_printer(&m_sla_archive); }
void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; }
- void set_gcode_result(GCodeProcessor::Result* result) { m_gcode_result = result; }
+ void set_gcode_result(GCodeProcessorResult* result) { m_gcode_result = result; }
// The following wxCommandEvent will be sent to the UI thread / Plater window, when the slicing is finished
// and the background processing will transition into G-code export.
@@ -216,7 +216,7 @@ private:
Print *m_fff_print = nullptr;
SLAPrint *m_sla_print = nullptr;
// Data structure, to which the G-code export writes its annotations.
- GCodeProcessor::Result *m_gcode_result = nullptr;
+ GCodeProcessorResult *m_gcode_result = nullptr;
// Callback function, used to write thumbnails into gcode.
ThumbnailsGeneratorCallback m_thumbnail_cb = nullptr;
SL1Archive m_sla_archive;
diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp
index 0b8e31e13..2d46a5228 100644
--- a/src/slic3r/GUI/BedShapeDialog.cpp
+++ b/src/slic3r/GUI/BedShapeDialog.cpp
@@ -22,98 +22,7 @@ namespace GUI {
BedShape::BedShape(const ConfigOptionPoints& points)
{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (points.size() < 3) {
- m_type = Bed3D::EShapeType::Invalid;
- return;
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
- // is this a rectangle ?
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Vec2d min;
- Vec2d max;
- if (Bed3D::is_rectangle(points.values, &min, &max)) {
- m_type = Bed3D::EShapeType::Rectangle;
- m_rectSize = max - min;
- m_rectOrigin = -min;
- return;
- }
-#else
- Polygon polygon = Polygon::new_scale(points.values);
- if (points.size() == 4) {
- auto lines = polygon.lines();
- if (lines[0].parallel_to(lines[2]) && lines[1].parallel_to(lines[3])) {
- // okay, it's a rectangle
- // find origin
- coordf_t x_min, x_max, y_min, y_max;
- x_max = x_min = points.values[0](0);
- y_max = y_min = points.values[0](1);
- for (auto pt : points.values)
- {
- x_min = std::min(x_min, pt(0));
- x_max = std::max(x_max, pt(0));
- y_min = std::min(y_min, pt(1));
- y_max = std::max(y_max, pt(1));
- }
-
- m_type = Type::Rectangular;
- m_rectSize = Vec2d(x_max - x_min, y_max - y_min);
- m_rectOrigin = Vec2d(-x_min, -y_min);
-
- return;
- }
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
- // is this a circle ?
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Vec2d center;
- double radius;
- if (Bed3D::is_circle(points.values, &center, &radius)) {
- m_type = Bed3D::EShapeType::Circle;
- m_diameter = 2.0 * radius;
- return;
- }
-
- // This is a custom bed shape, use the polygon provided.
- m_type = Bed3D::EShapeType::Custom;
-#else
- {
- // Analyze the array of points.Do they reside on a circle ?
- auto center = polygon.bounding_box().center();
- std::vector<double> vertex_distances;
- double avg_dist = 0;
- for (auto pt : polygon.points)
- {
- double distance = (pt - center).cast<double>().norm();
- vertex_distances.push_back(distance);
- avg_dist += distance;
- }
-
- avg_dist /= vertex_distances.size();
- bool defined_value = true;
- for (auto el : vertex_distances)
- {
- if (abs(el - avg_dist) > 10 * SCALED_EPSILON)
- defined_value = false;
- break;
- }
- if (defined_value) {
- // all vertices are equidistant to center
- m_type = Type::Circular;
- m_diameter = unscale<double>(avg_dist * 2);
-
- return;
- }
- }
-
- if (points.size() < 3)
- return;
-
- // This is a custom bed shape, use the polygon provided.
- m_type = Type::Custom;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ m_build_volume = { points.values, 0. };
}
static std::string get_option_label(BedShape::Parameter param)
@@ -122,119 +31,101 @@ static std::string get_option_label(BedShape::Parameter param)
case BedShape::Parameter::RectSize : return L("Size");
case BedShape::Parameter::RectOrigin: return L("Origin");
case BedShape::Parameter::Diameter : return L("Diameter");
- default: return "";
+ default: assert(false); return {};
}
}
void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter param)
{
ConfigOptionDef def;
-
- if (param == Parameter::RectSize) {
+ t_config_option_key key;
+ switch (param) {
+ case Parameter::RectSize:
def.type = coPoints;
def.set_default_value(new ConfigOptionPoints{ Vec2d(200, 200) });
def.min = 0;
def.max = 1200;
def.label = get_option_label(param);
def.tooltip = L("Size in X and Y of the rectangular plate.");
-
- Option option(def, "rect_size");
- optgroup->append_single_option_line(option);
- }
- else if (param == Parameter::RectOrigin) {
+ key = "rect_size";
+ break;
+ case Parameter::RectOrigin:
def.type = coPoints;
def.set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) });
def.min = -600;
def.max = 600;
def.label = get_option_label(param);
def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.");
-
- Option option(def, "rect_origin");
- optgroup->append_single_option_line(option);
- }
- else if (param == Parameter::Diameter) {
+ key = "rect_origin";
+ break;
+ case Parameter::Diameter:
def.type = coFloat;
def.set_default_value(new ConfigOptionFloat(200));
def.sidetext = L("mm");
def.label = get_option_label(param);
def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center.");
-
- Option option(def, "diameter");
- optgroup->append_single_option_line(option);
+ key = "diameter";
+ break;
+ default:
+ assert(false);
}
-}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-wxString BedShape::get_name(Bed3D::EShapeType type)
-{
- switch (type) {
- case Bed3D::EShapeType::Rectangle: { return _L("Rectangular"); }
- case Bed3D::EShapeType::Circle: { return _L("Circular"); }
- case Bed3D::EShapeType::Custom: { return _L("Custom"); }
- case Bed3D::EShapeType::Invalid:
- default: return _L("Invalid");
- }
+ optgroup->append_single_option_line({ def, std::move(key) });
}
-#else
-wxString BedShape::get_name(Type type)
+
+wxString BedShape::get_name(PageType type)
{
switch (type) {
- case Type::Rectangular: return _L("Rectangular");
- case Type::Circular: return _L("Circular");
- case Type::Custom: return _L("Custom");
- case Type::Invalid:
- default: return _L("Invalid");
+ case PageType::Rectangle: return _L("Rectangular");
+ case PageType::Circle: return _L("Circular");
+ case PageType::Custom: return _L("Custom");
}
+ // make visual studio happy
+ assert(false);
+ return {};
}
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-size_t BedShape::get_type()
+BedShape::PageType BedShape::get_page_type()
{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- return static_cast<size_t>(m_type == Bed3D::EShapeType::Invalid ? Bed3D::EShapeType::Rectangle : m_type);
-#else
- return static_cast<size_t>(m_type == Type::Invalid ? Type::Rectangular : m_type);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ switch (m_build_volume.type()) {
+ case BuildVolume::Type::Rectangle:
+ case BuildVolume::Type::Invalid: return PageType::Rectangle;
+ case BuildVolume::Type::Circle: return PageType::Circle;
+ case BuildVolume::Type::Convex:
+ case BuildVolume::Type::Custom: return PageType::Custom;
+ }
+ // make visual studio happy
+ assert(false);
+ return PageType::Rectangle;
}
wxString BedShape::get_full_name_with_params()
{
- wxString out = _L("Shape") + ": " + get_name(m_type);
-
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (m_type == Bed3D::EShapeType::Rectangle) {
-#else
- if (m_type == Type::Rectangular) {
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- out += "\n" + _(get_option_label(Parameter::RectSize)) + ": [" + ConfigOptionPoint(m_rectSize).serialize() + "]";
- out += "\n" + _(get_option_label(Parameter::RectOrigin))+ ": [" + ConfigOptionPoint(m_rectOrigin).serialize() + "]";
+ wxString out = _L("Shape") + ": " + get_name(this->get_page_type());
+ switch (m_build_volume.type()) {
+ case BuildVolume::Type::Circle:
+ out += "\n" + _L(get_option_label(Parameter::Diameter)) + ": [" + double_to_string(2. * unscaled<double>(m_build_volume.circle().radius)) + "]";
+ break;
+ default:
+ // rectangle, convex, concave...
+ out += "\n" + _(get_option_label(Parameter::RectSize)) + ": [" + ConfigOptionPoint(to_2d(m_build_volume.bounding_volume().size())).serialize() + "]";
+ out += "\n" + _(get_option_label(Parameter::RectOrigin)) + ": [" + ConfigOptionPoint(to_2d(m_build_volume.bounding_volume().min)).serialize() + "]";
+ break;
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- else if (m_type == Bed3D::EShapeType::Circle)
-#else
- else if (m_type == Type::Circular)
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- out += "\n" + _L(get_option_label(Parameter::Diameter)) + ": [" + double_to_string(m_diameter) + "]";
-
return out;
}
void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (m_type == Bed3D::EShapeType::Rectangle || m_type == Bed3D::EShapeType::Invalid) {
-#else
- if (m_type == Type::Rectangular || m_type == Type::Invalid) {
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- optgroup->set_value("rect_size" , new ConfigOptionPoints{ m_rectSize });
- optgroup->set_value("rect_origin" , new ConfigOptionPoints{ m_rectOrigin });
+ switch (m_build_volume.type()) {
+ case BuildVolume::Type::Circle:
+ optgroup->set_value("diameter", double_to_string(2. * unscaled<double>(m_build_volume.circle().radius)));
+ break;
+ default:
+ // rectangle, convex, concave...
+ optgroup->set_value("rect_size" , new ConfigOptionPoints{ to_2d(m_build_volume.bounding_volume().size()) });
+ optgroup->set_value("rect_origin" , new ConfigOptionPoints{ to_2d(m_build_volume.bounding_volume().min) });
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- else if (m_type == Bed3D::EShapeType::Circle)
-#else
- else if (m_type == Type::Circular)
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- optgroup->set_value("diameter", double_to_string(m_diameter));
}
void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
@@ -295,28 +186,16 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
sbsizer->Add(m_shape_options_book);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- auto optgroup = init_shape_options_page(BedShape::get_name(Bed3D::EShapeType::Rectangle));
-#else
- auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Rectangular));
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Rectangle));
BedShape::append_option_line(optgroup, BedShape::Parameter::RectSize);
BedShape::append_option_line(optgroup, BedShape::Parameter::RectOrigin);
activate_options_page(optgroup);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- optgroup = init_shape_options_page(BedShape::get_name(Bed3D::EShapeType::Circle));
-#else
- optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Circular));
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Circle));
BedShape::append_option_line(optgroup, BedShape::Parameter::Diameter);
activate_options_page(optgroup);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- optgroup = init_shape_options_page(BedShape::get_name(Bed3D::EShapeType::Custom));
-#else
- optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Custom));
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Custom));
Line line{ "", "" };
line.full_width = 1;
@@ -538,8 +417,8 @@ void BedShapePanel::set_shape(const ConfigOptionPoints& points)
{
BedShape shape(points);
- m_shape_options_book->SetSelection(shape.get_type());
- shape.apply_optgroup_values(m_optgroups[shape.get_type()]);
+ m_shape_options_book->SetSelection(int(shape.get_page_type()));
+ shape.apply_optgroup_values(m_optgroups[int(shape.get_page_type())]);
// Copy the polygon to the canvas, make a copy of the array, if custom shape is selected
if (shape.is_custom())
@@ -562,17 +441,9 @@ void BedShapePanel::update_shape()
auto page_idx = m_shape_options_book->GetSelection();
auto opt_group = m_optgroups[page_idx];
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Bed3D::EShapeType page_type = static_cast<Bed3D::EShapeType>(page_idx);
-#else
- BedShape::Type page_type = static_cast<BedShape::Type>(page_idx);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (page_type == Bed3D::EShapeType::Rectangle) {
-#else
- if (page_type == BedShape::Type::Rectangular) {
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ switch (static_cast<BedShape::PageType>(page_idx)) {
+ case BedShape::PageType::Rectangle:
+ {
Vec2d rect_size(Vec2d::Zero());
Vec2d rect_origin(Vec2d::Zero());
@@ -602,12 +473,10 @@ void BedShapePanel::update_shape()
Vec2d(x1, y0),
Vec2d(x1, y1),
Vec2d(x0, y1) };
+ break;
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- else if (page_type == Bed3D::EShapeType::Circle) {
-#else
- else if (page_type == BedShape::Type::Circular) {
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ case BedShape::PageType::Circle:
+ {
double diameter;
try { diameter = boost::any_cast<double>(opt_group->get_value("diameter")); }
catch (const std::exception & /* e */) { return; }
@@ -615,6 +484,7 @@ void BedShapePanel::update_shape()
if (diameter == 0.0) return ;
auto r = diameter / 2;
auto twopi = 2 * PI;
+ // Don't change this value without adjusting BuildVolume constructor detecting circle diameter!
auto edges = 72;
std::vector<Vec2d> points;
for (int i = 1; i <= edges; ++i) {
@@ -622,13 +492,12 @@ void BedShapePanel::update_shape()
points.push_back(Vec2d(r*cos(angle), r*sin(angle)));
}
m_shape = points;
+ break;
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- else if (page_type == Bed3D::EShapeType::Custom)
-#else
- else if (page_type == BedShape::Type::Custom)
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ case BedShape::PageType::Custom:
m_shape = m_loaded_shape;
+ break;
+ }
update_preview();
}
diff --git a/src/slic3r/GUI/BedShapeDialog.hpp b/src/slic3r/GUI/BedShapeDialog.hpp
index af84ffb95..032aa2880 100644
--- a/src/slic3r/GUI/BedShapeDialog.hpp
+++ b/src/slic3r/GUI/BedShapeDialog.hpp
@@ -5,11 +5,10 @@
#include "GUI_Utils.hpp"
#include "2DBed.hpp"
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-#include "3DBed.hpp"
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
#include "I18N.hpp"
+#include <libslic3r/BuildVolume.hpp>
+
#include <wx/dialog.h>
#include <wx/choicebk.h>
@@ -22,14 +21,11 @@ using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
struct BedShape
{
-#if !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- enum class Type {
- Rectangular = 0,
- Circular,
- Custom,
- Invalid
+ enum class PageType {
+ Rectangle,
+ Circle,
+ Custom
};
-#endif // !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
enum class Parameter {
RectSize,
@@ -39,34 +35,18 @@ struct BedShape
BedShape(const ConfigOptionPoints& points);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- bool is_custom() { return m_type == Bed3D::EShapeType::Custom; }
-#else
- bool is_custom() { return m_type == Type::Custom; }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ bool is_custom() { return m_build_volume.type() == BuildVolume::Type::Convex || m_build_volume.type() == BuildVolume::Type::Custom; }
static void append_option_line(ConfigOptionsGroupShp optgroup, Parameter param);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- static wxString get_name(Bed3D::EShapeType type);
-#else
- static wxString get_name(Type type);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ static wxString get_name(PageType type);
- // convert Type to size_t
- size_t get_type();
+ PageType get_page_type();
wxString get_full_name_with_params();
void apply_optgroup_values(ConfigOptionsGroupShp optgroup);
private:
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Bed3D::EShapeType m_type{ Bed3D::EShapeType::Invalid };
-#else
- Type m_type {Type::Invalid};
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Vec2d m_rectSize {200, 200};
- Vec2d m_rectOrigin {0, 0};
- double m_diameter {0};
+ BuildVolume m_build_volume;
};
class BedShapePanel : public wxPanel
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index 1d4551f2e..6463cc180 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -1,6 +1,7 @@
#include "libslic3r/libslic3r.h"
#include "GCodeViewer.hpp"
+#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/Geometry.hpp"
#include "libslic3r/Model.hpp"
@@ -20,9 +21,6 @@
#include "GLToolbar.hpp"
#include "GUI_Preview.hpp"
#include "GUI_ObjectManipulation.hpp"
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-#include "3DBed.hpp"
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
#include <imgui/imgui_internal.h>
@@ -123,7 +121,7 @@ void GCodeViewer::IBuffer::reset()
count = 0;
}
-bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const
+bool GCodeViewer::Path::matches(const GCodeProcessorResult::MoveVertex& move) const
{
auto matches_percent = [](float value1, float value2, float max_percent) {
return std::abs(value2 - value1) / value1 <= max_percent;
@@ -174,7 +172,7 @@ void GCodeViewer::TBuffer::reset()
#endif // ENABLE_SEAMS_USING_MODELS
}
-void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id)
+void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id)
{
Path::Endpoint endpoint = { b_id, i_id, s_id, move.position };
// use rounding to reduce the number of generated paths
@@ -665,7 +663,7 @@ void GCodeViewer::init()
}
#endif // ENABLE_SEAMS_USING_MODELS
-void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized)
+void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized)
{
// avoid processing if called with the same gcode_result
if (m_last_result_id == gcode_result.id)
@@ -737,7 +735,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
{ min.x(), max.y() } };
}
- wxGetApp().plater()->set_bed_shape(bed_shape, texture, model, gcode_result.bed_shape.empty());
+ wxGetApp().plater()->set_bed_shape(bed_shape, gcode_result.max_print_height, texture, model, gcode_result.bed_shape.empty());
}
m_print_statistics = gcode_result.print_statistics;
@@ -750,7 +748,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
}
}
-void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors)
+void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors)
{
#if ENABLE_GCODE_VIEWER_STATISTICS
auto start_time = std::chrono::high_resolution_clock::now();
@@ -779,7 +777,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std:
if (i == 0)
continue;
- const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i];
+ const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i];
switch (curr.type)
{
@@ -1210,7 +1208,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
fclose(fp);
}
-void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
+void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
{
// max index buffer size, in bytes
static const size_t IBUFFER_THRESHOLD_BYTES = 64 * 1024 * 1024;
@@ -1232,23 +1230,23 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
};
// format data into the buffers to be rendered as points
- auto add_vertices_as_point = [](const GCodeProcessor::MoveVertex& curr, VertexBuffer& vertices) {
+ auto add_vertices_as_point = [](const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
vertices.push_back(curr.position.x());
vertices.push_back(curr.position.y());
vertices.push_back(curr.position.z());
};
- auto add_indices_as_point = [](const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
+ auto add_indices_as_point = [](const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer,
unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) {
buffer.add_path(curr, ibuffer_id, indices.size(), move_id);
indices.push_back(static_cast<IBufferType>(indices.size()));
};
// format data into the buffers to be rendered as lines
- auto add_vertices_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, VertexBuffer& vertices) {
+ auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
// x component of the normal to the current segment (the normal is parallel to the XY plane)
const float normal_x = (curr.position - prev.position).normalized().y();
- auto add_vertex = [&vertices, normal_x](const GCodeProcessor::MoveVertex& vertex) {
+ auto add_vertex = [&vertices, normal_x](const GCodeProcessorResult::MoveVertex& vertex) {
// add position
vertices.push_back(vertex.position.x());
vertices.push_back(vertex.position.y());
@@ -1262,7 +1260,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
// add current vertex
add_vertex(curr);
};
- auto add_indices_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
+ auto add_indices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer,
unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) {
if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) {
// add starting index
@@ -1283,7 +1281,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
};
// format data into the buffers to be rendered as solid
- auto add_vertices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id) {
+ auto add_vertices_as_solid = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id) {
auto store_vertex = [](VertexBuffer& vertices, const Vec3f& position, const Vec3f& normal) {
// append position
vertices.push_back(position.x());
@@ -1340,7 +1338,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
last_path.sub_paths.back().last = { vbuffer_id, vertices.size(), move_id, curr.position };
};
- auto add_indices_as_solid = [&](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, const GCodeProcessor::MoveVertex* next,
+ auto add_indices_as_solid = [&](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, const GCodeProcessorResult::MoveVertex* next,
TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) {
static Vec3f prev_dir;
static Vec3f prev_up;
@@ -1482,7 +1480,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
#if ENABLE_SEAMS_USING_MODELS
// format data into the buffers to be rendered as instanced model
- auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) {
+ auto add_model_instance = [](const GCodeProcessorResult::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) {
// append position
instances.push_back(curr.position.x());
instances.push_back(curr.position.y());
@@ -1498,7 +1496,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
#if ENABLE_SEAMS_USING_BATCHED_MODELS
// format data into the buffers to be rendered as batched model
- auto add_vertices_as_model_batch = [](const GCodeProcessor::MoveVertex& curr, const GLModel::InitializationData& data, VertexBuffer& vertices, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) {
+ auto add_vertices_as_model_batch = [](const GCodeProcessorResult::MoveVertex& curr, const GLModel::InitializationData& data, VertexBuffer& vertices, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) {
const double width = static_cast<double>(1.5f * curr.width);
const double height = static_cast<double>(1.5f * curr.height);
@@ -1542,7 +1540,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
#if ENABLE_GCODE_VIEWER_STATISTICS
auto start_time = std::chrono::high_resolution_clock::now();
- m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessor::MoveVertex);
+ m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessorResult::MoveVertex);
m_statistics.results_time = gcode_result.time;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@@ -1561,7 +1559,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
wxBusyCursor busy;
// extract approximate paths bounding box from result
- for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
+ for (const GCodeProcessorResult::MoveVertex& move : gcode_result.moves) {
if (wxGetApp().is_gcode_viewer())
// for the gcode viewer we need to take in account all moves to correctly size the printbed
m_paths_bounding_box.merge(move.position.cast<double>());
@@ -1575,57 +1573,18 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
m_max_bounding_box = m_paths_bounding_box;
m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size().z() * Vec3d::UnitZ());
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (wxGetApp().is_editor()) {
- const Bed3D::EShapeType bed_type = wxGetApp().plater()->get_bed().get_shape_type();
- if (bed_type == Bed3D::EShapeType::Rectangle) {
- BoundingBoxf3 print_volume = wxGetApp().plater()->get_bed().get_bounding_box(false);
- print_volume.min.z() = -1e10;
- print_volume.max.z() = m_max_print_height;
- print_volume.min -= Vec3f(BedEpsilon, BedEpsilon, 0.0f).cast<double>();
- print_volume.max += Vec3f(BedEpsilon, BedEpsilon, 0.0f).cast<double>();
- m_contained_in_bed = print_volume.contains(m_paths_bounding_box);
- }
- else if (bed_type == Bed3D::EShapeType::Circle) {
- Vec2d center;
- double radius;
- Bed3D::is_circle(wxGetApp().plater()->get_bed().get_shape(), &center, &radius);
- const double sq_radius = sqr(radius);
- for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
- if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f) {
- if (sq_radius < (Vec2d(move.position.x(), move.position.y()) - center).squaredNorm()) {
- m_contained_in_bed = false;
- break;
- }
- }
- }
- }
- else if (bed_type == Bed3D::EShapeType::Custom) {
- const Pointfs& shape = wxGetApp().plater()->get_bed().get_shape();
- if (Bed3D::is_convex(shape)) {
- const Polygon poly = Polygon::new_scale(shape);
- for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
- if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f) {
- if (!poly.contains(Point::new_scale(Vec2d(move.position.x(), move.position.y())))) {
- m_contained_in_bed = false;
- break;
- }
- }
- }
- }
- }
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ if (wxGetApp().is_editor())
+ m_contained_in_bed = wxGetApp().plater()->build_volume().all_paths_inside(gcode_result, m_paths_bounding_box);
#if ENABLE_FIX_SEAMS_SYNCH
m_sequential_view.gcode_ids.clear();
for (size_t i = 0; i < gcode_result.moves.size(); ++i) {
- const GCodeProcessor::MoveVertex& move = gcode_result.moves[i];
+ const GCodeProcessorResult::MoveVertex& move = gcode_result.moves[i];
if (move.type != EMoveType::Seam)
m_sequential_view.gcode_ids.push_back(move.gcode_id);
}
#else
- for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
+ for (const GCodeProcessorResult::MoveVertex& move : gcode_result.moves) {
m_sequential_view.gcode_ids.push_back(move.gcode_id);
}
#endif // ENABLE_FIX_SEAMS_SYNCH
@@ -1648,7 +1607,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
// toolpaths data -> extract vertices from result
for (size_t i = 0; i < m_moves_count; ++i) {
- const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i];
+ const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i];
#if ENABLE_FIX_SEAMS_SYNCH
if (curr.type == EMoveType::Seam) {
++seams_count;
@@ -1662,7 +1621,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
if (i == 0)
continue;
- const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1];
+ const GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1];
// update progress dialog
++progress_count;
@@ -2066,7 +2025,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
#endif // ENABLE_FIX_SEAMS_SYNCH
for (size_t i = 0; i < m_moves_count; ++i) {
- const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i];
+ const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i];
#if ENABLE_FIX_SEAMS_SYNCH
if (curr.type == EMoveType::Seam)
++seams_count;
@@ -2078,8 +2037,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
if (i == 0)
continue;
- const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1];
- const GCodeProcessor::MoveVertex* next = nullptr;
+ const GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1];
+ const GCodeProcessorResult::MoveVertex* next = nullptr;
if (i < m_moves_count - 1)
next = &gcode_result.moves[i + 1];
@@ -2286,7 +2245,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
seams_count = 0;
#endif // ENABLE_FIX_SEAMS_SYNCH
for (size_t i = 0; i < m_moves_count; ++i) {
- const GCodeProcessor::MoveVertex& move = gcode_result.moves[i];
+ const GCodeProcessorResult::MoveVertex& move = gcode_result.moves[i];
#if ENABLE_FIX_SEAMS_SYNCH
if (move.type == EMoveType::Seam)
++seams_count;
diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp
index 66fcba2bc..85151ceb8 100644
--- a/src/slic3r/GUI/GCodeViewer.hpp
+++ b/src/slic3r/GUI/GCodeViewer.hpp
@@ -233,7 +233,7 @@ class GCodeViewer
unsigned char cp_color_id{ 0 };
std::vector<Sub_Path> sub_paths;
- bool matches(const GCodeProcessor::MoveVertex& move) const;
+ bool matches(const GCodeProcessorResult::MoveVertex& move) const;
size_t vertices_count() const {
return sub_paths.empty() ? 0 : sub_paths.back().last.s_id - sub_paths.front().first.s_id + 1;
}
@@ -251,7 +251,7 @@ class GCodeViewer
return -1;
}
}
- void add_sub_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id) {
+ void add_sub_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id) {
Endpoint endpoint = { b_id, i_id, s_id, move.position };
sub_paths.push_back({ endpoint , endpoint });
}
@@ -361,7 +361,7 @@ class GCodeViewer
// b_id index of buffer contained in this->indices
// i_id index of first index contained in this->indices[b_id]
// s_id index of first vertex contained in this->vertices
- void add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id);
+ void add_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id);
unsigned int max_vertices_per_segment() const {
switch (render_primitive_type)
@@ -802,7 +802,7 @@ private:
Statistics m_statistics;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
std::array<float, 2> m_detected_point_sizes = { 0.0f, 0.0f };
- GCodeProcessor::Result::SettingsIds m_settings_ids;
+ GCodeProcessorResult::SettingsIds m_settings_ids;
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
@@ -820,9 +820,9 @@ public:
#endif // ENABLE_SEAMS_USING_MODELS
// extract rendering data from the given parameters
- void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized);
+ void load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized);
// recalculate ranges in dependence of what is visible and sets tool/print colors
- void refresh(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors);
+ void refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
void refresh_render_paths();
void update_shells_color_by_extruder(const DynamicPrintConfig* config);
@@ -870,7 +870,7 @@ public:
size_t get_extruders_count() { return m_extruders_count; }
private:
- void load_toolpaths(const GCodeProcessor::Result& gcode_result);
+ void load_toolpaths(const GCodeProcessorResult& gcode_result);
void load_shells(const Print& print, bool initialized);
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
void render_toolpaths();
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index f349a0354..452173ae2 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -3,16 +3,18 @@
#include <igl/unproject.h>
+#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/GCode/ThumbnailData.hpp"
-#include "libslic3r/Geometry.hpp"
+#include "libslic3r/Geometry/ConvexHull.hpp"
#include "libslic3r/ExtrusionEntity.hpp"
#include "libslic3r/Layer.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Technologies.hpp"
#include "libslic3r/Tesselate.hpp"
#include "libslic3r/PresetBundle.hpp"
+#include "slic3r/GUI/3DBed.hpp"
#include "slic3r/GUI/3DScene.hpp"
#include "slic3r/GUI/BackgroundSlicingProcess.hpp"
#include "slic3r/GUI/GLShader.hpp"
@@ -20,7 +22,6 @@
#include "slic3r/GUI/Tab.hpp"
#include "slic3r/GUI/GUI_Preview.hpp"
#include "slic3r/GUI/OpenGLManager.hpp"
-#include "slic3r/GUI/3DBed.hpp"
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/MainFrame.hpp"
#include "slic3r/Utils/UndoRedo.hpp"
@@ -957,9 +958,10 @@ PrinterTechnology GLCanvas3D::current_printer_technology() const
return m_process->current_printer_technology();
}
-GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
+GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
: m_canvas(canvas)
, m_context(nullptr)
+ , m_bed(bed)
#if ENABLE_RETINA_GL
, m_retina_helper(nullptr)
#endif
@@ -1115,18 +1117,10 @@ void GLCanvas3D::reset_volumes()
_set_warning_notification(EWarning::ObjectOutside, false);
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state(bool as_toolpaths) const
-#else
ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
{
ModelInstanceEPrintVolumeState state;
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- m_volumes.check_outside_state(m_config, &state, as_toolpaths);
-#else
- m_volumes.check_outside_state(m_config, &state);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ m_volumes.check_outside_state(m_bed.build_volume(), &state);
return state;
}
@@ -1250,13 +1244,11 @@ BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
{
BoundingBoxf3 bb = volumes_bounding_box();
- bb.merge(wxGetApp().plater()->get_bed().get_bounding_box(true));
- if (m_config != nullptr) {
- double h = m_config->opt_float("max_print_height");
- bb.min(2) = std::min(bb.min(2), -h);
- bb.max(2) = std::max(bb.max(2), h);
- }
-
+ bb.merge(m_bed.extended_bounding_box());
+ double h = m_bed.build_volume().max_print_height();
+ //FIXME why -h?
+ bb.min.z() = std::min(bb.min.z(), -h);
+ bb.max.z() = std::max(bb.max.z(), h);
return bb;
}
@@ -1362,7 +1354,7 @@ void GLCanvas3D::allow_multisample(bool allow)
void GLCanvas3D::zoom_to_bed()
{
- _zoom_to_box(wxGetApp().plater()->get_bed().get_bounding_box(false));
+ _zoom_to_box(m_bed.build_volume().bounding_volume());
}
void GLCanvas3D::zoom_to_volumes()
@@ -1423,7 +1415,7 @@ void GLCanvas3D::render()
m_gcode_viewer.init();
#endif // ENABLE_SEAMS_USING_MODELS
- if (wxGetApp().plater()->get_bed().get_shape().empty()) {
+ if (! m_bed.build_volume().valid()) {
// this happens at startup when no data is still saved under <>\AppData\Roaming\Slic3rPE
post_event(SimpleEvent(EVT_GLCANVAS_UPDATE_BED_SHAPE));
return;
@@ -2057,7 +2049,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
// checks for geometry outside the print volume to render it accordingly
if (!m_volumes.empty()) {
ModelInstanceEPrintVolumeState state;
- const bool contained_min_one = m_volumes.check_outside_state(m_config, &state);
+ const bool contained_min_one = m_volumes.check_outside_state(m_bed.build_volume(), &state);
const bool partlyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Partly_Outside);
const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
@@ -2109,7 +2101,7 @@ static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume&
vol_old.finalize_geometry(gl_initialized);
}
-void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors)
+void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors)
{
m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized);
@@ -2138,10 +2130,6 @@ void GLCanvas3D::load_sla_preview()
// Release OpenGL data before generating new data.
reset_volumes();
_load_sla_shells();
-#if !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false);
- m_volumes.set_print_box(float(bed_bb.min.x()) - BedEpsilon, float(bed_bb.min.y()) - BedEpsilon, 0.0f, float(bed_bb.max.x()) + BedEpsilon, float(bed_bb.max.y()) + BedEpsilon, (float)m_config->opt_float("max_print_height"));
-#endif // !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
_update_sla_shells_outside_state();
_set_warning_notification_if_needed(EWarning::SlaSupportsOutside);
}
@@ -2158,20 +2146,12 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, c
// Release OpenGL data before generating new data.
this->reset_volumes();
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- bool requires_convex_hulls = wxGetApp().plater()->get_bed().get_shape_type() != Bed3D::EShapeType::Rectangle;
- _load_print_toolpaths(requires_convex_hulls);
- _load_wipe_tower_toolpaths(str_tool_colors, requires_convex_hulls);
+ const BuildVolume &build_volume = m_bed.build_volume();
+ _load_print_toolpaths(build_volume);
+ _load_wipe_tower_toolpaths(build_volume, str_tool_colors);
for (const PrintObject* object : print->objects())
- _load_print_object_toolpaths(*object, str_tool_colors, color_print_values, requires_convex_hulls);
-#else
- _load_print_toolpaths();
- _load_wipe_tower_toolpaths(str_tool_colors);
- for (const PrintObject* object : print->objects())
- _load_print_object_toolpaths(*object, str_tool_colors, color_print_values);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ _load_print_object_toolpaths(*object, build_volume, str_tool_colors, color_print_values);
- _update_toolpath_volumes_outside_state();
_set_warning_notification_if_needed(EWarning::ToolpathOutside);
}
@@ -3770,7 +3750,7 @@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
{
- return factor * wxGetApp().plater()->get_bed().get_bounding_box(false).max_size();
+ return factor * m_bed.build_volume().bounding_volume().max_size();
}
void GLCanvas3D::set_cursor(ECursorType type)
@@ -4161,7 +4141,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
}
else
// This happens for empty projects
- volumes_box = wxGetApp().plater()->get_bed().get_bounding_box(true);
+ volumes_box = m_bed.extended_bounding_box();
#endif // ENABLE_SAVE_COMMANDS_ALWAYS_ENABLED
Camera camera;
@@ -4178,7 +4158,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
// extends the near and far z of the frustrum to avoid the bed being clipped
// box in eye space
- BoundingBoxf3 t_bed_box = wxGetApp().plater()->get_bed().get_bounding_box(true).transformed(camera.get_view_matrix());
+ BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(camera.get_view_matrix());
near_z = -t_bed_box.max.z();
far_z = -t_bed_box.min.z();
}
@@ -4861,7 +4841,7 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be
bb.merge(BoundingBoxf3(sel_bb_center - extend_by, sel_bb_center + extend_by));
}
- bb.merge(wxGetApp().plater()->get_bed().get_bounding_box(include_bed_model));
+ bb.merge(include_bed_model ? m_bed.extended_bounding_box() : m_bed.build_volume().bounding_volume());
if (!m_main_toolbar.is_enabled())
bb.merge(m_gcode_viewer.get_max_bounding_box());
@@ -5035,25 +5015,6 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
_update_volumes_hover_state();
}
-#if !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-static BoundingBoxf3 print_volume(const DynamicPrintConfig& config)
-{
- // tolerance to avoid false detection at bed edges
- const double tolerance_x = 0.05;
- const double tolerance_y = 0.05;
-
- BoundingBoxf3 ret;
- const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config.option("bed_shape"));
- if (opt != nullptr) {
- BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
- ret = BoundingBoxf3(Vec3d(unscale<double>(bed_box_2D.min(0)) - tolerance_x, unscale<double>(bed_box_2D.min(1)) - tolerance_y, 0.0), Vec3d(unscale<double>(bed_box_2D.max(0)) + tolerance_x, unscale<double>(bed_box_2D.max(1)) + tolerance_y, config.opt_float("max_print_height")));
- // Allow the objects to protrude below the print bed
- ret.min(2) = -1e10;
- }
- return ret;
-}
-#endif // !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-
void GLCanvas3D::_render_background() const
{
bool use_error_color = false;
@@ -5064,15 +5025,7 @@ void GLCanvas3D::_render_background() const
if (!m_volumes.empty())
use_error_color &= _is_any_volume_outside();
else
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
use_error_color &= m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed();
-#else
- {
- const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
- const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
- use_error_color &= (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) ? !test_volume.contains(paths_volume) : false;
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
}
glsafe(::glPushMatrix());
@@ -5123,7 +5076,7 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
&& m_gizmos.get_current_type() != GLGizmosManager::Seam
&& m_gizmos.get_current_type() != GLGizmosManager::MmuSegmentation);
- wxGetApp().plater()->get_bed().render(*this, bottom, scale_factor, show_axes, show_texture);
+ m_bed.render(*this, bottom, scale_factor, show_axes, show_texture);
}
void GLCanvas3D::_render_bed_for_picking(bool bottom)
@@ -5133,7 +5086,7 @@ void GLCanvas3D::_render_bed_for_picking(bool bottom)
scale_factor = m_retina_helper->get_scale_factor();
#endif // ENABLE_RETINA_GL
- wxGetApp().plater()->get_bed().render_for_picking(*this, bottom, scale_factor);
+ m_bed.render_for_picking(*this, bottom, scale_factor);
}
void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
@@ -5148,55 +5101,35 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
if (m_picking_enabled) {
// Update the layer editing selection to the first object selected, update the current object maximum Z.
m_layers_editing.select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1);
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (m_config != nullptr) {
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- Bed3D::EShapeType type = wxGetApp().plater()->get_bed().get_shape_type();
- switch (type)
- {
- case Bed3D::EShapeType::Circle: {
- Vec2d center;
- double radius;
- if (Bed3D::is_circle(wxGetApp().plater()->get_bed().get_shape(), &center, &radius)) {
- m_volumes.set_print_volume({ static_cast<int>(type),
- { float(center.x()), float(center.y()), float(radius) + BedEpsilon, 0.0f },
- { 0.0f, float(m_config->opt_float("max_print_height")) } });
- }
+ if (const BuildVolume &build_volume = m_bed.build_volume(); build_volume.valid()) {
+ switch (build_volume.type()) {
+ case BuildVolume::Type::Rectangle: {
+ const BoundingBox3Base<Vec3d> bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon);
+ m_volumes.set_print_volume({ 0, // circle
+ { float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) },
+ { 0.0f, float(build_volume.max_print_height()) } });
break;
}
- case Bed3D::EShapeType::Rectangle: {
- const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false);
- m_volumes.set_print_volume({ static_cast<int>(type),
- { float(bed_bb.min.x()) - BedEpsilon, float(bed_bb.min.y()) - BedEpsilon, float(bed_bb.max.x()) + BedEpsilon, float(bed_bb.max.y()) + BedEpsilon },
- { 0.0f, float(m_config->opt_float("max_print_height")) } });
+ case BuildVolume::Type::Circle: {
+ m_volumes.set_print_volume({ 1, // rectangle
+ { unscaled<float>(build_volume.circle().center.x()), unscaled<float>(build_volume.circle().center.y()), unscaled<float>(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f },
+ { 0.0f, float(build_volume.max_print_height() + BuildVolume::SceneEpsilon) } });
break;
}
default:
- case Bed3D::EShapeType::Custom: {
+ case BuildVolume::Type::Custom: {
m_volumes.set_print_volume({ static_cast<int>(type),
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f } });
}
}
-#else
- const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false);
- m_volumes.set_print_box((float)bed_bb.min.x() - BedEpsilon, (float)bed_bb.min.y() - BedEpsilon, 0.0f, (float)bed_bb.max.x() + BedEpsilon, (float)bed_bb.max.y() + BedEpsilon, (float)m_config->opt_float("max_print_height"));
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
if (m_requires_check_outside_state) {
- m_volumes.check_outside_state(m_config, nullptr);
+ m_volumes.check_outside_state(build_volume, nullptr);
m_requires_check_outside_state = false;
}
-#else
- m_volumes.check_outside_state(m_config, nullptr);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
}
-#if !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
}
-#endif // !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
if (m_use_clipping_planes)
m_volumes.set_z_range(-m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]);
@@ -5206,11 +5139,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances());
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_mod");
-#else
- GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
if (shader != nullptr) {
shader->start_using();
@@ -5832,11 +5761,7 @@ void GLCanvas3D::_stop_timer()
m_timer.Stop();
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-void GLCanvas3D::_load_print_toolpaths(bool generate_convex_hulls)
-#else
-void GLCanvas3D::_load_print_toolpaths()
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume)
{
const Print *print = this->fff_print();
if (print == nullptr)
@@ -5889,18 +5814,11 @@ void GLCanvas3D::_load_print_toolpaths()
reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized);
}
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- if (generate_convex_hulls)
- volume->calc_convex_hull_3d();
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ volume->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(volume->indexed_vertex_array.vertices_and_normals_interleaved, volume->indexed_vertex_array.bounding_box());
volume->indexed_vertex_array.finalize_geometry(m_initialized);
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values, bool generate_convex_hulls)
-#else
-void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values)
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume& build_volume, const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values)
{
std::vector<std::array<float, 4>> tool_colors = _parse_colors(str_tool_colors);
@@ -6187,26 +6105,16 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
[](const GLVolume *volume) { return volume->empty(); }),
m_volumes.volumes.end());
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
- if (generate_convex_hulls)
- v->calc_convex_hull_3d();
+ v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
v->indexed_vertex_array.finalize_geometry(m_initialized);
}
-#else
- for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i)
- m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_initialized);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
}
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors, bool generate_convex_hulls)
-#else
-void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors)
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, const std::vector<std::string>& str_tool_colors)
{
const Print *print = this->fff_print();
if (print == nullptr || print->wipe_tower_data().tool_changes.empty())
@@ -6357,17 +6265,11 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
[](const GLVolume *volume) { return volume->empty(); }),
m_volumes.volumes.end());
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
- if (generate_convex_hulls)
- v->calc_convex_hull_3d();
+ v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
v->indexed_vertex_array.finalize_geometry(m_initialized);
}
-#else
- for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i)
- m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_initialized);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
}
@@ -6427,28 +6329,9 @@ void GLCanvas3D::_load_sla_shells()
update_volumes_colors_by_extruder();
}
-void GLCanvas3D::_update_toolpath_volumes_outside_state()
-{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- check_volumes_outside_state(true);
-#else
- BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
- for (GLVolume* volume : m_volumes.volumes) {
- volume->is_outside = (test_volume.radius() > 0.0 && volume->is_extrusion_path) ? !test_volume.contains(volume->bounding_box()) : false;
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
-}
-
void GLCanvas3D::_update_sla_shells_outside_state()
{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
check_volumes_outside_state();
-#else
- BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
- for (GLVolume* volume : m_volumes.volumes) {
- volume->is_outside = (test_volume.radius() > 0.0 && volume->shader_outside_printer_detection_enabled) ? !test_volume.contains(volume->transformed_convex_hull_bounding_box()) : false;
- }
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
}
void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 202036029..ffcc4a6a0 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -39,6 +39,7 @@ class wxGLContext;
namespace Slic3r {
class BackgroundSlicingProcess;
+class BuildVolume;
struct ThumbnailData;
struct ThumbnailsParams;
class ModelObject;
@@ -50,6 +51,8 @@ namespace CustomGCode { struct Item; }
namespace GUI {
+class Bed3D;
+
#if ENABLE_RETINA_GL
class RetinaHelper;
#endif
@@ -446,6 +449,7 @@ public:
private:
wxGLCanvas* m_canvas;
wxGLContext* m_context;
+ Bed3D &m_bed;
#if ENABLE_RETINA_GL
std::unique_ptr<RetinaHelper> m_retina_helper;
#endif
@@ -600,7 +604,7 @@ private:
m_gizmo_highlighter;
public:
- explicit GLCanvas3D(wxGLCanvas* canvas);
+ explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
~GLCanvas3D();
bool is_initialized() const { return m_initialized; }
@@ -621,11 +625,7 @@ public:
unsigned int get_volumes_count() const;
const GLVolumeCollection& get_volumes() const { return m_volumes; }
void reset_volumes();
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- ModelInstanceEPrintVolumeState check_volumes_outside_state(bool as_toolpaths = false) const;
-#else
ModelInstanceEPrintVolumeState check_volumes_outside_state() const;
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
#if ENABLE_SEAMS_USING_MODELS
void init_gcode_viewer() { m_gcode_viewer.init(); }
@@ -736,7 +736,7 @@ public:
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
- void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors);
+ void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
void refresh_gcode_preview_render_paths();
void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); }
GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); }
@@ -955,33 +955,19 @@ private:
void _start_timer();
void _stop_timer();
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// Create 3D thick extrusion lines for a skirt and brim.
- // Adds a new Slic3r::GUI::3DScene::Volume to volumes.
- void _load_print_toolpaths(bool generate_convex_hulls = false);
+ // Adds a new Slic3r::GUI::3DScene::Volume to volumes, updates collision with the build_volume.
+ void _load_print_toolpaths(const BuildVolume &build_volume);
// Create 3D thick extrusion lines for object forming extrusions.
// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
- // one for perimeters, one for infill and one for supports.
- void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors,
- const std::vector<CustomGCode::Item>& color_print_values, bool generate_convex_hulls = false);
- // Create 3D thick extrusion lines for wipe tower extrusions
- void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors, bool generate_convex_hulls = false);
-#else
- // Create 3D thick extrusion lines for a skirt and brim.
- // Adds a new Slic3r::GUI::3DScene::Volume to volumes.
- void _load_print_toolpaths();
- // Create 3D thick extrusion lines for object forming extrusions.
- // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
- // one for perimeters, one for infill and one for supports.
- void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors,
- const std::vector<CustomGCode::Item>& color_print_values);
- // Create 3D thick extrusion lines for wipe tower extrusions
- void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ // one for perimeters, one for infill and one for supports, updates collision with the build_volume.
+ void _load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume &build_volume,
+ const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values);
+ // Create 3D thick extrusion lines for wipe tower extrusions, updates collision with the build_volume.
+ void _load_wipe_tower_toolpaths(const BuildVolume &build_volume, const std::vector<std::string>& str_tool_colors);
// Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished.
void _load_sla_shells();
- void _update_toolpath_volumes_outside_state();
void _update_sla_shells_outside_state();
void _set_warning_notification_if_needed(EWarning warning);
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index e044056e6..4571b7346 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -2652,6 +2652,11 @@ Plater* GUI_App::plater()
return plater_;
}
+const Plater* GUI_App::plater() const
+{
+ return plater_;
+}
+
Model& GUI_App::model()
{
return plater_->model();
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 1d281cafe..95ac8c025 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -281,6 +281,7 @@ public:
ObjectList* obj_list();
ObjectLayers* obj_layers();
Plater* plater();
+ const Plater* plater() const;
Model& model();
NotificationManager * notification_manager();
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 9b1ee1cbf..69c855872 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -1758,12 +1758,9 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
new_object->invalidate_bounding_box();
new_object->translate(-bb.center());
- if (center) {
- const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb();
- new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -new_object->origin_translation.z()));
- } else {
- new_object->instances[0]->set_offset(bb.center());
- }
+ new_object->instances[0]->set_offset(center ?
+ to_3d(wxGetApp().plater()->build_volume().bounding_volume2d().center(), -new_object->origin_translation.z()) :
+ bb.center());
new_object->ensure_on_bed();
diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp
index d4aa918b4..f1607bafa 100644
--- a/src/slic3r/GUI/GUI_Preview.cpp
+++ b/src/slic3r/GUI/GUI_Preview.cpp
@@ -37,11 +37,11 @@
namespace Slic3r {
namespace GUI {
-View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
+View3D::View3D(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
: m_canvas_widget(nullptr)
, m_canvas(nullptr)
{
- init(parent, model, config, process);
+ init(parent, bed, model, config, process);
}
View3D::~View3D()
@@ -50,7 +50,7 @@ View3D::~View3D()
delete m_canvas_widget;
}
-bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
+bool View3D::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
{
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false;
@@ -59,7 +59,7 @@ bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, Ba
if (m_canvas_widget == nullptr)
return false;
- m_canvas = new GLCanvas3D(m_canvas_widget);
+ m_canvas = new GLCanvas3D(m_canvas_widget, bed);
m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget));
m_canvas->allow_multisample(OpenGLManager::can_multisample());
@@ -169,18 +169,18 @@ void View3D::render()
}
Preview::Preview(
- wxWindow* parent, Model* model, DynamicPrintConfig* config,
- BackgroundSlicingProcess* process, GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process_func)
+ wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config,
+ BackgroundSlicingProcess* process, GCodeProcessorResult* gcode_result, std::function<void()> schedule_background_process_func)
: m_config(config)
, m_process(process)
, m_gcode_result(gcode_result)
, m_schedule_background_process(schedule_background_process_func)
{
- if (init(parent, model))
+ if (init(parent, bed, model))
load_print();
}
-bool Preview::init(wxWindow* parent, Model* model)
+bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
{
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false;
@@ -196,7 +196,7 @@ bool Preview::init(wxWindow* parent, Model* model)
if (m_canvas_widget == nullptr)
return false;
- m_canvas = new GLCanvas3D(m_canvas_widget);
+ m_canvas = new GLCanvas3D(m_canvas_widget, bed);
m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget));
m_canvas->allow_multisample(OpenGLManager::can_multisample());
m_canvas->set_config(m_config);
diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp
index 97ced0a1e..42246aa18 100644
--- a/src/slic3r/GUI/GUI_Preview.hpp
+++ b/src/slic3r/GUI/GUI_Preview.hpp
@@ -44,7 +44,7 @@ class View3D : public wxPanel
GLCanvas3D* m_canvas;
public:
- View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
+ View3D(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
virtual ~View3D();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
@@ -70,7 +70,7 @@ public:
void render();
private:
- bool init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
+ bool init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
};
class Preview : public wxPanel
@@ -93,7 +93,7 @@ class Preview : public wxPanel
DynamicPrintConfig* m_config;
BackgroundSlicingProcess* m_process;
- GCodeProcessor::Result* m_gcode_result;
+ GCodeProcessorResult* m_gcode_result;
#ifdef __linux__
// We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955.
@@ -129,8 +129,8 @@ public:
Legend
};
- Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
- GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
+ Preview(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
+ GCodeProcessorResult* gcode_result, std::function<void()> schedule_background_process = []() {});
virtual ~Preview();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
@@ -161,7 +161,7 @@ public:
void hide_layers_slider();
private:
- bool init(wxWindow* parent, Model* model);
+ bool init(wxWindow* parent, Bed3D& bed, Model* model);
void bind_event_handlers();
void unbind_event_handlers();
diff --git a/src/slic3r/GUI/GalleryDialog.cpp b/src/slic3r/GUI/GalleryDialog.cpp
index 2aba75fba..1191e5c2e 100644
--- a/src/slic3r/GUI/GalleryDialog.cpp
+++ b/src/slic3r/GUI/GalleryDialog.cpp
@@ -26,10 +26,10 @@
#include "3DScene.hpp"
#include "GLCanvas3D.hpp"
#include "Plater.hpp"
-#include "3DBed.hpp"
#include "MsgDialog.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/AppConfig.hpp"
+#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/GCode/ThumbnailData.hpp"
#include "libslic3r/Format/OBJ.hpp"
@@ -270,9 +270,7 @@ static void generate_thumbnail_from_model(const std::string& filename)
model.objects[0]->center_around_origin(false);
model.objects[0]->ensure_on_bed(false);
- const Vec3d bed_center_3d = wxGetApp().plater()->get_bed().get_bounding_box(false).center();
- const Vec2d bed_center_2d = { bed_center_3d.x(), bed_center_3d.y()};
- model.center_instances_around_point(bed_center_2d);
+ model.center_instances_around_point(to_2d(wxGetApp().plater()->build_volume().bounding_volume().center()));
GLVolumeCollection volumes;
volumes.volumes.push_back(new GLVolume());
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
index 9e30202bd..9034d78d8 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
@@ -3,6 +3,7 @@
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
+#include "libslic3r/Geometry/ConvexHull.hpp"
#include "libslic3r/Model.hpp"
#include <numeric>
diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp
index f63cf5585..2771f9d27 100644
--- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp
+++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp
@@ -1,5 +1,6 @@
#include "ArrangeJob.hpp"
+#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/MTUtils.hpp"
#include "libslic3r/Model.hpp"
@@ -263,7 +264,7 @@ get_wipe_tower_arrangepoly(const Plater &plater)
}
double bed_stride(const Plater *plater) {
- double bedwidth = plater->bed_shape_bb().size().x();
+ double bedwidth = plater->build_volume().bounding_volume().size().x();
return scaled<double>((1. + LOGICAL_BED_GAP) * bedwidth);
}
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index c2344274a..6002e1d52 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -486,7 +486,7 @@ void MainFrame::update_layout()
case ESettingsLayout::GCodeViewer:
{
m_main_sizer->Add(m_plater, 1, wxEXPAND);
- m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, "", "", true);
+ m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, 0, {}, {}, true);
m_plater->get_collapse_toolbar().set_enabled(false);
m_plater->collapse_sidebar(true);
m_plater->Show();
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 04ccbb183..9d8fdc74c 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1554,7 +1554,7 @@ struct Plater::priv
Slic3r::SLAPrint sla_print;
Slic3r::Model model;
PrinterTechnology printer_technology = ptFFF;
- Slic3r::GCodeProcessor::Result gcode_result;
+ Slic3r::GCodeProcessorResult gcode_result;
// GUI elements
wxSizer* panel_sizer{ nullptr };
@@ -1717,8 +1717,6 @@ struct Plater::priv
void update_main_toolbar_tooltips();
// std::shared_ptr<ProgressStatusBar> statusbar();
std::string get_config(const std::string &key) const;
- BoundingBoxf bed_shape_bb() const;
- BoundingBox scaled_bed_shape_bb() const;
std::vector<size_t> load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool used_inches = false);
std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false);
@@ -1842,7 +1840,7 @@ struct Plater::priv
// triangulate the bed and store the triangles into m_bed.m_triangles,
// fills the m_bed.m_grid_lines and sets m_bed.m_origin.
// Sets m_bed.m_polygon to limit the object placement.
- void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
+ void set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
bool can_delete() const;
bool can_delete_all() const;
@@ -1956,8 +1954,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
sla_print.set_status_callback(statuscb);
this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
- view3D = new View3D(q, &model, config, &background_process);
- preview = new Preview(q, &model, config, &background_process, &gcode_result, [this]() { schedule_background_process(); });
+ view3D = new View3D(q, bed, &model, config, &background_process);
+ preview = new Preview(q, bed, &model, config, &background_process, &gcode_result, [this]() { schedule_background_process(); });
#ifdef __APPLE__
// set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size
@@ -2172,13 +2170,8 @@ void Plater::priv::update(unsigned int flags)
{
// the following line, when enabled, causes flickering on NVIDIA graphics cards
// wxWindowUpdateLocker freeze_guard(q);
- if (get_config("autocenter") == "1") {
- // auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
- // const auto bed_shape = Slic3r::Polygon::new_scale(bed_shape_opt->values);
- // const BoundingBox bed_shape_bb = bed_shape.bounding_box();
- const Vec2d& bed_center = bed_shape_bb().center();
- model.center_instances_around_point(bed_center);
- }
+ if (get_config("autocenter") == "1")
+ model.center_instances_around_point(this->bed.build_volume().bed_center());
unsigned int update_status = 0;
const bool force_background_processing_restart = this->printer_technology == ptSLA || (flags & (unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE);
@@ -2281,19 +2274,6 @@ std::string Plater::priv::get_config(const std::string &key) const
return wxGetApp().app_config->get(key);
}
-BoundingBoxf Plater::priv::bed_shape_bb() const
-{
- BoundingBox bb = scaled_bed_shape_bb();
- return BoundingBoxf(unscale(bb.min), unscale(bb.max));
-}
-
-BoundingBox Plater::priv::scaled_bed_shape_bb() const
-{
- const auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
- const auto bed_shape = Slic3r::Polygon::new_scale(bed_shape_opt->values);
- return bed_shape.bounding_box();
-}
-
std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool imperial_units/* = false*/)
{
if (input_files.empty()) { return std::vector<size_t>(); }
@@ -2564,7 +2544,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
if (one_by_one) {
if (type_3mf && !is_project_file)
- model.center_instances_around_point(bed_shape_bb().center());
+ model.center_instances_around_point(this->bed.build_volume().bed_center());
auto loaded_idxs = load_model_objects(model.objects, is_project_file);
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
} else {
@@ -2623,8 +2603,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z)
{
- const BoundingBoxf bed_shape = bed_shape_bb();
- const Vec3d bed_size = Slic3r::to_3d(bed_shape.size().cast<double>(), 1.0) - 2.0 * Vec3d::Ones();
+ const Vec3d bed_size = Slic3r::to_3d(this->bed.build_volume().bounding_volume2d().size(), 1.0) - 2.0 * Vec3d::Ones();
#ifndef AUTOPLACEMENT_ON_LOAD
// bool need_arrange = false;
@@ -2652,7 +2631,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
// add a default instance and center object around origin
object->center_around_origin(); // also aligns object to Z = 0
ModelInstance* instance = object->add_instance();
- instance->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -object->origin_translation(2)));
+ instance->set_offset(Slic3r::to_3d(this->bed.build_volume().bed_center(), -object->origin_translation(2)));
#endif /* AUTOPLACEMENT_ON_LOAD */
}
@@ -2989,7 +2968,7 @@ void Plater::find_new_position(const ModelInstancePtrs &instances)
if (auto wt = get_wipe_tower_arrangepoly(*this))
fixed.emplace_back(*wt);
- arrangement::arrange(movable, fixed, get_bed_shape(*config()), arr_params);
+ arrangement::arrange(movable, fixed, this->build_volume().polygon(), arr_params);
for (auto & m : movable)
m.apply();
@@ -3057,22 +3036,9 @@ void Plater::priv::schedule_background_process()
void Plater::priv::update_print_volume_state()
{
-#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
- const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(this->config->option("bed_shape"));
- const Polygon bed_poly_convex = offset(Geometry::convex_hull(Polygon::new_scale(opt->values).points), static_cast<float>(scale_(BedEpsilon))).front();
- const float bed_height = this->config->opt_float("max_print_height");
- this->q->model().update_print_volume_state(bed_poly_convex, bed_height);
-#else
- BoundingBox bed_box_2D = get_extents(Polygon::new_scale(this->config->opt<ConfigOptionPoints>("bed_shape")->values));
- BoundingBoxf3 print_volume(unscale(bed_box_2D.min(0), bed_box_2D.min(1), 0.0), unscale(bed_box_2D.max(0), bed_box_2D.max(1), scale_(this->config->opt_float("max_print_height"))));
- // Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
- print_volume.offset(BedEpsilon);
- print_volume.min(2) = -1e10;
- this->q->model().update_print_volume_state(print_volume);
-#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
+ this->q->model().update_print_volume_state(this->bed.build_volume());
}
-
void Plater::priv::process_validation_warning(const std::string& warning) const
{
if (warning.empty())
@@ -4588,9 +4554,9 @@ bool Plater::priv::can_reload_from_disk() const
return !paths.empty();
}
-void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
+void Plater::priv::set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
{
- bool new_shape = bed.set_shape(shape, custom_texture, custom_model, force_as_custom);
+ bool new_shape = bed.set_shape(shape, max_print_height, custom_texture, custom_model, force_as_custom);
if (new_shape) {
if (view3D) view3D->bed_shape_changed();
if (preview) preview->bed_shape_changed();
@@ -6278,13 +6244,14 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
void Plater::set_bed_shape() const
{
set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values,
+ p->config->option<ConfigOptionFloat>("max_print_height")->value,
p->config->option<ConfigOptionString>("bed_custom_texture")->value,
p->config->option<ConfigOptionString>("bed_custom_model")->value);
}
-void Plater::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const
+void Plater::set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const
{
- p->set_bed_shape(shape, custom_texture, custom_model, force_as_custom);
+ p->set_bed_shape(shape, max_print_height, custom_texture, custom_model, force_as_custom);
}
void Plater::force_filament_colors_update()
@@ -6339,7 +6306,7 @@ void Plater::on_activate()
}
// Get vector of extruder colors considering filament color, if extruder color is undefined.
-std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GCodeProcessor::Result* const result) const
+std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result) const
{
if (wxGetApp().is_gcode_viewer() && result != nullptr)
return result->extruder_colors;
@@ -6365,7 +6332,7 @@ std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GC
/* Get vector of colors used for rendering of a Preview scene in "Color print" mode
* It consists of extruder colors and colors, saved in model.custom_gcode_per_print_z
*/
-std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessor::Result* const result) const
+std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessorResult* const result) const
{
std::vector<std::string> colors = get_extruder_colors_from_plater_config(result);
colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size());
@@ -6431,11 +6398,6 @@ GLCanvas3D* Plater::get_current_canvas3D()
return p->get_current_canvas3D();
}
-BoundingBoxf Plater::bed_shape_bb() const
-{
- return p->bed_shape_bb();
-}
-
void Plater::arrange()
{
p->m_ui_jobs.arrange();
@@ -6725,14 +6687,9 @@ unsigned int Plater::get_environment_texture_id() const
}
#endif // ENABLE_ENVIRONMENT_MAP
-const Bed3D& Plater::get_bed() const
-{
- return p->bed;
-}
-
-Bed3D& Plater::get_bed()
+const BuildVolume& Plater::build_volume() const
{
- return p->bed;
+ return p->bed.build_volume();
}
const GLToolbar& Plater::get_view_toolbar() const
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 8bc683635..4c9bfc763 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -23,6 +23,7 @@ class wxString;
namespace Slic3r {
+class BuildVolume;
class Model;
class ModelObject;
enum class ModelObjectCutAttribute : int;
@@ -53,7 +54,6 @@ class GLCanvas3D;
class Mouse3DController;
class NotificationManager;
struct Camera;
-class Bed3D;
class GLToolbar;
class PlaterPresetComboBox;
@@ -265,8 +265,8 @@ public:
void force_print_bed_update();
// On activating the parent window.
void on_activate();
- std::vector<std::string> get_extruder_colors_from_plater_config(const GCodeProcessor::Result* const result = nullptr) const;
- std::vector<std::string> get_colors_for_color_print(const GCodeProcessor::Result* const result = nullptr) const;
+ std::vector<std::string> get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result = nullptr) const;
+ std::vector<std::string> get_colors_for_color_print(const GCodeProcessorResult* const result = nullptr) const;
void update_menus();
void show_action_buttons(const bool is_ready_to_slice) const;
@@ -282,7 +282,6 @@ public:
GLCanvas3D* canvas3D();
const GLCanvas3D * canvas3D() const;
GLCanvas3D* get_current_canvas3D();
- BoundingBoxf bed_shape_bb() const;
void arrange();
void find_new_position(const ModelInstancePtrs &instances);
@@ -339,8 +338,7 @@ public:
unsigned int get_environment_texture_id() const;
#endif // ENABLE_ENVIRONMENT_MAP
- const Bed3D& get_bed() const;
- Bed3D& get_bed();
+ const BuildVolume& build_volume() const;
const GLToolbar& get_view_toolbar() const;
GLToolbar& get_view_toolbar();
@@ -359,7 +357,7 @@ public:
Mouse3DController& get_mouse3d_controller();
void set_bed_shape() const;
- void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
+ void set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
NotificationManager * get_notification_manager();
const NotificationManager * get_notification_manager() const;