import openpyxl from openpyxl import Workbook from openpyxl.styles import Alignment, PatternFill import os import sys # Get the directory of the current Python script script_directory = os.path.dirname(os.path.abspath(__file__)) # Define the path for the Excel file in the same directory as the script output_excel_file = os.path.join(script_directory, "extracted_settings.xlsx") # Check if G-code file is provided as a command-line argument if len(sys.argv) > 1: input_gcode_file = sys.argv[1] else: print("Error: No G-code file provided.") sys.exit(1) # List of important settings with more descriptive categories settings_keywords = { "フィラメントの種類": ["filament_type"], "ノズル温度": ["temperature"], "ベッド温度": ["bed_temperature"], "射出率": ["extrusion_multiplier"], "積層ピッチ": ["layer_height"], "最初のレイヤー高さ": ["first_layer_height"], "境界線": ["perimeters"], "上部ソリッドレイヤー数": ["top_solid_layers"], "下部ソリッドレイヤー数": ["bottom_solid_layers"], "オーバーハングのしきい値": ["support_material_threshold"], "サポートスタイル": ["support_material_style"], "トップコンタクトZ距離": ["support_material_contact_distance"], "ボトムコンタクトZ距離": ["support_material_bottom_contact_distance"], "サポートパターン": ["support_material_pattern"], "パターンの間隔": ["support_material_spacing"], "パターン角度": ["support_material_angle"], "トップインターフェースレイヤー数": ["support_material_interface_layers"], "ボトムインターフェースレイヤー数": ["support_material_interface_layers"], "インターフェースパターン": ["support_material_interface_pattern"], "XY面でのサポートとモデルの隙間": ["support_material_xy_spacing"], "境界線速度": ["perimeter_speed"], "短い境界線速度": ["small_perimeter_speed"], "最外周速度": ["external_perimeter_speed"], "インフィル速度": ["infill_speed"], "ソリッドインフィル速度": ["solid_infill_speed"], "トップソリッドインフィル速度": ["top_solid_infill_speed"], "サポート速度": ["support_material_speed"], "サポートインターフェース速度": ["support_material_interface_speed"], "ブリッジ速度": ["bridge_speed"], "ギャップフィル速度": ["gap_fill_speed"], "移動速度": ["travel_speed"], "Z移動速度": ["travel_speed_z"], "1番目のレイヤー速度": ["first_layer_speed"], "デフォルト射出幅": ["extrusion_width"], "最初のレイヤー押出幅": ["first_layer_extrusion_width"], "境界線押出幅": ["perimeter_extrusion_width"], "最外周押出幅": ["external_perimeter_extrusion_width"], "インフィル押出幅": ["infill_extrusion_width"], "ソリッドインフィル押出幅": ["solid_infill_extrusion_width"], "トップソリッドインフィル押出幅": ["top_infill_extrusion_width"], "サポート材押出幅": ["support_material_extrusion_width"], "充填/外周オーバーラップ": ["infill_overlap"], "リトラクト高さ": ["filament_retract_lift"], "リトラクトの長さ": ["filament_retract_length"], "引き込み速度": ["filament_retract_speed"], "退避からの復帰速度": ["filament_deretract_speed"] } # Function to extract settings from G-code def extract_settings(input_file, keywords): settings = {category: {key: "-" for key in keys} for category, keys in keywords.items()} # Open the G-code file with UTF-8 encoding to avoid decode errors with open(input_file, "r", encoding="utf-8") as f: for line in f: # Check if the line is a comment containing a setting if line.startswith(";"): for category, keys in keywords.items(): for key in keys: if f"; {key} = " in line: # Extract the setting value setting_value = line.split("=")[-1].strip() settings[category][key] = setting_value return settings # Function to add settings to an Excel file in vertical format def add_settings_to_excel(output_file, settings): # Check if the file exists if os.path.exists(output_file): workbook = openpyxl.load_workbook(output_file) sheet = workbook.active else: workbook = Workbook() sheet = workbook.active sheet.title = "Print Settings" # Write headers sheet["A1"] = "Category" sheet["B1"] = "Setting" sheet["C1"] = "Value" # Center align all cells in columns A and the rest for row in sheet.iter_rows(min_row=1, max_row=sheet.max_row): for cell in row: cell.alignment = Alignment(horizontal="center", vertical="center") # Find the next available column for new data next_col = sheet.max_column + 1 # Write settings by category in vertical format row_mapping = {} for row in range(2, sheet.max_row + 1): category = sheet[f"A{row}"].value setting_name = sheet[f"B{row}"].value if category and setting_name: row_mapping[(category, setting_name)] = row for category, items in settings.items(): for setting_name, value in items.items(): # Check if the category and setting are already present in the sheet if (category, setting_name) in row_mapping: row = row_mapping[(category, setting_name)] else: # If not present, add the category and setting in a new row row = sheet.max_row + 1 sheet[f"A{row}"] = category sheet[f"B{row}"] = setting_name row_mapping[(category, setting_name)] = row # Write the setting value in the next available column sheet.cell(row=row, column=next_col, value=value) # Apply light green background if the value is different from the previous column if next_col > 3: # Skip if this is the first column of values prev_col_letter = openpyxl.utils.get_column_letter(next_col - 1) prev_value = sheet[f"{prev_col_letter}{row}"].value if prev_value != value: sheet.cell(row=row, column=next_col).fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid") # Auto-adjust column width of columns A and B based on max length of content, capped at 35 for column A max_length_a = max(len(str(cell.value)) for cell in sheet["A"] if cell.value) if sheet["A"] else 10 sheet.column_dimensions["A"].width = min(max_length_a + 2, 35) # Add padding, max width 35 max_length_b = max(len(str(cell.value)) for cell in sheet["B"] if cell.value) if sheet["B"] else 10 sheet.column_dimensions["B"].width = max_length_b + 2 # Add padding # Auto-adjust width of new column max_length = max(len(str(cell.value)) for cell in sheet[openpyxl.utils.get_column_letter(next_col)] if cell.value) sheet.column_dimensions[openpyxl.utils.get_column_letter(next_col)].width = max_length + 2 # Save the Excel file workbook.save(output_file) print(f"Settings added to {output_file}") # Main execution settings = extract_settings(input_gcode_file, settings_keywords) add_settings_to_excel(output_excel_file, settings)