diff --git a/conandata.yml b/conandata.yml index dfe9eb2ea2..20a961ef6e 100644 --- a/conandata.yml +++ b/conandata.yml @@ -567,17 +567,6 @@ pip_requirements_core: hashes: - sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5 - sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413 - pynavlib: - version: "0.9.4" - hashes: - - sha256:567efd0af97f9014326898b209eea94d9f5cc58e9f589ccf8354584568fcb87d - - sha256:fdd5ab5b6e0a2c9bbcebb154ac7303daf845865a1649be04e1bd8e8e5889401f - - sha256:f0d7ce426e816788aa96b419fd7da263eafb99aca46ce3b6e5dbaf2bbf6b614a - - sha256:493c4b3cacc939b021a694d99723106dbd7ee5515ad4dfc1c7fc8219ef20cf3a - - sha256:33962a322033a78db05a8c2cc3d59e057fbea5b04879c3c54e2fe3041d691a12 - - sha256:332831553a70be05fe58c43a08109b42970cfedc6086ffb4306859142a0e9210 - - sha256:d06d94b1dee4ba024b4a121869e572f571673a3b8c15b4055f52236d43c19a02 - - sha256:9173f61ad83172c306b92bbe38f949889c158cd6dfdc924db01f257a437bf2a6 Windows: twisted-iocpsupport: @@ -600,6 +589,22 @@ pip_requirements_core: hashes: - sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8 - sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755 + pynavlib: + version: "0.9.4" + hashes: + - sha256:fdd5ab5b6e0a2c9bbcebb154ac7303daf845865a1649be04e1bd8e8e5889401f + - sha256:493c4b3cacc939b021a694d99723106dbd7ee5515ad4dfc1c7fc8219ef20cf3a + - sha256:332831553a70be05fe58c43a08109b42970cfedc6086ffb4306859142a0e9210 + - sha256:9173f61ad83172c306b92bbe38f949889c158cd6dfdc924db01f257a437bf2a6 + + Macos: + pynavlib: + version: "0.9.4" + hashes: + - sha256:567efd0af97f9014326898b209eea94d9f5cc58e9f589ccf8354584568fcb87d + - sha256:f0d7ce426e816788aa96b419fd7da263eafb99aca46ce3b6e5dbaf2bbf6b614a + - sha256:33962a322033a78db05a8c2cc3d59e057fbea5b04879c3c54e2fe3041d691a12 + - sha256:d06d94b1dee4ba024b4a121869e572f571673a3b8c15b4055f52236d43c19a02 pip_requirements_dev: any_os: diff --git a/cura/NavlibClient.py b/cura/NavlibClient.py index 49bcb92131..db7711e773 100644 --- a/cura/NavlibClient.py +++ b/cura/NavlibClient.py @@ -1,4 +1,3 @@ -import pynavlib.pynavlib_interface as pynav from UM.Math.Matrix import Matrix from UM.Math.Vector import Vector from UM.Math.AxisAlignedBox import AxisAlignedBox @@ -6,10 +5,22 @@ from cura.PickingPass import PickingPass from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from cura.Scene.OverlayNode import OverlayNode, SceneNode from UM.Resources import Resources +from UM.Logger import Logger -class NavlibClient(pynav.NavlibNavigationModel): +try: + import pynavlib.pynavlib_interface as pynav + parent_class = pynav.NavlibNavigationModel +except BaseException as exception: + Logger.warning(f"Unable to load 3DConnexion library: {exception}") + pynav = None + parent_class = object + +class NavlibClient(parent_class): def __init__(self, scene, renderer) -> None: + if not pynav: + return + super().__init__(False, pynav.NavlibOptions.RowMajorOrder) self._scene = scene self._renderer = renderer @@ -19,6 +30,14 @@ class NavlibClient(pynav.NavlibNavigationModel): self._picking_pass = None self._pivot_node = OverlayNode(node=SceneNode(), image_path=Resources.getPath(Resources.Images, "cor.png"), size=2.5) + def put_profile_hint(self, hint) -> None: + if pynav: + super().put_profile_hint(hint) + + def enable_navigation(self, enabled) -> None: + if pynav: + super().enable_navigation(enabled) + def pick(self, x, y, check_selection = False, radius = 0.): if self._picking_pass is None or radius < 0.: @@ -39,7 +58,7 @@ class NavlibClient(pynav.NavlibNavigationModel): coord_x = (x - radius) + i * step coord_y = (y - radius) + j * step - + picked_depth = self._picking_pass.getPickedDepth(coord_x, coord_y) max_depth = 16777.215 @@ -62,10 +81,10 @@ class NavlibClient(pynav.NavlibNavigationModel): if picked_depth < min_depth: min_depth = picked_depth result_position = self._picking_pass.getPickedPosition(coord_x, coord_y) - + return result_position - - def get_pointer_position(self)->pynav.NavlibVector: + + def get_pointer_position(self) -> "pynav.NavlibVector": from UM.Qt.QtApplication import QtApplication main_window = QtApplication.getInstance().getMainWindow() @@ -77,7 +96,7 @@ class NavlibClient(pynav.NavlibNavigationModel): self._was_pick = True from cura.Utils.Threading import call_on_qt_thread wrapped_pick = call_on_qt_thread(self.pick) - + self._pointer_pick = wrapped_pick(x_n, y_n) return pynav.NavlibVector(0., 0., 0.) @@ -87,7 +106,7 @@ class NavlibClient(pynav.NavlibNavigationModel): return pynav.NavlibVector(pointer_position.x, pointer_position.y, pointer_position.z) - def get_view_extents(self)->pynav.NavlibBox: + def get_view_extents(self) -> "pynav.NavlibBox": view_width = self._scene.getActiveCamera().getViewportWidth() view_height = self._scene.getActiveCamera().getViewportHeight() @@ -99,18 +118,18 @@ class NavlibClient(pynav.NavlibNavigationModel): return pynav.NavlibBox(pt_min, pt_max) - def get_view_frustum(self)->pynav.NavlibFrustum: + def get_view_frustum(self) -> "pynav.NavlibFrustum": projection_matrix = self._scene.getActiveCamera().getProjectionMatrix() half_height = 2. / projection_matrix.getData()[1,1] half_width = half_height * (projection_matrix.getData()[1,1] / projection_matrix.getData()[0,0]) return pynav.NavlibFrustum(-half_width, half_width, -half_height, half_height, 1., 5000.) - - def get_is_view_perspective(self)->bool: + + def get_is_view_perspective(self) -> bool: return self._scene.getActiveCamera().isPerspective() - def get_selection_extents(self)->pynav.NavlibBox: + def get_selection_extents(self) -> "pynav.NavlibBox": from UM.Scene.Selection import Selection bounding_box = Selection.getBoundingBox() @@ -120,33 +139,33 @@ class NavlibClient(pynav.NavlibNavigationModel): pt_max = pynav.NavlibVector(bounding_box.maximum.x, bounding_box.maximum.y, bounding_box.maximum.z) return pynav.NavlibBox(pt_min, pt_max) - def get_selection_transform(self)->pynav.NavlibMatrix: + def get_selection_transform(self) -> "pynav.NavlibMatrix": return pynav.NavlibMatrix() - - def get_is_selection_empty(self)->bool: + + def get_is_selection_empty(self) -> bool: from UM.Scene.Selection import Selection return not Selection.hasSelection() - - def get_pivot_visible(self)->bool: + + def get_pivot_visible(self) -> bool: return False - - def get_camera_matrix(self)->pynav.NavlibMatrix: + + def get_camera_matrix(self) -> "pynav.NavlibMatrix": transformation = self._scene.getActiveCamera().getLocalTransformation() - + return pynav.NavlibMatrix([[transformation.at(0, 0), transformation.at(0, 1), transformation.at(0, 2), transformation.at(0, 3)], [transformation.at(1, 0), transformation.at(1, 1), transformation.at(1, 2), transformation.at(1, 3)], [transformation.at(2, 0), transformation.at(2, 1), transformation.at(2, 2), transformation.at(2, 3)], [transformation.at(3, 0), transformation.at(3, 1), transformation.at(3, 2), transformation.at(3, 3)]]) - def get_coordinate_system(self)->pynav.NavlibMatrix: + def get_coordinate_system(self) -> "pynav.NavlibMatrix": return pynav.NavlibMatrix() - - def get_front_view(self)->pynav.NavlibMatrix: + + def get_front_view(self) -> "pynav.NavlibMatrix": return pynav.NavlibMatrix() - - def get_model_extents(self)->pynav.NavlibBox: - + + def get_model_extents(self) -> "pynav.NavlibBox": + result_bbox = AxisAlignedBox() build_volume_bbox = None @@ -166,12 +185,12 @@ class NavlibClient(pynav.NavlibNavigationModel): self._scene_center = result_bbox.center self._scene_radius = (result_bbox.maximum - self._scene_center).length() return pynav.NavlibBox(pt_min, pt_max) - - def get_pivot_position(self)->pynav.NavlibVector: + + def get_pivot_position(self) -> "pynav.NavlibVector": return pynav.NavlibVector() - - def get_hit_look_at(self)->pynav.NavlibVector: - + + def get_hit_look_at(self) -> "pynav.NavlibVector": + if self._was_pick and self._pointer_pick is not None: return pynav.NavlibVector(self._pointer_pick.x, self._pointer_pick.y, self._pointer_pick.z) elif self._was_pick and self._pointer_pick is None: @@ -183,21 +202,21 @@ class NavlibClient(pynav.NavlibNavigationModel): if picked_position is not None: return pynav.NavlibVector(picked_position.x, picked_position.y, picked_position.z) - - def get_units_to_meters(self)->float: + + def get_units_to_meters(self) -> float: return 0.05 - - def is_user_pivot(self)->bool: + + def is_user_pivot(self) -> bool: return False - - def set_camera_matrix(self, matrix : pynav.NavlibMatrix): + + def set_camera_matrix(self, matrix : "pynav.NavlibMatrix"): # !!!!!! # Hit testing in Orthographic view is not reliable # Picking starts in camera position, not on near plane # which results in wrong depth values (visible geometry # cannot be picked properly) - Workaround needed (camera position offset) - # !!!!!! + # !!!!!! if not self.get_is_view_perspective(): affine = matrix._matrix direction = Vector(-affine[0][2], -affine[1][2], -affine[2][2]) @@ -216,7 +235,7 @@ class NavlibClient(pynav.NavlibNavigationModel): matrix._matrix[0][3] = matrix._matrix[0][3] - offset * direction.x matrix._matrix[1][3] = matrix._matrix[1][3] - offset * direction.y - matrix._matrix[2][3] = matrix._matrix[2][3] - offset * direction.z + matrix._matrix[2][3] = matrix._matrix[2][3] - offset * direction.z transformation = Matrix(data = matrix._matrix) self._scene.getActiveCamera().setTransformation(transformation) @@ -233,7 +252,7 @@ class NavlibClient(pynav.NavlibNavigationModel): self._pivot_node.scale(scale) - def set_view_extents(self, extents: pynav.NavlibBox): + def set_view_extents(self, extents: "pynav.NavlibBox"): view_width = self._scene.getActiveCamera().getViewportWidth() new_zoom = (extents._min._x + view_width / 2.) / - view_width self._scene.getActiveCamera().setZoomFactor(new_zoom) @@ -250,13 +269,12 @@ class NavlibClient(pynav.NavlibNavigationModel): else: self._was_pick = False self._renderer.removeRenderPass(self._picking_pass) - + def set_pivot_position(self, position): self._pivot_node._target_node.setPosition(position=Vector(position._x, position._y, position._z), transform_space = SceneNode.TransformSpace.World) - + def set_pivot_visible(self, visible): if visible: self._scene.getRoot().addChild(self._pivot_node) else: self._scene.getRoot().removeChild(self._pivot_node) - diff --git a/scripts/get_pypi_hashes.py b/scripts/get_pypi_hashes.py index aabe9ece0a..cd11312932 100755 --- a/scripts/get_pypi_hashes.py +++ b/scripts/get_pypi_hashes.py @@ -3,7 +3,7 @@ import argparse from pathlib import Path -def get_package_wheel_hashes(package, version): +def get_package_wheel_hashes(package, version, os): url = f"https://pypi.org/pypi/{package}/{version}/json" data = requests.get(url).json() @@ -12,7 +12,8 @@ def get_package_wheel_hashes(package, version): print(f" hashes:") for url in data["urls"]: - print(f" - sha256:{url['digests']['sha256']}") + if os is None or os in url["filename"]: + print(f" - sha256:{url['digests']['sha256']}") if __name__ == "__main__": @@ -20,5 +21,6 @@ if __name__ == "__main__": description="Display the hashes of the wheel files to be inserted in pip_requirements") parser.add_argument("package", type=Path, help="Name of the target package") parser.add_argument("version", type=Path, help="Version of the target package") + parser.add_argument('--os', type=str, help='Specific package OS', choices=['win', 'macosx', 'manylinux', 'musllinux']) args = parser.parse_args() - get_package_wheel_hashes(args.package, args.version) + get_package_wheel_hashes(args.package, args.version, args.os)