247 lines
10 KiB
Python
247 lines
10 KiB
Python
import os
|
||
|
||
def load_valid_keys():
|
||
valid = set()
|
||
if os.path.exists('valid_keys.txt'):
|
||
with open('valid_keys.txt', 'r') as f:
|
||
for line in f:
|
||
if line.strip():
|
||
valid.add(line.strip())
|
||
# 补充一些在 PrusaSlicer ini常见但可能在cli中缺失的原生合法字段
|
||
valid.update([
|
||
"start_gcode", "end_gcode", "before_layer_gcode", "temperature",
|
||
"first_layer_temperature", "bed_temperature", "first_layer_bed_temperature",
|
||
"printer_model", "family", "z_offset", "printer_technology",
|
||
"gcode_flavor", "silent_mode", "printer_variant", "max_print_height",
|
||
"nozzle_diameter", "extruder_colour", "extruder_offset", "use_relative_e_distances",
|
||
"use_firmware_retraction", "retract_layer_change", "retract_length",
|
||
"retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed",
|
||
"deretract_speed", "retract_before_travel", "retract_before_wipe", "wipe",
|
||
"machine_limits_usage", "machine_max_acceleration_x", "machine_max_acceleration_y",
|
||
"machine_max_acceleration_z", "machine_max_acceleration_e",
|
||
"machine_max_speed_x", "machine_max_speed_y", "machine_max_speed_z",
|
||
"machine_max_speed_e", "machine_max_jerk_x", "machine_max_jerk_y",
|
||
"machine_max_jerk_z", "machine_max_jerk_e", "machine_min_travel_rate",
|
||
"default_filament_colour", "filament_type", "filament_diameter",
|
||
"filament_density", "filament_cost", "fan_always_on", "cooling",
|
||
"support_material", "support_material_auto", "support_material_style"
|
||
])
|
||
return valid
|
||
|
||
VALID_KEYS = load_valid_keys()
|
||
|
||
# 基于全量 all_keys.txt 逐一梳理的语义映射字典
|
||
SEMANTIC_MAP = {
|
||
# 打印层高相关
|
||
"adaptive_layer_height": "variable_layer_height",
|
||
"initial_layer_print_height": "first_layer_height",
|
||
"layer_height": "layer_height",
|
||
"min_layer_height": "min_layer_height",
|
||
"max_layer_height": "max_layer_height",
|
||
"print_sequence": "complete_objects",
|
||
|
||
# 线宽相关
|
||
"line_width": "extrusion_width",
|
||
"initial_layer_line_width": "first_layer_extrusion_width",
|
||
"outer_wall_line_width": "external_perimeter_extrusion_width",
|
||
"inner_wall_line_width": "perimeter_extrusion_width",
|
||
"top_surface_line_width": "top_infill_extrusion_width",
|
||
"sparse_infill_line_width": "infill_extrusion_width",
|
||
"internal_solid_infill_line_width": "solid_infill_extrusion_width",
|
||
|
||
# 墙/外壳相关
|
||
"wall_loops": "perimeters",
|
||
"top_shell_layers": "top_solid_layers",
|
||
"bottom_shell_layers": "bottom_solid_layers",
|
||
"top_shell_thickness": "top_solid_min_thickness",
|
||
"bottom_shell_thickness": "bottom_solid_min_thickness",
|
||
"only_one_wall_top": "top_one_perimeter_type",
|
||
"detect_thin_wall": "thin_walls",
|
||
# "detect_narrow_internal_solid_infill": "thin_walls",
|
||
"reduce_crossing_wall": "avoid_crossing_perimeters",
|
||
|
||
# 填充相关
|
||
"sparse_infill_density": "fill_density",
|
||
"sparse_infill_pattern": "fill_pattern",
|
||
"infill_direction": "fill_angle",
|
||
"infill_wall_overlap": "infill_overlap",
|
||
"infill_combination": "solid_infill_every_layers",
|
||
"bottom_surface_pattern": "bottom_fill_pattern",
|
||
"top_surface_pattern": "top_fill_pattern",
|
||
"gap_fill_target": "gap_fill_enabled",
|
||
|
||
# 速度相关
|
||
"initial_layer_speed": "first_layer_speed",
|
||
"initial_layer_infill_speed": "first_layer_infill_speed",
|
||
"outer_wall_speed": "external_perimeter_speed",
|
||
"inner_wall_speed": "perimeter_speed",
|
||
"top_surface_speed": "top_solid_infill_speed",
|
||
"sparse_infill_speed": "infill_speed",
|
||
"internal_solid_infill_speed": "solid_infill_speed",
|
||
"gap_infill_speed": "gap_fill_speed",
|
||
"bridge_speed": "bridge_speed",
|
||
"travel_speed": "travel_speed",
|
||
"travel_speed_z": "travel_speed_z",
|
||
"small_perimeter_speed": "small_perimeter_speed",
|
||
"support_speed": "support_material_speed",
|
||
"support_interface_speed": "support_material_interface_speed",
|
||
|
||
# 加速度相关
|
||
"default_acceleration": "default_acceleration",
|
||
"initial_layer_acceleration": "first_layer_acceleration",
|
||
"outer_wall_acceleration": "external_perimeter_acceleration",
|
||
"inner_wall_acceleration": "perimeter_acceleration",
|
||
"top_surface_acceleration": "top_solid_infill_acceleration",
|
||
"travel_acceleration": "travel_acceleration",
|
||
"bridge_acceleration": "bridge_acceleration",
|
||
|
||
# 支撑相关
|
||
"support_angle": "support_material_angle",
|
||
"support_top_z_distance": "support_material_contact_distance",
|
||
"support_bottom_z_distance": "support_material_bottom_contact_distance",
|
||
"support_interface_top_layers": "support_material_interface_layers",
|
||
"support_interface_bottom_layers": "support_material_bottom_interface_layers",
|
||
"support_interface_spacing": "support_material_interface_spacing",
|
||
# "support_remove_small_overhang": "support_material_threshold",
|
||
"support_interface_pattern": "support_material_interface_pattern",
|
||
|
||
# 底座/附着相关
|
||
"brim_width": "brim_width",
|
||
"raft_layers": "raft_layers",
|
||
"raft_contact_distance": "raft_contact_distance",
|
||
"raft_expansion": "raft_expansion",
|
||
"raft_first_layer_density": "raft_first_layer_density",
|
||
"raft_first_layer_expansion": "raft_first_layer_expansion",
|
||
"skirt_distance": "skirt_distance",
|
||
"skirt_height": "skirt_height",
|
||
"skirt_loops": "skirts",
|
||
"elefant_foot_compensation": "elefant_foot_compensation",
|
||
|
||
# 回抽与耗材相关
|
||
"z_hop": "retract_lift",
|
||
"retract_length": "retract_length",
|
||
"retract_speed": "retract_speed",
|
||
"retract_before_wipe": "retract_before_wipe",
|
||
"retract_before_travel": "retract_before_travel",
|
||
"retract_layer_change": "retract_layer_change",
|
||
"retract_lift_above": "retract_lift_above",
|
||
"retract_lift_below": "retract_lift_below",
|
||
"filament_deretraction_speed": "filament_deretract_speed",
|
||
"filament_retraction_length": "filament_retract_length",
|
||
"filament_retraction_speed": "filament_retract_speed",
|
||
"material_type": "filament_type",
|
||
"nozzle_temperature": "temperature",
|
||
"nozzle_temperature_initial_layer": "first_layer_temperature",
|
||
"filament_flow_ratio": "extrusion_multiplier",
|
||
|
||
# 其他属性
|
||
"bridge_flow": "bridge_flow_ratio",
|
||
# "idle_temperature": "standby_temperature_delta",
|
||
"enable_arc_fitting": "arc_fitting",
|
||
"slowdown_for_curled_perimeters": "avoid_crossing_curled_overhangs",
|
||
"slow_down_layer_time": "slowdown_below_layer_time",
|
||
"fan_max_speed": "max_fan_speed",
|
||
"fan_min_speed": "min_fan_speed",
|
||
"spiral_mode": "spiral_vase",
|
||
"prime_tower_brim_width": "wipe_tower_brim_width",
|
||
"prime_tower_width": "wipe_tower_width",
|
||
|
||
"bridge_no_support": "dont_support_bridges",
|
||
"minimum_sparse_infill_area": "solid_infill_below_area",
|
||
"xy_hole_compensation": "xy_size_compensation",
|
||
"enable_prime_tower": "wipe_tower",
|
||
"ironing_flow": "ironing_flowrate",
|
||
"overhang_1_4_speed": "overhang_speed_0",
|
||
"overhang_2_4_speed": "overhang_speed_1",
|
||
"overhang_3_4_speed": "overhang_speed_2",
|
||
"overhang_4_4_speed": "overhang_speed_3",
|
||
"enable_overhang_speed": "enable_dynamic_overhang_speeds",
|
||
"enforce_support_layers": "support_material_enforce_layers",
|
||
"fuzzy_skin_point_distance": "fuzzy_skin_point_dist",
|
||
# "initial_layer_min_bead_width": "min_bead_width",
|
||
# "internal_bridge_flow": "bridge_flow_ratio",
|
||
# "internal_bridge_speed": "bridge_speed",
|
||
"internal_solid_infill_acceleration": "solid_infill_acceleration",
|
||
"internal_solid_infill_pattern": "solid_fill_pattern",
|
||
"is_infill_first": "infill_first",
|
||
"seam_gap": "seam_gap_distance",
|
||
"seam_slope_entire_loop": "scarf_seam_entire_loop",
|
||
"seam_slope_inner_walls": "scarf_seam_on_inner_perimeters",
|
||
"seam_slope_min_length": "scarf_seam_length",
|
||
"seam_slope_start_height": "scarf_seam_start_height",
|
||
"sparse_infill_acceleration": "infill_acceleration",
|
||
"internal_solid_infill_acceleration": "solid_infill_acceleration",
|
||
"wall_generator": "perimeter_generator",
|
||
# "wipe_tower_rotation_angle": "wipe_tower_cone_angle"
|
||
}
|
||
|
||
def process_file(filepath):
|
||
with open(filepath, 'r') as f:
|
||
lines = f.readlines()
|
||
|
||
new_lines = []
|
||
changed = False
|
||
|
||
for line in lines:
|
||
stripped = line.strip()
|
||
# 忽略空行、段名和已经是原生的配置行
|
||
if not stripped or stripped.startswith('[') or stripped.startswith(';') or stripped.startswith('show_name'):
|
||
new_lines.append(line)
|
||
continue
|
||
|
||
if '=' in line:
|
||
parts = line.split('=', 1)
|
||
raw_key = parts[0].strip()
|
||
# 兼容前面可能被加了;;;的key重新解开的情况(以防跑多次)
|
||
key = raw_key.lstrip(';')
|
||
val = parts[1].strip()
|
||
|
||
# 处理一些特有的布尔值或字符串转义差异
|
||
if key == "print_sequence" and val == "by layer":
|
||
val = "0"
|
||
elif key == "print_sequence" and val == "by object":
|
||
val = "1"
|
||
if key == "spiral_mode":
|
||
val = "1" if val != "0" else "0"
|
||
if key == "support_type" and "auto" in val:
|
||
val = "1"
|
||
|
||
if val == "zig-zag":
|
||
val = "zigzag"
|
||
|
||
if key == "enable_arc_fitting":
|
||
if str(val) == "1":
|
||
val = "emit_center"
|
||
else:
|
||
val = "disabled"
|
||
|
||
if key == "only_one_wall_top":
|
||
if str(val) == "1":
|
||
val = "top"
|
||
else:
|
||
val = "none"
|
||
|
||
if key in SEMANTIC_MAP:
|
||
new_key = SEMANTIC_MAP[key]
|
||
new_lines.append(f"{new_key} = {val}\n")
|
||
changed = True
|
||
elif key in VALID_KEYS:
|
||
# 已经是PrusaSlicer的原生可用属性
|
||
new_lines.append(f"{key} = {val}\n")
|
||
else:
|
||
# 在 all_keys.txt 中但找不到任何对应 PrusaSlicer 语义的属性
|
||
new_lines.append(f";;;{raw_key} = {val}\n")
|
||
changed = True
|
||
else:
|
||
new_lines.append(line)
|
||
|
||
if changed:
|
||
with open(filepath, 'w') as f:
|
||
f.writelines(new_lines)
|
||
|
||
for root, dirs, files in os.walk('print_config/prusa_slicer'):
|
||
for file in files:
|
||
if file.endswith('.ini'):
|
||
process_file(os.path.join(root, file))
|
||
print("All keys mapped exhaustively.")
|