Browse Source

Add `node` as an optional argument to `isometricSnapshot`

By setting this argument a single `SceneNode` can be used as subject for the snapshot. If argument is omitted then the scene root is taken as node.
c.lamboo 1 year ago
parent
commit
46bed2de56
2 changed files with 21 additions and 12 deletions
  1. 7 7
      cura/PreviewPass.py
  2. 14 5
      cura/Snapshot.py

+ 7 - 7
cura/PreviewPass.py

@@ -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.
     """
 
-    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)
 
-        self._camera = None  # type: Optional[Camera]
+        self._camera: Optional[Camera] = None
 
         self._renderer = Application.getInstance().getRenderer()
 
-        self._shader = None  # type: Optional[ShaderProgram]
-        self._non_printing_shader = None  # type: Optional[ShaderProgram]
-        self._support_mesh_shader = None  # type: Optional[ShaderProgram]
-        self._scene = Application.getInstance().getController().getScene()
+        self._shader: Optional[ShaderProgram] = None
+        self._non_printing_shader: Optional[ShaderProgram] = None
+        self._support_mesh_shader: Optional[ShaderProgram] = None
+        self._root = Application.getInstance().getController().getScene().getRoot() if root is None else root
 
     #   Set the camera to be used by this render pass
     #   if it's None, the active camera is used
@@ -96,7 +96,7 @@ class PreviewPass(RenderPass):
         batch_support_mesh = RenderBatch(self._support_mesh_shader)
 
         # 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 node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
                     per_mesh_stack = node.callDecoration("getStack")

+ 14 - 5
cura/Snapshot.py

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