mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Implemented inheritance of profiles inside a config bundle.
Updated the Prusa's presets to match the initial flat config bundle.
This commit is contained in:
		
							parent
							
								
									77e142553a
								
							
						
					
					
						commit
						f0fde26295
					
				
					 2 changed files with 161 additions and 39 deletions
				
			
		| 
						 | 
					@ -32,6 +32,7 @@ gap_fill_speed = 40
 | 
				
			||||||
gcode_comments = 0
 | 
					gcode_comments = 0
 | 
				
			||||||
infill_every_layers = 1
 | 
					infill_every_layers = 1
 | 
				
			||||||
infill_extruder = 1
 | 
					infill_extruder = 1
 | 
				
			||||||
 | 
					infill_extrusion_width = 0.45
 | 
				
			||||||
infill_first = 0
 | 
					infill_first = 0
 | 
				
			||||||
infill_only_where_needed = 0
 | 
					infill_only_where_needed = 0
 | 
				
			||||||
infill_overlap = 25%
 | 
					infill_overlap = 25%
 | 
				
			||||||
| 
						 | 
					@ -81,6 +82,7 @@ support_material_with_sheath = 0
 | 
				
			||||||
support_material_xy_spacing = 60%
 | 
					support_material_xy_spacing = 60%
 | 
				
			||||||
thin_walls = 0
 | 
					thin_walls = 0
 | 
				
			||||||
top_infill_extrusion_width = 0.45
 | 
					top_infill_extrusion_width = 0.45
 | 
				
			||||||
 | 
					top_solid_infill_speed = 40
 | 
				
			||||||
travel_speed = 180
 | 
					travel_speed = 180
 | 
				
			||||||
wipe_tower = 0
 | 
					wipe_tower = 0
 | 
				
			||||||
wipe_tower_per_color_wipe = 15
 | 
					wipe_tower_per_color_wipe = 15
 | 
				
			||||||
| 
						 | 
					@ -132,6 +134,7 @@ inherits = *0.05mm*
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1
 | 
				
			||||||
external_perimeter_extrusion_width = 0
 | 
					external_perimeter_extrusion_width = 0
 | 
				
			||||||
extrusion_width = 0.28
 | 
					extrusion_width = 0.28
 | 
				
			||||||
 | 
					fill_density = 20%
 | 
				
			||||||
first_layer_extrusion_width = 0.3
 | 
					first_layer_extrusion_width = 0.3
 | 
				
			||||||
infill_extrusion_width = 0
 | 
					infill_extrusion_width = 0
 | 
				
			||||||
infill_speed = 20
 | 
					infill_speed = 20
 | 
				
			||||||
| 
						 | 
					@ -171,10 +174,10 @@ infill_speed = 60
 | 
				
			||||||
perimeter_speed = 50
 | 
					perimeter_speed = 50
 | 
				
			||||||
perimeters = 3
 | 
					perimeters = 3
 | 
				
			||||||
solid_infill_speed = 50
 | 
					solid_infill_speed = 50
 | 
				
			||||||
top_solid_infill_speed = 40
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.10mm DETAIL MK3]
 | 
					[print:0.10mm DETAIL MK3]
 | 
				
			||||||
inherits = *0.10mm*
 | 
					inherits = *0.10mm*
 | 
				
			||||||
 | 
					bridge_flow_ratio = 0.8
 | 
				
			||||||
bridge_speed = 30
 | 
					bridge_speed = 30
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/
 | 
				
			||||||
external_perimeter_speed = 35
 | 
					external_perimeter_speed = 35
 | 
				
			||||||
| 
						 | 
					@ -190,35 +193,30 @@ top_solid_infill_speed = 50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.10mm DETAIL 0.25 nozzle]
 | 
					[print:0.10mm DETAIL 0.25 nozzle]
 | 
				
			||||||
inherits = *0.10mm*
 | 
					inherits = *0.10mm*
 | 
				
			||||||
bottom_solid_layers = 10
 | 
					bridge_acceleration = 600
 | 
				
			||||||
bridge_acceleration = 300
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1
 | 
					 | 
				
			||||||
default_acceleration = 500
 | 
					 | 
				
			||||||
external_perimeter_extrusion_width = 0
 | 
					 | 
				
			||||||
external_perimeter_speed = 20
 | 
					external_perimeter_speed = 20
 | 
				
			||||||
extrusion_width = 0.28
 | 
					external_perimeter_extrusion_width = 0.25
 | 
				
			||||||
first_layer_acceleration = 500
 | 
					extrusion_width = 0.25
 | 
				
			||||||
first_layer_extrusion_width = 0.3
 | 
					fill_density = 15%
 | 
				
			||||||
gap_fill_speed = 20
 | 
					first_layer_extrusion_width = 0.25
 | 
				
			||||||
infill_acceleration = 800
 | 
					infill_acceleration = 1600
 | 
				
			||||||
infill_extrusion_width = 0
 | 
					infill_extrusion_width = 0.25
 | 
				
			||||||
infill_speed = 20
 | 
					infill_speed = 40
 | 
				
			||||||
perimeter_acceleration = 300
 | 
					perimeter_acceleration = 600
 | 
				
			||||||
perimeter_extrusion_width = 0
 | 
					perimeter_extrusion_width = 0.25
 | 
				
			||||||
perimeter_speed = 20
 | 
					perimeter_speed = 25
 | 
				
			||||||
perimeters = 4
 | 
					perimeters = 4
 | 
				
			||||||
small_perimeter_speed = 10
 | 
					small_perimeter_speed = 10
 | 
				
			||||||
solid_infill_extrusion_width = 0
 | 
					solid_infill_extrusion_width = 0.25
 | 
				
			||||||
solid_infill_speed = 20
 | 
					solid_infill_speed = 40
 | 
				
			||||||
support_material_extrusion_width = 0.18
 | 
					support_material_extrusion_width = 0.18
 | 
				
			||||||
support_material_interface_layers = 0
 | 
					support_material_interface_layers = 0
 | 
				
			||||||
support_material_interface_spacing = 0.15
 | 
					support_material_interface_spacing = 0.15
 | 
				
			||||||
support_material_spacing = 1
 | 
					support_material_spacing = 1
 | 
				
			||||||
support_material_speed = 20
 | 
					 | 
				
			||||||
support_material_xy_spacing = 150%
 | 
					support_material_xy_spacing = 150%
 | 
				
			||||||
top_infill_extrusion_width = 0
 | 
					top_infill_extrusion_width = 0.25
 | 
				
			||||||
top_solid_infill_speed = 20
 | 
					top_solid_infill_speed = 30
 | 
				
			||||||
top_solid_layers = 15
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:*0.15mm*]
 | 
					[print:*0.15mm*]
 | 
				
			||||||
inherits = *common*
 | 
					inherits = *common*
 | 
				
			||||||
| 
						 | 
					@ -235,7 +233,6 @@ support_material_contact_distance = 0.15
 | 
				
			||||||
support_material_interface_spacing = 0.2
 | 
					support_material_interface_spacing = 0.2
 | 
				
			||||||
support_material_spacing = 2
 | 
					support_material_spacing = 2
 | 
				
			||||||
top_infill_extrusion_width = 0.4
 | 
					top_infill_extrusion_width = 0.4
 | 
				
			||||||
top_solid_infill_speed = 40
 | 
					 | 
				
			||||||
top_solid_layers = 7
 | 
					top_solid_layers = 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.15mm 100mms Linear Advance]
 | 
					[print:0.15mm 100mms Linear Advance]
 | 
				
			||||||
| 
						 | 
					@ -257,6 +254,7 @@ top_solid_layers = 5
 | 
				
			||||||
[print:0.15mm OPTIMAL]
 | 
					[print:0.15mm OPTIMAL]
 | 
				
			||||||
inherits = *0.15mm*
 | 
					inherits = *0.15mm*
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4
 | 
				
			||||||
 | 
					top_infill_extrusion_width = 0.45
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.15mm OPTIMAL 0.25 nozzle]
 | 
					[print:0.15mm OPTIMAL 0.25 nozzle]
 | 
				
			||||||
inherits = *0.15mm*
 | 
					inherits = *0.15mm*
 | 
				
			||||||
| 
						 | 
					@ -315,14 +313,12 @@ wipe_tower = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.15mm OPTIMAL SOLUBLE FULL]
 | 
					[print:0.15mm OPTIMAL SOLUBLE FULL]
 | 
				
			||||||
inherits = *0.15mm*
 | 
					inherits = *0.15mm*
 | 
				
			||||||
bottom_solid_layers = 4
 | 
					bottom_solid_layers = 5
 | 
				
			||||||
bridge_flow_ratio = 0.95
 | 
					 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders>1
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders>1
 | 
				
			||||||
external_perimeter_speed = 30
 | 
					external_perimeter_speed = 25
 | 
				
			||||||
notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder &  Support material/raft interface extruder
 | 
					notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder &  Support material/raft interface extruder
 | 
				
			||||||
overhangs = 1
 | 
					overhangs = 1
 | 
				
			||||||
perimeter_speed = 40
 | 
					perimeter_speed = 40
 | 
				
			||||||
perimeters = 2
 | 
					 | 
				
			||||||
skirts = 0
 | 
					skirts = 0
 | 
				
			||||||
solid_infill_speed = 40
 | 
					solid_infill_speed = 40
 | 
				
			||||||
support_material = 1
 | 
					support_material = 1
 | 
				
			||||||
| 
						 | 
					@ -334,10 +330,11 @@ support_material_interface_spacing = 0.1
 | 
				
			||||||
support_material_synchronize_layers = 1
 | 
					support_material_synchronize_layers = 1
 | 
				
			||||||
support_material_threshold = 80
 | 
					support_material_threshold = 80
 | 
				
			||||||
support_material_with_sheath = 1
 | 
					support_material_with_sheath = 1
 | 
				
			||||||
support_material_xy_spacing = 120%
 | 
					support_material_xy_spacing = 60%
 | 
				
			||||||
 | 
					top_infill_extrusion_width = 0.45
 | 
				
			||||||
top_solid_infill_speed = 30
 | 
					top_solid_infill_speed = 30
 | 
				
			||||||
top_solid_layers = 5
 | 
					 | 
				
			||||||
wipe_tower = 1
 | 
					wipe_tower = 1
 | 
				
			||||||
 | 
					wipe_tower_per_color_wipe = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.15mm OPTIMAL SOLUBLE INTERFACE]
 | 
					[print:0.15mm OPTIMAL SOLUBLE INTERFACE]
 | 
				
			||||||
inherits = 0.15mm OPTIMAL SOLUBLE FULL
 | 
					inherits = 0.15mm OPTIMAL SOLUBLE FULL
 | 
				
			||||||
| 
						 | 
					@ -345,7 +342,7 @@ notes = Set your solluble extruder in Multiple Extruders >  Support material/raf
 | 
				
			||||||
support_material_extruder = 0
 | 
					support_material_extruder = 0
 | 
				
			||||||
support_material_interface_layers = 3
 | 
					support_material_interface_layers = 3
 | 
				
			||||||
support_material_with_sheath = 0
 | 
					support_material_with_sheath = 0
 | 
				
			||||||
wipe_tower_per_color_wipe = 20
 | 
					support_material_xy_spacing = 120%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:*0.20mm*]
 | 
					[print:*0.20mm*]
 | 
				
			||||||
inherits = *common*
 | 
					inherits = *common*
 | 
				
			||||||
| 
						 | 
					@ -436,6 +433,7 @@ inherits = 0.20mm NORMAL SOLUBLE FULL
 | 
				
			||||||
notes = Set your solluble extruder in Multiple Extruders >  Support material/raft interface extruder
 | 
					notes = Set your solluble extruder in Multiple Extruders >  Support material/raft interface extruder
 | 
				
			||||||
support_material_extruder = 0
 | 
					support_material_extruder = 0
 | 
				
			||||||
support_material_interface_layers = 3
 | 
					support_material_interface_layers = 3
 | 
				
			||||||
 | 
					support_material_with_sheath = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:*0.35mm*]
 | 
					[print:*0.35mm*]
 | 
				
			||||||
inherits = *common*
 | 
					inherits = *common*
 | 
				
			||||||
| 
						 | 
					@ -448,10 +446,10 @@ infill_extrusion_width = 0.75
 | 
				
			||||||
infill_speed = 60
 | 
					infill_speed = 60
 | 
				
			||||||
layer_height = 0.35
 | 
					layer_height = 0.35
 | 
				
			||||||
perimeter_acceleration = 800
 | 
					perimeter_acceleration = 800
 | 
				
			||||||
perimeter_extrusion_width = 0.43
 | 
					perimeter_extrusion_width = 0.65
 | 
				
			||||||
perimeter_speed = 50
 | 
					perimeter_speed = 50
 | 
				
			||||||
perimeters = 2
 | 
					perimeters = 2
 | 
				
			||||||
solid_infill_extrusion_width = 0.7
 | 
					solid_infill_extrusion_width = 0.65
 | 
				
			||||||
solid_infill_speed = 60
 | 
					solid_infill_speed = 60
 | 
				
			||||||
support_material_contact_distance = 0.15
 | 
					support_material_contact_distance = 0.15
 | 
				
			||||||
support_material_interface_spacing = 0.2
 | 
					support_material_interface_spacing = 0.2
 | 
				
			||||||
| 
						 | 
					@ -461,27 +459,28 @@ top_solid_layers = 4
 | 
				
			||||||
wipe_tower = 1
 | 
					wipe_tower = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.35mm FAST]
 | 
					[print:0.35mm FAST]
 | 
				
			||||||
inherits = *common*
 | 
					inherits = *0.35mm*
 | 
				
			||||||
bridge_flow_ratio = 0.95
 | 
					bridge_flow_ratio = 0.95
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4
 | 
				
			||||||
 | 
					first_layer_extrusion_width = 0.42
 | 
				
			||||||
infill_extrusion_width = 0.7
 | 
					infill_extrusion_width = 0.7
 | 
				
			||||||
perimeter_extrusion_width = 0.65
 | 
					perimeter_extrusion_width = 0.43
 | 
				
			||||||
solid_infill_extrusion_width = 0.7
 | 
					solid_infill_extrusion_width = 0.7
 | 
				
			||||||
top_infill_extrusion_width = 0.43
 | 
					top_infill_extrusion_width = 0.43
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.35mm FAST 0.6 nozzle]
 | 
					[print:0.35mm FAST 0.6 nozzle]
 | 
				
			||||||
inherits = *common*
 | 
					inherits = *0.35mm*
 | 
				
			||||||
bottom_solid_layers = 7
 | 
					bottom_solid_layers = 7
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.61
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6
 | 
				
			||||||
 | 
					external_perimeter_extrusion_width = 0.61
 | 
				
			||||||
extrusion_width = 0.67
 | 
					extrusion_width = 0.67
 | 
				
			||||||
first_layer_extrusion_width = 0.65
 | 
					first_layer_extrusion_width = 0.65
 | 
				
			||||||
perimeters = 3
 | 
					perimeters = 3
 | 
				
			||||||
solid_infill_extrusion_width = 0.65
 | 
					 | 
				
			||||||
top_infill_extrusion_width = 0.6
 | 
					top_infill_extrusion_width = 0.6
 | 
				
			||||||
top_solid_layers = 9
 | 
					top_solid_layers = 9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.35mm FAST sol full 0.6 nozzle]
 | 
					[print:0.35mm FAST sol full 0.6 nozzle]
 | 
				
			||||||
inherits = *common*
 | 
					inherits = *0.35mm*
 | 
				
			||||||
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 and num_extruders>1
 | 
					compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 and num_extruders>1
 | 
				
			||||||
external_perimeter_speed = 30
 | 
					external_perimeter_speed = 30
 | 
				
			||||||
extrusion_width = 0.67
 | 
					extrusion_width = 0.67
 | 
				
			||||||
| 
						 | 
					@ -500,11 +499,12 @@ support_material_synchronize_layers = 1
 | 
				
			||||||
support_material_threshold = 80
 | 
					support_material_threshold = 80
 | 
				
			||||||
support_material_xy_spacing = 120%
 | 
					support_material_xy_spacing = 120%
 | 
				
			||||||
top_infill_extrusion_width = 0.57
 | 
					top_infill_extrusion_width = 0.57
 | 
				
			||||||
 | 
					wipe_tower_per_color_wipe = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print:0.35mm FAST sol int 0.6 nozzle]
 | 
					[print:0.35mm FAST sol int 0.6 nozzle]
 | 
				
			||||||
inherits = 0.35mm FAST sol full 0.6 nozzle
 | 
					inherits = 0.35mm FAST sol full 0.6 nozzle
 | 
				
			||||||
support_material_extruder = 0
 | 
					support_material_extruder = 0
 | 
				
			||||||
support_material_interface_layers = 0
 | 
					support_material_interface_layers = 2
 | 
				
			||||||
support_material_xy_spacing = 150%
 | 
					support_material_xy_spacing = 150%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[filament:*common*]
 | 
					[filament:*common*]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
#include <boost/property_tree/ini_parser.hpp>
 | 
					#include <boost/property_tree/ini_parser.hpp>
 | 
				
			||||||
#include <boost/property_tree/ptree.hpp>
 | 
					#include <boost/property_tree/ptree.hpp>
 | 
				
			||||||
#include <boost/locale.hpp>
 | 
					#include <boost/locale.hpp>
 | 
				
			||||||
 | 
					#include <boost/log/trivial.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <wx/dcmemory.h>
 | 
					#include <wx/dcmemory.h>
 | 
				
			||||||
#include <wx/image.h>
 | 
					#include <wx/image.h>
 | 
				
			||||||
| 
						 | 
					@ -474,6 +475,125 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const
 | 
				
			||||||
    this->update_compatible_with_printer(false);
 | 
					    this->update_compatible_with_printer(false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Process the Config Bundle loaded as a Boost property tree.
 | 
				
			||||||
 | 
					// For each print, filament and printer preset (group defined by group_name), apply the inherited presets.
 | 
				
			||||||
 | 
					// The presets starting with '*' are considered non-terminal and they are
 | 
				
			||||||
 | 
					// removed through the flattening process by this function.
 | 
				
			||||||
 | 
					// This function will never fail, but it will produce error messages through boost::log.
 | 
				
			||||||
 | 
					static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree, const std::string &group_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    namespace pt = boost::property_tree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef std::pair<pt::ptree::key_type, pt::ptree> ptree_child_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 1) For the group given by group_name, initialize the presets.
 | 
				
			||||||
 | 
					    struct Prst {
 | 
				
			||||||
 | 
					        Prst(const std::string &name, pt::ptree *node) : name(name), node(node) {}
 | 
				
			||||||
 | 
					        // Name of this preset. If the name starts with '*', it is an intermediate preset,
 | 
				
			||||||
 | 
					        // which will not make it into the result.
 | 
				
			||||||
 | 
					        const std::string           name;
 | 
				
			||||||
 | 
					        // Link to the source boost property tree node, owned by tree.
 | 
				
			||||||
 | 
					        pt::ptree                  *node;
 | 
				
			||||||
 | 
					        // Link to the presets, from which this preset inherits.
 | 
				
			||||||
 | 
					        std::vector<Prst*>          inherits;
 | 
				
			||||||
 | 
					        // Link to the presets, for which this preset is a direct parent.
 | 
				
			||||||
 | 
					        std::vector<Prst*>          parent_of;
 | 
				
			||||||
 | 
					        // When running the Kahn's Topological sorting algorithm, this counter is decreased from inherits.size() to zero.
 | 
				
			||||||
 | 
					        // A cycle is indicated, if the number does not drop to zero after the Kahn's algorithm finishes.
 | 
				
			||||||
 | 
					        size_t                      num_incoming_edges_left = 0;
 | 
				
			||||||
 | 
					        // Sorting by the name, to be used when inserted into std::set.
 | 
				
			||||||
 | 
					        bool operator==(const Prst &rhs) const { return this->name == rhs.name; }
 | 
				
			||||||
 | 
					        bool operator< (const Prst &rhs) const { return this->name < rhs.name; }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    // Find the presets, store them into a std::map, addressed by their names.
 | 
				
			||||||
 | 
					    std::set<Prst> presets;
 | 
				
			||||||
 | 
					    std::string group_name_preset = group_name + ":";
 | 
				
			||||||
 | 
					    for (auto §ion : tree)
 | 
				
			||||||
 | 
					        if (boost::starts_with(section.first, group_name_preset) && section.first.size() > group_name_preset.size())
 | 
				
			||||||
 | 
					            presets.emplace(section.first.substr(group_name_preset.size()), §ion.second);
 | 
				
			||||||
 | 
					    // Fill in the "inherits" and "parent_of" members, report invalid inheritance fields.
 | 
				
			||||||
 | 
					    for (const Prst &prst : presets) {
 | 
				
			||||||
 | 
					        // Parse the list of comma separated values, possibly enclosed in quotes.
 | 
				
			||||||
 | 
					        std::vector<std::string> inherits_names;
 | 
				
			||||||
 | 
					        if (Slic3r::unescape_strings_cstyle(prst.node->get<std::string>("inherits", ""), inherits_names)) {
 | 
				
			||||||
 | 
					            // Resolve the inheritance by name.
 | 
				
			||||||
 | 
					            std::vector<Prst*> &inherits_nodes = const_cast<Prst&>(prst).inherits;
 | 
				
			||||||
 | 
					            for (const std::string &node_name : inherits_names) {
 | 
				
			||||||
 | 
					                auto it = presets.find(Prst(node_name, nullptr));
 | 
				
			||||||
 | 
					                if (it == presets.end())
 | 
				
			||||||
 | 
					                    BOOST_LOG_TRIVIAL(error) << "flatten_configbundle_hierarchy: The preset " << prst.name << " inherits an unknown preset \"" << node_name << "\"";
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    inherits_nodes.emplace_back(const_cast<Prst*>(&(*it)));
 | 
				
			||||||
 | 
					                    inherits_nodes.back()->parent_of.emplace_back(const_cast<Prst*>(&prst));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            BOOST_LOG_TRIVIAL(error) << "flatten_configbundle_hierarchy: The preset " << prst.name << " has an invalid \"inherits\" field";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Remove the "inherits" key, it has no meaning outside the config bundle.
 | 
				
			||||||
 | 
					        const_cast<pt::ptree*>(prst.node)->erase("inherits");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 2) Create a linear ordering for the directed acyclic graph of preset inheritance.
 | 
				
			||||||
 | 
					    // https://en.wikipedia.org/wiki/Topological_sorting
 | 
				
			||||||
 | 
					    // Kahn's algorithm.
 | 
				
			||||||
 | 
					    std::vector<Prst*> sorted;
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Initialize S with the set of all nodes with no incoming edge.
 | 
				
			||||||
 | 
					        std::deque<Prst*> S;
 | 
				
			||||||
 | 
					        for (const Prst &prst : presets)
 | 
				
			||||||
 | 
					            if (prst.inherits.empty())
 | 
				
			||||||
 | 
					                S.emplace_back(const_cast<Prst*>(&prst));
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                const_cast<Prst*>(&prst)->num_incoming_edges_left = prst.inherits.size();
 | 
				
			||||||
 | 
					        while (! S.empty()) {
 | 
				
			||||||
 | 
					            Prst *n = S.front();
 | 
				
			||||||
 | 
					            S.pop_front();
 | 
				
			||||||
 | 
					            sorted.emplace_back(n);
 | 
				
			||||||
 | 
					            for (Prst *m : n->parent_of) {
 | 
				
			||||||
 | 
					                assert(m->num_incoming_edges_left > 0);
 | 
				
			||||||
 | 
					                if (-- m->num_incoming_edges_left == 0) {
 | 
				
			||||||
 | 
					                    // We have visited all parents of m.
 | 
				
			||||||
 | 
					                    S.emplace_back(m);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (sorted.size() < presets.size()) {
 | 
				
			||||||
 | 
					            for (const Prst &prst : presets)
 | 
				
			||||||
 | 
					                if (prst.num_incoming_edges_left)
 | 
				
			||||||
 | 
					                    BOOST_LOG_TRIVIAL(error) << "flatten_configbundle_hierarchy: The preset " << prst.name << " has cyclic dependencies";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Apply the dependencies in their topological ordering.
 | 
				
			||||||
 | 
					    for (Prst *prst : sorted) {
 | 
				
			||||||
 | 
					        // Merge the preset nodes in their order of application.
 | 
				
			||||||
 | 
					        // Iterate in a reverse order, so the last change will be placed first in merged.
 | 
				
			||||||
 | 
					        for (auto it_inherits = prst->inherits.rbegin(); it_inherits != prst->inherits.rend(); ++ it_inherits)
 | 
				
			||||||
 | 
					            for (auto it = (*it_inherits)->node->begin(); it != (*it_inherits)->node->end(); ++ it)
 | 
				
			||||||
 | 
					                if (prst->node->find(it->first) == prst->node->not_found())
 | 
				
			||||||
 | 
					                    prst->node->add_child(it->first, it->second);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Remove the "internal" presets from the ptree. These presets are marked with '*'.
 | 
				
			||||||
 | 
					    group_name_preset += '*';
 | 
				
			||||||
 | 
					    for (auto it_section = tree.begin(); it_section != tree.end(); ) {
 | 
				
			||||||
 | 
					        if (boost::starts_with(it_section->first, group_name_preset) && it_section->first.size() > group_name_preset.size())
 | 
				
			||||||
 | 
					            // Remove the "internal" preset from the ptree.
 | 
				
			||||||
 | 
					            it_section = tree.erase(it_section);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            // Keep the preset.
 | 
				
			||||||
 | 
					            ++ it_section;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    flatten_configbundle_hierarchy(tree, "print");
 | 
				
			||||||
 | 
					    flatten_configbundle_hierarchy(tree, "filament");
 | 
				
			||||||
 | 
					    flatten_configbundle_hierarchy(tree, "printer");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load a config bundle file, into presets and store the loaded presets into separate files
 | 
					// Load a config bundle file, into presets and store the loaded presets into separate files
 | 
				
			||||||
// of the local configuration directory.
 | 
					// of the local configuration directory.
 | 
				
			||||||
size_t PresetBundle::load_configbundle(const std::string &path, unsigned int flags)
 | 
					size_t PresetBundle::load_configbundle(const std::string &path, unsigned int flags)
 | 
				
			||||||
| 
						 | 
					@ -486,6 +606,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
 | 
				
			||||||
    pt::ptree tree;
 | 
					    pt::ptree tree;
 | 
				
			||||||
    boost::nowide::ifstream ifs(path);
 | 
					    boost::nowide::ifstream ifs(path);
 | 
				
			||||||
    pt::read_ini(ifs, tree);
 | 
					    pt::read_ini(ifs, tree);
 | 
				
			||||||
 | 
					    // Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
 | 
				
			||||||
 | 
					    flatten_configbundle_hierarchy(tree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
 | 
					    // 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
 | 
				
			||||||
    std::vector<std::string> loaded_prints;
 | 
					    std::vector<std::string> loaded_prints;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue