diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index daed3fb72..66387b9f0 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3645,18 +3645,10 @@ void ObjectList::update_after_undo_redo() void ObjectList::update_printable_state(int obj_idx, int instance_idx) { ModelObject* object = (*m_objects)[obj_idx]; - PrintIndicator printable = piUndef; + const PrintIndicator printable = object->instances[instance_idx]->printable ? piPrintable : piUnprintable; if (object->instances.size() == 1) - { - printable = object->instances[0]->printable ? piPrintable : piUnprintable; instance_idx = -1; - } - else - { - m_objects_model->SetPrintableState(piUndef, obj_idx); - printable = object->instances[instance_idx]->printable ? piPrintable : piUnprintable; - } m_objects_model->SetPrintableState(printable, obj_idx, instance_idx); } @@ -3667,7 +3659,26 @@ void ObjectList::toggle_printable_state(wxDataViewItem item) if (!(type&(itObject|itInstance/*|itVolume*/))) return; - wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); + if (type & itObject) + { + const int obj_idx = m_objects_model->GetObjectIdByItem(item); + ModelObject* object = (*m_objects)[obj_idx]; + + // get object's printable and change it + bool printable = !m_objects_model->IsPrintable(item); + // set printable value for all instances in object + for (auto inst : object->instances) + inst->printable = printable; + + // update printable state on canvas + std::vector obj_idxs = {(size_t)obj_idx}; + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs); + + // update printable state in ObjectList + m_objects_model->SetObjectPrintableState(printable ? piPrintable : piUnprintable , item); + } + else + wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); // update scene wxGetApp().plater()->update(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 5928a4c5d..dcc47750e 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -806,22 +806,8 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren size_t counter = 0; while (counter < print_indicator.size()) { instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); + instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); - // if InstanceRoot item is just created and start to adding Instances - if (just_created && counter == 0) - { - ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); - - // use object's printable state to first instance, if it was defined - instance_node->set_printable_icon(obj_node->IsPrintable() != piUndef ? obj_node->IsPrintable() : - print_indicator[counter] ? piPrintable : piUnprintable ); - - // and set printable state for object_node to piUndef - obj_node->set_printable_icon(piUndef); - ItemChanged(parent_item); - } - else - instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); inst_root_node->Append(instance_node); // notify control const wxDataViewItem instance_item((void*)instance_node); @@ -829,9 +815,64 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren ++counter; } + // update object_node printable property + UpdateObjectPrintable(parent_item); + return wxDataViewItem((void*)instance_node); } +void ObjectDataViewModel::UpdateObjectPrintable(wxDataViewItem parent_item) +{ + const wxDataViewItem inst_root_item = GetInstanceRootItem(parent_item); + if (!inst_root_item) + return; + + ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); + + const size_t child_cnt = inst_root_node->GetChildren().Count(); + PrintIndicator obj_pi = piUnprintable; + for (size_t i=0; i < child_cnt; i++) + if (inst_root_node->GetNthChild(i)->IsPrintable() & piPrintable) { + obj_pi = piPrintable; + break; + } + // and set printable state for object_node to piUndef + ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); + obj_node->set_printable_icon(obj_pi); + ItemChanged(parent_item); +} + +// update printable property for all instances from object +void ObjectDataViewModel::UpdateInstancesPrintable(wxDataViewItem parent_item) +{ + const wxDataViewItem inst_root_item = GetInstanceRootItem(parent_item); + if (!inst_root_item) + return; + + ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); + const PrintIndicator obj_pi = obj_node->IsPrintable(); + + ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); + const size_t child_cnt = inst_root_node->GetChildren().Count(); + + for (size_t i=0; i < child_cnt; i++) + { + ObjectDataViewModelNode* inst_node = inst_root_node->GetNthChild(i); + // and set printable state for object_node to piUndef + inst_node->set_printable_icon(obj_pi); + ItemChanged(wxDataViewItem((void*)inst_node)); + } +} + +bool ObjectDataViewModel::IsPrintable(const wxDataViewItem& item) const +{ + ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); + if (!node) + return false; + + return node->IsPrintable() == piPrintable; +} + wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_item) { return AddRoot(parent_item, itLayerRoot); @@ -951,6 +992,9 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) return ret_item; } + if (node->m_type & itInstance) + UpdateObjectPrintable(wxDataViewItem(node_parent->GetParent())); + // if there was last layer item, delete this one and layers root item if (node_parent->GetChildCount() == 0 && node_parent->m_type == itLayerRoot) { @@ -1083,6 +1127,9 @@ wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &par #endif //__WXGTK__ } + // update object_node printable property + UpdateObjectPrintable(parent_item); + return ret_item; } @@ -1676,9 +1723,27 @@ wxDataViewItem ObjectDataViewModel::SetPrintableState( node->set_printable_icon(printable); ItemChanged(item); + if (subobj_idx >= 0) + UpdateObjectPrintable(GetItemById(obj_idx)); + return item; } +wxDataViewItem ObjectDataViewModel::SetObjectPrintableState( + PrintIndicator printable, + wxDataViewItem obj_item) +{ + ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)obj_item.GetID(); + if (!node) + return wxDataViewItem(0); + node->set_printable_icon(printable); + ItemChanged(obj_item); + + UpdateInstancesPrintable(obj_item); + + return obj_item; +} + void ObjectDataViewModel::Rescale() { wxDataViewItemArray all_items; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 242a487d1..24a28ecff 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -482,12 +482,17 @@ public: void UpdateSettingsDigest( const wxDataViewItem &item, const std::vector& categories); + bool IsPrintable(const wxDataViewItem &item) const; + void UpdateObjectPrintable(wxDataViewItem parent_item); + void UpdateInstancesPrintable(wxDataViewItem parent_item); + void SetVolumeBitmaps(const std::vector& volume_bmps) { m_volume_bmps = volume_bmps; } void SetWarningBitmap(wxBitmap* bitmap) { m_warning_bmp = bitmap; } void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); wxDataViewItem SetPrintableState( PrintIndicator printable, int obj_idx, int subobj_idx = -1, ItemType subobj_type = itInstance); + wxDataViewItem SetObjectPrintableState(PrintIndicator printable, wxDataViewItem obj_item); void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } // Rescale bitmaps for existing Items