Merge branch 'dev_native' of https://github.com/prusa3d/Slic3r into dev_native

This commit is contained in:
bubnikv 2018-10-31 16:25:55 +01:00
commit 7e71aaffd5
36 changed files with 1313 additions and 565 deletions

View File

@ -1,3 +1,4 @@
#include "libslic3r.h"
#include "Geometry.hpp" #include "Geometry.hpp"
#include "ClipperUtils.hpp" #include "ClipperUtils.hpp"
#include "ExPolygon.hpp" #include "ExPolygon.hpp"
@ -369,12 +370,6 @@ contains(const std::vector<T> &vector, const Point &point)
} }
template bool contains(const ExPolygons &vector, const Point &point); template bool contains(const ExPolygons &vector, const Point &point);
double
rad2deg(double angle)
{
return angle / PI * 180.0;
}
double double
rad2deg_dir(double angle) rad2deg_dir(double angle)
{ {
@ -1232,4 +1227,161 @@ Vec3d extract_euler_angles(const Transform3d& transform)
return extract_euler_angles(m); return extract_euler_angles(m);
} }
#if ENABLE_MODELVOLUME_TRANSFORM
Transformation::Flags::Flags()
: dont_translate(true)
, dont_rotate(true)
, dont_scale(true)
#if ENABLE_MIRROR
, dont_mirror(true)
#endif // ENABLE_MIRROR
{
}
#if ENABLE_MIRROR
bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
{
return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror);
}
void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror)
{
this->dont_translate = dont_translate;
this->dont_rotate = dont_rotate;
this->dont_scale = dont_scale;
this->dont_mirror = dont_mirror;
}
#else
bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale) const
{
return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale);
}
void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale)
{
this->dont_translate = dont_translate;
this->dont_rotate = dont_rotate;
this->dont_scale = dont_scale;
}
#endif // ENABLE_MIRROR
Transformation::Transformation()
: m_offset(Vec3d::Zero())
, m_rotation(Vec3d::Zero())
, m_scaling_factor(Vec3d::Ones())
#if ENABLE_MIRROR
, m_mirror(Vec3d::Ones())
#endif // ENABLE_MIRROR
, m_matrix(Transform3d::Identity())
, m_dirty(false)
{
}
void Transformation::set_offset(const Vec3d& offset)
{
set_offset(X, offset(0));
set_offset(Y, offset(1));
set_offset(Z, offset(2));
}
void Transformation::set_offset(Axis axis, double offset)
{
if (m_offset(axis) != offset)
{
m_offset(axis) = offset;
m_dirty = true;
}
}
void Transformation::set_rotation(const Vec3d& rotation)
{
set_rotation(X, rotation(0));
set_rotation(Y, rotation(1));
set_rotation(Z, rotation(2));
}
void Transformation::set_rotation(Axis axis, double rotation)
{
rotation = angle_to_0_2PI(rotation);
if (m_rotation(axis) = rotation)
{
m_rotation(axis) = rotation;
m_dirty = true;
}
}
void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
{
set_scaling_factor(X, scaling_factor(0));
set_scaling_factor(Y, scaling_factor(1));
set_scaling_factor(Z, scaling_factor(2));
}
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
{
if (m_scaling_factor(axis) != std::abs(scaling_factor))
{
m_scaling_factor(axis) = std::abs(scaling_factor);
m_dirty = true;
}
}
void Transformation::set_mirror(const Vec3d& mirror)
{
set_mirror(X, mirror(0));
set_mirror(Y, mirror(1));
set_mirror(Z, mirror(2));
}
void Transformation::set_mirror(Axis axis, double mirror)
{
double abs_mirror = std::abs(mirror);
if (abs_mirror == 0.0)
mirror = 1.0;
else if (abs_mirror != 1.0)
mirror /= abs_mirror;
if (m_mirror(axis) != mirror)
{
m_mirror(axis) = mirror;
m_dirty = true;
}
}
#if ENABLE_MIRROR
const Transform3d& Transformation::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
#else
const Transform3d& Transformation::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale) const
#endif // ENABLE_MIRROR
{
#if ENABLE_MIRROR
if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror))
#else
if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale))
#endif // ENABLE_MIRROR
{
Vec3d translation = dont_translate ? Vec3d::Zero() : m_offset;
Vec3d rotation = dont_rotate ? Vec3d::Zero() : m_rotation;
Vec3d scale = dont_scale ? Vec3d::Ones() : m_scaling_factor;
#if ENABLE_MIRROR
Vec3d mirror = dont_mirror ? Vec3d::Ones() : m_mirror;
m_matrix = Geometry::assemble_transform(translation, rotation, scale, mirror);
#else
m_matrix = Geometry::assemble_transform(translation, rotation, scale);
#endif // ENABLE_MIRROR
#if ENABLE_MIRROR
m_flags.set(dont_translate, dont_rotate, dont_scale, dont_mirror);
#else
m_flags.set(dont_translate, dont_rotate, dont_scale);
#endif // ENABLE_MIRROR
m_dirty = false;
}
return m_matrix;
}
#endif // ENABLE_MODELVOLUME_TRANSFORM
} } } }

View File

@ -117,9 +117,23 @@ void chained_path(const Points &points, std::vector<Points::size_type> &retval);
template<class T> void chained_path_items(Points &points, T &items, T &retval); template<class T> void chained_path_items(Points &points, T &items, T &retval);
bool directions_parallel(double angle1, double angle2, double max_diff = 0); bool directions_parallel(double angle1, double angle2, double max_diff = 0);
template<class T> bool contains(const std::vector<T> &vector, const Point &point); template<class T> bool contains(const std::vector<T> &vector, const Point &point);
double rad2deg(double angle); template<typename T> T rad2deg(T angle) { return T(180.0) * angle / T(PI); }
double rad2deg_dir(double angle); double rad2deg_dir(double angle);
template<typename T> T deg2rad(T angle) { return T(PI) * angle / T(180.0); } template<typename T> T deg2rad(T angle) { return T(PI) * angle / T(180.0); }
template<typename T> T angle_to_0_2PI(T angle)
{
static const T TWO_PI = T(2) * T(PI);
while (angle < T(0))
{
angle += TWO_PI;
}
while (TWO_PI < angle)
{
angle -= TWO_PI;
}
return angle;
}
void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval); void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval);
double linint(double value, double oldmin, double oldmax, double newmin, double newmax); double linint(double value, double oldmin, double oldmax, double newmin, double newmax);
@ -200,6 +214,79 @@ Vec3d extract_euler_angles(const Eigen::Matrix<double, 3, 3, Eigen::DontAlign>&
// Returns the euler angles extracted from the given affine transform // Returns the euler angles extracted from the given affine transform
// Warning -> The transform should not contain any shear !!! // Warning -> The transform should not contain any shear !!!
Vec3d extract_euler_angles(const Transform3d& transform); Vec3d extract_euler_angles(const Transform3d& transform);
#if ENABLE_MODELVOLUME_TRANSFORM
class Transformation
{
struct Flags
{
bool dont_translate;
bool dont_rotate;
bool dont_scale;
#if ENABLE_MIRROR
bool dont_mirror;
#endif // ENABLE_MIRROR
Flags();
#if ENABLE_MIRROR
bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const;
void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror);
#else
bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale) const;
void set(bool dont_translate, bool dont_rotate, bool dont_scale);
#endif // ENABLE_MIRROR
};
Vec3d m_offset; // In unscaled coordinates
Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point
Vec3d m_scaling_factor; // Scaling factors along the three axes
#if ENABLE_MIRROR
Vec3d m_mirror; // Mirroring along the three axes
#endif // ENABLE_MIRROR
mutable Transform3d m_matrix;
mutable Flags m_flags;
mutable bool m_dirty;
public:
Transformation();
const Vec3d& get_offset() const { return m_offset; }
double get_offset(Axis axis) const { return m_offset(axis); }
void set_offset(const Vec3d& offset);
void set_offset(Axis axis, double offset);
const Vec3d& get_rotation() const { return m_rotation; }
double get_rotation(Axis axis) const { return m_rotation(axis); }
void set_rotation(const Vec3d& rotation);
void set_rotation(Axis axis, double rotation);
Vec3d get_scaling_factor() const { return m_scaling_factor; }
double get_scaling_factor(Axis axis) const { return m_scaling_factor(axis); }
#if ENABLE_MIRROR
void set_scaling_factor(const Vec3d& scaling_factor);
void set_scaling_factor(Axis axis, double scaling_factor);
const Vec3d& get_mirror() const { return m_mirror; }
double get_mirror(Axis axis) const { return m_mirror(axis); }
void set_mirror(const Vec3d& mirror);
void set_mirror(Axis axis, double mirror);
const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const;
#else
void set_scaling_factor(const Vec3d& scaling_factor) { m_scaling_factor = scaling_factor; }
void set_scaling_factor(Axis axis, double scaling_factor) { m_scaling_factor(axis) = scaling_factor; }
const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const;
#endif // ENABLE_MIRROR
};
#endif // ENABLE_MODELVOLUME_TRANSFORM
} } } }
#endif #endif

View File

@ -712,18 +712,32 @@ void ModelObject::center_around_origin()
if (!this->instances.empty()) { if (!this->instances.empty()) {
for (ModelInstance *i : this->instances) { for (ModelInstance *i : this->instances) {
#if ENABLE_MIRROR
i->set_offset(i->get_offset() - shift); i->set_offset(i->get_offset() - shift);
#else
// apply rotation and scaling to vector as well before translating instance,
// in order to leave final position unaltered
i->set_offset(i->get_offset() + i->transform_vector(-shift, true));
#endif // ENABLE_MIRROR
} }
this->invalidate_bounding_box(); this->invalidate_bounding_box();
} }
} }
void ModelObject::ensure_on_bed()
{
translate_instances(Vec3d(0.0, 0.0, -get_min_z()));
}
void ModelObject::translate_instances(const Vec3d& vector)
{
for (size_t i = 0; i < instances.size(); ++i)
{
translate_instance(i, vector);
}
}
void ModelObject::translate_instance(size_t instance_idx, const Vec3d& vector)
{
ModelInstance* i = instances[instance_idx];
i->set_offset(i->get_offset() + vector);
invalidate_bounding_box();
}
void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z) void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z)
{ {
for (ModelVolume *v : this->volumes) for (ModelVolume *v : this->volumes)
@ -895,6 +909,42 @@ void ModelObject::repair()
v->mesh.repair(); v->mesh.repair();
} }
double ModelObject::get_min_z() const
{
if (instances.empty())
return 0.0;
else
{
double min_z = DBL_MAX;
for (size_t i = 0; i < instances.size(); ++i)
{
min_z = std::min(min_z, get_instance_min_z(i));
}
return min_z;
}
}
double ModelObject::get_instance_min_z(size_t instance_idx) const
{
double min_z = DBL_MAX;
ModelInstance* inst = instances[instance_idx];
const Transform3d& m = inst->world_matrix(true);
for (ModelVolume *v : volumes)
{
for (uint32_t f = 0; f < v->mesh.stl.stats.number_of_facets; ++f)
{
const stl_facet* facet = v->mesh.stl.facet_start + f;
min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[0].cast<double>()));
min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[1].cast<double>()));
min_z = std::min(min_z, Vec3d::UnitZ().dot(m * facet->vertex[2].cast<double>()));
}
}
return min_z + inst->get_offset(Z);
}
unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume) unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
{ {
unsigned int num_printable = 0; unsigned int num_printable = 0;
@ -1074,6 +1124,7 @@ size_t ModelVolume::split(unsigned int max_extruders)
return idx; return idx;
} }
#if !ENABLE_MODELVOLUME_TRANSFORM
void ModelInstance::set_rotation(const Vec3d& rotation) void ModelInstance::set_rotation(const Vec3d& rotation)
{ {
set_rotation(X, rotation(0)); set_rotation(X, rotation(0));
@ -1126,6 +1177,7 @@ void ModelInstance::set_mirror(Axis axis, double mirror)
m_mirror(axis) = mirror; m_mirror(axis) = mirror;
} }
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // !ENABLE_MODELVOLUME_TRANSFORM
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
{ {
@ -1136,24 +1188,40 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes
{ {
// Rotate around mesh origin. // Rotate around mesh origin.
TriangleMesh copy(*mesh); TriangleMesh copy(*mesh);
#if ENABLE_MIRROR
copy.transform(world_matrix(true, false, true, true).cast<float>());
#else
copy.transform(world_matrix(true, false, true).cast<float>()); copy.transform(world_matrix(true, false, true).cast<float>());
#endif // ENABLE_MIRROR
BoundingBoxf3 bbox = copy.bounding_box(); BoundingBoxf3 bbox = copy.bounding_box();
if (!empty(bbox)) { if (!empty(bbox)) {
// Scale the bounding box along the three axes. // Scale the bounding box along the three axes.
for (unsigned int i = 0; i < 3; ++i) for (unsigned int i = 0; i < 3; ++i)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
if (std::abs(m_transformation.get_scaling_factor((Axis)i)-1.0) > EPSILON)
{
bbox.min(i) *= m_transformation.get_scaling_factor((Axis)i);
bbox.max(i) *= m_transformation.get_scaling_factor((Axis)i);
#else
if (std::abs(this->m_scaling_factor(i) - 1.0) > EPSILON) if (std::abs(this->m_scaling_factor(i) - 1.0) > EPSILON)
{ {
bbox.min(i) *= this->m_scaling_factor(i); bbox.min(i) *= this->m_scaling_factor(i);
bbox.max(i) *= this->m_scaling_factor(i); bbox.max(i) *= this->m_scaling_factor(i);
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
} }
// Translate the bounding box. // Translate the bounding box.
if (! dont_translate) { if (! dont_translate) {
#if ENABLE_MODELVOLUME_TRANSFORM
bbox.min += m_transformation.get_offset();
bbox.max += m_transformation.get_offset();
#else
bbox.min += this->m_offset; bbox.min += this->m_offset;
bbox.max += this->m_offset; bbox.max += this->m_offset;
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
} }
return bbox; return bbox;
@ -1171,12 +1239,20 @@ Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const
void ModelInstance::transform_polygon(Polygon* polygon) const void ModelInstance::transform_polygon(Polygon* polygon) const
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
// CHECK_ME -> Is the following correct or it should take in account all three rotations ?
polygon->rotate(m_transformation.get_rotation(Z)); // rotate around polygon origin
// CHECK_ME -> Is the following correct ?
polygon->scale(m_transformation.get_scaling_factor(X), m_transformation.get_scaling_factor(Y)); // scale around polygon origin
#else
// CHECK_ME -> Is the following correct or it should take in account all three rotations ? // CHECK_ME -> Is the following correct or it should take in account all three rotations ?
polygon->rotate(this->m_rotation(2)); // rotate around polygon origin polygon->rotate(this->m_rotation(2)); // rotate around polygon origin
// CHECK_ME -> Is the following correct ? // CHECK_ME -> Is the following correct ?
polygon->scale(this->m_scaling_factor(0), this->m_scaling_factor(1)); // scale around polygon origin polygon->scale(this->m_scaling_factor(0), this->m_scaling_factor(1)); // scale around polygon origin
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
#if !ENABLE_MODELVOLUME_TRANSFORM
#if ENABLE_MIRROR #if ENABLE_MIRROR
Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
#else #else
@ -1193,5 +1269,6 @@ Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, b
return Geometry::assemble_transform(translation, rotation, scale); return Geometry::assemble_transform(translation, rotation, scale);
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
} }
#endif // !ENABLE_MODELVOLUME_TRANSFORM
} }

View File

@ -11,6 +11,9 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#if ENABLE_MODELVOLUME_TRANSFORM
#include "Geometry.hpp"
#endif // ENABLE_MODELVOLUME_TRANSFORM
namespace Slic3r { namespace Slic3r {
@ -153,6 +156,9 @@ public:
// A snug bounding box around the transformed non-modifier object volumes. // A snug bounding box around the transformed non-modifier object volumes.
BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const; BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const;
void center_around_origin(); void center_around_origin();
void ensure_on_bed();
void translate_instances(const Vec3d& vector);
void translate_instance(size_t instance_idx, const Vec3d& vector);
void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); } void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
void translate(coordf_t x, coordf_t y, coordf_t z); void translate(coordf_t x, coordf_t y, coordf_t z);
void scale(const Vec3d &versor); void scale(const Vec3d &versor);
@ -167,6 +173,9 @@ public:
void split(ModelObjectPtrs* new_objects); void split(ModelObjectPtrs* new_objects);
void repair(); void repair();
double get_min_z() const;
double get_instance_min_z(size_t instance_idx) const;
// Called by Print::validate() from the UI thread. // Called by Print::validate() from the UI thread.
unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume); unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume);
@ -204,6 +213,10 @@ class ModelVolume : public ModelBase
// The convex hull of this model's mesh. // The convex hull of this model's mesh.
TriangleMesh m_convex_hull; TriangleMesh m_convex_hull;
#if ENABLE_MODELVOLUME_TRANSFORM
Geometry::Transformation m_transformation;
#endif // ENABLE_MODELVOLUME_TRANSFORM
public: public:
std::string name; std::string name;
// The triangular model. // The triangular model.
@ -251,6 +264,34 @@ public:
static Type type_from_string(const std::string &s); static Type type_from_string(const std::string &s);
static std::string type_to_string(const Type t); static std::string type_to_string(const Type t);
#if ENABLE_MODELVOLUME_TRANSFORM
const Vec3d& get_offset() const { return m_transformation.get_offset(); }
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); }
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); }
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); }
const Vec3d& get_rotation() const { return m_transformation.get_rotation(); }
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); }
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); }
void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); }
Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); }
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); }
#if ENABLE_MIRROR
const Vec3d& get_mirror() const { return m_transformation.get_mirror(); }
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); }
void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); }
void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); }
#endif // ENABLE_MIRROR
#endif // ENABLE_MODELVOLUME_TRANSFORM
private: private:
// Parent object owning this ModelVolume. // Parent object owning this ModelVolume.
ModelObject* object; ModelObject* object;
@ -300,12 +341,16 @@ public:
friend class ModelObject; friend class ModelObject;
private: private:
#if ENABLE_MODELVOLUME_TRANSFORM
Geometry::Transformation m_transformation;
#else
Vec3d m_offset; // in unscaled coordinates Vec3d m_offset; // in unscaled coordinates
Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point
Vec3d m_scaling_factor; // Scaling factors along the three axes Vec3d m_scaling_factor; // Scaling factors along the three axes
#if ENABLE_MIRROR #if ENABLE_MIRROR
Vec3d m_mirror; // Mirroring along the three axes Vec3d m_mirror; // Mirroring along the three axes
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // ENABLE_MODELVOLUME_TRANSFORM
public: public:
// flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state()) // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state())
@ -313,6 +358,36 @@ public:
ModelObject* get_object() const { return this->object; } ModelObject* get_object() const { return this->object; }
#if ENABLE_MODELVOLUME_TRANSFORM
const Geometry::Transformation& get_transformation() const { return m_transformation; }
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; }
const Vec3d& get_offset() const { return m_transformation.get_offset(); }
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); }
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); }
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); }
const Vec3d& get_rotation() const { return m_transformation.get_rotation(); }
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); }
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); }
void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); }
Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); }
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); }
#if ENABLE_MIRROR
const Vec3d& get_mirror() const { return m_transformation.get_mirror(); }
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); }
void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); }
void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); }
#endif // ENABLE_MIRROR
#else
const Vec3d& get_offset() const { return m_offset; } const Vec3d& get_offset() const { return m_offset; }
double get_offset(Axis axis) const { return m_offset(axis); } double get_offset(Axis axis) const { return m_offset(axis); }
@ -343,6 +418,7 @@ public:
void set_mirror(const Vec3d& mirror); void set_mirror(const Vec3d& mirror);
void set_mirror(Axis axis, double mirror); void set_mirror(Axis axis, double mirror);
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // ENABLE_MODELVOLUME_TRANSFORM
// To be called on an external mesh // To be called on an external mesh
void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const; void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const;
@ -355,11 +431,19 @@ public:
// To be called on an external polygon. It does not translate the polygon, only rotates and scales. // To be called on an external polygon. It does not translate the polygon, only rotates and scales.
void transform_polygon(Polygon* polygon) const; void transform_polygon(Polygon* polygon) const;
#if ENABLE_MODELVOLUME_TRANSFORM
#if ENABLE_MIRROR
const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.world_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); }
#else
const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const { return m_transformation.world_matrix(dont_translate, dont_rotate, dont_scale); }
#endif // ENABLE_MIRROR
#else
#if ENABLE_MIRROR #if ENABLE_MIRROR
Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const;
#else #else
Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const; Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const;
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // ENABLE_MODELVOLUME_TRANSFORM
bool is_printable() const { return print_volume_state == PVS_Inside; } bool is_printable() const { return print_volume_state == PVS_Inside; }
@ -367,6 +451,11 @@ private:
// Parent object, owning this instance. // Parent object, owning this instance.
ModelObject* object; ModelObject* object;
#if ENABLE_MODELVOLUME_TRANSFORM
ModelInstance(ModelObject *object) : object(object), print_volume_state(PVS_Inside) {}
ModelInstance(ModelObject *object, const ModelInstance &other) :
m_transformation(other.m_transformation), object(object), print_volume_state(PVS_Inside) {}
#else
#if ENABLE_MIRROR #if ENABLE_MIRROR
ModelInstance(ModelObject *object) : m_offset(Vec3d::Zero()), m_rotation(Vec3d::Zero()), m_scaling_factor(Vec3d::Ones()), m_mirror(Vec3d::Ones()), object(object), print_volume_state(PVS_Inside) {} ModelInstance(ModelObject *object) : m_offset(Vec3d::Zero()), m_rotation(Vec3d::Zero()), m_scaling_factor(Vec3d::Ones()), m_mirror(Vec3d::Ones()), object(object), print_volume_state(PVS_Inside) {}
ModelInstance(ModelObject *object, const ModelInstance &other) : ModelInstance(ModelObject *object, const ModelInstance &other) :
@ -376,6 +465,7 @@ private:
ModelInstance(ModelObject *object, const ModelInstance &other) : ModelInstance(ModelObject *object, const ModelInstance &other) :
m_rotation(other.m_rotation), m_scaling_factor(other.m_scaling_factor), m_offset(other.m_offset), object(object), print_volume_state(PVS_Inside) {} m_rotation(other.m_rotation), m_scaling_factor(other.m_scaling_factor), m_offset(other.m_offset), object(object), print_volume_state(PVS_Inside) {}
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // ENABLE_MODELVOLUME_TRANSFORM
explicit ModelInstance(ModelInstance &rhs) = delete; explicit ModelInstance(ModelInstance &rhs) = delete;
ModelInstance& operator=(ModelInstance &rhs) = delete; ModelInstance& operator=(ModelInstance &rhs) = delete;

View File

@ -19,10 +19,13 @@
#define ENABLE_USE_UNIQUE_GLCONTEXT (1 && ENABLE_1_42_0) #define ENABLE_USE_UNIQUE_GLCONTEXT (1 && ENABLE_1_42_0)
// New selections // New selections
#define ENABLE_EXTENDED_SELECTION (1 && ENABLE_1_42_0) #define ENABLE_EXTENDED_SELECTION (1 && ENABLE_1_42_0)
#define DISABLE_INSTANCES_SYNCH (1 && ENABLE_EXTENDED_SELECTION)
// Add mirror components along the three axes in ModelInstance and GLVolume // Add mirror components along the three axes in ModelInstance and GLVolume
#define ENABLE_MIRROR (1 && ENABLE_1_42_0) #define ENABLE_MIRROR (1 && ENABLE_1_42_0)
// Modified camera target behavior // Modified camera target behavior
#define ENABLE_MODIFIED_CAMERA_TARGET (1 && ENABLE_1_42_0) #define ENABLE_MODIFIED_CAMERA_TARGET (1 && ENABLE_1_42_0)
// Add Geometry::Transformation class and use it into ModelInstance, ModelVolume and GLVolume
#define ENABLE_MODELVOLUME_TRANSFORM (1 && ENABLE_1_42_0)
#endif // _technologies_h_ #endif // _technologies_h_

View File

@ -89,7 +89,7 @@ void Bed_2D::repaint()
dc.SetPen(wxPen(wxColour(230, 230, 230), 1, wxSOLID)); dc.SetPen(wxPen(wxColour(230, 230, 230), 1, wxSOLID));
for (auto pl : polylines) for (auto pl : polylines)
{ {
for (size_t i = 0; i < pl.points.size()-1; i++){ for (size_t i = 0; i < pl.points.size()-1; i++) {
Point pt1 = to_pixels(unscale(pl.points[i])); Point pt1 = to_pixels(unscale(pl.points[i]));
Point pt2 = to_pixels(unscale(pl.points[i+1])); Point pt2 = to_pixels(unscale(pl.points[i+1]));
dc.DrawLine(pt1(0), pt1(1), pt2(0), pt2(1)); dc.DrawLine(pt1(0), pt1(1), pt2(0), pt2(1));
@ -110,7 +110,7 @@ void Bed_2D::repaint()
dc.SetPen(wxPen(wxColour(255, 0, 0), 2, wxSOLID)); // red dc.SetPen(wxPen(wxColour(255, 0, 0), 2, wxSOLID)); // red
auto x_end = Vec2d(origin_px(0) + axes_len, origin_px(1)); auto x_end = Vec2d(origin_px(0) + axes_len, origin_px(1));
dc.DrawLine(wxPoint(origin_px(0), origin_px(1)), wxPoint(x_end(0), x_end(1))); dc.DrawLine(wxPoint(origin_px(0), origin_px(1)), wxPoint(x_end(0), x_end(1)));
for (auto angle : { -arrow_angle, arrow_angle }){ for (auto angle : { -arrow_angle, arrow_angle }) {
auto end = Eigen::Translation2d(x_end) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- x_end) * Eigen::Vector2d(x_end(0) - arrow_len, x_end(1)); auto end = Eigen::Translation2d(x_end) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- x_end) * Eigen::Vector2d(x_end(0) - arrow_len, x_end(1));
dc.DrawLine(wxPoint(x_end(0), x_end(1)), wxPoint(end(0), end(1))); dc.DrawLine(wxPoint(x_end(0), x_end(1)), wxPoint(end(0), end(1)));
} }
@ -151,12 +151,14 @@ void Bed_2D::repaint()
} }
// convert G - code coordinates into pixels // convert G - code coordinates into pixels
Point Bed_2D::to_pixels(Vec2d point){ Point Bed_2D::to_pixels(Vec2d point)
{
auto p = point * m_scale_factor + m_shift; auto p = point * m_scale_factor + m_shift;
return Point(p(0), GetSize().GetHeight() - p(1)); return Point(p(0), GetSize().GetHeight() - p(1));
} }
void Bed_2D::mouse_event(wxMouseEvent event){ void Bed_2D::mouse_event(wxMouseEvent event)
{
if (!m_interactive) return; if (!m_interactive) return;
if (!m_painted) return; if (!m_painted) return;
@ -170,11 +172,13 @@ void Bed_2D::mouse_event(wxMouseEvent event){
} }
// convert pixels into G - code coordinates // convert pixels into G - code coordinates
Vec2d Bed_2D::to_units(Point point){ Vec2d Bed_2D::to_units(Point point)
{
return (Vec2d(point(0), GetSize().GetHeight() - point(1)) - m_shift) * (1. / m_scale_factor); return (Vec2d(point(0), GetSize().GetHeight() - point(1)) - m_shift) * (1. / m_scale_factor);
} }
void Bed_2D::set_pos(Vec2d pos){ void Bed_2D::set_pos(Vec2d pos)
{
m_pos = pos; m_pos = pos;
Refresh(); Refresh();
} }

View File

@ -34,12 +34,12 @@ public:
#endif /*__APPLE__*/ #endif /*__APPLE__*/
Bind(wxEVT_PAINT, ([this](wxPaintEvent e) { repaint(); })); Bind(wxEVT_PAINT, ([this](wxPaintEvent e) { repaint(); }));
// EVT_ERASE_BACKGROUND($self, sub{}) if $self->{user_drawn_background}; // EVT_ERASE_BACKGROUND($self, sub{}) if $self->{user_drawn_background};
// Bind(EVT_MOUSE_EVENTS, ([this](wxMouseEvent event){/*mouse_event()*/; })); // Bind(EVT_MOUSE_EVENTS, ([this](wxMouseEvent event) {/*mouse_event()*/; }));
Bind(wxEVT_LEFT_DOWN, ([this](wxMouseEvent event){ mouse_event(event); })); Bind(wxEVT_LEFT_DOWN, ([this](wxMouseEvent event) { mouse_event(event); }));
Bind(wxEVT_MOTION, ([this](wxMouseEvent event){ mouse_event(event); })); Bind(wxEVT_MOTION, ([this](wxMouseEvent event) { mouse_event(event); }));
Bind(wxEVT_SIZE, ([this](wxSizeEvent e) { Refresh(); })); Bind(wxEVT_SIZE, ([this](wxSizeEvent e) { Refresh(); }));
} }
~Bed_2D(){} ~Bed_2D() {}
std::vector<Vec2d> m_bed_shape; std::vector<Vec2d> m_bed_shape;

View File

@ -195,6 +195,9 @@ const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f };
const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f }; const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f };
GLVolume::GLVolume(float r, float g, float b, float a) GLVolume::GLVolume(float r, float g, float b, float a)
#if ENABLE_MODELVOLUME_TRANSFORM
: m_transformed_bounding_box_dirty(true)
#else
: m_offset(Vec3d::Zero()) : m_offset(Vec3d::Zero())
, m_rotation(Vec3d::Zero()) , m_rotation(Vec3d::Zero())
, m_scaling_factor(Vec3d::Ones()) , m_scaling_factor(Vec3d::Ones())
@ -204,6 +207,7 @@ GLVolume::GLVolume(float r, float g, float b, float a)
, m_world_matrix(Transform3f::Identity()) , m_world_matrix(Transform3f::Identity())
, m_world_matrix_dirty(true) , m_world_matrix_dirty(true)
, m_transformed_bounding_box_dirty(true) , m_transformed_bounding_box_dirty(true)
#endif // ENABLE_MODELVOLUME_TRANSFORM
, m_transformed_convex_hull_bounding_box_dirty(true) , m_transformed_convex_hull_bounding_box_dirty(true)
, m_convex_hull(nullptr) , m_convex_hull(nullptr)
, composite_id(-1) , composite_id(-1)
@ -260,6 +264,7 @@ void GLVolume::set_render_color()
set_render_color(color, 4); set_render_color(color, 4);
} }
#if !ENABLE_MODELVOLUME_TRANSFORM
const Vec3d& GLVolume::get_rotation() const const Vec3d& GLVolume::get_rotation() const
{ {
return m_rotation; return m_rotation;
@ -360,6 +365,7 @@ void GLVolume::set_mirror(Axis axis, double mirror)
} }
} }
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // !ENABLE_MODELVOLUME_TRANSFORM
void GLVolume::set_convex_hull(const TriangleMesh& convex_hull) void GLVolume::set_convex_hull(const TriangleMesh& convex_hull)
{ {
@ -386,6 +392,7 @@ void GLVolume::set_drag_group_id(const std::string& drag_by)
} }
#endif // !ENABLE_EXTENDED_SELECTION #endif // !ENABLE_EXTENDED_SELECTION
#if !ENABLE_MODELVOLUME_TRANSFORM
const Transform3f& GLVolume::world_matrix() const const Transform3f& GLVolume::world_matrix() const
{ {
if (m_world_matrix_dirty) if (m_world_matrix_dirty)
@ -399,12 +406,17 @@ const Transform3f& GLVolume::world_matrix() const
} }
return m_world_matrix; return m_world_matrix;
} }
#endif // !ENABLE_MODELVOLUME_TRANSFORM
const BoundingBoxf3& GLVolume::transformed_bounding_box() const const BoundingBoxf3& GLVolume::transformed_bounding_box() const
{ {
if (m_transformed_bounding_box_dirty) if (m_transformed_bounding_box_dirty)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
m_transformed_bounding_box = bounding_box.transformed(world_matrix());
#else
m_transformed_bounding_box = bounding_box.transformed(world_matrix().cast<double>()); m_transformed_bounding_box = bounding_box.transformed(world_matrix().cast<double>());
#endif // ENABLE_MODELVOLUME_TRANSFORM
m_transformed_bounding_box_dirty = false; m_transformed_bounding_box_dirty = false;
} }
@ -415,10 +427,17 @@ const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const
{ {
if (m_transformed_convex_hull_bounding_box_dirty) if (m_transformed_convex_hull_bounding_box_dirty)
{ {
#if ENABLE_MODELVOLUME_TRANSFORM
if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0))
m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix());
else
m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix());
#else
if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0)) if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0))
m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix().cast<double>()); m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix().cast<double>());
else else
m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix().cast<double>()); m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix().cast<double>());
#endif // ENABLE_MODELVOLUME_TRANSFORM
m_transformed_convex_hull_bounding_box_dirty = false; m_transformed_convex_hull_bounding_box_dirty = false;
} }
@ -469,7 +488,11 @@ void GLVolume::render() const
::glCullFace(GL_BACK); ::glCullFace(GL_BACK);
::glPushMatrix(); ::glPushMatrix();
#if ENABLE_MODELVOLUME_TRANSFORM
::glMultMatrixd(world_matrix().data());
#else
::glMultMatrixf(world_matrix().data()); ::glMultMatrixf(world_matrix().data());
#endif // ENABLE_MODELVOLUME_TRANSFORM
if (this->indexed_vertex_array.indexed()) if (this->indexed_vertex_array.indexed())
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
else else
@ -507,7 +530,11 @@ void GLVolume::render_using_layer_height() const
glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width); glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width);
if (world_matrix_id >= 0) if (world_matrix_id >= 0)
#if ENABLE_MODELVOLUME_TRANSFORM
::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
#else
::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data());
#endif // ENABLE_MODELVOLUME_TRANSFORM
GLsizei w = (GLsizei)layer_height_texture_width(); GLsizei w = (GLsizei)layer_height_texture_width();
GLsizei h = (GLsizei)layer_height_texture_height(); GLsizei h = (GLsizei)layer_height_texture_height();
@ -567,7 +594,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
if (worldmatrix_id != -1) if (worldmatrix_id != -1)
#if ENABLE_MODELVOLUME_TRANSFORM
::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
#else
::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data());
#endif // ENABLE_MODELVOLUME_TRANSFORM
render(); render();
@ -586,7 +617,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
if (worldmatrix_id != -1) if (worldmatrix_id != -1)
#if ENABLE_MODELVOLUME_TRANSFORM
::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
#else
::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data());
#endif // ENABLE_MODELVOLUME_TRANSFORM
::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id); ::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
@ -594,7 +629,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
::glPushMatrix(); ::glPushMatrix();
#if ENABLE_MODELVOLUME_TRANSFORM
::glMultMatrixd(world_matrix().data());
#else
::glMultMatrixf(world_matrix().data()); ::glMultMatrixf(world_matrix().data());
#endif // ENABLE_MODELVOLUME_TRANSFORM
if (n_triangles > 0) if (n_triangles > 0)
{ {
@ -638,7 +677,11 @@ void GLVolume::render_legacy() const
::glPushMatrix(); ::glPushMatrix();
#if ENABLE_MODELVOLUME_TRANSFORM
::glMultMatrixd(world_matrix().data());
#else
::glMultMatrixf(world_matrix().data()); ::glMultMatrixf(world_matrix().data());
#endif // ENABLE_MODELVOLUME_TRANSFORM
if (n_triangles > 0) if (n_triangles > 0)
::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first); ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first);
@ -767,12 +810,16 @@ std::vector<int> GLVolumeCollection::load_object(
} }
v.is_modifier = ! model_volume->is_model_part(); v.is_modifier = ! model_volume->is_model_part();
v.shader_outside_printer_detection_enabled = model_volume->is_model_part(); v.shader_outside_printer_detection_enabled = model_volume->is_model_part();
#if ENABLE_MODELVOLUME_TRANSFORM
v.set_transformation(instance->get_transformation());
#else
v.set_offset(instance->get_offset()); v.set_offset(instance->get_offset());
v.set_rotation(instance->get_rotation()); v.set_rotation(instance->get_rotation());
v.set_scaling_factor(instance->get_scaling_factor()); v.set_scaling_factor(instance->get_scaling_factor());
#if ENABLE_MIRROR #if ENABLE_MIRROR
v.set_mirror(instance->get_mirror()); v.set_mirror(instance->get_mirror());
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
#endif // ENABLE_MODELVOLUME_TRANSFORM
} }
} }

View File

@ -254,6 +254,9 @@ public:
GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {} GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
private: private:
#if ENABLE_MODELVOLUME_TRANSFORM
Geometry::Transformation m_transformation;
#else
// Offset of the volume to be rendered. // Offset of the volume to be rendered.
Vec3d m_offset; Vec3d m_offset;
// Rotation around three axes of the volume to be rendered. // Rotation around three axes of the volume to be rendered.
@ -268,6 +271,7 @@ private:
mutable Transform3f m_world_matrix; mutable Transform3f m_world_matrix;
// Whether or not is needed to recalculate the world matrix. // Whether or not is needed to recalculate the world matrix.
mutable bool m_world_matrix_dirty; mutable bool m_world_matrix_dirty;
#endif // ENABLE_MODELVOLUME_TRANSFORM
// Bounding box of this volume, in unscaled coordinates. // Bounding box of this volume, in unscaled coordinates.
mutable BoundingBoxf3 m_transformed_bounding_box; mutable BoundingBoxf3 m_transformed_bounding_box;
// Whether or not is needed to recalculate the transformed bounding box. // Whether or not is needed to recalculate the transformed bounding box.
@ -280,7 +284,6 @@ private:
mutable bool m_transformed_convex_hull_bounding_box_dirty; mutable bool m_transformed_convex_hull_bounding_box_dirty;
public: public:
// Bounding box of this volume, in unscaled coordinates. // Bounding box of this volume, in unscaled coordinates.
BoundingBoxf3 bounding_box; BoundingBoxf3 bounding_box;
// Color of the triangles / quads held by this volume. // Color of the triangles / quads held by this volume.
@ -333,6 +336,36 @@ public:
// Sets render color in dependence of current state // Sets render color in dependence of current state
void set_render_color(); void set_render_color();
#if ENABLE_MODELVOLUME_TRANSFORM
const Geometry::Transformation& get_transformation() const { return m_transformation; }
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; set_bounding_boxes_as_dirty(); }
const Vec3d& get_offset() const { return m_transformation.get_offset(); }
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); }
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); }
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); }
const Vec3d& get_rotation() const { return m_transformation.get_rotation(); }
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); }
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); }
void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); }
Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); }
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); }
#if ENABLE_MIRROR
const Vec3d& get_mirror() const { return m_transformation.get_mirror(); }
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); }
void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); }
void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); set_bounding_boxes_as_dirty(); }
#endif // ENABLE_MIRROR
#else
const Vec3d& get_rotation() const; const Vec3d& get_rotation() const;
void set_rotation(const Vec3d& rotation); void set_rotation(const Vec3d& rotation);
@ -350,6 +383,7 @@ public:
const Vec3d& get_offset() const; const Vec3d& get_offset() const;
void set_offset(const Vec3d& offset); void set_offset(const Vec3d& offset);
#endif // ENABLE_MODELVOLUME_TRANSFORM
void set_convex_hull(const TriangleMesh& convex_hull); void set_convex_hull(const TriangleMesh& convex_hull);
@ -362,7 +396,11 @@ public:
int volume_idx() const { return (this->composite_id / 1000) % 1000; } int volume_idx() const { return (this->composite_id / 1000) % 1000; }
int instance_idx() const { return this->composite_id % 1000; } int instance_idx() const { return this->composite_id % 1000; }
#if ENABLE_MODELVOLUME_TRANSFORM
const Transform3d& world_matrix() const { return m_transformation.world_matrix(); }
#else
const Transform3f& world_matrix() const; const Transform3f& world_matrix() const;
#endif // ENABLE_MODELVOLUME_TRANSFORM
const BoundingBoxf3& transformed_bounding_box() const; const BoundingBoxf3& transformed_bounding_box() const;
const BoundingBoxf3& transformed_convex_hull_bounding_box() const; const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
@ -412,6 +450,10 @@ public:
} }
void reset_layer_height_texture_data() { layer_height_texture_data.reset(); } void reset_layer_height_texture_data() { layer_height_texture_data.reset(); }
#if ENABLE_MODELVOLUME_TRANSFORM
void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; }
#endif // ENABLE_MODELVOLUME_TRANSFORM
}; };
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION

View File

@ -28,7 +28,7 @@ void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt)
main_sizer->SetSizeHints(this); main_sizer->SetSizeHints(this);
// needed to actually free memory // needed to actually free memory
this->Bind(wxEVT_CLOSE_WINDOW, ([this](wxCloseEvent e){ this->Bind(wxEVT_CLOSE_WINDOW, ([this](wxCloseEvent e) {
EndModal(wxID_OK); EndModal(wxID_OK);
Destroy(); Destroy();
})); }));
@ -115,14 +115,15 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
// Called from the constructor. // Called from the constructor.
// Create a panel for a rectangular / circular / custom bed shape. // Create a panel for a rectangular / circular / custom bed shape.
ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title){ ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title)
{
auto panel = new wxPanel(m_shape_options_book); auto panel = new wxPanel(m_shape_options_book);
ConfigOptionsGroupShp optgroup; ConfigOptionsGroupShp optgroup;
optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Settings"))); optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Settings")));
optgroup->label_width = 100; optgroup->label_width = 100;
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
update_shape(); update_shape();
}; };
@ -234,14 +235,15 @@ void BedShapePanel::update_shape()
Vec2d rect_origin(Vec2d::Zero()); Vec2d rect_origin(Vec2d::Zero());
try{ try{
rect_size = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_size")); } rect_size = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_size")); }
catch (const std::exception & /* e */){ catch (const std::exception & /* e */) {
return; return;
} }
try{ try {
rect_origin = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_origin")); rect_origin = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_origin"));
} }
catch (const std::exception & /* e */){ catch (const std::exception & /* e */) {
return;} return;
}
auto x = rect_size(0); auto x = rect_size(0);
auto y = rect_size(1); auto y = rect_size(1);
@ -269,7 +271,7 @@ void BedShapePanel::update_shape()
try{ try{
diameter = boost::any_cast<double>(m_optgroups[SHAPE_CIRCULAR]->get_value("diameter")); diameter = boost::any_cast<double>(m_optgroups[SHAPE_CIRCULAR]->get_value("diameter"));
} }
catch (const std::exception & /* e */){ catch (const std::exception & /* e */) {
return; return;
} }
if (diameter == 0.0) return ; if (diameter == 0.0) return ;
@ -277,7 +279,7 @@ void BedShapePanel::update_shape()
auto twopi = 2 * PI; auto twopi = 2 * PI;
auto edges = 60; auto edges = 60;
std::vector<Vec2d> points; std::vector<Vec2d> points;
for (size_t i = 1; i <= 60; ++i){ for (size_t i = 1; i <= 60; ++i) {
auto angle = i * twopi / edges; auto angle = i * twopi / edges;
points.push_back(Vec2d(r*cos(angle), r*sin(angle))); points.push_back(Vec2d(r*cos(angle), r*sin(angle)));
} }

View File

@ -22,8 +22,8 @@ class BedShapePanel : public wxPanel
std::vector <ConfigOptionsGroupShp> m_optgroups; std::vector <ConfigOptionsGroupShp> m_optgroups;
public: public:
BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY){} BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) {}
~BedShapePanel(){} ~BedShapePanel() {}
void build_panel(ConfigOptionPoints* default_pt); void build_panel(ConfigOptionPoints* default_pt);
@ -42,8 +42,8 @@ class BedShapeDialog : public wxDialog
BedShapePanel* m_panel; BedShapePanel* m_panel;
public: public:
BedShapeDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, _(L("Bed Shape")), BedShapeDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, _(L("Bed Shape")),
wxDefaultPosition, wxSize(350, 700), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER){} wxDefaultPosition, wxSize(350, 700), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {}
~BedShapeDialog(){ } ~BedShapeDialog() {}
void build_dialog(ConfigOptionPoints* default_pt); void build_dialog(ConfigOptionPoints* default_pt);
std::vector<Vec2d> GetValue() { return m_panel->GetValue(); } std::vector<Vec2d> GetValue() { return m_panel->GetValue(); }

View File

@ -45,7 +45,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* ic
sys_label->Refresh(); sys_label->Refresh();
})); }));
size_t t= 0; size_t t= 0;
while (t < 3){ while (t < 3) {
grid_sizer->Add(new wxStaticText(this, wxID_ANY, ""), -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND); grid_sizer->Add(new wxStaticText(this, wxID_ANY, ""), -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
++t; ++t;
} }

View File

@ -14,7 +14,7 @@ class ButtonsDescription : public wxDialog
t_icon_descriptions* m_icon_descriptions; t_icon_descriptions* m_icon_descriptions;
public: public:
ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions); ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions);
~ButtonsDescription(){} ~ButtonsDescription() {}
}; };

View File

@ -11,270 +11,275 @@
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
wxString double_to_string(double const value) wxString double_to_string(double const value)
{ {
if (value - int(value) == 0) if (value - int(value) == 0)
return wxString::Format(_T("%i"), int(value)); return wxString::Format(_T("%i"), int(value));
else { else {
int precision = 4; int precision = 4;
for (size_t p = 1; p < 4; p++) for (size_t p = 1; p < 4; p++)
{
double cur_val = pow(10, p)*value;
if (cur_val - int(cur_val) == 0) {
precision = p;
break;
}
}
return wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None);
}
}
void Field::PostInitialize(){
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
if (wxMSW) {
m_Undo_btn->SetBackgroundColour(color);
m_Undo_to_sys_btn->SetBackgroundColour(color);
}
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_initial_value(); }));
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_sys_value(); }));
//set default bitmap
wxBitmap bmp;
bmp.LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG);
set_undo_bitmap(&bmp);
set_undo_to_sys_bitmap(&bmp);
switch (m_opt.type)
{ {
case coPercents: double cur_val = pow(10, p)*value;
case coFloats: if (cur_val - int(cur_val) == 0) {
case coStrings: precision = p;
case coBools:
case coInts: {
auto tag_pos = m_opt_id.find("#");
if (tag_pos != std::string::npos)
m_opt_idx = stoi(m_opt_id.substr(tag_pos + 1, m_opt_id.size()));
break;
}
default:
break;
}
BUILD();
}
void Field::on_kill_focus(wxEvent& event) {
// Without this, there will be nasty focus bugs on Windows.
// Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all
// non-command events to allow the default handling to take place."
event.Skip();
// call the registered function if it is available
if (m_on_kill_focus!=nullptr)
m_on_kill_focus();
}
void Field::on_change_field()
{
// std::cerr << "calling Field::_on_change \n";
if (m_on_change != nullptr && !m_disable_change_event)
m_on_change(m_opt_id, get_value());
}
void Field::on_back_to_initial_value(){
if (m_back_to_initial_value != nullptr && m_is_modified_value)
m_back_to_initial_value(m_opt_id);
}
void Field::on_back_to_sys_value(){
if (m_back_to_sys_value != nullptr && m_is_nonsys_value)
m_back_to_sys_value(m_opt_id);
}
wxString Field::get_tooltip_text(const wxString& default_string)
{
wxString tooltip_text("");
wxString tooltip = _(m_opt.tooltip);
if (tooltip.length() > 0)
tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " +
(boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string +
(boost::iends_with(m_opt_id, "_gcode") ? "" : "\n") +
_(L("parameter name")) + "\t: " + m_opt_id;
return tooltip_text;
}
bool Field::is_matched(const std::string& string, const std::string& pattern)
{
std::regex regex_pattern(pattern, std::regex_constants::icase); // use ::icase to make the matching case insensitive like /i in perl
return std::regex_match(string, regex_pattern);
}
void Field::get_value_by_opt_type(wxString& str)
{
switch (m_opt.type){
case coInt:
m_value = wxAtoi(str);
break;
case coPercent:
case coPercents:
case coFloats:
case coFloat:{
if (m_opt.type == coPercent && str.Last() == '%')
str.RemoveLast();
else if (str.Last() == '%') {
wxString label = m_Label->GetLabel();
if (label.Last() == '\n') label.RemoveLast();
while (label.Last() == ' ') label.RemoveLast();
if (label.Last() == ':') label.RemoveLast();
show_error(m_parent, wxString::Format(_(L("%s doesn't support percentage")), label));
set_value(double_to_string(m_opt.min), true);
m_value = double(m_opt.min);
break; break;
} }
double val;
if(!str.ToCDouble(&val))
{
show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits")));
set_value(double_to_string(val), true);
}
if (m_opt.min > val || val > m_opt.max)
{
show_error(m_parent, _(L("Input value is out of range")));
if (m_opt.min > val) val = m_opt.min;
if (val > m_opt.max) val = m_opt.max;
set_value(double_to_string(val), true);
}
m_value = val;
break; }
case coString:
case coStrings:
case coFloatOrPercent:
m_value = str.ToStdString();
break;
default:
break;
} }
return wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None);
}
}
void Field::PostInitialize()
{
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
if (wxMSW) {
m_Undo_btn->SetBackgroundColour(color);
m_Undo_to_sys_btn->SetBackgroundColour(color);
}
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); }));
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); }));
//set default bitmap
wxBitmap bmp;
bmp.LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG);
set_undo_bitmap(&bmp);
set_undo_to_sys_bitmap(&bmp);
switch (m_opt.type)
{
case coPercents:
case coFloats:
case coStrings:
case coBools:
case coInts: {
auto tag_pos = m_opt_id.find("#");
if (tag_pos != std::string::npos)
m_opt_idx = stoi(m_opt_id.substr(tag_pos + 1, m_opt_id.size()));
break;
}
default:
break;
} }
void TextCtrl::BUILD() { BUILD();
auto size = wxSize(wxDefaultSize); }
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
wxString text_value = wxString(""); void Field::on_kill_focus(wxEvent& event)
{
// Without this, there will be nasty focus bugs on Windows.
// Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all
// non-command events to allow the default handling to take place."
event.Skip();
// call the registered function if it is available
if (m_on_kill_focus!=nullptr)
m_on_kill_focus();
}
switch (m_opt.type) { void Field::on_change_field()
case coFloatOrPercent: {
{ std::cerr << "calling Field::_on_change \n";
text_value = double_to_string(m_opt.default_value->getFloat()); if (m_on_change != nullptr && !m_disable_change_event)
if (static_cast<const ConfigOptionFloatOrPercent*>(m_opt.default_value)->percent) m_on_change(m_opt_id, get_value());
text_value += "%"; }
void Field::on_back_to_initial_value()
{
if (m_back_to_initial_value != nullptr && m_is_modified_value)
m_back_to_initial_value(m_opt_id);
}
void Field::on_back_to_sys_value()
{
if (m_back_to_sys_value != nullptr && m_is_nonsys_value)
m_back_to_sys_value(m_opt_id);
}
wxString Field::get_tooltip_text(const wxString& default_string)
{
wxString tooltip_text("");
wxString tooltip = _(m_opt.tooltip);
if (tooltip.length() > 0)
tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " +
(boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string +
(boost::iends_with(m_opt_id, "_gcode") ? "" : "\n") +
_(L("parameter name")) + "\t: " + m_opt_id;
return tooltip_text;
}
bool Field::is_matched(const std::string& string, const std::string& pattern)
{
std::regex regex_pattern(pattern, std::regex_constants::icase); // use ::icase to make the matching case insensitive like /i in perl
return std::regex_match(string, regex_pattern);
}
void Field::get_value_by_opt_type(wxString& str)
{
switch (m_opt.type) {
case coInt:
m_value = wxAtoi(str);
break;
case coPercent:
case coPercents:
case coFloats:
case coFloat:{
if (m_opt.type == coPercent && str.Last() == '%')
str.RemoveLast();
else if (str.Last() == '%') {
wxString label = m_Label->GetLabel();
if (label.Last() == '\n') label.RemoveLast();
while (label.Last() == ' ') label.RemoveLast();
if (label.Last() == ':') label.RemoveLast();
show_error(m_parent, wxString::Format(_(L("%s doesn't support percentage")), label));
set_value(double_to_string(m_opt.min), true);
m_value = double(m_opt.min);
break; break;
} }
case coPercent: double val;
if(!str.ToCDouble(&val))
{ {
text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat())); show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits")));
set_value(double_to_string(val), true);
}
if (m_opt.min > val || val > m_opt.max)
{
show_error(m_parent, _(L("Input value is out of range")));
if (m_opt.min > val) val = m_opt.min;
if (val > m_opt.max) val = m_opt.max;
set_value(double_to_string(val), true);
}
m_value = val;
break; }
case coString:
case coStrings:
case coFloatOrPercent:
m_value = str.ToStdString();
break;
default:
break;
}
}
void TextCtrl::BUILD() {
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
wxString text_value = wxString("");
switch (m_opt.type) {
case coFloatOrPercent:
{
text_value = double_to_string(m_opt.default_value->getFloat());
if (static_cast<const ConfigOptionFloatOrPercent*>(m_opt.default_value)->percent)
text_value += "%"; text_value += "%";
break; break;
} }
case coPercents: case coPercent:
case coFloats: {
case coFloat: text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat()));
{ text_value += "%";
double val = m_opt.type == coFloats ? break;
static_cast<const ConfigOptionFloats*>(m_opt.default_value)->get_at(m_opt_idx) : }
m_opt.type == coFloat ? case coPercents:
m_opt.default_value->getFloat() : case coFloats:
static_cast<const ConfigOptionPercents*>(m_opt.default_value)->get_at(m_opt_idx); case coFloat:
text_value = double_to_string(val); {
break; double val = m_opt.type == coFloats ?
} static_cast<const ConfigOptionFloats*>(m_opt.default_value)->get_at(m_opt_idx) :
case coString: m_opt.type == coFloat ?
text_value = static_cast<const ConfigOptionString*>(m_opt.default_value)->value; m_opt.default_value->getFloat() :
break; static_cast<const ConfigOptionPercents*>(m_opt.default_value)->get_at(m_opt_idx);
case coStrings: text_value = double_to_string(val);
{ break;
const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(m_opt.default_value); }
if (vec == nullptr || vec->empty()) break; //for the case of empty default value case coString:
text_value = vec->get_at(m_opt_idx); text_value = static_cast<const ConfigOptionString*>(m_opt.default_value)->value;
break; break;
} case coStrings:
default: {
break; const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(m_opt.default_value);
} if (vec == nullptr || vec->empty()) break; //for the case of empty default value
text_value = vec->get_at(m_opt_idx);
break;
}
default:
break;
}
auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, (m_opt.multiline ? wxTE_MULTILINE : 0)); auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, (m_opt.multiline ? wxTE_MULTILINE : 0));
temp->SetToolTip(get_tooltip_text(text_value)); temp->SetToolTip(get_tooltip_text(text_value));
temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event) temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event)
{ {
//! to allow the default handling //! to allow the default handling
event.Skip(); event.Skip();
//! eliminating the g-code pop up text description //! eliminating the g-code pop up text description
bool flag = false; bool flag = false;
#ifdef __WXGTK__ #ifdef __WXGTK__
// I have no idea why, but on GTK flag works in other way // I have no idea why, but on GTK flag works in other way
flag = true; flag = true;
#endif // __WXGTK__ #endif // __WXGTK__
temp->GetToolTip()->Enable(flag); temp->GetToolTip()->Enable(flag);
}), temp->GetId()); }), temp->GetId());
#if !defined(__WXGTK__) #if !defined(__WXGTK__)
temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e) temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e)
{ {
e.Skip();// on_kill_focus(e); e.Skip();// on_kill_focus(e);
temp->GetToolTip()->Enable(true); temp->GetToolTip()->Enable(true);
}), temp->GetId()); }), temp->GetId());
#endif // __WXGTK__ #endif // __WXGTK__
temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt) temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt)
{
#ifdef __WXGTK__
if (bChangedValueEvent)
#endif //__WXGTK__
on_change_field();
}), temp->GetId());
#ifdef __WXGTK__
// to correct value updating on GTK we should:
// call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT
// and prevent value updating on wxEVT_KEY_DOWN
temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this);
temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this);
#endif //__WXGTK__
// select all text using Ctrl+A
temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event)
{
if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL))
temp->SetSelection(-1, -1); //select all
event.Skip();
}));
// recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp);
}
boost::any& TextCtrl::get_value()
{ {
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue(); #ifdef __WXGTK__
get_value_by_opt_type(ret_str); if (bChangedValueEvent)
#endif //__WXGTK__
return m_value; on_change_field();
} }), temp->GetId());
void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); }
void TextCtrl::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); }
#ifdef __WXGTK__ #ifdef __WXGTK__
void TextCtrl::change_field_value(wxEvent& event) // to correct value updating on GTK we should:
{ // call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT
if (bChangedValueEvent = event.GetEventType()==wxEVT_KEY_UP) // and prevent value updating on wxEVT_KEY_DOWN
on_change_field(); temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this);
event.Skip(); temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this);
}; #endif //__WXGTK__
// select all text using Ctrl+A
temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event)
{
if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL))
temp->SetSelection(-1, -1); //select all
event.Skip();
}));
// recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp);
}
boost::any& TextCtrl::get_value()
{
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
get_value_by_opt_type(ret_str);
return m_value;
}
void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); }
void TextCtrl::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); }
#ifdef __WXGTK__
void TextCtrl::change_field_value(wxEvent& event)
{
if (bChangedValueEvent = event.GetEventType()==wxEVT_KEY_UP)
on_change_field();
event.Skip();
};
#endif //__WXGTK__ #endif //__WXGTK__
void CheckBox::BUILD() { void CheckBox::BUILD() {
@ -384,10 +389,10 @@ void Choice::BUILD() {
// recast as a wxWindow to fit the calling convention // recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp); window = dynamic_cast<wxWindow*>(temp);
if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()){ if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()) {
} }
else{ else{
for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels){ for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) {
const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el; const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el;
temp->Append(str); temp->Append(str);
} }
@ -402,7 +407,7 @@ void Choice::BUILD() {
void Choice::set_selection() void Choice::set_selection()
{ {
wxString text_value = wxString(""); wxString text_value = wxString("");
switch (m_opt.type){ switch (m_opt.type) {
case coFloat: case coFloat:
case coPercent: { case coPercent: {
double val = m_opt.default_value->getFloat(); double val = m_opt.default_value->getFloat();
@ -481,12 +486,12 @@ void Choice::set_value(const boost::any& value, bool change_event)
{ {
m_disable_change_event = !change_event; m_disable_change_event = !change_event;
switch (m_opt.type){ switch (m_opt.type) {
case coInt: case coInt:
case coFloat: case coFloat:
case coPercent: case coPercent:
case coString: case coString:
case coStrings:{ case coStrings: {
wxString text_value; wxString text_value;
if (m_opt.type == coInt) if (m_opt.type == coInt)
text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value))); text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value)));
@ -504,11 +509,11 @@ void Choice::set_value(const boost::any& value, bool change_event)
dynamic_cast<wxComboBox*>(window)->SetSelection(idx); dynamic_cast<wxComboBox*>(window)->SetSelection(idx);
break; break;
} }
case coEnum:{ case coEnum: {
int val = boost::any_cast<int>(value); int val = boost::any_cast<int>(value);
if (m_opt_id.compare("external_fill_pattern") == 0) if (m_opt_id.compare("external_fill_pattern") == 0)
{ {
if (!m_opt.enum_values.empty()){ if (!m_opt.enum_values.empty()) {
std::string key; std::string key;
t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values(); t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
for (auto it : map_names) { for (auto it : map_names) {
@ -579,7 +584,7 @@ boost::any& Choice::get_value()
int ret_enum = static_cast<wxComboBox*>(window)->GetSelection(); int ret_enum = static_cast<wxComboBox*>(window)->GetSelection();
if (m_opt_id.compare("external_fill_pattern") == 0) if (m_opt_id.compare("external_fill_pattern") == 0)
{ {
if (!m_opt.enum_values.empty()){ if (!m_opt.enum_values.empty()) {
std::string key = m_opt.enum_values[ret_enum]; std::string key = m_opt.enum_values[ret_enum];
t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values(); t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
int value = map_names.at(key); int value = map_names.at(key);
@ -627,7 +632,8 @@ void ColourPicker::BUILD()
temp->SetToolTip(get_tooltip_text(clr_str)); temp->SetToolTip(get_tooltip_text(clr_str));
} }
boost::any& ColourPicker::get_value(){ boost::any& ColourPicker::get_value()
{
// boost::any m_value; // boost::any m_value;
auto colour = static_cast<wxColourPickerCtrl*>(window)->GetColour(); auto colour = static_cast<wxColourPickerCtrl*>(window)->GetColour();
@ -746,7 +752,7 @@ void SliderCtrl::BUILD()
temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0);
m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) { m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) {
if (!m_disable_change_event){ if (!m_disable_change_event) {
int val = boost::any_cast<int>(get_value()); int val = boost::any_cast<int>(get_value());
m_textctrl->SetLabel(wxString::Format("%d", val)); m_textctrl->SetLabel(wxString::Format("%d", val));
on_change_field(); on_change_field();
@ -755,7 +761,7 @@ void SliderCtrl::BUILD()
m_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { m_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) {
std::string value = e.GetString().utf8_str().data(); std::string value = e.GetString().utf8_str().data();
if (is_matched(value, "^-?\\d+(\\.\\d*)?$")){ if (is_matched(value, "^-?\\d+(\\.\\d*)?$")) {
m_disable_change_event = true; m_disable_change_event = true;
m_slider->SetValue(stoi(value)*m_scale); m_slider->SetValue(stoi(value)*m_scale);
m_disable_change_event = false; m_disable_change_event = false;

View File

@ -1426,8 +1426,10 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation)
} }
} }
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance) if (m_mode == Instance)
_synchronize_unselected_instances(); _synchronize_unselected_instances();
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
@ -1453,8 +1455,10 @@ void GLCanvas3D::Selection::scale(const Vec3d& scale)
} }
} }
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance) if (m_mode == Instance)
_synchronize_unselected_instances(); _synchronize_unselected_instances();
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
@ -1471,13 +1475,105 @@ void GLCanvas3D::Selection::mirror(Axis axis)
(*m_volumes)[i]->set_mirror(axis, -(*m_volumes)[i]->get_mirror(axis)); (*m_volumes)[i]->set_mirror(axis, -(*m_volumes)[i]->get_mirror(axis));
} }
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance) if (m_mode == Instance)
_synchronize_unselected_instances(); _synchronize_unselected_instances();
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
void GLCanvas3D::Selection::translate(unsigned int object_idx, const Vec3d& displacement)
{
if (!m_valid)
return;
for (unsigned int i : m_list)
{
GLVolume* v = (*m_volumes)[i];
if (v->object_idx() == object_idx)
v->set_offset(v->get_offset() + displacement);
}
std::set<unsigned int> done; // prevent processing volumes twice
done.insert(m_list.begin(), m_list.end());
for (unsigned int i : m_list)
{
if (done.size() == m_volumes->size())
break;
int object_idx = (*m_volumes)[i]->object_idx();
if (object_idx >= 1000)
continue;
// Process unselected volumes of the object.
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
{
if (done.size() == m_volumes->size())
break;
if (done.find(j) != done.end())
continue;
GLVolume* v = (*m_volumes)[j];
if (v->object_idx() != object_idx)
continue;
v->set_offset(v->get_offset() + displacement);
done.insert(j);
}
}
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement)
{
if (!m_valid)
return;
for (unsigned int i : m_list)
{
GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
v->set_offset(v->get_offset() + displacement);
}
std::set<unsigned int> done; // prevent processing volumes twice
done.insert(m_list.begin(), m_list.end());
for (unsigned int i : m_list)
{
if (done.size() == m_volumes->size())
break;
int object_idx = (*m_volumes)[i]->object_idx();
if (object_idx >= 1000)
continue;
// Process unselected volumes of the object.
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
{
if (done.size() == m_volumes->size())
break;
if (done.find(j) != done.end())
continue;
GLVolume* v = (*m_volumes)[j];
if ((v->object_idx() != object_idx) || (v->instance_idx() != instance_idx))
continue;
v->set_offset(v->get_offset() + displacement);
done.insert(j);
}
}
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::render(bool show_indirect_selection) const void GLCanvas3D::Selection::render(bool show_indirect_selection) const
{ {
if (is_empty()) if (is_empty())
@ -6648,10 +6744,10 @@ void GLCanvas3D::_on_move()
if (done.find(done_id) != done.end()) if (done.find(done_id) != done.end())
continue; continue;
done.insert(done_id);
if (object_idx < 1000) if (object_idx < 1000)
{ {
done.insert(done_id);
// Move instances. // Move instances.
ModelObject* model_object = m_model->objects[object_idx]; ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) if (model_object != nullptr)
@ -6666,6 +6762,14 @@ void GLCanvas3D::_on_move()
wipe_tower_origin = v->get_offset(); wipe_tower_origin = v->get_offset();
} }
for (const std::pair<int, int>& i : done)
{
ModelObject* m = m_model->objects[i.first];
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
if (object_moved) if (object_moved)
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED)); post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED));
@ -6700,10 +6804,19 @@ void GLCanvas3D::_on_rotate()
if (model_object != nullptr) if (model_object != nullptr)
{ {
model_object->instances[instance_idx]->set_rotation(v->get_rotation()); model_object->instances[instance_idx]->set_rotation(v->get_rotation());
model_object->instances[instance_idx]->set_offset(v->get_offset());
model_object->invalidate_bounding_box(); model_object->invalidate_bounding_box();
} }
} }
for (const std::pair<int, int>& i : done)
{
ModelObject* m = m_model->objects[i.first];
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
} }
@ -6734,10 +6847,19 @@ void GLCanvas3D::_on_scale()
if (model_object != nullptr) if (model_object != nullptr)
{ {
model_object->instances[instance_idx]->set_scaling_factor(v->get_scaling_factor()); model_object->instances[instance_idx]->set_scaling_factor(v->get_scaling_factor());
model_object->instances[instance_idx]->set_offset(v->get_offset());
model_object->invalidate_bounding_box(); model_object->invalidate_bounding_box();
} }
} }
for (const std::pair<int, int>& i : done)
{
ModelObject* m = m_model->objects[i.first];
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
} }

View File

@ -508,6 +508,9 @@ public:
void mirror(Axis axis); void mirror(Axis axis);
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
void translate(unsigned int object_idx, const Vec3d& displacement);
void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement);
void render(bool show_indirect_selection) const; void render(bool show_indirect_selection) const;
private: private:

View File

@ -926,7 +926,11 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
// gets transform from first selected volume // gets transform from first selected volume
const GLVolume* v = selection.get_volume(*idxs.begin()); const GLVolume* v = selection.get_volume(*idxs.begin());
#if ENABLE_MODELVOLUME_TRANSFORM
transform = v->world_matrix();
#else
transform = v->world_matrix().cast<double>(); transform = v->world_matrix().cast<double>();
#endif // ENABLE_MODELVOLUME_TRANSFORM
// gets angles from first selected volume // gets angles from first selected volume
angles = v->get_rotation(); angles = v->get_rotation();

View File

@ -135,11 +135,11 @@ PreviewIface* create_preview_iface(wxNotebook* parent, DynamicPrintConfig* confi
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/) void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
{ {
try{ try{
switch (config.def()->get(opt_key)->type){ switch (config.def()->get(opt_key)->type) {
case coFloatOrPercent:{ case coFloatOrPercent:{
std::string str = boost::any_cast<std::string>(value); std::string str = boost::any_cast<std::string>(value);
bool percent = false; bool percent = false;
if (str.back() == '%'){ if (str.back() == '%') {
str.pop_back(); str.pop_back();
percent = true; percent = true;
} }
@ -172,7 +172,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
config.option<ConfigOptionStrings>(opt_key)->values = config.option<ConfigOptionStrings>(opt_key)->values =
boost::any_cast<std::vector<std::string>>(value); boost::any_cast<std::vector<std::string>>(value);
} }
else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0){ else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0) {
std::string str = boost::any_cast<std::string>(value); std::string str = boost::any_cast<std::string>(value);
if (str.back() == ';') str.pop_back(); if (str.back() == ';') str.pop_back();
// Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values. // Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
@ -219,7 +219,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
} }
break; break;
case coPoints:{ case coPoints:{
if (opt_key.compare("bed_shape") == 0){ if (opt_key.compare("bed_shape") == 0) {
config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value); config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
break; break;
} }
@ -239,22 +239,26 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
} }
} }
void show_error(wxWindow* parent, const wxString& message) { void show_error(wxWindow* parent, const wxString& message)
{
ErrorDialog msg(parent, message); ErrorDialog msg(parent, message);
msg.ShowModal(); msg.ShowModal();
} }
void show_error_id(int id, const std::string& message) { void show_error_id(int id, const std::string& message)
{
auto *parent = id != 0 ? wxWindow::FindWindowById(id) : nullptr; auto *parent = id != 0 ? wxWindow::FindWindowById(id) : nullptr;
show_error(parent, wxString::FromUTF8(message.data())); show_error(parent, wxString::FromUTF8(message.data()));
} }
void show_info(wxWindow* parent, const wxString& message, const wxString& title){ void show_info(wxWindow* parent, const wxString& message, const wxString& title)
{
wxMessageDialog msg_wingow(parent, message, title.empty() ? _(L("Notice")) : title, wxOK | wxICON_INFORMATION); wxMessageDialog msg_wingow(parent, message, title.empty() ? _(L("Notice")) : title, wxOK | wxICON_INFORMATION);
msg_wingow.ShowModal(); msg_wingow.ShowModal();
} }
void warning_catcher(wxWindow* parent, const wxString& message){ void warning_catcher(wxWindow* parent, const wxString& message)
{
if (message == "GLUquadricObjPtr | " + _(L("Attempt to free unreferenced scalar")) ) if (message == "GLUquadricObjPtr | " + _(L("Attempt to free unreferenced scalar")) )
return; return;
wxMessageDialog msg(parent, message, _(L("Warning")), wxOK | wxICON_WARNING); wxMessageDialog msg(parent, message, _(L("Warning")), wxOK | wxICON_WARNING);

View File

@ -122,7 +122,7 @@ bool GUI_App::OnInit()
// try to get the mutex. If we can't, just skip this idle event and get the next one. // try to get the mutex. If we can't, just skip this idle event and get the next one.
if (!callback_register.try_lock()) return; if (!callback_register.try_lock()) return;
// pop callback // pop callback
if (m_cb.size() != 0){ if (m_cb.size() != 0) {
cur_cb = m_cb.top(); cur_cb = m_cb.top();
m_cb.pop(); m_cb.pop();
} }
@ -143,7 +143,7 @@ bool GUI_App::OnInit()
// On OS X the UI tends to freeze in weird ways if modal dialogs(config wizard, update notifications, ...) // On OS X the UI tends to freeze in weird ways if modal dialogs(config wizard, update notifications, ...)
// are shown before or in the same event callback with the main frame creation. // are shown before or in the same event callback with the main frame creation.
// Therefore we schedule them for later using CallAfter. // Therefore we schedule them for later using CallAfter.
CallAfter([this](){ CallAfter([this]() {
// eval{ // eval{
if (!preset_updater->config_update()) if (!preset_updater->config_update())
mainframe->Close(); mainframe->Close();
@ -154,7 +154,7 @@ bool GUI_App::OnInit()
// } // }
}); });
CallAfter([this](){ CallAfter([this]() {
if (!config_wizard_startup(app_conf_exists)) { if (!config_wizard_startup(app_conf_exists)) {
// Only notify if there was not wizard so as not to bother too much ... // Only notify if there was not wizard so as not to bother too much ...
preset_updater->slic3r_update_notify(); preset_updater->slic3r_update_notify();
@ -196,13 +196,13 @@ void GUI_App::init_label_colours()
void GUI_App::update_label_colours_from_appconfig() void GUI_App::update_label_colours_from_appconfig()
{ {
if (app_config->has("label_clr_sys")){ if (app_config->has("label_clr_sys")) {
auto str = app_config->get("label_clr_sys"); auto str = app_config->get("label_clr_sys");
if (str != "") if (str != "")
m_color_label_sys = wxColour(str); m_color_label_sys = wxColour(str);
} }
if (app_config->has("label_clr_modified")){ if (app_config->has("label_clr_modified")) {
auto str = app_config->get("label_clr_modified"); auto str = app_config->get("label_clr_modified");
if (str != "") if (str != "")
m_color_label_modified = wxColour(str); m_color_label_modified = wxColour(str);
@ -251,7 +251,7 @@ void GUI_App::recreate_GUI()
// On OSX the UI was not initialized correctly if the wizard was called // On OSX the UI was not initialized correctly if the wizard was called
// before the UI was up and running. // before the UI was up and running.
CallAfter([](){ CallAfter([]() {
// Run the config wizard, don't offer the "reset user profile" checkbox. // Run the config wizard, don't offer the "reset user profile" checkbox.
config_wizard_startup(true); config_wizard_startup(true);
}); });
@ -267,7 +267,8 @@ void GUI_App::system_info()
// static method accepting a wxWindow object as first parameter // static method accepting a wxWindow object as first parameter
bool GUI_App::catch_error(std::function<void()> cb, bool GUI_App::catch_error(std::function<void()> cb,
// wxMessageDialog* message_dialog, // wxMessageDialog* message_dialog,
const std::string& err /*= ""*/){ const std::string& err /*= ""*/)
{
if (!err.empty()) { if (!err.empty()) {
if (cb) if (cb)
cb(); cb();
@ -280,14 +281,16 @@ bool GUI_App::catch_error(std::function<void()> cb,
} }
// static method accepting a wxWindow object as first parameter // static method accepting a wxWindow object as first parameter
void fatal_error(wxWindow* parent){ void fatal_error(wxWindow* parent)
{
show_error(parent, ""); show_error(parent, "");
// exit 1; // #ys_FIXME // exit 1; // #ys_FIXME
} }
// Called after the Preferences dialog is closed and the program settings are saved. // Called after the Preferences dialog is closed and the program settings are saved.
// Update the UI based on the current preferences. // Update the UI based on the current preferences.
void GUI_App::update_ui_from_settings(){ void GUI_App::update_ui_from_settings()
{
mainframe->update_ui_from_settings(); mainframe->update_ui_from_settings();
} }
@ -364,7 +367,7 @@ bool GUI_App::select_language( wxArrayString & names,
_(L("Array of language names and identifiers should have the same size."))); _(L("Array of language names and identifiers should have the same size.")));
int init_selection = 0; int init_selection = 0;
long current_language = m_wxLocale ? m_wxLocale->GetLanguage() : wxLANGUAGE_UNKNOWN; long current_language = m_wxLocale ? m_wxLocale->GetLanguage() : wxLANGUAGE_UNKNOWN;
for (auto lang : identifiers){ for (auto lang : identifiers) {
if (lang == current_language) if (lang == current_language)
break; break;
++init_selection; ++init_selection;
@ -526,7 +529,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// TODO: for when we're able to flash dictionaries // TODO: for when we're able to flash dictionaries
// local_menu->Append(config_id_base + FirmwareMenuDict, _(L("Flash language file")), _(L("Upload a language dictionary file into a Prusa printer"))); // local_menu->Append(config_id_base + FirmwareMenuDict, _(L("Flash language file")), _(L("Upload a language dictionary file into a Prusa printer")));
local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event){ local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) {
switch (event.GetId() - config_id_base) { switch (event.GetId() - config_id_base) {
case ConfigMenuWizard: case ConfigMenuWizard:
config_wizard(ConfigWizard::RR_USER); config_wizard(ConfigWizard::RR_USER);
@ -692,7 +695,7 @@ wxNotebook* GUI_App::tab_panel() const
// } // }
// Do we need this function??? // Do we need this function???
// void GUI_App::notify(message){ // void GUI_App::notify(message) {
// auto frame = GetTopWindow(); // auto frame = GetTopWindow();
// // try harder to attract user attention on OS X // // try harder to attract user attention on OS X
// if (!frame->IsActive()) // if (!frame->IsActive())

View File

@ -150,7 +150,8 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt)
GetMainWindow()->SetToolTip(""); // hide tooltip GetMainWindow()->SetToolTip(""); // hide tooltip
} }
wxPoint ObjectList::get_mouse_position_in_control() { wxPoint ObjectList::get_mouse_position_in_control()
{
const wxPoint& pt = wxGetMousePosition(); const wxPoint& pt = wxGetMousePosition();
// wxWindow* win = GetMainWindow(); // wxWindow* win = GetMainWindow();
// wxPoint screen_pos = win->GetScreenPosition(); // wxPoint screen_pos = win->GetScreenPosition();
@ -159,10 +160,9 @@ wxPoint ObjectList::get_mouse_position_in_control() {
int ObjectList::get_selected_obj_idx() const int ObjectList::get_selected_obj_idx() const
{ {
if (GetSelectedItemsCount() == 1) { if (GetSelectedItemsCount() == 1)
auto item = GetSelection(); return m_objects_model->GetIdByItem(m_objects_model->GetTopParent(GetSelection()));
return m_objects_model->GetIdByItem(item);
}
return -1; return -1;
} }
@ -209,7 +209,8 @@ void ObjectList::update_extruder_in_config(const wxString& selection)
wxGetApp().plater()->update(); wxGetApp().plater()->update();
} }
void ObjectList::init_icons(){ void ObjectList::init_icons()
{
m_bmp_modifiermesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); m_bmp_modifiermesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
m_bmp_solidmesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); m_bmp_solidmesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
@ -297,7 +298,7 @@ void ObjectList::key_event(wxKeyEvent& event)
#ifdef __WXOSX__ #ifdef __WXOSX__
|| event.GetKeyCode() == WXK_BACK || event.GetKeyCode() == WXK_BACK
#endif //__WXOSX__ #endif //__WXOSX__
){ ) {
printf("WXK_BACK\n"); printf("WXK_BACK\n");
remove(); remove();
} }
@ -565,7 +566,7 @@ wxMenu* ObjectList::create_add_part_popupmenu()
// Append settings popupmenu // Append settings popupmenu
menu->Append(menu_item_settings(menu, config_id_base + i + 5, false)); menu->Append(menu_item_settings(menu, config_id_base + i + 5, false));
menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event){ menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) {
switch (event.GetId() - config_id_base) { switch (event.GetId() - config_id_base) {
case 0: case 0:
load_subobject(); load_subobject();
@ -609,7 +610,7 @@ wxMenu* ObjectList::create_part_settings_popupmenu()
// Append settings popupmenu // Append settings popupmenu
menu->Append(menu_item_settings(menu, config_id_base + 1, true)); menu->Append(menu_item_settings(menu, config_id_base + 1, true));
menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event){ menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) {
switch (event.GetId() - config_id_base) { switch (event.GetId() - config_id_base) {
case 0: case 0:
split(true); split(true);
@ -686,6 +687,7 @@ void ObjectList::load_part( ModelObject* model_object,
{ {
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0); wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
m_parts_changed = false;
wxArrayString input_files; wxArrayString input_files;
wxGetApp().open_model(parent, input_files); wxGetApp().open_model(parent, input_files);
for (int i = 0; i < input_files.size(); ++i) { for (int i = 0; i < input_files.size(); ++i) {
@ -706,6 +708,7 @@ void ObjectList::load_part( ModelObject* model_object,
if (model_object->origin_translation != Vec3d::Zero()) if (model_object->origin_translation != Vec3d::Zero())
{ {
object->center_around_origin(); object->center_around_origin();
object->ensure_on_bed();
delta = model_object->origin_translation - object->origin_translation; delta = model_object->origin_translation - object->origin_translation;
} }
for (auto volume : object->volumes) { for (auto volume : object->volumes) {
@ -737,6 +740,7 @@ void ObjectList::load_lambda( ModelObject* model_object,
{ {
auto dlg = new LambdaObjectDialog(GetMainWindow()); auto dlg = new LambdaObjectDialog(GetMainWindow());
if (dlg->ShowModal() == wxID_CANCEL) { if (dlg->ShowModal() == wxID_CANCEL) {
m_parts_changed = false;
return; return;
} }
@ -800,7 +804,7 @@ void ObjectList::load_lambda(const std::string& type_name)
mesh = make_cylinder(params.cyl_r, params.cyl_h); mesh = make_cylinder(params.cyl_r, params.cyl_h);
else if (type_name == _("Sphere")) else if (type_name == _("Sphere"))
mesh = make_sphere(params.sph_rho); mesh = make_sphere(params.sph_rho);
else if (type_name == _("Slab")){ else if (type_name == _("Slab")) {
const auto& size = (*m_objects)[m_selected_object_id]->bounding_box().size(); const auto& size = (*m_objects)[m_selected_object_id]->bounding_box().size();
mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h); mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h);
// box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z // box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z
@ -955,6 +959,11 @@ void ObjectList::split(const bool split_part)
m_parts_changed = true; m_parts_changed = true;
parts_changed(m_selected_object_id); parts_changed(m_selected_object_id);
#if ENABLE_EXTENDED_SELECTION
// restores selection
_3DScene::get_canvas(wxGetApp().canvas3D())->get_selection().add_object(m_selected_object_id);
#endif // ENABLE_EXTENDED_SELECTION
} }
bool ObjectList::get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume) bool ObjectList::get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume)
@ -995,9 +1004,17 @@ bool ObjectList::is_splittable_object(const bool split_part)
return splittable; return splittable;
} }
void ObjectList::part_settings_changed()
{
m_part_settings_changed = true;
wxGetApp().plater()->changed_object(get_selected_obj_idx());
m_part_settings_changed = false;
}
void ObjectList::parts_changed(int obj_idx) void ObjectList::parts_changed(int obj_idx)
{ {
wxGetApp().mainframe->m_plater->changed_object_settings(obj_idx); wxGetApp().plater()->changed_object(get_selected_obj_idx());
m_parts_changed = false;
} }
void ObjectList::part_selection_changed() void ObjectList::part_selection_changed()
@ -1035,7 +1052,7 @@ void ObjectList::part_selection_changed()
m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config;
} }
} }
else if (m_objects_model->GetItemType(item) == itVolume){ else if (m_objects_model->GetItemType(item) == itVolume) {
og_name = _(L("Part manipulation")); og_name = _(L("Part manipulation"));
is_part = true; is_part = true;
const auto volume_id = m_objects_model->GetVolumeIdByItem(item); const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
@ -1085,7 +1102,7 @@ void ObjectList::add_object_to_list(size_t obj_idx)
auto stats = model_object->volumes[0]->mesh.stl.stats; auto stats = model_object->volumes[0]->mesh.stl.stats;
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
stats.facets_added + stats.facets_reversed + stats.backwards_edges; stats.facets_added + stats.facets_reversed + stats.backwards_edges;
if (errors > 0) { if (errors > 0) {
wxVariant variant; wxVariant variant;
variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning); variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning);
m_objects_model->SetValue(variant, item, 0); m_objects_model->SetValue(variant, item, 0);
@ -1235,7 +1252,7 @@ void ObjectList::update_selections_on_canvas()
auto add_to_selection = [this](const wxDataViewItem& item, GLCanvas3D::Selection& selection, bool as_single_selection) auto add_to_selection = [this](const wxDataViewItem& item, GLCanvas3D::Selection& selection, bool as_single_selection)
{ {
if (m_objects_model->GetParent(item) == wxDataViewItem(0)){ if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection); selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection);
return; return;
} }

View File

@ -95,10 +95,11 @@ public:
bool is_splittable_object(const bool split_part); bool is_splittable_object(const bool split_part);
wxPoint get_mouse_position_in_control(); wxPoint get_mouse_position_in_control();
wxBoxSizer* get_sizer(){return m_sizer;} wxBoxSizer* get_sizer() {return m_sizer;}
int get_selected_obj_idx() const; int get_selected_obj_idx() const;
bool is_parts_changed() const { return m_parts_changed; } bool is_parts_changed() const { return m_parts_changed; }
bool is_part_settings_changed() const{ return m_part_settings_changed; } bool is_part_settings_changed() const { return m_part_settings_changed; }
void part_settings_changed();
void parts_changed(int obj_idx); void parts_changed(int obj_idx);
void part_selection_changed(); void part_selection_changed();

View File

@ -32,8 +32,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent):
m_og->label_width = 100; m_og->label_width = 100;
m_og->set_grid_vgap(5); m_og->set_grid_vgap(5);
m_og->m_on_change = [this](t_config_option_key opt_key, boost::any value){ m_og->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
if (opt_key == "scale_unit"){ if (opt_key == "scale_unit") {
const wxString& selection = boost::any_cast<wxString>(value); const wxString& selection = boost::any_cast<wxString>(value);
std::vector<std::string> axes{ "x", "y", "z" }; std::vector<std::string> axes{ "x", "y", "z" };
for (auto axis : axes) { for (auto axis : axes) {
@ -80,7 +80,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent):
if (option_name == "Scale") { if (option_name == "Scale") {
line.near_label_widget = [](wxWindow* parent) { line.near_label_widget = [](wxWindow* parent) {
auto btn = new PrusaLockButton(parent, wxID_ANY); auto btn = new PrusaLockButton(parent, wxID_ANY);
btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event){ btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event) {
event.Skip(); event.Skip();
wxTheApp->CallAfter([btn]() { wxTheApp->CallAfter([btn]() {
wxGetApp().obj_manipul()->set_uniform_scaling(btn->IsLocked()); wxGetApp().obj_manipul()->set_uniform_scaling(btn->IsLocked());
@ -188,7 +188,7 @@ void ObjectManipulation::update_settings_list()
#ifdef __WXMSW__ #ifdef __WXMSW__
btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__ #endif // __WXMSW__
btn->Bind(wxEVT_BUTTON, [opt_key, config](wxEvent &event){ btn->Bind(wxEVT_BUTTON, [opt_key, config](wxEvent &event) {
config->erase(opt_key); config->erase(opt_key);
wxTheApp->CallAfter([]() { wxGetApp().obj_manipul()->update_settings_list(); }); wxTheApp->CallAfter([]() { wxGetApp().obj_manipul()->update_settings_list(); });
}); });
@ -225,6 +225,9 @@ void ObjectManipulation::update_settings_list()
optgroup->label_width = 150; optgroup->label_width = 150;
optgroup->sidetext_width = 70; optgroup->sidetext_width = 70;
optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) {
wxGetApp().obj_list()->part_settings_changed(); };
for (auto& opt : cat.second) for (auto& opt : cat.second)
{ {
if (opt == "extruder") if (opt == "extruder")
@ -268,7 +271,7 @@ void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& sele
{ {
if (selection.is_single_full_object()) if (selection.is_single_full_object())
{ {
if (wxGetApp().mainframe->m_plater->model().objects[selection.get_object_idx()]->instances.size() == 1) if (!wxGetApp().model_objects()->empty() && (*wxGetApp().model_objects())[selection.get_object_idx()]->instances.size() == 1)
{ {
// all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());

View File

@ -38,8 +38,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
ConfigOptionDef def; ConfigOptionDef def;
def.width = 70; def.width = 70;
auto optgroup = init_modificator_options_page(_(L("Box"))); auto optgroup = init_modificator_options_page(_(L("Box")));
if (optgroup){ if (optgroup) {
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
int opt_id = opt_key == "l" ? 0 : int opt_id = opt_key == "l" ? 0 :
opt_key == "w" ? 1 : opt_key == "w" ? 1 :
opt_key == "h" ? 2 : -1; opt_key == "h" ? 2 : -1;
@ -63,8 +63,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
} }
optgroup = init_modificator_options_page(_(L("Cylinder"))); optgroup = init_modificator_options_page(_(L("Cylinder")));
if (optgroup){ if (optgroup) {
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
int val = boost::any_cast<int>(value); int val = boost::any_cast<int>(value);
if (opt_key == "cyl_r") if (opt_key == "cyl_r")
object_parameters.cyl_r = val; object_parameters.cyl_r = val;
@ -85,8 +85,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
} }
optgroup = init_modificator_options_page(_(L("Sphere"))); optgroup = init_modificator_options_page(_(L("Sphere")));
if (optgroup){ if (optgroup) {
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
if (opt_key == "sph_rho") if (opt_key == "sph_rho")
object_parameters.sph_rho = boost::any_cast<double>(value); object_parameters.sph_rho = boost::any_cast<double>(value);
else return; else return;
@ -100,8 +100,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
} }
optgroup = init_modificator_options_page(_(L("Slab"))); optgroup = init_modificator_options_page(_(L("Slab")));
if (optgroup){ if (optgroup) {
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
double val = boost::any_cast<double>(value); double val = boost::any_cast<double>(value);
if (opt_key == "slab_z") if (opt_key == "slab_z")
object_parameters.slab_z = val; object_parameters.slab_z = val;
@ -171,7 +171,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
// Called from the constructor. // Called from the constructor.
// Create a panel for a rectangular / circular / custom bed shape. // Create a panel for a rectangular / circular / custom bed shape.
ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(const wxString& title){ ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(const wxString& title)
{
if (!m_type_name.IsEmpty() && m_type_name != title) if (!m_type_name.IsEmpty() && m_type_name != title)
return nullptr; return nullptr;

View File

@ -41,10 +41,10 @@ class LambdaObjectDialog : public wxDialog
public: public:
LambdaObjectDialog(wxWindow* parent, LambdaObjectDialog(wxWindow* parent,
const wxString type_name = wxEmptyString); const wxString type_name = wxEmptyString);
~LambdaObjectDialog(){} ~LambdaObjectDialog() {}
bool CanClose() { return true; } // ??? bool CanClose() { return true; } // ???
OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; } OBJECT_PARAMETERS& ObjectParameters() { return object_parameters; }
ConfigOptionsGroupShp init_modificator_options_page(const wxString& title); ConfigOptionsGroupShp init_modificator_options_page(const wxString& title);

View File

@ -81,7 +81,7 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL
Layout(); Layout();
// declare events // declare events
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event){ Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event) {
if (event.CanVeto() && !wxGetApp().check_unsaved_changes()) { if (event.CanVeto() && !wxGetApp().check_unsaved_changes()) {
event.Veto(); event.Veto();
return; return;
@ -118,7 +118,7 @@ void MainFrame::init_tabpanel()
{ {
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL); m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL);
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&){ m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
auto panel = m_tabpanel->GetCurrentPage(); auto panel = m_tabpanel->GetCurrentPage();
// panel->OnActivate(); if panel->can('OnActivate'); // panel->OnActivate(); if panel->can('OnActivate');
@ -162,7 +162,7 @@ void MainFrame::init_tabpanel()
// Show a correct number of filament fields. // Show a correct number of filament fields.
// nozzle_diameter is undefined when SLA printer is selected // nozzle_diameter is undefined when SLA printer is selected
if (full_config.has("nozzle_diameter")){ if (full_config.has("nozzle_diameter")) {
m_plater->on_extruders_change(full_config.option<ConfigOptionFloats>("nozzle_diameter")->values.size()); m_plater->on_extruders_change(full_config.option<ConfigOptionFloats>("nozzle_diameter")->values.size());
} }
} }
@ -181,7 +181,7 @@ std::vector<PresetTab>& MainFrame::get_preset_tabs() {
Tab* MainFrame::get_tab(const std::string& name) Tab* MainFrame::get_tab(const std::string& name)
{ {
std::vector<PresetTab>::iterator it = std::find_if(preset_tabs.begin(), preset_tabs.end(), std::vector<PresetTab>::iterator it = std::find_if(preset_tabs.begin(), preset_tabs.end(),
[name](PresetTab& tab){ return name == tab.name; }); [name](PresetTab& tab) { return name == tab.name; });
return it != preset_tabs.end() ? it->panel : nullptr; return it != preset_tabs.end() ? it->panel : nullptr;
} }
@ -218,7 +218,7 @@ void MainFrame::add_created_tab(Tab* panel)
bool add_panel = true; bool add_panel = true;
auto it = std::find_if(preset_tabs.begin(), preset_tabs.end(), auto it = std::find_if(preset_tabs.begin(), preset_tabs.end(),
[tab_name](PresetTab& tab){return tab.name == tab_name; }); [tab_name](PresetTab& tab) {return tab.name == tab_name; });
if (it != preset_tabs.end()) { if (it != preset_tabs.end()) {
it->panel = panel; it->panel = panel;
add_panel = it->technology == wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); add_panel = it->technology == wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
@ -236,59 +236,59 @@ void MainFrame::init_menubar()
append_menu_item(fileMenu, wxID_ANY, _(L("Open STL/OBJ/AMF/3MF…\tCtrl+O")), _(L("Open a model")), append_menu_item(fileMenu, wxID_ANY, _(L("Open STL/OBJ/AMF/3MF…\tCtrl+O")), _(L("Open a model")),
[this](wxCommandEvent&) { if (m_plater) m_plater->add(); }, "brick_add.png"); [this](wxCommandEvent&) { if (m_plater) m_plater->add(); }, "brick_add.png");
append_menu_item(fileMenu, wxID_ANY, _(L("&Load Config…\tCtrl+L")), _(L("Load exported configuration file")), append_menu_item(fileMenu, wxID_ANY, _(L("&Load Config…\tCtrl+L")), _(L("Load exported configuration file")),
[this](wxCommandEvent&){ load_config_file(); }, "plugin_add.png"); [this](wxCommandEvent&) { load_config_file(); }, "plugin_add.png");
append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config…\tCtrl+E")), _(L("Export current configuration to file")), append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config…\tCtrl+E")), _(L("Export current configuration to file")),
[this](wxCommandEvent&){ export_config(); }, "plugin_go.png"); [this](wxCommandEvent&) { export_config(); }, "plugin_go.png");
append_menu_item(fileMenu, wxID_ANY, _(L("&Load Config Bundle…")), _(L("Load presets from a bundle")), append_menu_item(fileMenu, wxID_ANY, _(L("&Load Config Bundle…")), _(L("Load presets from a bundle")),
[this](wxCommandEvent&){ load_configbundle(); }, "lorry_add.png"); [this](wxCommandEvent&) { load_configbundle(); }, "lorry_add.png");
append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config Bundle…")), _(L("Export all presets to file")), append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config Bundle…")), _(L("Export all presets to file")),
[this](wxCommandEvent&){ export_configbundle(); }, "lorry_go.png"); [this](wxCommandEvent&) { export_configbundle(); }, "lorry_go.png");
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
wxMenuItem* repeat = nullptr; wxMenuItem* repeat = nullptr;
append_menu_item(fileMenu, wxID_ANY, _(L("Q&uick Slice…\tCtrl+U")), _(L("Slice a file into a G-code")), append_menu_item(fileMenu, wxID_ANY, _(L("Q&uick Slice…\tCtrl+U")), _(L("Slice a file into a G-code")),
[this, repeat](wxCommandEvent&){ [this, repeat](wxCommandEvent&) {
wxTheApp->CallAfter([this, repeat](){ wxTheApp->CallAfter([this, repeat]() {
quick_slice(); quick_slice();
repeat->Enable(is_last_input_file()); repeat->Enable(is_last_input_file());
}); }, "cog_go.png"); }); }, "cog_go.png");
append_menu_item(fileMenu, wxID_ANY, _(L("Quick Slice and Save &As…\tCtrl+Alt+U")), _(L("Slice a file into a G-code, save as")), append_menu_item(fileMenu, wxID_ANY, _(L("Quick Slice and Save &As…\tCtrl+Alt+U")), _(L("Slice a file into a G-code, save as")),
[this, repeat](wxCommandEvent&){ [this, repeat](wxCommandEvent&) {
wxTheApp->CallAfter([this, repeat](){ wxTheApp->CallAfter([this, repeat]() {
quick_slice(qsSaveAs); quick_slice(qsSaveAs);
repeat->Enable(is_last_input_file()); repeat->Enable(is_last_input_file());
}); }, "cog_go.png"); }); }, "cog_go.png");
repeat = append_menu_item(fileMenu, wxID_ANY, _(L("&Repeat Last Quick Slice\tCtrl+Shift+U")), _(L("Repeat last quick slice")), repeat = append_menu_item(fileMenu, wxID_ANY, _(L("&Repeat Last Quick Slice\tCtrl+Shift+U")), _(L("Repeat last quick slice")),
[this](wxCommandEvent&){ [this](wxCommandEvent&) {
wxTheApp->CallAfter([this](){ wxTheApp->CallAfter([this]() {
quick_slice(qsReslice); quick_slice(qsReslice);
}); }, "cog_go.png"); }); }, "cog_go.png");
repeat->Enable(0); repeat->Enable(0);
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_ANY, _(L("Slice to SV&G…\tCtrl+G")), _(L("Slice file to a multi-layer SVG")), append_menu_item(fileMenu, wxID_ANY, _(L("Slice to SV&G…\tCtrl+G")), _(L("Slice file to a multi-layer SVG")),
[this](wxCommandEvent&){ quick_slice(qsSaveAs | qsExportSVG); }, "shape_handles.png"); [this](wxCommandEvent&) { quick_slice(qsSaveAs | qsExportSVG); }, "shape_handles.png");
append_menu_item(fileMenu, wxID_ANY, _(L("Slice to PNG…")), _(L("Slice file to a set of PNG files")), append_menu_item(fileMenu, wxID_ANY, _(L("Slice to PNG…")), _(L("Slice file to a set of PNG files")),
[this](wxCommandEvent&){ slice_to_png(); /*$self->quick_slice(save_as = > 0, export_png = > 1);*/ }, "shape_handles.png"); [this](wxCommandEvent&) { slice_to_png(); /*$self->quick_slice(save_as = > 0, export_png = > 1);*/ }, "shape_handles.png");
m_menu_item_reslice_now = append_menu_item(fileMenu, wxID_ANY, _(L("(&Re)Slice Now\tCtrl+S")), _(L("Start new slicing process")), m_menu_item_reslice_now = append_menu_item(fileMenu, wxID_ANY, _(L("(&Re)Slice Now\tCtrl+S")), _(L("Start new slicing process")),
[this](wxCommandEvent&){ reslice_now(); }, "shape_handles.png"); [this](wxCommandEvent&) { reslice_now(); }, "shape_handles.png");
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_ANY, _(L("Repair STL file…")), _(L("Automatically repair an STL file")), append_menu_item(fileMenu, wxID_ANY, _(L("Repair STL file…")), _(L("Automatically repair an STL file")),
[this](wxCommandEvent&){ repair_stl(); }, "wrench.png"); [this](wxCommandEvent&) { repair_stl(); }, "wrench.png");
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")), append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")),
[this](wxCommandEvent&){ Close(false); } ); [this](wxCommandEvent&) { Close(false); } );
} }
// Plater menu // Plater menu
if (m_plater) { if (m_plater) {
m_plater_menu = new wxMenu(); m_plater_menu = new wxMenu();
append_menu_item(m_plater_menu, wxID_ANY, _(L("Export G-code...")), _(L("Export current plate as G-code")), append_menu_item(m_plater_menu, wxID_ANY, _(L("Export G-code...")), _(L("Export current plate as G-code")),
[this](wxCommandEvent&){ m_plater->export_gcode(); }, "cog_go.png"); [this](wxCommandEvent&) { m_plater->export_gcode(); }, "cog_go.png");
append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as STL...")), _(L("Export current plate as STL")), append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as STL...")), _(L("Export current plate as STL")),
[this](wxCommandEvent&){ m_plater->export_stl(); }, "brick_go.png"); [this](wxCommandEvent&) { m_plater->export_stl(); }, "brick_go.png");
append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as AMF...")), _(L("Export current plate as AMF")), append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as AMF...")), _(L("Export current plate as AMF")),
[this](wxCommandEvent&){ m_plater->export_amf(); }, "brick_go.png"); [this](wxCommandEvent&) { m_plater->export_amf(); }, "brick_go.png");
append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as 3MF...")), _(L("Export current plate as 3MF")), append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as 3MF...")), _(L("Export current plate as 3MF")),
[this](wxCommandEvent&){ m_plater->export_3mf(); }, "brick_go.png"); [this](wxCommandEvent&) { m_plater->export_3mf(); }, "brick_go.png");
} }
// Window menu // Window menu
@ -297,18 +297,18 @@ void MainFrame::init_menubar()
size_t tab_offset = 0; size_t tab_offset = 0;
if (m_plater) { if (m_plater) {
append_menu_item(windowMenu, wxID_ANY, L("Select &Plater Tab\tCtrl+1"), L("Show the plater"), append_menu_item(windowMenu, wxID_ANY, L("Select &Plater Tab\tCtrl+1"), L("Show the plater"),
[this](wxCommandEvent&){ select_tab(0); }, "application_view_tile.png"); [this](wxCommandEvent&) { select_tab(0); }, "application_view_tile.png");
tab_offset += 1; tab_offset += 1;
} }
if (tab_offset > 0) { if (tab_offset > 0) {
windowMenu->AppendSeparator(); windowMenu->AppendSeparator();
} }
append_menu_item(windowMenu, wxID_ANY, L("Select P&rint Settings Tab\tCtrl+2"), L("Show the print settings"), append_menu_item(windowMenu, wxID_ANY, L("Select P&rint Settings Tab\tCtrl+2"), L("Show the print settings"),
[this, tab_offset](wxCommandEvent&){ select_tab(tab_offset + 0); }, "cog.png"); [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog.png");
append_menu_item(windowMenu, wxID_ANY, L("Select &Filament Settings Tab\tCtrl+3"), L("Show the filament settings"), append_menu_item(windowMenu, wxID_ANY, L("Select &Filament Settings Tab\tCtrl+3"), L("Show the filament settings"),
[this, tab_offset](wxCommandEvent&){ select_tab(tab_offset + 1); }, "spool.png"); [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 1); }, "spool.png");
append_menu_item(windowMenu, wxID_ANY, L("Select Print&er Settings Tab\tCtrl+4"), L("Show the printer settings"), append_menu_item(windowMenu, wxID_ANY, L("Select Print&er Settings Tab\tCtrl+4"), L("Show the printer settings"),
[this, tab_offset](wxCommandEvent&){ select_tab(tab_offset + 2); }, "printer_empty.png"); [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer_empty.png");
} }
// View menu // View menu
@ -317,40 +317,40 @@ void MainFrame::init_menubar()
// \xA0 is a non-breaing space. It is entered here to spoil the automatic accelerators, // \xA0 is a non-breaing space. It is entered here to spoil the automatic accelerators,
// as the simple numeric accelerators spoil all numeric data entry. // as the simple numeric accelerators spoil all numeric data entry.
// The camera control accelerators are captured by GLCanvas3D::on_char(). // The camera control accelerators are captured by GLCanvas3D::on_char().
append_menu_item(m_viewMenu, wxID_ANY, _(L("Iso")) + "\t\xA0" + "0", _(L("Iso View")), [this](wxCommandEvent&){ select_view("iso"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Iso")) + "\t\xA0" + "0", _(L("Iso View")), [this](wxCommandEvent&) { select_view("iso"); });
m_viewMenu->AppendSeparator(); m_viewMenu->AppendSeparator();
append_menu_item(m_viewMenu, wxID_ANY, _(L("Top")) + "\t\xA0" + "1", _(L("Top View")), [this](wxCommandEvent&){ select_view("top"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Top")) + "\t\xA0" + "1", _(L("Top View")), [this](wxCommandEvent&) { select_view("top"); });
append_menu_item(m_viewMenu, wxID_ANY, _(L("Bottom")) + "\t\xA0" + "2", _(L("Bottom View")), [this](wxCommandEvent&){ select_view("bottom"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Bottom")) + "\t\xA0" + "2", _(L("Bottom View")), [this](wxCommandEvent&) { select_view("bottom"); });
append_menu_item(m_viewMenu, wxID_ANY, _(L("Front")) + "\t\xA0" + "3", _(L("Front View")), [this](wxCommandEvent&){ select_view("front"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Front")) + "\t\xA0" + "3", _(L("Front View")), [this](wxCommandEvent&) { select_view("front"); });
append_menu_item(m_viewMenu, wxID_ANY, _(L("Rear")) + "\t\xA0" + "4", _(L("Rear View")), [this](wxCommandEvent&){ select_view("rear"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Rear")) + "\t\xA0" + "4", _(L("Rear View")), [this](wxCommandEvent&) { select_view("rear"); });
append_menu_item(m_viewMenu, wxID_ANY, _(L("Left")) + "\t\xA0" + "5", _(L("Left View")), [this](wxCommandEvent&){ select_view("left"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Left")) + "\t\xA0" + "5", _(L("Left View")), [this](wxCommandEvent&) { select_view("left"); });
append_menu_item(m_viewMenu, wxID_ANY, _(L("Right")) + "\t\xA0" + "6", _(L("Right View")), [this](wxCommandEvent&){ select_view("right"); }); append_menu_item(m_viewMenu, wxID_ANY, _(L("Right")) + "\t\xA0" + "6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); });
} }
// Help menu // Help menu
auto helpMenu = new wxMenu(); auto helpMenu = new wxMenu();
{ {
append_menu_item(helpMenu, wxID_ANY, _(L("Prusa 3D Drivers")), _(L("Open the Prusa3D drivers download page in your browser")), append_menu_item(helpMenu, wxID_ANY, _(L("Prusa 3D Drivers")), _(L("Open the Prusa3D drivers download page in your browser")),
[this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://www.prusa3d.com/drivers/"); }); [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://www.prusa3d.com/drivers/"); });
append_menu_item(helpMenu, wxID_ANY, _(L("Prusa Edition Releases")), _(L("Open the Prusa Edition releases page in your browser")), append_menu_item(helpMenu, wxID_ANY, _(L("Prusa Edition Releases")), _(L("Open the Prusa Edition releases page in your browser")),
[this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/releases"); }); [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/releases"); });
//# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{ //# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{
//# wxTheApp->check_version(1); //# wxTheApp->check_version(1);
//# }); //# });
//# $versioncheck->Enable(wxTheApp->have_version_check); //# $versioncheck->Enable(wxTheApp->have_version_check);
append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Website")), _(L("Open the Slic3r website in your browser")), append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Website")), _(L("Open the Slic3r website in your browser")),
[this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://slic3r.org/"); }); [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://slic3r.org/"); });
append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Manual")), _(L("Open the Slic3r manual in your browser")), append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Manual")), _(L("Open the Slic3r manual in your browser")),
[this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://manual.slic3r.org/"); }); [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://manual.slic3r.org/"); });
helpMenu->AppendSeparator(); helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _(L("System Info")), _(L("Show system information")), append_menu_item(helpMenu, wxID_ANY, _(L("System Info")), _(L("Show system information")),
[this](wxCommandEvent&){ wxGetApp().system_info(); }); [this](wxCommandEvent&) { wxGetApp().system_info(); });
append_menu_item(helpMenu, wxID_ANY, _(L("Show &Configuration Folder")), _(L("Show user configuration folder (datadir)")), append_menu_item(helpMenu, wxID_ANY, _(L("Show &Configuration Folder")), _(L("Show user configuration folder (datadir)")),
[this](wxCommandEvent&){ Slic3r::GUI::desktop_open_datadir_folder(); }); [this](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); });
append_menu_item(helpMenu, wxID_ANY, _(L("Report an Issue")), _(L("Report an issue on the Slic3r Prusa Edition")), append_menu_item(helpMenu, wxID_ANY, _(L("Report an Issue")), _(L("Report an issue on the Slic3r Prusa Edition")),
[this](wxCommandEvent&){ wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); }); [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); });
append_menu_item(helpMenu, wxID_ANY, _(L("&About Slic3r")), _(L("Show about dialog")), append_menu_item(helpMenu, wxID_ANY, _(L("&About Slic3r")), _(L("Show about dialog")),
[this](wxCommandEvent&){ Slic3r::GUI::about(); }); [this](wxCommandEvent&) { Slic3r::GUI::about(); });
} }
// menubar // menubar
@ -369,14 +369,16 @@ void MainFrame::init_menubar()
} }
} }
void MainFrame::slice_to_png(){ void MainFrame::slice_to_png()
{
// m_plater->stop_background_process(); // m_plater->stop_background_process();
// m_plater->async_apply_config(); // m_plater->async_apply_config();
m_appController->print_ctl()->slice_to_png(); m_appController->print_ctl()->slice_to_png();
} }
// To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG". // To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG".
void MainFrame::quick_slice(const int qs){ void MainFrame::quick_slice(const int qs)
{
// my $progress_dialog; // my $progress_dialog;
wxString input_file; wxString input_file;
// eval // eval
@ -422,7 +424,7 @@ void MainFrame::quick_slice(const int qs){
// //
// auto sprint = new Slic3r::Print::Simple( // auto sprint = new Slic3r::Print::Simple(
// print_center = > print_center, // print_center = > print_center,
// status_cb = > [](int percent, const wxString& msg){ // status_cb = > [](int percent, const wxString& msg) {
// m_progress_dialog->Update(percent, msg+"…"); // m_progress_dialog->Update(percent, msg+"…");
// }); // });
@ -502,7 +504,7 @@ void MainFrame::quick_slice(const int qs){
// wxTheApp->notify(message); // wxTheApp->notify(message);
wxMessageDialog(this, message, _(L("Slicing Done!")), wxOK | wxICON_INFORMATION).ShowModal(); wxMessageDialog(this, message, _(L("Slicing Done!")), wxOK | wxICON_INFORMATION).ShowModal();
// }; // };
// Slic3r::GUI::catch_error(this, [](){ if (m_progress_dialog) m_progress_dialog->Destroy(); }); // Slic3r::GUI::catch_error(this, []() { if (m_progress_dialog) m_progress_dialog->Destroy(); });
} }
void MainFrame::reslice_now() void MainFrame::reslice_now()
@ -701,7 +703,7 @@ void MainFrame::on_presets_changed(SimpleEvent &event)
// FIXME: The preset type really should be a property of Tab instead // FIXME: The preset type really should be a property of Tab instead
Slic3r::Preset::Type preset_type = tab->type(); Slic3r::Preset::Type preset_type = tab->type();
if (preset_type == Slic3r::Preset::TYPE_INVALID){ if (preset_type == Slic3r::Preset::TYPE_INVALID) {
wxASSERT(false); wxASSERT(false);
return; return;
} }
@ -737,7 +739,7 @@ void MainFrame::on_value_changed(wxCommandEvent& event)
auto opt_key = event.GetString(); auto opt_key = event.GetString();
if (m_plater) { if (m_plater) {
m_plater->on_config_change(*tab->get_config()); // propagate config change events to the plater m_plater->on_config_change(*tab->get_config()); // propagate config change events to the plater
if (opt_key == "extruders_count"){ if (opt_key == "extruders_count") {
auto value = event.GetInt(); auto value = event.GetInt();
m_plater->on_extruders_change(value); m_plater->on_extruders_change(value);
} }

View File

@ -66,13 +66,13 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
} }
// Grab a reference to fields for convenience // Grab a reference to fields for convenience
const t_field& field = m_fields[id]; const t_field& field = m_fields[id];
field->m_on_change = [this](std::string opt_id, boost::any value){ field->m_on_change = [this](std::string opt_id, boost::any value) {
//! This function will be called from Field. //! This function will be called from Field.
//! Call OptionGroup._on_change(...) //! Call OptionGroup._on_change(...)
if (!m_disabled) if (!m_disabled)
this->on_change_OG(opt_id, value); this->on_change_OG(opt_id, value);
}; };
field->m_on_kill_focus = [this](){ field->m_on_kill_focus = [this]() {
//! This function will be called from Field. //! This function will be called from Field.
if (!m_disabled) if (!m_disabled)
this->on_kill_focus(); this->on_kill_focus();
@ -81,11 +81,11 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
//! Label to change background color, when option is modified //! Label to change background color, when option is modified
field->m_Label = label; field->m_Label = label;
field->m_back_to_initial_value = [this](std::string opt_id){ field->m_back_to_initial_value = [this](std::string opt_id) {
if (!m_disabled) if (!m_disabled)
this->back_to_initial_value(opt_id); this->back_to_initial_value(opt_id);
}; };
field->m_back_to_sys_value = [this](std::string opt_id){ field->m_back_to_sys_value = [this](std::string opt_id) {
if (!this->m_disabled) if (!this->m_disabled)
this->back_to_sys_value(opt_id); this->back_to_sys_value(opt_id);
}; };
@ -107,8 +107,8 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
} }
void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) { void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) {
//! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){ //! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)) {
if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){ if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width) {
if (line.sizer != nullptr) { if (line.sizer != nullptr) {
sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
return; return;
@ -313,7 +313,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
// get value // get value
//! auto field_value = get_value(opt_id); //! auto field_value = get_value(opt_id);
if (option.gui_flags.compare("serialized")==0) { if (option.gui_flags.compare("serialized")==0) {
if (opt_index != -1){ if (opt_index != -1) {
// die "Can't set serialized option indexed value" ; // die "Can't set serialized option indexed value" ;
} }
change_opt_value(*m_config, opt_key, value); change_opt_value(*m_config, opt_key, value);
@ -355,7 +355,7 @@ void ConfigOptionsGroup::back_to_sys_value(const std::string& opt_key)
void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key) void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key)
{ {
boost::any value; boost::any value;
if (opt_key == "extruders_count"){ if (opt_key == "extruders_count") {
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter")); auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
value = int(nozzle_diameter->values.size()); value = int(nozzle_diameter->values.size());
} }
@ -376,7 +376,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
on_change_OG(opt_key, get_value(opt_key)); on_change_OG(opt_key, get_value(opt_key));
} }
void ConfigOptionsGroup::reload_config(){ void ConfigOptionsGroup::reload_config() {
for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
auto opt_id = it->first; auto opt_id = it->first;
std::string opt_key = m_opt_map.at(opt_id).first; std::string opt_key = m_opt_map.at(opt_id).first;
@ -420,7 +420,7 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) {
return true; return true;
} }
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize){ boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) {
if (deserialize) { if (deserialize) {
// Want to edit a vector value(currently only multi - strings) in a single edit box. // Want to edit a vector value(currently only multi - strings) in a single edit box.
@ -444,7 +444,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
boost::any ret; boost::any ret;
wxString text_value = wxString(""); wxString text_value = wxString("");
const ConfigOptionDef* opt = config.def()->get(opt_key); const ConfigOptionDef* opt = config.def()->get(opt_key);
switch (opt->type){ switch (opt->type) {
case coFloatOrPercent:{ case coFloatOrPercent:{
const auto &value = *config.option<ConfigOptionFloatOrPercent>(opt_key); const auto &value = *config.option<ConfigOptionFloatOrPercent>(opt_key);
if (value.percent) if (value.percent)
@ -477,13 +477,13 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
ret = static_cast<wxString>(config.opt_string(opt_key)); ret = static_cast<wxString>(config.opt_string(opt_key));
break; break;
case coStrings: case coStrings:
if (opt_key.compare("compatible_printers") == 0){ if (opt_key.compare("compatible_printers") == 0) {
ret = config.option<ConfigOptionStrings>(opt_key)->values; ret = config.option<ConfigOptionStrings>(opt_key)->values;
break; break;
} }
if (config.option<ConfigOptionStrings>(opt_key)->values.empty()) if (config.option<ConfigOptionStrings>(opt_key)->values.empty())
ret = text_value; ret = text_value;
else if (opt->gui_flags.compare("serialized") == 0){ else if (opt->gui_flags.compare("serialized") == 0) {
std::vector<std::string> values = config.option<ConfigOptionStrings>(opt_key)->values; std::vector<std::string> values = config.option<ConfigOptionStrings>(opt_key)->values;
if (!values.empty() && values[0].compare("") != 0) if (!values.empty() && values[0].compare("") != 0)
for (auto el : values) for (auto el : values)
@ -507,19 +507,19 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
break; break;
case coEnum:{ case coEnum:{
if (opt_key.compare("external_fill_pattern") == 0 || if (opt_key.compare("external_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0 ){ opt_key.compare("fill_pattern") == 0 ) {
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value); ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
} }
else if (opt_key.compare("gcode_flavor") == 0 ){ else if (opt_key.compare("gcode_flavor") == 0 ) {
ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value); ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value);
} }
else if (opt_key.compare("support_material_pattern") == 0){ else if (opt_key.compare("support_material_pattern") == 0) {
ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value); ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value);
} }
else if (opt_key.compare("seam_position") == 0){ else if (opt_key.compare("seam_position") == 0) {
ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value); ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
} }
else if (opt_key.compare("host_type") == 0){ else if (opt_key.compare("host_type") == 0) {
ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value); ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
} }
} }
@ -537,13 +537,14 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
return ret; return ret;
} }
Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index){ Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index)
{
Field* field = get_field(opt_key); Field* field = get_field(opt_key);
if (field != nullptr) if (field != nullptr)
return field; return field;
std::string opt_id = ""; std::string opt_id = "";
for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second){ if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second) {
opt_id = it->first; opt_id = it->first;
break; break;
} }

View File

@ -156,7 +156,7 @@ public:
column_t extra_clmn = nullptr) : column_t extra_clmn = nullptr) :
m_parent(_parent), title(title), m_parent(_parent), title(title),
m_show_modified_btns(is_tab_opt), m_show_modified_btns(is_tab_opt),
staticbox(title!=""), extra_column(extra_clmn){ staticbox(title!=""), extra_column(extra_clmn) {
if (staticbox) { if (staticbox) {
stb = new wxStaticBox(_parent, wxID_ANY, title); stb = new wxStaticBox(_parent, wxID_ANY, title);
stb->SetFont(wxGetApp().bold_font()); stb->SetFont(wxGetApp().bold_font());
@ -177,7 +177,7 @@ public:
#endif /* __WXGTK__ */ #endif /* __WXGTK__ */
} }
wxGridSizer* get_grid_sizer(){ return m_grid_sizer; } wxGridSizer* get_grid_sizer() { return m_grid_sizer; }
protected: protected:
std::map<t_config_option_key, Option> m_options; std::map<t_config_option_key, Option> m_options;
@ -208,10 +208,10 @@ protected:
const t_field& build_field(const Option& opt, wxStaticText* label = nullptr); const t_field& build_field(const Option& opt, wxStaticText* label = nullptr);
void add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field); void add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field);
virtual void on_kill_focus (){}; virtual void on_kill_focus () {};
virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value); virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value);
virtual void back_to_initial_value(const std::string& opt_key){} virtual void back_to_initial_value(const std::string& opt_key) {}
virtual void back_to_sys_value(const std::string& opt_key){} virtual void back_to_sys_value(const std::string& opt_key) {}
}; };
class ConfigOptionsGroup: public OptionsGroup { class ConfigOptionsGroup: public OptionsGroup {
@ -225,7 +225,7 @@ public:
bool m_full_labels {0}; bool m_full_labels {0};
t_opt_map m_opt_map; t_opt_map m_opt_map;
void set_config(DynamicPrintConfig* config){ m_config = config; } void set_config(DynamicPrintConfig* config) { m_config = config; }
Option get_option(const std::string& opt_key, int opt_index = -1); Option get_option(const std::string& opt_key, int opt_index = -1);
Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{ Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{
Option option = get_option(title, idx); Option option = get_option(title, idx);
@ -258,8 +258,8 @@ public:
class ogStaticText :public wxStaticText{ class ogStaticText :public wxStaticText{
public: public:
ogStaticText() {} ogStaticText() {}
ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize){} ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize) {}
~ogStaticText(){} ~ogStaticText() {}
void SetText(const wxString& value, bool wrap = true); void SetText(const wxString& value, bool wrap = true);
}; };

View File

@ -132,18 +132,27 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
Add(grid_sizer, 0, wxEXPAND); Add(grid_sizer, 0, wxEXPAND);
} }
enum SlisedInfoIdx
{
siFilament_m,
siFilament_mm3,
siFilament_g,
siCost,
siTimeNormal,
siTimeSilent,
siWTNumbetOfToolchanges,
siCount
};
class SlicedInfo : public wxStaticBoxSizer class SlicedInfo : public wxStaticBoxSizer
{ {
public: public:
SlicedInfo(wxWindow *parent); SlicedInfo(wxWindow *parent);
void SetTextAndShow(SlisedInfoIdx idx, const wxString& text);
private: private:
wxStaticText *info_filament_m; std::vector<std::pair<wxStaticText*, wxStaticText*>> info_vec;
wxStaticText *info_filament_mm3;
wxStaticText *info_filament_g;
wxStaticText *info_cost;
wxStaticText *info_time_normal;
wxStaticText *info_time_silent;
}; };
SlicedInfo::SlicedInfo(wxWindow *parent) : SlicedInfo::SlicedInfo(wxWindow *parent) :
@ -155,23 +164,37 @@ SlicedInfo::SlicedInfo(wxWindow *parent) :
grid_sizer->SetFlexibleDirection(wxHORIZONTAL); grid_sizer->SetFlexibleDirection(wxHORIZONTAL);
grid_sizer->AddGrowableCol(1, 1); grid_sizer->AddGrowableCol(1, 1);
auto init_info_label = [parent, grid_sizer](wxStaticText *&info_label, wxString text_label) { info_vec.reserve(siCount);
auto init_info_label = [this, parent, grid_sizer](wxString text_label) {
auto *text = new wxStaticText(parent, wxID_ANY, text_label); auto *text = new wxStaticText(parent, wxID_ANY, text_label);
text->SetFont(wxGetApp().small_font()); text->SetFont(wxGetApp().small_font());
info_label = new wxStaticText(parent, wxID_ANY, "N/A"); auto info_label = new wxStaticText(parent, wxID_ANY, "N/A");
info_label->SetFont(wxGetApp().small_font()); info_label->SetFont(wxGetApp().small_font());
grid_sizer->Add(text, 0); grid_sizer->Add(text, 0);
grid_sizer->Add(info_label, 0); grid_sizer->Add(info_label, 0);
info_vec.push_back(std::pair<wxStaticText*, wxStaticText*>(text, info_label));
}; };
init_info_label(info_filament_m, _(L("Used Filament (m)"))); init_info_label(_(L("Used Filament (m)")));
init_info_label(info_filament_mm3, _(L("Used Filament (mm³)"))); init_info_label(_(L("Used Filament (mm³)")));
init_info_label(info_filament_g, _(L("Used Filament (g)"))); init_info_label(_(L("Used Filament (g)")));
init_info_label(info_cost, _(L("Cost"))); init_info_label(_(L("Cost")));
init_info_label(info_time_normal, _(L("Estimated printing time (normal mode)"))); init_info_label(_(L("Estimated printing time (normal mode)")));
init_info_label(info_time_silent, _(L("Estimated printing time (silent mode)"))); init_info_label(_(L("Estimated printing time (silent mode)")));
init_info_label(_(L("Number of tool changes")));
Add(grid_sizer, 0, wxEXPAND); Add(grid_sizer, 0, wxEXPAND);
this->Show(false);
}
void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text)
{
const bool show = text != "N/A";
if (show)
info_vec[idx].second->SetLabelText(text);
info_vec[idx].first->Show(show);
info_vec[idx].second->Show(show);
} }
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) : PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
@ -256,13 +279,13 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
m_og->set_config(config); m_og->set_config(config);
m_og->label_width = label_width; m_og->label_width = label_width;
m_og->m_on_change = [config, this](t_config_option_key opt_key, boost::any value){ m_og->m_on_change = [config, this](t_config_option_key opt_key, boost::any value) {
TabPrint* tab_print = nullptr; TabPrint* tab_print = nullptr;
for (size_t i = 0; i < wxGetApp().tab_panel()->GetPageCount(); ++i) { for (size_t i = 0; i < wxGetApp().tab_panel()->GetPageCount(); ++i) {
Tab *tab = dynamic_cast<Tab*>(wxGetApp().tab_panel()->GetPage(i)); Tab *tab = dynamic_cast<Tab*>(wxGetApp().tab_panel()->GetPage(i));
if (!tab) if (!tab)
continue; continue;
if (tab->name() == "print"){ if (tab->name() == "print") {
tab_print = static_cast<TabPrint*>(tab); tab_print = static_cast<TabPrint*>(tab);
break; break;
} }
@ -270,14 +293,14 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
if (tab_print == nullptr) if (tab_print == nullptr)
return; return;
if (opt_key == "fill_density"){ if (opt_key == "fill_density") {
value = m_og->get_config_value(*config, opt_key); value = m_og->get_config_value(*config, opt_key);
tab_print->set_value(opt_key, value); tab_print->set_value(opt_key, value);
tab_print->update(); tab_print->update();
} }
else{ else{
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
if (opt_key == "brim"){ if (opt_key == "brim") {
double new_val; double new_val;
double brim_width = config->opt_float("brim_width"); double brim_width = config->opt_float("brim_width");
if (boost::any_cast<bool>(value) == true) if (boost::any_cast<bool>(value) == true)
@ -344,7 +367,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
Line line = { "", "" }; Line line = { "", "" };
line.widget = [config, this](wxWindow* parent){ line.widget = [config, this](wxWindow* parent) {
m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_wiping_dialog_button); sizer->Add(m_wiping_dialog_button);
@ -642,7 +665,43 @@ void Sidebar::show_info_sizers(const bool show)
{ {
p->object_info->Show(show); p->object_info->Show(show);
p->object_info->manifold_warning_icon->Show(show && p->show_manifold_warning_icon); // where is g_show_manifold_warning_icon updating? #ys_FIXME p->object_info->manifold_warning_icon->Show(show && p->show_manifold_warning_icon); // where is g_show_manifold_warning_icon updating? #ys_FIXME
p->sliced_info->Show(show && p->show_print_info); // where is g_show_print_info updating? #ys_FIXME // p->sliced_info->Show(show && p->show_print_info);
}
void Sidebar::show_sliced_info_sizer(const bool show)
{
p->plater->Freeze();
// p->show_print_info = show;
p->sliced_info->Show(show);
if (show) {
const PrintStatistics& ps = p->plater->print().print_statistics();
const bool is_wipe_tower = ps.total_wipe_tower_filament > 0;
wxString info_text = is_wipe_tower ?
wxString::Format("%.2f (%.2f %s + %.2f %s)", ps.total_used_filament / 1000,
(ps.total_used_filament - ps.total_wipe_tower_filament) / 1000, _(L("objects")),
ps.total_wipe_tower_filament / 1000, _(L("wipe tower"))) :
wxString::Format("%.2f", ps.total_used_filament / 1000);
p->sliced_info->SetTextAndShow(siFilament_m, info_text);
p->sliced_info->SetTextAndShow(siFilament_mm3, wxString::Format("%.2f", ps.total_extruded_volume));
p->sliced_info->SetTextAndShow(siFilament_g, wxString::Format("%.2f", ps.total_weight));
info_text = is_wipe_tower ?
wxString::Format("%.2f (%.2f %s + %.2f %s)", ps.total_cost,
(ps.total_cost - ps.total_wipe_tower_cost), _(L("objects")),
ps.total_wipe_tower_cost, _(L("wipe tower"))) :
wxString::Format("%.2f", ps.total_cost);
p->sliced_info->SetTextAndShow(siCost, info_text);
p->sliced_info->SetTextAndShow(siTimeNormal, ps.estimated_normal_print_time);
p->sliced_info->SetTextAndShow(siTimeSilent, ps.estimated_silent_print_time);
// if there is a wipe tower, insert number of toolchanges info into the array:
p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->print().wipe_tower_data().number_of_toolchanges) : "N/A");
}
p->scrolled->Layout();
p->plater->Layout();
p->plater->Thaw();
} }
void Sidebar::show_buttons(const bool show) void Sidebar::show_buttons(const bool show)
@ -902,7 +961,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) :
background_process.set_sliced_event(EVT_SLICING_COMPLETED); background_process.set_sliced_event(EVT_SLICING_COMPLETED);
background_process.set_finished_event(EVT_PROCESS_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED);
// Register progress callback from the Print class to the Platter. // Register progress callback from the Print class to the Platter.
print.set_status_callback([this](int percent, const std::string &message){ print.set_status_callback([this](int percent, const std::string &message) {
wxCommandEvent event(EVT_PROGRESS_BAR); wxCommandEvent event(EVT_PROGRESS_BAR);
event.SetInt(percent); event.SetInt(percent);
event.SetString(message); event.SetString(message);
@ -932,7 +991,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) :
_3DScene::enable_force_zoom_to_bed(canvas3D, true); _3DScene::enable_force_zoom_to_bed(canvas3D, true);
this->background_process_timer.SetOwner(this->q, 0); this->background_process_timer.SetOwner(this->q, 0);
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt){ this->async_apply_config(); }); this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->async_apply_config(); });
auto *bed_shape = config->opt<ConfigOptionPoints>("bed_shape"); auto *bed_shape = config->opt<ConfigOptionPoints>("bed_shape");
_3DScene::set_bed_shape(canvas3D, bed_shape->values); _3DScene::set_bed_shape(canvas3D, bed_shape->values);
@ -1160,6 +1219,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path> &input_
if (type_3mf) { if (type_3mf) {
for (ModelObject* model_object : model.objects) { for (ModelObject* model_object : model.objects) {
model_object->center_around_origin(); model_object->center_around_origin();
model_object->ensure_on_bed();
} }
} }
@ -1244,6 +1304,8 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
} }
} }
object->ensure_on_bed();
// print.auto_assign_extruders(object); // print.auto_assign_extruders(object);
// print.add_model_object(object); // print.add_model_object(object);
} }
@ -1627,23 +1689,30 @@ void Plater::priv::split_object()
ModelObjectPtrs new_objects; ModelObjectPtrs new_objects;
current_model_object->split(&new_objects); current_model_object->split(&new_objects);
if (new_objects.size() == 1) if (new_objects.size() == 1)
{
Slic3r::GUI::warning_catcher(q, _(L("The selected object couldn't be split because it contains only one part."))); Slic3r::GUI::warning_catcher(q, _(L("The selected object couldn't be split because it contains only one part.")));
}
else else
{ {
unsigned int counter = 1; unsigned int counter = 1;
for (ModelObject* m : new_objects) for (ModelObject* m : new_objects)
{ {
m->name = current_model_object->name + "_" + std::to_string(counter++); m->name = current_model_object->name + "_" + std::to_string(counter++);
m->center_around_origin(); for (ModelInstance* i : current_model_object->instances)
{
m->add_instance(*i);
}
} }
remove(obj_idx); remove(obj_idx);
// load all model objects at once, otherwise the plate would be rearranged after each one // load all model objects at once, otherwise the plate would be rearranged after each one
// causing original positions not to be kept // causing original positions not to be kept
load_model_objects(new_objects); std::vector<size_t> idxs = load_model_objects(new_objects);
// select newly added objects
for (size_t idx : idxs)
{
get_selection().add_object((unsigned int)idx, false);
}
} }
#endif // ENABLE_EXTENDED_SELECTION #endif // ENABLE_EXTENDED_SELECTION
} }
@ -1677,7 +1746,7 @@ void Plater::priv::async_apply_config()
if (invalidated == Print::APPLY_STATUS_INVALIDATED) { if (invalidated == Print::APPLY_STATUS_INVALIDATED) {
// Some previously calculated data on the Print was invalidated. // Some previously calculated data on the Print was invalidated.
// Hide the slicing results, as the current slicing status is no more valid. // Hide the slicing results, as the current slicing status is no more valid.
this->sidebar->show_info_sizers(false); this->sidebar->show_sliced_info_sizer(false);
// Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared.
// Otherwise they will be just refreshed. // Otherwise they will be just refreshed.
this->gcode_preview_data.reset(); this->gcode_preview_data.reset();
@ -1694,7 +1763,7 @@ void Plater::priv::async_apply_config()
} }
if (invalidated != Print::APPLY_STATUS_UNCHANGED && this->get_config("background_processing") == "1" && if (invalidated != Print::APPLY_STATUS_UNCHANGED && this->get_config("background_processing") == "1" &&
this->print.num_object_instances() > 0 && this->background_process.start()) this->print.num_object_instances() > 0 && this->background_process.start())
this->statusbar()->set_cancel_callback([this](){ this->statusbar()->set_cancel_callback([this]() {
this->statusbar()->set_status_text(L("Cancelling")); this->statusbar()->set_status_text(L("Cancelling"));
this->background_process.stop(); this->background_process.stop();
}); });
@ -1857,7 +1926,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
if (canceled) if (canceled)
this->statusbar()->set_status_text(L("Cancelled")); this->statusbar()->set_status_text(L("Cancelled"));
this->sidebar->show_info_sizers(success); this->sidebar->show_sliced_info_sizer(success);
// this updates buttons status // this updates buttons status
//$self->object_list_changed; //$self->object_list_changed;
@ -2030,13 +2099,13 @@ void Plater::priv::on_update_geometry(Vec3dsEvent<2>&)
bool Plater::priv::init_object_menu() bool Plater::priv::init_object_menu()
{ {
wxMenuItem* item_delete = append_menu_item(&object_menu, wxID_ANY, _(L("Delete\tDel")), _(L("Remove the selected object")), wxMenuItem* item_delete = append_menu_item(&object_menu, wxID_ANY, _(L("Delete\tDel")), _(L("Remove the selected object")),
[this](wxCommandEvent&){ q->remove_selected(); }, "brick_delete.png"); [this](wxCommandEvent&) { q->remove_selected(); }, "brick_delete.png");
wxMenuItem* item_increase = append_menu_item(&object_menu, wxID_ANY, _(L("Increase copies\t+")), _(L("Place one more copy of the selected object")), wxMenuItem* item_increase = append_menu_item(&object_menu, wxID_ANY, _(L("Increase copies\t+")), _(L("Place one more copy of the selected object")),
[this](wxCommandEvent&){ q->increase_instances(); }, "add.png"); [this](wxCommandEvent&) { q->increase_instances(); }, "add.png");
wxMenuItem* item_decrease = append_menu_item(&object_menu, wxID_ANY, _(L("Decrease copies\t-")), _(L("Remove one copy of the selected object")), wxMenuItem* item_decrease = append_menu_item(&object_menu, wxID_ANY, _(L("Decrease copies\t-")), _(L("Remove one copy of the selected object")),
[this](wxCommandEvent&){ q->decrease_instances(); }, "delete.png"); [this](wxCommandEvent&) { q->decrease_instances(); }, "delete.png");
wxMenuItem* item_set_number_of_copies = append_menu_item(&object_menu, wxID_ANY, _(L("Set number of copies…")), _(L("Change the number of copies of the selected object")), wxMenuItem* item_set_number_of_copies = append_menu_item(&object_menu, wxID_ANY, _(L("Set number of copies…")), _(L("Change the number of copies of the selected object")),
[this](wxCommandEvent&){ q->set_number_of_copies(); }, "textfield.png"); [this](wxCommandEvent&) { q->set_number_of_copies(); }, "textfield.png");
object_menu.AppendSeparator(); object_menu.AppendSeparator();
@ -2046,11 +2115,11 @@ bool Plater::priv::init_object_menu()
return false; return false;
append_menu_item(mirror_menu, wxID_ANY, _(L("Along X axis")), _(L("Mirror the selected object along the X axis")), append_menu_item(mirror_menu, wxID_ANY, _(L("Along X axis")), _(L("Mirror the selected object along the X axis")),
[this](wxCommandEvent&){ mirror(X); }, "bullet_red.png", &object_menu); [this](wxCommandEvent&) { mirror(X); }, "bullet_red.png", &object_menu);
append_menu_item(mirror_menu, wxID_ANY, _(L("Along Y axis")), _(L("Mirror the selected object along the Y axis")), append_menu_item(mirror_menu, wxID_ANY, _(L("Along Y axis")), _(L("Mirror the selected object along the Y axis")),
[this](wxCommandEvent&){ mirror(Y); }, "bullet_green.png", &object_menu); [this](wxCommandEvent&) { mirror(Y); }, "bullet_green.png", &object_menu);
append_menu_item(mirror_menu, wxID_ANY, _(L("Along Z axis")), _(L("Mirror the selected object along the Z axis")), append_menu_item(mirror_menu, wxID_ANY, _(L("Along Z axis")), _(L("Mirror the selected object along the Z axis")),
[this](wxCommandEvent&){ mirror(Z); }, "bullet_blue.png", &object_menu); [this](wxCommandEvent&) { mirror(Z); }, "bullet_blue.png", &object_menu);
wxMenuItem* item_mirror = append_submenu(&object_menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object"))); wxMenuItem* item_mirror = append_submenu(&object_menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object")));
#endif // ENABLE_MIRROR #endif // ENABLE_MIRROR
@ -2060,9 +2129,9 @@ bool Plater::priv::init_object_menu()
return false; return false;
wxMenuItem* item_split_objects = append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")), wxMenuItem* item_split_objects = append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")),
[this](wxCommandEvent&){ split_object(); }, "shape_ungroup.png", &object_menu); [this](wxCommandEvent&) { split_object(); }, "shape_ungroup.png", &object_menu);
wxMenuItem* item_split_volumes = append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")), wxMenuItem* item_split_volumes = append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")),
[this](wxCommandEvent&){ split_volume(); }, "shape_ungroup.png", &object_menu); [this](wxCommandEvent&) { split_volume(); }, "shape_ungroup.png", &object_menu);
wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "shape_ungroup.png"); wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "shape_ungroup.png");
@ -2455,7 +2524,7 @@ void Plater::reslice()
// this->p->stop_background_process(); // this->p->stop_background_process();
// Rather perform one additional unnecessary update of the print object instead of skipping a pending async update. // Rather perform one additional unnecessary update of the print object instead of skipping a pending async update.
this->p->async_apply_config(); this->p->async_apply_config();
this->p->statusbar()->set_cancel_callback([this](){ this->p->statusbar()->set_cancel_callback([this]() {
this->p->statusbar()->set_status_text(L("Cancelling")); this->p->statusbar()->set_status_text(L("Cancelling"));
this->p->background_process.stop(); this->p->background_process.stop();
}); });
@ -2548,7 +2617,7 @@ wxGLCanvas* Plater::canvas3D()
return p->canvas3D; return p->canvas3D;
} }
void Plater::changed_object_settings(int obj_idx) void Plater::changed_object(int obj_idx)
{ {
if (obj_idx < 0) if (obj_idx < 0)
return; return;
@ -2561,6 +2630,8 @@ void Plater::changed_object_settings(int obj_idx)
// recenter and re - align to Z = 0 // recenter and re - align to Z = 0
auto model_object = p->model.objects[obj_idx]; auto model_object = p->model.objects[obj_idx];
model_object->center_around_origin(); model_object->center_around_origin();
model_object->ensure_on_bed();
_3DScene::reload_scene(p->canvas3D, false);
} }
// update print // update print
@ -2571,7 +2642,6 @@ void Plater::changed_object_settings(int obj_idx)
auto selections = p->collect_selections(); auto selections = p->collect_selections();
_3DScene::set_objects_selections(p->canvas3D, selections); _3DScene::set_objects_selections(p->canvas3D, selections);
#endif // !ENABLE_EXTENDED_SELECTION #endif // !ENABLE_EXTENDED_SELECTION
_3DScene::reload_scene(p->canvas3D, false);
#if !ENABLE_MODIFIED_CAMERA_TARGET #if !ENABLE_MODIFIED_CAMERA_TARGET
_3DScene::zoom_to_volumes(p->canvas3D); _3DScene::zoom_to_volumes(p->canvas3D);
#endif // !ENABLE_MODIFIED_CAMERA_TARGET #endif // !ENABLE_MODIFIED_CAMERA_TARGET

View File

@ -78,6 +78,7 @@ public:
wxButton* get_wiping_dialog_button(); wxButton* get_wiping_dialog_button();
void update_objects_list_extruder_column(int extruders_count); void update_objects_list_extruder_column(int extruders_count);
void show_info_sizers(const bool show); void show_info_sizers(const bool show);
void show_sliced_info_sizer(const bool show);
void show_buttons(const bool show); void show_buttons(const bool show);
void show_button(ButtonAction but_action, bool show); void show_button(ButtonAction but_action, bool show);
void enable_buttons(bool enable); void enable_buttons(bool enable);
@ -122,7 +123,7 @@ public:
void export_amf(); void export_amf();
void export_3mf(); void export_3mf();
void reslice(); void reslice();
void changed_object_settings(int obj_idx); void changed_object(int obj_idx);
void send_gcode(); void send_gcode();
void on_extruders_change(int extruders_count); void on_extruders_change(int extruders_count);

View File

@ -17,7 +17,7 @@ class PreferencesDialog : public wxDialog
std::shared_ptr<ConfigOptionsGroup> m_optgroup; std::shared_ptr<ConfigOptionsGroup> m_optgroup;
public: public:
PreferencesDialog(wxWindow* parent); PreferencesDialog(wxWindow* parent);
~PreferencesDialog(){ } ~PreferencesDialog() {}
void build(); void build();
void accept(); void accept();

View File

@ -795,7 +795,7 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
bmp = m_bitmap_cache->insert(bitmap_key, bmps); bmp = m_bitmap_cache->insert(bitmap_key, bmps);
} }
if (preset.is_default || preset.is_system){ if (preset.is_default || preset.is_system) {
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (i == m_idx_selected) if (i == m_idx_selected)
@ -855,7 +855,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati
bmp = m_bitmap_cache->insert(bitmap_key, bmps); bmp = m_bitmap_cache->insert(bitmap_key, bmps);
} }
if (preset.is_default || preset.is_system){ if (preset.is_default || preset.is_system) {
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (i == m_idx_selected) if (i == m_idx_selected)

View File

@ -1183,7 +1183,7 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati
prefered_print_profile.empty() ? prefered_print_profile.empty() ?
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible, this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; }); [&prefered_print_profile](const std::string& profile_name) { return profile_name == prefered_print_profile; });
prefered_filament_profiles.empty() ? prefered_filament_profiles.empty() ?
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible, this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
@ -1203,7 +1203,7 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati
const std::string &preferred = (idx < prefered_filament_profiles.size()) ? const std::string &preferred = (idx < prefered_filament_profiles.size()) ?
prefered_filament_profiles[idx] : prefered_filament_profiles.front(); prefered_filament_profiles[idx] : prefered_filament_profiles.front();
filament_name = this->filaments.first_compatible( filament_name = this->filaments.first_compatible(
[&preferred](const std::string& profile_name){ return profile_name == preferred; }).name; [&preferred](const std::string& profile_name) { return profile_name == preferred; }).name;
} }
} }
} }
@ -1215,7 +1215,7 @@ void PresetBundle::update_compatible_with_printer(bool select_other_if_incompati
prefered_sla_material_profile.empty() ? prefered_sla_material_profile.empty() ?
this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible) : this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible, this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_sla_material_profile](const std::string& profile_name){ return profile_name == prefered_sla_material_profile; }); [&prefered_sla_material_profile](const std::string& profile_name){ return profile_name == prefered_sla_material_profile; });
} }
} }
} }
@ -1364,7 +1364,7 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
bitmap = m_bitmapCache->insert(bitmap_key, bmps); bitmap = m_bitmapCache->insert(bitmap_key, bmps);
} }
if (preset.is_default || preset.is_system){ if (preset.is_default || preset.is_system) {
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
(bitmap == 0) ? wxNullBitmap : *bitmap); (bitmap == 0) ? wxNullBitmap : *bitmap);
if (selected) if (selected)

View File

@ -125,16 +125,16 @@ void Tab::create_preset_tab()
set_tooltips_text(); set_tooltips_text();
m_undo_btn->SetBitmap(m_bmp_white_bullet); m_undo_btn->SetBitmap(m_bmp_white_bullet);
m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(); })); m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); }));
m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet); m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet);
m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(true); })); m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); }));
m_question_btn->SetBitmap(m_bmp_question); m_question_btn->SetBitmap(m_bmp_question);
m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent)
{ {
auto dlg = new ButtonsDescription(this, &m_icon_descriptions); auto dlg = new ButtonsDescription(this, &m_icon_descriptions);
if (dlg->ShowModal() == wxID_OK){ if (dlg->ShowModal() == wxID_OK) {
// Colors for ui "decoration" // Colors for ui "decoration"
for (Tab *tab : wxGetApp().tabs_list){ for (Tab *tab : wxGetApp().tabs_list) {
tab->m_sys_label_clr = wxGetApp().get_label_clr_sys(); tab->m_sys_label_clr = wxGetApp().get_label_clr_sys();
tab->m_modified_label_clr = wxGetApp().get_label_clr_modified(); tab->m_modified_label_clr = wxGetApp().get_label_clr_modified();
tab->update_labels_colour(); tab->update_labels_colour();
@ -185,7 +185,7 @@ void Tab::create_preset_tab()
m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this); m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this);
m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this); m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e){ m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) {
//! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox,
//! but the OSX version derived from wxOwnerDrawnCombo, instead of: //! but the OSX version derived from wxOwnerDrawnCombo, instead of:
//! select_preset(m_presets_choice->GetStringSelection().ToStdString()); //! select_preset(m_presets_choice->GetStringSelection().ToStdString());
@ -193,11 +193,11 @@ void Tab::create_preset_tab()
int selected_item = m_presets_choice->GetSelection(); int selected_item = m_presets_choice->GetSelection();
if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty())
return; return;
if (selected_item >= 0){ if (selected_item >= 0) {
std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
if (selected_string.find("-------") == 0 if (selected_string.find("-------") == 0
/*selected_string == "------- System presets -------" || /*selected_string == "------- System presets -------" ||
selected_string == "------- User presets -------"*/){ selected_string == "------- User presets -------"*/) {
m_presets_choice->SetSelection(m_selected_preset_item); m_presets_choice->SetSelection(m_selected_preset_item);
return; return;
} }
@ -206,9 +206,9 @@ void Tab::create_preset_tab()
} }
})); }));
m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e){ save_preset(); })); m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); }));
m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e){ delete_preset(); })); m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); }));
m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e){ m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) {
toggle_show_hide_incompatible(); toggle_show_hide_incompatible();
})); }));
@ -281,7 +281,7 @@ void Tab::update_labels_colour()
const wxColour *color = &m_sys_label_clr; const wxColour *color = &m_sys_label_clr;
// value isn't equal to system value // value isn't equal to system value
if ((opt.second & osSystemValue) == 0){ if ((opt.second & osSystemValue) == 0) {
// value is equal to last saved // value is equal to last saved
if ((opt.second & osInitValue) != 0) if ((opt.second & osInitValue) != 0)
color = &m_default_text_clr; color = &m_default_text_clr;
@ -304,7 +304,7 @@ void Tab::update_labels_colour()
Thaw(); Thaw();
auto cur_item = m_treectrl->GetFirstVisibleItem(); auto cur_item = m_treectrl->GetFirstVisibleItem();
while (cur_item){ while (cur_item) {
auto title = m_treectrl->GetItemText(cur_item); auto title = m_treectrl->GetItemText(cur_item);
for (auto page : m_pages) for (auto page : m_pages)
{ {
@ -331,7 +331,7 @@ void Tab::update_changed_ui()
const bool deep_compare = (m_name == "printer" || m_name == "sla_material"); const bool deep_compare = (m_name == "printer" || m_name == "sla_material");
auto dirty_options = m_presets->current_dirty_options(deep_compare); auto dirty_options = m_presets->current_dirty_options(deep_compare);
auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare); auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare);
if (name() == "printer"){ if (name() == "printer") {
TabPrinter* tab = static_cast<TabPrinter*>(this); TabPrinter* tab = static_cast<TabPrinter*>(this);
if (tab->m_initial_extruders_count != tab->m_extruders_count) if (tab->m_initial_extruders_count != tab->m_extruders_count)
dirty_options.emplace_back("extruders_count"); dirty_options.emplace_back("extruders_count");
@ -360,7 +360,7 @@ void Tab::update_changed_ui()
const wxString *tt = &m_tt_value_revert; const wxString *tt = &m_tt_value_revert;
// value isn't equal to system value // value isn't equal to system value
if ((opt.second & osSystemValue) == 0){ if ((opt.second & osSystemValue) == 0) {
is_nonsys_value = true; is_nonsys_value = true;
sys_icon = m_bmp_non_system; sys_icon = m_bmp_non_system;
sys_tt = m_tt_non_system; sys_tt = m_tt_non_system;
@ -426,7 +426,7 @@ void TabPrinter::init_options_list()
for (const auto opt_key : m_config->keys()) for (const auto opt_key : m_config->keys())
{ {
if (opt_key == "bed_shape"){ if (opt_key == "bed_shape") {
m_options_list.emplace(opt_key, m_opt_status_value); m_options_list.emplace(opt_key, m_opt_status_value);
continue; continue;
} }
@ -451,7 +451,7 @@ void TabSLAMaterial::init_options_list()
for (const auto opt_key : m_config->keys()) for (const auto opt_key : m_config->keys())
{ {
if (opt_key == "compatible_printers"){ if (opt_key == "compatible_printers") {
m_options_list.emplace(opt_key, m_opt_status_value); m_options_list.emplace(opt_key, m_opt_status_value);
continue; continue;
} }
@ -481,7 +481,7 @@ void Tab::update_changed_tree_ui()
if (!cur_item || !m_treectrl->IsVisible(cur_item)) if (!cur_item || !m_treectrl->IsVisible(cur_item))
return; return;
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
while (cur_item){ while (cur_item) {
auto title = m_treectrl->GetItemText(cur_item); auto title = m_treectrl->GetItemText(cur_item);
for (auto page : m_pages) for (auto page : m_pages)
{ {
@ -489,13 +489,13 @@ void Tab::update_changed_tree_ui()
continue; continue;
bool sys_page = true; bool sys_page = true;
bool modified_page = false; bool modified_page = false;
if (title == _("General")){ if (title == _("General")) {
std::initializer_list<const char*> optional_keys{ "extruders_count", "bed_shape" }; std::initializer_list<const char*> optional_keys{ "extruders_count", "bed_shape" };
for (auto &opt_key : optional_keys) { for (auto &opt_key : optional_keys) {
get_sys_and_mod_flags(opt_key, sys_page, modified_page); get_sys_and_mod_flags(opt_key, sys_page, modified_page);
} }
} }
if (title == _("Dependencies")){ if (title == _("Dependencies")) {
if (name() != "printer") if (name() != "printer")
get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
else { else {
@ -523,7 +523,7 @@ void Tab::update_changed_tree_ui()
page->m_is_nonsys_values = !sys_page; page->m_is_nonsys_values = !sys_page;
page->m_is_modified_values = modified_page; page->m_is_modified_values = modified_page;
if (selection == title){ if (selection == title) {
m_is_nonsys_values = page->m_is_nonsys_values; m_is_nonsys_values = page->m_is_nonsys_values;
m_is_modified_values = page->m_is_modified_values; m_is_modified_values = page->m_is_modified_values;
} }
@ -561,20 +561,20 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
for (auto page : m_pages) for (auto page : m_pages)
if (page->title() == selection) { if (page->title() == selection) {
for (auto group : page->m_optgroups){ for (auto group : page->m_optgroups) {
if (group->title == _("Capabilities")){ if (group->title == _("Capabilities")) {
if ((m_options_list["extruders_count"] & os) == 0) if ((m_options_list["extruders_count"] & os) == 0)
to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count"); to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count");
} }
if (group->title == _("Size and coordinates")){ if (group->title == _("Size and coordinates")) {
if ((m_options_list["bed_shape"] & os) == 0){ if ((m_options_list["bed_shape"] & os) == 0) {
to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape"); to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape");
load_key_value("bed_shape", true/*some value*/, true); load_key_value("bed_shape", true/*some value*/, true);
} }
} }
if (group->title == _("Profile dependencies") && name() != "printer"){ if (group->title == _("Profile dependencies") && name() != "printer") {
if ((m_options_list["compatible_printers"] & os) == 0){ if ((m_options_list["compatible_printers"] & os) == 0) {
to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers"); to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers");
load_key_value("compatible_printers", true/*some value*/, true); load_key_value("compatible_printers", true/*some value*/, true);
@ -598,7 +598,8 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
// Update the combo box label of the selected preset based on its "dirty" state, // Update the combo box label of the selected preset based on its "dirty" state,
// comparing the selected preset config with $self->{config}. // comparing the selected preset config with $self->{config}.
void Tab::update_dirty(){ void Tab::update_dirty()
{
m_presets->update_dirty_ui(m_presets_choice); m_presets->update_dirty_ui(m_presets_choice);
on_presets_changed(); on_presets_changed();
update_changed_ui(); update_changed_ui();
@ -657,7 +658,7 @@ void Tab::update_visibility(ConfigOptionMode mode)
Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const
{ {
Field* field = nullptr; Field* field = nullptr;
for (auto page : m_pages){ for (auto page : m_pages) {
field = page->get_field(opt_key, opt_index); field = page->get_field(opt_key, opt_index);
if (field != nullptr) if (field != nullptr)
return field; return field;
@ -668,7 +669,7 @@ Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/
// Set a key/value pair on this page. Return true if the value has been modified. // Set a key/value pair on this page. Return true if the value has been modified.
// Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer // Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer
// after a preset is loaded. // after a preset is loaded.
bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value){ bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value) {
bool changed = false; bool changed = false;
for(auto page: m_pages) { for(auto page: m_pages) {
if (page->set_value(opt_key, value)) if (page->set_value(opt_key, value))
@ -786,7 +787,7 @@ void Tab::update_preset_description_line()
description_line += "\n\n" + _(L("Additional information:")) + "\n"; description_line += "\n\n" + _(L("Additional information:")) + "\n";
description_line += "\t" + _(L("vendor")) + ": " + (name()=="printer" ? "\n\t\t" : "") + parent->vendor->name + description_line += "\t" + _(L("vendor")) + ": " + (name()=="printer" ? "\n\t\t" : "") + parent->vendor->name +
", ver: " + parent->vendor->config_version.to_string(); ", ver: " + parent->vendor->config_version.to_string();
if (name() == "printer"){ if (name() == "printer") {
const std::string &printer_model = preset.config.opt_string("printer_model"); const std::string &printer_model = preset.config.opt_string("printer_model");
//FIXME add prefered_sla_material_profile for SLA //FIXME add prefered_sla_material_profile for SLA
const std::string &default_print_profile = preset.config.opt_string("default_print_profile"); const std::string &default_print_profile = preset.config.opt_string("default_print_profile");
@ -798,7 +799,7 @@ void Tab::update_preset_description_line()
if (!default_filament_profiles.empty()) if (!default_filament_profiles.empty())
{ {
description_line += "\n\n\t" + _(L("default filament profile")) + ": \n\t\t"; description_line += "\n\n\t" + _(L("default filament profile")) + ": \n\t\t";
for (auto& profile : default_filament_profiles){ for (auto& profile : default_filament_profiles) {
if (&profile != &*default_filament_profiles.begin()) if (&profile != &*default_filament_profiles.begin())
description_line += ", "; description_line += ", ";
description_line += profile; description_line += profile;
@ -1043,7 +1044,7 @@ void TabPrint::build()
page = add_options_page(_(L("Dependencies")), "wrench.png"); page = add_options_page(_(L("Dependencies")), "wrench.png");
optgroup = page->new_optgroup(_(L("Profile dependencies"))); optgroup = page->new_optgroup(_(L("Profile dependencies")));
line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" }; line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" };
line.widget = [this](wxWindow* parent){ line.widget = [this](wxWindow* parent) {
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn); return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
}; };
optgroup->append_line(line, &m_colored_Label); optgroup->append_line(line, &m_colored_Label);
@ -1061,7 +1062,8 @@ void TabPrint::build()
} }
// Reload current config (aka presets->edited_preset->config) into the UI fields. // Reload current config (aka presets->edited_preset->config) into the UI fields.
void TabPrint::reload_config(){ void TabPrint::reload_config()
{
reload_compatible_printers_widget(); reload_compatible_printers_widget();
Tab::reload_config(); Tab::reload_config();
} }
@ -1176,7 +1178,7 @@ void TabPrint::update()
break; break;
} }
} }
if (!str_fill_pattern.empty()){ if (!str_fill_pattern.empty()) {
auto external_fill_pattern = m_config->def()->get("external_fill_pattern")->enum_values; auto external_fill_pattern = m_config->def()->get("external_fill_pattern")->enum_values;
bool correct_100p_fill = false; bool correct_100p_fill = false;
for (auto fill : external_fill_pattern) for (auto fill : external_fill_pattern)
@ -1186,7 +1188,7 @@ void TabPrint::update()
} }
// get fill_pattern name from enum_labels for using this one at dialog_msg // get fill_pattern name from enum_labels for using this one at dialog_msg
str_fill_pattern = m_config->def()->get("fill_pattern")->enum_labels[fill_pattern]; str_fill_pattern = m_config->def()->get("fill_pattern")->enum_labels[fill_pattern];
if (!correct_100p_fill){ if (!correct_100p_fill) {
wxString msg_text = _(L("The ")) + str_fill_pattern + _(L(" infill pattern is not supposed to work at 100% density.\n" wxString msg_text = _(L("The ")) + str_fill_pattern + _(L(" infill pattern is not supposed to work at 100% density.\n"
"\nShall I switch to rectilinear fill pattern?")); "\nShall I switch to rectilinear fill pattern?"));
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO); auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO);
@ -1369,7 +1371,7 @@ void TabFilament::build()
optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower"); optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower");
line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" }; line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" };
line.widget = [this](wxWindow* parent){ line.widget = [this](wxWindow* parent) {
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(ramming_dialog_btn); sizer->Add(ramming_dialog_btn);
@ -1409,7 +1411,7 @@ void TabFilament::build()
page = add_options_page(_(L("Dependencies")), "wrench.png"); page = add_options_page(_(L("Dependencies")), "wrench.png");
optgroup = page->new_optgroup(_(L("Profile dependencies"))); optgroup = page->new_optgroup(_(L("Profile dependencies")));
line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" }; line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" };
line.widget = [this](wxWindow* parent){ line.widget = [this](wxWindow* parent) {
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn); return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
}; };
optgroup->append_line(line, &m_colored_Label); optgroup->append_line(line, &m_colored_Label);
@ -1427,7 +1429,8 @@ void TabFilament::build()
} }
// Reload current config (aka presets->edited_preset->config) into the UI fields. // Reload current config (aka presets->edited_preset->config) into the UI fields.
void TabFilament::reload_config(){ void TabFilament::reload_config()
{
reload_compatible_printers_widget(); reload_compatible_printers_widget();
Tab::reload_config(); Tab::reload_config();
} }
@ -1504,7 +1507,7 @@ void TabPrinter::build_fff()
auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
line.widget = [this](wxWindow* parent){ line.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(wxGetApp().small_font()); btn->SetFont(wxGetApp().small_font());
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
@ -1516,7 +1519,7 @@ void TabPrinter::build_fff()
{ {
auto dlg = new BedShapeDialog(this); auto dlg = new BedShapeDialog(this);
dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape")); dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape"));
if (dlg->ShowModal() == wxID_OK){ if (dlg->ShowModal() == wxID_OK) {
load_key_value("bed_shape", dlg->GetValue()); load_key_value("bed_shape", dlg->GetValue());
update_changed_ui(); update_changed_ui();
} }
@ -1540,9 +1543,9 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
optgroup->append_single_option_line("single_extruder_multi_material"); optgroup->append_single_option_line("single_extruder_multi_material");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) {
size_t extruders_count = boost::any_cast<int>(optgroup->get_value("extruders_count")); size_t extruders_count = boost::any_cast<int>(optgroup->get_value("extruders_count"));
wxTheApp->CallAfter([this, opt_key, value, extruders_count](){ wxTheApp->CallAfter([this, opt_key, value, extruders_count]() {
if (opt_key.compare("extruders_count")==0 || opt_key.compare("single_extruder_multi_material")==0) { if (opt_key.compare("extruders_count")==0 || opt_key.compare("single_extruder_multi_material")==0) {
extruders_count_changed(extruders_count); extruders_count_changed(extruders_count);
update_dirty(); update_dirty();
@ -1563,7 +1566,7 @@ void TabPrinter::build_fff()
optgroup = page->new_optgroup(_(L("USB/Serial connection"))); optgroup = page->new_optgroup(_(L("USB/Serial connection")));
line = {_(L("Serial port")), ""}; line = {_(L("Serial port")), ""};
Option serial_port = optgroup->get_option("serial_port"); Option serial_port = optgroup->get_option("serial_port");
serial_port.side_widget = ([this](wxWindow* parent){ serial_port.side_widget = ([this](wxWindow* parent) {
auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(Slic3r::var("arrow_rotate_clockwise.png")), wxBITMAP_TYPE_PNG), auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(Slic3r::var("arrow_rotate_clockwise.png")), wxBITMAP_TYPE_PNG),
wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
btn->SetToolTip(_(L("Rescan serial ports"))); btn->SetToolTip(_(L("Rescan serial ports")));
@ -1573,7 +1576,7 @@ void TabPrinter::build_fff()
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {update_serial_ports(); }); btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {update_serial_ports(); });
return sizer; return sizer;
}); });
auto serial_test = [this](wxWindow* parent){ auto serial_test = [this](wxWindow* parent) {
auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY, auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY,
_(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(Slic3r::GUI::small_font()); btn->SetFont(Slic3r::GUI::small_font());
@ -1581,7 +1584,7 @@ void TabPrinter::build_fff()
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e){ btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e) {
auto sender = Slic3r::make_unique<GCodeSender>(); auto sender = Slic3r::make_unique<GCodeSender>();
auto res = sender->connect( auto res = sender->connect(
m_config->opt_string("serial_port"), m_config->opt_string("serial_port"),
@ -1666,7 +1669,7 @@ void TabPrinter::build_fff()
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e){ btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e) {
static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*")); static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"));
wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST); wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (openFileDialog.ShowModal() != wxID_CANCEL) { if (openFileDialog.ShowModal() != wxID_CANCEL) {
@ -1700,8 +1703,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line("silent_mode"); optgroup->append_single_option_line("silent_mode");
optgroup->append_single_option_line("remaining_times"); optgroup->append_single_option_line("remaining_times");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) {
wxTheApp->CallAfter([this, opt_key, value](){ wxTheApp->CallAfter([this, opt_key, value]() {
if (opt_key.compare("silent_mode") == 0) { if (opt_key.compare("silent_mode") == 0) {
bool val = boost::any_cast<bool>(value); bool val = boost::any_cast<bool>(value);
if (m_use_silent_mode != val) { if (m_use_silent_mode != val) {
@ -1790,7 +1793,7 @@ void TabPrinter::build_sla()
auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
line.widget = [this](wxWindow* parent){ line.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
// btn->SetFont(Slic3r::GUI::small_font); // btn->SetFont(Slic3r::GUI::small_font);
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
@ -1802,7 +1805,7 @@ void TabPrinter::build_sla()
{ {
auto dlg = new BedShapeDialog(this); auto dlg = new BedShapeDialog(this);
dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape")); dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape"));
if (dlg->ShowModal() == wxID_OK){ if (dlg->ShowModal() == wxID_OK) {
load_key_value("bed_shape", dlg->GetValue()); load_key_value("bed_shape", dlg->GetValue());
update_changed_ui(); update_changed_ui();
} }
@ -1852,13 +1855,15 @@ void TabPrinter::build_sla()
optgroup->append_line(line); optgroup->append_line(line);
} }
void TabPrinter::update_serial_ports(){ void TabPrinter::update_serial_ports()
{
Field *field = get_field("serial_port"); Field *field = get_field("serial_port");
Choice *choice = static_cast<Choice *>(field); Choice *choice = static_cast<Choice *>(field);
choice->set_values(Utils::scan_serial_ports()); choice->set_values(Utils::scan_serial_ports());
} }
void TabPrinter::extruders_count_changed(size_t extruders_count){ void TabPrinter::extruders_count_changed(size_t extruders_count)
{
m_extruders_count = extruders_count; m_extruders_count = extruders_count;
m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count);
m_preset_bundle->update_multi_material_filament_presets(); m_preset_bundle->update_multi_material_filament_presets();
@ -1949,7 +1954,7 @@ void TabPrinter::build_extruder_pages()
break; break;
} }
if (existed_page < n_before_extruders && is_marlin_flavor){ if (existed_page < n_before_extruders && is_marlin_flavor) {
auto page = build_kinematics_page(); auto page = build_kinematics_page();
m_pages.insert(m_pages.begin() + n_before_extruders, page); m_pages.insert(m_pages.begin() + n_before_extruders, page);
} }
@ -1982,7 +1987,7 @@ void TabPrinter::build_extruder_pages()
} }
for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx){ for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) {
//# build page //# build page
char buf[MIN_BUF_LENGTH_FOR_L]; char buf[MIN_BUF_LENGTH_FOR_L];
sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1);
@ -2178,7 +2183,8 @@ void TabPrinter::update_fff()
Thaw(); Thaw();
} }
void TabPrinter::update_sla(){ ; } void TabPrinter::update_sla()
{ ; }
// Initialize the UI from the current preset // Initialize the UI from the current preset
void Tab::load_current_preset() void Tab::load_current_preset()
@ -2501,7 +2507,7 @@ void Tab::save_preset(std::string name /*= ""*/)
if (dlg->ShowModal() != wxID_OK) if (dlg->ShowModal() != wxID_OK)
return; return;
name = dlg->get_name(); name = dlg->get_name();
if (name == ""){ if (name == "") {
show_error(this, _(L("The supplied name is empty. It can't be saved."))); show_error(this, _(L("The supplied name is empty. It can't be saved.")));
return; return;
} }
@ -2745,7 +2751,7 @@ void Page::update_visibility(ConfigOptionMode mode)
Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const
{ {
Field* field = nullptr; Field* field = nullptr;
for (auto opt : m_optgroups){ for (auto opt : m_optgroups) {
field = opt->get_fieldc(opt_key, opt_index); field = opt->get_fieldc(opt_key, opt_index);
if (field != nullptr) if (field != nullptr)
return field; return field;
@ -2753,7 +2759,7 @@ Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*
return field; return field;
} }
bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value){ bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value) {
bool changed = false; bool changed = false;
for(auto optgroup: m_optgroups) { for(auto optgroup: m_optgroups) {
if (optgroup->set_value(opt_key, value)) if (optgroup->set_value(opt_key, value))
@ -2789,7 +2795,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
#else #else
auto tab = GetParent(); auto tab = GetParent();
#endif #endif
optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value) {
//! This function will be called from OptionGroup. //! This function will be called from OptionGroup.
//! Using of CallAfter is redundant. //! Using of CallAfter is redundant.
//! And in some cases it causes update() function to be recalled again //! And in some cases it causes update() function to be recalled again
@ -2799,17 +2805,17 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
//! }); //! });
}; };
optgroup->m_get_initial_config = [this, tab](){ optgroup->m_get_initial_config = [this, tab]() {
DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset().config; DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset().config;
return config; return config;
}; };
optgroup->m_get_sys_config = [this, tab](){ optgroup->m_get_sys_config = [this, tab]() {
DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent()->config; DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent()->config;
return config; return config;
}; };
optgroup->have_sys_config = [this, tab](){ optgroup->have_sys_config = [this, tab]() {
return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr; return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr;
}; };
@ -2850,8 +2856,8 @@ void SavePresetWindow::accept()
bool is_unusable_symbol = false; bool is_unusable_symbol = false;
bool is_unusable_postfix = false; bool is_unusable_postfix = false;
const std::string unusable_postfix = PresetCollection::get_suffix_modified();//"(modified)"; const std::string unusable_postfix = PresetCollection::get_suffix_modified();//"(modified)";
for (size_t i = 0; i < std::strlen(unusable_symbols); i++){ for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos){ if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) {
is_unusable_symbol = true; is_unusable_symbol = true;
break; break;
} }
@ -2863,7 +2869,7 @@ void SavePresetWindow::accept()
show_error(this,_(L("The supplied name is not valid;")) + "\n" + show_error(this,_(L("The supplied name is not valid;")) + "\n" +
_(L("the following characters are not allowed:")) + " <>:/\\|?*\""); _(L("the following characters are not allowed:")) + " <>:/\\|?*\"");
} }
else if (is_unusable_postfix){ else if (is_unusable_postfix) {
show_error(this,_(L("The supplied name is not valid;")) + "\n" + show_error(this,_(L("The supplied name is not valid;")) + "\n" +
_(L("the following postfix are not allowed:")) + "\n\t" + //unusable_postfix); _(L("the following postfix are not allowed:")) + "\n\t" + //unusable_postfix);
wxString::FromUTF8(unusable_postfix.c_str())); wxString::FromUTF8(unusable_postfix.c_str()));
@ -2896,7 +2902,7 @@ void TabSLAMaterial::build()
optgroup->label_width = 190; optgroup->label_width = 190;
std::vector<std::string> corrections = { "material_correction_printing", "material_correction_curing" }; std::vector<std::string> corrections = { "material_correction_printing", "material_correction_curing" };
std::vector<std::string> axes{ "X", "Y", "Z" }; std::vector<std::string> axes{ "X", "Y", "Z" };
for (auto& opt_key : corrections){ for (auto& opt_key : corrections) {
auto line = Line{ m_config->def()->get(opt_key)->full_label, "" }; auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
int id = 0; int id = 0;
for (auto& axis : axes) { for (auto& axis : axes) {
@ -2920,7 +2926,7 @@ void TabSLAMaterial::build()
page = add_options_page(_(L("Dependencies")), "wrench.png"); page = add_options_page(_(L("Dependencies")), "wrench.png");
optgroup = page->new_optgroup(_(L("Profile dependencies"))); optgroup = page->new_optgroup(_(L("Profile dependencies")));
Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" }; Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" };
line.widget = [this](wxWindow* parent){ line.widget = [this](wxWindow* parent) {
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn); return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
}; };
optgroup->append_line(line, &m_colored_Label); optgroup->append_line(line, &m_colored_Label);

View File

@ -59,7 +59,7 @@ public:
m_item_color = &wxGetApp().get_label_clr_default(); m_item_color = &wxGetApp().get_label_clr_default();
SetSizer(m_vsizer); SetSizer(m_vsizer);
} }
~Page(){} ~Page() {}
bool m_is_modified_values{ false }; bool m_is_modified_values{ false };
bool m_is_nonsys_values{ true }; bool m_is_nonsys_values{ true };
@ -205,7 +205,7 @@ public:
set_type(); set_type();
wxGetApp().tabs_list.push_back(this); wxGetApp().tabs_list.push_back(this);
} }
~Tab(){ ~Tab() {
wxGetApp().delete_tab_from_list(this); wxGetApp().delete_tab_from_list(this);
} }
@ -245,7 +245,7 @@ public:
PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false); PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false);
virtual void OnActivate(); virtual void OnActivate();
virtual void on_preset_loaded(){} virtual void on_preset_loaded() {}
virtual void build() = 0; virtual void build() = 0;
virtual void update() = 0; virtual void update() = 0;
virtual void init_options_list(); virtual void init_options_list();
@ -283,7 +283,7 @@ public:
TabPrint() {} TabPrint() {}
TabPrint(wxNotebook* parent) : TabPrint(wxNotebook* parent) :
Tab(parent, _(L("Print Settings")), "print") {} Tab(parent, _(L("Print Settings")), "print") {}
~TabPrint(){} ~TabPrint() {}
ogStaticText* m_recommended_thin_wall_thickness_description_line; ogStaticText* m_recommended_thin_wall_thickness_description_line;
bool m_support_material_overhangs_queried = false; bool m_support_material_overhangs_queried = false;
@ -304,7 +304,7 @@ public:
TabFilament() {} TabFilament() {}
TabFilament(wxNotebook* parent) : TabFilament(wxNotebook* parent) :
Tab(parent, _(L("Filament Settings")), "filament") {} Tab(parent, _(L("Filament Settings")), "filament") {}
~TabFilament(){} ~TabFilament() {}
void build() override; void build() override;
void reload_config() override; void reload_config() override;
@ -337,7 +337,7 @@ public:
TabPrinter() {} TabPrinter() {}
TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), "printer") {} TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), "printer") {}
~TabPrinter(){} ~TabPrinter() {}
void build() override; void build() override;
void build_fff(); void build_fff();
@ -361,7 +361,7 @@ public:
TabSLAMaterial() {} TabSLAMaterial() {}
TabSLAMaterial(wxNotebook* parent) : TabSLAMaterial(wxNotebook* parent) :
Tab(parent, _(L("SLA Material Settings")), "sla_material") {} Tab(parent, _(L("SLA Material Settings")), "sla_material") {}
~TabSLAMaterial(){} ~TabSLAMaterial() {}
void build() override; void build() override;
void update() override; void update() override;
@ -372,8 +372,8 @@ public:
class SavePresetWindow :public wxDialog class SavePresetWindow :public wxDialog
{ {
public: public:
SavePresetWindow(wxWindow* parent) :wxDialog(parent, wxID_ANY, _(L("Save preset"))){} SavePresetWindow(wxWindow* parent) :wxDialog(parent, wxID_ANY, _(L("Save preset"))) {}
~SavePresetWindow(){} ~SavePresetWindow() {}
std::string m_chosen_name; std::string m_chosen_name;
wxComboBox* m_combo; wxComboBox* m_combo;

View File

@ -534,7 +534,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddInstanceChild(const wxDataViewItem &
// Add instance nodes // Add instance nodes
PrusaObjectDataViewModelNode *instance_node = nullptr; PrusaObjectDataViewModelNode *instance_node = nullptr;
size_t counter = 0; size_t counter = 0;
while (counter < num){ while (counter < num) {
instance_node = new PrusaObjectDataViewModelNode(inst_root_node, itInstance); instance_node = new PrusaObjectDataViewModelNode(inst_root_node, itInstance);
inst_root_node->Append(instance_node); inst_root_node->Append(instance_node);
// notify control // notify control
@ -559,11 +559,11 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
// first remove the node from the parent's array of children; // first remove the node from the parent's array of children;
// NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_
// thus removing the node from it doesn't result in freeing it // thus removing the node from it doesn't result in freeing it
if (node_parent){ if (node_parent) {
auto id = node_parent->GetChildren().Index(node); auto id = node_parent->GetChildren().Index(node);
auto idx = node->GetIdx(); auto idx = node->GetIdx();
node_parent->GetChildren().Remove(node); node_parent->GetChildren().Remove(node);
if (id > 0){ if (id > 0) {
if(id == node_parent->GetChildCount()) id--; if(id == node_parent->GetChildCount()) id--;
ret_item = wxDataViewItem(node_parent->GetChildren().Item(id)); ret_item = wxDataViewItem(node_parent->GetChildren().Item(id));
} }
@ -607,7 +607,7 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
auto id = it - m_objects.begin(); auto id = it - m_objects.begin();
if (it != m_objects.end()) if (it != m_objects.end())
m_objects.erase(it); m_objects.erase(it);
if (id > 0){ if (id > 0) {
if(id == m_objects.size()) id--; if(id == m_objects.size()) id--;
ret_item = wxDataViewItem(m_objects[id]); ret_item = wxDataViewItem(m_objects[id]);
} }
@ -862,7 +862,7 @@ wxDataViewItem PrusaObjectDataViewModel::MoveChildUp(const wxDataViewItem &item)
return ret_item; return ret_item;
auto volume_id = node->GetVolumeId(); auto volume_id = node->GetVolumeId();
if (0 < volume_id && volume_id < node_parent->GetChildCount()){ if (0 < volume_id && volume_id < node_parent->GetChildCount()) {
node_parent->SwapChildrens(volume_id - 1, volume_id); node_parent->SwapChildrens(volume_id - 1, volume_id);
ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id - 1)); ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id - 1));
ItemChanged(item); ItemChanged(item);
@ -886,7 +886,7 @@ wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &ite
return ret_item; return ret_item;
auto volume_id = node->GetVolumeId(); auto volume_id = node->GetVolumeId();
if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()){ if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()) {
node_parent->SwapChildrens(volume_id + 1, volume_id); node_parent->SwapChildrens(volume_id + 1, volume_id);
ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id + 1)); ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id + 1));
ItemChanged(item); ItemChanged(item);
@ -1586,7 +1586,7 @@ void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event)
} }
m_is_left_down = true; m_is_left_down = true;
if (is_point_in_rect(pos, m_rect_one_layer_icon)){ if (is_point_in_rect(pos, m_rect_one_layer_icon)) {
m_is_one_layer = !m_is_one_layer; m_is_one_layer = !m_is_one_layer;
m_selection == ssLower ? correct_lower_value() : correct_higher_value(); m_selection == ssLower ? correct_lower_value() : correct_higher_value();
if (!m_selection) m_selection = ssHigher; if (!m_selection) m_selection = ssHigher;
@ -1626,10 +1626,10 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event)
const wxClientDC dc(this); const wxClientDC dc(this);
const wxPoint pos = event.GetLogicalPosition(dc); const wxPoint pos = event.GetLogicalPosition(dc);
m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon); m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon);
if (!m_is_left_down && !m_is_one_layer){ if (!m_is_left_down && !m_is_one_layer) {
m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action);
} }
else if (m_is_left_down || m_is_right_down){ else if (m_is_left_down || m_is_right_down) {
if (m_selection == ssLower) { if (m_selection == ssLower) {
m_lower_value = get_value_from_position(pos.x, pos.y); m_lower_value = get_value_from_position(pos.x, pos.y);
correct_lower_value(); correct_lower_value();
@ -1741,7 +1741,7 @@ void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event)
{ {
if (key == WXK_LEFT || key == WXK_RIGHT) if (key == WXK_LEFT || key == WXK_RIGHT)
move_current_thumb(key == WXK_LEFT); move_current_thumb(key == WXK_LEFT);
else if (key == WXK_UP || key == WXK_DOWN){ else if (key == WXK_UP || key == WXK_DOWN) {
m_selection = key == WXK_UP ? ssHigher : ssLower; m_selection = key == WXK_UP ? ssHigher : ssLower;
Refresh(); Refresh();
} }

View File

@ -638,7 +638,7 @@ public:
long style = wxSL_VERTICAL, long style = wxSL_VERTICAL,
const wxValidator& val = wxDefaultValidator, const wxValidator& val = wxDefaultValidator,
const wxString& name = wxEmptyString); const wxString& name = wxEmptyString);
~PrusaDoubleSlider(){} ~PrusaDoubleSlider() {}
int GetLowerValue() const { int GetLowerValue() const {
return m_lower_value; return m_lower_value;
@ -661,12 +661,12 @@ public:
} }
void ChangeOneLayerLock(); void ChangeOneLayerLock();
void OnPaint(wxPaintEvent& ){ render();} void OnPaint(wxPaintEvent& ) { render();}
void OnLeftDown(wxMouseEvent& event); void OnLeftDown(wxMouseEvent& event);
void OnMotion(wxMouseEvent& event); void OnMotion(wxMouseEvent& event);
void OnLeftUp(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event);
void OnEnterWin(wxMouseEvent& event){ enter_window(event, true); } void OnEnterWin(wxMouseEvent& event) { enter_window(event, true); }
void OnLeaveWin(wxMouseEvent& event){ enter_window(event, false); } void OnLeaveWin(wxMouseEvent& event) { enter_window(event, false); }
void OnWheel(wxMouseEvent& event); void OnWheel(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent &event); void OnKeyDown(wxKeyEvent &event);
void OnKeyUp(wxKeyEvent &event); void OnKeyUp(wxKeyEvent &event);
@ -770,11 +770,11 @@ public:
wxWindowID id, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize); const wxSize& size = wxDefaultSize);
~PrusaLockButton(){} ~PrusaLockButton() {}
void OnButton(wxCommandEvent& event); void OnButton(wxCommandEvent& event);
void OnEnterBtn(wxMouseEvent& event){ enter_button(true); event.Skip(); } void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); }
void OnLeaveBtn(wxMouseEvent& event){ enter_button(false); event.Skip(); } void OnLeaveBtn(wxMouseEvent& event) { enter_button(false); event.Skip(); }
bool IsLocked() const { return m_is_pushed; } bool IsLocked() const { return m_is_pushed; }