mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	FIX: support to import color in standard 3mf
Change-Id: I631e3f62c4d996924efafdfe9352d1585ad4d130 (cherry picked from commit ec08a5194b45a98973eb53ab0022a0799238134c)
This commit is contained in:
		
							parent
							
								
									56fddf988a
								
							
						
					
					
						commit
						084ea583fb
					
				
					 3 changed files with 93 additions and 15 deletions
				
			
		|  | @ -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
 | ||||
|  |  | |||
|  | @ -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()) { | ||||
|  |  | |||
|  | @ -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",
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 zhimin.zeng
						zhimin.zeng