Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Ha <jackha@gmail.com>2018-02-05 16:36:42 +0300
committerJack Ha <jackha@gmail.com>2018-02-05 16:36:42 +0300
commit0e7edc3eaf5ccf52f21c2ea0229b529f8ed344e5 (patch)
treed5a77100f37346cb87dce169ea14a52ba1996015 /cura/Snapshot.py
parenta3ed385259c03f1a950c85cd5f9f8e6e72fae27f (diff)
CURA-4425 the thumbnail now crops correctly
Diffstat (limited to 'cura/Snapshot.py')
-rw-r--r--cura/Snapshot.py74
1 files changed, 23 insertions, 51 deletions
diff --git a/cura/Snapshot.py b/cura/Snapshot.py
index f12ff3e0e1..ff915eeaeb 100644
--- a/cura/Snapshot.py
+++ b/cura/Snapshot.py
@@ -17,11 +17,16 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
class Snapshot:
+ ## Return a QImage of the scene
+ # Uses PreviewPass that leaves out some elements
+ # Aspect ratio assumes a square
@staticmethod
def snapshot(width = 300, height = 300):
scene = Application.getInstance().getController().getScene()
active_camera = scene.getActiveCamera()
render_width, render_height = active_camera.getWindowSize()
+ render_width = int(render_width)
+ render_height = int(render_height)
preview_pass = PreviewPass(render_width, render_height)
root = scene.getRoot()
@@ -29,7 +34,6 @@ class Snapshot:
# determine zoom and look at
bbox = None
- hulls = None
for node in DepthFirstIterator(root):
if type(node) == ConvexHullNode:
print(node)
@@ -38,16 +42,12 @@ class Snapshot:
bbox = node.getBoundingBox()
else:
bbox = bbox + node.getBoundingBox()
- convex_hull = node.getMeshData().getConvexHullTransformedVertices(node.getWorldTransformation())
- if hulls is None:
- hulls = convex_hull
- else:
- hulls = numpy.concatenate((hulls, convex_hull), axis = 0)
if bbox is None:
bbox = AxisAlignedBox()
look_at = bbox.center
+ # guessed size so the objects are hopefully big
size = max(bbox.width, bbox.height, bbox.depth * 0.5)
# Somehow the aspect ratio is also influenced in reverse by the screen width/height
@@ -56,56 +56,27 @@ class Snapshot:
projection_matrix.setPerspective(30, render_width / render_height, 1, 500)
camera.setProjectionMatrix(projection_matrix)
+ # Looking from this direction (x, y, z) in OGL coordinates
looking_from_offset = Vector(1, 1, 2)
if size > 0:
# determine the watch distance depending on the size
looking_from_offset = looking_from_offset * size * 1.3
- camera.setViewportSize(render_width, render_height)
- camera.setWindowSize(render_width, render_height)
camera.setPosition(look_at + looking_from_offset)
camera.lookAt(look_at)
- # we need this for the projection calculation
- hulls4 = numpy.ones((hulls.shape[0], 4))
- hulls4[:, :-1] = hulls
- #position = Vector(10, 10, 10)
- # projected_position = camera.project(position)
-
preview_pass.setCamera(camera)
- preview_pass.setSize(render_width, render_height) # texture size
preview_pass.render()
pixel_output = preview_pass.getOutput()
- print("Calculating image coordinates...")
- view = camera.getWorldTransformation().getInverse()
- min_x, max_x, min_y, max_y = render_width, 0, render_height, 0
- for hull_coords in hulls4:
- projected_position = view.getData().dot(hull_coords)
- projected_position2 = projection_matrix.getData().dot(projected_position)
- #xx, yy = camera.project(Vector(data = hull_coords))
- # xx, yy range from -1 to 1
- xx = projected_position2[0] / projected_position2[2] / 2.0
- yy = projected_position2[1] / projected_position2[2] / 2.0
- # x, y 0..render_width/height
- x = int(render_width / 2 + xx * render_width / 2)
- y = int(render_height / 2 + yy * render_height / 2)
- min_x = min(x, min_x)
- max_x = max(x, max_x)
- min_y = min(y, min_y)
- max_y = max(y, max_y)
- print(min_x, max_x, min_y, max_y)
-
- # print("looping all pixels in python...")
- # min_x_, max_x_, min_y_, max_y_ = render_width, 0, render_height, 0
- # for y in range(int(render_height)):
- # for x in range(int(render_width)):
- # color = pixel_output.pixelColor(x, y)
- # if color.alpha() > 0:
- # min_x_ = min(x, min_x_)
- # max_x_ = max(x, max_x_)
- # min_y_ = min(y, min_y_)
- # max_y_ = max(y, max_y_)
- # print(min_x_, max_x_, min_y_, max_y_)
+ # Look at the resulting image to get a good crop.
+ # Get the pixels as byte array
+ pixel_array = pixel_output.bits().asarray(pixel_output.byteCount())
+ # Convert to numpy array, assume it's 32 bit (it should always be)
+ pixels = numpy.frombuffer(pixel_array, dtype=numpy.uint8).reshape([render_height, render_width, 4])
+ # Find indices of non zero pixels
+ nonzero_pixels = numpy.nonzero(pixels)
+ min_y, min_x, min_a_ = numpy.amin(nonzero_pixels, axis=1)
+ max_y, max_x, max_a_ = numpy.amax(nonzero_pixels, axis=1)
# make it a square
if max_x - min_x >= max_y - min_y:
@@ -114,11 +85,12 @@ class Snapshot:
else:
# make x bigger
min_x, max_x = int((max_x + min_x) / 2 - (max_y - min_y) / 2), int((max_x + min_x) / 2 + (max_y - min_y) / 2)
- copy_pixel_output = pixel_output.copy(min_x, min_y, max_x - min_x, max_y - min_y)
+ cropped_image = pixel_output.copy(min_x, min_y, max_x - min_x, max_y - min_y)
- # Scale it to the correct height
- image = copy_pixel_output.scaledToHeight(height, QtCore.Qt.SmoothTransformation)
- # Then chop of the width
- cropped_image = image.copy(image.width() // 2 - width // 2, 0, width, height)
+ # Scale it to the correct size
+ scaled_image = cropped_image.scaled(
+ width, height,
+ aspectRatioMode = QtCore.Qt.IgnoreAspectRatio,
+ transformMode = QtCore.Qt.SmoothTransformation)
- return cropped_image
+ return scaled_image