mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/Prusa3d/PrusaSlicer
This commit is contained in:
		
						commit
						e2f91cacab
					
				
					 23 changed files with 252 additions and 167 deletions
				
			
		|  | @ -203,13 +203,42 @@ if(UNIX AND OPENVDB_USE_STATIC_LIBS) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| set(OpenVDB_LIB_COMPONENTS "") | set(OpenVDB_LIB_COMPONENTS "") | ||||||
|  | set(OpenVDB_DEBUG_SUFFIX "d" CACHE STRING "Suffix for the debug libraries") | ||||||
|  | 
 | ||||||
|  | get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | ||||||
| 
 | 
 | ||||||
| foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | ||||||
|   set(LIB_NAME ${COMPONENT}) |   set(LIB_NAME ${COMPONENT}) | ||||||
|   find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} lib${LIB_NAME} | 
 | ||||||
|  |   find_library(OpenVDB_${COMPONENT}_LIBRARY_RELEASE ${LIB_NAME} lib${LIB_NAME} | ||||||
|     PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} |     PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} | ||||||
|     PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} |     PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} | ||||||
|   ) |   ) | ||||||
|  | 
 | ||||||
|  |   find_library(OpenVDB_${COMPONENT}_LIBRARY_DEBUG ${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} lib${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} | ||||||
|  |     PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} | ||||||
|  |     PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   if (_is_multi) | ||||||
|  |     list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) | ||||||
|  | 
 | ||||||
|  |     list(FIND CMAKE_CONFIGURATION_TYPES "Debug" _has_debug) | ||||||
|  |      | ||||||
|  |     if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND (_has_debug LESS 0 OR OpenVDB_${COMPONENT}_LIBRARY_DEBUG)) | ||||||
|  |       set(OpenVDB_${COMPONENT}_FOUND TRUE) | ||||||
|  |     else() | ||||||
|  |       set(OpenVDB_${COMPONENT}_FOUND FALSE) | ||||||
|  |     endif() | ||||||
|  |   else () | ||||||
|  |     string(TOUPPER "${CMAKE_BUILD_TYPE}" _BUILD_TYPE) | ||||||
|  | 
 | ||||||
|  |     set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_${_BUILD_TYPE}}) | ||||||
|  | 
 | ||||||
|  |     if (NOT MSVC AND NOT OpenVDB_${COMPONENT}_LIBRARY) | ||||||
|  |       set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}) | ||||||
|  |     endif () | ||||||
|  | 
 | ||||||
|     list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) |     list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) | ||||||
| 
 | 
 | ||||||
|     if(OpenVDB_${COMPONENT}_LIBRARY) |     if(OpenVDB_${COMPONENT}_LIBRARY) | ||||||
|  | @ -217,6 +246,7 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | ||||||
|     else() |     else() | ||||||
|       set(OpenVDB_${COMPONENT}_FOUND FALSE) |       set(OpenVDB_${COMPONENT}_FOUND FALSE) | ||||||
|     endif() |     endif() | ||||||
|  |   endif () | ||||||
| endforeach() | endforeach() | ||||||
| 
 | 
 | ||||||
| if(UNIX AND OPENVDB_USE_STATIC_LIBS) | if(UNIX AND OPENVDB_USE_STATIC_LIBS) | ||||||
|  | @ -465,7 +495,6 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | ||||||
|   if(NOT TARGET OpenVDB::${COMPONENT}) |   if(NOT TARGET OpenVDB::${COMPONENT}) | ||||||
|     add_library(OpenVDB::${COMPONENT} UNKNOWN IMPORTED) |     add_library(OpenVDB::${COMPONENT} UNKNOWN IMPORTED) | ||||||
|     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES |     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES | ||||||
|       IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" |  | ||||||
|       INTERFACE_COMPILE_OPTIONS "${OpenVDB_DEFINITIONS}" |       INTERFACE_COMPILE_OPTIONS "${OpenVDB_DEFINITIONS}" | ||||||
|       INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}" |       INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}" | ||||||
|       IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps |       IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps | ||||||
|  | @ -473,6 +502,17 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | ||||||
|       INTERFACE_COMPILE_FEATURES cxx_std_11 |       INTERFACE_COMPILE_FEATURES cxx_std_11 | ||||||
|    ) |    ) | ||||||
| 
 | 
 | ||||||
|  |   if (_is_multi) | ||||||
|  |     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES  | ||||||
|  |       IMPORTED_LOCATION_RELEASE "${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}" | ||||||
|  |       IMPORTED_LOCATION_DEBUG "${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}" | ||||||
|  |     ) | ||||||
|  |   else () | ||||||
|  |     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES  | ||||||
|  |       IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" | ||||||
|  |     ) | ||||||
|  |   endif () | ||||||
|  | 
 | ||||||
|    if (OPENVDB_USE_STATIC_LIBS) |    if (OPENVDB_USE_STATIC_LIBS) | ||||||
|     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES |     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES | ||||||
|       INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" |       INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								deps/CGAL/CGAL.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/CGAL/CGAL.cmake
									
										
									
									
										vendored
									
									
								
							|  | @ -7,3 +7,9 @@ prusaslicer_add_cmake_project( | ||||||
|     # URL_HASH SHA256=bd9327be903ab7ee379a8a7a0609eba0962f5078d2497cf8e13e8e1598584154 |     # URL_HASH SHA256=bd9327be903ab7ee379a8a7a0609eba0962f5078d2497cf8e13e8e1598584154 | ||||||
|     DEPENDS dep_boost dep_GMP dep_MPFR |     DEPENDS dep_boost dep_GMP dep_MPFR | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | ExternalProject_Add_Step(dep_CGAL dep_CGAL_relocation_fix | ||||||
|  |     DEPENDEES install | ||||||
|  |     COMMAND ${CMAKE_COMMAND} -E remove CGALConfig-installation-dirs.cmake | ||||||
|  |     WORKING_DIRECTORY "${DESTDIR}/usr/local/lib/cmake/CGAL" | ||||||
|  | ) | ||||||
							
								
								
									
										1
									
								
								deps/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -47,6 +47,7 @@ message(STATUS "PrusaSlicer deps debug build: ${DEP_DEBUG}") | ||||||
| 
 | 
 | ||||||
| find_package(Git REQUIRED) | find_package(Git REQUIRED) | ||||||
| 
 | 
 | ||||||
|  | get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | ||||||
| 
 | 
 | ||||||
| function(prusaslicer_add_cmake_project projectname) | function(prusaslicer_add_cmake_project projectname) | ||||||
|     cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN}) |     cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN}) | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| 	 viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> | 	 viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> | ||||||
| <g id="hex_x5F_plus"> | <g id="hex_x5F_plus"> | ||||||
| 	<g> | 	<g> | ||||||
| 		<polygon fill="#ED6B21" points="2,8 2,11 8,15 14,11 14,8 "/> | 		<polygon fill="#ED6B21" points="1,8 1,11 8,16 15,11 15,8 " style="stroke:white;stroke-width:1"/> | ||||||
| 	</g> | 	</g> | ||||||
| </g> | </g> | ||||||
| </svg> | </svg> | ||||||
|  |  | ||||||
| Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 482 B | 
|  | @ -4,7 +4,7 @@ | ||||||
| 	 viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> | 	 viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> | ||||||
| <g id="hex_x5F_plus"> | <g id="hex_x5F_plus"> | ||||||
| 	<g> | 	<g> | ||||||
| 		<polygon fill="#ED6B21" points="8,1 2,5 2,7 2,8 14,8 14,7 14,5 		"/> | 		<polygon fill="#ED6B21" points="8,0 1,5 1,7 1,8 15,8 15,7 15,5" style="stroke:white;stroke-width:1"/> | ||||||
| 	</g> | 	</g> | ||||||
| </g> | </g> | ||||||
| </svg> | </svg> | ||||||
|  |  | ||||||
| Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 487 B | 
|  | @ -51,7 +51,7 @@ const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; | ||||||
| const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; | const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; | ||||||
| const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Prusa_Slicer_layer_config_ranges.xml"; | const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Prusa_Slicer_layer_config_ranges.xml"; | ||||||
| const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt"; | const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt"; | ||||||
| const std::string CUSTOM_GCODE_PER_HEIGHT_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_height.xml"; | const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml"; | ||||||
| 
 | 
 | ||||||
| const char* MODEL_TAG = "model"; | const char* MODEL_TAG = "model"; | ||||||
| const char* RESOURCES_TAG = "resources"; | const char* RESOURCES_TAG = "resources"; | ||||||
|  | @ -418,7 +418,7 @@ namespace Slic3r { | ||||||
|         void _extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); |         void _extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||||
|         void _extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); |         void _extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||||
| 
 | 
 | ||||||
|         void _extract_custom_gcode_per_height_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); |         void _extract_custom_gcode_per_print_z_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); | ||||||
| 
 | 
 | ||||||
|         void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename); |         void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename); | ||||||
|         bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model); |         bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model); | ||||||
|  | @ -629,10 +629,10 @@ namespace Slic3r { | ||||||
|                     // extract slic3r print config file
 |                     // extract slic3r print config file
 | ||||||
|                     _extract_print_config_from_archive(archive, stat, config, filename); |                     _extract_print_config_from_archive(archive, stat, config, filename); | ||||||
|                 } |                 } | ||||||
|                 if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_HEIGHT_FILE)) |                 if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_PRINT_Z_FILE)) | ||||||
|                 { |                 { | ||||||
|                     // extract slic3r layer config ranges file
 |                     // extract slic3r layer config ranges file
 | ||||||
|                     _extract_custom_gcode_per_height_from_archive(archive, stat); |                     _extract_custom_gcode_per_print_z_from_archive(archive, stat); | ||||||
|                 } |                 } | ||||||
|                 else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) |                 else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) | ||||||
|                 { |                 { | ||||||
|  | @ -1064,7 +1064,7 @@ namespace Slic3r { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void _3MF_Importer::_extract_custom_gcode_per_height_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) |     void _3MF_Importer::_extract_custom_gcode_per_print_z_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) | ||||||
|     { |     { | ||||||
|         if (stat.m_uncomp_size > 0) |         if (stat.m_uncomp_size > 0) | ||||||
|         { |         { | ||||||
|  | @ -1079,24 +1079,23 @@ namespace Slic3r { | ||||||
|             pt::ptree main_tree; |             pt::ptree main_tree; | ||||||
|             pt::read_xml(iss, main_tree); |             pt::read_xml(iss, main_tree); | ||||||
| 
 | 
 | ||||||
|             if (main_tree.front().first != "custom_gcodes_per_height") |             if (main_tree.front().first != "custom_gcodes_per_print_z") | ||||||
|                 return; |                 return; | ||||||
|             pt::ptree code_tree = main_tree.front().second; |             pt::ptree code_tree = main_tree.front().second; | ||||||
| 
 | 
 | ||||||
|             if (!m_model->custom_gcode_per_height.empty()) |             m_model->custom_gcode_per_print_z.clear(); | ||||||
|                 m_model->custom_gcode_per_height.clear(); |  | ||||||
| 
 | 
 | ||||||
|             for (const auto& code : code_tree) |             for (const auto& code : code_tree) | ||||||
|             { |             { | ||||||
|                 if (code.first != "code") |                 if (code.first != "code") | ||||||
|                     continue; |                     continue; | ||||||
|                 pt::ptree tree = code.second; |                 pt::ptree tree = code.second; | ||||||
|                 double height       = tree.get<double>("<xmlattr>.height"); |                 double print_z      = tree.get<double>      ("<xmlattr>.print_z"    ); | ||||||
|                 std::string gcode   = tree.get<std::string>("<xmlattr>.gcode"); |                 std::string gcode   = tree.get<std::string> ("<xmlattr>.gcode"      ); | ||||||
|                 int extruder        = tree.get<int>("<xmlattr>.extruder"); |                 int extruder        = tree.get<int>         ("<xmlattr>.extruder"   ); | ||||||
|                 std::string color   = tree.get<std::string>("<xmlattr>.color"); |                 std::string color   = tree.get<std::string> ("<xmlattr>.color"      ); | ||||||
| 
 | 
 | ||||||
|                 m_model->custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)) ; |                 m_model->custom_gcode_per_print_z.push_back(Model::CustomGCode{print_z, gcode, extruder, color}) ; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -1885,7 +1884,7 @@ namespace Slic3r { | ||||||
|         bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model); |         bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model); | ||||||
|         bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config); |         bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config); | ||||||
|         bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); |         bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); | ||||||
|         bool _add_custom_gcode_per_height_file_to_archive(mz_zip_archive& archive, Model& model); |         bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| #if ENABLE_THUMBNAIL_GENERATOR | #if ENABLE_THUMBNAIL_GENERATOR | ||||||
|  | @ -1988,9 +1987,9 @@ namespace Slic3r { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_height.xml").
 |         // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml").
 | ||||||
|         // All custom gcode per height of whole Model are stored here
 |         // All custom gcode per height of whole Model are stored here
 | ||||||
|         if (!_add_custom_gcode_per_height_file_to_archive(archive, model)) |         if (!_add_custom_gcode_per_print_z_file_to_archive(archive, model)) | ||||||
|         { |         { | ||||||
|             close_zip_writer(&archive); |             close_zip_writer(&archive); | ||||||
|             boost::filesystem::remove(filename); |             boost::filesystem::remove(filename); | ||||||
|  | @ -2567,20 +2566,20 @@ namespace Slic3r { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| bool _3MF_Exporter::_add_custom_gcode_per_height_file_to_archive( mz_zip_archive& archive, Model& model) | bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archive& archive, Model& model) | ||||||
| { | { | ||||||
|     std::string out = ""; |     std::string out = ""; | ||||||
| 
 | 
 | ||||||
|     if (!model.custom_gcode_per_height.empty()) |     if (!model.custom_gcode_per_print_z.empty()) | ||||||
|     { |     { | ||||||
|         pt::ptree tree; |         pt::ptree tree; | ||||||
|         pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); |         pt::ptree& main_tree = tree.add("custom_gcodes_per_print_z", ""); | ||||||
| 
 | 
 | ||||||
|         for (const Model::CustomGCode& code : model.custom_gcode_per_height) |         for (const Model::CustomGCode& code : model.custom_gcode_per_print_z) | ||||||
|         { |         { | ||||||
|             pt::ptree& code_tree = main_tree.add("code", ""); |             pt::ptree& code_tree = main_tree.add("code", ""); | ||||||
|             // store minX and maxZ
 |             // store minX and maxZ
 | ||||||
|             code_tree.put("<xmlattr>.height"    , code.height   ); |             code_tree.put("<xmlattr>.print_z"   , code.print_z  ); | ||||||
|             code_tree.put("<xmlattr>.gcode"     , code.gcode    ); |             code_tree.put("<xmlattr>.gcode"     , code.gcode    ); | ||||||
|             code_tree.put("<xmlattr>.extruder"  , code.extruder ); |             code_tree.put("<xmlattr>.extruder"  , code.extruder ); | ||||||
|             code_tree.put("<xmlattr>.color"     , code.color    ); |             code_tree.put("<xmlattr>.color"     , code.color    ); | ||||||
|  | @ -2599,9 +2598,9 @@ bool _3MF_Exporter::_add_custom_gcode_per_height_file_to_archive( mz_zip_archive | ||||||
| 
 | 
 | ||||||
|     if (!out.empty()) |     if (!out.empty()) | ||||||
|     { |     { | ||||||
|         if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_HEIGHT_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) |         if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_PRINT_Z_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) | ||||||
|         { |         { | ||||||
|             add_error("Unable to add custom Gcodes per height file to archive"); |             add_error("Unable to add custom Gcodes per print_z file to archive"); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -637,7 +637,7 @@ void AMFParserContext::endElement(const char * /* name */) | ||||||
|         int extruder = atoi(m_value[2].c_str()); |         int extruder = atoi(m_value[2].c_str()); | ||||||
|         const std::string& color = m_value[3]; |         const std::string& color = m_value[3]; | ||||||
| 
 | 
 | ||||||
|         m_model.custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)); |         m_model.custom_gcode_per_print_z.push_back(Model::CustomGCode{height, gcode, extruder, color}); | ||||||
| 
 | 
 | ||||||
|         for (std::string& val: m_value) |         for (std::string& val: m_value) | ||||||
|             val.clear(); |             val.clear(); | ||||||
|  | @ -1221,21 +1221,21 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) | ||||||
|         stream << "  </constellation>\n"; |         stream << "  </constellation>\n"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!model->custom_gcode_per_height.empty()) |     if (!model->custom_gcode_per_print_z.empty()) | ||||||
|     { |     { | ||||||
|         std::string out = ""; |         std::string out = ""; | ||||||
|         pt::ptree tree; |         pt::ptree tree; | ||||||
| 
 | 
 | ||||||
|         pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); |         pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); | ||||||
| 
 | 
 | ||||||
|         for (const Model::CustomGCode& code : model->custom_gcode_per_height) |         for (const Model::CustomGCode& code : model->custom_gcode_per_print_z) | ||||||
|         { |         { | ||||||
|             pt::ptree& code_tree = main_tree.add("code", ""); |             pt::ptree& code_tree = main_tree.add("code", ""); | ||||||
|             // store minX and maxZ
 |             // store minX and maxZ
 | ||||||
|             code_tree.put("<xmlattr>.height", code.height); |             code_tree.put("<xmlattr>.print_z"   , code.print_z  ); | ||||||
|             code_tree.put("<xmlattr>.gcode", code.gcode); |             code_tree.put("<xmlattr>.gcode"     , code.gcode    ); | ||||||
|             code_tree.put("<xmlattr>.extruder", code.extruder); |             code_tree.put("<xmlattr>.extruder"  , code.extruder ); | ||||||
|             code_tree.put("<xmlattr>.color", code.color); |             code_tree.put("<xmlattr>.color"     , code.color    ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!tree.empty()) |         if (!tree.empty()) | ||||||
|  |  | ||||||
|  | @ -936,7 +936,7 @@ void GCode::_do_export(Print& print, FILE* file) | ||||||
| 
 | 
 | ||||||
|     // Initialize custom gcode
 |     // Initialize custom gcode
 | ||||||
|     Model* model = print.get_object(0)->model_object()->get_model(); |     Model* model = print.get_object(0)->model_object()->get_model(); | ||||||
|     m_custom_g_code_heights = model->custom_gcode_per_height; |     m_custom_gcode_per_print_z = model->custom_gcode_per_print_z; | ||||||
| 
 | 
 | ||||||
|     // Initialize autospeed.
 |     // Initialize autospeed.
 | ||||||
|     { |     { | ||||||
|  | @ -1124,20 +1124,22 @@ void GCode::_do_export(Print& print, FILE* file) | ||||||
|     } |     } | ||||||
|     print.throw_if_canceled(); |     print.throw_if_canceled(); | ||||||
| 
 | 
 | ||||||
|  | // #ys_FIXME_no_exported_codes
 | ||||||
|  |     /*
 | ||||||
|     /* To avoid change filament for non-used extruder for Multi-material,
 |     /* To avoid change filament for non-used extruder for Multi-material,
 | ||||||
|      * check model->custom_gcode_per_height using tool_ordering values |      * check model->custom_gcode_per_print_z using tool_ordering values | ||||||
|      * */ |      * / | ||||||
|     if (!m_custom_g_code_heights. empty()) |     if (!m_custom_gcode_per_print_z. empty()) | ||||||
|     { |     { | ||||||
|         bool delete_executed = false; |         bool delete_executed = false; | ||||||
|         auto it = m_custom_g_code_heights.end(); |         auto it = m_custom_gcode_per_print_z.end(); | ||||||
|         while (it != m_custom_g_code_heights.begin()) |         while (it != m_custom_gcode_per_print_z.begin()) | ||||||
|         { |         { | ||||||
|             --it; |             --it; | ||||||
|             if (it->gcode != ColorChangeCode) |             if (it->gcode != ColorChangeCode) | ||||||
|                 continue; |                 continue; | ||||||
| 
 | 
 | ||||||
|             auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(it->height)); |             auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(it->print_z)); | ||||||
| 
 | 
 | ||||||
|             bool used_extruder = false; |             bool used_extruder = false; | ||||||
|             for (; it_layer_tools != tool_ordering.end(); it_layer_tools++) |             for (; it_layer_tools != tool_ordering.end(); it_layer_tools++) | ||||||
|  | @ -1154,16 +1156,16 @@ void GCode::_do_export(Print& print, FILE* file) | ||||||
| 
 | 
 | ||||||
|             /* If we are there, current extruder wouldn't be used,
 |             /* If we are there, current extruder wouldn't be used,
 | ||||||
|              * so this color change is a redundant move. |              * so this color change is a redundant move. | ||||||
|              * Delete this item from m_custom_g_code_heights |              * Delete this item from m_custom_gcode_per_print_z | ||||||
|              * */ |              * / | ||||||
|             it = m_custom_g_code_heights.erase(it); |             it = m_custom_gcode_per_print_z.erase(it); | ||||||
|             delete_executed = true; |             delete_executed = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (delete_executed) |         if (delete_executed) | ||||||
|             model->custom_gcode_per_height = m_custom_g_code_heights; |             model->custom_gcode_per_print_z = m_custom_gcode_per_print_z; | ||||||
|     } |     } | ||||||
| 
 | */ | ||||||
| 
 | 
 | ||||||
|     m_cooling_buffer->set_current_extruder(initial_extruder_id); |     m_cooling_buffer->set_current_extruder(initial_extruder_id); | ||||||
| 
 | 
 | ||||||
|  | @ -1461,7 +1463,7 @@ void GCode::_do_export(Print& print, FILE* file) | ||||||
|                 dst.first += buf; |                 dst.first += buf; | ||||||
|                 ++ dst.second; |                 ++ dst.second; | ||||||
|             }; |             }; | ||||||
|             print.m_print_statistics.filament_stats.insert(std::pair<size_t, float>(extruder.id(), (float)used_filament)); |             print.m_print_statistics.filament_stats.insert(std::pair<size_t, float>{extruder.id(), (float)used_filament}); | ||||||
|             append(out_filament_used_mm,  "%.1lf", used_filament); |             append(out_filament_used_mm,  "%.1lf", used_filament); | ||||||
|             append(out_filament_used_cm3, "%.1lf", extruded_volume * 0.001); |             append(out_filament_used_cm3, "%.1lf", extruded_volume * 0.001); | ||||||
|             if (filament_weight > 0.) { |             if (filament_weight > 0.) { | ||||||
|  | @ -1835,15 +1837,15 @@ void GCode::process_layer( | ||||||
|     std::string custom_code = ""; |     std::string custom_code = ""; | ||||||
|     std::string pause_print_msg = ""; |     std::string pause_print_msg = ""; | ||||||
|     int m600_before_extruder = -1; |     int m600_before_extruder = -1; | ||||||
|     while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { |     while (!m_custom_gcode_per_print_z.empty() && m_custom_gcode_per_print_z.front().print_z - EPSILON < layer.print_z) { | ||||||
|         custom_code = m_custom_g_code_heights.front().gcode; |         custom_code = m_custom_gcode_per_print_z.front().gcode; | ||||||
| 
 | 
 | ||||||
|         if (custom_code == ColorChangeCode && m_custom_g_code_heights.front().extruder > 0) |         if (custom_code == ColorChangeCode && m_custom_gcode_per_print_z.front().extruder > 0) | ||||||
|             m600_before_extruder = m_custom_g_code_heights.front().extruder - 1; |             m600_before_extruder = m_custom_gcode_per_print_z.front().extruder - 1; | ||||||
|         if (custom_code == PausePrintCode) |         if (custom_code == PausePrintCode) | ||||||
|             pause_print_msg = m_custom_g_code_heights.front().color; |             pause_print_msg = m_custom_gcode_per_print_z.front().color; | ||||||
| 
 | 
 | ||||||
|         m_custom_g_code_heights.erase(m_custom_g_code_heights.begin()); |         m_custom_gcode_per_print_z.erase(m_custom_gcode_per_print_z.begin()); | ||||||
|         colorprint_change = true; |         colorprint_change = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -367,7 +367,7 @@ protected: | ||||||
|      * Updated before the export and erased during the process, |      * Updated before the export and erased during the process, | ||||||
|      * so no toolchange occurs twice. |      * so no toolchange occurs twice. | ||||||
|      * */ |      * */ | ||||||
|     std::vector<Model::CustomGCode> m_custom_g_code_heights; |     std::vector<Model::CustomGCode> m_custom_gcode_per_print_z; | ||||||
| 
 | 
 | ||||||
|     // Time estimators
 |     // Time estimators
 | ||||||
|     GCodeTimeEstimator m_normal_time_estimator; |     GCodeTimeEstimator m_normal_time_estimator; | ||||||
|  |  | ||||||
|  | @ -10,6 +10,11 @@ | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
| 
 | 
 | ||||||
|  | // Additional Codes which can be set by user using DoubleSlider
 | ||||||
|  | static constexpr char ColorChangeCode[]     = "M600"; | ||||||
|  | static constexpr char PausePrintCode[]      = "M601"; | ||||||
|  | static constexpr char ExtruderChangeCode[]  = "tool_change"; | ||||||
|  | 
 | ||||||
| class GCodeWriter { | class GCodeWriter { | ||||||
| public: | public: | ||||||
|     GCodeConfig config; |     GCodeConfig config; | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ | ||||||
| 
 | 
 | ||||||
| #include "SVG.hpp" | #include "SVG.hpp" | ||||||
| #include <Eigen/Dense> | #include <Eigen/Dense> | ||||||
|  | #include "GCodeWriter.hpp" | ||||||
|  | #include "GCode/PreviewData.hpp" | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
| 
 | 
 | ||||||
|  | @ -43,7 +45,7 @@ Model& Model::assign_copy(const Model &rhs) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // copy custom code per height
 |     // copy custom code per height
 | ||||||
|     this->custom_gcode_per_height = rhs.custom_gcode_per_height; |     this->custom_gcode_per_print_z = rhs.custom_gcode_per_print_z; | ||||||
|     return *this; |     return *this; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -64,7 +66,7 @@ Model& Model::assign_copy(Model &&rhs) | ||||||
|     rhs.objects.clear(); |     rhs.objects.clear(); | ||||||
| 
 | 
 | ||||||
|     // copy custom code per height
 |     // copy custom code per height
 | ||||||
|     this->custom_gcode_per_height = rhs.custom_gcode_per_height; |     this->custom_gcode_per_print_z = rhs.custom_gcode_per_print_z; | ||||||
|     return *this; |     return *this; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -124,6 +126,8 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c | ||||||
|     if (add_default_instances) |     if (add_default_instances) | ||||||
|         model.add_default_instances(); |         model.add_default_instances(); | ||||||
| 
 | 
 | ||||||
|  |     update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); | ||||||
|  | 
 | ||||||
|     return model; |     return model; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -159,6 +163,8 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig | ||||||
|     if (add_default_instances) |     if (add_default_instances) | ||||||
|         model.add_default_instances(); |         model.add_default_instances(); | ||||||
| 
 | 
 | ||||||
|  |     update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); | ||||||
|  | 
 | ||||||
|     return model; |     return model; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -595,16 +601,15 @@ std::string Model::propose_export_file_name_and_path(const std::string &new_exte | ||||||
| std::vector<std::pair<double, DynamicPrintConfig>> Model::get_custom_tool_changes(double default_layer_height, size_t num_extruders) const | std::vector<std::pair<double, DynamicPrintConfig>> Model::get_custom_tool_changes(double default_layer_height, size_t num_extruders) const | ||||||
| { | { | ||||||
|     std::vector<std::pair<double, DynamicPrintConfig>> custom_tool_changes; |     std::vector<std::pair<double, DynamicPrintConfig>> custom_tool_changes; | ||||||
|     if (!custom_gcode_per_height.empty()) { |     for (const CustomGCode& custom_gcode : custom_gcode_per_print_z) | ||||||
|         for (const CustomGCode& custom_gcode : custom_gcode_per_height) |  | ||||||
|         if (custom_gcode.gcode == ExtruderChangeCode) { |         if (custom_gcode.gcode == ExtruderChangeCode) { | ||||||
|             DynamicPrintConfig config; |             DynamicPrintConfig config; | ||||||
|             // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders
 |             // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders
 | ||||||
|             config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder > num_extruders ? 0 : custom_gcode.extruder)); |             config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder > num_extruders ? 0 : custom_gcode.extruder)); | ||||||
|             // For correct extruders(tools) changing, we should decrease custom_gcode.height value by one default layer height
 |             // For correct extruders(tools) changing, we should decrease custom_gcode.height value by one default layer height
 | ||||||
|                 custom_tool_changes.push_back({ custom_gcode.height - default_layer_height, config }); |             custom_tool_changes.push_back({ custom_gcode.print_z - default_layer_height, config }); | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|     return custom_tool_changes; |     return custom_tool_changes; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1933,6 +1938,30 @@ extern bool model_has_advanced_features(const Model &model) | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | extern void update_custom_gcode_per_print_z_from_config(std::vector<Model::CustomGCode>& custom_gcode_per_print_z, DynamicPrintConfig* config) | ||||||
|  | { | ||||||
|  |     if (!config->has("colorprint_heights")) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     const std::vector<std::string>& colors = GCodePreviewData::ColorPrintColors(); | ||||||
|  | 
 | ||||||
|  |     const auto& colorprint_values = config->option<ConfigOptionFloats>("colorprint_heights")->values; | ||||||
|  |      | ||||||
|  |     if (!colorprint_values.empty()) | ||||||
|  |     { | ||||||
|  |         custom_gcode_per_print_z.clear(); | ||||||
|  |         custom_gcode_per_print_z.reserve(colorprint_values.size()); | ||||||
|  |         int i = 0; | ||||||
|  |         for (auto val : colorprint_values) | ||||||
|  |             custom_gcode_per_print_z.emplace_back(Model::CustomGCode{ val, ColorChangeCode, 1, colors[(++i)%7] }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* There is one and only place this configuration option is used now.
 | ||||||
|  |      * It wouldn't be used in the future, so erase it. | ||||||
|  |      * */ | ||||||
|  |     config->erase("colorprint_heights"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||||
| // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | ||||||
| void check_model_ids_validity(const Model &model) | void check_model_ids_validity(const Model &model) | ||||||
|  |  | ||||||
|  | @ -749,33 +749,30 @@ public: | ||||||
|     // Extensions for color print
 |     // Extensions for color print
 | ||||||
|     struct CustomGCode |     struct CustomGCode | ||||||
|     { |     { | ||||||
|         CustomGCode(double height, const std::string& code, int extruder, const std::string& color) : |         bool operator<(const CustomGCode& other) const { return other.print_z > this->print_z; } | ||||||
|             height(height), gcode(code), extruder(extruder), color(color) {} |  | ||||||
| 
 |  | ||||||
|         bool operator<(const CustomGCode& other) const { return other.height > this->height; } |  | ||||||
|         bool operator==(const CustomGCode& other) const |         bool operator==(const CustomGCode& other) const | ||||||
|         { |         { | ||||||
|             return (other.height    == this->height)     &&  |             return (other.print_z   == this->print_z    ) &&  | ||||||
|                    (other.gcode     == this->gcode)      &&  |                    (other.gcode     == this->gcode      ) &&  | ||||||
|                    (other.extruder  == this->extruder   )&&  |                    (other.extruder  == this->extruder   ) &&  | ||||||
|                    (other.color     == this->color      ); |                    (other.color     == this->color      ); | ||||||
|         } |         } | ||||||
|         bool operator!=(const CustomGCode& other) const |         bool operator!=(const CustomGCode& other) const | ||||||
|         { |         { | ||||||
|             return (other.height    != this->height)     ||  |             return (other.print_z   != this->print_z    ) ||  | ||||||
|                    (other.gcode     != this->gcode)      ||  |                    (other.gcode     != this->gcode      ) ||  | ||||||
|                    (other.extruder  != this->extruder   )||  |                    (other.extruder  != this->extruder   ) ||  | ||||||
|                    (other.color     != this->color      ); |                    (other.color     != this->color      ); | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         double      height; |         double      print_z; | ||||||
|         std::string gcode; |         std::string gcode; | ||||||
|         int         extruder;   // 0    - "gcode" will be applied for whole print
 |         int         extruder;   // 0    - "gcode" will be applied for whole print
 | ||||||
|                                 // else - "gcode" will be applied only for "extruder" print
 |                                 // else - "gcode" will be applied only for "extruder" print
 | ||||||
|         std::string color;      // if gcode is equal to PausePrintCode, 
 |         std::string color;      // if gcode is equal to PausePrintCode, 
 | ||||||
|                                 // this field is used for save a short message shown on Printer display 
 |                                 // this field is used for save a short message shown on Printer display 
 | ||||||
|     }; |     }; | ||||||
|     std::vector<CustomGCode> custom_gcode_per_height; |     std::vector<CustomGCode> custom_gcode_per_print_z; | ||||||
|      |      | ||||||
|     // Default constructor assigns a new ID to the model.
 |     // Default constructor assigns a new ID to the model.
 | ||||||
|     Model() { assert(this->id().valid()); } |     Model() { assert(this->id().valid()); } | ||||||
|  | @ -841,7 +838,7 @@ public: | ||||||
|     // Propose an output path, replace extension. The new_extension shall contain the initial dot.
 |     // Propose an output path, replace extension. The new_extension shall contain the initial dot.
 | ||||||
|     std::string   propose_export_file_name_and_path(const std::string &new_extension) const; |     std::string   propose_export_file_name_and_path(const std::string &new_extension) const; | ||||||
| 
 | 
 | ||||||
|     // from custom_gcode_per_height get just tool_change codes
 |     // from custom_gcode_per_print_z get just tool_change codes
 | ||||||
|     std::vector<std::pair<double, DynamicPrintConfig>> get_custom_tool_changes(double default_layer_height, size_t num_extruders) const; |     std::vector<std::pair<double, DynamicPrintConfig>> get_custom_tool_changes(double default_layer_height, size_t num_extruders) const; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -877,6 +874,10 @@ extern bool model_volume_list_changed(const ModelObject &model_object_old, const | ||||||
| extern bool model_has_multi_part_objects(const Model &model); | extern bool model_has_multi_part_objects(const Model &model); | ||||||
| // If the model has advanced features, then it cannot be processed in simple mode.
 | // If the model has advanced features, then it cannot be processed in simple mode.
 | ||||||
| extern bool model_has_advanced_features(const Model &model); | extern bool model_has_advanced_features(const Model &model); | ||||||
|  | /* If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), 
 | ||||||
|  |  * then model.custom_gcode_per_print_z should be updated considering this option | ||||||
|  |  * */ | ||||||
|  | extern void update_custom_gcode_per_print_z_from_config(std::vector<Model::CustomGCode>& custom_gcode_per_print_z, DynamicPrintConfig* config); | ||||||
| 
 | 
 | ||||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||||
| // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | ||||||
|  |  | ||||||
|  | @ -739,10 +739,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ | ||||||
| 				model_object_status.emplace(model_object->id(), ModelObjectStatus::Old); | 				model_object_status.emplace(model_object->id(), ModelObjectStatus::Old); | ||||||
| 
 | 
 | ||||||
|             // But if custom gcode per layer height was changed
 |             // But if custom gcode per layer height was changed
 | ||||||
|             if (m_model.custom_gcode_per_height != model.custom_gcode_per_height) { |             if (m_model.custom_gcode_per_print_z != model.custom_gcode_per_print_z) { | ||||||
|                 // we should stop background processing
 |                 // we should stop background processing
 | ||||||
|                 update_apply_status(this->invalidate_step(psGCodeExport)); |                 update_apply_status(this->invalidate_step(psGCodeExport)); | ||||||
|                 m_model.custom_gcode_per_height = model.custom_gcode_per_height; |                 m_model.custom_gcode_per_print_z = model.custom_gcode_per_print_z; | ||||||
|             } |             } | ||||||
|         } else if (model_object_list_extended(m_model, model)) { |         } else if (model_object_list_extended(m_model, model)) { | ||||||
|             // Add new objects. Their volumes and configs will be synchronized later.
 |             // Add new objects. Their volumes and configs will be synchronized later.
 | ||||||
|  |  | ||||||
|  | @ -71,12 +71,6 @@ enum SLAPillarConnectionMode { | ||||||
|     slapcmDynamic |     slapcmDynamic | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // ys_FIXME ! may be, it's not a best place
 |  | ||||||
| // Additional Codes which can be set by user using DoubleSlider
 |  | ||||||
| static const std::string ColorChangeCode    = "M600"; |  | ||||||
| static const std::string PausePrintCode     = "M601"; |  | ||||||
| static const std::string ExtruderChangeCode = "tool_change"; |  | ||||||
| 
 |  | ||||||
| template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() { | template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() { | ||||||
|     static t_config_enum_values keys_map; |     static t_config_enum_values keys_map; | ||||||
|     if (keys_map.empty()) { |     if (keys_map.empty()) { | ||||||
|  |  | ||||||
|  | @ -94,12 +94,13 @@ void BackgroundSlicingProcess::process_fff() | ||||||
|     m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); |     m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); | ||||||
| #endif // ENABLE_THUMBNAIL_GENERATOR
 | #endif // ENABLE_THUMBNAIL_GENERATOR
 | ||||||
| 
 | 
 | ||||||
|     if (m_fff_print->model().custom_gcode_per_height != GUI::wxGetApp().model().custom_gcode_per_height) { |     /* #ys_FIXME_no_exported_codes
 | ||||||
|         GUI::wxGetApp().model().custom_gcode_per_height = m_fff_print->model().custom_gcode_per_height; |     if (m_fff_print->model().custom_gcode_per_print_z != GUI::wxGetApp().model().custom_gcode_per_print_z) { | ||||||
|         // #ys_FIXME : controll text
 |         GUI::wxGetApp().model().custom_gcode_per_print_z = m_fff_print->model().custom_gcode_per_print_z; | ||||||
|         GUI::show_info(nullptr, _(L("To except of redundant tool manipulation, \n" |         GUI::show_info(nullptr, _(L("To except of redundant tool manipulation, \n" | ||||||
|                                     "Color change(s) for unused extruder(s) was(were) deleted")), _(L("Info"))); |                                     "Color change(s) for unused extruder(s) was(were) deleted")), _(L("Info"))); | ||||||
|     } |     } | ||||||
|  |     */ | ||||||
| 
 | 
 | ||||||
| 	if (this->set_step_started(bspsGCodeFinalize)) { | 	if (this->set_step_started(bspsGCodeFinalize)) { | ||||||
| 	    if (! m_export_path.empty()) { | 	    if (! m_export_path.empty()) { | ||||||
|  |  | ||||||
|  | @ -1011,24 +1011,25 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | ||||||
|                                                                 std::vector<float>& colors, |                                                                 std::vector<float>& colors, | ||||||
|                                                                 std::vector<std::string>& cp_legend_items) |                                                                 std::vector<std::string>& cp_legend_items) | ||||||
| { | { | ||||||
|     std::vector<Model::CustomGCode> custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; |     std::vector<Model::CustomGCode> custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z; | ||||||
| 
 | 
 | ||||||
|     const int extruders_cnt = wxGetApp().extruders_edited_cnt(); |     const int extruders_cnt = wxGetApp().extruders_edited_cnt(); | ||||||
|     if (extruders_cnt == 1)  |     if (extruders_cnt == 1)  | ||||||
|     { |     { | ||||||
|         if (custom_gcode_per_height.empty()) { |         if (custom_gcode_per_print_z.empty()) { | ||||||
|             cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); |             cp_legend_items.emplace_back(I18N::translate_utf8(L("Default print color"))); | ||||||
|             colors = colors_in; |             colors = colors_in; | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         std::vector<std::pair<double, double>> cp_values; |         std::vector<std::pair<double, double>> cp_values; | ||||||
|  |         cp_values.reserve(custom_gcode_per_print_z.size()); | ||||||
|          |          | ||||||
|         std::vector<double> print_zs = canvas.get_current_print_zs(true); |         std::vector<double> print_zs = canvas.get_current_print_zs(true); | ||||||
|         for (auto custom_code : custom_gcode_per_height) |         for (auto custom_code : custom_gcode_per_print_z) | ||||||
|         { |         { | ||||||
|             if (custom_code.gcode != ColorChangeCode) |             if (custom_code.gcode != ColorChangeCode) | ||||||
|                 continue; |                 continue; | ||||||
|             auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon()); |             auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.print_z - DoubleSlider::epsilon()); | ||||||
| 
 | 
 | ||||||
|             if (lower_b == print_zs.end()) |             if (lower_b == print_zs.end()) | ||||||
|                 continue; |                 continue; | ||||||
|  | @ -1039,14 +1040,14 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | ||||||
|             // to avoid duplicate values, check adding values
 |             // to avoid duplicate values, check adding values
 | ||||||
|             if (cp_values.empty() || |             if (cp_values.empty() || | ||||||
|                 !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) |                 !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) | ||||||
|                 cp_values.push_back(std::pair<double, double>(previous_z, current_z)); |                 cp_values.emplace_back(std::pair<double, double>(previous_z, current_z)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const auto items_cnt = (int)cp_values.size(); |         const auto items_cnt = (int)cp_values.size(); | ||||||
|         if (items_cnt == 0) // There is no one color change, but there is/are some pause print or custom Gcode
 |         if (items_cnt == 0) // There is no one color change, but there is/are some pause print or custom Gcode
 | ||||||
|         { |         { | ||||||
|             cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); |             cp_legend_items.emplace_back(I18N::translate_utf8(L("Default print color"))); | ||||||
|             cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); |             cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); | ||||||
|             colors = colors_in; |             colors = colors_in; | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | @ -1055,7 +1056,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | ||||||
|         colors.resize(colors_in.size(), 0.0); |         colors.resize(colors_in.size(), 0.0); | ||||||
|                  |                  | ||||||
|         ::memcpy((void*)(colors.data()), (const void*)(colors_in.data() + (color_cnt - 1) * 4), 4 * sizeof(float)); |         ::memcpy((void*)(colors.data()), (const void*)(colors_in.data() + (color_cnt - 1) * 4), 4 * sizeof(float)); | ||||||
|         cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); |         cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); | ||||||
|         size_t color_pos = 4; |         size_t color_pos = 4; | ||||||
| 
 | 
 | ||||||
|         for (int i = items_cnt; i >= 0; --i, color_pos+=4) |         for (int i = items_cnt; i >= 0; --i, color_pos+=4) | ||||||
|  | @ -1067,15 +1068,15 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | ||||||
|             std::string id_str = std::to_string(i + 1) + ": "; |             std::string id_str = std::to_string(i + 1) + ": "; | ||||||
| 
 | 
 | ||||||
|             if (i == 0) { |             if (i == 0) { | ||||||
|                 cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values[0].first).str()); |                 cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values[0].first).str()); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             if (i == items_cnt) { |             if (i == items_cnt) { | ||||||
|                 cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); |                 cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); |             cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|  | @ -1089,20 +1090,20 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | ||||||
|         size_t color_in_pos = 4 * (color_cnt - 1); |         size_t color_in_pos = 4 * (color_cnt - 1); | ||||||
|          |          | ||||||
|         for (unsigned int i = 0; i < (unsigned int)extruders_cnt; ++i) |         for (unsigned int i = 0; i < (unsigned int)extruders_cnt; ++i) | ||||||
|             cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); |             cp_legend_items.emplace_back((boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); | ||||||
| 
 | 
 | ||||||
|         ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); |         ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); | ||||||
|         color_pos += 4; |         color_pos += 4; | ||||||
|         color_in_pos -= 4; |         color_in_pos -= 4; | ||||||
|         cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); |         cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); | ||||||
| 
 | 
 | ||||||
|         int cnt = custom_gcode_per_height.size(); |         int cnt = custom_gcode_per_print_z.size(); | ||||||
|         for (int i = cnt-1; i >= 0; --i) |         for (int i = cnt-1; i >= 0; --i) | ||||||
|             if (custom_gcode_per_height[i].gcode == ColorChangeCode) { |             if (custom_gcode_per_print_z[i].gcode == ColorChangeCode) { | ||||||
|                 ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); |                 ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); | ||||||
|                 color_pos += 4; |                 color_pos += 4; | ||||||
|                 color_in_pos -= 4; |                 color_in_pos -= 4; | ||||||
|                 cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_height[i].extruder % custom_gcode_per_height[i].height).str()); |                 cp_legend_items.emplace_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str()); | ||||||
|             } |             } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -5389,7 +5390,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | ||||||
|         // For coloring by a color_print(M600), return a parsed color.
 |         // For coloring by a color_print(M600), return a parsed color.
 | ||||||
|         bool                         color_by_color_print() const { return color_print_values!=nullptr; } |         bool                         color_by_color_print() const { return color_print_values!=nullptr; } | ||||||
|         const size_t                 color_print_color_idx_by_layer_idx(const size_t layer_idx) const { |         const size_t                 color_print_color_idx_by_layer_idx(const size_t layer_idx) const { | ||||||
|             const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0, ""); |             const Model::CustomGCode value{layers[layer_idx]->print_z + EPSILON, "", 0, ""}; | ||||||
|             auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); |             auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); | ||||||
|             return (it - color_print_values->begin()) % number_tools(); |             return (it - color_print_values->begin()) % number_tools(); | ||||||
|         } |         } | ||||||
|  | @ -5400,7 +5401,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | ||||||
| 
 | 
 | ||||||
|             auto it = std::find_if(color_print_values->begin(), color_print_values->end(), |             auto it = std::find_if(color_print_values->begin(), color_print_values->end(), | ||||||
|                 [print_z](const Model::CustomGCode& code) |                 [print_z](const Model::CustomGCode& code) | ||||||
|                 { return fabs(code.height - print_z) < EPSILON; }); |                 { return fabs(code.print_z - print_z) < EPSILON; }); | ||||||
|             if (it != color_print_values->end()) |             if (it != color_print_values->end()) | ||||||
|             { |             { | ||||||
|                 const std::string& code = it->gcode; |                 const std::string& code = it->gcode; | ||||||
|  | @ -5420,7 +5421,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             const Model::CustomGCode value(print_z + EPSILON, "", 0, ""); |             const Model::CustomGCode value{print_z + EPSILON, "", 0, ""}; | ||||||
|             it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); |             it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); | ||||||
|             while (it != color_print_values->begin()) |             while (it != color_print_values->begin()) | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -3874,8 +3874,8 @@ void ObjectList::show_multi_selection_menu() | ||||||
|     GetSelections(sels); |     GetSelections(sels); | ||||||
| 
 | 
 | ||||||
|     for (const wxDataViewItem& item : sels) |     for (const wxDataViewItem& item : sels) | ||||||
|         if (!(m_objects_model->GetItemType(item) & (itVolume | itObject))) |         if (!(m_objects_model->GetItemType(item) & (itVolume | itObject | itInstance))) | ||||||
|             // show this menu only for Object(s)/Volume(s) selection
 |             // show this menu only for Objects(Instances mixed with Objects)/Volumes selection
 | ||||||
|             return; |             return; | ||||||
| 
 | 
 | ||||||
|     wxMenu* menu = new wxMenu(); |     wxMenu* menu = new wxMenu(); | ||||||
|  | @ -3885,7 +3885,12 @@ void ObjectList::show_multi_selection_menu() | ||||||
|             _(L("Select extruder number for selected objects and/or parts")), |             _(L("Select extruder number for selected objects and/or parts")), | ||||||
|             [this](wxCommandEvent&) { extruder_selection(); }, "", menu); |             [this](wxCommandEvent&) { extruder_selection(); }, "", menu); | ||||||
| 
 | 
 | ||||||
|     PopupMenu(menu); |     append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")), | ||||||
|  |         [this](wxCommandEvent&) { wxGetApp().plater()->reload_from_disk(); }, "", menu, []() { | ||||||
|  |         return wxGetApp().plater()->can_reload_from_disk(); | ||||||
|  |     }, wxGetApp().plater()); | ||||||
|  | 
 | ||||||
|  |     wxGetApp().plater()->PopupMenu(menu); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ObjectList::extruder_selection() | void ObjectList::extruder_selection() | ||||||
|  |  | ||||||
|  | @ -366,6 +366,8 @@ public: | ||||||
|     void update_printable_state(int obj_idx, int instance_idx); |     void update_printable_state(int obj_idx, int instance_idx); | ||||||
|     void toggle_printable_state(wxDataViewItem item); |     void toggle_printable_state(wxDataViewItem item); | ||||||
| 
 | 
 | ||||||
|  |     void show_multi_selection_menu(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
| #ifdef __WXOSX__ | #ifdef __WXOSX__ | ||||||
| //    void OnChar(wxKeyEvent& event);
 | //    void OnChar(wxKeyEvent& event);
 | ||||||
|  | @ -384,8 +386,6 @@ private: | ||||||
| 	void OnEditingStarted(wxDataViewEvent &event); | 	void OnEditingStarted(wxDataViewEvent &event); | ||||||
| #endif /* __WXMSW__ */ | #endif /* __WXMSW__ */ | ||||||
|     void OnEditingDone(wxDataViewEvent &event); |     void OnEditingDone(wxDataViewEvent &event); | ||||||
| 
 |  | ||||||
|     void show_multi_selection_menu(); |  | ||||||
|     void extruder_selection(); |     void extruder_selection(); | ||||||
|     void set_extruder_for_selected_items(const int extruder) const ; |     void set_extruder_for_selected_items(const int extruder) const ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -569,7 +569,7 @@ void Preview::update_view_type(bool slice_completed) | ||||||
| { | { | ||||||
|     const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; |     const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; | ||||||
| 
 | 
 | ||||||
|     const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() /*&&
 |     const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_print_z.empty() /*&&
 | ||||||
|                              (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) */?  |                              (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) */?  | ||||||
|                                 _(L("Color Print")) : |                                 _(L("Color Print")) : | ||||||
|                                 config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values.size() > 1 ? |                                 config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values.size() > 1 ? | ||||||
|  | @ -600,7 +600,7 @@ void Preview::create_double_slider() | ||||||
| 
 | 
 | ||||||
|     Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { |     Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { | ||||||
|         Model& model = wxGetApp().plater()->model(); |         Model& model = wxGetApp().plater()->model(); | ||||||
|         model.custom_gcode_per_height = m_slider->GetTicksValues(); |         model.custom_gcode_per_print_z = m_slider->GetTicksValues(); | ||||||
|         m_schedule_background_process(); |         m_schedule_background_process(); | ||||||
| 
 | 
 | ||||||
|         update_view_type(false); |         update_view_type(false); | ||||||
|  | @ -646,7 +646,7 @@ void Preview::check_slider_values(std::vector<Model::CustomGCode>& ticks_from_mo | ||||||
|     ticks_from_model.erase(std::remove_if(ticks_from_model.begin(), ticks_from_model.end(), |     ticks_from_model.erase(std::remove_if(ticks_from_model.begin(), ticks_from_model.end(), | ||||||
|                      [layers_z](Model::CustomGCode val) |                      [layers_z](Model::CustomGCode val) | ||||||
|         { |         { | ||||||
|             auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.height - DoubleSlider::epsilon()); |             auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.print_z - DoubleSlider::epsilon()); | ||||||
|             return it == layers_z.end(); |             return it == layers_z.end(); | ||||||
|         }), |         }), | ||||||
|         ticks_from_model.end()); |         ticks_from_model.end()); | ||||||
|  | @ -669,7 +669,7 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee | ||||||
|     bool   snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); |     bool   snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); | ||||||
| 	bool   snap_to_max  = force_sliders_full_range || m_slider->is_higher_at_max(); | 	bool   snap_to_max  = force_sliders_full_range || m_slider->is_higher_at_max(); | ||||||
| 
 | 
 | ||||||
|     std::vector<Model::CustomGCode> &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; |     std::vector<Model::CustomGCode> &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; | ||||||
|     check_slider_values(ticks_from_model, layers_z); |     check_slider_values(ticks_from_model, layers_z); | ||||||
| 
 | 
 | ||||||
|     m_slider->SetSliderValues(layers_z); |     m_slider->SetSliderValues(layers_z); | ||||||
|  | @ -789,7 +789,7 @@ void Preview::load_print_as_fff(bool keep_z_range) | ||||||
|         colors.push_back("#808080"); // gray color for pause print or custom G-code 
 |         colors.push_back("#808080"); // gray color for pause print or custom G-code 
 | ||||||
| 
 | 
 | ||||||
|         if (!gcode_preview_data_valid) |         if (!gcode_preview_data_valid) | ||||||
|             color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; |             color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z; | ||||||
|     } |     } | ||||||
|     else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) |     else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -2334,7 +2334,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ | ||||||
|                         config += std::move(config_loaded); |                         config += std::move(config_loaded); | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     this->model.custom_gcode_per_height = model.custom_gcode_per_height; |                     this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (load_config) |                 if (load_config) | ||||||
|  | @ -2753,7 +2753,7 @@ void Plater::priv::reset() | ||||||
|     // The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here
 |     // The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here
 | ||||||
|     this->sidebar->show_sliced_info_sizer(false); |     this->sidebar->show_sliced_info_sizer(false); | ||||||
| 
 | 
 | ||||||
|     model.custom_gcode_per_height.clear(); |     model.custom_gcode_per_print_z.clear(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Plater::priv::mirror(Axis axis) | void Plater::priv::mirror(Axis axis) | ||||||
|  | @ -3615,8 +3615,11 @@ void Plater::priv::on_right_click(RBtnEvent& evt) | ||||||
|         if (evt.data.second) // right button was clicked on empty space
 |         if (evt.data.second) // right button was clicked on empty space
 | ||||||
|             menu = &default_menu; |             menu = &default_menu; | ||||||
|         else |         else | ||||||
|  |         { | ||||||
|  |             sidebar->obj_list()->show_multi_selection_menu(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         // If in 3DScene is(are) selected volume(s), but right button was clicked on empty space
 |         // If in 3DScene is(are) selected volume(s), but right button was clicked on empty space
 | ||||||
|  | @ -5174,6 +5177,7 @@ const DynamicPrintConfig* Plater::get_plater_config() const | ||||||
|     return p->config; |     return p->config; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Get vector of extruder colors considering filament color, if extruder color is undefined.
 | ||||||
| std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const | std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const | ||||||
| { | { | ||||||
|     const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; |     const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; | ||||||
|  | @ -5193,13 +5197,17 @@ std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const | ||||||
|     return extruder_colors; |     return extruder_colors; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Get vector of colors used for rendering of a Preview scene in "Color print" mode
 | ||||||
|  |  * It consists of extruder colors and colors, saved in model.custom_gcode_per_print_z | ||||||
|  |  */ | ||||||
| std::vector<std::string> Plater::get_colors_for_color_print() const | std::vector<std::string> Plater::get_colors_for_color_print() const | ||||||
| { | { | ||||||
|     std::vector<std::string> colors = get_extruder_colors_from_plater_config(); |     std::vector<std::string> colors = get_extruder_colors_from_plater_config(); | ||||||
|  |     colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.size()); | ||||||
| 
 | 
 | ||||||
|     for (const Model::CustomGCode& code : p->model.custom_gcode_per_height) |     for (const Model::CustomGCode& code : p->model.custom_gcode_per_print_z) | ||||||
|         if (code.gcode == ColorChangeCode) |         if (code.gcode == ColorChangeCode) | ||||||
|             colors.push_back(code.color); |             colors.emplace_back(code.color); | ||||||
| 
 | 
 | ||||||
|     return colors; |     return colors; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "libslic3r/libslic3r.h" | #include "libslic3r/libslic3r.h" | ||||||
| #include "libslic3r/Utils.hpp" | #include "libslic3r/Utils.hpp" | ||||||
|  | #include "GUI_App.hpp" | ||||||
| 
 | 
 | ||||||
| // Store the print/filament/printer presets into a "presets" subdirectory of the Slic3rPE config dir.
 | // Store the print/filament/printer presets into a "presets" subdirectory of the Slic3rPE config dir.
 | ||||||
| // This breaks compatibility with the upstream Slic3r if the --datadir is used to switch between the two versions.
 | // This breaks compatibility with the upstream Slic3r if the --datadir is used to switch between the two versions.
 | ||||||
|  | @ -868,6 +869,9 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool | ||||||
|         } |         } | ||||||
|         // 4) Load the project config values (the per extruder wipe matrix etc).
 |         // 4) Load the project config values (the per extruder wipe matrix etc).
 | ||||||
|         this->project_config.apply_only(config, s_project_options); |         this->project_config.apply_only(config, s_project_options); | ||||||
|  | 
 | ||||||
|  |         update_custom_gcode_per_print_z_from_config(GUI::wxGetApp().plater()->model().custom_gcode_per_print_z, &this->project_config); | ||||||
|  | 
 | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     case ptSLA: |     case ptSLA: | ||||||
|  |  | ||||||
|  | @ -2538,7 +2538,7 @@ std::vector<t_custom_code> DoubleSlider::GetTicksValues() const | ||||||
|         for (const TICK_CODE& tick : m_ticks_) { |         for (const TICK_CODE& tick : m_ticks_) { | ||||||
|             if (tick.tick > val_size) |             if (tick.tick > val_size) | ||||||
|                 break; |                 break; | ||||||
|             values.push_back(t_custom_code(m_values[tick.tick], tick.gcode, tick.extruder, tick.color)); |             values.emplace_back(t_custom_code{m_values[tick.tick], tick.gcode, tick.extruder, tick.color}); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     return values; |     return values; | ||||||
|  | @ -2553,12 +2553,12 @@ void DoubleSlider::SetTicksValues(const std::vector<t_custom_code>& heights) | ||||||
| 
 | 
 | ||||||
|     m_ticks_.clear(); |     m_ticks_.clear(); | ||||||
|     for (auto h : heights) { |     for (auto h : heights) { | ||||||
|         auto it = std::lower_bound(m_values.begin(), m_values.end(), h.height - epsilon()); |         auto it = std::lower_bound(m_values.begin(), m_values.end(), h.print_z - epsilon()); | ||||||
| 
 | 
 | ||||||
|         if (it == m_values.end()) |         if (it == m_values.end()) | ||||||
|             continue; |             continue; | ||||||
| 
 | 
 | ||||||
|         m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder, h.color)); |         m_ticks_.emplace(TICK_CODE{int(it-m_values.begin()), h.gcode, h.extruder, h.color}); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     if (!was_empty && m_ticks_.empty()) |     if (!was_empty && m_ticks_.empty()) | ||||||
|  | @ -2642,7 +2642,7 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); |     wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); | ||||||
|     if (m_ticks_.find(tick) != m_ticks_.end()) |     if (m_ticks_.find(TICK_CODE{tick}) != m_ticks_.end()) | ||||||
|         icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); |         icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); | ||||||
| 
 | 
 | ||||||
|     wxCoord x_draw, y_draw; |     wxCoord x_draw, y_draw; | ||||||
|  | @ -3081,7 +3081,7 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) | ||||||
|     else if (m_is_action_icon_focesed) |     else if (m_is_action_icon_focesed) | ||||||
|     { |     { | ||||||
|         const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; |         const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; | ||||||
|         const auto tick_code_it = m_ticks_.find(tick); |         const auto tick_code_it = m_ticks_.find(TICK_CODE{tick}); | ||||||
|         tooltip = tick_code_it == m_ticks_.end()            ? (m_state == msSingleExtruder ? |         tooltip = tick_code_it == m_ticks_.end()            ? (m_state == msSingleExtruder ? | ||||||
|                         _(L("For add color change use left mouse button click")) : |                         _(L("For add color change use left mouse button click")) : | ||||||
|                         _(L("For add change extruder use left mouse button click"))) + "\n" + |                         _(L("For add change extruder use left mouse button click"))) + "\n" + | ||||||
|  | @ -3240,13 +3240,13 @@ void DoubleSlider::action_tick(const TicksAction action) | ||||||
| 
 | 
 | ||||||
|     const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; |     const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; | ||||||
| 
 | 
 | ||||||
|     const auto it = m_ticks_.find(tick); |     const auto it = m_ticks_.find(TICK_CODE{tick}); | ||||||
| 
 | 
 | ||||||
|     if (it != m_ticks_.end()) // erase this tick
 |     if (it != m_ticks_.end()) // erase this tick
 | ||||||
|     { |     { | ||||||
|         if (action == taAdd) |         if (action == taAdd) | ||||||
|             return; |             return; | ||||||
|         m_ticks_.erase(TICK_CODE(tick)); |         m_ticks_.erase(TICK_CODE{tick}); | ||||||
| 
 | 
 | ||||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); |         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||||
|         Refresh(); |         Refresh(); | ||||||
|  | @ -3350,7 +3350,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) | ||||||
|     { |     { | ||||||
|         const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; |         const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; | ||||||
|         // if on this Z doesn't exist tick
 |         // if on this Z doesn't exist tick
 | ||||||
|         auto it = m_ticks_.find(tick); |         auto it = m_ticks_.find(TICK_CODE{ tick }); | ||||||
|         if (it == m_ticks_.end()) |         if (it == m_ticks_.end()) | ||||||
|         { |         { | ||||||
|             // show context menu on OnRightUp()
 |             // show context menu on OnRightUp()
 | ||||||
|  | @ -3387,7 +3387,7 @@ int DoubleSlider::get_extruder_for_tick(int tick) | ||||||
|     if (m_ticks_.empty()) |     if (m_ticks_.empty()) | ||||||
|         return 0; |         return 0; | ||||||
|      |      | ||||||
|     auto it = m_ticks_.lower_bound(tick); |     auto it = m_ticks_.lower_bound(TICK_CODE{tick}); | ||||||
|     while (it != m_ticks_.begin()) { |     while (it != m_ticks_.begin()) { | ||||||
|         --it; |         --it; | ||||||
|         if(it->gcode == Slic3r::ExtruderChangeCode) |         if(it->gcode == Slic3r::ExtruderChangeCode) | ||||||
|  | @ -3454,7 +3454,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) | ||||||
|     else if (m_show_edit_menu) { |     else if (m_show_edit_menu) { | ||||||
|         wxMenu menu; |         wxMenu menu; | ||||||
| 
 | 
 | ||||||
|         std::set<TICK_CODE>::iterator it = m_ticks_.find(m_selection == ssLower ? m_lower_value : m_higher_value); |         std::set<TICK_CODE>::iterator it = m_ticks_.find(TICK_CODE{ m_selection == ssLower ? m_lower_value : m_higher_value }); | ||||||
|         const bool is_color_change = it->gcode == Slic3r::ColorChangeCode; |         const bool is_color_change = it->gcode == Slic3r::ColorChangeCode; | ||||||
| 
 | 
 | ||||||
|         append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Edit color")) : |         append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Edit color")) : | ||||||
|  | @ -3526,7 +3526,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) | ||||||
| { | { | ||||||
|     const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; |     const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; | ||||||
|     // if on this Z doesn't exist tick
 |     // if on this Z doesn't exist tick
 | ||||||
|     auto it = m_ticks_.find(tick); |     auto it = m_ticks_.find(TICK_CODE{ tick }); | ||||||
|     if (it == m_ticks_.end()) |     if (it == m_ticks_.end()) | ||||||
|     { |     { | ||||||
|         std::string color = ""; |         std::string color = ""; | ||||||
|  | @ -3535,7 +3535,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) | ||||||
|             std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); |             std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); | ||||||
| 
 | 
 | ||||||
|             if (m_state == msSingleExtruder && !m_ticks_.empty()) { |             if (m_state == msSingleExtruder && !m_ticks_.empty()) { | ||||||
|                 auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), tick); |                 auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), TICK_CODE{ tick }); | ||||||
|                 while (before_tick_it != m_ticks_.begin()) { |                 while (before_tick_it != m_ticks_.begin()) { | ||||||
|                     --before_tick_it; |                     --before_tick_it; | ||||||
|                     if (before_tick_it->gcode == Slic3r::ColorChangeCode) { |                     if (before_tick_it->gcode == Slic3r::ColorChangeCode) { | ||||||
|  | @ -3580,7 +3580,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) | ||||||
|                 extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); |                 extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         m_ticks_.insert(TICK_CODE(tick, code, extruder, color)); |         m_ticks_.emplace(TICK_CODE{tick, code, extruder, color}); | ||||||
| 
 | 
 | ||||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); |         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||||
|         Refresh(); |         Refresh(); | ||||||
|  | @ -3592,7 +3592,7 @@ void DoubleSlider::edit_tick() | ||||||
| { | { | ||||||
|     const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; |     const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; | ||||||
|     // if on this Z exists tick
 |     // if on this Z exists tick
 | ||||||
|     std::set<TICK_CODE>::iterator it = m_ticks_.find(tick); |     std::set<TICK_CODE>::iterator it = m_ticks_.find(TICK_CODE{ tick }); | ||||||
|     if (it != m_ticks_.end()) |     if (it != m_ticks_.end()) | ||||||
|     { |     { | ||||||
|         std::string edited_value; |         std::string edited_value; | ||||||
|  | @ -3619,7 +3619,7 @@ void DoubleSlider::edit_tick() | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         m_ticks_.erase(it); |         m_ticks_.erase(it); | ||||||
|         m_ticks_.insert(changed_tick); |         m_ticks_.emplace(changed_tick); | ||||||
| 
 | 
 | ||||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); |         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||||
|     } |     } | ||||||
|  | @ -3632,9 +3632,9 @@ void DoubleSlider::change_extruder(int extruder) | ||||||
|     std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); |     std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); | ||||||
| 
 | 
 | ||||||
|     // if on this Y doesn't exist tick
 |     // if on this Y doesn't exist tick
 | ||||||
|     if (m_ticks_.find(tick) == m_ticks_.end()) |     if (m_ticks_.find(TICK_CODE{tick}) == m_ticks_.end()) | ||||||
|     {         |     {         | ||||||
|         m_ticks_.insert(TICK_CODE(tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1])); |         m_ticks_.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]}); | ||||||
| 
 | 
 | ||||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); |         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||||
|         Refresh(); |         Refresh(); | ||||||
|  | @ -3672,7 +3672,7 @@ void DoubleSlider::edit_extruder_sequence() | ||||||
|     while (tick <= m_max_value) |     while (tick <= m_max_value) | ||||||
|     { |     { | ||||||
|         int cur_extruder = m_extruders_sequence.extruders[extruder]; |         int cur_extruder = m_extruders_sequence.extruders[extruder]; | ||||||
|         m_ticks_.insert(TICK_CODE(tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder])); |         m_ticks_.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder]}); | ||||||
| 
 | 
 | ||||||
|         extruder++; |         extruder++; | ||||||
|         if (extruder == extr_cnt) |         if (extruder == extr_cnt) | ||||||
|  | @ -3680,12 +3680,12 @@ void DoubleSlider::edit_extruder_sequence() | ||||||
|         if (m_extruders_sequence.is_mm_intervals) |         if (m_extruders_sequence.is_mm_intervals) | ||||||
|         { |         { | ||||||
|             value += m_extruders_sequence.interval_by_mm; |             value += m_extruders_sequence.interval_by_mm; | ||||||
|             auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); |             auto val_it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); | ||||||
| 
 | 
 | ||||||
|             if (it == m_values.end()) |             if (val_it == m_values.end()) | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|             tick = it - m_values.begin(); |             tick = val_it - m_values.begin(); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|             tick += m_extruders_sequence.interval_by_layers; |             tick += m_extruders_sequence.interval_by_layers; | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| #include <set> | #include <set> | ||||||
| #include <functional> | #include <functional> | ||||||
| #include "libslic3r/Model.hpp" | #include "libslic3r/Model.hpp" | ||||||
|  | #include "libslic3r/GCodeWriter.hpp" | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
|     enum class ModelVolumeType : int; |     enum class ModelVolumeType : int; | ||||||
|  | @ -958,24 +959,12 @@ private: | ||||||
| 
 | 
 | ||||||
|     struct TICK_CODE |     struct TICK_CODE | ||||||
|     { |     { | ||||||
|         TICK_CODE(int tick):tick(tick), gcode(Slic3r::ColorChangeCode), extruder(0), color("") {} |  | ||||||
|         TICK_CODE(int tick, const std::string& code) :  |  | ||||||
|                             tick(tick), gcode(code), extruder(0) {} |  | ||||||
|         TICK_CODE(int tick, int extruder) : |  | ||||||
|                             tick(tick), gcode(Slic3r::ColorChangeCode), extruder(extruder) {} |  | ||||||
|         TICK_CODE(int tick, const std::string& code, int extruder, const std::string& color) :  |  | ||||||
|                             tick(tick), gcode(code), extruder(extruder), color(color) {} |  | ||||||
| 
 |  | ||||||
|         bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } |         bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } | ||||||
|         bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } |         bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } | ||||||
|         TICK_CODE operator=(const TICK_CODE& other) const { |  | ||||||
|             TICK_CODE ret_val(other.tick, other.gcode, other.extruder, other.color); |  | ||||||
|             return ret_val; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         int         tick; |         int         tick; | ||||||
|         std::string gcode; |         std::string gcode = Slic3r::ColorChangeCode; | ||||||
|         int         extruder; |         int         extruder = 0; | ||||||
|         std::string color; |         std::string color; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv