Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Ultimaker/Cura
Browse files Browse the repository at this point in the history
  • Loading branch information
saumyaj3 committed Oct 2, 2023
2 parents 5709980 + 24e1cfa commit bcf77bd
Show file tree
Hide file tree
Showing 1,457 changed files with 13,878 additions and 531 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ jobs:
p12-file-base64: ${{ secrets.MACOS_CERT_INSTALLER_P12 }}
p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }}

- name: Remove private Artifactory
run: conan remote remove cura-conan-private || true

- name: Get Conan configuration
run: |
conan config install https://github.com/Ultimaker/conan-config.git
Expand All @@ -155,7 +158,7 @@ jobs:
run: conan install $CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$ENTERPRISE -o cura:staging=$STAGING --json "cura_inst/conan_install_info.json"

- name: Upload the Package(s)
if: always()
if: ${{ inputs.operating_system != 'self-hosted' }}
run: |
conan upload "*" -r cura --all -c
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,5 @@ Ultimaker-Cura.spec
/resources/qml/Dialogs/AboutDialogVersionsList.qml
/plugins/CuraEngineGradualFlow
/resources/bundled_packages/bundled_*.json
curaengine_plugin_gradual_flow
curaengine_plugin_gradual_flow.exe
1 change: 1 addition & 0 deletions .printer-linter
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ checks:
diagnostic-mesh-file-extension: true
diagnostic-mesh-file-size: true
diagnostic-definition-redundant-override: true
diagnostic-resources-macos-app-directory-name: true
fixes:
diagnostic-definition-redundant-override: true
format:
Expand Down
5 changes: 5 additions & 0 deletions conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ pyinstaller:
src: "bin"
dst: "."
binary: "CuraEngine"
curaengine_gradual_flow_plugin_service:
package: "curaengine_plugin_gradual_flow"
src: "bin"
dst: "."
binary: "curaengine_plugin_gradual_flow"
hiddenimports:
- "pySavitar"
- "pyArcus"
Expand Down
8 changes: 3 additions & 5 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class CuraConan(ConanFile):

def set_version(self):
if not self.version:
self.version = "5.5.0-alpha"
self.version = "5.5.0-beta.1"

@property
def _pycharm_targets(self):
Expand Down Expand Up @@ -357,10 +357,8 @@ def generate(self):
# Copy the external plugins that we want to bundle with Cura
rmdir(self,str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")))
curaengine_plugin_gradual_flow = self.dependencies["curaengine_plugin_gradual_flow"].cpp_info
copy(self, "*.py", curaengine_plugin_gradual_flow.resdirs[0], str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")), keep_path = True)
ext = ".exe" if self.settings.os == "Windows" else ""
copy(self, f"curaengine_plugin_gradual_flow{ext}", curaengine_plugin_gradual_flow.resdirs[0], str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")), keep_path = True)
copy(self, "*.json", curaengine_plugin_gradual_flow.resdirs[0], str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")), keep_path = True)
copy(self, "*", curaengine_plugin_gradual_flow.resdirs[0], str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")), keep_path = True)
copy(self, "*", curaengine_plugin_gradual_flow.bindirs[0], self.source_folder, keep_path = False)
copy(self, "bundled_*.json", curaengine_plugin_gradual_flow.resdirs[1], str(self.source_path.joinpath("resources", "bundled_packages")), keep_path = False)

# Copy resources of cura_binary_data
Expand Down
34 changes: 29 additions & 5 deletions cura/BackendPlugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copyright (c) 2023 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import socket
import os
import subprocess
from typing import Optional, List

Expand All @@ -9,6 +11,7 @@
from UM.PluginObject import PluginObject
from UM.i18n import i18nCatalog
from UM.Platform import Platform
from UM.Resources import Resources


class BackendPlugin(AdditionalSettingDefinitionsAppender, PluginObject):
Expand Down Expand Up @@ -42,6 +45,15 @@ def getPort(self) -> int:
def getAddress(self) -> str:
return self._plugin_address

def setAvailablePort(self) -> None:
"""
Sets the port to a random available port.
"""
sock = socket.socket()
sock.bind((self.getAddress(), 0))
port = sock.getsockname()[1]
self.setPort(port)

def _validatePluginCommand(self) -> list[str]:
"""
Validate the plugin command and add the port parameter if it is missing.
Expand All @@ -61,14 +73,26 @@ def start(self) -> bool:
"""
if not self.usePlugin():
return False
Logger.info(f"Starting backend_plugin [{self._plugin_id}] with command: {self._validatePluginCommand()}")
plugin_log_path = os.path.join(Resources.getDataStoragePath(), f"{self.getPluginId()}.log")
if os.path.exists(plugin_log_path):
try:
os.remove(plugin_log_path)
except:
pass # removing is only done such that it doesn't grow out of proportions, if it fails once or twice that is okay
Logger.info(f"Logging plugin output to: {plugin_log_path}")
try:
# STDIN needs to be None because we provide no input, but communicate via a local socket instead.
# The NUL device sometimes doesn't exist on some computers.
Logger.info(f"Starting backend_plugin [{self._plugin_id}] with command: {self._validatePluginCommand()}")
popen_kwargs = {"stdin": None}
if Platform.isWindows():
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
self._process = subprocess.Popen(self._validatePluginCommand(), **popen_kwargs)
with open(plugin_log_path, 'a') as f:
popen_kwargs = {
"stdin": None,
"stdout": f, # Redirect output to file
"stderr": subprocess.STDOUT, # Combine stderr and stdout
}
if Platform.isWindows():
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
self._process = subprocess.Popen(self._validatePluginCommand(), **popen_kwargs)
self._is_running = True
return True
except PermissionError:
Expand Down
2 changes: 1 addition & 1 deletion cura/PlatformPhysics.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def _onChangeTimerFinished(self):
move_vector = move_vector.set(y = -bbox.bottom + z_offset)

# If there is no convex hull for the node, start calculating it and continue.
if not node.getDecorator(ConvexHullDecorator) and not node.callDecoration("isNonPrintingMesh"):
if not node.getDecorator(ConvexHullDecorator) and not node.callDecoration("isNonPrintingMesh") and node.callDecoration("getLayerData") is None:
node.addDecorator(ConvexHullDecorator())

# only push away objects if this node is a printing mesh
Expand Down
1 change: 1 addition & 0 deletions cura/Settings/cura_empty_instance_containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
empty_material_container.setMetaDataEntry("base_file", "empty_material")
empty_material_container.setMetaDataEntry("GUID", "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")
empty_material_container.setMetaDataEntry("material", "empty")
empty_material_container.setMetaDataEntry("brand", "empty_brand")

# Empty quality
EMPTY_QUALITY_CONTAINER_ID = "empty_quality"
Expand Down
4 changes: 1 addition & 3 deletions plugins/CuraEngineBackend/CuraEngineBackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ def __init__(self) -> None:
os.path.join(CuraApplication.getInstallPrefix(), "bin"),
os.path.dirname(os.path.abspath(sys.executable)),
]
self._last_backend_plugin_port = self._port + 1000
for path in search_path:
engine_path = os.path.join(path, executable_name)
if os.path.isfile(engine_path):
Expand Down Expand Up @@ -205,8 +204,7 @@ def startPlugins(self) -> None:
for backend_plugin in backend_plugins:
# Set the port to prevent plugins from using the same one.
if backend_plugin.getPort() < 1:
backend_plugin.setPort(self._last_backend_plugin_port)
self._last_backend_plugin_port += 1
backend_plugin.setAvailablePort()
backend_plugin.start()

def stopPlugins(self) -> None:
Expand Down
7 changes: 0 additions & 7 deletions plugins/USBPrinting/AutoDetectBaudJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,7 @@ def run(self) -> None:
write_timeout = 3
read_timeout = 3
tries = 2

programmer = Stk500v2()
serial = None
try:
programmer.connect(self._serial_port)
serial = programmer.leaveISP()
except ispBase.IspError:
programmer.close()

for retry in range(tries):
for baud_rate in self._all_baud_rates:
Expand Down
2 changes: 1 addition & 1 deletion printer-linter/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "printerlinter"
description = "Cura UltiMaker printer linting tool"
version = "0.1.0"
version = "0.1.1"
authors = [
{ name = "UltiMaker", email = "[email protected]" }
]
Expand Down
13 changes: 7 additions & 6 deletions printer-linter/src/printerlinter/factory.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
from pathlib import Path
from typing import Optional
from typing import Optional, List

from .linters.profile import Profile
from .linters.defintion import Definition
from .linters.linter import Linter
from .linters.meshes import Meshes
from .linters.directory import Directory


def getLinter(file: Path, settings: dict) -> Optional[Linter]:
def getLinter(file: Path, settings: dict) -> Optional[List[Linter]]:
""" Returns a Linter depending on the file format """
if not file.exists():
return None

if ".inst" in file.suffixes and ".cfg" in file.suffixes:
return Profile(file, settings)
return [Directory(file, settings), Profile(file, settings)]

if ".def" in file.suffixes and ".json" in file.suffixes:
if file.stem in ("fdmprinter.def", "fdmextruder.def"):
return None
return Definition(file, settings)
return [Directory(file, settings), Definition(file, settings)]

if file.parent.stem == "meshes":
return Meshes(file, settings)
return [Meshes(file, settings)]

return None
return [Directory(file, settings)]
31 changes: 31 additions & 0 deletions printer-linter/src/printerlinter/linters/directory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from pathlib import Path
from typing import Iterator

from ..diagnostic import Diagnostic
from .linter import Linter


class Directory(Linter):
def __init__(self, file: Path, settings: dict) -> None:
""" Finds issues in the parent directory"""
super().__init__(file, settings)

def check(self) -> Iterator[Diagnostic]:
if self._settings["checks"].get("diagnostic-resources-macos-app-directory-name", False):
for check in self.checkForDotInDirName():
yield check

yield

def checkForDotInDirName(self) -> Iterator[Diagnostic]:
""" Check if there is a dot in the directory name, MacOS has trouble signing and notarizing otherwise """
if any("." in p for p in self._file.parent.parts):
yield Diagnostic(
file = self._file,
diagnostic_name = "diagnostic-resources-macos-app-directory-name",
message = f"Directory name containing a `.` not allowed {self._file.suffix}, rename directory containing this file e.q: `_`",
level = "Error",
offset = 1
)
yield

10 changes: 7 additions & 3 deletions printer-linter/src/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,16 @@ def main() -> None:

def diagnoseIssuesWithFile(file: Path, settings: dict) -> List[Diagnostic]:
""" For file, runs all diagnostic checks in settings and returns a list of diagnostics """
linter = factory.getLinter(file, settings)
linters = factory.getLinter(file, settings)

if not linter:
if not linters:
return []

return list(filter(lambda d: d is not None, linter.check()))
linter_results = []
for linter in linters:
linter_results.extend(list(filter(lambda d: d is not None, linter.check())))

return linter_results


def applyFixesToFile(file, settings, full_body_check) -> None:
Expand Down
10 changes: 9 additions & 1 deletion resources/definitions/fdmprinter.def.json
Original file line number Diff line number Diff line change
Expand Up @@ -2453,7 +2453,7 @@
"material_print_temperature_layer_0":
{
"label": "Printing Temperature Initial Layer",
"description": "The temperature used for printing the first layer. Set at 0 to disable special handling of the initial layer.",
"description": "The temperature used for printing the first layer.",
"unit": "\u00b0C",
"type": "float",
"default_value": 215,
Expand Down Expand Up @@ -8125,6 +8125,14 @@
"resolve": "max(extruderValues('raft_base_wall_count'))",
"settable_per_mesh": false,
"settable_per_extruder": false
},
"group_outer_walls":
{
"label": "Group Outer Walls",
"description": "Outer walls of different islands in the same layer are printed in sequence. When enabled the amount of flow changes is limited because walls are printed one type at a time, when disabled the number of travels between islands is reduced because walls in the same islands are grouped.",
"type": "bool",
"default_value": true,
"settable_per_mesh": true
}
}
},
Expand Down
Loading

0 comments on commit bcf77bd

Please sign in to comment.