import subprocess def slice_stl(file_path, output_dir, options=None): """ STL 파일을 PrusaSlicer를 사용하여 슬라이스하는 함수 """ command = [ 'PrusaSlicer', '-g' ] # 옵션 추가 for key, value in options.items(): command.extend([f'--{key}', value]) # 파일 경로 추가 command.append(' '+file_path) # 출력 디렉토리는 PrusaSlicer가 인식할 수 있는 형식으로 설정 command.extend(['-o', output_dir]) try: result = subprocess.run(' '.join(command), shell=True, capture_output=True, text=True, check=True) print("PrusaSlicer output:", result.stdout) return True except subprocess.CalledProcessError as e: print("PrusaSlicer error:", e.stderr) return False # STL 파일 경로 및 출력 디렉토리 설정 stl_file = '/home/gds/printer/stl/A30_3D_Flexi_Dragon.stl' output_directory = '/home/gds/printer/gcode' start_gcode = """ M17 M862.1 P[nozzle_diameter] M862.3 P "MK4" M862.5 P2 M862.6 P "Input shaper" M115 U6.0.1+14848 M555 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} W{((min(print_bed_max[0], max(first_layer_print_min[0] + 32, first_layer_print_max[0])))) - ((min(print_bed_max[0], first_layer_print_min[0] + 32) - 32))} H{((first_layer_print_max[1])) - ((max(0, first_layer_print_min[1]) - 4))} G90 M83 M140 S[first_layer_bed_temperature] {if filament_notes[0]=~/.*HT_MBL10.*/} M104 T0 S{first_layer_temperature[0] - 10} M109 T0 R{first_layer_temperature[0] - 10} {endif} {if filament_type[0] == "PC" or filament_type[0] == "PA"} M104 T0 S{first_layer_temperature[0] - 25} M109 T0 R{first_layer_temperature[0] - 25} {endif} {if filament_type[0] == "FLEX"} M104 T0 S210 M109 T0 R210 {endif} {if filament_type[0]=~/.*PET.*/} M104 T0 S175 M109 T0 R175 {endif} {if not (filament_notes[0]=~/.*HT_MBL10.*/ or filament_type[0] == "PC" or filament_type[0] == "PA" or filament_type[0] == "FLEX" or filament_type[0]=~/.*PET.*/)} M104 T0 S170 M109 T0 R170 {endif} M84 E G28 G1 X{10 + 32} Y-4 Z5 F4800 M302 S160 {if filament_type[initial_tool]=="FLEX"} G1 E-4 F2400 {else} G1 E-2 F2400 {endif} M84 E G29 P9 X10 Y-4 W32 H4 {if first_layer_bed_temperature[initial_tool]<=60}M106 S100{endif} G0 Z40 F10000 M190 S[first_layer_bed_temperature] M107 M84 E G29 P1 G29 P1 X0 Y0 W50 H20 C G29 P3.2 G29 P3.13 G29 A M104 S{first_layer_temperature[0]} G0 X0 Y-4 Z15 F4800 M109 S{first_layer_temperature[0]} G92 E0 M569 S0 E G92 E0 G1 E{(filament_type[0] == "FLEX" ? 4 : 2)} F2400 G0 E7 X15 Z0.2 F500 G0 X25 E4 F500 G0 X35 E4 F650 G0 X45 E4 F800 G0 X{45 + 3} Z{0.05} F{8000} G0 X{45 + 3 * 2} Z0.2 F{8000} G92 E0 M221 S100 """ end_gcode = """ {if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+1, max_print_height)} F720{endif} M104 S0 M140 S0 M107 G1 X241 Y170 F3600 {if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+23, max_print_height)} F300{endif} G4 M572 S0 M593 X T2 F0 M593 Y T2 F0 M84 X Y E """ # PrusaSlicer 슬라이스 옵션 설정 options = { 'start-gcode': f"'{start_gcode}'", 'end-gcode': f"'{end_gcode}'", 'layer-height': '0.1', 'first-layer-height': '0.2', 'perimeters': '3', 'top-solid-layers': '8', 'bottom-solid-layers': '6', 'top-solid-min-thickness': '0.7', 'bottom-solid-min-thickness': '0.5', 'extra-perimeters': '', 'extra-perimeters-on-overhangs': '', 'avoid-crossing-perimeters': '', 'avoid-crossing-perimeters-max-detour': '1', 'thick-bridges': '', 'overhangs': '', 'seam-position': 'aligned', 'staggered-inner-seams': '', 'external-perimeters-first': '', 'gap-fill-enabled': '', 'perimeter-generator': 'arachne', 'fuzzy-skin': 'none', 'fuzzy-skin-thickness': '0.3', 'fuzzy-skin-point-dist': '0.8', 'fill-density': '15%', 'fill-pattern': 'grid', 'infill-anchor': '2', 'infill-anchor-max': '12', 'top-fill-pattern': 'monotoniclines', 'bottom-fill-pattern': 'monotoniclines', 'ironing': '', 'ironing-type': 'top', 'ironing-flowrate': '15', 'ironing-spacing': '0.1', 'infill-every-layers': '1', 'solid-infill-every-layers': '0', 'fill-angle': '45', 'solid-infill-below-area': '0', 'bridge-angle': '0', 'only-retract-when-crossing-perimeters': '', 'infill-first': '', 'skirts': '1', 'skirt-distance': '6', 'skirt-height': '1', 'draft-shield': 'limited', 'min-skirt-length': '4', 'brim-type': 'outer_only', 'brim-width': '0', 'brim-separation': '0.1', 'support-material': '', 'support-material-auto': '', 'support-material-threshold': '40', 'support-material-enforce-layers': '0', 'raft-first-layer-density': '80', 'raft-first-layer-expansion': '3.5', 'raft-layers': '0', 'raft-contact-distance': '0.15', 'raft-expansion': '1.5', 'support-material-style': 'snug', 'support-material-contact-distance': '0.17', 'support-material-bottom-contact-distance': '0.17', 'support-material-pattern': 'rectilinear', 'support-material-with-sheath': '', 'support-material-spacing': '2', 'support-material-angle': '0', 'support-material-closing-radius': '2', 'support-material-interface-layers': '5', 'support-material-bottom-interface-layers': '5', 'support-material-interface-pattern': 'auto', 'support-material-interface-spacing': '0.2', 'support-material-interface-contact-loops': '', 'support-material-buildplate-only': '', 'support-material-xy-spacing': '0.8', 'dont-support-bridges': '', 'support-material-synchronize-layers': '', 'support-tree-angle': '40', 'support-tree-angle-slow': '25', 'support-tree-branch-diameter': '2', 'support-tree-branch-diameter-angle': '5', 'support-tree-branch-diameter-double-wall': '3', 'support-tree-tip-diameter': '0.8', 'support-tree-branch-distance': '1', 'support-tree-top-rate': '30', 'perimeter-speed': '140', 'small-perimeter-speed': '140', 'external-perimeter-speed': '140', 'infill-speed': '140', 'solid-infill-speed': '200', 'top-solid-infill-speed': '100', 'support-material-speed': '120', 'support-material-interface-speed': '50', 'bridge-speed': '40', 'gap-fill-speed': '120', 'ironing-speed': '15', 'enable-dynamic-overhang-speeds': '', 'overhang-speed-0': '15', 'overhang-speed-1': '25', 'overhang-speed-2': '30', 'overhang-speed-3': '80', 'travel-speed': '300', 'travel-speed-z': '12', 'first-layer-speed': '40', 'first-layer-speed-over-raft': '150', 'external-perimeter-acceleration': '2000', 'perimeter-acceleration': '2500', 'top-solid-infill-acceleration': '1500', 'solid-infill-acceleration': '3500', 'infill-acceleration': '4000', 'bridge-acceleration': '3500', 'first-layer-acceleration': '500', 'wipe-tower-acceleration': '0', 'travel-acceleration': '4000', 'default-acceleration': '3000', 'max-print-speed': '200', 'max-volumetric-speed': '0', 'max-volumetric-extrusion-rate-slope-positive': '0', 'max-volumetric-extrusion-rate-slope-negative': '0', 'perimeter-extruder': '1', 'infill-extruder': '1', 'solid-infill-extruder': '1', 'support-material-extruder': '0', 'support-material-interface-extruder': '0', 'ooze-prevention': '', 'standby-temperature-delta': '-5', 'wipe-tower-x': '180', 'wipe-tower-y': '140', 'wipe-tower-width': '60', 'wipe-tower-rotation-angle': '0', 'wipe-tower-brim-width': '2', 'wipe-tower-bridging': '10', 'wipe-tower-cone-angle': '25', 'wipe-tower-extra-spacing': '110', 'wipe-tower-extra-flow': '250', 'wipe-tower-no-sparse-layers': '', 'interface-shells': '', 'mmu-segmented-region-max-width': '0', 'mmu-segmented-region-interlocking-depth': '0', 'extrusion-width': '0.45', 'first-layer-extrusion-width': '0.5', 'perimeter-extrusion-width': '0.45', 'external-perimeter-extrusion-width': '0.45', 'infill-extrusion-width': '0.45', 'solid-infill-extrusion-width': '0.45', 'top-infill-extrusion-width': '0.4', 'support-material-extrusion-width': '0.39', 'infill-overlap': '0.15', 'bridge-flow-ratio': '1', 'slice-closing-radius': '0.049', 'slicing-mode': 'regular', 'resolution': '0', 'gcode-resolution': '0.008', 'arc-fitting': 'emit_center', 'xy-size-compensation': '0', 'elefant-foot-compensation': '0.2', 'wall-transition-angle': '10', 'wall-transition-filter-deviation': '25%', 'wall-transition-length': '100%', 'wall-distribution-count': '1', 'min-bead-width': '85%', 'min-feature-size': '25%', 'filament-colour': '"#29B2B2"', 'filament-diameter': '1.75', 'extrusion-multiplier': '1', 'filament-density': '1.24', 'filament-cost': '25.4', 'filament-spool-weight': '0', 'idle-temperature': '70', 'first-layer-temperature': '230', 'temperature': '220', 'first-layer-bed-temperature': '60', 'bed-temperature': '60', 'fan-always-on': '', 'cooling': '', 'min-fan-speed': '100', 'max-fan-speed': '100', 'bridge-fan-speed': '100', 'disable-fan-first-layers': '1', 'full-fan-speed-layer': '0', 'enable-dynamic-fan-speeds': '', 'overhang-fan-speed-0': '0', 'overhang-fan-speed-1': '0', 'overhang-fan-speed-2': '0', 'overhang-fan-speed-3': '0', 'fan-below-layer-time': '100', 'slowdown-below-layer-time': '8', 'min-print-speed': '15', 'filament-max-volumetric-speed': '15', 'filament-minimal-purge-on-wipe-tower': '15', 'filament-loading-speed-start': '50', 'filament-loading-speed': '10', 'filament-unloading-speed-start': '100', 'filament-unloading-speed': '100', 'filament-load-time': '10.5', 'filament-unload-time': '8.5', 'filament-toolchange-delay': '0', 'filament-cooling-moves': '2', 'filament-cooling-initial-speed': '10', 'filament-cooling-final-speed': '3.5', 'filament-stamping-loading-speed': '29', 'filament-stamping-distance': '45', 'filament-purge-multiplier': '81.25', 'filament-multitool-ramming': '', 'filament-multitool-ramming-volume': '10', 'filament-multitool-ramming-flow': '10', } # STL 파일 슬라이스 실행 success = slice_stl(stl_file, output_directory,options=options) if success: print("STL 파일을 성공적으로 슬라이스했습니다.") else: print("STL 파일 슬라이스 중 오류가 발생했습니다.")