Merge pull request #17188 from Ultimaker/node-snapshot

Add `node` as an optional argument to `isometricSnapshot`
This commit is contained in:
Remco Burema 2023-11-03 16:17:05 +01:00 committed by GitHub
commit ce353896b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 12 deletions

View File

@ -45,17 +45,17 @@ class PreviewPass(RenderPass):
This is useful to get a preview image of a scene taken from a different location as the active camera. This is useful to get a preview image of a scene taken from a different location as the active camera.
""" """
def __init__(self, width: int, height: int) -> None: def __init__(self, width: int, height: int, *, root: CuraSceneNode = None) -> None:
super().__init__("preview", width, height, 0) super().__init__("preview", width, height, 0)
self._camera = None # type: Optional[Camera] self._camera: Optional[Camera] = None
self._renderer = Application.getInstance().getRenderer() self._renderer = Application.getInstance().getRenderer()
self._shader = None # type: Optional[ShaderProgram] self._shader: Optional[ShaderProgram] = None
self._non_printing_shader = None # type: Optional[ShaderProgram] self._non_printing_shader: Optional[ShaderProgram] = None
self._support_mesh_shader = None # type: Optional[ShaderProgram] self._support_mesh_shader: Optional[ShaderProgram] = None
self._scene = Application.getInstance().getController().getScene() self._root = Application.getInstance().getController().getScene().getRoot() if root is None else root
# Set the camera to be used by this render pass # Set the camera to be used by this render pass
# if it's None, the active camera is used # if it's None, the active camera is used
@ -96,7 +96,7 @@ class PreviewPass(RenderPass):
batch_support_mesh = RenderBatch(self._support_mesh_shader) batch_support_mesh = RenderBatch(self._support_mesh_shader)
# Fill up the batch with objects that can be sliced. # Fill up the batch with objects that can be sliced.
for node in DepthFirstIterator(self._scene.getRoot()): for node in DepthFirstIterator(self._root):
if hasattr(node, "_outside_buildarea") and not getattr(node, "_outside_buildarea"): if hasattr(node, "_outside_buildarea") and not getattr(node, "_outside_buildarea"):
if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible(): if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
per_mesh_stack = node.callDecoration("getStack") per_mesh_stack = node.callDecoration("getStack")

View File

@ -37,15 +37,24 @@ class Snapshot:
return min_x, max_x, min_y, max_y return min_x, max_x, min_y, max_y
@staticmethod @staticmethod
def isometricSnapshot(width: int = 300, height: int = 300) -> Optional[QImage]: def isometricSnapshot(width: int = 300, height: int = 300, *, node: Optional[SceneNode] = None) -> Optional[QImage]:
"""Create an isometric snapshot of the scene.""" """
Create an isometric snapshot of the scene.
root = Application.getInstance().getController().getScene().getRoot() :param width: width of the aspect ratio default 300
:param height: height of the aspect ratio default 300
:param node: node of the scene default is the root of the scene
:return: None when there is no model on the build plate otherwise it will return an image
"""
if node is None:
root = Application.getInstance().getController().getScene().getRoot()
# the direction the camera is looking at to create the isometric view # the direction the camera is looking at to create the isometric view
iso_view_dir = Vector(-1, -1, -1).normalized() iso_view_dir = Vector(-1, -1, -1).normalized()
bounds = Snapshot.nodeBounds(root) bounds = Snapshot.nodeBounds(node)
if bounds is None: if bounds is None:
Logger.log("w", "There appears to be nothing to render") Logger.log("w", "There appears to be nothing to render")
return None return None
@ -93,7 +102,7 @@ class Snapshot:
# Render the scene # Render the scene
renderer = QtRenderer() renderer = QtRenderer()
render_pass = PreviewPass(width, height) render_pass = PreviewPass(width, height, root=node)
renderer.setViewportSize(width, height) renderer.setViewportSize(width, height)
renderer.setWindowSize(width, height) renderer.setWindowSize(width, height)
render_pass.setCamera(camera) render_pass.setCamera(camera)