有3d gcode预览,基本能按要求切片,但是缩放后切片会失败
This commit is contained in:
159
app/tasks.py
159
app/tasks.py
@@ -2,10 +2,14 @@ from huey import SqliteHuey
|
||||
import subprocess
|
||||
import os
|
||||
from .models import db, PrintFile, SystemConfig
|
||||
from .conf_parse import ConfParse
|
||||
import json
|
||||
import uuid
|
||||
import configparser
|
||||
|
||||
|
||||
huey = SqliteHuey(filename='huey_queue.db')
|
||||
|
||||
import configparser
|
||||
|
||||
@huey.task()
|
||||
def slice_stl_task(file_id, stl_filepath, quality_preset=None, infill_density=None, support_enable=None, support_pattern=None, delete_stl=False):
|
||||
@@ -26,6 +30,8 @@ def slice_stl_task(file_id, stl_filepath, quality_preset=None, infill_density=No
|
||||
|
||||
# Remove DB session to avoid locking the sqlite db during long slicing operations
|
||||
db.session.remove()
|
||||
|
||||
tmp_def_path = None
|
||||
|
||||
try:
|
||||
# Create Cura engine options
|
||||
@@ -34,48 +40,142 @@ def slice_stl_task(file_id, stl_filepath, quality_preset=None, infill_density=No
|
||||
printers_path = os.path.join(print_config_path, 'printers')
|
||||
extruders_path = os.path.join(print_config_path, 'extruders')
|
||||
materials_path = os.path.join(print_config_path, 'materials')
|
||||
presets_path = os.path.join(print_config_path, 'presets')
|
||||
env = os.environ.copy()
|
||||
env["CURA_ENGINE_SEARCH_PATH"] = f"{printers_path}:{extruders_path}:{materials_path}:{presets_path}"
|
||||
presets_path = os.path.join(print_config_path, 'quality')
|
||||
variants_path = os.path.join(print_config_path, 'variants')
|
||||
|
||||
command = [
|
||||
"CuraEngine", "slice",
|
||||
"-j", os.path.join(printers_path, "creality_ender3v3se.def.json")
|
||||
env = os.environ.copy()
|
||||
env["CURA_ENGINE_SEARCH_PATH"] = f"{printers_path}:{extruders_path}:{materials_path}:{presets_path}:{variants_path}"
|
||||
|
||||
def_files = [
|
||||
os.path.join(printers_path, "fdmprinter.def.json"),
|
||||
os.path.join(printers_path, "fdmextruder.def.json"),
|
||||
os.path.join(printers_path, "creality_base.def.json"),
|
||||
os.path.join(printers_path, "creality_ender3v3se.def.json")
|
||||
]
|
||||
|
||||
# Apply quality presets if any
|
||||
inst_files_list = []
|
||||
|
||||
if quality_preset:
|
||||
config = configparser.ConfigParser()
|
||||
preset_path = os.path.join(presets_path, 'creality', 'base', quality_preset)
|
||||
preset_path = os.path.join(presets_path, 'creality', 'presets', quality_preset)
|
||||
if os.path.exists(preset_path):
|
||||
config.read(preset_path)
|
||||
if config.has_section('values'):
|
||||
for key, val in config.items('values'):
|
||||
command.extend(['-s', f"{key}={val}"])
|
||||
|
||||
material_type = config.get('metadata', 'material', fallback=None)
|
||||
variant_type = config.get('metadata', 'variant', fallback=None)
|
||||
quality_type = config.get('metadata', 'quality_type', fallback=None)
|
||||
|
||||
if material_type:
|
||||
m_path = os.path.join(materials_path, f"{material_type}.inst.cfg")
|
||||
if os.path.exists(m_path): inst_files_list.append(m_path)
|
||||
if variant_type:
|
||||
variant_d = variant_type.split("mm")[0]
|
||||
v_path = os.path.join(variants_path, "creality", f"creality_ender3v3se_{variant_d}.inst.cfg")
|
||||
if os.path.exists(v_path): inst_files_list.append(v_path)
|
||||
|
||||
if support_pattern == 'tree':
|
||||
t_path = os.path.join(print_config_path, 'supports', 'tree.inst.cfg')
|
||||
if os.path.exists(t_path): inst_files_list.append(t_path)
|
||||
elif support_pattern and support_pattern != 'false':
|
||||
n_path = os.path.join(print_config_path, 'supports', 'normal.inst.cfg')
|
||||
if os.path.exists(n_path): inst_files_list.append(n_path)
|
||||
|
||||
if quality_preset and quality_type:
|
||||
g_path = os.path.join(presets_path, 'creality', 'globals', f"{quality_type}.inst.cfg")
|
||||
if os.path.exists(g_path): inst_files_list.append(g_path)
|
||||
|
||||
if quality_preset and os.path.exists(preset_path):
|
||||
inst_files_list.append(preset_path)
|
||||
|
||||
|
||||
p = ConfParse(def_files)
|
||||
settings_with_inst = p.add_inst_cfg(inst_files_list)
|
||||
|
||||
if infill_density is not None:
|
||||
command.extend(['-s', f"infill_sparse_density={infill_density}"])
|
||||
command.extend(['-s', f"infill_line_distance={100 / int(infill_density) if int(infill_density) > 0 else 9999}"])
|
||||
if "infill_sparse_density" not in settings_with_inst: settings_with_inst["infill_sparse_density"] = {}
|
||||
settings_with_inst["infill_sparse_density"]["value"] = str(infill_density)
|
||||
if "infill_line_distance" not in settings_with_inst: settings_with_inst["infill_line_distance"] = {}
|
||||
settings_with_inst["infill_line_distance"]["value"] = str(100 / int(infill_density)) if int(infill_density) > 0 else "9999"
|
||||
|
||||
if support_enable is not None:
|
||||
command.extend(['-s', f"support_enable={'true' if support_enable == 'true' or support_enable == 'buildplate' else 'false'}"])
|
||||
command.extend(['-s', f"support_type={'buildplate' if support_enable == 'buildplate' else 'everywhere'}"])
|
||||
if support_pattern == 'tree':
|
||||
command.extend(['-s', 'support_structure=tree'])
|
||||
command.extend(['-s', 'support_tree_enable=true'])
|
||||
elif support_pattern and support_pattern != 'false':
|
||||
command.extend(['-s', 'support_structure=normal'])
|
||||
command.extend(['-s', f'support_pattern={support_pattern}'])
|
||||
|
||||
command.extend([
|
||||
if "support_enable" not in settings_with_inst: settings_with_inst["support_enable"] = {}
|
||||
settings_with_inst["support_enable"]["value"] = True if support_enable in ['true', 'buildplate'] else False
|
||||
if "support_type" not in settings_with_inst: settings_with_inst["support_type"] = {}
|
||||
settings_with_inst["support_type"]["value"] = "'buildplate'" if support_enable == 'buildplate' else "'everywhere'"
|
||||
|
||||
if support_pattern == 'tree':
|
||||
if "support_structure" not in settings_with_inst: settings_with_inst["support_structure"] = {}
|
||||
settings_with_inst["support_structure"]["value"] = "'tree'"
|
||||
elif support_pattern in settings_with_inst["support_pattern"]["options"].keys():
|
||||
if "support_structure" not in settings_with_inst: settings_with_inst["support_structure"] = {}
|
||||
settings_with_inst["support_structure"]["value"] = "'normal'"
|
||||
if "support_pattern" not in settings_with_inst: settings_with_inst["support_pattern"] = {}
|
||||
settings_with_inst["support_pattern"]["value"] = f"'{support_pattern}'"
|
||||
|
||||
# Parse to exact values
|
||||
res = p.parse_configs(settings_with_inst)
|
||||
|
||||
override_dict = {}
|
||||
for k, v in res.items():
|
||||
if v.get("enabled", True):
|
||||
val = v.get("value", None)
|
||||
if val is not None:
|
||||
# Filter out our protective ConfigStr wrappers
|
||||
# if type(val).__name__ == "ConfigStr": pass
|
||||
# else: override_dict[k] = {"default_value": val}
|
||||
override_dict[k] = {"value": val,"default_value": val}
|
||||
elif "default_value" in v:
|
||||
override_dict[k] = {"default_value": v["default_value"], "value": v["default_value"]}
|
||||
|
||||
|
||||
|
||||
tmp_def_filename = f"tmp_{uuid.uuid4().hex}.def.json"
|
||||
tmp_def_path = os.path.join(app.config['UPLOAD_FOLDER'], tmp_def_filename)
|
||||
|
||||
tmp_def_obj = {
|
||||
"version": 2,
|
||||
"name": "TempProfile",
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": True,
|
||||
"author": "System",
|
||||
"manufacturer": "System",
|
||||
"file_formats": "text/x-gcode",
|
||||
"first_start_actions": ["MachineSettingsAction"],
|
||||
"has_materials": True,
|
||||
"has_variants": True,
|
||||
"has_machine_quality": True,
|
||||
"variants_name": "Nozzle Size",
|
||||
|
||||
"preferred_variant_name": "0.4mm Nozzle",
|
||||
"preferred_quality_type": "standard",
|
||||
"preferred_material": "generic_pla",
|
||||
|
||||
},
|
||||
"overrides": override_dict
|
||||
}
|
||||
|
||||
pretty_json = json.dumps(tmp_def_obj, indent=4)
|
||||
|
||||
with open(tmp_def_path, "w") as f:
|
||||
f.write(pretty_json)
|
||||
|
||||
command = [
|
||||
"CuraEngine", "slice",
|
||||
"-j", tmp_def_path,
|
||||
"-l", stl_filepath,
|
||||
"-o", gcode_filepath
|
||||
])
|
||||
]
|
||||
|
||||
app.logger.info(f"Running command: {' '.join(command)}")
|
||||
# print(f"Running command: {' '.join(command)}")
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
|
||||
stdout, stderr = process.communicate()
|
||||
|
||||
# if stdout:
|
||||
# print(f"[CuraEngine STDOUT]\n{stdout.decode('utf-8', errors='ignore')}")
|
||||
# if stderr:
|
||||
# print(f"[CuraEngine STDERR]\n{stderr.decode('utf-8', errors='ignore')}", flush=True)
|
||||
|
||||
# Re-fetch print_file and update status
|
||||
print_file = PrintFile.query.get(file_id)
|
||||
if not print_file:
|
||||
@@ -100,6 +200,13 @@ def slice_stl_task(file_id, stl_filepath, quality_preset=None, infill_density=No
|
||||
except Exception as e:
|
||||
app.logger.error(f"Failed to delete temp STL {stl_filepath}: {e}")
|
||||
|
||||
if tmp_def_path and os.path.exists(tmp_def_path):
|
||||
try:
|
||||
os.remove(tmp_def_path)
|
||||
# pass
|
||||
except Exception as e:
|
||||
app.logger.error(f"Failed to delete temp JSON config {tmp_def_path}: {e}")
|
||||
|
||||
db.session.commit()
|
||||
db.session.remove()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user