mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 00:45:57 +08:00
Cut WIP:
* ObjectDataViewModel: Respect to the volume id, when adding the new volume to the object * 3mf : Save/Load info about connectors
This commit is contained in:
parent
0201a5055a
commit
d1c871758b
@ -409,6 +409,19 @@ namespace Slic3r {
|
|||||||
VolumeMetadataList volumes;
|
VolumeMetadataList volumes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CutObjectInfo
|
||||||
|
{
|
||||||
|
struct Connector
|
||||||
|
{
|
||||||
|
int volume_id;
|
||||||
|
int type;
|
||||||
|
float r_tolerance;
|
||||||
|
float h_tolerance;
|
||||||
|
};
|
||||||
|
CutObjectBase id;
|
||||||
|
std::vector<Connector> connectors;
|
||||||
|
};
|
||||||
|
|
||||||
// Map from a 1 based 3MF object ID to a 0 based ModelObject index inside m_model->objects.
|
// Map from a 1 based 3MF object ID to a 0 based ModelObject index inside m_model->objects.
|
||||||
typedef std::map<int, int> IdToModelObjectMap;
|
typedef std::map<int, int> IdToModelObjectMap;
|
||||||
typedef std::map<int, ComponentsList> IdToAliasesMap;
|
typedef std::map<int, ComponentsList> IdToAliasesMap;
|
||||||
@ -417,7 +430,7 @@ namespace Slic3r {
|
|||||||
typedef std::map<int, Geometry> IdToGeometryMap;
|
typedef std::map<int, Geometry> IdToGeometryMap;
|
||||||
typedef std::map<int, std::vector<coordf_t>> IdToLayerHeightsProfileMap;
|
typedef std::map<int, std::vector<coordf_t>> IdToLayerHeightsProfileMap;
|
||||||
typedef std::map<int, t_layer_config_ranges> IdToLayerConfigRangesMap;
|
typedef std::map<int, t_layer_config_ranges> IdToLayerConfigRangesMap;
|
||||||
typedef std::map<int, CutObjectBase> IdToCutObjectIdMap;
|
typedef std::map<int, CutObjectInfo> IdToCutObjectInfoMap;
|
||||||
typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap;
|
typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap;
|
||||||
typedef std::map<int, std::vector<sla::DrainHole>> IdToSlaDrainHolesMap;
|
typedef std::map<int, std::vector<sla::DrainHole>> IdToSlaDrainHolesMap;
|
||||||
|
|
||||||
@ -445,7 +458,7 @@ namespace Slic3r {
|
|||||||
IdToGeometryMap m_geometries;
|
IdToGeometryMap m_geometries;
|
||||||
CurrentConfig m_curr_config;
|
CurrentConfig m_curr_config;
|
||||||
IdToMetadataMap m_objects_metadata;
|
IdToMetadataMap m_objects_metadata;
|
||||||
IdToCutObjectIdMap m_cut_object_ids;
|
IdToCutObjectInfoMap m_cut_object_infos;
|
||||||
IdToLayerHeightsProfileMap m_layer_heights_profiles;
|
IdToLayerHeightsProfileMap m_layer_heights_profiles;
|
||||||
IdToLayerConfigRangesMap m_layer_config_ranges;
|
IdToLayerConfigRangesMap m_layer_config_ranges;
|
||||||
IdToSlaSupportPointsMap m_sla_support_points;
|
IdToSlaSupportPointsMap m_sla_support_points;
|
||||||
@ -774,11 +787,6 @@ namespace Slic3r {
|
|||||||
return false;
|
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.
|
// 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);
|
IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.second + 1);
|
||||||
if (obj_layer_heights_profile != m_layer_heights_profiles.end())
|
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))
|
if (!_generate_volumes(*model_object, obj_geometry->second, *volumes_ptr, config_substitutions))
|
||||||
return false;
|
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
|
// If instances contain a single volume, the volume offset should be 0,0,0
|
||||||
@ -979,22 +1000,39 @@ namespace Slic3r {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdToCutObjectIdMap::iterator object_item = m_cut_object_ids.find(obj_idx);
|
IdToCutObjectInfoMap::iterator object_item = m_cut_object_infos.find(obj_idx);
|
||||||
if (object_item != m_cut_object_ids.end()) {
|
if (object_item != m_cut_object_infos.end()) {
|
||||||
add_error("Found duplicated cut_object_id");
|
add_error("Found duplicated cut_object_id");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& obj_cut_id : object_tree) {
|
CutObjectBase cut_id;
|
||||||
if (obj_cut_id.first != "cut_id")
|
std::vector<CutObjectInfo::Connector> connectors;
|
||||||
continue;
|
|
||||||
pt::ptree cut_id_tree = obj_cut_id.second;
|
for (const auto& obj_cut_info : object_tree) {
|
||||||
ObjectID obj_id(cut_id_tree.get<size_t>("<xmlattr>.id"));
|
if (obj_cut_info.first == "cut_id") {
|
||||||
CutObjectBase cut_id(ObjectID(cut_id_tree.get<size_t>("<xmlattr>.id")),
|
pt::ptree cut_id_tree = obj_cut_info.second;
|
||||||
|
cut_id = CutObjectBase(ObjectID( cut_id_tree.get<size_t>("<xmlattr>.id")),
|
||||||
cut_id_tree.get<size_t>("<xmlattr>.check_sum"),
|
cut_id_tree.get<size_t>("<xmlattr>.check_sum"),
|
||||||
cut_id_tree.get<size_t>("<xmlattr>.connectors_cnt"));
|
cut_id_tree.get<size_t>("<xmlattr>.connectors_cnt"));
|
||||||
m_cut_object_ids.insert({ obj_idx, std::move(cut_id) });
|
|
||||||
}
|
}
|
||||||
|
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<int>("<xmlattr>.volume_id"),
|
||||||
|
connector_tree.get<int>("<xmlattr>.type"),
|
||||||
|
connector_tree.get<float>("<xmlattr>.r_tolerance"),
|
||||||
|
connector_tree.get<float>("<xmlattr>.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("<xmlattr>.id", object->cut_id.id().id);
|
cut_id_tree.put("<xmlattr>.id", object->cut_id.id().id);
|
||||||
cut_id_tree.put("<xmlattr>.check_sum", object->cut_id.check_sum());
|
cut_id_tree.put("<xmlattr>.check_sum", object->cut_id.check_sum());
|
||||||
cut_id_tree.put("<xmlattr>.connectors_cnt", object->cut_id.connectors_cnt());
|
cut_id_tree.put("<xmlattr>.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("<xmlattr>.volume_id", volume_idx);
|
||||||
|
connectors_tree.put("<xmlattr>.type", int(volume->cut_info.connector_type));
|
||||||
|
connectors_tree.put("<xmlattr>.r_tolerance", volume->cut_info.radius_tolerance);
|
||||||
|
connectors_tree.put("<xmlattr>.h_tolerance", volume->cut_info.height_tolerance);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tree.empty()) {
|
if (!tree.empty()) {
|
||||||
@ -2876,6 +2926,10 @@ namespace Slic3r {
|
|||||||
boost::replace_all(out, "><object", ">\n <object");
|
boost::replace_all(out, "><object", ">\n <object");
|
||||||
boost::replace_all(out, "><cut_id", ">\n <cut_id");
|
boost::replace_all(out, "><cut_id", ">\n <cut_id");
|
||||||
boost::replace_all(out, "></cut_id>", ">\n </cut_id>");
|
boost::replace_all(out, "></cut_id>", ">\n </cut_id>");
|
||||||
|
boost::replace_all(out, "><connectors", ">\n <connectors");
|
||||||
|
boost::replace_all(out, "></connectors>", ">\n </connectors>");
|
||||||
|
boost::replace_all(out, "><connector", ">\n <connector");
|
||||||
|
boost::replace_all(out, "></connector>", ">\n </connector>");
|
||||||
boost::replace_all(out, "></object>", ">\n </object>");
|
boost::replace_all(out, "></object>", ">\n </object>");
|
||||||
// OR just
|
// OR just
|
||||||
boost::replace_all(out, "><", ">\n<");
|
boost::replace_all(out, "><", ">\n<");
|
||||||
|
@ -730,9 +730,9 @@ public:
|
|||||||
float height_tolerance{ 0.f };// [0.f : 1.f]
|
float height_tolerance{ 0.f };// [0.f : 1.f]
|
||||||
|
|
||||||
CutInfo() = default;
|
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_connector(true),
|
||||||
is_processed(false),
|
is_processed(processed),
|
||||||
connector_type(type),
|
connector_type(type),
|
||||||
radius_tolerance(rad_tolerance),
|
radius_tolerance(rad_tolerance),
|
||||||
height_tolerance(h_tolerance)
|
height_tolerance(h_tolerance)
|
||||||
|
@ -288,6 +288,9 @@ public:
|
|||||||
void changed_object(const int obj_idx = -1) const;
|
void changed_object(const int obj_idx = -1) const;
|
||||||
void part_selection_changed();
|
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<bool(const ModelVolume*)> add_to_selection = nullptr);
|
||||||
// Add object to the list
|
// Add object to the list
|
||||||
void add_object_to_list(size_t obj_idx, bool call_selection_changed = true);
|
void add_object_to_list(size_t obj_idx, bool call_selection_changed = true);
|
||||||
// Delete object from the list
|
// Delete object from the list
|
||||||
@ -392,7 +395,7 @@ public:
|
|||||||
void toggle_printable_state();
|
void toggle_printable_state();
|
||||||
|
|
||||||
void set_extruder_for_selected_items(const int extruder) const ;
|
void set_extruder_for_selected_items(const int extruder) const ;
|
||||||
wxDataViewItemArray reorder_volumes_and_get_selection(int obj_idx, std::function<bool(const ModelVolume*)> add_to_selection = nullptr);
|
wxDataViewItemArray reorder_volumes_and_get_selection(size_t obj_idx, std::function<bool(const ModelVolume*)> add_to_selection = nullptr);
|
||||||
void apply_volumes_order();
|
void apply_volumes_order();
|
||||||
bool has_paint_on_segmentation();
|
bool has_paint_on_segmentation();
|
||||||
|
|
||||||
|
@ -373,13 +373,12 @@ void ObjectDataViewModel::UpdateBitmapForNode(ObjectDataViewModelNode* node, con
|
|||||||
UpdateBitmapForNode(node);
|
UpdateBitmapForNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDataViewItem ObjectDataViewModel::Add(const wxString &name,
|
wxDataViewItem ObjectDataViewModel::AddObject(const wxString &name,
|
||||||
const int extruder,
|
const wxString& extruder,
|
||||||
const std::string& warning_icon_name,
|
const std::string& warning_icon_name,
|
||||||
const bool has_lock)
|
const bool has_lock)
|
||||||
{
|
{
|
||||||
const wxString extruder_str = extruder == 0 ? _L("default") : wxString::Format("%d", extruder);
|
auto root = new ObjectDataViewModelNode(name, extruder);
|
||||||
auto root = new ObjectDataViewModelNode(name, extruder_str);
|
|
||||||
// Add warning icon if detected auto-repaire
|
// Add warning icon if detected auto-repaire
|
||||||
UpdateBitmapForNode(root, warning_icon_name, has_lock);
|
UpdateBitmapForNode(root, warning_icon_name, has_lock);
|
||||||
|
|
||||||
@ -394,37 +393,20 @@ wxDataViewItem ObjectDataViewModel::Add(const wxString &name,
|
|||||||
|
|
||||||
wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent_item,
|
wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent_item,
|
||||||
const wxString &name,
|
const wxString &name,
|
||||||
|
const int volume_idx,
|
||||||
const Slic3r::ModelVolumeType volume_type,
|
const Slic3r::ModelVolumeType volume_type,
|
||||||
const std::string& warning_icon_name/* = std::string()*/,
|
const std::string& warning_icon_name,
|
||||||
const int extruder/* = 0*/,
|
const wxString& extruder)
|
||||||
const bool create_frst_child/* = true*/)
|
|
||||||
{
|
{
|
||||||
ObjectDataViewModelNode *root = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
ObjectDataViewModelNode *root = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
||||||
if (!root) return wxDataViewItem(0);
|
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
|
// get insertion position according to the existed Layers and/or Instances Items
|
||||||
int insert_position = get_root_idx(root, itLayerRoot);
|
int insert_position = get_root_idx(root, itLayerRoot);
|
||||||
if (insert_position < 0)
|
if (insert_position < 0)
|
||||||
insert_position = get_root_idx(root, itInstanceRoot);
|
insert_position = get_root_idx(root, itInstanceRoot);
|
||||||
|
|
||||||
if (create_frst_child && root->m_volumes_cnt == 0)
|
const auto node = new ObjectDataViewModelNode(root, name, volume_type, extruder, volume_idx);
|
||||||
{
|
|
||||||
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);
|
|
||||||
UpdateBitmapForNode(node, warning_icon_name, root->has_lock() && volume_type < ModelVolumeType::PARAMETER_MODIFIER);
|
UpdateBitmapForNode(node, warning_icon_name, root->has_lock() && volume_type < ModelVolumeType::PARAMETER_MODIFIER);
|
||||||
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
|
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,
|
wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item,
|
||||||
const t_layer_height_range& layer_range,
|
const t_layer_height_range& layer_range,
|
||||||
const int extruder/* = 0*/,
|
const wxString& extruder,
|
||||||
const int index /* = -1*/)
|
const int index /* = -1*/)
|
||||||
{
|
{
|
||||||
ObjectDataViewModelNode *parent_node = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
ObjectDataViewModelNode *parent_node = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
||||||
if (!parent_node) return wxDataViewItem(0);
|
if (!parent_node) return wxDataViewItem(0);
|
||||||
|
|
||||||
wxString extruder_str = extruder == 0 ? _(L("default")) : wxString::Format("%d", extruder);
|
|
||||||
|
|
||||||
// get LayerRoot node
|
// get LayerRoot node
|
||||||
ObjectDataViewModelNode *layer_root_node;
|
ObjectDataViewModelNode *layer_root_node;
|
||||||
wxDataViewItem layer_root_item;
|
wxDataViewItem layer_root_item;
|
||||||
@ -655,7 +635,7 @@ wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add layer node
|
// 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)
|
if (index < 0)
|
||||||
layer_root_node->Append(layer_node);
|
layer_root_node->Append(layer_node);
|
||||||
else
|
else
|
||||||
|
@ -271,16 +271,16 @@ public:
|
|||||||
ObjectDataViewModel();
|
ObjectDataViewModel();
|
||||||
~ObjectDataViewModel();
|
~ObjectDataViewModel();
|
||||||
|
|
||||||
wxDataViewItem Add( const wxString &name,
|
wxDataViewItem AddObject( const wxString &name,
|
||||||
const int extruder,
|
const wxString& extruder,
|
||||||
const std::string& warning_icon_name,
|
const std::string& warning_icon_name,
|
||||||
const bool has_lock);
|
const bool has_lock);
|
||||||
wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item,
|
wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item,
|
||||||
const wxString &name,
|
const wxString &name,
|
||||||
|
const int volume_idx,
|
||||||
const Slic3r::ModelVolumeType volume_type,
|
const Slic3r::ModelVolumeType volume_type,
|
||||||
const std::string& warning_icon_name = std::string(),
|
const std::string& warning_icon_name,
|
||||||
const int extruder = 0,
|
const wxString& extruder);
|
||||||
const bool create_frst_child = true);
|
|
||||||
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
||||||
wxDataViewItem AddInfoChild(const wxDataViewItem &parent_item, InfoItemType info_type);
|
wxDataViewItem AddInfoChild(const wxDataViewItem &parent_item, InfoItemType info_type);
|
||||||
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num);
|
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num);
|
||||||
@ -288,7 +288,7 @@ public:
|
|||||||
wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item);
|
wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item);
|
||||||
wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item,
|
wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item,
|
||||||
const t_layer_height_range& layer_range,
|
const t_layer_height_range& layer_range,
|
||||||
const int extruder = 0,
|
const wxString& extruder,
|
||||||
const int index = -1);
|
const int index = -1);
|
||||||
size_t GetItemIndexForFirstVolume(ObjectDataViewModelNode* node_parent);
|
size_t GetItemIndexForFirstVolume(ObjectDataViewModelNode* node_parent);
|
||||||
wxDataViewItem Delete(const wxDataViewItem &item);
|
wxDataViewItem Delete(const wxDataViewItem &item);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user