mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-17 08:56:41 +08:00
Merge remote-tracking branch 'origin/main' into CURA-11137_update_pyqt6
This commit is contained in:
commit
0aa7e74fe5
@ -179,6 +179,7 @@ class CuraApplication(QtApplication):
|
|||||||
self._use_single_instance = False
|
self._use_single_instance = False
|
||||||
|
|
||||||
self._single_instance = None
|
self._single_instance = None
|
||||||
|
self._open_project_mode: Optional[str] = None
|
||||||
|
|
||||||
self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions]
|
self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions]
|
||||||
|
|
||||||
@ -1845,7 +1846,7 @@ class CuraApplication(QtApplication):
|
|||||||
Logger.log("i", "Attempting to read file %s", file.toString())
|
Logger.log("i", "Attempting to read file %s", file.toString())
|
||||||
if not file.isValid():
|
if not file.isValid():
|
||||||
return
|
return
|
||||||
|
self._open_project_mode = project_mode
|
||||||
scene = self.getController().getScene()
|
scene = self.getController().getScene()
|
||||||
|
|
||||||
for node in DepthFirstIterator(scene.getRoot()):
|
for node in DepthFirstIterator(scene.getRoot()):
|
||||||
@ -1855,16 +1856,16 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
is_project_file = self.checkIsValidProjectFile(file)
|
is_project_file = self.checkIsValidProjectFile(file)
|
||||||
|
|
||||||
if project_mode is None:
|
if self._open_project_mode is None:
|
||||||
project_mode = self.getPreferences().getValue("cura/choice_on_open_project")
|
self._open_project_mode = self.getPreferences().getValue("cura/choice_on_open_project")
|
||||||
|
|
||||||
if is_project_file and project_mode == "open_as_project":
|
if is_project_file and self._open_project_mode == "open_as_project":
|
||||||
# open as project immediately without presenting a dialog
|
# open as project immediately without presenting a dialog
|
||||||
workspace_handler = self.getWorkspaceFileHandler()
|
workspace_handler = self.getWorkspaceFileHandler()
|
||||||
workspace_handler.readLocalFile(file, add_to_recent_files_hint = add_to_recent_files)
|
workspace_handler.readLocalFile(file, add_to_recent_files_hint = add_to_recent_files)
|
||||||
return
|
return
|
||||||
|
|
||||||
if is_project_file and project_mode == "always_ask":
|
if is_project_file and self._open_project_mode == "always_ask":
|
||||||
# present a dialog asking to open as project or import models
|
# present a dialog asking to open as project or import models
|
||||||
self.callLater(self.openProjectFile.emit, file, add_to_recent_files)
|
self.callLater(self.openProjectFile.emit, file, add_to_recent_files)
|
||||||
return
|
return
|
||||||
@ -1999,8 +2000,11 @@ class CuraApplication(QtApplication):
|
|||||||
center_y = 0
|
center_y = 0
|
||||||
|
|
||||||
node.translate(Vector(0, center_y, 0))
|
node.translate(Vector(0, center_y, 0))
|
||||||
|
|
||||||
nodes_to_arrange.append(node)
|
nodes_to_arrange.append(node)
|
||||||
|
# If the file is a project,and models are to be loaded from a that project,
|
||||||
|
# models inside file should be arranged in buildplate.
|
||||||
|
elif self._open_project_mode == "open_as_model":
|
||||||
|
nodes_to_arrange.append(node)
|
||||||
|
|
||||||
# This node is deep copied from some other node which already has a BuildPlateDecorator, but the deepcopy
|
# This node is deep copied from some other node which already has a BuildPlateDecorator, but the deepcopy
|
||||||
# of BuildPlateDecorator produces one that's associated with build plate -1. So, here we need to check if
|
# of BuildPlateDecorator produces one that's associated with build plate -1. So, here we need to check if
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# Copyright (c) 2019 Ultimaker B.V.
|
# Copyright (c) 2019 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
import math
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
from typing import Optional, cast
|
from typing import Optional, cast
|
||||||
@ -186,6 +187,11 @@ class LayerPolygon:
|
|||||||
def types(self):
|
def types(self):
|
||||||
return self._types
|
return self._types
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lineLengths(self):
|
||||||
|
data_array = numpy.array(self._data)
|
||||||
|
return numpy.linalg.norm(data_array[1:] - data_array[:-1], axis=1)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
return self._data
|
return self._data
|
||||||
|
@ -49,7 +49,7 @@ class Snapshot:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if node is None:
|
if node is None:
|
||||||
root = Application.getInstance().getController().getScene().getRoot()
|
node = Application.getInstance().getController().getScene().getRoot()
|
||||||
|
|
||||||
# the direction the camera is looking at to create the isometric view
|
# the direction the camera is looking at to create the isometric view
|
||||||
iso_view_dir = Vector(-1, -1, -1).normalized()
|
iso_view_dir = Vector(-1, -1, -1).normalized()
|
||||||
|
@ -78,6 +78,8 @@ class SimulationView(CuraView):
|
|||||||
self._minimum_path_num = 0
|
self._minimum_path_num = 0
|
||||||
self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged)
|
self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged)
|
||||||
|
|
||||||
|
self._current_feedrates = {}
|
||||||
|
self._lengths_of_polyline ={}
|
||||||
self._busy = False
|
self._busy = False
|
||||||
self._simulation_running = False
|
self._simulation_running = False
|
||||||
|
|
||||||
@ -400,6 +402,15 @@ class SimulationView(CuraView):
|
|||||||
def getMaxFeedrate(self) -> float:
|
def getMaxFeedrate(self) -> float:
|
||||||
return self._max_feedrate
|
return self._max_feedrate
|
||||||
|
|
||||||
|
def getSimulationTime(self, currentIndex) -> float:
|
||||||
|
try:
|
||||||
|
return (self._lengths_of_polyline[self._current_layer_num][currentIndex] / self._current_feedrates[self._current_layer_num][currentIndex])[0]
|
||||||
|
|
||||||
|
except:
|
||||||
|
# In case of change in layers, currentIndex comes one more than the items in the lengths_of_polyline
|
||||||
|
# We give 1 second time for layer change
|
||||||
|
return 1.0
|
||||||
|
|
||||||
def getMinThickness(self) -> float:
|
def getMinThickness(self) -> float:
|
||||||
if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding.
|
if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding.
|
||||||
return 0.0 # If it's still max-float, there are no measurements. Use 0 then.
|
return 0.0 # If it's still max-float, there are no measurements. Use 0 then.
|
||||||
@ -524,8 +535,10 @@ class SimulationView(CuraView):
|
|||||||
visible_indicies_with_extrusion = numpy.where(numpy.isin(polyline.types, visible_line_types_with_extrusion))[0]
|
visible_indicies_with_extrusion = numpy.where(numpy.isin(polyline.types, visible_line_types_with_extrusion))[0]
|
||||||
if visible_indices.size == 0: # No items to take maximum or minimum of.
|
if visible_indices.size == 0: # No items to take maximum or minimum of.
|
||||||
continue
|
continue
|
||||||
|
self._lengths_of_polyline[layer_index] = polyline.lineLengths
|
||||||
visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices)
|
visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices)
|
||||||
visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion)
|
visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion)
|
||||||
|
self._current_feedrates[layer_index] = polyline.lineFeedrates
|
||||||
visible_linewidths = numpy.take(polyline.lineWidths, visible_indices)
|
visible_linewidths = numpy.take(polyline.lineWidths, visible_indices)
|
||||||
visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion)
|
visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion)
|
||||||
visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices)
|
visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices)
|
||||||
|
@ -136,7 +136,7 @@ Item
|
|||||||
Timer
|
Timer
|
||||||
{
|
{
|
||||||
id: simulationTimer
|
id: simulationTimer
|
||||||
interval: 100
|
interval: UM.SimulationView.simulationTime
|
||||||
running: false
|
running: false
|
||||||
repeat: true
|
repeat: true
|
||||||
onTriggered:
|
onTriggered:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import numpy
|
||||||
from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty
|
from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
@ -11,6 +12,11 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class SimulationViewProxy(QObject):
|
class SimulationViewProxy(QObject):
|
||||||
|
|
||||||
|
S_TO_MS = 1000
|
||||||
|
SPEED_OF_SIMULATION = 10
|
||||||
|
FACTOR = S_TO_MS/SPEED_OF_SIMULATION
|
||||||
|
|
||||||
def __init__(self, simulation_view: "SimulationView", parent=None) -> None:
|
def __init__(self, simulation_view: "SimulationView", parent=None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._simulation_view = simulation_view
|
self._simulation_view = simulation_view
|
||||||
@ -54,6 +60,14 @@ class SimulationViewProxy(QObject):
|
|||||||
def currentPath(self):
|
def currentPath(self):
|
||||||
return self._simulation_view.getCurrentPath()
|
return self._simulation_view.getCurrentPath()
|
||||||
|
|
||||||
|
@pyqtProperty(int, notify=currentPathChanged)
|
||||||
|
def simulationTime(self):
|
||||||
|
# Extracts the currents paths simulation time (in seconds) for the current path from the dict of simulation time of the current layer.
|
||||||
|
# We multiply the time with 100 to make it to ms from s.(Should be 1000 in real time). This scaling makes the simulation time 10x faster than the real time.
|
||||||
|
simulationTimeOfpath = self._simulation_view.getSimulationTime(self._simulation_view.getCurrentPath()) * SimulationViewProxy.FACTOR
|
||||||
|
# Since the timer cannot process time less than 1 ms, we put a lower limit here
|
||||||
|
return int(max(1, simulationTimeOfpath))
|
||||||
|
|
||||||
@pyqtProperty(int, notify=currentPathChanged)
|
@pyqtProperty(int, notify=currentPathChanged)
|
||||||
def minimumPath(self):
|
def minimumPath(self):
|
||||||
return self._simulation_view.getMinimumPath()
|
return self._simulation_view.getMinimumPath()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user