diff --git a/.github/workflows/conan-package-create.yml b/.github/workflows/conan-package-create.yml index da641c5c78..3e5f3dbe1c 100644 --- a/.github/workflows/conan-package-create.yml +++ b/.github/workflows/conan-package-create.yml @@ -66,10 +66,8 @@ jobs: cache: 'pip' cache-dependency-path: .github/workflows/requirements-conan-package.txt - - name: Install Python requirements and Create default Conan profile - run: | - pip install -r .github/workflows/requirements-conan-package.txt - conan profile new default --detect + - name: Install Python requirements for runner + run: pip install -r .github/workflows/requirements-conan-package.txt - name: Use Conan download cache (Bash) if: ${{ runner.os != 'Windows' }} @@ -105,10 +103,21 @@ jobs: - name: Install Linux system requirements if: ${{ runner.os == 'Linux' }} run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt update sudo apt upgrade sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y + - name: Install GCC-12 on ubuntu-22.04 + if: ${{ matrix.os == 'ubuntu-22.04' }} + run: | + sudo apt install g++-12 gcc-12 -y + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12 + + - name: Create the default Conan profile + run: conan profile new default --detect + - name: Get Conan configuration from branch if: ${{ inputs.conan_config_branch != '' }} run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}" @@ -140,5 +149,5 @@ jobs: run: conan upload "*" -r cura --all -c - name: Upload the Package(s) community - if: ${{ always() && inputs.conan_upload_community == 'true' }} + if: ${{ always() && inputs.conan_upload_community == true }} run: conan upload "*" -r cura-ce -c diff --git a/.github/workflows/conan-recipe-export.yml b/.github/workflows/conan-recipe-export.yml index cab21604fe..f38c0046c9 100644 --- a/.github/workflows/conan-recipe-export.yml +++ b/.github/workflows/conan-recipe-export.yml @@ -102,5 +102,5 @@ jobs: run: conan upload "*" -r cura --all -c - name: Upload the Package(s) community - if: ${{ always() && inputs.conan_upload_community == 'true' }} + if: ${{ always() && inputs.conan_upload_community == true }} run: conan upload "*" -r cura-ce -c diff --git a/.github/workflows/conan-recipe-version.yml b/.github/workflows/conan-recipe-version.yml index fe85766db0..5a24754f03 100644 --- a/.github/workflows/conan-recipe-version.yml +++ b/.github/workflows/conan-recipe-version.yml @@ -7,6 +7,11 @@ on: required: true type: string + additional_buildmetadata: + required: false + default: "" + type: string + outputs: recipe_id_full: description: "The full Conan recipe id: /@/" @@ -79,6 +84,7 @@ jobs: issue_number = "${{ github.ref }}".split('/')[2] is_tag = "${{ github.ref_type }}" == "tag" is_release_branch = False + buildmetadata = "" if "${{ inputs.additional_buildmetadata }}" == "" else "${{ inputs.additional_buildmetadata }}_" # FIXME: for when we push a tag (such as an release) channel = "testing" @@ -130,7 +136,7 @@ jobs: channel = "_" else: if event_name == "pull_request": - actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+pr_{issue_number}_{no_commits}" + actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}pr_{issue_number}_{no_commits}" else: if channel in ("stable", "_", ""): channel_metadata = f"{no_commits}" @@ -139,9 +145,9 @@ jobs: # FIXME: for when we create a new release branch if latest_branch_version.prerelease == "": bump_up_minor = int(latest_branch_version.minor) + 1 - actual_version = f"{latest_branch_version.major}.{bump_up_minor}.{latest_branch_version.patch}-alpha+{channel_metadata}" + actual_version = f"{latest_branch_version.major}.{bump_up_minor}.{latest_branch_version.patch}-alpha+{buildmetadata}{channel_metadata}" else: - actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{channel_metadata}" + actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}{channel_metadata}" # %% print to output cmd_name = ["echo", f"::set-output name=name::{project_name}"] diff --git a/.github/workflows/cura-installer.yml b/.github/workflows/cura-installer.yml index 2941d34e7f..10e7888029 100644 --- a/.github/workflows/cura-installer.yml +++ b/.github/workflows/cura-installer.yml @@ -77,10 +77,8 @@ jobs: cache: 'pip' cache-dependency-path: .github/workflows/requirements-conan-package.txt - - name: Install Python requirements and Create default Conan profile - run: | - pip install -r .github/workflows/requirements-conan-package.txt - conan profile new default --detect + - name: Install Python requirements for runner + run: pip install -r .github/workflows/requirements-conan-package.txt - name: Use Conan download cache (Bash) if: ${{ runner.os != 'Windows' }} @@ -116,6 +114,7 @@ jobs: - name: Install Linux system requirements if: ${{ runner.os == 'Linux' }} run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt update sudo apt upgrade sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y @@ -123,6 +122,16 @@ jobs: chmod +x $GITHUB_WORKSPACE/appimagetool echo "APPIMAGETOOL_LOCATION=$GITHUB_WORKSPACE/appimagetool" >> $GITHUB_ENV + - name: Install GCC-12 on ubuntu-22.04 + if: ${{ matrix.os == 'ubuntu-22.04' }} + run: | + sudo apt install g++-12 gcc-12 -y + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12 + + - name: Create the default Conan profile + run: conan profile new default --detect + - name: Configure GPG Key Linux (Bash) if: ${{ runner.os == 'Linux' }} run: echo -n "$GPG_PRIVATE_KEY" | base64 --decode | gpg --import diff --git a/.github/workflows/requirements-conan-package.txt b/.github/workflows/requirements-conan-package.txt index 9ac91d2704..cf9d4193ef 100644 --- a/.github/workflows/requirements-conan-package.txt +++ b/.github/workflows/requirements-conan-package.txt @@ -1,2 +1,2 @@ -conan!=1.51.0 +conan!=1.51.0,!=1.51.1,!=1.51.2,!=1.51.3 sip==6.5.1 diff --git a/.run_templates/pycharm_cura_run.run.xml.jinja b/.run_templates/pycharm_cura_run.run.xml.jinja new file mode 100644 index 0000000000..3c04c5eaef --- /dev/null +++ b/.run_templates/pycharm_cura_run.run.xml.jinja @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/.run_templates/pycharm_cura_test.run.xml.jinja b/.run_templates/pycharm_cura_test.run.xml.jinja new file mode 100644 index 0000000000..428876ee52 --- /dev/null +++ b/.run_templates/pycharm_cura_test.run.xml.jinja @@ -0,0 +1,23 @@ + + + + + diff --git a/conandata.yml b/conandata.yml index 7db6e9a28d..4b9d8dd612 100644 --- a/conandata.yml +++ b/conandata.yml @@ -20,6 +20,9 @@ - "fdm_materials/(latest)@ultimaker/testing" - "cura_binary_data/(latest)@ultimaker/testing" - "cpython/3.10.4" + internal_requirements: + - "fdm_materials_private/(latest)@ultimaker/testing" + - "cura_private_data/(latest)@ultimaker/testing" runinfo: entrypoint: "cura_app.py" pyinstaller: @@ -32,6 +35,11 @@ package: "cura" src: "resources" dst: "share/cura/resources" + cura_private_data: + package: "cura_private_data" + src: "resources" + dst: "share/cura/resources" + internal: true uranium_plugins: package: "uranium" src: "plugins" @@ -60,6 +68,11 @@ package: "fdm_materials" src: "materials" dst: "share/cura/resources/materials" + fdm_materials_private: + package: "fdm_materials_private" + src: "resources/materials" + dst: "share/cura/resources/materials" + internal: true tcl: package: "tcl" src: "lib/tcl8.6" @@ -112,6 +125,9 @@ - "fdm_materials/(latest)@ultimaker/testing" - "cura_binary_data/(latest)@ultimaker/testing" - "cpython/3.10.4" + internal_requirements: + - "fdm_materials_private/(latest)@ultimaker/testing" + - "cura_private_data/(latest)@ultimaker/testing" runinfo: entrypoint: "cura_app.py" pyinstaller: @@ -124,6 +140,11 @@ package: "cura" src: "resources" dst: "share/cura/resources" + cura_private_data: + package: "cura_private_data" + src: "resources" + dst: "share/cura/resources" + internal: true uranium_plugins: package: "uranium" src: "plugins" @@ -152,6 +173,11 @@ package: "fdm_materials" src: "materials" dst: "share/cura/resources/materials" + fdm_materials_private: + package: "fdm_materials_private" + src: "resources/materials" + dst: "share/cura/resources/materials" + internal: true tcl: package: "tcl" src: "lib/tcl8.6" @@ -286,3 +312,113 @@ Windows: "./icons/Cura.ico" Macos: "./icons/cura.icns" Linux: "./icons/cura-128.png" +pycharm_targets: + - jinja_path: .run_templates/pycharm_cura_run.run.xml.jinja + module_name: Cura + name: cura + script_name: cura_app.py + - jinja_path: .run_templates/pycharm_cura_run.run.xml.jinja + module_name: Cura + name: cura_external_engine + parameters: --external-backend + script_name: cura_app.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in tests + script_name: tests/ + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestBuildVolume.py + script_name: tests/TestBuildVolume.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestConvexHullDecorator.py + script_name: tests/TestConvexHullDecorator.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestCuraSceneNode.py + script_name: tests/TestCuraSceneNode.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestCuraSceneNode.py + script_name: tests/TestExtruderManager.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestGCodeListDecorator.py + script_name: tests/TestGCodeListDecorator.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestIntentManager.py + script_name: tests/TestIntentManager.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestLayer.py + script_name: tests/TestLayer.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestMachineAction.py + script_name: tests/TestMachineAction.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestMachineManager.py + script_name: tests/TestMachineManager.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestOAuth2.py + script_name: tests/TestOAuth2.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestObjectsModel.py + script_name: tests/TestObjectsModel.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestPrintInformation.py + script_name: tests/TestPrintInformation.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestProfileRequirements.py + script_name: tests/TestProfileRequirements.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestThemes.py + script_name: tests/TestThemes.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestContainerManager.py + script_name: tests/Settings/TestContainerManager.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestCuraContainerRegistry.py + script_name: tests/Settings/TestCuraContainerRegistry.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestCuraStackBuilder.py + script_name: tests/Settings/TestCuraStackBuilder.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestDefinitionContainer.py + script_name: tests/Settings/TestDefinitionContainer.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestExtruderStack.py + script_name: tests/Settings/TestExtruderStack.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestGlobalStack.py + script_name: tests/Settings/TestGlobalStack.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestProfiles.py + script_name: tests/Settings/TestProfiles.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestSettingInheritanceManager.py + script_name: tests/Settings/TestSettingInheritanceManager.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestSettingOverrideDecorator.py + script_name: tests/Settings/TestSettingOverrideDecorator.py + - jinja_path: .run_templates/pycharm_cura_test.run.xml.jinja + module_name: Cura + name: pytest in TestSettingVisibilityPresets.py + script_name: tests/Settings/TestSettingVisibilityPresets.py diff --git a/conanfile.py b/conanfile.py index c59a22eef2..1250683926 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,11 +1,6 @@ import os -import sys from pathlib import Path -from io import StringIO - -from platform import python_version - from jinja2 import Template from conans import tools @@ -14,7 +9,7 @@ from conan.tools import files from conan.tools.env import VirtualRunEnv, Environment from conan.errors import ConanInvalidConfiguration -required_conan_version = ">=1.47.0" +required_conan_version = ">=1.48.0" class CuraConan(ConanFile): @@ -40,7 +35,8 @@ class CuraConan(ConanFile): "devtools": [True, False], # FIXME: Split this up in testing and (development / build (pyinstaller) / system installer) tools "cloud_api_version": "ANY", "display_name": "ANY", # TODO: should this be an option?? - "cura_debug_mode": [True, False] # FIXME: Use profiles + "cura_debug_mode": [True, False], # FIXME: Use profiles + "internal": [True, False] } default_options = { "enterprise": "False", @@ -48,7 +44,8 @@ class CuraConan(ConanFile): "devtools": False, "cloud_api_version": "1", "display_name": "Ultimaker Cura", - "cura_debug_mode": False # Not yet implemented + "cura_debug_mode": False, # Not yet implemented + "internal": False, } scm = { "type": "git", @@ -57,18 +54,9 @@ class CuraConan(ConanFile): "revision": "auto" } - # TODO: Add unit tests (but they need a different jinja template - _pycharm_targets = [{ - "name": "cura", - "module_name": "Cura", - "script_name": "cura_app.py", - }, { - "name": "cura_external_engine", - "module_name": "Cura", - "script_name": "cura_app.py", - "parameters": "--external-backend" - } - ] + @property + def _pycharm_targets(self): + return self.conan_data["pycharm_targets"] # FIXME: These env vars should be defined in the runenv. _cura_env = None @@ -157,11 +145,16 @@ class CuraConan(ConanFile): with open(Path(__file__).parent.joinpath("CuraVersion.py.jinja"), "r") as f: cura_version_py = Template(f.read()) + cura_version = self.version + if self.options.internal: + version = tools.Version(self.version) + cura_version = f"{version.major}.{version.minor}.{version.patch}-{version.prerelease.replace('+', '+internal_')}" + with open(Path(location, "CuraVersion.py"), "w") as f: f.write(cura_version_py.render( cura_app_name = self.name, cura_app_display_name = self.options.display_name, - cura_version = self.version, + cura_version = cura_version, cura_build_type = "Enterprise" if self._enterprise else "", cura_debug_mode = self.options.cura_debug_mode, cura_cloud_api_root = self._cloud_api_root, @@ -174,6 +167,9 @@ class CuraConan(ConanFile): pyinstaller_metadata = self._um_data()["pyinstaller"] datas = [(str(self._base_dir.joinpath("conan_install_info.json")), ".")] for data in pyinstaller_metadata["datas"].values(): + if not self.options.internal and data.get("internal", False): + continue + if "package" in data: # get the paths from conan package if data["package"] == self.name: if self.in_local_cache: @@ -255,6 +251,9 @@ class CuraConan(ConanFile): def requirements(self): for req in self._um_data()["requirements"]: self.requires(req) + if self.options.internal: + for req in self._um_data()["internal_requirements"]: + self.requires(req) def layout(self): self.folders.source = "." @@ -293,11 +292,17 @@ class CuraConan(ConanFile): self.copy("*.fdm_material", root_package = "fdm_materials", src = "@resdirs", dst = "resources/materials", keep_path = False) self.copy("*.sig", root_package = "fdm_materials", src = "@resdirs", dst = "resources/materials", keep_path = False) + if self.options.internal: + self.copy("*.fdm_material", root_package = "fdm_materials_private", src = "@resdirs", dst = "resources/materials", keep_path = False) + self.copy("*.sig", root_package = "fdm_materials_private", src = "@resdirs", dst = "resources/materials", keep_path = False) + self.copy("*", root_package = "cura_private_data", src = self.deps_cpp_info["cura_private_data"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources"), keep_path = True) + # Copy resources of cura_binary_data self.copy("*", root_package = "cura_binary_data", src = self.deps_cpp_info["cura_binary_data"].resdirs[0], - dst = "venv/share/cura", keep_path = True) + dst = self._share_dir.joinpath("cura", "resources"), keep_path = True) self.copy("*", root_package = "cura_binary_data", src = self.deps_cpp_info["cura_binary_data"].resdirs[1], - dst = "venv/share/uranium", keep_path = True) + dst =self._share_dir.joinpath("uranium", "resources"), keep_path = True) self.copy("*.dll", src = "@bindirs", dst = self._site_packages) self.copy("*.pyd", src = "@libdirs", dst = self._site_packages) @@ -325,6 +330,15 @@ class CuraConan(ConanFile): self.copy_deps("*.sig", root_package = "fdm_materials", src = self.deps_cpp_info["fdm_materials"].resdirs[0], dst = self._share_dir.joinpath("cura", "resources", "materials"), keep_path = False) + # Copy internal resources + if self.options.internal: + self.copy_deps("*.fdm_material", root_package = "fdm_materials_private", src = self.deps_cpp_info["fdm_materials_private"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources", "materials"), keep_path = False) + self.copy_deps("*.sig", root_package = "fdm_materials_private", src = self.deps_cpp_info["fdm_materials_private"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources", "materials"), keep_path = False) + self.copy_deps("*", root_package = "cura_private_data", src = self.deps_cpp_info["cura_private_data"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources"), keep_path = True) + # Copy resources of Uranium (keep folder structure) self.copy_deps("*", root_package = "uranium", src = self.deps_cpp_info["uranium"].resdirs[0], dst = self._share_dir.joinpath("uranium", "resources"), keep_path = True) diff --git a/cura/Arranging/ShapeArray.py b/cura/Arranging/ShapeArray.py index 5607c03663..714d9d3837 100644 --- a/cura/Arranging/ShapeArray.py +++ b/cura/Arranging/ShapeArray.py @@ -74,14 +74,14 @@ class ShapeArray: # If the child-nodes are included, adjust convex hulls as well: if include_children: children = node.getAllChildren() - if not children is None: + if children is not None: for child in children: # 'Inefficient' combination of convex hulls through known code rather than mess it up: child_hull = child.callDecoration("getConvexHull") - if not child_hull is None: + if child_hull is not None: hull_verts = hull_verts.unionConvexHulls(child_hull) child_hull_head = child.callDecoration("getConvexHullHead") or child_hull - if not child_hull_head is None: + if child_hull_head is not None: hull_head_verts = hull_head_verts.unionConvexHulls(child_hull_head) offset_verts = hull_head_verts.getMinkowskiHull(Polygon.approximatedCircle(min_offset)) @@ -159,4 +159,4 @@ class ShapeArray: max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1] sign = numpy.sign(p2[0] - p1[0]) - return idxs[1] * sign <= max_col_idx * sign \ No newline at end of file + return idxs[1] * sign <= max_col_idx * sign diff --git a/docs/repositories.md b/docs/repositories.md index 3b4c4bc317..0d882c44b2 100644 --- a/docs/repositories.md +++ b/docs/repositories.md @@ -1,21 +1,33 @@ Repositories ==== Cura uses a number of repositories where parts of our source code are separated, in order to get a cleaner architecture. Those repositories are: -* [Cura](https://github.com/Ultimaker/Cura), the main repository for the front-end of Cura. This contains all of the business logic for the front-end, including the specific types of profiles that are available, the concept of 3D printers and materials, specific tools for handling 3D printed models, pretty much all of the GUI, as well as Ultimaker services such as the Marketplace and accounts. -* The Cura repository is built on [Uranium](https://github.com/Ultimaker/Uranium), a framework for desktop applications that handle 3D models and have a separate back-end. This provides Cura with a basic GUI framework ([Qt](https://www.qt.io/)), a 3D scene, a rendering system, a plug-in system and a system for stacked profiles that change settings. -* In order to slice, Cura starts [CuraEngine](https://github.com/Ultimaker/CuraEngine) in the background. This does the actual process that converts 3D models into a toolpath for the printer. -* Communication to CuraEngine goes via [libArcus](https://github.com/Ultimaker/libArcus), a small library that wraps around [Protobuf](https://developers.google.com/protocol-buffers/) in order to make it run over a local socket. -* Cura's build scripts are in [cura-build](https://github.com/Ultimaker/cura-build) and build scripts for building dependencies are in [cura-build-environment](https://github.com/Ultimaker/cura-build-environment). +* [Cura](https://github.com/Ultimaker/Cura) is the main repository for the front-end of Cura. This contains: + - all of the business logic for the front-end, including the specific types of profiles that are available + - the concept of 3D printers and materials + - specific tools for handling 3D printed models + - pretty much all of the GUI + - Ultimaker services such as the Marketplace and accounts. +* [Uranium](https://github.com/Ultimaker/Uranium) is the underlying framework the Cura repository is built on. [Uranium](https://github.com/Ultimaker/Uranium) is a framework for desktop applications that handle 3D models. It has a separate back-end. This provides Cura with: + - a basic GUI framework ([Qt](https://www.qt.io/)) + - a 3D scene, a rendering system + - a plug-in system + - a system for stacked profiles that change settings. +* [CuraEngine](https://github.com/Ultimaker/CuraEngine) is the slicer used by Cura in the background. This does the actual process that converts 3D models into a toolpath for the printer. +* [libArcus](https://github.com/Ultimaker/libArcus) handles the communication to CuraEngine. [libArcus](https://github.com/Ultimaker/libArcus) is a small library that wraps around [Protobuf](https://developers.google.com/protocol-buffers/) in order to make it run over a local socket. +* [cura-build](https://github.com/Ultimaker/cura-build): Cura's build scripts. +* [cura-build-environment](https://github.com/Ultimaker/cura-build-environment) build scripts for building dependencies. There are also a number of repositories under our control that are not integral parts of Cura's architecture, but more like separated side-gigs: -* Loading and writing 3MF files is done through [libSavitar](https://github.com/Ultimaker/libSavitar). -* Loading and writing UFP files is done through [libCharon](https://github.com/Ultimaker/libCharon). -* To make the build system a bit simpler, some parts are pre-compiled in [cura-binary-data](https://github.com/Ultimaker/cura-binary-data). This holds things like the machine-readable translation files and the Marlin builds for firmware updates, which would require considerable tooling to build automatically. -* There are automated GUI tests in [Cura-squish-tests](https://github.com/Ultimaker/Cura-squish-tests). -* Material profiles are stored in [fdm_materials](https://github.com/Ultimaker/fdm_materials). This is separated out and combined in our build process, so that the firmware for Ultimaker's printers can use the same set of profiles too. +* [libSavitar](https://github.com/Ultimaker/libSavitar) is used for loading and writing 3MF files. +* [libCharon](https://github.com/Ultimaker/libCharon) is used for loading and writing UFP files. +* [cura-binary-data](https://github.com/Ultimaker/cura-binary-data) pre-compiled parts to make the build system a bit simpler. This holds things which would require considerable tooling to build automatically like: + - the machine-readable translation files + - the Marlin builds for firmware updates +* [Cura-squish-tests](https://github.com/Ultimaker/Cura-squish-tests): automated GUI tests. +* [fdm_materials](https://github.com/Ultimaker/fdm_materials) stores Material profiles. This is separated out and combined in our build process, so that the firmware for Ultimaker's printers can use the same set of profiles too. Interplay ---- At a very high level, Cura's repositories interconnect as follows: -![Overview of interplay between repositories](resources/repositories.svg) \ No newline at end of file +![Overview of interplay between repositories](resources/repositories.svg) diff --git a/plugins/PostProcessingPlugin/scripts/Stretch.py b/plugins/PostProcessingPlugin/scripts/Stretch.py index 924563d305..8d35f68822 100644 --- a/plugins/PostProcessingPlugin/scripts/Stretch.py +++ b/plugins/PostProcessingPlugin/scripts/Stretch.py @@ -432,7 +432,7 @@ class Stretcher: """ dist_palp = self.line_width # Palpation distance to seek for a wall mrot = np.array([[0, -1], [1, 0]]) # Rotation matrix for a quarter turn - for i in range(len(orig_seq)): + for i, _ in enumerate(orig_seq): ibeg = i # Index of the first point of the segment iend = i + 1 # Index of the last point of the segment if iend == len(orig_seq): diff --git a/plugins/X3DReader/X3DReader.py b/plugins/X3DReader/X3DReader.py index 548c9f44e6..0b41578a05 100644 --- a/plugins/X3DReader/X3DReader.py +++ b/plugins/X3DReader/X3DReader.py @@ -134,7 +134,7 @@ class X3DReader(MeshReader): geometry = self.resolveDefUse(sub_node) # TODO: appearance is completely ignored. At least apply the material color... - if not geometry is None: + if geometry is not None: try: self.verts = self.faces = [] # Safeguard self.geometry_importers[geometry.tag](self, geometry) @@ -493,12 +493,12 @@ class X3DReader(MeshReader): # Columns are the unit vectors for the xz plane for the cross-section if orient: mrot = orient[i] if len(orient) > 1 else orient[0] - if not mrot is None: + if mrot is not None: m = m.dot(mrot) # Tested against X3DOM, the result matches, still not sure :( if scale: mscale = scale[i] if len(scale) > 1 else scale[0] - if not mscale is None: + if mscale is not None: m = m.dot(mscale) # First the cross-section 2-vector is scaled, @@ -703,7 +703,7 @@ class X3DReader(MeshReader): for c in node: if c.tag == "Coordinate": c = self.resolveDefUse(c) - if not c is None: + if c is not None: pt = c.attrib.get("point") if pt: # allow the list of float values in 'point' attribute to diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index bb3b0cdbec..0317cb7814 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -51,7 +51,17 @@ Item { target: infillSlider property: "value" - value: parseInt(infillDensity.properties.value) + value: { + // The infill slider has a max value of 100. When it is given a value > 100 onValueChanged updates the setting to be 100. + // When changing to an intent with infillDensity > 100, it would always be clamped to 100. + // This will force the slider to ignore the first onValueChanged for values > 100 so higher values can be set. + var density = parseInt(infillDensity.properties.value) + if (density > 100) { + infillSlider.ignoreValueChange = true + } + + return density + } } // Here are the elements that are shown in the left column @@ -84,6 +94,8 @@ Item { id: infillSlider + property var ignoreValueChange: false + width: parent.width height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider @@ -157,7 +169,13 @@ Item target: infillSlider function onValueChanged() { - // Don't round the value if it's already the same + if (infillSlider.ignoreValueChange) + { + infillSlider.ignoreValueChange = false + return + } + + // Don't update if the setting value, if the slider has the same value if (parseInt(infillDensity.properties.value) == infillSlider.value) { return