mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
optimize icon position for circle bed
This commit is contained in:
parent
cb22560d38
commit
ef3614a21a
12 changed files with 99 additions and 67 deletions
|
@ -70,6 +70,26 @@ public:
|
||||||
return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
|
return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
|
||||||
this->max(1) < other.min(1) || this->min(1) > other.max(1));
|
this->max(1) < other.min(1) || this->min(1) > other.max(1));
|
||||||
}
|
}
|
||||||
|
PointClass operator[](size_t idx) const {
|
||||||
|
switch (idx) {
|
||||||
|
case 0:
|
||||||
|
return min;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return PointClass(max(0), min(1));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return max;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return PointClass(min(0), max(1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return PointClass();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return PointClass();
|
||||||
|
}
|
||||||
bool operator==(const BoundingBoxBase<PointClass> &rhs) { return this->min == rhs.min && this->max == rhs.max; }
|
bool operator==(const BoundingBoxBase<PointClass> &rhs) { return this->min == rhs.min && this->max == rhs.max; }
|
||||||
bool operator!=(const BoundingBoxBase<PointClass> &rhs) { return ! (*this == rhs); }
|
bool operator!=(const BoundingBoxBase<PointClass> &rhs) { return ! (*this == rhs); }
|
||||||
friend std::ostream &operator<<(std::ostream &os, const BoundingBoxBase &bbox)
|
friend std::ostream &operator<<(std::ostream &os, const BoundingBoxBase &bbox)
|
||||||
|
|
|
@ -24,7 +24,7 @@ BuildVolume::BuildVolume(const std::vector<Vec2d> &printable_area, const double
|
||||||
|
|
||||||
if (printable_area.size() >= 4 && std::abs((m_area - double(m_bbox.size().x()) * double(m_bbox.size().y()))) < sqr(SCALED_EPSILON)) {
|
if (printable_area.size() >= 4 && std::abs((m_area - double(m_bbox.size().x()) * double(m_bbox.size().y()))) < sqr(SCALED_EPSILON)) {
|
||||||
// Square print bed, use the bounding box for collision detection.
|
// Square print bed, use the bounding box for collision detection.
|
||||||
m_type = Type::Rectangle;
|
m_type = BuildVolume_Type::Rectangle;
|
||||||
m_circle.center = 0.5 * (m_bbox.min.cast<double>() + m_bbox.max.cast<double>());
|
m_circle.center = 0.5 * (m_bbox.min.cast<double>() + m_bbox.max.cast<double>());
|
||||||
m_circle.radius = 0.5 * m_bbox.size().cast<double>().norm();
|
m_circle.radius = 0.5 * m_bbox.size().cast<double>().norm();
|
||||||
} else if (printable_area.size() > 3) {
|
} else if (printable_area.size() > 3) {
|
||||||
|
@ -52,16 +52,16 @@ BuildVolume::BuildVolume(const std::vector<Vec2d> &printable_area, const double
|
||||||
prev = p;
|
prev = p;
|
||||||
}
|
}
|
||||||
if (is_circle) {
|
if (is_circle) {
|
||||||
m_type = Type::Circle;
|
m_type = BuildVolume_Type::Circle;
|
||||||
m_circle.center = scaled<double>(m_circle.center);
|
m_circle.center = scaled<double>(m_circle.center);
|
||||||
m_circle.radius = scaled<double>(m_circle.radius);
|
m_circle.radius = scaled<double>(m_circle.radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printable_area.size() >= 3 && m_type == Type::Invalid) {
|
if (printable_area.size() >= 3 && m_type == BuildVolume_Type::Invalid) {
|
||||||
// Circle check is not used for Convex / Custom shapes, fill it with something reasonable.
|
// Circle check is not used for Convex / Custom shapes, fill it with something reasonable.
|
||||||
m_circle = Geometry::smallest_enclosing_circle_welzl(m_convex_hull.points);
|
m_circle = Geometry::smallest_enclosing_circle_welzl(m_convex_hull.points);
|
||||||
m_type = (m_convex_hull.area() - m_area) < sqr(SCALED_EPSILON) ? Type::Convex : Type::Custom;
|
m_type = (m_convex_hull.area() - m_area) < sqr(SCALED_EPSILON) ? BuildVolume_Type::Convex : BuildVolume_Type::Custom;
|
||||||
// Initialize the top / bottom decomposition for inside convex polygon check. Do it with two different epsilons applied.
|
// Initialize the top / bottom decomposition for inside convex polygon check. Do it with two different epsilons applied.
|
||||||
auto convex_decomposition = [](const Polygon &in, double epsilon) {
|
auto convex_decomposition = [](const Polygon &in, double epsilon) {
|
||||||
Polygon src = expand(in, float(epsilon)).front();
|
Polygon src = expand(in, float(epsilon)).front();
|
||||||
|
@ -272,7 +272,7 @@ BuildVolume::ObjectState object_state_templ(const indexed_triangle_set &its, con
|
||||||
BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& its, const Transform3f& trafo, bool may_be_below_bed, bool ignore_bottom) const
|
BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& its, const Transform3f& trafo, bool may_be_below_bed, bool ignore_bottom) const
|
||||||
{
|
{
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Type::Rectangle:
|
case BuildVolume_Type::Rectangle:
|
||||||
{
|
{
|
||||||
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(SceneEpsilon);
|
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(SceneEpsilon);
|
||||||
if (m_max_print_height == 0.0)
|
if (m_max_print_height == 0.0)
|
||||||
|
@ -285,20 +285,20 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i
|
||||||
//FIXME This test does NOT correctly interprets intersection of a non-convex object with a rectangular build volume.
|
//FIXME This test does NOT correctly interprets intersection of a non-convex object with a rectangular build volume.
|
||||||
return object_state_templ(its, trafo, may_be_below_bed, [build_volumef](const Vec3f &pt) { return build_volumef.contains(pt); });
|
return object_state_templ(its, trafo, may_be_below_bed, [build_volumef](const Vec3f &pt) { return build_volumef.contains(pt); });
|
||||||
}
|
}
|
||||||
case Type::Circle:
|
case BuildVolume_Type::Circle:
|
||||||
{
|
{
|
||||||
Geometry::Circlef circle { unscaled<float>(m_circle.center), unscaled<float>(m_circle.radius + SceneEpsilon) };
|
Geometry::Circlef circle { unscaled<float>(m_circle.center), unscaled<float>(m_circle.radius + SceneEpsilon) };
|
||||||
return m_max_print_height == 0.0 ?
|
return m_max_print_height == 0.0 ?
|
||||||
object_state_templ(its, trafo, may_be_below_bed, [circle](const Vec3f &pt) { return circle.contains(to_2d(pt)); }) :
|
object_state_templ(its, trafo, may_be_below_bed, [circle](const Vec3f &pt) { return circle.contains(to_2d(pt)); }) :
|
||||||
object_state_templ(its, trafo, may_be_below_bed, [circle, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && circle.contains(to_2d(pt)); });
|
object_state_templ(its, trafo, may_be_below_bed, [circle, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && circle.contains(to_2d(pt)); });
|
||||||
}
|
}
|
||||||
case Type::Convex:
|
case BuildVolume_Type::Convex:
|
||||||
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
||||||
case Type::Custom:
|
case BuildVolume_Type::Custom:
|
||||||
return m_max_print_height == 0.0 ?
|
return m_max_print_height == 0.0 ?
|
||||||
object_state_templ(its, trafo, may_be_below_bed, [this](const Vec3f &pt) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast<double>()); }) :
|
object_state_templ(its, trafo, may_be_below_bed, [this](const Vec3f &pt) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast<double>()); }) :
|
||||||
object_state_templ(its, trafo, may_be_below_bed, [this, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast<double>()); });
|
object_state_templ(its, trafo, may_be_below_bed, [this, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast<double>()); });
|
||||||
case Type::Invalid:
|
case BuildVolume_Type::Invalid:
|
||||||
default:
|
default:
|
||||||
return ObjectState::Inside;
|
return ObjectState::Inside;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i
|
||||||
|
|
||||||
BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom) const
|
BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom) const
|
||||||
{
|
{
|
||||||
assert(m_type == Type::Rectangle);
|
assert(m_type == BuildVolume_Type::Rectangle);
|
||||||
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(SceneEpsilon);
|
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(SceneEpsilon);
|
||||||
if (m_max_print_height == 0.0)
|
if (m_max_print_height == 0.0)
|
||||||
build_volume.max.z() = std::numeric_limits<double>::max();
|
build_volume.max.z() = std::numeric_limits<double>::max();
|
||||||
|
@ -325,7 +325,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun
|
||||||
static constexpr const double epsilon = BedEpsilon;
|
static constexpr const double epsilon = BedEpsilon;
|
||||||
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Type::Rectangle:
|
case BuildVolume_Type::Rectangle:
|
||||||
{
|
{
|
||||||
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
|
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
|
||||||
if (m_max_print_height == 0.0)
|
if (m_max_print_height == 0.0)
|
||||||
|
@ -334,7 +334,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun
|
||||||
build_volume.min.z() = -std::numeric_limits<double>::max();
|
build_volume.min.z() = -std::numeric_limits<double>::max();
|
||||||
return build_volume.contains(paths_bbox);
|
return build_volume.contains(paths_bbox);
|
||||||
}
|
}
|
||||||
case Type::Circle:
|
case BuildVolume_Type::Circle:
|
||||||
{
|
{
|
||||||
const Vec2f c = unscaled<float>(m_circle.center);
|
const Vec2f c = unscaled<float>(m_circle.center);
|
||||||
const float r = unscaled<double>(m_circle.radius) + epsilon;
|
const float r = unscaled<double>(m_circle.radius) + epsilon;
|
||||||
|
@ -345,9 +345,9 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun
|
||||||
std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2, z = m_max_print_height + epsilon](const GCodeProcessorResult::MoveVertex& move)
|
std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2, z = m_max_print_height + epsilon](const GCodeProcessorResult::MoveVertex& move)
|
||||||
{ return ! move_valid(move) || ((to_2d(move.position) - c).squaredNorm() <= r2 && move.position.z() <= z); });
|
{ return ! move_valid(move) || ((to_2d(move.position) - c).squaredNorm() <= r2 && move.position.z() <= z); });
|
||||||
}
|
}
|
||||||
case Type::Convex:
|
case BuildVolume_Type::Convex:
|
||||||
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
||||||
case Type::Custom:
|
case BuildVolume_Type::Custom:
|
||||||
return m_max_print_height == 0.0 ?
|
return m_max_print_height == 0.0 ?
|
||||||
std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, this](const GCodeProcessorResult::MoveVertex &move)
|
std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, this](const GCodeProcessorResult::MoveVertex &move)
|
||||||
{ return ! move_valid(move) || Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(move.position).cast<double>()); }) :
|
{ return ! move_valid(move) || Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(move.position).cast<double>()); }) :
|
||||||
|
@ -375,7 +375,7 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v
|
||||||
assert(paths.size() % 6 == 0);
|
assert(paths.size() % 6 == 0);
|
||||||
static constexpr const double epsilon = BedEpsilon;
|
static constexpr const double epsilon = BedEpsilon;
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Type::Rectangle:
|
case BuildVolume_Type::Rectangle:
|
||||||
{
|
{
|
||||||
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
|
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
|
||||||
if (m_max_print_height == 0.0)
|
if (m_max_print_height == 0.0)
|
||||||
|
@ -384,7 +384,7 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v
|
||||||
build_volume.min.z() = -std::numeric_limits<double>::max();
|
build_volume.min.z() = -std::numeric_limits<double>::max();
|
||||||
return build_volume.contains(paths_bbox.min().cast<double>()) && build_volume.contains(paths_bbox.max().cast<double>());
|
return build_volume.contains(paths_bbox.min().cast<double>()) && build_volume.contains(paths_bbox.max().cast<double>());
|
||||||
}
|
}
|
||||||
case Type::Circle:
|
case BuildVolume_Type::Circle:
|
||||||
{
|
{
|
||||||
const Vec2f c = unscaled<float>(m_circle.center);
|
const Vec2f c = unscaled<float>(m_circle.center);
|
||||||
const float r = unscaled<double>(m_circle.radius) + float(epsilon);
|
const float r = unscaled<double>(m_circle.radius) + float(epsilon);
|
||||||
|
@ -393,9 +393,9 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v
|
||||||
all_inside_vertices_normals_interleaved(paths, [c, r2](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2; }) :
|
all_inside_vertices_normals_interleaved(paths, [c, r2](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2; }) :
|
||||||
all_inside_vertices_normals_interleaved(paths, [c, r2, z = m_max_print_height + epsilon](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2 && p.z() <= z; });
|
all_inside_vertices_normals_interleaved(paths, [c, r2, z = m_max_print_height + epsilon](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2 && p.z() <= z; });
|
||||||
}
|
}
|
||||||
case Type::Convex:
|
case BuildVolume_Type::Convex:
|
||||||
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
||||||
case Type::Custom:
|
case BuildVolume_Type::Custom:
|
||||||
return m_max_print_height == 0.0 ?
|
return m_max_print_height == 0.0 ?
|
||||||
all_inside_vertices_normals_interleaved(paths, [this](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()); }) :
|
all_inside_vertices_normals_interleaved(paths, [this](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()); }) :
|
||||||
all_inside_vertices_normals_interleaved(paths, [this, z = m_max_print_height + epsilon](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()) && p.z() <= z; });
|
all_inside_vertices_normals_interleaved(paths, [this, z = m_max_print_height + epsilon](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()) && p.z() <= z; });
|
||||||
|
@ -404,15 +404,15 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view BuildVolume::type_name(Type type)
|
std::string_view BuildVolume::type_name(BuildVolume_Type type)
|
||||||
{
|
{
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::Invalid: return "Invalid"sv;
|
case BuildVolume_Type::Invalid: return "Invalid"sv;
|
||||||
case Type::Rectangle: return "Rectangle"sv;
|
case BuildVolume_Type::Rectangle: return "Rectangle"sv;
|
||||||
case Type::Circle: return "Circle"sv;
|
case BuildVolume_Type::Circle: return "Circle"sv;
|
||||||
case Type::Convex: return "Convex"sv;
|
case BuildVolume_Type::Convex: return "Convex"sv;
|
||||||
case Type::Custom: return "Custom"sv;
|
case BuildVolume_Type::Custom: return "Custom"sv;
|
||||||
}
|
}
|
||||||
// make visual studio happy
|
// make visual studio happy
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
|
@ -12,24 +12,23 @@
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
struct GCodeProcessorResult;
|
struct GCodeProcessorResult;
|
||||||
|
enum class BuildVolume_Type : unsigned char {
|
||||||
|
// Not set yet or undefined.
|
||||||
|
Invalid,
|
||||||
|
// Rectangular print bed. Most common, cheap to work with.
|
||||||
|
Rectangle,
|
||||||
|
// Circular print bed. Common on detals, cheap to work with.
|
||||||
|
Circle,
|
||||||
|
// Convex print bed. Complex to process.
|
||||||
|
Convex,
|
||||||
|
// Some non convex shape.
|
||||||
|
Custom
|
||||||
|
};
|
||||||
// For collision detection of objects and G-code (extrusion paths) against the build volume.
|
// For collision detection of objects and G-code (extrusion paths) against the build volume.
|
||||||
class BuildVolume
|
class BuildVolume
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class Type : unsigned char
|
|
||||||
{
|
|
||||||
// Not set yet or undefined.
|
|
||||||
Invalid,
|
|
||||||
// Rectangular print bed. Most common, cheap to work with.
|
|
||||||
Rectangle,
|
|
||||||
// Circular print bed. Common on detals, cheap to work with.
|
|
||||||
Circle,
|
|
||||||
// Convex print bed. Complex to process.
|
|
||||||
Convex,
|
|
||||||
// Some non convex shape.
|
|
||||||
Custom
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialized to empty, all zeros, Invalid.
|
// Initialized to empty, all zeros, Invalid.
|
||||||
BuildVolume() {}
|
BuildVolume() {}
|
||||||
|
@ -41,11 +40,11 @@ public:
|
||||||
double printable_height() const { return m_max_print_height; }
|
double printable_height() const { return m_max_print_height; }
|
||||||
|
|
||||||
// Derived data
|
// Derived data
|
||||||
Type type() const { return m_type; }
|
BuildVolume_Type type() const { return m_type; }
|
||||||
// Format the type for console output.
|
// Format the type for console output.
|
||||||
static std::string_view type_name(Type type);
|
static std::string_view type_name(BuildVolume_Type type);
|
||||||
std::string_view type_name() const { return type_name(m_type); }
|
std::string_view type_name() const { return type_name(m_type); }
|
||||||
bool valid() const { return m_type != Type::Invalid; }
|
bool valid() const { return m_type != BuildVolume_Type::Invalid; }
|
||||||
// Same as printable_area(), but scaled coordinates.
|
// Same as printable_area(), but scaled coordinates.
|
||||||
const Polygon& polygon() const { return m_polygon; }
|
const Polygon& polygon() const { return m_polygon; }
|
||||||
// Bounding box of polygon(), scaled.
|
// Bounding box of polygon(), scaled.
|
||||||
|
@ -101,7 +100,7 @@ private:
|
||||||
double m_max_print_height { 0.f };
|
double m_max_print_height { 0.f };
|
||||||
|
|
||||||
// Derived values.
|
// Derived values.
|
||||||
Type m_type { Type::Invalid };
|
BuildVolume_Type m_type { BuildVolume_Type::Invalid };
|
||||||
// Geometry of the print bed, scaled copy of m_bed_shape.
|
// Geometry of the print bed, scaled copy of m_bed_shape.
|
||||||
Polygon m_polygon;
|
Polygon m_polygon;
|
||||||
// Scaled snug bounding box around m_polygon.
|
// Scaled snug bounding box around m_polygon.
|
||||||
|
|
|
@ -131,6 +131,9 @@ public:
|
||||||
// Was the model generated procedurally?
|
// Was the model generated procedurally?
|
||||||
bool is_custom() const { return m_type == Type::Custom; }
|
bool is_custom() const { return m_type == Type::Custom; }
|
||||||
|
|
||||||
|
// get the bed shape type
|
||||||
|
BuildVolume_Type get_build_volume_type() const { return m_build_volume.type(); }
|
||||||
|
|
||||||
// Bounding box around the print bed, axes and model, for rendering.
|
// Bounding box around the print bed, axes and model, for rendering.
|
||||||
const BoundingBoxf3& extended_bounding_box() const { return m_extended_bounding_box; }
|
const BoundingBoxf3& extended_bounding_box() const { return m_extended_bounding_box; }
|
||||||
|
|
||||||
|
|
|
@ -1414,14 +1414,14 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
|
||||||
state = BuildVolume::ObjectState::Below;
|
state = BuildVolume::ObjectState::Below;
|
||||||
else {
|
else {
|
||||||
switch (plate_build_volume.type()) {
|
switch (plate_build_volume.type()) {
|
||||||
case BuildVolume::Type::Rectangle:
|
case BuildVolume_Type::Rectangle:
|
||||||
//FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
|
//FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
|
||||||
state = plate_build_volume.volume_state_bbox(bb);
|
state = plate_build_volume.volume_state_bbox(bb);
|
||||||
break;
|
break;
|
||||||
case BuildVolume::Type::Circle:
|
case BuildVolume_Type::Circle:
|
||||||
case BuildVolume::Type::Convex:
|
case BuildVolume_Type::Convex:
|
||||||
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
||||||
case BuildVolume::Type::Custom:
|
case BuildVolume_Type::Custom:
|
||||||
state = plate_build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
|
state = plate_build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -88,11 +88,11 @@ wxString BedShape::get_name(PageType type)
|
||||||
BedShape::PageType BedShape::get_page_type()
|
BedShape::PageType BedShape::get_page_type()
|
||||||
{
|
{
|
||||||
switch (m_build_volume.type()) {
|
switch (m_build_volume.type()) {
|
||||||
case BuildVolume::Type::Rectangle:
|
case BuildVolume_Type::Rectangle:
|
||||||
case BuildVolume::Type::Invalid: return PageType::Rectangle;
|
case BuildVolume_Type::Invalid: return PageType::Rectangle;
|
||||||
case BuildVolume::Type::Circle: return PageType::Circle;
|
case BuildVolume_Type::Circle: return PageType::Circle;
|
||||||
case BuildVolume::Type::Convex:
|
case BuildVolume_Type::Convex:
|
||||||
case BuildVolume::Type::Custom: return PageType::Custom;
|
case BuildVolume_Type::Custom: return PageType::Custom;
|
||||||
}
|
}
|
||||||
// make visual studio happy
|
// make visual studio happy
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -103,7 +103,7 @@ wxString BedShape::get_full_name_with_params()
|
||||||
{
|
{
|
||||||
wxString out = _L("Shape") + ": " + get_name(this->get_page_type());
|
wxString out = _L("Shape") + ": " + get_name(this->get_page_type());
|
||||||
switch (m_build_volume.type()) {
|
switch (m_build_volume.type()) {
|
||||||
case BuildVolume::Type::Circle:
|
case BuildVolume_Type::Circle:
|
||||||
out += "\n" + _L(get_option_label(Parameter::Diameter)) + ": [" + double_to_string(2. * unscaled<double>(m_build_volume.circle().radius)) + "]";
|
out += "\n" + _L(get_option_label(Parameter::Diameter)) + ": [" + double_to_string(2. * unscaled<double>(m_build_volume.circle().radius)) + "]";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -118,7 +118,7 @@ wxString BedShape::get_full_name_with_params()
|
||||||
void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
|
void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
|
||||||
{
|
{
|
||||||
switch (m_build_volume.type()) {
|
switch (m_build_volume.type()) {
|
||||||
case BuildVolume::Type::Circle:
|
case BuildVolume_Type::Circle:
|
||||||
optgroup->set_value("diameter", double_to_string(2. * unscaled<double>(m_build_volume.circle().radius)));
|
optgroup->set_value("diameter", double_to_string(2. * unscaled<double>(m_build_volume.circle().radius)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct BedShape
|
||||||
|
|
||||||
BedShape(const ConfigOptionPoints& points);
|
BedShape(const ConfigOptionPoints& points);
|
||||||
|
|
||||||
bool is_custom() { return m_build_volume.type() == BuildVolume::Type::Convex || m_build_volume.type() == BuildVolume::Type::Custom; }
|
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);
|
static void append_option_line(ConfigOptionsGroupShp optgroup, Parameter param);
|
||||||
static wxString get_name(PageType type);
|
static wxString get_name(PageType type);
|
||||||
|
|
|
@ -116,7 +116,7 @@ RetinaHelper::~RetinaHelper() {}
|
||||||
float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleFactor()); }
|
float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleFactor()); }
|
||||||
#endif // __WXGTK3__
|
#endif // __WXGTK3__
|
||||||
|
|
||||||
// Fixed the collision between BuildVolume::Type::Convex and macro Convex defined inside /usr/include/X11/X.h that is included by WxWidgets 3.0.
|
// Fixed the collision between BuildVolume_Type::Convex and macro Convex defined inside /usr/include/X11/X.h that is included by WxWidgets 3.0.
|
||||||
#if defined(__linux__) && defined(Convex)
|
#if defined(__linux__) && defined(Convex)
|
||||||
#undef Convex
|
#undef Convex
|
||||||
#endif
|
#endif
|
||||||
|
@ -6542,22 +6542,22 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
||||||
|
|
||||||
if (const BuildVolume &build_volume = m_bed.build_volume(); build_volume.valid()) {
|
if (const BuildVolume &build_volume = m_bed.build_volume(); build_volume.valid()) {
|
||||||
switch (build_volume.type()) {
|
switch (build_volume.type()) {
|
||||||
case BuildVolume::Type::Rectangle: {
|
case BuildVolume_Type::Rectangle: {
|
||||||
const BoundingBox3Base<Vec3d> bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon);
|
const BoundingBox3Base<Vec3d> bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon);
|
||||||
m_volumes.set_print_volume({ 0, // Rectangle
|
m_volumes.set_print_volume({ 0, // Rectangle
|
||||||
{ float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) },
|
{ 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.printable_height()) } });
|
{ 0.0f, float(build_volume.printable_height()) } });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BuildVolume::Type::Circle: {
|
case BuildVolume_Type::Circle: {
|
||||||
m_volumes.set_print_volume({ 1, // Circle
|
m_volumes.set_print_volume({ 1, // Circle
|
||||||
{ unscaled<float>(build_volume.circle().center.x()), unscaled<float>(build_volume.circle().center.y()), unscaled<float>(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f },
|
{ 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.printable_height() + BuildVolume::SceneEpsilon) } });
|
{ 0.0f, float(build_volume.printable_height() + BuildVolume::SceneEpsilon) } });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
case BuildVolume::Type::Convex:
|
case BuildVolume_Type::Convex:
|
||||||
case BuildVolume::Type::Custom: {
|
case BuildVolume_Type::Custom: {
|
||||||
m_volumes.set_print_volume({ static_cast<int>(type),
|
m_volumes.set_print_volume({ static_cast<int>(type),
|
||||||
{ -FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX },
|
{ -FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX },
|
||||||
{ -FLT_MAX, FLT_MAX } }
|
{ -FLT_MAX, FLT_MAX } }
|
||||||
|
|
|
@ -437,7 +437,8 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffe
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP + PARTPLATE_ICON_SIZE - offset_x), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP)- PARTPLATE_ICON_GAP - PARTPLATE_TEXT_OFFSET_Y)});
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP + PARTPLATE_ICON_SIZE - offset_x), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP)- PARTPLATE_ICON_GAP - PARTPLATE_TEXT_OFFSET_Y)});
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP + offset_x), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP)- PARTPLATE_ICON_GAP - PARTPLATE_TEXT_OFFSET_Y) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP + offset_x), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP)- PARTPLATE_ICON_GAP - PARTPLATE_TEXT_OFFSET_Y) });
|
||||||
#else //in the bottom
|
#else //in the bottom
|
||||||
Vec2d& p = m_shape[1];
|
auto bed_ext = get_extents(m_shape);
|
||||||
|
Vec2d p = bed_ext[1];
|
||||||
float offset_x = one_number?PARTPLATE_TEXT_OFFSET_X1: PARTPLATE_TEXT_OFFSET_X2;
|
float offset_x = one_number?PARTPLATE_TEXT_OFFSET_X1: PARTPLATE_TEXT_OFFSET_X2;
|
||||||
|
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) + PARTPLATE_TEXT_OFFSET_Y) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) + PARTPLATE_TEXT_OFFSET_Y) });
|
||||||
|
@ -453,7 +454,11 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffe
|
||||||
void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer)
|
void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer)
|
||||||
{
|
{
|
||||||
ExPolygon poly;
|
ExPolygon poly;
|
||||||
Vec2d& p = m_shape[2];
|
auto bed_ext = get_extents(m_shape);
|
||||||
|
Vec2d p = bed_ext[2];
|
||||||
|
if (m_plater->get_build_volume_type() == BuildVolume_Type::Circle)
|
||||||
|
p[1] -= std::max(
|
||||||
|
0.0, (bed_ext.size()(1) - 5 * PARTPLATE_ICON_SIZE - 4 * PARTPLATE_ICON_GAP_Y - PARTPLATE_ICON_GAP_TOP) / 2);
|
||||||
|
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y) - PARTPLATE_ICON_GAP_TOP - PARTPLATE_ICON_SIZE) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y) - PARTPLATE_ICON_GAP_TOP - PARTPLATE_ICON_SIZE) });
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP - PARTPLATE_ICON_SIZE) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP - PARTPLATE_ICON_SIZE) });
|
||||||
|
@ -468,7 +473,8 @@ void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer)
|
||||||
void PartPlate::calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer)
|
void PartPlate::calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer)
|
||||||
{
|
{
|
||||||
ExPolygon poly;
|
ExPolygon poly;
|
||||||
Vec2d& p = m_shape[2];
|
auto bed_ext = get_extents(m_shape);
|
||||||
|
Vec2d p = bed_ext[2];
|
||||||
|
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - icon_count * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y) - PARTPLATE_ICON_GAP_TOP) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - icon_count * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y) - PARTPLATE_ICON_GAP_TOP) });
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - icon_count * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - icon_count * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP) });
|
||||||
|
@ -1576,7 +1582,7 @@ void PartPlate::generate_plate_name_texture()
|
||||||
float offset_x = 1;
|
float offset_x = 1;
|
||||||
w = int(factor * (m_name_texture.get_width() * 16) / m_name_texture.get_height());
|
w = int(factor * (m_name_texture.get_width() * 16) / m_name_texture.get_height());
|
||||||
h = int(factor * 16);
|
h = int(factor * 16);
|
||||||
Vec2d p = m_shape[3] + Vec2d(0, h*0.6);
|
Vec2d p = bed_ext[3] + Vec2d(0, h*0.6);
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y) });
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y) });
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y) });
|
||||||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y)});
|
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y)});
|
||||||
|
|
|
@ -6862,8 +6862,8 @@ bool Plater::priv::has_assemble_view() const
|
||||||
#if ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
#if ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
||||||
bool Plater::priv::can_scale_to_print_volume() const
|
bool Plater::priv::can_scale_to_print_volume() const
|
||||||
{
|
{
|
||||||
const BuildVolume::Type type = this->bed.build_volume().type();
|
const BuildVolume_Type type = this->bed.build_volume().type();
|
||||||
return !view3D->get_canvas3d()->get_selection().is_empty() && (type == BuildVolume::Type::Rectangle || type == BuildVolume::Type::Circle);
|
return !view3D->get_canvas3d()->get_selection().is_empty() && (type == BuildVolume_Type::Rectangle || type == BuildVolume_Type::Circle);
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
||||||
|
|
||||||
|
@ -8369,6 +8369,7 @@ void Plater::calib_VFA(const Calib_Params& params)
|
||||||
|
|
||||||
p->background_process.fff_print()->set_calib_params(params);
|
p->background_process.fff_print()->set_calib_params(params);
|
||||||
}
|
}
|
||||||
|
BuildVolume_Type Plater::get_build_volume_type() const { return p->bed.get_build_volume_type(); }
|
||||||
void Plater::import_sl1_archive()
|
void Plater::import_sl1_archive()
|
||||||
{
|
{
|
||||||
if (!p->m_ui_jobs.is_any_running())
|
if (!p->m_ui_jobs.is_any_running())
|
||||||
|
|
|
@ -38,6 +38,7 @@ class Button;
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class BuildVolume;
|
class BuildVolume;
|
||||||
|
enum class BuildVolume_Type : unsigned char;
|
||||||
class Model;
|
class Model;
|
||||||
class ModelObject;
|
class ModelObject;
|
||||||
enum class ModelObjectCutAttribute : int;
|
enum class ModelObjectCutAttribute : int;
|
||||||
|
@ -236,6 +237,8 @@ public:
|
||||||
void calib_max_vol_speed(const Calib_Params& params);
|
void calib_max_vol_speed(const Calib_Params& params);
|
||||||
void calib_VFA(const Calib_Params& params);
|
void calib_VFA(const Calib_Params& params);
|
||||||
|
|
||||||
|
BuildVolume_Type get_build_volume_type() const;
|
||||||
|
|
||||||
//BBS: add only gcode mode
|
//BBS: add only gcode mode
|
||||||
bool only_gcode_mode() { return m_only_gcode; }
|
bool only_gcode_mode() { return m_only_gcode; }
|
||||||
void set_only_gcode(bool only_gcode) { m_only_gcode = only_gcode; }
|
void set_only_gcode(bool only_gcode) { m_only_gcode = only_gcode; }
|
||||||
|
|
|
@ -1234,8 +1234,8 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
|
||||||
|
|
||||||
switch (volume.type())
|
switch (volume.type())
|
||||||
{
|
{
|
||||||
case BuildVolume::Type::Rectangle: { fit_rectangle(volume); break; }
|
case BuildVolume_Type::Rectangle: { fit_rectangle(volume); break; }
|
||||||
case BuildVolume::Type::Circle: { fit_circle(volume); break; }
|
case BuildVolume_Type::Circle: { fit_circle(volume); break; }
|
||||||
default: { break; }
|
default: { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue