1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
# Copyright (c) 2021 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.
from UM.Message import Message
from UM.Math.Vector import Vector
from UM.Logger import Logger
from UM.FileHandler.ReadFileJob import ReadFileJob
import math
from UM.i18n import i18nCatalog
i18n_catalog = i18nCatalog("uranium")
class ReadMeshJob(ReadFileJob):
"""A Job subclass that performs mesh loading.
The result of this Job is a MeshData object.
"""
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
from UM.Qt.QtApplication import QtApplication
self._application = QtApplication.getInstance()
self._handler = QtApplication.getInstance().getMeshFileHandler()
def run(self):
super().run()
if not self._result:
self._add_to_recent_files = False # Failed to read any models due to error.
self._result = []
# Scale down to maximum bounds size if that is available
if hasattr(self._application.getController().getScene(), "_maximum_bounds"):
for node in self._result:
max_bounds = self._application.getController().getScene()._maximum_bounds
node._resetAABB()
build_bounds = node.getBoundingBox()
if build_bounds is None or max_bounds is None:
continue
if self._application.getInstance().getPreferences().getValue("mesh/scale_to_fit") == True or self._application.getInstance().getPreferences().getValue("mesh/scale_tiny_meshes") == True:
scale_factor_width = max_bounds.width / build_bounds.width
scale_factor_height = max_bounds.height / build_bounds.height
scale_factor_depth = max_bounds.depth / build_bounds.depth
scale_factor = min(scale_factor_width, scale_factor_depth, scale_factor_height)
if self._application.getInstance().getPreferences().getValue("mesh/scale_to_fit") == True and (scale_factor_width < 1 or scale_factor_height < 1 or scale_factor_depth < 1): # Use scale factor to scale large object down
# Ignore scaling on models which are less than 1.25 times bigger than the build volume
ignore_factor = 1.25
if 1 / scale_factor < ignore_factor:
Logger.log("i", "Ignoring auto-scaling, because %.3d < %.3d" % (1 / scale_factor, ignore_factor))
scale_factor = 1
pass
elif self._application.getInstance().getPreferences().getValue("mesh/scale_tiny_meshes") == True and (scale_factor_width > 100 and scale_factor_height > 100 and scale_factor_depth > 100):
# Round scale factor to lower factor of 10 to scale tiny object up (eg convert m to mm units)
try:
scale_factor = math.pow(10, math.floor(math.log(scale_factor) / math.log(10)))
except:
# In certain cases the scale_factor can be inf which can make this fail. Just use 1 instead.
scale_factor = 1
else:
scale_factor = 1
if scale_factor != 1:
scale_vector = Vector(scale_factor, scale_factor, scale_factor)
display_scale_factor = scale_factor * 100
scale_message = Message(i18n_catalog.i18nc("@info:status",
"Auto scaled model to {0}% of original size",
("%i" % display_scale_factor)),
title = i18n_catalog.i18nc("@info:title", "Scaling Object"))
try:
node.scale(scale_vector)
scale_message.show()
except Exception:
Logger.logException("e", "While auto-scaling an exception has been raised")
|