nodeslicer/infra/prusaslicer_profiles/profiles.py

55 lines
No EOL
2.7 KiB
Python

from pathlib import Path
from typing import Any
from .expression_parser import Parser, ExprNode
class Profile():
def __init__(self, key: str, category: str, path: Path, has_header: bool, conf_dict: dict[str, Any]):
self.id: str = key.split(':')[1] if len(key.split(':')) > 1 else key
self.key: str = key
self.category: str = category
self.vendor: str = ''
self.path: Path = path
self.has_header: bool = has_header
self.conf_dict: dict[str, Any] = conf_dict
self.all_conf_dict: dict[str, Any] = {}
self.compatible_profiles: list[str] = []
self.compatibility_expression: ExprNode | None = None
def evaluate_compatibility(self, compats: dict[str, ExprNode | None]):
self.compatible_profiles = []
if self.category.startswith('printer:'): return
for key, compat in compats.items():
if not compat: self.compatible_profiles.append(key); continue
if compat.eval(self.all_conf_dict): self.compatible_profiles.append(key)
pass
print(f'Evaled {self.id}')
def generate_inherited_confs(self, all_confs_dict: dict[str, Any] = {}):
self.all_conf_dict = generate_conf(all_confs_dict, self.key)
if self.category == 'printer': self.all_conf_dict['num_extruders'] = str(len(self.all_conf_dict['nozzle_diameter'].split(',')))
self.vendor = self.all_conf_dict.get('filament_vendor', '')
if exp := self.all_conf_dict.get('compatible_printers_condition'):
try:
self.compatibility_expression = Parser(exp).parse()
except:
print(f'Expression parsing failed: {exp}')
def generate_conf(profiles: dict[str, Any], id: str) -> dict[str, str]:
if not (profile := profiles.get(id)): return {}
if not profile.conf_dict: return {}
conf_current = profiles[id].conf_dict # Copy to avoid modifying the original config
if conf_current.get('inherits', False):
curr_category = id.split(":")[0]
inherited_ids = [curr_category + ":" + inherit_id.strip() for inherit_id in conf_current['inherits'].split(';')] # Split on semicolon for multiple inheritance
merged_conf = {}
for inherit_id in inherited_ids:
if inherit_id in profiles:
inherited_conf = generate_conf(profiles, inherit_id) # Recursive call for each inherited config
merged_conf.update(inherited_conf) # Merge each inherited config
merged_conf.update(conf_current) # Update with current config values (overriding inherited)
conf_current = merged_conf
conf_current.pop('inherits', None)
conf_current.pop('renamed_from', None)
return conf_current