From 2b8ac10f57d3f330c24d365eab5f03f97fec751b Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 10 Dec 2025 10:15:19 +0100 Subject: [PATCH] Unhardcode belt-angle setting. Don't merge to main. Part of CURA-12625 --- .../CuraEngineBackend/BlackBeltDecorator.py | 75 ------------------- plugins/CuraEngineBackend/StartSliceJob.py | 51 ++++++++++--- .../definitions/custom_belt_printer.def.json | 21 +----- resources/definitions/fdmprinter.def.json | 10 +++ 4 files changed, 52 insertions(+), 105 deletions(-) delete mode 100644 plugins/CuraEngineBackend/BlackBeltDecorator.py diff --git a/plugins/CuraEngineBackend/BlackBeltDecorator.py b/plugins/CuraEngineBackend/BlackBeltDecorator.py deleted file mode 100644 index 379a26b9d2..0000000000 --- a/plugins/CuraEngineBackend/BlackBeltDecorator.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2018 fieldOfView -# The Blackbelt plugin is released under the terms of the LGPLv3 or higher. - -from UM.Scene.SceneNodeDecorator import SceneNodeDecorator -from UM.Application import Application - -from UM.Math.Matrix import Matrix - -import math - -## Decorator for easy access to gantry angle and transform matrix. -class BlackBeltDecorator(SceneNodeDecorator): - def __init__(self): - super().__init__() - self._gantry_angle = 0 - self._transform_matrix = Matrix() - self._scene_front_offset = 0 - - @staticmethod - def calculateTransformData() -> Matrix: - global_stack = Application.getInstance().getGlobalContainerStack() - - #self._scene_front_offset = 0 - #gantry_angle = 0.7 #global_stack.getProperty("blackbelt_gantry_angle", "value") - #if not gantry_angle: - #self._gantry_angle = 0 - #self._transform_matrix = Matrix() - # return Matrix() - gantry_angle = 0.48869219 #math.radians(float(gantry_angle)) - - machine_depth = global_stack.getProperty("machine_depth", "value") - - matrix = Matrix() - matrix.setColumn(1, [0, 1 / math.tan(gantry_angle), 1, (machine_depth / 2) * (1 - math.cos(gantry_angle))]) - matrix.setColumn(2, [0, - 1 / math.sin(gantry_angle), 0, machine_depth / 2]) - #self._transform_matrix = matrix - return matrix - - # The above magic transform matrix is composed as follows: - """ - import numpy - matrix_data = numpy.identity(4) - matrix_data[2, 2] = 1/math.sin(self._gantry_angle) # scale Z - matrix_data[1, 2] = -1/math.tan(self._gantry_angle) # shear ZY - matrix = Matrix(matrix_data) - - matrix_data = numpy.identity(4) - # use front buildvolume face instead of bottom face - matrix_data[1, 1] = 0 - matrix_data[1, 2] = 1 - matrix_data[2, 1] = -1 - matrix_data[2, 2] = 0 - axes_matrix = Matrix(matrix_data) - - matrix.multiply(axes_matrix) - - # bottom face has origin at the center, front face has origin at one side - matrix.translate(Vector(0, - math.sin(self._gantry_angle) * machine_depth / 2, 0)) - # make sure objects are not transformed to be below the buildplate - matrix.translate(Vector(0, 0, machine_depth / 2)) - - self._transform_matrix = matrix - """ - - def getGantryAngle(self): - return self._gantry_angle - - def getTransformMatrix(self): - return self._transform_matrix - - def setSceneFrontOffset(self, front_offset): - self._scene_front_offset = front_offset - - def getSceneFrontOffset(self): - return self._scene_front_offset \ No newline at end of file diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index ac8fbb095a..0f5165f5f8 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -14,6 +14,7 @@ from PyQt6.QtCore import QCoreApplication from UM.Job import Job from UM.Logger import Logger +from UM.Math.Matrix import Matrix from UM.Scene.SceneNode import SceneNode from UM.Settings.ContainerStack import ContainerStack #For typing. from UM.Settings.InstanceContainer import InstanceContainer @@ -39,7 +40,6 @@ from cura.OneAtATimeIterator import OneAtATimeIterator from cura.Settings.CuraContainerStack import CuraContainerStack from cura.Settings.ExtruderManager import ExtruderManager from cura.CuraVersion import CuraVersion -from .BlackBeltDecorator import BlackBeltDecorator from .SupportMeshCreator import SupportMeshCreator NON_PRINTING_MESH_SETTINGS = ["anti_overhang_mesh", "infill_mesh", "cutting_mesh"] @@ -291,6 +291,45 @@ class StartSliceJob(Job): return False + @staticmethod + def _beltPrinterTransform() -> Matrix: + # Both the comment and the resulting method where originally in the BlackBeltPrinter plugin by fieldOfView. + """ + # The below magic transform matrix is composed as follows. + import numpy + matrix_data = numpy.identity(4) + matrix_data[2, 2] = 1/math.sin(self._gantry_angle) # scale Z + matrix_data[1, 2] = -1/math.tan(self._gantry_angle) # shear ZY + matrix = Matrix(matrix_data) + + matrix_data = numpy.identity(4) + # use front buildvolume face instead of bottom face + matrix_data[1, 1] = 0 + matrix_data[1, 2] = 1 + matrix_data[2, 1] = -1 + matrix_data[2, 2] = 0 + axes_matrix = Matrix(matrix_data) + + matrix.multiply(axes_matrix) + + # bottom face has origin at the center, front face has origin at one side + matrix.translate(Vector(0, - math.sin(self._gantry_angle) * machine_depth / 2, 0)) + # make sure objects are not transformed to be below the buildplate + matrix.translate(Vector(0, 0, machine_depth / 2)) + + self._transform_matrix = matrix + """ + + global_stack = CuraApplication.getInstance().getGlobalContainerStack() + gantry_angle = math.radians(float(global_stack.getProperty("belt_gantry_angle", "value"))) + + machine_depth = global_stack.getProperty("machine_depth", "value") + + matrix = Matrix() + matrix.setColumn(1, [0, 1 / math.tan(gantry_angle), 1, (machine_depth / 2) * (1 - math.cos(gantry_angle))]) + matrix.setColumn(2, [0, - 1 / math.sin(gantry_angle), 0, machine_depth / 2]) + return matrix + def run(self) -> None: """Runs the job that initiates the slicing.""" @@ -606,7 +645,7 @@ class StartSliceJob(Job): if added_meshes: group += added_meshes - transform_matrix = BlackBeltDecorator.calculateTransformData() # self._scene.getRoot().callDecoration("getTransformMatrix") ### ????? BOOKMARK! + transform_matrix = StartSliceJob._beltPrinterTransform() front_offset = None raft_offset = 0 @@ -710,14 +749,6 @@ class StartSliceJob(Job): obj.vertices = flat_verts - uv_coordinates = mesh_data.getUVCoordinates() - if uv_coordinates is not None: - obj.uv_coordinates = uv_coordinates.flatten() - - packed_texture = object.callDecoration("packTexture") - if packed_texture is not None: - obj.texture = packed_texture - if object.getName() in raft_meshes: self._addSettingsMessage(obj, { "wall_line_count": 99999999, diff --git a/resources/definitions/custom_belt_printer.def.json b/resources/definitions/custom_belt_printer.def.json index a393973755..b0e1481791 100644 --- a/resources/definitions/custom_belt_printer.def.json +++ b/resources/definitions/custom_belt_printer.def.json @@ -19,24 +19,5 @@ "overrides": { "machine_depth": { "default_value": 99999 } - }, - "settings": - { - "blackbelt_settings": - { - "children": - { - "blackbelt_gantry_angle": - { - "default_value": "45", - "description": "The angle of the gantry relative to the build plate. Match this setting with the current printer configuration.", - "label": "Gantry Angle", - "settable_per_extruder": false, - "settable_per_mesh": false, - "type": "float", - "unit": "\u00b0" - } - } - } } -} \ No newline at end of file +} diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6747bf9ceb..3d0c045192 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -8107,6 +8107,16 @@ "description": "Non-traditional ways to print your models.", "children": { + "belt_gantry_angle": + { + "default_value": 28.0, + "description": "The angle of the gantry relative to the build plate. Match this setting with the current printer configuration.", + "label": "Gantry Angle", + "settable_per_extruder": false, + "settable_per_mesh": false, + "type": "float", + "unit": "\u00b0" + }, "print_sequence": { "label": "Print Sequence",