def _onActiveExtruderChanged(self): if self._active_extruder_stack: self._active_extruder_stack.propertyChanged.disconnect(self._onSettingChanged) self._active_extruder_stack.containersChanged.disconnect(self._onChanged) self._active_extruder_stack = ExtruderManager.getInstance().getActiveExtruderStack() if self._active_extruder_stack: self._active_extruder_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed. self._active_extruder_stack.containersChanged.connect(self._onChanged)
def _onActiveExtruderChanged(self): if self._active_extruder_stack: self._active_extruder_stack.propertyChanged.disconnect( self._onSettingChanged) self._active_extruder_stack.containersChanged.disconnect( self._onChanged) self._active_extruder_stack = ExtruderManager.getInstance( ).getActiveExtruderStack() if self._active_extruder_stack: self._active_extruder_stack.propertyChanged.connect( self._onSettingChanged ) # Note: Only starts slicing when the value changed. self._active_extruder_stack.containersChanged.connect( self._onChanged) self._onChanged()
def run(self): stack = Application.getInstance().getGlobalContainerStack() if not stack: self.setResult(StartJobResult.Error) return # Don't slice if there is a setting with an error value. if self._checkStackForErrors(stack): self.setResult(StartJobResult.SettingError) return # Don't slice if there is a per object setting with an error value. for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is not SceneNode or not node.isSelectable(): continue if self._checkStackForErrors(node.callDecoration("getStack")): self.setResult(StartJobResult.SettingError) return with self._scene.getSceneLock(): # Remove old layer data. for node in DepthFirstIterator(self._scene.getRoot()): if node.callDecoration("getLayerData"): node.getParent().removeChild(node) break # Get the objects in their groups to print. object_groups = [] if stack.getProperty("print_sequence", "value") == "one_at_a_time": for node in OneAtATimeIterator(self._scene.getRoot()): temp_list = [] # Node can't be printed, so don't bother sending it. if getattr(node, "_outside_buildarea", False): continue children = node.getAllChildren() children.append(node) for child_node in children: if type(child_node) is SceneNode and child_node.getMeshData() and child_node.getMeshData().getVertices() is not None: temp_list.append(child_node) if temp_list: object_groups.append(temp_list) Job.yieldThread() if len(object_groups) == 0: Logger.log("w", "No objects suitable for one at a time found, or no correct order found") else: temp_list = [] for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: if not getattr(node, "_outside_buildarea", False): temp_list.append(node) Job.yieldThread() if temp_list: object_groups.append(temp_list) if not object_groups: self.setResult(StartJobResult.NothingToSlice) return self._buildGlobalSettingsMessage(stack) for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(stack.getBottom().getId()): self._buildExtruderMessage(extruder_stack) for group in object_groups: group_message = self._slice_message.addRepeatedMessage("object_lists") if group[0].getParent().callDecoration("isGroup"): self._handlePerObjectSettings(group[0].getParent(), group_message) for object in group: mesh_data = object.getMeshData().getTransformed(object.getWorldTransformation()) obj = group_message.addRepeatedMessage("objects") obj.id = id(object) verts = numpy.array(mesh_data.getVertices()) # Convert from Y up axes to Z up axes. Equals a 90 degree rotation. verts[:, [1, 2]] = verts[:, [2, 1]] verts[:, 1] *= -1 obj.vertices = verts self._handlePerObjectSettings(object, obj) Job.yieldThread() self.setResult(StartJobResult.Finished)
def __init__(self): super().__init__() # Find out where the engine is located, and how it is called. This depends on how Cura is packaged and which OS we are running on. default_engine_location = os.path.join(Application.getInstallPrefix(), "bin", "CuraEngine") if hasattr(sys, "frozen"): default_engine_location = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), "CuraEngine") if Platform.isWindows(): default_engine_location += ".exe" default_engine_location = os.path.abspath(default_engine_location) Preferences.getInstance().addPreference("backend/location", default_engine_location) self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) # Workaround to disable layer view processing if layer view is not active. self._layer_view_active = False Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged) self._onActiveViewChanged() self._stored_layer_data = [] #Triggers for when to (re)start slicing: self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) self._onGlobalStackChanged() self._active_extruder_stack = None ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged) self._onActiveExtruderChanged() #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. #TODO: Properly group propertyChanged signals by whether they are triggered by the same user interaction. self._change_timer = QTimer() self._change_timer.setInterval(500) self._change_timer.setSingleShot(True) self._change_timer.timeout.connect(self.slice) #Listeners for receiving messages from the back-end. self._message_handlers["cura.proto.Layer"] = self._onLayerMessage self._message_handlers["cura.proto.Progress"] = self._onProgressMessage self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage self._message_handlers["cura.proto.PrintTimeMaterialEstimates"] = self._onPrintTimeMaterialEstimates #self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage self._message_handlers["cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage self._start_slice_job = None self._slicing = False #Are we currently slicing? self._restart = False #Back-end is currently restarting? self._enabled = True #Should we be slicing? Slicing might be paused when, for instance, the user is dragging the mesh around. self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness. self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers. self._error_message = None #Pop-up message that shows errors. self.backendQuit.connect(self._onBackendQuit) self.backendConnected.connect(self._onBackendConnected) #When a tool operation is in progress, don't slice. So we need to listen for tool operations. Application.getInstance().getController().toolOperationStarted.connect(self._onToolOperationStarted) Application.getInstance().getController().toolOperationStopped.connect(self._onToolOperationStopped)
def run(self): stack = Application.getInstance().getGlobalContainerStack() if not stack: self.setResult(StartJobResult.Error) return # Don't slice if there is a setting with an error value. if self._checkStackForErrors(stack): self.setResult(StartJobResult.SettingError) return # Don't slice if there is a per object setting with an error value. for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is not SceneNode or not node.isSelectable(): continue if self._checkStackForErrors(node.callDecoration("getStack")): self.setResult(StartJobResult.SettingError) return with self._scene.getSceneLock(): # Remove old layer data. for node in DepthFirstIterator(self._scene.getRoot()): if node.callDecoration("getLayerData"): node.getParent().removeChild(node) break # Get the objects in their groups to print. object_groups = [] if stack.getProperty("print_sequence", "value") == "one_at_a_time": for node in OneAtATimeIterator(self._scene.getRoot()): temp_list = [] # Node can't be printed, so don't bother sending it. if getattr(node, "_outside_buildarea", False): continue children = node.getAllChildren() children.append(node) for child_node in children: if type(child_node ) is SceneNode and child_node.getMeshData( ) and child_node.getMeshData().getVertices( ) is not None: temp_list.append(child_node) if temp_list: object_groups.append(temp_list) Job.yieldThread() if len(object_groups) == 0: Logger.log( "w", "No objects suitable for one at a time found, or no correct order found" ) else: temp_list = [] for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData( ) and node.getMeshData().getVertices() is not None: if not getattr(node, "_outside_buildarea", False): temp_list.append(node) Job.yieldThread() if temp_list: object_groups.append(temp_list) if not object_groups: self.setResult(StartJobResult.NothingToSlice) return self._buildGlobalSettingsMessage(stack) for extruder_stack in ExtruderManager.getInstance( ).getMachineExtruders(stack.getBottom().getId()): self._buildExtruderMessage(extruder_stack) for group in object_groups: group_message = self._slice_message.addRepeatedMessage( "object_lists") if group[0].getParent().callDecoration("isGroup"): self._handlePerObjectSettings(group[0].getParent(), group_message) for object in group: mesh_data = object.getMeshData().getTransformed( object.getWorldTransformation()) obj = group_message.addRepeatedMessage("objects") obj.id = id(object) verts = numpy.array(mesh_data.getVertices()) # Convert from Y up axes to Z up axes. Equals a 90 degree rotation. verts[:, [1, 2]] = verts[:, [2, 1]] verts[:, 1] *= -1 obj.vertices = verts self._handlePerObjectSettings(object, obj) Job.yieldThread() self.setResult(StartJobResult.Finished)
def __init__(self): super().__init__() # Find out where the engine is located, and how it is called. This depends on how Cura is packaged and which OS we are running on. default_engine_location = os.path.join(Application.getInstallPrefix(), "bin", "CuraEngine") if hasattr(sys, "frozen"): default_engine_location = os.path.join( os.path.dirname(os.path.abspath(sys.executable)), "CuraEngine") if Platform.isWindows(): default_engine_location += ".exe" default_engine_location = os.path.abspath(default_engine_location) Preferences.getInstance().addPreference("backend/location", default_engine_location) self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) # Workaround to disable layer view processing if layer view is not active. self._layer_view_active = False Application.getInstance().getController().activeViewChanged.connect( self._onActiveViewChanged) self._onActiveViewChanged() self._stored_layer_data = [] #Triggers for when to (re)start slicing: self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect( self._onGlobalStackChanged) self._onGlobalStackChanged() self._active_extruder_stack = None ExtruderManager.getInstance().activeExtruderChanged.connect( self._onActiveExtruderChanged) self._onActiveExtruderChanged() #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. #This timer will group them up, and only slice for the last setting changed signal. #TODO: Properly group propertyChanged signals by whether they are triggered by the same user interaction. self._change_timer = QTimer() self._change_timer.setInterval(500) self._change_timer.setSingleShot(True) self._change_timer.timeout.connect(self.slice) #Listeners for receiving messages from the back-end. self._message_handlers["cura.proto.Layer"] = self._onLayerMessage self._message_handlers["cura.proto.Progress"] = self._onProgressMessage self._message_handlers[ "cura.proto.GCodeLayer"] = self._onGCodeLayerMessage self._message_handlers[ "cura.proto.GCodePrefix"] = self._onGCodePrefixMessage self._message_handlers[ "cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage self._message_handlers[ "cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage self._start_slice_job = None self._slicing = False #Are we currently slicing? self._restart = False #Back-end is currently restarting? self._enabled = True #Should we be slicing? Slicing might be paused when, for instance, the user is dragging the mesh around. self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness. self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers. self._error_message = None #Pop-up message that shows errors. self.backendQuit.connect(self._onBackendQuit) self.backendConnected.connect(self._onBackendConnected) #When a tool operation is in progress, don't slice. So we need to listen for tool operations. Application.getInstance().getController().toolOperationStarted.connect( self._onToolOperationStarted) Application.getInstance().getController().toolOperationStopped.connect( self._onToolOperationStopped)