Merge branch 'dev_native' of http://github.com/prusa3d/Slic3r into dev_native
This commit is contained in:
commit
13a2532746
8 changed files with 225 additions and 128 deletions
BIN
resources/icons/support_blocker_.png
Normal file
BIN
resources/icons/support_blocker_.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/icons/support_enforcer_.png
Normal file
BIN
resources/icons/support_enforcer_.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -864,43 +864,46 @@ void ModelObject::scale(const Vec3d &versor)
|
|||
this->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
void ModelObject::rotate(float angle, const Axis& axis)
|
||||
void ModelObject::rotate(double angle, Axis axis)
|
||||
{
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.rotate(angle, axis);
|
||||
v->m_convex_hull.rotate(angle, axis);
|
||||
v->rotate(angle, axis);
|
||||
}
|
||||
|
||||
center_around_origin();
|
||||
|
||||
#if !ENABLE_MODELVOLUME_TRANSFORM
|
||||
this->origin_translation = Vec3d::Zero();
|
||||
#endif // !ENABLE_MODELVOLUME_TRANSFORM
|
||||
this->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
void ModelObject::rotate(float angle, const Vec3d& axis)
|
||||
void ModelObject::rotate(double angle, const Vec3d& axis)
|
||||
{
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.rotate(angle, axis);
|
||||
v->m_convex_hull.rotate(angle, axis);
|
||||
v->rotate(angle, axis);
|
||||
}
|
||||
|
||||
center_around_origin();
|
||||
|
||||
#if !ENABLE_MODELVOLUME_TRANSFORM
|
||||
this->origin_translation = Vec3d::Zero();
|
||||
#endif // !ENABLE_MODELVOLUME_TRANSFORM
|
||||
this->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
void ModelObject::mirror(const Axis &axis)
|
||||
void ModelObject::mirror(Axis axis)
|
||||
{
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.mirror(axis);
|
||||
v->m_convex_hull.mirror(axis);
|
||||
v->mirror(axis);
|
||||
}
|
||||
|
||||
#if !ENABLE_MODELVOLUME_TRANSFORM
|
||||
this->origin_translation = Vec3d::Zero();
|
||||
#endif // !ENABLE_MODELVOLUME_TRANSFORM
|
||||
this->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
|
@ -1249,6 +1252,48 @@ void ModelVolume::scale(const Vec3d& scaling_factors)
|
|||
#endif // ENABLE_MODELVOLUME_TRANSFORM
|
||||
}
|
||||
|
||||
void ModelVolume::rotate(double angle, Axis axis)
|
||||
{
|
||||
#if ENABLE_MODELVOLUME_TRANSFORM
|
||||
switch (axis)
|
||||
{
|
||||
case X: { rotate(angle, Vec3d::UnitX()); break; }
|
||||
case Y: { rotate(angle, Vec3d::UnitY()); break; }
|
||||
case Z: { rotate(angle, Vec3d::UnitZ()); break; }
|
||||
}
|
||||
#else
|
||||
mesh.rotate(angle, axis);
|
||||
m_convex_hull.rotate(angle, axis);
|
||||
#endif // ENABLE_MODELVOLUME_TRANSFORM
|
||||
}
|
||||
|
||||
void ModelVolume::rotate(double angle, const Vec3d& axis)
|
||||
{
|
||||
#if ENABLE_MODELVOLUME_TRANSFORM
|
||||
m_transformation.set_rotation(m_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix()));
|
||||
#else
|
||||
mesh.rotate(angle, axis);
|
||||
m_convex_hull.rotate(angle, axis);
|
||||
#endif // ENABLE_MODELVOLUME_TRANSFORM
|
||||
}
|
||||
|
||||
void ModelVolume::mirror(Axis axis)
|
||||
{
|
||||
#if ENABLE_MODELVOLUME_TRANSFORM
|
||||
Vec3d mirror = m_transformation.get_mirror();
|
||||
switch (axis)
|
||||
{
|
||||
case X: { mirror(0) *= -1.0; break; }
|
||||
case Y: { mirror(1) *= -1.0; break; }
|
||||
case Z: { mirror(2) *= -1.0; break; }
|
||||
}
|
||||
m_transformation.set_mirror(mirror);
|
||||
#else
|
||||
mesh.mirror(axis);
|
||||
m_convex_hull.mirror(axis);
|
||||
#endif // ENABLE_MODELVOLUME_TRANSFORM
|
||||
}
|
||||
|
||||
#if !ENABLE_MODELVOLUME_TRANSFORM
|
||||
void ModelInstance::set_rotation(const Vec3d& rotation)
|
||||
{
|
||||
|
|
|
@ -231,9 +231,9 @@ public:
|
|||
void scale(const Vec3d &versor);
|
||||
void scale(const double s) { this->scale(Vec3d(s, s, s)); }
|
||||
void scale(double x, double y, double z) { this->scale(Vec3d(x, y, z)); }
|
||||
void rotate(float angle, const Axis &axis);
|
||||
void rotate(float angle, const Vec3d& axis);
|
||||
void mirror(const Axis &axis);
|
||||
void rotate(double angle, Axis axis);
|
||||
void rotate(double angle, const Vec3d& axis);
|
||||
void mirror(Axis axis);
|
||||
size_t materials_count() const;
|
||||
size_t facets_count() const;
|
||||
bool needed_repair() const;
|
||||
|
@ -319,6 +319,9 @@ public:
|
|||
void scale(const Vec3d& scaling_factors);
|
||||
void scale(double x, double y, double z) { scale(Vec3d(x, y, z)); }
|
||||
void scale(double s) { scale(Vec3d(s, s, s)); }
|
||||
void rotate(double angle, Axis axis);
|
||||
void rotate(double angle, const Vec3d& axis);
|
||||
void mirror(Axis axis);
|
||||
|
||||
ModelMaterial* assign_unique_material();
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||
CATEGORY_ICON[L("Advanced")] = wxBitmap(from_u8(var("wand.png")), wxBITMAP_TYPE_PNG);
|
||||
}
|
||||
|
||||
init_icons();
|
||||
|
||||
// create control
|
||||
create_objects_ctrl();
|
||||
|
||||
init_icons();
|
||||
|
||||
// describe control behavior
|
||||
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) {
|
||||
selection_changed();
|
||||
|
@ -213,17 +213,27 @@ void ObjectList::update_extruder_in_config(const wxString& selection)
|
|||
|
||||
void ObjectList::init_icons()
|
||||
{
|
||||
m_bmp_modifiermesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_solidmesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_modifiermesh = wxBitmap(from_u8(var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_solidmesh = wxBitmap(from_u8(var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
|
||||
|
||||
m_bmp_support_enforcer = wxBitmap(from_u8(var("support_enforcer_.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_support_blocker = wxBitmap(from_u8(var("support_blocker_.png")), wxBITMAP_TYPE_PNG);
|
||||
|
||||
m_bmp_vector.reserve(4); // bitmaps for different types of parts
|
||||
m_bmp_vector.push_back(&m_bmp_solidmesh); // Add part
|
||||
m_bmp_vector.push_back(&m_bmp_modifiermesh); // Add modifier
|
||||
m_bmp_vector.push_back(&m_bmp_support_enforcer); // Add support enforcer
|
||||
m_bmp_vector.push_back(&m_bmp_support_blocker); // Add support blocker
|
||||
m_objects_model->SetVolumeBitmaps(m_bmp_vector);
|
||||
|
||||
// init icon for manifold warning
|
||||
m_bmp_manifold_warning = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_manifold_warning = wxBitmap(from_u8(var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG);
|
||||
|
||||
// init bitmap for "Split to sub-objects" context menu
|
||||
m_bmp_split = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("split.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_split = wxBitmap(from_u8(var("split.png")), wxBITMAP_TYPE_PNG);
|
||||
|
||||
// init bitmap for "Add Settings" context menu
|
||||
m_bmp_cog = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG);
|
||||
m_bmp_cog = wxBitmap(from_u8(var("cog.png")), wxBITMAP_TYPE_PNG);
|
||||
}
|
||||
|
||||
|
||||
|
@ -552,47 +562,60 @@ wxMenuItem* ObjectList::menu_item_settings(wxMenu* menu, int id, const bool is_p
|
|||
wxMenu* ObjectList::create_add_part_popupmenu()
|
||||
{
|
||||
wxMenu *menu = new wxMenu;
|
||||
std::vector<std::string> menu_items = { L("Add part"), L("Add modifier"), L("Add generic") };
|
||||
std::vector<std::string> menu_object_types_items = {L("Add part"),
|
||||
L("Add modifier"),
|
||||
L("Add support enforcer"),
|
||||
L("Add support bloker"),
|
||||
L("Add generic") };
|
||||
const int obj_types_count = menu_object_types_items.size();
|
||||
const int generics_count = 4;
|
||||
|
||||
wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size() + 4 + 2);
|
||||
wxWindowID config_id_base = NewControlId(menu_object_types_items.size() + 4 + 2);
|
||||
|
||||
int i = 0;
|
||||
for (auto& item : menu_items) {
|
||||
// Add first 4 menu items
|
||||
int i;
|
||||
for (i = 0; i < obj_types_count - 1; i++) {
|
||||
auto& item = menu_object_types_items[i];
|
||||
auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item));
|
||||
menu_item->SetBitmap(i == 0 ? m_bmp_solidmesh : m_bmp_modifiermesh);
|
||||
if (item == "Add generic")
|
||||
menu_item_add_generic(menu_item, config_id_base + i);
|
||||
menu_item->SetBitmap(*m_bmp_vector[i]);
|
||||
menu->Append(menu_item);
|
||||
i++;
|
||||
}
|
||||
// Add generic modifier
|
||||
auto& item = menu_object_types_items[i];
|
||||
auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item));
|
||||
menu_item->SetBitmap(*m_bmp_vector[1]); // set modifier's icon
|
||||
menu_item_add_generic(menu_item, config_id_base + i);
|
||||
menu->Append(menu_item);
|
||||
|
||||
// Split object to parts
|
||||
menu->AppendSeparator();
|
||||
auto menu_item = menu_item_split(menu, config_id_base + i + 4);
|
||||
menu_item = menu_item_split(menu, config_id_base + obj_types_count + generics_count);
|
||||
menu->Append(menu_item);
|
||||
menu_item->Enable(is_splittable_object(false));
|
||||
|
||||
// Settings
|
||||
menu->AppendSeparator();
|
||||
// Append settings popupmenu
|
||||
menu->Append(menu_item_settings(menu, config_id_base + i + 5, false));
|
||||
menu->Append(menu_item_settings(menu, config_id_base + obj_types_count + generics_count+1, false));
|
||||
|
||||
menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) {
|
||||
switch (event.GetId() - config_id_base) {
|
||||
case 0:
|
||||
load_subobject();
|
||||
case 0: // ~ModelVolume::MODEL_PART
|
||||
case 1: // ~ModelVolume::PARAMETER_MODIFIER
|
||||
case 2: // ~ModelVolume::SUPPORT_ENFORCER
|
||||
case 3: // ~ModelVolume::SUPPORT_BLOCKER
|
||||
load_subobject(event.GetId() - config_id_base);
|
||||
break;
|
||||
case 1:
|
||||
load_subobject(true);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
#ifdef __WXMSW__
|
||||
load_lambda(menu->GetLabel(event.GetId()).ToStdString());
|
||||
#endif // __WXMSW__
|
||||
break;
|
||||
case 7: //3:
|
||||
case 9:
|
||||
split(false);
|
||||
break;
|
||||
default:
|
||||
|
@ -609,24 +632,33 @@ wxMenu* ObjectList::create_add_part_popupmenu()
|
|||
wxMenu* ObjectList::create_part_settings_popupmenu()
|
||||
{
|
||||
wxMenu *menu = new wxMenu;
|
||||
wxWindowID config_id_base = wxWindow::NewControlId(2);
|
||||
wxWindowID config_id_base = NewControlId(3);
|
||||
|
||||
auto menu_item = menu_item_split(menu, config_id_base);
|
||||
menu->Append(menu_item);
|
||||
menu_item->Enable(is_splittable_object(true));
|
||||
|
||||
// Append change part type
|
||||
menu->AppendSeparator();
|
||||
menu->Append(new wxMenuItem(menu, config_id_base + 1, _(L("Change type"))));
|
||||
|
||||
// Append settings popupmenu
|
||||
menu->Append(menu_item_settings(menu, config_id_base + 1, true));
|
||||
menu->AppendSeparator();
|
||||
menu_item = menu_item_settings(menu, config_id_base + 2, true);
|
||||
menu->Append(menu_item);
|
||||
menu_item->Enable(get_selected_model_volume()->type() <= ModelVolume::PARAMETER_MODIFIER);
|
||||
|
||||
menu->Bind(wxEVT_MENU, [config_id_base, menu, this](wxEvent &event) {
|
||||
switch (event.GetId() - config_id_base) {
|
||||
case 0:
|
||||
split(true);
|
||||
break;
|
||||
default:{
|
||||
case 1:
|
||||
change_part_type();
|
||||
break;
|
||||
default:
|
||||
get_settings_choice(menu, event.GetId(), true);
|
||||
break; }
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -655,31 +687,21 @@ wxMenu* ObjectList::create_add_settings_popupmenu(bool is_part)
|
|||
return menu;
|
||||
}
|
||||
|
||||
|
||||
// Load SubObjects (parts and modifiers)
|
||||
void ObjectList::load_subobject(bool is_modifier /*= false*/, bool is_lambda/* = false*/)
|
||||
void ObjectList::load_subobject(int type)
|
||||
{
|
||||
auto item = GetSelection();
|
||||
if (!item)
|
||||
return;
|
||||
int obj_idx = -1;
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0))
|
||||
obj_idx = m_objects_model->GetIdByItem(item);
|
||||
else
|
||||
if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0))
|
||||
return;
|
||||
int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
|
||||
if (obj_idx < 0) return;
|
||||
wxArrayString part_names;
|
||||
if (is_lambda)
|
||||
load_lambda((*m_objects)[obj_idx], part_names, is_modifier);
|
||||
else
|
||||
load_part((*m_objects)[obj_idx], part_names, is_modifier);
|
||||
load_part((*m_objects)[obj_idx], part_names, type);
|
||||
|
||||
parts_changed(obj_idx);
|
||||
|
||||
for (int i = 0; i < part_names.size(); ++i) {
|
||||
const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i),
|
||||
is_modifier ? m_bmp_modifiermesh : m_bmp_solidmesh);
|
||||
const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), /**m_bmp_vector[*/type/*]*/);
|
||||
|
||||
if (i == part_names.size() - 1)
|
||||
select_item(sel_item);
|
||||
|
@ -688,11 +710,12 @@ void ObjectList::load_subobject(bool is_modifier /*= false*/, bool is_lambda/* =
|
|||
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||
// selection_changed();
|
||||
#endif //no __WXOSX__//__WXMSW__
|
||||
|
||||
}
|
||||
|
||||
void ObjectList::load_part( ModelObject* model_object,
|
||||
wxArrayString& part_names,
|
||||
const bool is_modifier)
|
||||
int type)
|
||||
{
|
||||
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
|
||||
|
||||
|
@ -722,7 +745,7 @@ void ObjectList::load_part( ModelObject* model_object,
|
|||
}
|
||||
for (auto volume : object->volumes) {
|
||||
auto new_volume = model_object->add_volume(*volume);
|
||||
new_volume->set_type(is_modifier ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART);
|
||||
new_volume->set_type(static_cast<ModelVolume::Type>(type));
|
||||
boost::filesystem::path(input_file).filename().string();
|
||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||
|
||||
|
@ -738,58 +761,7 @@ void ObjectList::load_part( ModelObject* model_object,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectList::load_lambda( ModelObject* model_object,
|
||||
wxArrayString& part_names,
|
||||
const bool is_modifier)
|
||||
{
|
||||
auto dlg = new LambdaObjectDialog(GetMainWindow());
|
||||
if (dlg->ShowModal() == wxID_CANCEL) {
|
||||
m_parts_changed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name = "lambda-";
|
||||
TriangleMesh mesh;
|
||||
|
||||
auto params = dlg->ObjectParameters();
|
||||
switch (params.type)
|
||||
{
|
||||
case LambdaTypeBox:{
|
||||
mesh = make_cube(params.dim[0], params.dim[1], params.dim[2]);
|
||||
name += "Box";
|
||||
break; }
|
||||
case LambdaTypeCylinder:{
|
||||
mesh = make_cylinder(params.cyl_r, params.cyl_h);
|
||||
name += "Cylinder";
|
||||
break; }
|
||||
case LambdaTypeSphere:{
|
||||
mesh = make_sphere(params.sph_rho);
|
||||
name += "Sphere";
|
||||
break; }
|
||||
case LambdaTypeSlab:{
|
||||
const auto& size = model_object->bounding_box().size();
|
||||
mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h);
|
||||
// box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z
|
||||
mesh.translate(-size(0)*1.5 / 2.0, -size(1)*1.5 / 2.0, params.slab_z);
|
||||
name += "Slab";
|
||||
break; }
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mesh.repair();
|
||||
|
||||
auto new_volume = model_object->add_volume(mesh);
|
||||
new_volume->set_type(is_modifier ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART);
|
||||
|
||||
new_volume->name = name;
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
||||
part_names.Add(name);
|
||||
|
||||
m_parts_changed = true;
|
||||
}
|
||||
|
||||
void ObjectList::load_lambda(const std::string& type_name)
|
||||
|
@ -828,8 +800,7 @@ void ObjectList::load_lambda(const std::string& type_name)
|
|||
m_parts_changed = true;
|
||||
parts_changed(m_selected_object_id);
|
||||
|
||||
select_item(m_objects_model->AddVolumeChild(GetSelection(),
|
||||
name, m_bmp_modifiermesh));
|
||||
select_item(m_objects_model->AddVolumeChild(GetSelection(), name, ModelVolume::PARAMETER_MODIFIER/*m_bmp_modifiermesh*/));
|
||||
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||
selection_changed();
|
||||
#endif //no __WXOSX__ //__WXMSW__
|
||||
|
@ -946,7 +917,7 @@ void ObjectList::split(const bool split_part)
|
|||
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||
m_objects_model->AddVolumeChild(parent, model_object->volumes[id]->name,
|
||||
model_object->volumes[id]->is_modifier() ? m_bmp_modifiermesh : m_bmp_solidmesh,
|
||||
model_object->volumes[id]->is_modifier() ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART,
|
||||
model_object->volumes[id]->config.has("extruder") ?
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||
false);
|
||||
|
@ -956,7 +927,7 @@ void ObjectList::split(const bool split_part)
|
|||
else {
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||
m_objects_model->AddVolumeChild(item, model_object->volumes[id]->name,
|
||||
m_bmp_solidmesh,
|
||||
ModelVolume::MODEL_PART,
|
||||
model_object->volumes[id]->config.has("extruder") ?
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||
false);
|
||||
|
@ -967,7 +938,7 @@ void ObjectList::split(const bool split_part)
|
|||
parts_changed(m_selected_object_id);
|
||||
|
||||
// restores selection
|
||||
_3DScene::get_canvas(wxGetApp().canvas3D())->get_selection().add_object(m_selected_object_id);
|
||||
// _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection().add_object(m_selected_object_id);
|
||||
}
|
||||
|
||||
bool ObjectList::get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume)
|
||||
|
@ -1017,7 +988,7 @@ void ObjectList::part_settings_changed()
|
|||
|
||||
void ObjectList::parts_changed(int obj_idx)
|
||||
{
|
||||
wxGetApp().plater()->changed_object(get_selected_obj_idx());
|
||||
wxGetApp().plater()->changed_object(obj_idx);
|
||||
m_parts_changed = false;
|
||||
}
|
||||
|
||||
|
@ -1109,7 +1080,7 @@ void ObjectList::add_object_to_list(size_t obj_idx)
|
|||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||
m_objects_model->AddVolumeChild(item,
|
||||
model_object->volumes[id]->name,
|
||||
m_bmp_solidmesh,
|
||||
ModelVolume::MODEL_PART,
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
|
||||
false);
|
||||
Expand(item);
|
||||
|
@ -1334,5 +1305,53 @@ void ObjectList::fix_multiselection_conflicts()
|
|||
m_prevent_list_events = false;
|
||||
}
|
||||
|
||||
ModelVolume* ObjectList::get_selected_model_volume()
|
||||
{
|
||||
auto item = GetSelection();
|
||||
if (!item || m_objects_model->GetItemType(item) != itVolume)
|
||||
return nullptr;
|
||||
|
||||
const auto vol_idx = m_objects_model->GetVolumeIdByItem(item);
|
||||
const auto obj_idx = get_selected_obj_idx();
|
||||
if (vol_idx < 0 || obj_idx < 0)
|
||||
return nullptr;
|
||||
|
||||
return (*m_objects)[obj_idx]->volumes[vol_idx];
|
||||
}
|
||||
|
||||
void ObjectList::change_part_type()
|
||||
{
|
||||
ModelVolume* volume = get_selected_model_volume();
|
||||
if (!volume)
|
||||
return;
|
||||
const auto type = volume->type();
|
||||
|
||||
const wxString names[] = { "Part", "Modifier", "Support Enforcer", "Support Blocker" };
|
||||
|
||||
auto new_type = wxGetSingleChoiceIndex("Type: ", _(L("Select type of part")), wxArrayString(4, names), type);
|
||||
|
||||
if (new_type == type || new_type < 0)
|
||||
return;
|
||||
|
||||
const auto item = GetSelection();
|
||||
volume->set_type(static_cast<ModelVolume::Type>(new_type));
|
||||
m_objects_model->SetVolumeType(item, new_type);
|
||||
|
||||
m_parts_changed = true;
|
||||
parts_changed(get_selected_obj_idx());
|
||||
|
||||
// Update settings showing, if we have it
|
||||
//(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer)
|
||||
const auto settings_item = m_objects_model->GetSettingsItem(item);
|
||||
if (settings_item &&
|
||||
new_type == ModelVolume::SUPPORT_ENFORCER || new_type == ModelVolume::SUPPORT_BLOCKER) {
|
||||
m_objects_model->Delete(settings_item);
|
||||
}
|
||||
else if (!settings_item &&
|
||||
new_type == ModelVolume::MODEL_PART || new_type == ModelVolume::PARAMETER_MODIFIER) {
|
||||
select_item(m_objects_model->AddSettingsChild(item));
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace GUI
|
||||
} //namespace Slic3r
|
|
@ -28,10 +28,14 @@ class ObjectList : public wxDataViewCtrl
|
|||
|
||||
wxBitmap m_bmp_modifiermesh;
|
||||
wxBitmap m_bmp_solidmesh;
|
||||
wxBitmap m_bmp_support_enforcer;
|
||||
wxBitmap m_bmp_support_blocker;
|
||||
wxBitmap m_bmp_manifold_warning;
|
||||
wxBitmap m_bmp_cog;
|
||||
wxBitmap m_bmp_split;
|
||||
|
||||
std::vector<wxBitmap*> m_bmp_vector;
|
||||
|
||||
int m_selected_object_id = -1;
|
||||
bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select()
|
||||
// happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler
|
||||
|
@ -85,9 +89,8 @@ public:
|
|||
wxMenu* create_part_settings_popupmenu();
|
||||
wxMenu* create_add_settings_popupmenu(bool is_part);
|
||||
|
||||
void load_subobject(bool is_modifier = false, bool is_lambda = false);
|
||||
void load_part(ModelObject* model_object, wxArrayString& part_names, const bool is_modifier);
|
||||
void load_lambda(ModelObject* model_object, wxArrayString& part_names, const bool is_modifier);
|
||||
void load_subobject(int type);
|
||||
void load_part(ModelObject* model_object, wxArrayString& part_names, int type);
|
||||
void load_lambda(const std::string& type_name);
|
||||
void del_subobject_item(wxDataViewItem& item);
|
||||
void del_settings_from_config();
|
||||
|
@ -142,6 +145,9 @@ public:
|
|||
void select_all();
|
||||
// correct current selections to avoid of the possible conflicts
|
||||
void fix_multiselection_conflicts();
|
||||
|
||||
ModelVolume* get_selected_model_volume();
|
||||
void change_part_type();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <wx/numformatter.h>
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "Model.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, wxEvtHandler* event_handler)
|
||||
|
@ -400,10 +401,9 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std:
|
|||
|
||||
m_opt_categories = categories;
|
||||
m_name = wxEmptyString;
|
||||
// m_icon = m_empty_icon;
|
||||
m_bmp = m_empty_bmp;
|
||||
|
||||
std::map<std::string, wxBitmap>& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON;//Slic3r::GUI::get_category_icon();
|
||||
std::map<std::string, wxBitmap>& categories_icon = Slic3r::GUI::wxGetApp().obj_list()->CATEGORY_ICON;
|
||||
|
||||
for (auto& cat : m_opt_categories)
|
||||
m_name += cat + "; ";
|
||||
|
@ -453,19 +453,18 @@ wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name)
|
|||
|
||||
wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &parent_item,
|
||||
const wxString &name,
|
||||
const wxBitmap& icon,
|
||||
const int volume_type,
|
||||
const int extruder/* = 0*/,
|
||||
const bool create_frst_child/* = true*/)
|
||||
{
|
||||
PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID();
|
||||
if (!root) return wxDataViewItem(0);
|
||||
|
||||
const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder);
|
||||
wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder);
|
||||
|
||||
if (create_frst_child && root->m_volumes_cnt == 0)
|
||||
{
|
||||
const auto bmp_solid_mesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);
|
||||
const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, bmp_solid_mesh, extruder_str, 0);
|
||||
const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, *m_volume_bmps[0], extruder_str, 0);
|
||||
root->Append(node);
|
||||
// notify control
|
||||
const wxDataViewItem child((void*)node);
|
||||
|
@ -474,7 +473,10 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa
|
|||
root->m_volumes_cnt++;
|
||||
}
|
||||
|
||||
const auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, root->m_volumes_cnt);
|
||||
// if (volume_type >= Slic3r::ModelVolume::SUPPORT_ENFORCER)
|
||||
// extruder_str = "";
|
||||
|
||||
const auto node = new PrusaObjectDataViewModelNode(root, name, *m_volume_bmps[volume_type], extruder_str, root->m_volumes_cnt);
|
||||
root->Append(node);
|
||||
// notify control
|
||||
const wxDataViewItem child((void*)node);
|
||||
|
@ -563,6 +565,10 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
|
|||
auto id = node_parent->GetChildren().Index(node);
|
||||
auto idx = node->GetIdx();
|
||||
node_parent->GetChildren().Remove(node);
|
||||
|
||||
if (node->m_type == itVolume)
|
||||
node_parent->m_volumes_cnt--;
|
||||
|
||||
if (id > 0) {
|
||||
if(id == node_parent->GetChildCount()) id--;
|
||||
ret_item = wxDataViewItem(node_parent->GetChildren().Item(id));
|
||||
|
@ -692,6 +698,9 @@ void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent)
|
|||
auto item = wxDataViewItem(node);
|
||||
children.RemoveAt(id);
|
||||
|
||||
if (node->m_type == itVolume)
|
||||
root->m_volumes_cnt--;
|
||||
|
||||
// free the node
|
||||
delete node;
|
||||
|
||||
|
@ -1050,6 +1059,16 @@ void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item,
|
|||
ItemChanged(item);
|
||||
}
|
||||
|
||||
void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const int type)
|
||||
{
|
||||
if (!item.IsOk() || GetItemType(item) != itVolume)
|
||||
return;
|
||||
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
node->SetBitmap(*m_volume_bmps[type]);
|
||||
ItemChanged(item);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PrusaDataViewBitmapText
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -424,7 +424,9 @@ private:
|
|||
|
||||
class PrusaObjectDataViewModel :public wxDataViewModel
|
||||
{
|
||||
std::vector<PrusaObjectDataViewModelNode*> m_objects;
|
||||
std::vector<PrusaObjectDataViewModelNode*> m_objects;
|
||||
std::vector<wxBitmap*> m_volume_bmps;
|
||||
|
||||
public:
|
||||
PrusaObjectDataViewModel();
|
||||
~PrusaObjectDataViewModel();
|
||||
|
@ -432,7 +434,7 @@ public:
|
|||
wxDataViewItem Add(const wxString &name);
|
||||
wxDataViewItem AddVolumeChild(const wxDataViewItem &parent_item,
|
||||
const wxString &name,
|
||||
const wxBitmap& icon,
|
||||
const int volume_type,
|
||||
const int extruder = 0,
|
||||
const bool create_frst_child = true);
|
||||
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
||||
|
@ -491,6 +493,9 @@ public:
|
|||
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
|
||||
bool IsSettingsItem(const wxDataViewItem &item) const;
|
||||
void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories);
|
||||
|
||||
void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; }
|
||||
void SetVolumeType(const wxDataViewItem &item, const int type);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue