mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-04 20:44:00 -06:00
Merge branch 'dev_native' into vb_dev_native_background_processing
This commit is contained in:
commit
edc79cb922
47 changed files with 1617 additions and 238 deletions
|
@ -198,6 +198,9 @@ GLVolume::GLVolume(float r, float g, float b, float a)
|
|||
: m_offset(Vec3d::Zero())
|
||||
, m_rotation(Vec3d::Zero())
|
||||
, m_scaling_factor(Vec3d::Ones())
|
||||
#if ENABLE_MIRROR
|
||||
, m_mirror(Vec3d::Ones())
|
||||
#endif // ENABLE_MIRROR
|
||||
, m_world_matrix(Transform3f::Identity())
|
||||
, m_world_matrix_dirty(true)
|
||||
, m_transformed_bounding_box_dirty(true)
|
||||
|
@ -324,6 +327,40 @@ void GLVolume::set_scaling_factor(const Vec3d& scaling_factor)
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
const Vec3d& GLVolume::get_mirror() const
|
||||
{
|
||||
return m_mirror;
|
||||
}
|
||||
|
||||
double GLVolume::get_mirror(Axis axis) const
|
||||
{
|
||||
return m_mirror(axis);
|
||||
}
|
||||
|
||||
void GLVolume::set_mirror(const Vec3d& mirror)
|
||||
{
|
||||
if (m_mirror != mirror)
|
||||
{
|
||||
m_mirror = mirror;
|
||||
m_world_matrix_dirty = true;
|
||||
m_transformed_bounding_box_dirty = true;
|
||||
m_transformed_convex_hull_bounding_box_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLVolume::set_mirror(Axis axis, double mirror)
|
||||
{
|
||||
if (m_mirror(axis) != mirror)
|
||||
{
|
||||
m_mirror(axis) = mirror;
|
||||
m_world_matrix_dirty = true;
|
||||
m_transformed_bounding_box_dirty = true;
|
||||
m_transformed_convex_hull_bounding_box_dirty = true;
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void GLVolume::set_convex_hull(const TriangleMesh& convex_hull)
|
||||
{
|
||||
m_convex_hull = &convex_hull;
|
||||
|
@ -353,7 +390,11 @@ const Transform3f& GLVolume::world_matrix() const
|
|||
{
|
||||
if (m_world_matrix_dirty)
|
||||
{
|
||||
#if ENABLE_MIRROR
|
||||
m_world_matrix = Geometry::assemble_transform(m_offset, m_rotation, m_scaling_factor, m_mirror).cast<float>();
|
||||
#else
|
||||
m_world_matrix = Geometry::assemble_transform(m_offset, m_rotation, m_scaling_factor).cast<float>();
|
||||
#endif // ENABLE_MIRROR
|
||||
m_world_matrix_dirty = false;
|
||||
}
|
||||
return m_world_matrix;
|
||||
|
@ -729,6 +770,9 @@ std::vector<int> GLVolumeCollection::load_object(
|
|||
v.set_offset(instance->get_offset());
|
||||
v.set_rotation(instance->get_rotation());
|
||||
v.set_scaling_factor(instance->get_scaling_factor());
|
||||
#if ENABLE_MIRROR
|
||||
v.set_mirror(instance->get_mirror());
|
||||
#endif // ENABLE_MIRROR
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2076,6 +2120,15 @@ int _3DScene::get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx)
|
|||
return s_canvas_mgr.get_in_object_volume_id(canvas, scene_vol_idx);
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
void _3DScene::mirror_selection(wxGLCanvas* canvas, Axis axis)
|
||||
{
|
||||
s_canvas_mgr.mirror_selection(canvas, axis);
|
||||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void _3DScene::reload_scene(wxGLCanvas* canvas, bool force)
|
||||
{
|
||||
s_canvas_mgr.reload_scene(canvas, force);
|
||||
|
|
|
@ -260,6 +260,10 @@ private:
|
|||
Vec3d m_rotation;
|
||||
// Scale factor along the three axes of the volume to be rendered.
|
||||
Vec3d m_scaling_factor;
|
||||
#if ENABLE_MIRROR
|
||||
// Mirroring along the three axes of the volume to be rendered.
|
||||
Vec3d m_mirror;
|
||||
#endif // ENABLE_MIRROR
|
||||
// World matrix of the volume to be rendered.
|
||||
mutable Transform3f m_world_matrix;
|
||||
// Whether or not is needed to recalculate the world matrix.
|
||||
|
@ -337,6 +341,13 @@ public:
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
void set_scaling_factor(const Vec3d& scaling_factor);
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
const Vec3d& get_mirror() const;
|
||||
double get_mirror(Axis axis) const;
|
||||
void set_mirror(const Vec3d& mirror);
|
||||
void set_mirror(Axis axis, double mirror);
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
const Vec3d& get_offset() const;
|
||||
void set_offset(const Vec3d& offset);
|
||||
|
||||
|
@ -581,6 +592,12 @@ public:
|
|||
static int get_first_volume_id(wxGLCanvas* canvas, int obj_idx);
|
||||
static int get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx);
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
static void mirror_selection(wxGLCanvas* canvas, Axis axis);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
static void reload_scene(wxGLCanvas* canvas, bool force);
|
||||
|
||||
static void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
|
||||
|
|
|
@ -54,10 +54,13 @@ public:
|
|||
virtual bool
|
||||
AcceptsFocusFromKeyboard() const { return false; }
|
||||
|
||||
void set_as_hidden() {
|
||||
Hide();
|
||||
hidden = true;
|
||||
}
|
||||
|
||||
virtual bool Show(bool show = true) override {
|
||||
if (!show)
|
||||
hidden = true;
|
||||
return wxButton::Show(!hidden);
|
||||
return wxButton::Show(hidden ? false : show);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1409,14 +1409,13 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
if (is_single_full_instance())
|
||||
(*m_volumes)[i]->set_rotation(rotation);
|
||||
else
|
||||
{
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
// extracts rotations from the composed transformation
|
||||
Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_rotation_matrix());
|
||||
|
||||
|
@ -1436,15 +1435,13 @@ void GLCanvas3D::Selection::scale(const Vec3d& scale)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
Transform3d m = Transform3d::Identity();
|
||||
m.scale(scale);
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
if (is_single_full_instance())
|
||||
(*m_volumes)[i]->set_scaling_factor(scale);
|
||||
else
|
||||
{
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
|
@ -1460,6 +1457,25 @@ void GLCanvas3D::Selection::scale(const Vec3d& scale)
|
|||
m_bounding_box_dirty = true;
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
void GLCanvas3D::Selection::mirror(Axis axis)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
if (is_single_full_instance())
|
||||
(*m_volumes)[i]->set_mirror(axis, -(*m_volumes)[i]->get_mirror(axis));
|
||||
}
|
||||
|
||||
if (m_mode == Instance)
|
||||
_synchronize_unselected_instances();
|
||||
|
||||
m_bounding_box_dirty = true;
|
||||
}
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void GLCanvas3D::Selection::render(bool show_indirect_selection) const
|
||||
{
|
||||
if (is_empty())
|
||||
|
@ -1783,6 +1799,9 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances()
|
|||
int instance_idx = volume->instance_idx();
|
||||
const Vec3d& rotation = volume->get_rotation();
|
||||
const Vec3d& scaling_factor = volume->get_scaling_factor();
|
||||
#if ENABLE_MIRROR
|
||||
const Vec3d& mirror = volume->get_mirror();
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
// Process unselected instances.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
|
||||
|
@ -1799,6 +1818,9 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances()
|
|||
|
||||
v->set_rotation(rotation);
|
||||
v->set_scaling_factor(scaling_factor);
|
||||
#if ENABLE_MIRROR
|
||||
v->set_mirror(mirror);
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
done.insert(j);
|
||||
}
|
||||
|
@ -2674,9 +2696,11 @@ wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
|
|||
wxDEFINE_EVENT(EVT_GLCANVAS_MODEL_UPDATE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ROTATE_OBJECT, Event<int>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_SCALE_UNIFORMLY, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_OBJECTS, Event<int>);
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||
|
@ -3404,6 +3428,17 @@ int GLCanvas3D::get_in_object_volume_id(int scene_vol_idx) const
|
|||
return ((0 <= scene_vol_idx) && (scene_vol_idx < (int)m_volumes.volumes.size())) ? m_volumes.volumes[scene_vol_idx]->volume_idx() : -1;
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
void GLCanvas3D::mirror_selection(Axis axis)
|
||||
{
|
||||
m_selection.mirror(axis);
|
||||
_on_mirror();
|
||||
wxGetApp().obj_manipul()->update_settings_value(m_selection);
|
||||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void GLCanvas3D::reload_scene(bool force)
|
||||
{
|
||||
if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
|
||||
|
@ -3421,7 +3456,12 @@ void GLCanvas3D::reload_scene(bool force)
|
|||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
if (m_regenerate_volumes)
|
||||
{
|
||||
reset_volumes();
|
||||
|
||||
// to update the toolbar
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
set_bed_shape(dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"))->values);
|
||||
|
@ -3441,9 +3481,6 @@ void GLCanvas3D::reload_scene(bool force)
|
|||
{
|
||||
load_object(*m_model, obj_idx);
|
||||
}
|
||||
|
||||
// to update the toolbar
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
}
|
||||
|
||||
update_gizmos_data();
|
||||
|
@ -3685,24 +3722,26 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
|||
switch (keyCode)
|
||||
{
|
||||
// key +
|
||||
case 43: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_OBJECTS, +1)); break; }
|
||||
case 43: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; }
|
||||
// key -
|
||||
case 45: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_OBJECTS, -1)); break; }
|
||||
case 45: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; }
|
||||
// key A/a
|
||||
case 65:
|
||||
case 97: { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
|
||||
// key B/b
|
||||
case 66:
|
||||
case 98: { zoom_to_bed(); break; }
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
// key L/l
|
||||
case 76:
|
||||
case 108: { post_event(Event<int>(EVT_GLCANVAS_ROTATE_OBJECT, -1)); break; }
|
||||
// key R/r
|
||||
// key R/r
|
||||
case 82:
|
||||
case 114: { post_event(Event<int>(EVT_GLCANVAS_ROTATE_OBJECT, +1)); break; }
|
||||
// key S/s
|
||||
// key S/s
|
||||
case 83:
|
||||
case 115: { post_event(SimpleEvent(EVT_GLCANVAS_SCALE_UNIFORMLY)); break; }
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
// key Z/z
|
||||
case 90:
|
||||
case 122: { zoom_to_volumes(); break; }
|
||||
|
@ -3820,7 +3859,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
case Gizmos::Scale:
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
m_regenerate_volumes = false;
|
||||
m_selection.scale(m_gizmos.get_scale());
|
||||
_on_scale();
|
||||
#else
|
||||
|
@ -3837,7 +3875,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
case Gizmos::Rotate:
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
m_regenerate_volumes = false;
|
||||
m_selection.rotate(m_gizmos.get_rotation());
|
||||
_on_rotate();
|
||||
#else
|
||||
|
@ -3903,9 +3940,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
else if (!m_selection.is_empty() && m_gizmos.grabber_contains_mouse())
|
||||
else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse())
|
||||
#else
|
||||
else if ((selected_object_idx != -1) && m_gizmos.grabber_contains_mouse())
|
||||
else if (evt.LeftDown() && (selected_object_idx != -1) && m_gizmos.grabber_contains_mouse())
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
{
|
||||
update_gizmos_data();
|
||||
|
@ -3920,7 +3957,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
if (m_gizmos.get_current_type() == Gizmos::Flatten) {
|
||||
// Rotate the object so the normal points downward:
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
m_regenerate_volumes = false;
|
||||
m_selection.rotate(m_gizmos.get_flattening_rotation());
|
||||
_on_flatten();
|
||||
wxGetApp().obj_manipul()->update_settings_value(m_selection);
|
||||
|
@ -3951,14 +3987,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
#if ENABLE_EXTENDED_SELECTION
|
||||
if (evt.LeftDown() && (m_hover_volume_id != -1))
|
||||
{
|
||||
if (evt.ControlDown())
|
||||
m_selection.remove(m_hover_volume_id);
|
||||
else
|
||||
if (!evt.ShiftDown() || !m_selection.contains_volume(m_hover_volume_id))
|
||||
m_selection.add(m_hover_volume_id, !evt.ShiftDown());
|
||||
else
|
||||
m_selection.remove(m_hover_volume_id);
|
||||
|
||||
m_gizmos.update_on_off_state(m_selection);
|
||||
update_gizmos_data();
|
||||
wxGetApp().obj_manipul()->update_settings_value(m_selection);
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
m_dirty = true;
|
||||
}
|
||||
#else
|
||||
|
@ -3983,16 +4020,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
|
||||
// propagate event through callback
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
if (m_picking_enabled && (m_hover_volume_id != -1))
|
||||
{
|
||||
int object_idx = m_selection.get_object_idx();
|
||||
_on_select(m_hover_volume_id, object_idx);
|
||||
}
|
||||
#else
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
if (m_picking_enabled && (volume_idx != -1))
|
||||
_on_select(volume_idx, selected_object_idx);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
if (m_hover_volume_id != -1)
|
||||
|
@ -4319,10 +4350,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
#if ENABLE_EXTENDED_SELECTION
|
||||
m_selection.clear();
|
||||
wxGetApp().obj_manipul()->update_settings_value(m_selection);
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
#else
|
||||
deselect_volumes();
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
_on_select(-1, -1);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
update_gizmos_data();
|
||||
}
|
||||
#if ENABLE_GIZMOS_RESET
|
||||
|
@ -4363,7 +4395,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
case Gizmos::Scale:
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
m_regenerate_volumes = false;
|
||||
_on_scale();
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
break;
|
||||
|
@ -4371,7 +4402,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
case Gizmos::Rotate:
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
m_regenerate_volumes = false;
|
||||
_on_rotate();
|
||||
#else
|
||||
post_event(Vec3dEvent(EVT_GIZMO_ROTATE, m_gizmos.get_rotation()));
|
||||
|
@ -6524,6 +6554,41 @@ void GLCanvas3D::_on_flatten()
|
|||
_on_rotate();
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
void GLCanvas3D::_on_mirror()
|
||||
{
|
||||
if (m_model == nullptr)
|
||||
return;
|
||||
|
||||
std::set<std::pair<int, int>> done; // prevent mirroring instances twice
|
||||
|
||||
for (const GLVolume* v : m_volumes.volumes)
|
||||
{
|
||||
int object_idx = v->object_idx();
|
||||
if (object_idx >= 1000)
|
||||
continue;
|
||||
|
||||
int instance_idx = v->instance_idx();
|
||||
|
||||
// prevent mirroring instances twice
|
||||
std::pair<int, int> done_id(object_idx, instance_idx);
|
||||
if (done.find(done_id) != done.end())
|
||||
continue;
|
||||
|
||||
done.insert(done_id);
|
||||
|
||||
// Mirror instances.
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr)
|
||||
{
|
||||
model_object->instances[instance_idx]->set_mirror(v->get_mirror());
|
||||
model_object->invalidate_bounding_box();
|
||||
}
|
||||
}
|
||||
|
||||
// schedule_background_process
|
||||
}
|
||||
#endif // ENABLE_MIRROR
|
||||
#else
|
||||
void GLCanvas3D::_on_move(const std::vector<int>& volume_idxs)
|
||||
{
|
||||
|
@ -6572,11 +6637,9 @@ void GLCanvas3D::_on_move(const std::vector<int>& volume_idxs)
|
|||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void GLCanvas3D::_on_select(int volume_idx, int object_idx)
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
#else
|
||||
int vol_id = -1;
|
||||
int obj_id = -1;
|
||||
|
||||
|
@ -6605,8 +6668,8 @@ void GLCanvas3D::_on_select(int volume_idx, int object_idx)
|
|||
|
||||
post_event(ObjectSelectEvent(obj_id, vol_id));
|
||||
wxGetApp().obj_list()->select_current_volume(obj_id, vol_id);
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
|
||||
{
|
||||
|
|
|
@ -112,9 +112,11 @@ wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
|
|||
wxDECLARE_EVENT(EVT_GLCANVAS_MODEL_UPDATE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ROTATE_OBJECT, Event<int>); // data: -1 => rotate left, +1 => rotate right
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_SCALE_UNIFORMLY, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_OBJECTS, Event<int>); // data: +1 => increase, -1 => decrease
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); // data: +1 => increase, -1 => decrease
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||
|
@ -483,6 +485,8 @@ public:
|
|||
bool is_from_single_instance() const { return get_instance_idx() != -1; }
|
||||
bool is_from_single_object() const { return get_object_idx() != -1; }
|
||||
|
||||
bool contains_volume(unsigned int volume_idx) const { return std::find(m_list.begin(), m_list.end(), volume_idx) != m_list.end(); }
|
||||
|
||||
// Returns the the object id if the selection is from a single object, otherwise is -1
|
||||
int get_object_idx() const;
|
||||
// Returns the instance id if the selection is from a single object and from a single instance, otherwise is -1
|
||||
|
@ -499,6 +503,9 @@ public:
|
|||
void translate(const Vec3d& displacement);
|
||||
void rotate(const Vec3d& rotation);
|
||||
void scale(const Vec3d& scale);
|
||||
#if ENABLE_MIRROR
|
||||
void mirror(Axis axis);
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void render(bool show_indirect_selection) const;
|
||||
|
||||
|
@ -831,6 +838,12 @@ public:
|
|||
int get_first_volume_id(int obj_idx) const;
|
||||
int get_in_object_volume_id(int scene_vol_idx) const;
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
void mirror_selection(Axis axis);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void reload_scene(bool force);
|
||||
|
||||
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
|
||||
|
@ -953,10 +966,15 @@ private:
|
|||
void _on_rotate();
|
||||
void _on_scale();
|
||||
void _on_flatten();
|
||||
#if ENABLE_MIRROR
|
||||
void _on_mirror();
|
||||
#endif // ENABLE_MIRROR
|
||||
#else
|
||||
void _on_move(const std::vector<int>& volume_idxs);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void _on_select(int volume_idx, int object_idx);
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
// generates the legend texture in dependence of the current shown view type
|
||||
void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
|
||||
|
|
|
@ -596,6 +596,17 @@ int GLCanvas3DManager::get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol
|
|||
return (it != m_canvases.end()) ? it->second->get_in_object_volume_id(scene_vol_idx) : -1;
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
void GLCanvas3DManager::mirror_selection(wxGLCanvas* canvas, Axis axis)
|
||||
{
|
||||
CanvasesMap::iterator it = _get_canvas(canvas);
|
||||
if (it != m_canvases.end())
|
||||
it->second->mirror_selection(axis);
|
||||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void GLCanvas3DManager::reload_scene(wxGLCanvas* canvas, bool force)
|
||||
{
|
||||
CanvasesMap::iterator it = _get_canvas(canvas);
|
||||
|
|
|
@ -163,6 +163,12 @@ public:
|
|||
int get_first_volume_id(wxGLCanvas* canvas, int obj_idx) const;
|
||||
int get_in_object_volume_id(wxGLCanvas* canvas, int scene_vol_idx) const;
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
void mirror_selection(wxGLCanvas* canvas, Axis axis);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
void reload_scene(wxGLCanvas* canvas, bool force);
|
||||
|
||||
void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
|
||||
|
|
|
@ -868,7 +868,7 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
|||
BoundingBoxf3 box;
|
||||
Transform3d transform = Transform3d::Identity();
|
||||
Vec3d angles = Vec3d::Zero();
|
||||
Transform3d rotation = Transform3d::Identity();
|
||||
Transform3d offsets_transform = Transform3d::Identity();
|
||||
|
||||
if (selection.is_from_single_instance())
|
||||
{
|
||||
|
@ -880,13 +880,19 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
|||
}
|
||||
|
||||
// gets transform from first selected volume
|
||||
transform = selection.get_volume(*idxs.begin())->world_matrix().cast<double>();
|
||||
const GLVolume* v = selection.get_volume(*idxs.begin());
|
||||
transform = v->world_matrix().cast<double>();
|
||||
|
||||
// extract angles from transform
|
||||
angles = Slic3r::Geometry::extract_euler_angles(transform);
|
||||
// gets angles from first selected volume
|
||||
angles = v->get_rotation();
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
// consider rotation+mirror only components of the transform for offsets
|
||||
offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v->get_mirror());
|
||||
#else
|
||||
// set rotation-only component of transform
|
||||
rotation = Geometry::assemble_transform(Vec3d::Zero(), angles);
|
||||
offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles);
|
||||
#endif // ENABLE_MIRROR
|
||||
}
|
||||
else
|
||||
box = selection.get_bounding_box();
|
||||
|
@ -898,9 +904,9 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
|||
|
||||
const Vec3d& center = m_box.center();
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
Vec3d offset_x = rotation * Vec3d((double)Offset, 0.0, 0.0);
|
||||
Vec3d offset_y = rotation * Vec3d(0.0, (double)Offset, 0.0);
|
||||
Vec3d offset_z = rotation * Vec3d(0.0, 0.0, (double)Offset);
|
||||
Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0);
|
||||
Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0);
|
||||
Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
// x axis
|
||||
|
@ -1468,6 +1474,7 @@ void GLGizmoFlatten::on_render(const BoundingBoxf3& box) const
|
|||
|
||||
::glEnable(GL_BLEND);
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
::glDisable(GL_CULL_FACE);
|
||||
|
||||
for (int i=0; i<(int)m_planes.size(); ++i) {
|
||||
if (i == m_hover_id)
|
||||
|
@ -1506,6 +1513,7 @@ void GLGizmoFlatten::on_render(const BoundingBoxf3& box) const
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
|
||||
::glEnable(GL_CULL_FACE);
|
||||
::glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
@ -1516,6 +1524,7 @@ void GLGizmoFlatten::on_render_for_picking(const BoundingBoxf3& box) const
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
{
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
::glDisable(GL_CULL_FACE);
|
||||
|
||||
for (unsigned int i = 0; i < m_planes.size(); ++i)
|
||||
{
|
||||
|
@ -1546,6 +1555,8 @@ void GLGizmoFlatten::on_render_for_picking(const BoundingBoxf3& box) const
|
|||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
|
||||
::glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
|
||||
|
@ -1769,9 +1780,9 @@ Vec3d GLGizmoFlatten::get_flattening_rotation() const
|
|||
// calculates the rotations in model space, taking in account the scaling factors
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> m = m_model_object->instances.front()->world_matrix(true, true).matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
Eigen::Quaterniond q;
|
||||
Vec3d angles = q.setFromTwoVectors(m * m_normal, -Vec3d::UnitZ()).toRotationMatrix().eulerAngles(2, 1, 0);
|
||||
Vec3d angles = Geometry::extract_euler_angles(q.setFromTwoVectors(m * m_normal, -Vec3d::UnitZ()).toRotationMatrix());
|
||||
m_normal = Vec3d::Zero();
|
||||
return Vec3d(angles(2), angles(1), angles(0));
|
||||
return angles;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
@ -327,24 +327,6 @@ void GUI_App::CallAfter(std::function<void()> cb)
|
|||
callback_register.unlock();
|
||||
}
|
||||
|
||||
wxMenuItem* GUI_App::append_submenu(wxMenu* menu,
|
||||
wxMenu* sub_menu,
|
||||
int id,
|
||||
const wxString& string,
|
||||
const wxString& description,
|
||||
const std::string& icon)
|
||||
{
|
||||
if (id == wxID_ANY)
|
||||
id = wxNewId();
|
||||
auto item = new wxMenuItem(menu, id, string, description);
|
||||
if (!icon.empty())
|
||||
item->SetBitmap(wxBitmap(Slic3r::var(icon), wxBITMAP_TYPE_PNG));
|
||||
item->SetSubMenu(sub_menu);
|
||||
menu->Append(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name)
|
||||
{
|
||||
if (name.empty()) { return; }
|
||||
|
@ -500,7 +482,8 @@ ConfigMenuIDs GUI_App::get_view_mode()
|
|||
return ConfigMenuModeSimple;
|
||||
|
||||
const auto mode = app_config->get("view_mode");
|
||||
return mode == "expert" ? ConfigMenuModeExpert : ConfigMenuModeSimple;
|
||||
return mode == "expert" ? ConfigMenuModeExpert :
|
||||
mode == "simple" ? ConfigMenuModeSimple : ConfigMenuModeMiddle;
|
||||
}
|
||||
|
||||
// Update view mode according to selected menu
|
||||
|
@ -518,6 +501,11 @@ void GUI_App::update_mode()
|
|||
|
||||
sidebar().Layout();
|
||||
mainframe->m_plater->Layout();
|
||||
|
||||
ConfigOptionMode opt_mode = mode == ConfigMenuModeSimple ? comSimple :
|
||||
mode == ConfigMenuModeExpert ? comExpert : comMiddle;
|
||||
for (auto tab : tabs_list)
|
||||
tab->update_visibility(opt_mode);
|
||||
}
|
||||
|
||||
void GUI_App::add_config_menu(wxMenuBar *menu)
|
||||
|
@ -537,6 +525,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
|||
local_menu->AppendSeparator();
|
||||
auto mode_menu = new wxMenu();
|
||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("&Simple")), _(L("Simple View Mode")));
|
||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeMiddle, _(L("&Middle")), _(L("Middle View Mode")));
|
||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("&Expert")), _(L("Expert View Mode")));
|
||||
mode_menu->Check(config_id_base + get_view_mode(), true);
|
||||
local_menu->AppendSubMenu(mode_menu, _(L("&Mode")), _(L("Slic3r View Mode")));
|
||||
|
@ -607,8 +596,9 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
|||
}
|
||||
});
|
||||
mode_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) {
|
||||
std::string mode = event.GetId() - config_id_base == ConfigMenuModeExpert ?
|
||||
"expert" : "simple";
|
||||
int id_mode = event.GetId() - config_id_base;
|
||||
std::string mode = id_mode == ConfigMenuModeExpert ? "expert" :
|
||||
id_mode == ConfigMenuModeSimple ? "simple" : "middle";
|
||||
app_config->set("view_mode", mode);
|
||||
app_config->save();
|
||||
update_mode();
|
||||
|
|
|
@ -51,6 +51,7 @@ enum ConfigMenuIDs {
|
|||
ConfigMenuUpdate,
|
||||
ConfigMenuPreferences,
|
||||
ConfigMenuModeSimple,
|
||||
ConfigMenuModeMiddle,
|
||||
ConfigMenuModeExpert,
|
||||
ConfigMenuLanguage,
|
||||
ConfigMenuFlashFirmware,
|
||||
|
@ -107,12 +108,6 @@ public:
|
|||
// void notify(/*message*/);
|
||||
void update_ui_from_settings();
|
||||
void CallAfter(std::function<void()> cb);
|
||||
wxMenuItem* append_submenu(wxMenu* menu,
|
||||
wxMenu* sub_menu,
|
||||
int id,
|
||||
const wxString& string,
|
||||
const wxString& description,
|
||||
const std::string& icon);
|
||||
|
||||
void window_pos_save(wxTopLevelWindow* window, const std::string &name);
|
||||
void window_pos_restore(wxTopLevelWindow* window, const std::string &name);
|
||||
|
|
|
@ -868,7 +868,7 @@ void ObjectList::del_settings_from_config()
|
|||
|
||||
void ObjectList::del_instances_from_object(const int obj_idx)
|
||||
{
|
||||
auto instances = (*m_objects)[obj_idx]->instances;
|
||||
auto& instances = (*m_objects)[obj_idx]->instances;
|
||||
if (instances.size() <= 1)
|
||||
return;
|
||||
|
||||
|
@ -1054,7 +1054,11 @@ void ObjectList::part_selection_changed()
|
|||
|
||||
m_selected_object_id = obj_idx;
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
wxGetApp().obj_manipul()->update_settings_value(_3DScene::get_canvas(wxGetApp().canvas3D())->get_selection());
|
||||
#else
|
||||
wxGetApp().obj_manipul()->update_values();
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
|
||||
void ObjectList::update_manipulation_sizer(const bool is_simple_mode)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <wx/bitmap.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class wxBoxSizer;
|
||||
class PrusaObjectDataViewModel;
|
||||
|
|
|
@ -221,7 +221,7 @@ void ObjectManipulation::update_settings_list()
|
|||
if (cat.second.size() == 1 && cat.second[0] == "extruder")
|
||||
continue;
|
||||
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, cat.first, config, false, ogDEFAULT, extra_column);
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, cat.first, config, false, extra_column);
|
||||
optgroup->label_width = 150;
|
||||
optgroup->sidetext_width = 70;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <wx/toplevel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/checkbox.h>
|
||||
|
||||
#include "libslic3r/Config.hpp"
|
||||
|
@ -16,6 +15,30 @@ namespace Slic3r {
|
|||
namespace GUI {
|
||||
|
||||
|
||||
CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
|
||||
: wxPanel(parent, wxID_ANY)
|
||||
{
|
||||
// WARN: wxMSW does some extra shenanigans to calc the extra control size.
|
||||
// It first calls the create function with a dummy empty wxDialog parent and saves its size.
|
||||
// Afterwards, the create function is called again with the real parent.
|
||||
// Additionally there's no way to pass any extra data to the create function (no closure),
|
||||
// which is why we have to this stuff here. Grrr!
|
||||
auto *dlg = dynamic_cast<CheckboxFileDialog*>(parent);
|
||||
const wxString checkbox_label(dlg != nullptr ? dlg->checkbox_label : wxString("String long enough to contain dlg->checkbox_label"));
|
||||
|
||||
auto* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
cbox = new wxCheckBox(this, wxID_ANY, checkbox_label);
|
||||
cbox->SetValue(true);
|
||||
sizer->AddSpacer(5);
|
||||
sizer->Add(this->cbox, 0, wxEXPAND | wxALL, 5);
|
||||
SetSizer(sizer);
|
||||
sizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
wxWindow* CheckboxFileDialog::ExtraPanel::ctor(wxWindow *parent) {
|
||||
return new ExtraPanel(parent);
|
||||
}
|
||||
|
||||
CheckboxFileDialog::CheckboxFileDialog(wxWindow *parent,
|
||||
const wxString &checkbox_label,
|
||||
bool checkbox_value,
|
||||
|
@ -29,35 +52,22 @@ CheckboxFileDialog::CheckboxFileDialog(wxWindow *parent,
|
|||
const wxString &name
|
||||
)
|
||||
: wxFileDialog(parent, message, default_dir, default_file, wildcard, style, pos, size, name)
|
||||
, cbox(nullptr)
|
||||
, checkbox_label(checkbox_label)
|
||||
{
|
||||
if (checkbox_label.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
extra_control_creator = [this, checkbox_label](wxWindow *parent) -> wxWindow* {
|
||||
wxPanel* panel = new wxPanel(parent, -1);
|
||||
wxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
this->cbox = new wxCheckBox(panel, wxID_HIGHEST + 1, checkbox_label);
|
||||
this->cbox->SetValue(true);
|
||||
sizer->AddSpacer(5);
|
||||
sizer->Add(this->cbox, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
|
||||
panel->SetSizer(sizer);
|
||||
sizer->SetSizeHints(panel);
|
||||
|
||||
return panel;
|
||||
};
|
||||
|
||||
SetExtraControlCreator(*extra_control_creator.target<ExtraControlCreatorFunction>());
|
||||
SetExtraControlCreator(ExtraPanel::ctor);
|
||||
}
|
||||
|
||||
bool CheckboxFileDialog::get_checkbox_value() const
|
||||
{
|
||||
return this->cbox != nullptr ? cbox->IsChecked() : false;
|
||||
auto *extra_panel = dynamic_cast<ExtraPanel*>(GetExtraControl());
|
||||
return extra_panel != nullptr ? extra_panel->cbox->GetValue() : false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WindowMetrics WindowMetrics::from_window(wxTopLevelWindow *window)
|
||||
{
|
||||
WindowMetrics res;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/panel.h>
|
||||
|
||||
class wxCheckBox;
|
||||
class wxTopLevelWindow;
|
||||
|
@ -37,8 +38,15 @@ public:
|
|||
bool get_checkbox_value() const;
|
||||
|
||||
private:
|
||||
std::function<wxWindow*(wxWindow*)> extra_control_creator;
|
||||
wxCheckBox *cbox;
|
||||
struct ExtraPanel : public wxPanel
|
||||
{
|
||||
wxCheckBox *cbox;
|
||||
|
||||
ExtraPanel(wxWindow *parent);
|
||||
static wxWindow* ctor(wxWindow *parent);
|
||||
};
|
||||
|
||||
wxString checkbox_label;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -296,13 +296,13 @@ void MainFrame::init_menubar()
|
|||
if (m_plater) {
|
||||
m_plater_menu = new wxMenu();
|
||||
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")),
|
||||
[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")),
|
||||
[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")),
|
||||
[this](wxCommandEvent&){ /*m_plater->export_3mf(); */}, "brick_go.png");
|
||||
[this](wxCommandEvent&){ m_plater->export_3mf(); }, "brick_go.png");
|
||||
}
|
||||
|
||||
// Window menu
|
||||
|
|
|
@ -97,8 +97,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
|||
void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field)
|
||||
{
|
||||
if (!m_show_modified_btns) {
|
||||
field->m_Undo_btn->Hide();
|
||||
field->m_Undo_to_sys_btn->Hide();
|
||||
field->m_Undo_btn->set_as_hidden();
|
||||
field->m_Undo_to_sys_btn->set_as_hidden();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,6 +123,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
for (auto opt : option_set)
|
||||
m_options.emplace(opt.opt_id, opt);
|
||||
|
||||
// add mode value for current line to m_options_mode
|
||||
if (!option_set.empty())
|
||||
m_options_mode.push_back(option_set[0].opt.mode);
|
||||
|
||||
// if we have a single option with no label, no sidetext just add it directly to sizer
|
||||
if (option_set.size() == 1 && label_width == 0 && option_set.front().opt.full_width &&
|
||||
option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&
|
||||
|
@ -156,16 +160,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
#endif /* __WXGTK__ */
|
||||
|
||||
// if we have an extra column, build it
|
||||
if (extra_column) {
|
||||
if (extra_column) {
|
||||
grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3);
|
||||
}
|
||||
else {
|
||||
// if the callback provides no sizer for the extra cell, put a spacer
|
||||
grid_sizer->AddSpacer(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra_column)
|
||||
grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3);
|
||||
|
||||
// Build a label if we have it
|
||||
wxStaticText* label=nullptr;
|
||||
|
@ -182,16 +178,14 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
label->SetFont(label_font);
|
||||
label->Wrap(label_width); // avoid a Linux/GTK bug
|
||||
if (!line.near_label_widget)
|
||||
grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) |
|
||||
(m_flag == ogSIDE_OPTIONS_VERTICAL ? wxTOP : wxALIGN_CENTER_VERTICAL), 5);
|
||||
grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
|
||||
else {
|
||||
// If we're here, we have some widget near the label
|
||||
// so we need a horizontal sizer to arrange these things
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
|
||||
sizer->Add(line.near_label_widget(parent()), 0, wxRIGHT, 7);
|
||||
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) |
|
||||
(m_flag == ogSIDE_OPTIONS_VERTICAL ? wxTOP : wxALIGN_CENTER_VERTICAL), 5);
|
||||
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
|
||||
}
|
||||
if (line.label_tooltip.compare("") != 0)
|
||||
label->SetToolTip(line.label_tooltip);
|
||||
|
@ -208,7 +202,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
|
||||
// If we're here, we have more than one option or a single option with sidetext
|
||||
// so we need a horizontal sizer to arrange these things
|
||||
auto sizer = new wxBoxSizer(m_flag == ogSIDE_OPTIONS_VERTICAL ? wxVERTICAL : wxHORIZONTAL);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
|
||||
// If we have a single option with no sidetext just add it directly to the grid sizer
|
||||
if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
|
||||
|
@ -227,14 +221,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
|
||||
for (auto opt : option_set) {
|
||||
ConfigOptionDef option = opt.opt;
|
||||
wxSizer* sizer_tmp;
|
||||
if (m_flag == ogSIDE_OPTIONS_VERTICAL){
|
||||
auto sz = new wxFlexGridSizer(1, 3, 2, 2);
|
||||
sz->RemoveGrowableCol(2);
|
||||
sizer_tmp = sz;
|
||||
}
|
||||
else
|
||||
sizer_tmp = sizer;
|
||||
wxSizer* sizer_tmp = sizer;
|
||||
// add label if any
|
||||
if (option.label != "") {
|
||||
wxString str_label = _(option.label);
|
||||
|
@ -260,7 +247,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
auto sidetext = new wxStaticText( parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,
|
||||
wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT);
|
||||
sidetext->SetFont(sidetext_font);
|
||||
sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, m_flag == ogSIDE_OPTIONS_VERTICAL ? 0 : 4);
|
||||
sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
|
||||
field->set_side_text_ptr(sidetext);
|
||||
}
|
||||
|
||||
|
@ -269,13 +256,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
|||
sizer_tmp->Add(opt.side_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
|
||||
}
|
||||
|
||||
if (opt.opt_id != option_set.back().opt_id && m_flag != ogSIDE_OPTIONS_VERTICAL) //! istead of (opt != option_set.back())
|
||||
if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
|
||||
{
|
||||
sizer_tmp->AddSpacer(6);
|
||||
}
|
||||
|
||||
if (m_flag == ogSIDE_OPTIONS_VERTICAL)
|
||||
sizer->Add(sizer_tmp, 0, wxALIGN_RIGHT|wxALL, 0);
|
||||
}
|
||||
// add extra sizers if any
|
||||
for (auto extra_widget : line.get_extra_widgets()) {
|
||||
|
@ -403,6 +387,39 @@ void ConfigOptionsGroup::reload_config(){
|
|||
|
||||
}
|
||||
|
||||
bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) {
|
||||
if (m_options_mode.empty())
|
||||
return true;
|
||||
if (m_grid_sizer->GetEffectiveRowsCount() != m_options_mode.size() &&
|
||||
m_options_mode.size() == 1)
|
||||
return m_options_mode[0] <= mode;
|
||||
|
||||
sizer->ShowItems(true);
|
||||
#ifdef __WXGTK__
|
||||
m_panel->Show(true);
|
||||
m_grid_sizer->Show(true);
|
||||
#endif /* __WXGTK__ */
|
||||
|
||||
int coef = 0;
|
||||
int hidden_row_cnt = 0;
|
||||
const int cols = m_grid_sizer->GetCols();
|
||||
for (auto opt_mode : m_options_mode) {
|
||||
const bool show = opt_mode <= mode;
|
||||
if (!show) {
|
||||
hidden_row_cnt++;
|
||||
for (int i = 0; i < cols; ++i)
|
||||
m_grid_sizer->Show(coef + i, show);
|
||||
}
|
||||
coef+= cols;
|
||||
}
|
||||
|
||||
if (hidden_row_cnt == m_options_mode.size()) {
|
||||
sizer->ShowItems(false);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize){
|
||||
|
||||
if (deserialize) {
|
||||
|
|
|
@ -27,11 +27,6 @@
|
|||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
enum ogDrawFlag{
|
||||
ogDEFAULT,
|
||||
ogSIDE_OPTIONS_VERTICAL
|
||||
};
|
||||
|
||||
/// Widget type describes a function object that returns a wxWindow (our widget) and accepts a wxWidget (parent window).
|
||||
using widget_t = std::function<wxSizer*(wxWindow*)>;//!std::function<wxWindow*(wxWindow*)>;
|
||||
|
||||
|
@ -151,7 +146,6 @@ public:
|
|||
|
||||
inline void enable() { for (auto& field : m_fields) field.second->enable(); }
|
||||
inline void disable() { for (auto& field : m_fields) field.second->disable(); }
|
||||
void set_flag(ogDrawFlag flag) { m_flag = flag; }
|
||||
void set_grid_vgap(int gap) { m_grid_sizer->SetVGap(gap); }
|
||||
|
||||
void set_show_modified_btns_val(bool show) {
|
||||
|
@ -159,9 +153,10 @@ public:
|
|||
}
|
||||
|
||||
OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false,
|
||||
ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) :
|
||||
m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt),
|
||||
staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){
|
||||
column_t extra_clmn = nullptr) :
|
||||
m_parent(_parent), title(title),
|
||||
m_show_modified_btns(is_tab_opt),
|
||||
staticbox(title!=""), extra_column(extra_clmn){
|
||||
if (staticbox) {
|
||||
stb = new wxStaticBox(_parent, wxID_ANY, title);
|
||||
stb->SetFont(wxGetApp().bold_font());
|
||||
|
@ -172,7 +167,7 @@ public:
|
|||
if (extra_column != nullptr) num_columns++;
|
||||
m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0);
|
||||
static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/);
|
||||
static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width != 0);
|
||||
static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width == 0 ? 0 : !extra_column ? 1 : 2 );
|
||||
#ifdef __WXGTK__
|
||||
m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
sizer->Fit(m_panel);
|
||||
|
@ -187,6 +182,7 @@ public:
|
|||
protected:
|
||||
std::map<t_config_option_key, Option> m_options;
|
||||
wxWindow* m_parent {nullptr};
|
||||
std::vector<ConfigOptionMode> m_options_mode;
|
||||
|
||||
/// Field list, contains unique_ptrs of the derived type.
|
||||
/// using types that need to know what it is beyond the public interface
|
||||
|
@ -197,8 +193,6 @@ protected:
|
|||
// "true" if option is created in preset tabs
|
||||
bool m_show_modified_btns{ false };
|
||||
|
||||
ogDrawFlag m_flag{ ogDEFAULT };
|
||||
|
||||
// This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox
|
||||
// Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel
|
||||
// inside it before you insert the other controls.
|
||||
|
@ -223,8 +217,8 @@ protected:
|
|||
class ConfigOptionsGroup: public OptionsGroup {
|
||||
public:
|
||||
ConfigOptionsGroup( wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr,
|
||||
bool is_tab_opt = false, ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) :
|
||||
OptionsGroup(parent, title, is_tab_opt, flag, extra_clmn), m_config(_config) {}
|
||||
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
|
||||
OptionsGroup(parent, title, is_tab_opt, extra_clmn), m_config(_config) {}
|
||||
|
||||
/// reference to libslic3r config, non-owning pointer (?).
|
||||
DynamicPrintConfig* m_config {nullptr};
|
||||
|
@ -252,6 +246,8 @@ public:
|
|||
void back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key);
|
||||
void on_kill_focus() override{ reload_config();}
|
||||
void reload_config();
|
||||
// return value shows visibility : false => all options are hidden
|
||||
bool update_visibility(ConfigOptionMode mode);
|
||||
boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize);
|
||||
// return option value from config
|
||||
boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);
|
||||
|
|
|
@ -701,7 +701,7 @@ private:
|
|||
static const std::regex pattern_drop;
|
||||
};
|
||||
|
||||
const std::regex PlaterDropTarget::pattern_drop("[.](stl|obj|amf|3mf|prusa)$", std::regex::icase);
|
||||
const std::regex PlaterDropTarget::pattern_drop(".*[.](stl|obj|amf|3mf|prusa)", std::regex::icase);
|
||||
|
||||
bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
|
||||
{
|
||||
|
@ -783,13 +783,19 @@ struct Plater::priv
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
void selection_changed();
|
||||
void object_list_changed();
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void select_view();
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
void remove(size_t obj_idx);
|
||||
void reset();
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void rotate();
|
||||
void mirror(const Axis &axis);
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
void mirror(Axis axis);
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void scale();
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
void arrange();
|
||||
void split_object();
|
||||
void schedule_background_process();
|
||||
|
@ -844,12 +850,17 @@ private:
|
|||
bool can_split_object() const;
|
||||
bool can_cut_object() const;
|
||||
bool layers_height_allowed() const;
|
||||
bool can_delete_all() const;
|
||||
bool can_arrange() const;
|
||||
#if ENABLE_MIRROR
|
||||
bool can_mirror() const;
|
||||
#endif // ENABLE_MIRROR
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
};
|
||||
|
||||
const std::regex Plater::priv::pattern_bundle("[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)$", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_3mf("[.]3mf$", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_zip_amf("[.]zip[.]amf$", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_3mf(".*3mf", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_zip_amf(".*[.]zip[.]amf", std::regex::icase);
|
||||
|
||||
Plater::priv::priv(Plater *q, MainFrame *main_frame) :
|
||||
q(q),
|
||||
|
@ -925,9 +936,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) :
|
|||
canvas3D->Bind(EVT_GLCANVAS_MODEL_UPDATE, &priv::on_model_update, this);
|
||||
canvas3D->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); });
|
||||
canvas3D->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); });
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
canvas3D->Bind(EVT_GLCANVAS_ROTATE_OBJECT, [this](Event<int> &evt) { /*TODO: call rotate */ });
|
||||
canvas3D->Bind(EVT_GLCANVAS_SCALE_UNIFORMLY, [this](SimpleEvent&) { scale(); });
|
||||
canvas3D->Bind(EVT_GLCANVAS_INCREASE_OBJECTS, [q](Event<int> &evt) { evt.data == 1 ? q->increase() : q->decrease(); });
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
canvas3D->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [q](Event<int> &evt) { evt.data == 1 ? q->increase_instances() : q->decrease_instances(); });
|
||||
canvas3D->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
|
||||
canvas3D->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
|
||||
canvas3D->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, &priv::on_enable_action_buttons, this);
|
||||
|
@ -937,8 +950,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) :
|
|||
canvas3D->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); } );
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); });
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); });
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase(); });
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease(); });
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); });
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); });
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_SPLIT, &priv::on_action_split, this);
|
||||
canvas3D->Bind(EVT_GLTOOLBAR_CUT, &priv::on_action_cut, this);
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
|
@ -1092,6 +1105,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path> &input_
|
|||
// $self->async_apply_config;
|
||||
} else {
|
||||
model = Slic3r::Model::read_from_file(path.string(), nullptr, false);
|
||||
for (auto obj : model.objects)
|
||||
if (obj->name.empty())
|
||||
obj->name = fs::path(obj->input_file).filename().string();
|
||||
}
|
||||
}
|
||||
catch (const std::runtime_error &e) {
|
||||
|
@ -1139,7 +1155,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path> &input_
|
|||
new_model->convert_multipart_object(nozzle_dmrs->values.size());
|
||||
}
|
||||
|
||||
auto loaded_idxs = load_model_objects(model.objects);
|
||||
auto loaded_idxs = load_model_objects(new_model->objects);
|
||||
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
|
||||
}
|
||||
|
||||
|
@ -1159,7 +1175,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
|||
bool scaled_down = false;
|
||||
std::vector<size_t> obj_idxs;
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
unsigned int obj_count = 0;
|
||||
unsigned int obj_count = model.objects.size();
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
for (ModelObject *model_object : model_objects) {
|
||||
|
@ -1238,7 +1254,8 @@ std::unique_ptr<CheckboxFileDialog> Plater::priv::get_export_file(GUI::FileType
|
|||
case FT_STL:
|
||||
case FT_AMF:
|
||||
case FT_3MF:
|
||||
wildcard = file_wildcards[FT_STL];
|
||||
case FT_GCODE:
|
||||
wildcard = file_wildcards[file_type];
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1342,7 +1359,7 @@ void Plater::priv::selection_changed()
|
|||
_3DScene::enable_toolbar_item(canvas3D, "split", have_sel);
|
||||
_3DScene::enable_toolbar_item(canvas3D, "cut", have_sel);
|
||||
_3DScene::enable_toolbar_item(canvas3D, "settings", have_sel);
|
||||
_3DScene::enable_toolbar_item(canvas3D, "layersediting", layers_height_allowed);
|
||||
_3DScene::enable_toolbar_item(canvas3D, "layersediting", have_sel && config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D));
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
|
@ -1421,25 +1438,31 @@ void Plater::priv::object_list_changed()
|
|||
{
|
||||
// Enable/disable buttons depending on whether there are any objects on the platter.
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
const bool have_objects = !model.objects.empty();
|
||||
_3DScene::enable_toolbar_item(canvas3D, "deleteall", can_delete_all());
|
||||
_3DScene::enable_toolbar_item(canvas3D, "arrange", can_arrange());
|
||||
#else
|
||||
const bool have_objects = !objects.empty();
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
_3DScene::enable_toolbar_item(canvas3D, "deleteall", have_objects);
|
||||
_3DScene::enable_toolbar_item(canvas3D, "arrange", have_objects);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
const bool export_in_progress = !(export_gcode_output_file.empty() && send_gcode_file.empty());
|
||||
// XXX: is this right?
|
||||
const bool model_fits = _3DScene::check_volumes_outside_state(canvas3D, config) == ModelInstance::PVS_Inside;
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits);
|
||||
#else
|
||||
sidebar->enable_buttons(have_objects && !export_in_progress && model_fits);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void Plater::priv::select_view()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
void Plater::priv::remove(size_t obj_idx)
|
||||
{
|
||||
|
@ -1448,6 +1471,9 @@ void Plater::priv::remove(size_t obj_idx)
|
|||
// Prevent toolpaths preview from rendering while we modify the Print object
|
||||
preview->set_enabled(false);
|
||||
|
||||
if (_3DScene::is_layers_editing_enabled(canvas3D))
|
||||
_3DScene::enable_layers_editing(canvas3D, false);
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
objects.erase(objects.begin() + obj_idx);
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
@ -1471,6 +1497,9 @@ void Plater::priv::reset()
|
|||
// Prevent toolpaths preview from rendering while we modify the Print object
|
||||
preview->set_enabled(false);
|
||||
|
||||
if (_3DScene::is_layers_editing_enabled(canvas3D))
|
||||
_3DScene::enable_layers_editing(canvas3D, false);
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
objects.clear();
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
@ -1487,13 +1516,20 @@ void Plater::priv::reset()
|
|||
update();
|
||||
}
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void Plater::priv::rotate()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
void Plater::priv::mirror(const Axis &axis)
|
||||
void Plater::priv::mirror(Axis axis)
|
||||
{
|
||||
#if ENABLE_MIRROR
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
_3DScene::mirror_selection(canvas3D, axis);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
#else
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
int obj_idx = get_selected_object_idx();
|
||||
if (obj_idx == -1)
|
||||
|
@ -1526,12 +1562,15 @@ void Plater::priv::mirror(const Axis &axis)
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
selection_changed();
|
||||
update();
|
||||
#endif // ENABLE_MIRROR
|
||||
}
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
void Plater::priv::scale()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
#endif // !ENABLE_EXTENDED_SELECTION
|
||||
|
||||
void Plater::priv::arrange()
|
||||
{
|
||||
|
@ -1547,7 +1586,45 @@ void Plater::priv::arrange()
|
|||
|
||||
void Plater::priv::split_object()
|
||||
{
|
||||
// TODO
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
int obj_idx = get_selected_object_idx();
|
||||
if (obj_idx == -1)
|
||||
return;
|
||||
|
||||
// we clone model object because split_object() adds the split volumes
|
||||
// into the same model object, thus causing duplicates when we call load_model_objects()
|
||||
Model new_model = model;
|
||||
ModelObject* current_model_object = new_model.objects[obj_idx];
|
||||
|
||||
if (current_model_object->volumes.size() > 1)
|
||||
{
|
||||
Slic3r::GUI::warning_catcher(q, _(L("The selected object can't be split because it contains more than one volume/material.")));
|
||||
return;
|
||||
}
|
||||
|
||||
// $self->stop_background_process;
|
||||
|
||||
ModelObjectPtrs new_objects;
|
||||
current_model_object->split(&new_objects);
|
||||
if (new_objects.size() == 1)
|
||||
{
|
||||
Slic3r::GUI::warning_catcher(q, _(L("The selected object couldn't be split because it contains only one part.")));
|
||||
// $self->schedule_background_process;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ModelObject* m : new_objects)
|
||||
{
|
||||
m->center_around_origin();
|
||||
}
|
||||
|
||||
remove(obj_idx);
|
||||
|
||||
// load all model objects at once, otherwise the plate would be rearranged after each one
|
||||
// causing original positions not to be kept
|
||||
load_model_objects(new_objects);
|
||||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
|
||||
void Plater::priv::schedule_background_process()
|
||||
|
@ -1821,7 +1898,7 @@ void Plater::priv::on_action_add(SimpleEvent&)
|
|||
|
||||
void Plater::priv::on_action_split(SimpleEvent&)
|
||||
{
|
||||
// TODO
|
||||
split_object();
|
||||
}
|
||||
|
||||
void Plater::priv::on_action_cut(SimpleEvent&)
|
||||
|
@ -1838,7 +1915,10 @@ void Plater::priv::on_action_settings(SimpleEvent&)
|
|||
|
||||
void Plater::priv::on_action_layersediting(SimpleEvent&)
|
||||
{
|
||||
// TODO
|
||||
bool enable = !_3DScene::is_layers_editing_enabled(canvas3D);
|
||||
_3DScene::enable_layers_editing(canvas3D, enable);
|
||||
if (enable && !_3DScene::is_layers_editing_enabled(canvas3D))
|
||||
_3DScene::enable_toolbar_item(canvas3D, "layersediting", false);
|
||||
}
|
||||
|
||||
#if !ENABLE_EXTENDED_SELECTION
|
||||
|
@ -1958,17 +2038,41 @@ bool Plater::priv::init_object_menu()
|
|||
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");
|
||||
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(); }, "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")),
|
||||
[this](wxCommandEvent&){ q->decrease(); }, "delete.png");
|
||||
[this](wxCommandEvent&){ q->decrease_instances(); }, "delete.png");
|
||||
|
||||
object_menu.AppendSeparator();
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
wxMenu* mirror_menu = new wxMenu();
|
||||
if (mirror_menu == nullptr)
|
||||
return false;
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
wxMenuItem* item_mirror = append_submenu(&object_menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object")));
|
||||
#endif // ENABLE_MIRROR
|
||||
|
||||
wxMenuItem* item_split = append_menu_item(&object_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual parts")),
|
||||
[this](wxCommandEvent&){ split_object(); }, "shape_ungroup.png");
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
// ui updates needs to be binded to the parent panel
|
||||
if (q != nullptr)
|
||||
{
|
||||
#if ENABLE_MIRROR
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_mirror()); }, item_mirror->GetId());
|
||||
#endif // ENABLE_MIRROR
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete_object()); }, item_delete->GetId());
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_increase_instances()); }, item_increase->GetId());
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_decrease_instances()); }, item_decrease->GetId());
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_split_object()); }, item_split->GetId());
|
||||
}
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
|
@ -1997,7 +2101,7 @@ bool Plater::priv::can_decrease_instances() const
|
|||
bool Plater::priv::can_split_object() const
|
||||
{
|
||||
int obj_idx = get_selected_object_idx();
|
||||
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size());
|
||||
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && !model.objects[obj_idx]->is_multiparts();
|
||||
}
|
||||
|
||||
bool Plater::priv::can_cut_object() const
|
||||
|
@ -2008,8 +2112,26 @@ bool Plater::priv::can_cut_object() const
|
|||
|
||||
bool Plater::priv::layers_height_allowed() const
|
||||
{
|
||||
return config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D);
|
||||
int obj_idx = get_selected_object_idx();
|
||||
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D);
|
||||
}
|
||||
|
||||
bool Plater::priv::can_delete_all() const
|
||||
{
|
||||
return !model.objects.empty();
|
||||
}
|
||||
|
||||
bool Plater::priv::can_arrange() const
|
||||
{
|
||||
return !model.objects.empty();
|
||||
}
|
||||
|
||||
#if ENABLE_MIRROR
|
||||
bool Plater::priv::can_mirror() const
|
||||
{
|
||||
return get_selection().is_from_single_instance();
|
||||
}
|
||||
#endif // ENABLE_MIRROR
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
// Plater / Public
|
||||
|
@ -2063,7 +2185,7 @@ void Plater::remove_selected()
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
}
|
||||
|
||||
void Plater::increase(size_t num)
|
||||
void Plater::increase_instances(size_t num)
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
int obj_idx = p->get_selected_object_idx();
|
||||
|
@ -2105,12 +2227,16 @@ void Plater::increase(size_t num)
|
|||
p->update();
|
||||
}
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
p->get_selection().add_instance(obj_idx, (int)model_object->instances.size() - 1);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
p->selection_changed();
|
||||
|
||||
this->p->schedule_background_process();
|
||||
}
|
||||
|
||||
void Plater::decrease(size_t num)
|
||||
void Plater::decrease_instances(size_t num)
|
||||
{
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
int obj_idx = p->get_selected_object_idx();
|
||||
|
@ -2148,6 +2274,12 @@ void Plater::decrease(size_t num)
|
|||
}
|
||||
|
||||
p->update();
|
||||
|
||||
#if ENABLE_EXTENDED_SELECTION
|
||||
if (!model_object->instances.empty())
|
||||
p->get_selection().add_instance(obj_idx, (int)model_object->instances.size() - 1);
|
||||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
p->selection_changed();
|
||||
|
||||
// $self->schedule_background_process;
|
||||
|
@ -2169,11 +2301,10 @@ void Plater::set_number_of_copies(size_t num)
|
|||
#endif // ENABLE_EXTENDED_SELECTION
|
||||
|
||||
int diff = (int)num - (int)model_object->instances.size();
|
||||
if (diff > 0) {
|
||||
increase(diff);
|
||||
} else if (diff < 0) {
|
||||
decrease(-diff);
|
||||
}
|
||||
if (diff > 0)
|
||||
increase_instances(diff);
|
||||
else if (diff < 0)
|
||||
decrease_instances(-diff);
|
||||
}
|
||||
|
||||
fs::path Plater::export_gcode(const fs::path &output_path)
|
||||
|
|
|
@ -113,8 +113,8 @@ public:
|
|||
|
||||
void remove(size_t obj_idx);
|
||||
void remove_selected();
|
||||
void increase(size_t num = 1);
|
||||
void decrease(size_t num = 1);
|
||||
void increase_instances(size_t num = 1);
|
||||
void decrease_instances(size_t num = 1);
|
||||
void set_number_of_copies(size_t num);
|
||||
|
||||
// Note: empty path means "use the default"
|
||||
|
|
|
@ -476,14 +476,14 @@ void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool
|
|||
void Tab::update_changed_tree_ui()
|
||||
{
|
||||
auto cur_item = m_treectrl->GetFirstVisibleItem();
|
||||
if (!m_treectrl->IsVisible(cur_item))
|
||||
if (!cur_item || !m_treectrl->IsVisible(cur_item))
|
||||
return;
|
||||
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
|
||||
while (cur_item){
|
||||
auto title = m_treectrl->GetItemText(cur_item);
|
||||
for (auto page : m_pages)
|
||||
{
|
||||
if (page->title() != title)
|
||||
if (page->title() != title)
|
||||
continue;
|
||||
bool sys_page = true;
|
||||
bool modified_page = false;
|
||||
|
@ -632,6 +632,25 @@ void Tab::reload_config(){
|
|||
Thaw();
|
||||
}
|
||||
|
||||
void Tab::update_visibility(ConfigOptionMode mode)
|
||||
{
|
||||
Freeze();
|
||||
|
||||
for (auto page : m_pages)
|
||||
page->update_visibility(mode);
|
||||
update_page_tree_visibility();
|
||||
|
||||
m_hsizer->Layout();
|
||||
Refresh();
|
||||
|
||||
Thaw();
|
||||
|
||||
// to update tree items color
|
||||
wxTheApp->CallAfter([this]() {
|
||||
update_changed_tree_ui();
|
||||
});
|
||||
}
|
||||
|
||||
Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const
|
||||
{
|
||||
Field* field = nullptr;
|
||||
|
@ -1021,7 +1040,7 @@ void TabPrint::build()
|
|||
|
||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||
line = { _(L("Compatible printers")), "" };
|
||||
line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
|
||||
};
|
||||
|
@ -1347,7 +1366,7 @@ void TabFilament::build()
|
|||
optgroup->append_single_option_line("filament_cooling_final_speed");
|
||||
optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower");
|
||||
|
||||
line = { _(L("Ramming")), "" };
|
||||
line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
@ -1387,7 +1406,7 @@ void TabFilament::build()
|
|||
|
||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||
line = { _(L("Compatible printers")), "" };
|
||||
line = optgroup->create_single_option_line("compatible_printers");//{ _(L("Compatible printers")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
|
||||
};
|
||||
|
@ -1482,7 +1501,7 @@ void TabPrinter::build_fff()
|
|||
auto page = add_options_page(_(L("General")), "printer_empty.png");
|
||||
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
|
||||
|
||||
Line line{ _(L("Bed shape")), "" };
|
||||
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
btn->SetFont(wxGetApp().small_font());
|
||||
|
@ -1514,6 +1533,7 @@ void TabPrinter::build_fff()
|
|||
def.label = L("Extruders");
|
||||
def.tooltip = L("Number of extruders of the printer.");
|
||||
def.min = 1;
|
||||
def.mode = comExpert;
|
||||
Option option(def, "extruders_count");
|
||||
optgroup->append_single_option_line(option);
|
||||
optgroup->append_single_option_line("single_extruder_multi_material");
|
||||
|
@ -1767,7 +1787,7 @@ void TabPrinter::build_sla()
|
|||
auto page = add_options_page(_(L("General")), "printer_empty.png");
|
||||
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
|
||||
|
||||
Line line{ _(L("Bed shape")), "" };
|
||||
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
// btn->SetFont(Slic3r::GUI::small_font);
|
||||
|
@ -2255,6 +2275,33 @@ void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/)
|
|||
Thaw();
|
||||
}
|
||||
|
||||
void Tab::update_page_tree_visibility()
|
||||
{
|
||||
const auto sel_item = m_treectrl->GetSelection();
|
||||
const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : "";
|
||||
const auto rootItem = m_treectrl->GetRootItem();
|
||||
|
||||
auto have_selection = 0;
|
||||
m_treectrl->DeleteChildren(rootItem);
|
||||
for (auto p : m_pages)
|
||||
{
|
||||
if (!p->get_show())
|
||||
continue;
|
||||
auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID());
|
||||
m_treectrl->SetItemTextColour(itemId, p->get_item_colour());
|
||||
if (p->title() == selected) {
|
||||
m_treectrl->SelectItem(itemId);
|
||||
have_selection = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_selection) {
|
||||
// this is triggered on first load, so we don't disable the sel change event
|
||||
m_treectrl->SelectItem(m_treectrl->GetFirstVisibleItem());//! (treectrl->GetFirstChild(rootItem));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Called by the UI combo box when the user switches profiles.
|
||||
// Select a preset by a name.If !defined(name), then the default preset is selected.
|
||||
// If the current profile is modified, user is asked to save the changes.
|
||||
|
@ -2379,10 +2426,13 @@ void Tab::OnTreeSelChange(wxTreeEvent& event)
|
|||
wxWindowUpdateLocker noUpdates(this);
|
||||
#endif
|
||||
|
||||
if (m_pages.empty())
|
||||
return;
|
||||
|
||||
Page* page = nullptr;
|
||||
const auto sel_item = m_treectrl->GetSelection();
|
||||
const auto selection = sel_item ? m_treectrl->GetItemText(sel_item) : "";
|
||||
for (auto p : m_pages)
|
||||
for (auto p : m_pages)
|
||||
if (p->title() == selection)
|
||||
{
|
||||
page = p.get();
|
||||
|
@ -2681,6 +2731,15 @@ void Page::reload_config()
|
|||
group->reload_config();
|
||||
}
|
||||
|
||||
void Page::update_visibility(ConfigOptionMode mode)
|
||||
{
|
||||
bool ret_val = false;
|
||||
for (auto group : m_optgroups)
|
||||
ret_val = group->update_visibility(mode) || ret_val;
|
||||
|
||||
m_show = ret_val;
|
||||
}
|
||||
|
||||
Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const
|
||||
{
|
||||
Field* field = nullptr;
|
||||
|
@ -2704,8 +2763,22 @@ bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value
|
|||
// package Slic3r::GUI::Tab::Page;
|
||||
ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/)
|
||||
{
|
||||
auto extra_column = [](wxWindow* parent, const Line& line)
|
||||
{
|
||||
std::string bmp_name;
|
||||
if (line.get_options().size() == 0)
|
||||
bmp_name = "error.png";
|
||||
else {
|
||||
auto mode = line.get_options()[0].opt.mode; //we assume that we have one option per line
|
||||
bmp_name = mode == comExpert ? "mode_expert_.png" :
|
||||
mode == comMiddle ? "mode_middle_.png" : "mode_simple_.png";
|
||||
}
|
||||
auto bmp = new wxStaticBitmap(parent, wxID_ANY, wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG));
|
||||
return bmp;
|
||||
};
|
||||
|
||||
//! config_ have to be "right"
|
||||
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(this, title, m_config, true);
|
||||
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(this, title, m_config, true, extra_column);
|
||||
if (noncommon_label_width >= 0)
|
||||
optgroup->label_width = noncommon_label_width;
|
||||
|
||||
|
@ -2844,7 +2917,7 @@ void TabSLAMaterial::build()
|
|||
|
||||
page = add_options_page(_(L("Dependencies")), "wrench.png");
|
||||
optgroup = page->new_optgroup(_(L("Profile dependencies")));
|
||||
auto line = Line { _(L("Compatible printers")), "" };
|
||||
Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" };
|
||||
line.widget = [this](wxWindow* parent){
|
||||
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
|
||||
};
|
||||
|
|
|
@ -47,6 +47,7 @@ class Page : public wxScrolledWindow
|
|||
wxString m_title;
|
||||
size_t m_iconID;
|
||||
wxBoxSizer* m_vsizer;
|
||||
bool m_show = true;
|
||||
public:
|
||||
Page(wxWindow* parent, const wxString title, const int iconID) :
|
||||
m_parent(parent),
|
||||
|
@ -73,6 +74,7 @@ public:
|
|||
size_t iconID() const { return m_iconID; }
|
||||
void set_config(DynamicPrintConfig* config_in) { m_config = config_in; }
|
||||
void reload_config();
|
||||
void update_visibility(ConfigOptionMode mode);
|
||||
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
|
||||
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
|
||||
ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1);
|
||||
|
@ -88,6 +90,7 @@ public:
|
|||
const wxColour get_item_colour() {
|
||||
return *m_item_color;
|
||||
}
|
||||
bool get_show() const { return m_show; }
|
||||
|
||||
protected:
|
||||
// Color of TreeCtrlItem. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
|
||||
|
@ -214,6 +217,7 @@ public:
|
|||
void create_preset_tab();
|
||||
void load_current_preset();
|
||||
void rebuild_page_tree(bool tree_sel_change_event = false);
|
||||
void update_page_tree_visibility();
|
||||
void select_preset(std::string preset_name = "");
|
||||
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "");
|
||||
wxSizer* compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn);
|
||||
|
@ -249,6 +253,7 @@ public:
|
|||
void update_tab_ui();
|
||||
void load_config(const DynamicPrintConfig& config);
|
||||
virtual void reload_config();
|
||||
void update_visibility(ConfigOptionMode mode);
|
||||
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
|
||||
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
|
||||
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "GUI_ObjectList.hpp"
|
||||
|
||||
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
|
||||
std::function<void(wxCommandEvent& event)> cb, const std::string& icon)
|
||||
std::function<void(wxCommandEvent& event)> cb, const std::string& icon, wxEvtHandler* event_handler)
|
||||
{
|
||||
if (id == wxID_ANY)
|
||||
id = wxNewId();
|
||||
|
@ -20,7 +20,26 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const
|
|||
if (!icon.empty())
|
||||
item->SetBitmap(wxBitmap(Slic3r::var(icon), wxBITMAP_TYPE_PNG));
|
||||
|
||||
menu->Bind(wxEVT_MENU, cb, id);
|
||||
if (event_handler != nullptr)
|
||||
event_handler->Bind(wxEVT_MENU, cb, id);
|
||||
else
|
||||
menu->Bind(wxEVT_MENU, cb, id);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, const std::string& icon)
|
||||
{
|
||||
if (id == wxID_ANY)
|
||||
id = wxNewId();
|
||||
|
||||
wxMenuItem* item = new wxMenuItem(menu, id, string, description);
|
||||
if (!icon.empty())
|
||||
item->SetBitmap(wxBitmap(Slic3r::var(icon), wxBITMAP_TYPE_PNG));
|
||||
|
||||
item->SetSubMenu(sub_menu);
|
||||
menu->Append(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
@ -770,7 +789,7 @@ void PrusaObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType&
|
|||
type = itUndef;
|
||||
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
if (!node || node->GetIdx() < 0 && node->GetType() != itObject)
|
||||
if (!node || node->GetIdx() < 0 && !(node->GetType() & (itObject|itSettings|itInstanceRoot)))
|
||||
return;
|
||||
|
||||
idx = node->GetIdx();
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
|
||||
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
|
||||
std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "");
|
||||
std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr);
|
||||
|
||||
wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, const std::string& icon = "");
|
||||
|
||||
class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
|
||||
{
|
||||
|
@ -259,7 +262,10 @@ public:
|
|||
m_name = "Settings to modified";
|
||||
}
|
||||
else if (type == itInstanceRoot) {
|
||||
m_name = "Instances";
|
||||
m_name = "Instances";
|
||||
#ifdef __WXGTK__
|
||||
m_container = true;
|
||||
#endif //__WXGTK__
|
||||
}
|
||||
else if (type == itInstance) {
|
||||
m_idx = parent->GetChildCount();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue