Prusaslicerconf node
This commit is contained in:
parent
4bfc351189
commit
d49f89ec43
5 changed files with 135 additions and 15 deletions
|
|
@ -61,6 +61,118 @@ class SLICENODE_InputObject(InputNode):
|
||||||
input_type = "Object"
|
input_type = "Object"
|
||||||
bl_icon = "OBJECT_DATA"
|
bl_icon = "OBJECT_DATA"
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICENODE_PrusaslicerConf(SliceNode):
|
||||||
|
bl_label = "PrusaSlicer Config"
|
||||||
|
bl_icon = "PROPERTIES"
|
||||||
|
|
||||||
|
_cache = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cache(cls):
|
||||||
|
if cls._cache is None:
|
||||||
|
from ...infra.prusaslicer_profiles import LocalCache
|
||||||
|
cls._cache = LocalCache()
|
||||||
|
return cls._cache
|
||||||
|
|
||||||
|
def update_profiles(self, context):
|
||||||
|
cache = self.get_cache()
|
||||||
|
if not cache.profiles and self.config_path:
|
||||||
|
abs_path = bpy.path.abspath(self.config_path)
|
||||||
|
if os.path.isdir(abs_path):
|
||||||
|
cache.load([abs_path])
|
||||||
|
|
||||||
|
if self.printer_enum != 'NONE':
|
||||||
|
cache.evaluate_compatibility({self.printer_enum}, set(cache.vendors))
|
||||||
|
|
||||||
|
def get_printers(self, context):
|
||||||
|
cache = self.get_cache()
|
||||||
|
items = [('NONE', "None", "No printer selected")]
|
||||||
|
for k, p in cache.printer_profiles.items():
|
||||||
|
items.append((k, p.id, p.path.name))
|
||||||
|
return items
|
||||||
|
|
||||||
|
def get_filaments(self, context):
|
||||||
|
cache = self.get_cache()
|
||||||
|
items = [('NONE', "None", "No filament selected")]
|
||||||
|
|
||||||
|
printer_id = self.printer_enum
|
||||||
|
if printer_id == 'NONE':
|
||||||
|
return items
|
||||||
|
|
||||||
|
printer = cache.printer_profiles.get(printer_id)
|
||||||
|
if not printer:
|
||||||
|
return items
|
||||||
|
|
||||||
|
for k in printer.compatible_profiles:
|
||||||
|
if k.startswith("filament:"):
|
||||||
|
p = cache.profiles[k]
|
||||||
|
items.append((k, p.id, p.path.name))
|
||||||
|
return items
|
||||||
|
|
||||||
|
def get_prints(self, context):
|
||||||
|
cache = self.get_cache()
|
||||||
|
items = [('NONE', "None", "No print selected")]
|
||||||
|
|
||||||
|
printer_id = self.printer_enum
|
||||||
|
if printer_id == 'NONE':
|
||||||
|
return items
|
||||||
|
|
||||||
|
printer = cache.printer_profiles.get(printer_id)
|
||||||
|
if not printer:
|
||||||
|
return items
|
||||||
|
|
||||||
|
for k in printer.compatible_profiles:
|
||||||
|
if k.startswith("print:"):
|
||||||
|
p = cache.profiles[k]
|
||||||
|
items.append((k, p.id, p.path.name))
|
||||||
|
return items
|
||||||
|
|
||||||
|
config_path: StringProperty(
|
||||||
|
name="Profiles",
|
||||||
|
subtype='DIR_PATH',
|
||||||
|
update=update_profiles
|
||||||
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
|
printer_enum: EnumProperty(
|
||||||
|
name="Printer",
|
||||||
|
items=get_printers,
|
||||||
|
update=update_profiles
|
||||||
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
|
filament_enum: EnumProperty(
|
||||||
|
name="Filament",
|
||||||
|
items=get_filaments
|
||||||
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
|
print_enum: EnumProperty(
|
||||||
|
name="Print",
|
||||||
|
items=get_prints
|
||||||
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
|
def init(self, context):
|
||||||
|
self.add_output("SLICESOCK_PrusaslicerConf", "Config")
|
||||||
|
|
||||||
|
def draw_buttons(self, context, layout):
|
||||||
|
assert layout
|
||||||
|
layout.prop(self, "config_path")
|
||||||
|
layout.prop(self, "printer_enum")
|
||||||
|
if self.printer_enum != 'NONE':
|
||||||
|
layout.prop(self, "filament_enum")
|
||||||
|
layout.prop(self, "print_enum")
|
||||||
|
|
||||||
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
||||||
|
if self.printer_enum == 'NONE' or self.filament_enum == 'NONE' or self.print_enum == 'NONE':
|
||||||
|
return None
|
||||||
|
|
||||||
|
cache = self.get_cache()
|
||||||
|
return {
|
||||||
|
'printer': self.printer_enum,
|
||||||
|
'filament': [self.filament_enum],
|
||||||
|
'print': self.print_enum,
|
||||||
|
'cache': cache
|
||||||
|
}
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputPrinter(SliceNode):
|
class SLICENODE_InputPrinter(SliceNode):
|
||||||
bl_label = "Printer"
|
bl_label = "Printer"
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,14 @@ class SLICESOCK_Object(InputNodeSocket):
|
||||||
name="Object",
|
name="Object",
|
||||||
type=bpy.types.Object,
|
type=bpy.types.Object,
|
||||||
) # pyright: ignore[reportInvalidTypeForm]
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
color = (0.9, 0.7, 0.2, 1.0)
|
bl_color = (0.9, 0.7, 0.2, 1.0)
|
||||||
|
|
||||||
|
|
||||||
class SLICESOCK_Float_Common(InputNodeSocket):
|
class SLICESOCK_Float_Common(InputNodeSocket):
|
||||||
bl_label = "Float"
|
bl_label = "Float"
|
||||||
|
|
||||||
value: FloatProperty(name="Float", default=0) # pyright: ignore[reportInvalidTypeForm]
|
value: FloatProperty(name="Float", default=0) # pyright: ignore[reportInvalidTypeForm]
|
||||||
color = (161/255, 161/255, 161/255, 1.0)
|
bl_color = (161/255, 161/255, 161/255, 1.0)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_FloatRo(ReadonlySocket, SLICESOCK_Float_Common): ...
|
class SLICESOCK_FloatRo(ReadonlySocket, SLICESOCK_Float_Common): ...
|
||||||
|
|
@ -58,7 +58,7 @@ class SLICESOCK_Int_Common(InputNodeSocket):
|
||||||
bl_label = "Integer"
|
bl_label = "Integer"
|
||||||
|
|
||||||
value: IntProperty(name="Int", default=0) # pyright: ignore[reportInvalidTypeForm]
|
value: IntProperty(name="Int", default=0) # pyright: ignore[reportInvalidTypeForm]
|
||||||
color = (161/255, 161/255, 161/255, 1.0)
|
bl_color = (161/255, 161/255, 161/255, 1.0)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_Int(SLICESOCK_Int_Common): ...
|
class SLICESOCK_Int(SLICESOCK_Int_Common): ...
|
||||||
|
|
@ -71,21 +71,21 @@ class SLICESOCK_String(InputNodeSocket):
|
||||||
bl_label = "String"
|
bl_label = "String"
|
||||||
|
|
||||||
value: StringProperty(name="String", default="") # pyright: ignore[reportInvalidTypeForm]
|
value: StringProperty(name="String", default="") # pyright: ignore[reportInvalidTypeForm]
|
||||||
color = (0.4, 0.7, 1.0, 1.0)
|
bl_color = (0.4, 0.7, 1.0, 1.0)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_FilePath(InputNodeSocket):
|
class SLICESOCK_FilePath(InputNodeSocket):
|
||||||
bl_label = "Filepath"
|
bl_label = "Filepath"
|
||||||
|
|
||||||
value: StringProperty(name="Filepath", default="", subtype='FILE_PATH') # pyright: ignore[reportInvalidTypeForm]
|
value: StringProperty(name="Filepath", default="", subtype='FILE_PATH') # pyright: ignore[reportInvalidTypeForm]
|
||||||
color = (0.4, 0.7, 1.0, 1.0)
|
bl_color = (0.4, 0.7, 1.0, 1.0)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_VectorRotation_Common(InputNodeSocket):
|
class SLICESOCK_VectorRotation_Common(InputNodeSocket):
|
||||||
bl_label = "VectorRotation"
|
bl_label = "VectorRotation"
|
||||||
|
|
||||||
value: bpy.props.FloatVectorProperty(name="Vector", size=3, default=(0.0, 0.0, 0.0), subtype='EULER') # pyright: ignore[reportInvalidTypeForm]
|
value: bpy.props.FloatVectorProperty(name="Vector", size=3, default=(0.0, 0.0, 0.0), subtype='EULER') # pyright: ignore[reportInvalidTypeForm]
|
||||||
color = (0.39, 0.39, 0.78, 1.0)
|
bl_color = (0.39, 0.39, 0.78, 1.0)
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_VectorRotation(SLICESOCK_VectorRotation_Common): ...
|
class SLICESOCK_VectorRotation(SLICESOCK_VectorRotation_Common): ...
|
||||||
@register_class
|
@register_class
|
||||||
|
|
@ -95,31 +95,37 @@ class SLICESOCK_VectorRotationRo(ReadonlySocket, SLICESOCK_VectorRotation_Common
|
||||||
class SLICESOCK_Mesh(LabelNodeSocket):
|
class SLICESOCK_Mesh(LabelNodeSocket):
|
||||||
bl_label = "Mesh"
|
bl_label = "Mesh"
|
||||||
default = None
|
default = None
|
||||||
color = (0, 214/255, 163/255, 1.0)
|
bl_color = (0, 214/255, 163/255, 1.0)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_Paths(LabelNodeSocket):
|
class SLICESOCK_Paths(LabelNodeSocket):
|
||||||
bl_label = "Paths"
|
bl_label = "Paths"
|
||||||
default = SlicePaths()
|
default = SlicePaths()
|
||||||
color = (214/255, 0, 120/255, 1.0)
|
bl_color = (214/255, 0, 120/255, 1.0)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_Gcode(LabelNodeSocket):
|
class SLICESOCK_Gcode(LabelNodeSocket):
|
||||||
bl_label = "Gcode"
|
bl_label = "Gcode"
|
||||||
default = ""
|
default = ""
|
||||||
color = (1., 1., 1., 1.)
|
bl_color = (1., 1., 1., 1.)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_Intrinsics(LabelNodeSocket):
|
class SLICESOCK_Intrinsics(LabelNodeSocket):
|
||||||
bl_label = "Intrinsics"
|
bl_label = "Intrinsics"
|
||||||
default = None
|
default = None
|
||||||
color = (0.2, 0.2, 0.2, 1.0)
|
bl_color = (0.2, 0.2, 0.2, 1.0)
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_PrusaslicerConf(LabelNodeSocket):
|
||||||
|
bl_label = "PrusaSlicer Config"
|
||||||
|
default = None
|
||||||
|
bl_color = (0.95, 0.42, 0.13, 1.0) # #F26C21
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_ExecutionLink(LabelNodeSocket):
|
class SLICESOCK_ExecutionLink(LabelNodeSocket):
|
||||||
bl_label = "Execution Link"
|
bl_label = "Execution Link"
|
||||||
default = None
|
default = None
|
||||||
color = (0.5, 0.0, 0.5, 1.0) # Purple
|
bl_color = (0.5, 0.0, 0.5, 1.0) # Purple
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_Printer(InputNodeSocket):
|
class SLICESOCK_Printer(InputNodeSocket):
|
||||||
|
|
@ -142,7 +148,7 @@ class SLICESOCK_Printer(InputNodeSocket):
|
||||||
default='PRUSALINK'
|
default='PRUSALINK'
|
||||||
) # pyright: ignore[reportInvalidTypeForm]
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
color = (1.0, 0.45, 0.1, 1.0) # Orange
|
bl_color = (1.0, 0.45, 0.1, 1.0) # Orange
|
||||||
|
|
||||||
def draw(self, context, layout, node, text):
|
def draw(self, context, layout, node, text):
|
||||||
if self.is_output or self.is_linked:
|
if self.is_output or self.is_linked:
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ class SLICENODE_MT_Menu(Menu):
|
||||||
layout.operator("node.add_node", text="Integer Math").type = "SLICENODE_IntMath"
|
layout.operator("node.add_node", text="Integer Math").type = "SLICENODE_IntMath"
|
||||||
layout.operator("node.add_node", text="Object").type = "SLICENODE_InputObject"
|
layout.operator("node.add_node", text="Object").type = "SLICENODE_InputObject"
|
||||||
layout.operator("node.add_node", text="Printer").type = "SLICENODE_InputPrinter"
|
layout.operator("node.add_node", text="Printer").type = "SLICENODE_InputPrinter"
|
||||||
|
layout.operator("node.add_node", text="PrusaSlicer Config").type = "SLICENODE_PrusaslicerConf"
|
||||||
layout.operator("node.add_node", text="Printer List").type = "SLICENODE_PrinterList"
|
layout.operator("node.add_node", text="Printer List").type = "SLICENODE_PrinterList"
|
||||||
layout.operator("node.add_node", text="Printer Intrinsics").type = "SLICENODE_InputIntrinsics"
|
layout.operator("node.add_node", text="Printer Intrinsics").type = "SLICENODE_InputIntrinsics"
|
||||||
layout.operator("node.add_node", text="Test").type = "SLICENODE_Test"
|
layout.operator("node.add_node", text="Test").type = "SLICENODE_Test"
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,10 @@ class AutoBlIdName:
|
||||||
|
|
||||||
class SliceNodeSocket(NodeSocket, AutoBlIdName):
|
class SliceNodeSocket(NodeSocket, AutoBlIdName):
|
||||||
default: Any = None
|
default: Any = None
|
||||||
color = (1., 1., 1., 1.)
|
bl_color = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
def draw_color(self, context, node) -> tuple[float, float, float, float]: return self.color # pyright: ignore[reportIncompatibleMethodOverride]
|
def draw_color(self, context, node) -> tuple[float, float, float, float]: # pyright: ignore[reportIncompatibleMethodOverride]
|
||||||
|
return self.bl_color
|
||||||
|
|
||||||
class SliceNode(Node, AutoBlIdName):
|
class SliceNode(Node, AutoBlIdName):
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any: ...
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any: ...
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class ConfigWriter:
|
||||||
for key, val in dict(sorted(self.config_dict.items())).items():
|
for key, val in dict(sorted(self.config_dict.items())).items():
|
||||||
file.write(f"; {key} = {val}\n")
|
file.write(f"; {key} = {val}\n")
|
||||||
|
|
||||||
def get(self, key: str, default: Any = None) -> str | list[str]:
|
def get(self, key: str, default: str = "") -> str | list[str]:
|
||||||
return self.config_dict.get(key, default)
|
return self.config_dict.get(key, default)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue