mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-26 10:11:10 -06:00
New BuildVolume class was created, which detects build volume type (rectangular,
circular, convex, concave) and performs efficient collision detection agains these build volumes. As of now, collision detection is performed against a convex hull of a concave build volume for efficency. GCodeProcessor::Result renamed out of GCodeProcessor to GCodeProcessorResult, so it could be forward declared. Plater newly exports BuildVolume, not Bed3D. Bed3D is a rendering class, while BuildVolume is a purely geometric class. Reduced usage of global wxGetApp, the Bed3D is passed as a parameter to View3D/Preview/GLCanvas. Convex hull code was extracted from Geometry.cpp/hpp to Geometry/ConvexHulll.cpp,hpp. New test inside_convex_polygon(). New efficent point inside polygon test: Decompose convex hull to bottom / top parts and use the decomposition to detect point inside a convex polygon in O(log n). decompose_convex_polygon_top_bottom(), inside_convex_polygon(). New Circle constructing functions: circle_ransac() and circle_taubin_newton(). New polygon_is_convex() test with unit tests.
This commit is contained in:
parent
b431fd1f7e
commit
cc44089440
51 changed files with 1544 additions and 1594 deletions
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
~Bed3D() { release_VBOs(); }
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
const BoundingBoxf3& get_bounding_box(bool extended) const { return extended ? m_extended_bounding_box : m_bounding_box; }
|
||||
// Build volume geometry for various collision detection tasks.
|
||||
const BuildVolume& build_volume() const { return m_build_volume; }
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -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, ¢er, &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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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, ¢er, &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);
|
||||
}
|
||||
|
||||
optgroup->append_single_option_line({ def, std::move(key) });
|
||||
}
|
||||
|
||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||
wxString BedShape::get_name(Bed3D::EShapeType type)
|
||||
wxString BedShape::get_name(PageType 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");
|
||||
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 {};
|
||||
}
|
||||
#else
|
||||
wxString BedShape::get_name(Type 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");
|
||||
}
|
||||
}
|
||||
#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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(), ¢er, &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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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(), ¢er, &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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ public:
|
|||
ObjectList* obj_list();
|
||||
ObjectLayers* obj_layers();
|
||||
Plater* plater();
|
||||
const Plater* plater() const;
|
||||
Model& model();
|
||||
NotificationManager * notification_manager();
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
const BuildVolume& Plater::build_volume() const
|
||||
{
|
||||
return p->bed;
|
||||
}
|
||||
|
||||
Bed3D& Plater::get_bed()
|
||||
{
|
||||
return p->bed;
|
||||
return p->bed.build_volume();
|
||||
}
|
||||
|
||||
const GLToolbar& Plater::get_view_toolbar() const
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue