mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-23 14:44:13 -06:00
CURA-4425 scale image to full size; still has a bug that it is shifted vertically; still need to clean code
This commit is contained in:
parent
c432646908
commit
7856d61b5a
2 changed files with 67 additions and 17 deletions
|
@ -1,7 +1,6 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from cura.Settings.ExtrudersModel import ExtrudersModel
|
from cura.Settings.ExtrudersModel import ExtrudersModel
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
import numpy
|
||||||
|
|
||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
|
|
||||||
from cura.PreviewPass import PreviewPass
|
from cura.PreviewPass import PreviewPass
|
||||||
|
from cura.Scene import ConvexHullNode
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
||||||
from UM.Math.Matrix import Matrix
|
from UM.Math.Matrix import Matrix
|
||||||
from UM.Math.Vector import Vector
|
from UM.Math.Vector import Vector
|
||||||
|
from UM.Mesh.MeshData import transformVertices
|
||||||
from UM.Scene.Camera import Camera
|
from UM.Scene.Camera import Camera
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
|
|
||||||
|
@ -25,18 +29,33 @@ class Snapshot:
|
||||||
|
|
||||||
# determine zoom and look at
|
# determine zoom and look at
|
||||||
bbox = None
|
bbox = None
|
||||||
|
hulls = None
|
||||||
for node in DepthFirstIterator(root):
|
for node in DepthFirstIterator(root):
|
||||||
|
if type(node) == ConvexHullNode:
|
||||||
|
print(node)
|
||||||
if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
|
if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
|
||||||
if bbox is None:
|
if bbox is None:
|
||||||
bbox = node.getBoundingBox()
|
bbox = node.getBoundingBox()
|
||||||
else:
|
else:
|
||||||
bbox = bbox + node.getBoundingBox()
|
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:
|
if bbox is None:
|
||||||
bbox = AxisAlignedBox()
|
bbox = AxisAlignedBox()
|
||||||
|
|
||||||
look_at = bbox.center
|
look_at = bbox.center
|
||||||
size = max(bbox.width, bbox.height, bbox.depth * 0.5)
|
size = max(bbox.width, bbox.height, bbox.depth * 0.5)
|
||||||
|
|
||||||
|
# Somehow the aspect ratio is also influenced in reverse by the screen width/height
|
||||||
|
# So you have to set it to render_width/render_height to get 1
|
||||||
|
projection_matrix = Matrix()
|
||||||
|
projection_matrix.setPerspective(30, render_width / render_height, 1, 500)
|
||||||
|
camera.setProjectionMatrix(projection_matrix)
|
||||||
|
|
||||||
looking_from_offset = Vector(1, 1, 2)
|
looking_from_offset = Vector(1, 1, 2)
|
||||||
if size > 0:
|
if size > 0:
|
||||||
# determine the watch distance depending on the size
|
# determine the watch distance depending on the size
|
||||||
|
@ -46,28 +65,60 @@ class Snapshot:
|
||||||
camera.setPosition(look_at + looking_from_offset)
|
camera.setPosition(look_at + looking_from_offset)
|
||||||
camera.lookAt(look_at)
|
camera.lookAt(look_at)
|
||||||
|
|
||||||
# Somehow the aspect ratio is also influenced in reverse by the screen width/height
|
# we need this for the projection calculation
|
||||||
# So you have to set it to render_width/render_height to get 1
|
hulls4 = numpy.ones((hulls.shape[0], 4))
|
||||||
projection_matrix = Matrix()
|
hulls4[:, :-1] = hulls
|
||||||
projection_matrix.setPerspective(30, render_width / render_height, 1, 500)
|
#position = Vector(10, 10, 10)
|
||||||
|
# projected_position = camera.project(position)
|
||||||
camera.setProjectionMatrix(projection_matrix)
|
|
||||||
|
|
||||||
preview_pass.setCamera(camera)
|
preview_pass.setCamera(camera)
|
||||||
preview_pass.setSize(render_width, render_height) # texture size
|
preview_pass.setSize(render_width, render_height) # texture size
|
||||||
preview_pass.render()
|
preview_pass.render()
|
||||||
pixel_output = preview_pass.getOutput()
|
pixel_output = preview_pass.getOutput()
|
||||||
|
|
||||||
# It's a bit annoying that window size has to be taken into account
|
print("Calculating image coordinates...")
|
||||||
if pixel_output.width() >= pixel_output.height():
|
view = camera.getWorldTransformation().getInverse()
|
||||||
# Scale it to the correct height
|
min_x, max_x, min_y, max_y = render_width, 0, render_height, 0
|
||||||
image = pixel_output.scaledToHeight(height, QtCore.Qt.SmoothTransformation)
|
for hull_coords in hulls4:
|
||||||
# Then chop of the width
|
projected_position = view.getData().dot(hull_coords)
|
||||||
cropped_image = image.copy(image.width() // 2 - width // 2, 0, width, height)
|
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_)
|
||||||
|
|
||||||
|
# make it a square
|
||||||
|
if max_x - min_x >= max_y - min_y:
|
||||||
|
# make y bigger
|
||||||
|
min_y, max_y = int((max_y + min_y) / 2 - (max_x - min_x) / 2), int((max_y + min_y) / 2 + (max_x - min_x) / 2)
|
||||||
else:
|
else:
|
||||||
# Scale it to the correct width
|
# make x bigger
|
||||||
image = pixel_output.scaledToWidth(width, QtCore.Qt.SmoothTransformation)
|
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)
|
||||||
# Then chop of the height
|
copy_pixel_output = pixel_output.copy(min_x, min_y, max_x - min_x, max_y - min_y)
|
||||||
cropped_image = image.copy(0, image.height() // 2 - height // 2, width, height)
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
return cropped_image
|
return cropped_image
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue