FIX: support to import color in standard 3mf

Change-Id: I631e3f62c4d996924efafdfe9352d1585ad4d130
(cherry picked from commit ec08a5194b45a98973eb53ab0022a0799238134c)
This commit is contained in:
zhimin.zeng 2022-09-13 14:36:51 +08:00 committed by Lane.Wei
parent 56fddf988a
commit 084ea583fb
3 changed files with 93 additions and 15 deletions

View File

@ -160,6 +160,8 @@ const unsigned int METADATA_STR_LEN = 9;
static constexpr const char* MODEL_TAG = "model";
static constexpr const char* RESOURCES_TAG = "resources";
static constexpr const char* COLOR_GROUP_TAG = "m:colorgroup";
static constexpr const char* COLOR_TAG = "m:color";
static constexpr const char* OBJECT_TAG = "object";
static constexpr const char* MESH_TAG = "mesh";
static constexpr const char* MESH_STAT_TAG = "mesh_stat";
@ -193,6 +195,7 @@ static constexpr const char* SLICE_HEADER_ITEM_TAG = "header_item";
// BBS: encrypt
static constexpr const char* RELATIONSHIP_TAG = "Relationship";
static constexpr const char* PID_ATTR = "pid";
static constexpr const char* PUUID_ATTR = "p:uuid";
static constexpr const char* PPATH_ATTR = "p:path";
static constexpr const char* OBJECT_UUID_SUFFIX = "-41cb-4c03-9d28-80fed5dfa1dc";
@ -203,6 +206,7 @@ static constexpr const char* RELS_TYPE_ATTR = "Type";
static constexpr const char* UNIT_ATTR = "unit";
static constexpr const char* NAME_ATTR = "name";
static constexpr const char* COLOR_ATTR = "color";
static constexpr const char* TYPE_ATTR = "type";
static constexpr const char* ID_ATTR = "id";
static constexpr const char* X_ATTR = "x";
@ -549,6 +553,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
//int subobject_id;
std::string name;
std::string uuid;
int pid{-1};
//bool is_model_object;
CurrentObject() { reset(); }
@ -713,6 +718,9 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
PlateData* m_curr_plater;
CurrentInstance m_curr_instance;
int m_current_color_group{-1};
std::map<int, std::string> m_group_id_to_color;
public:
_BBS_3MF_Importer();
~_BBS_3MF_Importer();
@ -778,6 +786,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
bool _handle_start_object(const char** attributes, unsigned int num_attributes);
bool _handle_end_object();
bool _handle_start_color_group(const char **attributes, unsigned int num_attributes);
bool _handle_end_color_group();
bool _handle_start_color(const char **attributes, unsigned int num_attributes);
bool _handle_end_color();
bool _handle_start_mesh(const char** attributes, unsigned int num_attributes);
bool _handle_end_mesh();
@ -1314,6 +1328,20 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
}
}
std::map<int, int> color_group_id_to_extruder_id_map;
std::map<std::string, int> color_to_extruder_id_map;
int extruder_id = 0;
for (auto group_iter = m_group_id_to_color.begin(); group_iter != m_group_id_to_color.end(); ++group_iter) {
auto color_iter = color_to_extruder_id_map.find(group_iter->second);
if (color_iter == color_to_extruder_id_map.end()) {
++extruder_id;
color_to_extruder_id_map[group_iter->second] = extruder_id;
color_group_id_to_extruder_id_map[group_iter->first] = extruder_id;
} else {
color_group_id_to_extruder_id_map[group_iter->first] = color_iter->second;
}
}
for (const IdToModelObjectMap::value_type& object : m_objects) {
if (object.second >= int(m_model->objects.size())) {
add_error("invalid object, id: "+std::to_string(object.first.second));
@ -1383,6 +1411,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
volumes.emplace_back(object_id.second);
}
IdToCurrentObjectMap::const_iterator current_object = m_current_objects.find(object.first);
if (current_object != m_current_objects.end()) {
// get name
model_object->name = current_object->second.name;
// get color
auto extruder_itor = color_group_id_to_extruder_id_map.find(current_object->second.pid);
if (extruder_itor != color_group_id_to_extruder_id_map.end()) {
model_object->config.set_key_value("extruder", new ConfigOptionInt(extruder_itor->second));
}
}
// select as volumes
volumes_ptr = &volumes;
}
@ -2213,6 +2253,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
res = _handle_start_resources(attributes, num_attributes);
else if (::strcmp(OBJECT_TAG, name) == 0)
res = _handle_start_object(attributes, num_attributes);
else if (::strcmp(COLOR_GROUP_TAG, name) == 0)
res = _handle_start_color_group(attributes, num_attributes);
else if (::strcmp(COLOR_TAG, name) == 0)
res = _handle_start_color(attributes, num_attributes);
else if (::strcmp(MESH_TAG, name) == 0)
res = _handle_start_mesh(attributes, num_attributes);
else if (::strcmp(VERTICES_TAG, name) == 0)
@ -2251,6 +2295,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
res = _handle_end_resources();
else if (::strcmp(OBJECT_TAG, name) == 0)
res = _handle_end_object();
else if (::strcmp(COLOR_GROUP_TAG, name) == 0)
res = _handle_end_color_group();
else if (::strcmp(COLOR_TAG, name) == 0)
res = _handle_end_color();
else if (::strcmp(MESH_TAG, name) == 0)
res = _handle_end_mesh();
else if (::strcmp(VERTICES_TAG, name) == 0)
@ -2434,6 +2482,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
m_curr_object->name = bbs_get_attribute_value_string(attributes, num_attributes, NAME_ATTR);
m_curr_object->uuid = bbs_get_attribute_value_string(attributes, num_attributes, PUUID_ATTR);
m_curr_object->pid = bbs_get_attribute_value_int(attributes, num_attributes, PID_ATTR);
}
return true;
@ -2543,6 +2592,31 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
return true;
}
bool _BBS_3MF_Importer::_handle_start_color_group(const char **attributes, unsigned int num_attributes)
{
m_current_color_group = bbs_get_attribute_value_int(attributes, num_attributes, ID_ATTR);
return true;
}
bool _BBS_3MF_Importer::_handle_end_color_group()
{
// do nothing
return true;
}
bool _BBS_3MF_Importer::_handle_start_color(const char **attributes, unsigned int num_attributes)
{
std::string color = bbs_get_attribute_value_string(attributes, num_attributes, COLOR_ATTR);
m_group_id_to_color[m_current_color_group] = color;
return true;
}
bool _BBS_3MF_Importer::_handle_end_color()
{
// do nothing
return true;
}
bool _BBS_3MF_Importer::_handle_start_mesh(const char** attributes, unsigned int num_attributes)
{
// reset current geometry

View File

@ -608,11 +608,15 @@ void Model::convert_multipart_object(unsigned int max_extruders)
// Revert the centering operation.
trafo_volume.set_offset(trafo_volume.get_offset() - o->origin_translation);
int counter = 1;
auto copy_volume = [o, max_extruders, &counter, &extruder_counter](ModelVolume *new_v) {
auto copy_volume = [o, v, max_extruders, &counter, &extruder_counter](ModelVolume *new_v) {
assert(new_v != nullptr);
new_v->name = (counter > 1) ? o->name + "_" + std::to_string(counter++) : o->name;
//BBS: use default extruder id
//new_v->config.set("extruder", auto_extruder_id(max_extruders, extruder_counter));
//BBS: Use extruder priority: volumn > object > default
if (v->config.option("extruder"))
new_v->config.set("extruder", v->config.extruder());
else if (o->config.option("extruder"))
new_v->config.set("extruder", o->config.extruder());
return new_v;
};
if (o->instances.empty()) {

View File

@ -2709,8 +2709,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % file_version.to_string();
// 1. add extruder for prusa model if the number of existing extruders is not enough
// 2. add extruder for BBS model if only import geometry
if (en_3mf_file_type == En3mfType::From_Prusa || (en_3mf_file_type == En3mfType::From_BBS && load_model && !load_config)) {
// 2. add extruder for BBS or Other model if only import geometry
if (en_3mf_file_type == En3mfType::From_Prusa || (load_model && !load_config)) {
std::set<int> extruderIds;
for (ModelObject *o : model.objects) {
if (o->config.option("extruder")) extruderIds.insert(o->config.extruder());
@ -3082,16 +3082,16 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
// convert_model_if(model, answer_convert_from_imperial_units == wxID_YES);
}
// if (model.looks_like_multipart_object()) {
// MessageDialog msg_dlg(q, _L(
// "This file contains several objects positioned at multiple heights.\n"
// "Instead of considering them as multiple objects, should \n"
// "the file be loaded as a single object having multiple parts?") + "\n",
// _L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO);
// if (msg_dlg.ShowModal() == wxID_YES) {
// model.convert_multipart_object(filaments_cnt);
// }
//}
if (model.looks_like_multipart_object()) {
MessageDialog msg_dlg(q, _L(
"This file contains several objects positioned at multiple heights.\n"
"Instead of considering them as multiple objects, should \n"
"the file be loaded as a single object having multiple parts?") + "\n",
_L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO);
if (msg_dlg.ShowModal() == wxID_YES) {
model.convert_multipart_object(filaments_cnt);
}
}
}
// else if ((wxGetApp().get_mode() == comSimple) && (type_3mf || type_any_amf) && model_has_advanced_features(model)) {
// MessageDialog msg_dlg(q, _L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?")+"\n",