Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/libslic3r/Slicing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,35 @@ std::vector<coordf_t> layer_height_profile_from_ranges(
return layer_height_profile;
}

std::vector<coordf_t> layer_height_profile_from_other_object(const std::vector<coordf_t> &other_layer_height_profile, coordf_t object_height, coordf_t layer_height)
{
std::vector<coordf_t> out;
out.reserve(other_layer_height_profile.size() + 4);

size_t i = 0;
for (; i + 1 < other_layer_height_profile.size() && other_layer_height_profile[i] < object_height - EPSILON; i += 2) {
out.push_back(other_layer_height_profile[i]);
out.push_back(other_layer_height_profile[i + 1]);
}
if (out.empty())
return out;

const coordf_t z = *(out.end() - 2);
coordf_t height = layer_height;
if (i + 1 < other_layer_height_profile.size())
// The other object is the taller one, cut its last step where this object ends.
height = lerp(out.back(), other_layer_height_profile[i + 1], (object_height - z) / (other_layer_height_profile[i] - z));
else if (!is_approx(out.back(), layer_height)) {
// Step back to the default layer height for the part standing above the other object.
out.push_back(z);
out.push_back(layer_height);
}
out.push_back(object_height);
out.push_back(height);

return out;
}

// Based on the work of @platsch
// Fill layer_height_profile by heights ensuring a prescribed maximum cusp height.
std::vector<double> layer_height_profile_adaptive(const SlicingParameters& slicing_params, const ModelObject& object, float quality_factor)
Expand Down
6 changes: 6 additions & 0 deletions src/libslic3r/Slicing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ extern std::vector<double> layer_height_profile_adaptive(
const SlicingParameters& slicing_params,
const ModelObject& object, float quality_factor);

// Reproduce the layer heights of another object up to its top, the layers above it keep the default layer height.
extern std::vector<coordf_t> layer_height_profile_from_other_object(
const std::vector<coordf_t> &other_layer_height_profile,
coordf_t object_height,
coordf_t layer_height);

struct HeightProfileSmoothingParams
{
unsigned int radius;
Expand Down
10 changes: 10 additions & 0 deletions src/slic3r/GUI/GUI_Factories.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,8 @@ void MenuFactory::create_bbl_object_menu()
append_menu_item_per_object_process(&m_object_menu);
// Enter per object parameters
append_menu_item_per_object_settings(&m_object_menu);
// Share the layer heights with the other objects of the plate
append_menu_item_apply_layer_height(&m_object_menu);
m_object_menu.AppendSeparator();
append_menu_item_reload_from_disk(&m_object_menu);
append_menu_item_replace_with_stl(&m_object_menu);
Expand Down Expand Up @@ -2353,6 +2355,14 @@ void MenuFactory::append_menu_item_per_object_settings(wxMenu* menu)
}, m_parent);
}

void MenuFactory::append_menu_item_apply_layer_height(wxMenu* menu)
{
append_menu_item(menu, wxID_ANY, _L("Apply layer height to other objects"),
_L("Slice the other objects of this plate with the layer heights of the selected object, as required by the prime tower"),
[](wxCommandEvent&) { obj_list()->apply_layer_height_to_other_objects(); }, "", nullptr,
[]() { return obj_list()->can_apply_layer_height_to_other_objects(); }, m_parent);
}

void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
{
const std::vector<wxString> names = { _L("Change Filament"), _L("Set Filament for selected items") };
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/GUI_Factories.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class MenuFactory
void append_menu_item_sub_merge(wxMenu *menu);
void append_menu_item_per_object_process(wxMenu* menu);
void append_menu_item_per_object_settings(wxMenu* menu);
void append_menu_item_apply_layer_height(wxMenu* menu);
void append_menu_item_change_filament(wxMenu* menu);
void append_menu_item_set_printable(wxMenu* menu);
void append_menu_item_locked(wxMenu* menu);
Expand Down
47 changes: 47 additions & 0 deletions src/slic3r/GUI/GUI_ObjectList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,53 @@ void ObjectList::paste_layers_into_list()
#endif //no __WXOSX__
}

bool ObjectList::can_apply_layer_height_to_other_objects() const
{
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
return get_selected_obj_idx() >= 0 && plate->get_obj_idxs_on_this_plate().size() > 1;
}

void ObjectList::apply_layer_height_to_other_objects()
{
const int obj_idx = get_selected_obj_idx();
if (obj_idx < 0 || (size_t)obj_idx >= m_objects->size())
return;

take_snapshot("Apply layer height to other objects");

PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
const ModelObject* from_object = object(obj_idx);
const ConfigOption* layer_height_option = from_object->config.option("layer_height");
const coordf_t layer_height = layer_height_option ? layer_height_option->getFloat() :
wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("layer_height");

std::vector<size_t> changed_idxs;
for (int idx : plate->get_obj_idxs_on_this_plate()) {
if (idx == obj_idx)
continue;

ModelObject* to_object = object(idx);
if (layer_height_option)
to_object->config.set_key_value("layer_height", layer_height_option->clone());
else
to_object->config.erase("layer_height");
to_object->layer_config_ranges = from_object->layer_config_ranges;
to_object->layer_height_profile.set(layer_height_profile_from_other_object(from_object->layer_height_profile.get(),
to_object->bounding_box().max.z(), layer_height));

const wxDataViewItem object_item = m_objects_model->GetItemById(idx);
if (wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(object_item))
m_objects_model->Delete(layers_item);
add_layer_root_item(object_item);
add_settings_item(object_item, &to_object->config.get());
update_info_items(idx);

changed_idxs.push_back(idx);
}

wxGetApp().plater()->changed_objects(changed_idxs);
}

void ObjectList::copy_settings_to_clipboard()
{
wxDataViewItem item = GetSelection();
Expand Down
2 changes: 2 additions & 0 deletions src/slic3r/GUI/GUI_ObjectList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ class ObjectList : public wxDataViewCtrl

void copy_layers_to_clipboard();
void paste_layers_into_list();
bool can_apply_layer_height_to_other_objects() const;
void apply_layer_height_to_other_objects();
void copy_settings_to_clipboard();
void paste_settings_into_list();
bool can_paste_settings_into_list();
Expand Down
9 changes: 9 additions & 0 deletions src/slic3r/GUI/PartPlate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2549,6 +2549,15 @@ ModelObjectPtrs PartPlate::get_objects_on_this_plate() {
return objects_ptr;
}

std::set<int> PartPlate::get_obj_idxs_on_this_plate()
{
std::set<int> obj_idxs;
for (auto it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); it++) {
obj_idxs.insert(it->first);
}
return obj_idxs;
}

ModelInstance* PartPlate::get_instance(int obj_id, int instance_id)
{
if (!contain_instance(obj_id, instance_id))
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/PartPlate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ class PartPlate : public ObjectBase
Vec2d get_size() const { return Vec2d(m_width, m_depth); }
ModelObjectPtrs get_objects() { return m_model->objects; }
ModelObjectPtrs get_objects_on_this_plate();
std::set<int> get_obj_idxs_on_this_plate();
std::set<std::pair<int, int>>& get_obj_and_inst_set() { return obj_to_instance_set; }
std::set<std::pair<int, int>>& get_obj_and_inst_outside_set() { return instance_outside_set; }
ModelInstance* get_instance(int obj_id, int instance_id);
Expand Down