This commit is contained in:
Enrico Turri 2019-09-19 14:03:05 +02:00
commit 0de8245432
4 changed files with 126 additions and 34 deletions

View File

@ -279,6 +279,7 @@ void ObjectList::create_popup_menus()
create_part_popupmenu(&m_menu_part); create_part_popupmenu(&m_menu_part);
create_sla_object_popupmenu(&m_menu_sla_object); create_sla_object_popupmenu(&m_menu_sla_object);
create_instance_popupmenu(&m_menu_instance); create_instance_popupmenu(&m_menu_instance);
create_default_popupmenu(&m_menu_default);
} }
void ObjectList::get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& input_item/* = wxDataViewItem(nullptr)*/) void ObjectList::get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& input_item/* = wxDataViewItem(nullptr)*/)
@ -783,18 +784,23 @@ void ObjectList::OnChar(wxKeyEvent& event)
void ObjectList::OnContextMenu(wxDataViewEvent&) void ObjectList::OnContextMenu(wxDataViewEvent&)
{ {
list_manipulation(); list_manipulation(true);
} }
void ObjectList::list_manipulation() void ObjectList::list_manipulation(bool evt_context_menu/* = false*/)
{ {
wxDataViewItem item; wxDataViewItem item;
wxDataViewColumn* col = nullptr; wxDataViewColumn* col = nullptr;
const wxPoint pt = get_mouse_position_in_control(); const wxPoint pt = get_mouse_position_in_control();
HitTest(pt, item, col); HitTest(pt, item, col);
if (!item || col == nullptr) { if (!item) {
if (col == nullptr)
return; return;
if (evt_context_menu) {
show_context_menu(evt_context_menu);
return;
}
} }
const wxString title = col->GetTitle(); const wxString title = col->GetTitle();
@ -802,7 +808,7 @@ void ObjectList::list_manipulation()
if (title == " ") if (title == " ")
toggle_printable_state(item); toggle_printable_state(item);
else if (title == _("Editing")) else if (title == _("Editing"))
show_context_menu(); show_context_menu(evt_context_menu);
else if (title == _("Name")) else if (title == _("Name"))
{ {
int obj_idx, vol_idx; int obj_idx, vol_idx;
@ -818,7 +824,7 @@ void ObjectList::list_manipulation()
#endif //__WXMSW__ #endif //__WXMSW__
} }
void ObjectList::show_context_menu() void ObjectList::show_context_menu(const bool evt_context_menu)
{ {
if (multiple_selection()) if (multiple_selection())
{ {
@ -831,22 +837,26 @@ void ObjectList::show_context_menu()
} }
const auto item = GetSelection(); const auto item = GetSelection();
wxMenu* menu {nullptr};
if (item) if (item)
{ {
const ItemType type = m_objects_model->GetItemType(item); const ItemType type = m_objects_model->GetItemType(item);
if (!(type & (itObject | itVolume | itLayer | itInstance))) if (!(type & (itObject | itVolume | itLayer | itInstance)))
return; return;
wxMenu* menu = type & itInstance ? &m_menu_instance : menu = type & itInstance ? &m_menu_instance :
type & itLayer ? &m_menu_layer : type & itLayer ? &m_menu_layer :
m_objects_model->GetParent(item) != wxDataViewItem(nullptr) ? &m_menu_part : m_objects_model->GetParent(item) != wxDataViewItem(nullptr) ? &m_menu_part :
printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object;
if (!(type & itInstance)) if (!(type & itInstance))
append_menu_item_settings(menu); append_menu_item_settings(menu);
wxGetApp().plater()->PopupMenu(menu);
} }
else if (evt_context_menu)
menu = &m_menu_default;
if (menu)
wxGetApp().plater()->PopupMenu(menu);
} }
void ObjectList::copy() void ObjectList::copy()
@ -1286,13 +1296,16 @@ void ObjectList::show_settings(const wxDataViewItem settings_item)
wxMenu* ObjectList::append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type) { wxMenu* ObjectList::append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type) {
auto sub_menu = new wxMenu; auto sub_menu = new wxMenu;
if (wxGetApp().get_mode() == comExpert) { if (wxGetApp().get_mode() == comExpert && type != ModelVolumeType::INVALID) {
append_menu_item(sub_menu, wxID_ANY, _(L("Load")) + " " + dots, "", append_menu_item(sub_menu, wxID_ANY, _(L("Load")) + " " + dots, "",
[this, type](wxCommandEvent&) { load_subobject(type); }, "", menu); [this, type](wxCommandEvent&) { load_subobject(type); }, "", menu);
sub_menu->AppendSeparator(); sub_menu->AppendSeparator();
} }
for (auto& item : { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }) { for (auto& item : { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") })
{
if (type == ModelVolumeType::INVALID && item == "Slab")
continue;
append_menu_item(sub_menu, wxID_ANY, _(item), "", append_menu_item(sub_menu, wxID_ANY, _(item), "",
[this, type, item](wxCommandEvent&) { load_generic_subobject(item, type); }, "", menu); [this, type, item](wxCommandEvent&) { load_generic_subobject(item, type); }, "", menu);
} }
@ -1579,6 +1592,12 @@ void ObjectList::create_instance_popupmenu(wxMenu*menu)
}, m_menu_item_split_instances->GetId()); }, m_menu_item_split_instances->GetId());
} }
void ObjectList::create_default_popupmenu(wxMenu*menu)
{
wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType::INVALID);
append_submenu(menu, sub_menu, wxID_ANY, _(L("Add Shape")), "", "add_part");
}
wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu)
{ {
wxMenu *menu = new wxMenu; wxMenu *menu = new wxMenu;
@ -1717,8 +1736,38 @@ void ObjectList::load_part( ModelObject* model_object,
} }
static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf3& bb)
{
TriangleMesh mesh;
const double side = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.1);
if (type_name == "Box")
// Sitting on the print bed, left front front corner at (0, 0).
mesh = make_cube(side, side, side);
else if (type_name == "Cylinder")
// Centered around 0, sitting on the print bed.
// The cylinder has the same volume as the box above.
mesh = make_cylinder(0.564 * side, side);
else if (type_name == "Sphere")
// Centered around 0, half the sphere below the print bed, half above.
// The sphere has the same volume as the box above.
mesh = make_sphere(0.62 * side, PI / 18);
else if (type_name == "Slab")
// Sitting on the print bed, left front front corner at (0, 0).
mesh = make_cube(bb.size().x() * 1.5, bb.size().y() * 1.5, bb.size().z() * 0.5);
mesh.repair();
return mesh;
}
void ObjectList::load_generic_subobject(const std::string& type_name, const ModelVolumeType type) void ObjectList::load_generic_subobject(const std::string& type_name, const ModelVolumeType type)
{ {
if (type == ModelVolumeType::INVALID) {
load_shape_object(type_name);
return;
}
const int obj_idx = get_selected_obj_idx(); const int obj_idx = get_selected_obj_idx();
if (obj_idx < 0) if (obj_idx < 0)
return; return;
@ -1741,26 +1790,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
// Bounding box of the selected instance in world coordinate system including the translation, without modifiers. // Bounding box of the selected instance in world coordinate system including the translation, without modifiers.
BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx); BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx);
const wxString name = _(L("Generic")) + "-" + _(type_name); TriangleMesh mesh = create_mesh(type_name, instance_bb);
TriangleMesh mesh;
double side = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.1);
if (type_name == "Box")
// Sitting on the print bed, left front front corner at (0, 0).
mesh = make_cube(side, side, side);
else if (type_name == "Cylinder")
// Centered around 0, sitting on the print bed.
// The cylinder has the same volume as the box above.
mesh = make_cylinder(0.564 * side, side);
else if (type_name == "Sphere")
// Centered around 0, half the sphere below the print bed, half above.
// The sphere has the same volume as the box above.
mesh = make_sphere(0.62 * side, PI / 18);
else if (type_name == "Slab")
// Sitting on the print bed, left front front corner at (0, 0).
mesh = make_cube(instance_bb.size().x()*1.5, instance_bb.size().y()*1.5, instance_bb.size().z()*0.5);
mesh.repair();
// Mesh will be centered when loading. // Mesh will be centered when loading.
ModelVolume *new_volume = model_object.add_volume(std::move(mesh)); ModelVolume *new_volume = model_object.add_volume(std::move(mesh));
@ -1782,6 +1812,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset); new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
} }
const wxString name = _(L("Generic")) + "-" + _(type_name);
new_volume->name = into_u8(name); new_volume->name = into_u8(name);
// set a default extruder value, since user can't add it manually // set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
@ -1799,6 +1830,57 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
#endif //no __WXOSX__ //__WXMSW__ #endif //no __WXOSX__ //__WXMSW__
} }
void ObjectList::load_shape_object(const std::string& type_name)
{
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
assert(selection.get_object_idx() == -1); // Add nothing is something is selected on 3DScene
if (selection.get_object_idx() != -1)
return;
const int obj_idx = m_objects->size();
if (obj_idx < 0)
return;
take_snapshot(_(L("Add Shape")));
// Create mesh
BoundingBoxf3 bb;
TriangleMesh mesh = create_mesh(type_name, bb);
// Add mesh to model as a new object
Model& model = wxGetApp().plater()->model();
const wxString name = _(L("Shape")) + "-" + _(type_name);
#ifdef _DEBUG
check_model_ids_validity(model);
#endif /* _DEBUG */
std::vector<size_t> object_idxs;
ModelObject* new_object = model.add_object();
new_object->name = into_u8(name);
new_object->add_instance(); // each object should have at list one instance
ModelVolume* new_volume = new_object->add_volume(mesh);
new_volume->name = into_u8(name);
// set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
new_object->invalidate_bounding_box();
const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb();
new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -new_object->origin_translation(2)));
object_idxs.push_back(model.objects.size() - 1);
#ifdef _DEBUG
check_model_ids_validity(model);
#endif /* _DEBUG */
paste_objects_into_list(object_idxs);
#ifdef _DEBUG
check_model_ids_validity(model);
#endif /* _DEBUG */
}
void ObjectList::del_object(const int obj_idx) void ObjectList::del_object(const int obj_idx)
{ {
wxGetApp().plater()->delete_object_from_model(obj_idx); wxGetApp().plater()->delete_object_from_model(obj_idx);
@ -3585,7 +3667,8 @@ void ObjectList::msw_rescale()
&m_menu_part, &m_menu_part,
&m_menu_sla_object, &m_menu_sla_object,
&m_menu_instance, &m_menu_instance,
&m_menu_layer }) &m_menu_layer,
&m_menu_default})
msw_rescale_menu(menu); msw_rescale_menu(menu);
Layout(); Layout();

View File

@ -132,6 +132,7 @@ private:
MenuWithSeparators m_menu_sla_object; MenuWithSeparators m_menu_sla_object;
MenuWithSeparators m_menu_instance; MenuWithSeparators m_menu_instance;
MenuWithSeparators m_menu_layer; MenuWithSeparators m_menu_layer;
MenuWithSeparators m_menu_default;
wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_settings { nullptr };
wxMenuItem* m_menu_item_split_instances { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr };
@ -208,7 +209,7 @@ public:
void set_tooltip_for_item(const wxPoint& pt); void set_tooltip_for_item(const wxPoint& pt);
void selection_changed(); void selection_changed();
void show_context_menu(); void show_context_menu(const bool evt_context_menu);
#ifndef __WXOSX__ #ifndef __WXOSX__
void key_event(wxKeyEvent& event); void key_event(wxKeyEvent& event);
#endif /* __WXOSX__ */ #endif /* __WXOSX__ */
@ -240,6 +241,7 @@ public:
void create_sla_object_popupmenu(wxMenu*menu); void create_sla_object_popupmenu(wxMenu*menu);
void create_part_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu);
void create_instance_popupmenu(wxMenu*menu); void create_instance_popupmenu(wxMenu*menu);
void create_default_popupmenu(wxMenu *menu);
wxMenu* create_settings_popupmenu(wxMenu *parent_menu); wxMenu* create_settings_popupmenu(wxMenu *parent_menu);
void create_freq_settings_popupmenu(wxMenu *parent_menu, const bool is_object_settings = true); void create_freq_settings_popupmenu(wxMenu *parent_menu, const bool is_object_settings = true);
@ -248,6 +250,7 @@ public:
void load_subobject(ModelVolumeType type); void load_subobject(ModelVolumeType type);
void load_part(ModelObject* model_object, std::vector<std::pair<wxString, bool>> &volumes_info, ModelVolumeType type); void load_part(ModelObject* model_object, std::vector<std::pair<wxString, bool>> &volumes_info, ModelVolumeType type);
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
void load_shape_object(const std::string &type_name);
void del_object(const int obj_idx); void del_object(const int obj_idx);
void del_subobject_item(wxDataViewItem& item); void del_subobject_item(wxDataViewItem& item);
void del_settings_from_config(const wxDataViewItem& parent_item); void del_settings_from_config(const wxDataViewItem& parent_item);
@ -362,7 +365,7 @@ private:
// void OnChar(wxKeyEvent& event); // void OnChar(wxKeyEvent& event);
#endif /* __WXOSX__ */ #endif /* __WXOSX__ */
void OnContextMenu(wxDataViewEvent &event); void OnContextMenu(wxDataViewEvent &event);
void list_manipulation(); void list_manipulation(bool evt_context_menu = false);
void OnBeginDrag(wxDataViewEvent &event); void OnBeginDrag(wxDataViewEvent &event);
void OnDropPossible(wxDataViewEvent &event); void OnDropPossible(wxDataViewEvent &event);

View File

@ -4881,6 +4881,11 @@ GLCanvas3D* Plater::canvas3D()
return p->view3D->get_canvas3d(); return p->view3D->get_canvas3d();
} }
BoundingBoxf Plater::bed_shape_bb() const
{
return p->bed_shape_bb();
}
PrinterTechnology Plater::printer_technology() const PrinterTechnology Plater::printer_technology() const
{ {
return p->printer_technology; return p->printer_technology;

View File

@ -225,6 +225,7 @@ public:
int get_selected_object_idx(); int get_selected_object_idx();
bool is_single_full_object_selection() const; bool is_single_full_object_selection() const;
GLCanvas3D* canvas3D(); GLCanvas3D* canvas3D();
BoundingBoxf bed_shape_bb() const;
PrinterTechnology printer_technology() const; PrinterTechnology printer_technology() const;
void set_printer_technology(PrinterTechnology printer_technology); void set_printer_technology(PrinterTechnology printer_technology);