mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-25 15:44:12 -06:00
Merge branch 'dev_native' of https://github.com/prusa3d/Slic3r into dev_native
This commit is contained in:
commit
7dcfe57db1
3 changed files with 130 additions and 51 deletions
|
@ -898,8 +898,10 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
|
||||||
void ObjectList::split(const bool split_part)
|
void ObjectList::split(const bool split_part)
|
||||||
{
|
{
|
||||||
const auto item = GetSelection();
|
const auto item = GetSelection();
|
||||||
if (!item || m_selected_object_id < 0)
|
const int obj_idx = get_selected_obj_idx();
|
||||||
|
if (!item || obj_idx < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ModelVolume* volume;
|
ModelVolume* volume;
|
||||||
if (!get_volume_by_item(split_part, item, volume)) return;
|
if (!get_volume_by_item(split_part, item, volume)) return;
|
||||||
DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||||
|
@ -909,52 +911,51 @@ void ObjectList::split(const bool split_part)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto model_object = (*m_objects)[m_selected_object_id];
|
auto model_object = (*m_objects)[obj_idx];
|
||||||
|
|
||||||
if (split_part) {
|
auto parent = m_objects_model->GetTopParent(item);
|
||||||
auto parent = m_objects_model->GetParent(item);
|
if (parent)
|
||||||
m_objects_model->DeleteChildren(parent);
|
m_objects_model->DeleteVolumeChildren(parent);
|
||||||
|
else
|
||||||
|
parent = item;
|
||||||
|
|
||||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
for (auto id = 0; id < model_object->volumes.size(); id++) {
|
||||||
m_objects_model->AddVolumeChild(parent, model_object->volumes[id]->name,
|
const auto vol_item = m_objects_model->AddVolumeChild(parent, model_object->volumes[id]->name,
|
||||||
model_object->volumes[id]->is_modifier() ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART,
|
model_object->volumes[id]->is_modifier() ?
|
||||||
model_object->volumes[id]->config.has("extruder") ?
|
ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART,
|
||||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
model_object->volumes[id]->config.has("extruder") ?
|
||||||
false);
|
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||||
|
false);
|
||||||
Expand(parent);
|
// add settings to the part, if it has those
|
||||||
}
|
auto opt_keys = model_object->volumes[id]->config.keys();
|
||||||
else {
|
if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) {
|
||||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
select_item(m_objects_model->AddSettingsChild(vol_item));
|
||||||
m_objects_model->AddVolumeChild(item, model_object->volumes[id]->name,
|
Collapse(vol_item);
|
||||||
ModelVolume::MODEL_PART,
|
}
|
||||||
model_object->volumes[id]->config.has("extruder") ?
|
|
||||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
|
||||||
false);
|
|
||||||
Expand(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_parts_changed = true;
|
m_parts_changed = true;
|
||||||
parts_changed(m_selected_object_id);
|
parts_changed(obj_idx);
|
||||||
|
|
||||||
// restores selection
|
|
||||||
// _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)
|
bool ObjectList::get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume)
|
||||||
{
|
{
|
||||||
if (!item || m_selected_object_id < 0)
|
auto obj_idx = get_selected_obj_idx();
|
||||||
|
if (!item || obj_idx < 0)
|
||||||
return false;
|
return false;
|
||||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||||
|
|
||||||
|
// object is selected
|
||||||
if (volume_id < 0) {
|
if (volume_id < 0) {
|
||||||
if (split_part) return false;
|
if ( split_part || (*m_objects)[obj_idx]->volumes.size() > 1 )
|
||||||
volume = (*m_objects)[m_selected_object_id]->volumes[0];
|
return false;
|
||||||
|
volume = (*m_objects)[obj_idx]->volumes[0];
|
||||||
}
|
}
|
||||||
|
// volume is selected
|
||||||
else
|
else
|
||||||
volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
volume = (*m_objects)[obj_idx]->volumes[volume_id];
|
||||||
if (volume)
|
|
||||||
return true;
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectList::is_splittable_object(const bool split_part)
|
bool ObjectList::is_splittable_object(const bool split_part)
|
||||||
|
@ -962,20 +963,14 @@ bool ObjectList::is_splittable_object(const bool split_part)
|
||||||
const wxDataViewItem item = GetSelection();
|
const wxDataViewItem item = GetSelection();
|
||||||
if (!item) return false;
|
if (!item) return false;
|
||||||
|
|
||||||
wxDataViewItemArray children;
|
|
||||||
if (!split_part && m_objects_model->GetChildren(item, children) > 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ModelVolume* volume;
|
ModelVolume* volume;
|
||||||
if (!get_volume_by_item(split_part, item, volume) || !volume)
|
if (!get_volume_by_item(split_part, item, volume) || !volume)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TriangleMeshPtrs meshptrs = volume->mesh.split();
|
TriangleMeshPtrs meshptrs = volume->mesh.split();
|
||||||
bool splittable = meshptrs.size() > 1;
|
bool splittable = meshptrs.size() > 1;
|
||||||
for (TriangleMesh* m : meshptrs)
|
for (TriangleMesh* m : meshptrs) { delete m; }
|
||||||
{
|
|
||||||
delete m;
|
|
||||||
}
|
|
||||||
return splittable;
|
return splittable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,6 +1071,7 @@ void ObjectList::add_object_to_list(size_t obj_idx)
|
||||||
m_objects_model->SetValue(variant, item, 0);
|
m_objects_model->SetValue(variant, item, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add volumes to the object
|
||||||
if (model_object->volumes.size() > 1) {
|
if (model_object->volumes.size() > 1) {
|
||||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||||
m_objects_model->AddVolumeChild(item,
|
m_objects_model->AddVolumeChild(item,
|
||||||
|
@ -1086,9 +1082,17 @@ void ObjectList::add_object_to_list(size_t obj_idx)
|
||||||
Expand(item);
|
Expand(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add instances to the object, if it has those
|
||||||
if (model_object->instances.size()>1)
|
if (model_object->instances.size()>1)
|
||||||
increase_object_instances(obj_idx, model_object->instances.size());
|
increase_object_instances(obj_idx, model_object->instances.size());
|
||||||
|
|
||||||
|
// add settings to the object, if it has those
|
||||||
|
auto opt_keys = model_object->config.keys();
|
||||||
|
if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) {
|
||||||
|
select_item(m_objects_model->AddSettingsChild(item));
|
||||||
|
Collapse(item);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef __WXOSX__
|
#ifndef __WXOSX__
|
||||||
selection_changed();
|
selection_changed();
|
||||||
#endif //__WXMSW__
|
#endif //__WXMSW__
|
||||||
|
@ -1198,11 +1202,18 @@ void ObjectList::update_selections()
|
||||||
auto& selection = _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection();
|
auto& selection = _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection();
|
||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
|
|
||||||
for (auto idx: selection.get_volume_idxs())
|
if (selection.is_single_full_object()) {
|
||||||
{
|
for (auto idx : selection.get_volume_idxs()) {
|
||||||
const auto gl_vol = selection.get_volume(idx);
|
const auto gl_vol = selection.get_volume(idx);
|
||||||
sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx()));
|
sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (selection.is_single_full_instance()) {
|
||||||
|
for (auto idx : selection.get_instance_idxs()) {
|
||||||
|
sels.Add(m_objects_model->GetItemByInstanceId(selection.get_object_idx(), idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
select_items(sels);
|
select_items(sels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -714,6 +714,39 @@ void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent)
|
||||||
#endif //__WXGTK__
|
#endif //__WXGTK__
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrusaObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent)
|
||||||
|
{
|
||||||
|
PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent.GetID();
|
||||||
|
if (!root) // happens if item.IsOk()==false
|
||||||
|
return;
|
||||||
|
|
||||||
|
// first remove the node from the parent's array of children;
|
||||||
|
// NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_
|
||||||
|
// thus removing the node from it doesn't result in freeing it
|
||||||
|
auto& children = root->GetChildren();
|
||||||
|
for (int id = root->GetChildCount() - 1; id >= 0; --id)
|
||||||
|
{
|
||||||
|
auto node = children[id];
|
||||||
|
if (node->m_type != itVolume)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto item = wxDataViewItem(node);
|
||||||
|
children.RemoveAt(id);
|
||||||
|
root->m_volumes_cnt--;
|
||||||
|
|
||||||
|
// free the node
|
||||||
|
delete node;
|
||||||
|
|
||||||
|
// notify control
|
||||||
|
ItemDeleted(parent, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set m_containet to FALSE if parent has no child
|
||||||
|
#ifndef __WXGTK__
|
||||||
|
root->m_container = false;
|
||||||
|
#endif //__WXGTK__
|
||||||
|
}
|
||||||
|
|
||||||
wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx)
|
wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx)
|
||||||
{
|
{
|
||||||
if (obj_idx >= m_objects.size())
|
if (obj_idx >= m_objects.size())
|
||||||
|
@ -727,7 +760,7 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx)
|
||||||
|
|
||||||
wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx)
|
wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx)
|
||||||
{
|
{
|
||||||
if (obj_idx >= m_objects.size()) {
|
if (obj_idx >= m_objects.size() || obj_idx < 0) {
|
||||||
printf("Error! Out of objects range.\n");
|
printf("Error! Out of objects range.\n");
|
||||||
return wxDataViewItem(0);
|
return wxDataViewItem(0);
|
||||||
}
|
}
|
||||||
|
@ -749,6 +782,25 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volu
|
||||||
return wxDataViewItem(0);
|
return wxDataViewItem(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxDataViewItem PrusaObjectDataViewModel::GetItemByInstanceId(int obj_idx, int inst_idx)
|
||||||
|
{
|
||||||
|
if (obj_idx >= m_objects.size() || obj_idx < 0) {
|
||||||
|
printf("Error! Out of objects range.\n");
|
||||||
|
return wxDataViewItem(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto instances_item = GetInstanceRootItem(wxDataViewItem(m_objects[obj_idx]));
|
||||||
|
if (!instances_item)
|
||||||
|
return wxDataViewItem(0);
|
||||||
|
|
||||||
|
auto parent = (PrusaObjectDataViewModelNode*)instances_item.GetID();;
|
||||||
|
for (size_t i = 0; i < parent->GetChildCount(); i++)
|
||||||
|
if (parent->GetNthChild(i)->m_idx == inst_idx)
|
||||||
|
return wxDataViewItem(parent->GetNthChild(i));
|
||||||
|
|
||||||
|
return wxDataViewItem(0);
|
||||||
|
}
|
||||||
|
|
||||||
int PrusaObjectDataViewModel::GetIdByItem(const wxDataViewItem& item)
|
int PrusaObjectDataViewModel::GetIdByItem(const wxDataViewItem& item)
|
||||||
{
|
{
|
||||||
wxASSERT(item.IsOk());
|
wxASSERT(item.IsOk());
|
||||||
|
@ -1024,21 +1076,33 @@ ItemType PrusaObjectDataViewModel::GetItemType(const wxDataViewItem &item) const
|
||||||
return node->m_type;
|
return node->m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDataViewItem PrusaObjectDataViewModel::GetSettingsItem(const wxDataViewItem &item) const
|
wxDataViewItem PrusaObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_item, ItemType type) const
|
||||||
{
|
{
|
||||||
if (!item.IsOk())
|
if (!parent_item.IsOk())
|
||||||
return wxDataViewItem(0);
|
return wxDataViewItem(0);
|
||||||
|
|
||||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent_item.GetID();
|
||||||
if (node->GetChildCount() == 0)
|
if (node->GetChildCount() == 0)
|
||||||
return wxDataViewItem(0);
|
return wxDataViewItem(0);
|
||||||
|
|
||||||
if (node->GetNthChild(0)->m_type == itSettings)
|
for (int i = 0; i < node->GetChildCount(); i++) {
|
||||||
return wxDataViewItem((void*)node->GetNthChild(0));
|
if (node->GetNthChild(i)->m_type == type)
|
||||||
|
return wxDataViewItem((void*)node->GetNthChild(i));
|
||||||
|
}
|
||||||
|
|
||||||
return wxDataViewItem(0);
|
return wxDataViewItem(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxDataViewItem PrusaObjectDataViewModel::GetSettingsItem(const wxDataViewItem &item) const
|
||||||
|
{
|
||||||
|
return GetItemByType(item, itSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDataViewItem PrusaObjectDataViewModel::GetInstanceRootItem(const wxDataViewItem &item) const
|
||||||
|
{
|
||||||
|
return GetItemByType(item, itInstanceRoot);
|
||||||
|
}
|
||||||
|
|
||||||
bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const
|
bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const
|
||||||
{
|
{
|
||||||
if (!item.IsOk())
|
if (!item.IsOk())
|
||||||
|
|
|
@ -443,8 +443,10 @@ public:
|
||||||
wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num);
|
wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num);
|
||||||
void DeleteAll();
|
void DeleteAll();
|
||||||
void DeleteChildren(wxDataViewItem& parent);
|
void DeleteChildren(wxDataViewItem& parent);
|
||||||
|
void DeleteVolumeChildren(wxDataViewItem& parent);
|
||||||
wxDataViewItem GetItemById(int obj_idx);
|
wxDataViewItem GetItemById(int obj_idx);
|
||||||
wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx);
|
wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx);
|
||||||
|
wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx);
|
||||||
int GetIdByItem(const wxDataViewItem& item);
|
int GetIdByItem(const wxDataViewItem& item);
|
||||||
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
|
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
|
||||||
int GetVolumeIdByItem(const wxDataViewItem& item) const;
|
int GetVolumeIdByItem(const wxDataViewItem& item) const;
|
||||||
|
@ -490,7 +492,9 @@ public:
|
||||||
virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
|
virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
|
||||||
|
|
||||||
ItemType GetItemType(const wxDataViewItem &item) const ;
|
ItemType GetItemType(const wxDataViewItem &item) const ;
|
||||||
|
wxDataViewItem GetItemByType(const wxDataViewItem &parent_item, ItemType type) const;
|
||||||
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
|
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
|
||||||
|
wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const;
|
||||||
bool IsSettingsItem(const wxDataViewItem &item) const;
|
bool IsSettingsItem(const wxDataViewItem &item) const;
|
||||||
void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories);
|
void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue