Merging CURA-7435_3DConnexionII

This commit is contained in:
c.lamboo 2025-01-24 13:20:41 +01:00
commit 7a962216fb
318 changed files with 13486 additions and 10653 deletions

View file

@ -196,7 +196,8 @@ class DigitalFactoryApiClient:
url = "{}/projects/{}/files".format(self.CURA_API_ROOT, library_project_id)
self._http.get(url,
scope = self._scope,
callback = self._parseCallback(on_finished, DigitalFactoryFileResponse, failed),
callback=self._parseCallback(on_finished, DigitalFactoryFileResponse, failed,
default_values={'username': ''}),
error_callback = failed,
timeout = self.DEFAULT_REQUEST_TIMEOUT)
@ -205,7 +206,8 @@ class DigitalFactoryApiClient:
Callable[[List[CloudApiClientModel]], Any]],
model: Type[CloudApiClientModel],
on_error: Optional[Callable] = None,
pagination_manager: Optional[PaginationManager] = None) -> Callable[[QNetworkReply], None]:
pagination_manager: Optional[PaginationManager] = None,
default_values: Dict[str, str] = None) -> Callable[[QNetworkReply], None]:
"""
Creates a callback function so that it includes the parsing of the response into the correct model.
@ -234,7 +236,8 @@ class DigitalFactoryApiClient:
if status_code >= 300 and on_error is not None:
on_error()
else:
self._parseModels(response, on_finished, model, pagination_manager = pagination_manager)
self._parseModels(response, on_finished, model, pagination_manager=pagination_manager,
default_values=default_values)
self._anti_gc_callbacks.append(parse)
return parse
@ -262,7 +265,8 @@ class DigitalFactoryApiClient:
on_finished: Union[Callable[[CloudApiClientModel], Any],
Callable[[List[CloudApiClientModel]], Any]],
model_class: Type[CloudApiClientModel],
pagination_manager: Optional[PaginationManager] = None) -> None:
pagination_manager: Optional[PaginationManager] = None,
default_values: Dict[str, str] = None) -> None:
"""Parses the given models and calls the correct callback depending on the result.
:param response: The response from the server, after being converted to a dict.
@ -279,7 +283,10 @@ class DigitalFactoryApiClient:
if "links" in response and pagination_manager:
pagination_manager.setLinks(response["links"])
if isinstance(data, list):
results = [model_class(**c) for c in data] # type: List[CloudApiClientModel]
results = [] # type: List[CloudApiClientModel]
for model_data in data:
complete_model_data = (default_values | model_data) if default_values is not None else model_data
results.append(model_class(**complete_model_data))
on_finished_list = cast(Callable[[List[CloudApiClientModel]], Any], on_finished)
on_finished_list(results)
else:

View file

@ -298,8 +298,14 @@ class FlavorParser:
position.e.extend([0] * (self._extruder_number - len(position.e) + 1))
return position
def processMCode(self, M: int, line: str, position: Position, path: List[List[Union[float, int]]]) -> Position:
pass
def processMCode(self, M: int, line: str, position: Position, path: List[List[Union[float, int]]]) -> None:
# Set extrusion mode
if M == 82:
# Set absolute extrusion mode
self._is_absolute_extrusion = True
elif M == 83:
# Set relative extrusion mode
self._is_absolute_extrusion = False
_type_keyword = ";TYPE:"
_layer_keyword = ";LAYER:"

View file

@ -11,14 +11,6 @@ class RepRapFlavorParser(FlavorParser.FlavorParser):
def __init__(self):
super().__init__()
def processMCode(self, M, line, position, path):
if M == 82:
# Set absolute extrusion mode
self._is_absolute_extrusion = True
elif M == 83:
# Set relative extrusion mode
self._is_absolute_extrusion = False
def _gCode90(self, position, params, path):
"""Set the absolute positioning

View file

@ -214,7 +214,7 @@ Item
settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Y min")
labelText: catalog.i18nc("@label", "Y min ( '-' towards back)")
labelFont: base.labelFont
labelWidth: base.labelWidth
controlWidth: base.controlWidth
@ -254,7 +254,7 @@ Item
settingKey: "machine_head_with_fans_polygon"
settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Y max")
labelText: catalog.i18nc("@label", "Y max ( '+' towards front)")
labelFont: base.labelFont
labelWidth: base.labelWidth
controlWidth: base.controlWidth

View file

@ -250,7 +250,7 @@ class MakerbotWriter(MeshWriter):
meta["preferences"] = dict()
bounds = application.getBuildVolume().getBoundingBox()
meta["preferences"]["instance0"] = {
"machineBounds": [bounds.right, bounds.back, bounds.left, bounds.front] if bounds is not None else None,
"machineBounds": [bounds.right, bounds.front, bounds.left, bounds.back] if bounds is not None else None,
"printMode": CuraApplication.getInstance().getIntentManager().currentIntentCategory,
}

View file

@ -222,12 +222,11 @@ class SimulationView(CuraView):
self.setPath(i + fractional_value)
def advanceTime(self, time_increase: float) -> bool:
def advanceTime(self, time_increase: float) -> None:
"""
Advance the time by the given amount.
:param time_increase: The amount of time to advance (in seconds).
:return: True if the time was advanced, False if the end of the simulation was reached.
"""
total_duration = 0.0
if len(self.cumulativeLineDuration()) > 0:
@ -237,15 +236,13 @@ class SimulationView(CuraView):
# If we have reached the end of the simulation, go to the next layer.
if self.getCurrentLayer() == self.getMaxLayers():
# If we are already at the last layer, go to the first layer.
self.setTime(total_duration)
return False
# advance to the next layer, and reset the time
self.setLayer(self.getCurrentLayer() + 1)
self.setLayer(0)
else:
# advance to the next layer, and reset the time
self.setLayer(self.getCurrentLayer() + 1)
self.setTime(0.0)
else:
self.setTime(self._current_time + time_increase)
return True
def cumulativeLineDuration(self) -> List[float]:
# Make sure _cumulative_line_duration is initialized properly

View file

@ -144,9 +144,7 @@ Item
{
// divide by 1000 to account for ms to s conversion
const advance_time = simulationTimer.interval / 1000.0;
if (!UM.SimulationView.advanceTime(advance_time)) {
playButton.pauseSimulation();
}
UM.SimulationView.advanceTime(advance_time);
// The status must be set here instead of in the resumeSimulation function otherwise it won't work
// correctly, because part of the logic is in this trigger function.
isSimulationPlaying = true;

View file

@ -54,9 +54,9 @@ class SimulationViewProxy(QObject):
def currentPath(self):
return self._simulation_view.getCurrentPath()
@pyqtSlot(float, result=bool)
def advanceTime(self, duration: float) -> bool:
return self._simulation_view.advanceTime(duration)
@pyqtSlot(float)
def advanceTime(self, duration: float) -> None:
self._simulation_view.advanceTime(duration)
@pyqtProperty(int, notify=currentPathChanged)
def minimumPath(self):

View file

@ -360,8 +360,8 @@ geometry41core =
((v_prev_line_type[0] != 1) && (v_line_type[0] == 1)) ||
((v_prev_line_type[0] != 4) && (v_line_type[0] == 4))
)) {
float w = size_x;
float h = size_y;
float w = max(0.05, size_x);
float h = max(0.05, size_y);
myEmitVertex(v_vertex[0] + vec3( w, h, w), u_starts_color, normalize(vec3( 1.0, 1.0, 1.0)), viewProjectionMatrix * (gl_in[0].gl_Position + vec4( w, h, w, 0.0))); // Front-top-left
myEmitVertex(v_vertex[0] + vec3(-w, h, w), u_starts_color, normalize(vec3(-1.0, 1.0, 1.0)), viewProjectionMatrix * (gl_in[0].gl_Position + vec4(-w, h, w, 0.0))); // Front-top-right

View file

@ -1,11 +1,12 @@
# Copyright (c) 2023 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
import datetime
import json
import os
import platform
import time
from typing import Optional, Set, TYPE_CHECKING
from typing import Any, Optional, Set, TYPE_CHECKING
from PyQt6.QtCore import pyqtSlot, QObject
from PyQt6.QtNetwork import QNetworkRequest
@ -33,7 +34,18 @@ class SliceInfo(QObject, Extension):
no model files are being sent (Just a SHA256 hash of the model).
"""
info_url = "https://stats.ultimaker.com/api/cura"
info_url = "https://statistics.ultimaker.com/api/v2/cura/slice"
_adjust_flattened_names = {
"extruders_extruder": "extruders",
"extruders_settings": "extruders",
"models_model": "models",
"models_transformation_data": "models_transformation",
"print_settings_": "",
"print_times": "print_time",
"active_machine_": "",
"slice_uuid": "slice_id",
}
def __init__(self, parent = None):
QObject.__init__(self, parent)
@ -112,6 +124,27 @@ class SliceInfo(QObject, Extension):
return list(sorted(user_modified_setting_keys))
def _flattenData(self, data: Any, result: dict, current_flat_key: Optional[str] = None,
lift_list: bool = False) -> None:
if isinstance(data, dict):
for key, value in data.items():
total_flat_key = key if current_flat_key is None else f"{current_flat_key}_{key}"
self._flattenData(value, result, total_flat_key, lift_list)
elif isinstance(data, list):
for item in data:
self._flattenData(item, result, current_flat_key, True)
else:
actual_flat_key = current_flat_key.lower()
for key, value in self._adjust_flattened_names.items():
if actual_flat_key.startswith(key):
actual_flat_key = actual_flat_key.replace(key, value)
if lift_list:
if actual_flat_key not in result:
result[actual_flat_key] = []
result[actual_flat_key].append(data)
else:
result[actual_flat_key] = data
def _onWriteStarted(self, output_device):
try:
if not self._application.getPreferences().getValue("info/send_slice_info"):
@ -125,8 +158,7 @@ class SliceInfo(QObject, Extension):
global_stack = machine_manager.activeMachine
data = dict() # The data that we're going to submit.
data["time_stamp"] = time.time()
data["schema_version"] = 0
data["schema_version"] = 1000
data["cura_version"] = self._application.getVersion()
data["cura_build_type"] = ApplicationMetadata.CuraBuildType
org_id = user_profile.get("organization_id", None) if user_profile else None
@ -298,6 +330,11 @@ class SliceInfo(QObject, Extension):
"time_backend": int(round(time_backend)),
}
# Massage data into format used in the DB:
flat_data = dict()
self._flattenData(data, flat_data)
data = flat_data
# Convert data to bytes
binary_data = json.dumps(data).encode("utf-8")