up
This commit is contained in:
parent
fdf49ef611
commit
6def135bbc
2 changed files with 56 additions and 14 deletions
|
|
@ -963,9 +963,11 @@ class SLICENODE_GcodeToFile(ExecSliceNode):
|
||||||
|
|
||||||
def evaluate(self, operator=None):
|
def evaluate(self, operator=None):
|
||||||
from ...infra.networking.bgcode import convert_to_bgcode
|
from ...infra.networking.bgcode import convert_to_bgcode
|
||||||
|
from ...infra.networking.gcode_utils import get_gcode_name_from_metadata
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
gcodes: str = self.resolve_multi_input('Gcode')
|
gcodes: list[str] = [gc for gc in self.resolve_multi_input('Gcode') if gc]
|
||||||
|
|
||||||
folder: str = resolve_input(self.inputs.get("Folder"))
|
folder: str = resolve_input(self.inputs.get("Folder"))
|
||||||
if not gcodes:
|
if not gcodes:
|
||||||
|
|
@ -976,18 +978,7 @@ class SLICENODE_GcodeToFile(ExecSliceNode):
|
||||||
return 'error'
|
return 'error'
|
||||||
|
|
||||||
for i, gc in enumerate(gcodes):
|
for i, gc in enumerate(gcodes):
|
||||||
|
name = get_gcode_name_from_metadata(gc, default=f'object_{i}')
|
||||||
import re, json
|
|
||||||
parts_match = re.search(r"; objects_info = (.*)", gc)
|
|
||||||
name: str = ""
|
|
||||||
if parts_match:
|
|
||||||
gcode_info = json.loads(parts_match.group(1))
|
|
||||||
names: list[str] = [str(v['name']) for v in gcode_info['objects']]
|
|
||||||
from collections import Counter
|
|
||||||
counts = Counter(names)
|
|
||||||
name = "-".join(f"{c}x{n}" if c > 1 else n for n, c in counts.items())
|
|
||||||
else:
|
|
||||||
name = 'object_'+str(i)
|
|
||||||
|
|
||||||
# User's requested logic: .split('.')[0]
|
# User's requested logic: .split('.')[0]
|
||||||
folder_path = Path(bpy.path.abspath(f"//{folder}"))
|
folder_path = Path(bpy.path.abspath(f"//{folder}"))
|
||||||
|
|
@ -1012,11 +1003,12 @@ class SLICENODE_GcodeToFile(ExecSliceNode):
|
||||||
with open(filepath, "w", encoding="utf-8", newline="\n") as f:
|
with open(filepath, "w", encoding="utf-8", newline="\n") as f:
|
||||||
f.write(gc)
|
f.write(gc)
|
||||||
if operator: operator.report({'INFO'}, f"G-code saved to {filepath}")
|
if operator: operator.report({'INFO'}, f"G-code saved to {filepath}")
|
||||||
return 'ok'
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if operator: operator.report({'ERROR'}, str(e))
|
if operator: operator.report({'ERROR'}, str(e))
|
||||||
return 'error'
|
return 'error'
|
||||||
|
|
||||||
|
return 'ok'
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_GcodeToTextBlock(ExecSliceNode):
|
class SLICENODE_GcodeToTextBlock(ExecSliceNode):
|
||||||
bl_label = "Gcode to Text Block"
|
bl_label = "Gcode to Text Block"
|
||||||
|
|
|
||||||
50
infra/networking/gcode_utils.py
Normal file
50
infra/networking/gcode_utils.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
from collections import Counter
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
def parse_gcode_metadata(gcode: str) -> dict[str, Any]:
|
||||||
|
"""Extracts metadata fields from G-code comments."""
|
||||||
|
fields = {}
|
||||||
|
|
||||||
|
# 1. Time per print (decimal hours)
|
||||||
|
time_match = re.search(r"; estimated printing time \(normal mode\) = (.*)", gcode)
|
||||||
|
if time_match:
|
||||||
|
time_str = time_match.group(1)
|
||||||
|
h = re.search(r"(\d+)h", time_str)
|
||||||
|
m = re.search(r"(\d+)m", time_str)
|
||||||
|
s = re.search(r"(\d+)s", time_str)
|
||||||
|
total_hours = 0.0
|
||||||
|
if h: total_hours += float(h.group(1))
|
||||||
|
if m: total_hours += float(m.group(1)) / 60.0
|
||||||
|
if s: total_hours += float(s.group(1)) / 3600.0
|
||||||
|
fields["Time per print"] = round(total_hours, 2)
|
||||||
|
|
||||||
|
# 2. Parts per print
|
||||||
|
parts_match = re.search(r"; objects_info = (.*)", gcode)
|
||||||
|
if parts_match:
|
||||||
|
try:
|
||||||
|
info = json.loads(parts_match.group(1))
|
||||||
|
fields["Parts per print"] = len(info.get("objects", []))
|
||||||
|
fields["objects_info"] = info
|
||||||
|
except Exception: pass
|
||||||
|
|
||||||
|
# 3. Weight per print
|
||||||
|
weight_match = re.search(r"; total filament used \[g\] = ([\d\.]+)", gcode)
|
||||||
|
if weight_match:
|
||||||
|
fields["Weight per print"] = int(float(weight_match.group(1)))
|
||||||
|
|
||||||
|
return fields
|
||||||
|
|
||||||
|
def get_gcode_name_from_metadata(gcode: str, default: str = "output") -> str:
|
||||||
|
"""Generates a descriptive name for the G-code based on its objects_info metadata."""
|
||||||
|
parts_match = re.search(r"; objects_info = (.*)", gcode)
|
||||||
|
if parts_match:
|
||||||
|
try:
|
||||||
|
gcode_info = json.loads(parts_match.group(1))
|
||||||
|
names: list[str] = [str(v['name']) for v in gcode_info['objects']]
|
||||||
|
counts = Counter(names)
|
||||||
|
return "-".join(f"{c}x{n}" if c > 1 else n for n, c in counts.items())
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return default
|
||||||
Loading…
Add table
Reference in a new issue