From d1c871758b72ec7a683df01de4907169978b4785 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 29 Sep 2022 12:26:08 +0200 Subject: [PATCH] Cut WIP: * ObjectDataViewModel: Respect to the volume id, when adding the new volume to the object * 3mf : Save/Load info about connectors --- src/libslic3r/Format/3mf.cpp | 90 ++++++++++++++++++++------ src/libslic3r/Model.hpp | 4 +- src/slic3r/GUI/GUI_ObjectList.hpp | 5 +- src/slic3r/GUI/ObjectDataViewModel.cpp | 38 +++-------- src/slic3r/GUI/ObjectDataViewModel.hpp | 12 ++-- 5 files changed, 93 insertions(+), 56 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 4251110c4..f2056b8bd 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -409,6 +409,19 @@ namespace Slic3r { VolumeMetadataList volumes; }; + struct CutObjectInfo + { + struct Connector + { + int volume_id; + int type; + float r_tolerance; + float h_tolerance; + }; + CutObjectBase id; + std::vector connectors; + }; + // Map from a 1 based 3MF object ID to a 0 based ModelObject index inside m_model->objects. typedef std::map IdToModelObjectMap; typedef std::map IdToAliasesMap; @@ -417,7 +430,7 @@ namespace Slic3r { typedef std::map IdToGeometryMap; typedef std::map> IdToLayerHeightsProfileMap; typedef std::map IdToLayerConfigRangesMap; - typedef std::map IdToCutObjectIdMap; + typedef std::map IdToCutObjectInfoMap; typedef std::map> IdToSlaSupportPointsMap; typedef std::map> IdToSlaDrainHolesMap; @@ -445,7 +458,7 @@ namespace Slic3r { IdToGeometryMap m_geometries; CurrentConfig m_curr_config; IdToMetadataMap m_objects_metadata; - IdToCutObjectIdMap m_cut_object_ids; + IdToCutObjectInfoMap m_cut_object_infos; IdToLayerHeightsProfileMap m_layer_heights_profiles; IdToLayerConfigRangesMap m_layer_config_ranges; IdToSlaSupportPointsMap m_sla_support_points; @@ -774,11 +787,6 @@ namespace Slic3r { return false; } - // m_cut_object_ids are indexed by a 1 based model object index. - IdToCutObjectIdMap::iterator cut_object_id = m_cut_object_ids.find(object.second + 1); - if (cut_object_id != m_cut_object_ids.end()) - model_object->cut_id = std::move(cut_object_id->second); - // m_layer_heights_profiles are indexed by a 1 based model object index. IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.second + 1); if (obj_layer_heights_profile != m_layer_heights_profiles.end()) @@ -831,6 +839,19 @@ namespace Slic3r { if (!_generate_volumes(*model_object, obj_geometry->second, *volumes_ptr, config_substitutions)) return false; + + // Apply cut information for object if any was loaded + // m_cut_object_ids are indexed by a 1 based model object index. + IdToCutObjectInfoMap::iterator cut_object_info = m_cut_object_infos.find(object.second + 1); + if (cut_object_info != m_cut_object_infos.end()) { + model_object->cut_id = cut_object_info->second.id; + + for (auto connector : cut_object_info->second.connectors) { + assert(0 <= connector.volume_id && connector.volume_id <= int(model_object->volumes.size())); + model_object->volumes[connector.volume_id]->cut_info = + ModelVolume::CutInfo(CutConnectorType(connector.type), connector.r_tolerance, connector.h_tolerance, true); + } + } } // If instances contain a single volume, the volume offset should be 0,0,0 @@ -979,22 +1000,39 @@ namespace Slic3r { continue; } - IdToCutObjectIdMap::iterator object_item = m_cut_object_ids.find(obj_idx); - if (object_item != m_cut_object_ids.end()) { + IdToCutObjectInfoMap::iterator object_item = m_cut_object_infos.find(obj_idx); + if (object_item != m_cut_object_infos.end()) { add_error("Found duplicated cut_object_id"); continue; } - for (const auto& obj_cut_id : object_tree) { - if (obj_cut_id.first != "cut_id") - continue; - pt::ptree cut_id_tree = obj_cut_id.second; - ObjectID obj_id(cut_id_tree.get(".id")); - CutObjectBase cut_id(ObjectID(cut_id_tree.get(".id")), - cut_id_tree.get(".check_sum"), - cut_id_tree.get(".connectors_cnt")); - m_cut_object_ids.insert({ obj_idx, std::move(cut_id) }); + CutObjectBase cut_id; + std::vector connectors; + + for (const auto& obj_cut_info : object_tree) { + if (obj_cut_info.first == "cut_id") { + pt::ptree cut_id_tree = obj_cut_info.second; + cut_id = CutObjectBase(ObjectID( cut_id_tree.get(".id")), + cut_id_tree.get(".check_sum"), + cut_id_tree.get(".connectors_cnt")); + } + if (obj_cut_info.first == "connectors") { + pt::ptree cut_connectors_tree = obj_cut_info.second; + for (const auto& cut_connector : cut_connectors_tree) { + if (cut_connector.first != "connector") + continue; + pt::ptree connector_tree = cut_connector.second; + CutObjectInfo::Connector connector = {connector_tree.get(".volume_id"), + connector_tree.get(".type"), + connector_tree.get(".r_tolerance"), + connector_tree.get(".h_tolerance")}; + connectors.emplace_back(connector); + } + } } + + CutObjectInfo cut_info {cut_id, connectors}; + m_cut_object_infos.insert({ obj_idx, cut_info }); } } } @@ -2865,6 +2903,18 @@ namespace Slic3r { cut_id_tree.put(".id", object->cut_id.id().id); cut_id_tree.put(".check_sum", object->cut_id.check_sum()); cut_id_tree.put(".connectors_cnt", object->cut_id.connectors_cnt()); + + int volume_idx = -1; + for (const ModelVolume* volume : object->volumes) { + ++volume_idx; + if (volume->is_cut_connector()) { + pt::ptree& connectors_tree = obj_tree.add("connectors.connector", ""); + connectors_tree.put(".volume_id", volume_idx); + connectors_tree.put(".type", int(volume->cut_info.connector_type)); + connectors_tree.put(".r_tolerance", volume->cut_info.radius_tolerance); + connectors_tree.put(".h_tolerance", volume->cut_info.height_tolerance); + } + } } if (!tree.empty()) { @@ -2876,6 +2926,10 @@ namespace Slic3r { boost::replace_all(out, ">\n \n ", ">\n "); + boost::replace_all(out, ">\n ", ">\n "); + boost::replace_all(out, ">\n ", ">\n "); boost::replace_all(out, ">", ">\n "); // OR just boost::replace_all(out, "><", ">\n<"); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index cc2c612fe..01cd37414 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -730,9 +730,9 @@ public: float height_tolerance{ 0.f };// [0.f : 1.f] CutInfo() = default; - CutInfo(CutConnectorType type, float rad_tolerance, float h_tolerance) : + CutInfo(CutConnectorType type, float rad_tolerance, float h_tolerance, bool processed = false) : is_connector(true), - is_processed(false), + is_processed(processed), connector_type(type), radius_tolerance(rad_tolerance), height_tolerance(h_tolerance) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 79f8e74c6..3ae0d0533 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -288,6 +288,9 @@ public: void changed_object(const int obj_idx = -1) const; void part_selection_changed(); + // Add object's volumes to the list + // Return selected items, if add_to_selection is defined + wxDataViewItemArray add_volumes_to_object_in_list(size_t obj_idx, std::function add_to_selection = nullptr); // Add object to the list void add_object_to_list(size_t obj_idx, bool call_selection_changed = true); // Delete object from the list @@ -392,7 +395,7 @@ public: void toggle_printable_state(); void set_extruder_for_selected_items(const int extruder) const ; - wxDataViewItemArray reorder_volumes_and_get_selection(int obj_idx, std::function add_to_selection = nullptr); + wxDataViewItemArray reorder_volumes_and_get_selection(size_t obj_idx, std::function add_to_selection = nullptr); void apply_volumes_order(); bool has_paint_on_segmentation(); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 4c592b878..0475fe395 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -373,13 +373,12 @@ void ObjectDataViewModel::UpdateBitmapForNode(ObjectDataViewModelNode* node, con UpdateBitmapForNode(node); } -wxDataViewItem ObjectDataViewModel::Add(const wxString &name, - const int extruder, +wxDataViewItem ObjectDataViewModel::AddObject(const wxString &name, + const wxString& extruder, const std::string& warning_icon_name, const bool has_lock) { - const wxString extruder_str = extruder == 0 ? _L("default") : wxString::Format("%d", extruder); - auto root = new ObjectDataViewModelNode(name, extruder_str); + auto root = new ObjectDataViewModelNode(name, extruder); // Add warning icon if detected auto-repaire UpdateBitmapForNode(root, warning_icon_name, has_lock); @@ -394,37 +393,20 @@ wxDataViewItem ObjectDataViewModel::Add(const wxString &name, wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent_item, const wxString &name, + const int volume_idx, const Slic3r::ModelVolumeType volume_type, - const std::string& warning_icon_name/* = std::string()*/, - const int extruder/* = 0*/, - const bool create_frst_child/* = true*/) + const std::string& warning_icon_name, + const wxString& extruder) { ObjectDataViewModelNode *root = static_cast(parent_item.GetID()); if (!root) return wxDataViewItem(0); - wxString extruder_str = extruder == 0 ? _(L("default")) : wxString::Format("%d", extruder); - // get insertion position according to the existed Layers and/or Instances Items int insert_position = get_root_idx(root, itLayerRoot); if (insert_position < 0) insert_position = get_root_idx(root, itInstanceRoot); - if (create_frst_child && root->m_volumes_cnt == 0) - { - const Slic3r::ModelVolumeType type = Slic3r::ModelVolumeType::MODEL_PART; - const auto node = new ObjectDataViewModelNode(root, root->m_name, type, extruder_str, 0); - UpdateBitmapForNode(node, root->warning_icon_name(), root->has_lock()); - - insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position); - // notify control - const wxDataViewItem child((void*)node); - ItemAdded(parent_item, child); - - root->m_volumes_cnt++; - if (insert_position >= 0) insert_position++; - } - - const auto node = new ObjectDataViewModelNode(root, name, volume_type, extruder_str, root->m_volumes_cnt); + const auto node = new ObjectDataViewModelNode(root, name, volume_type, extruder, volume_idx); UpdateBitmapForNode(node, warning_icon_name, root->has_lock() && volume_type < ModelVolumeType::PARAMETER_MODIFIER); insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position); @@ -631,14 +613,12 @@ wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_i wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, const t_layer_height_range& layer_range, - const int extruder/* = 0*/, + const wxString& extruder, const int index /* = -1*/) { ObjectDataViewModelNode *parent_node = static_cast(parent_item.GetID()); if (!parent_node) return wxDataViewItem(0); - wxString extruder_str = extruder == 0 ? _(L("default")) : wxString::Format("%d", extruder); - // get LayerRoot node ObjectDataViewModelNode *layer_root_node; wxDataViewItem layer_root_item; @@ -655,7 +635,7 @@ wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_ } // Add layer node - ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, layer_range, index, extruder_str); + ObjectDataViewModelNode *layer_node = new ObjectDataViewModelNode(layer_root_node, layer_range, index, extruder); if (index < 0) layer_root_node->Append(layer_node); else diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp index bc9144803..55dbaafe2 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.hpp +++ b/src/slic3r/GUI/ObjectDataViewModel.hpp @@ -271,16 +271,16 @@ public: ObjectDataViewModel(); ~ObjectDataViewModel(); - wxDataViewItem Add( const wxString &name, - const int extruder, + wxDataViewItem AddObject( const wxString &name, + const wxString& extruder, const std::string& warning_icon_name, const bool has_lock); wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item, const wxString &name, + const int volume_idx, const Slic3r::ModelVolumeType volume_type, - const std::string& warning_icon_name = std::string(), - const int extruder = 0, - const bool create_frst_child = true); + const std::string& warning_icon_name, + const wxString& extruder); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInfoChild(const wxDataViewItem &parent_item, InfoItemType info_type); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); @@ -288,7 +288,7 @@ public: wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, const t_layer_height_range& layer_range, - const int extruder = 0, + const wxString& extruder, const int index = -1); size_t GetItemIndexForFirstVolume(ObjectDataViewModelNode* node_parent); wxDataViewItem Delete(const wxDataViewItem &item);