def _createEraserMesh(self, parent: CuraSceneNode, position: Vector): node = CuraSceneNode() node.setName("Eraser") node.setSelectable(True) node.setCalculateBoundingBox(True) mesh = self._createCube(10) node.setMeshData(mesh.build()) node.calculateBoundingBoxMesh() active_build_plate = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate node.addDecorator(BuildPlateDecorator(active_build_plate)) node.addDecorator(SliceableObjectDecorator()) stack = node.callDecoration("getStack") # created by SettingOverrideDecorator that is automatically added to CuraSceneNode settings = stack.getTop() definition = stack.getSettingDefinition("anti_overhang_mesh") new_instance = SettingInstance(definition, settings) new_instance.setProperty("value", True) new_instance.resetState() # Ensure that the state is not seen as a user state. settings.addInstance(new_instance) op = GroupedOperation() # First add node to the scene at the correct position/scale, before parenting, so the eraser mesh does not get scaled with the parent op.addOperation(AddSceneNodeOperation(node, self._controller.getScene().getRoot())) op.addOperation(SetParentOperation(node, parent)) op.push() node.setPosition(position, CuraSceneNode.TransformSpace.World) CuraApplication.getInstance().getController().getScene().sceneChanged.emit(node)
def updateSceneFromOptimizationResult( self, analysis: pywim.smartslice.result.Analysis): type_map = { 'int': int, 'float': float, 'str': str, 'enum': str, 'bool': bool } our_only_node = getPrintableNodes()[0] active_extruder = getNodeActiveExtruder(our_only_node) # TODO - Move this into a common class or function to apply an am.Config to GlobalStack/ExtruderStack if analysis.print_config.infill: infill_density = analysis.print_config.infill.density infill_pattern = analysis.print_config.infill.pattern if infill_pattern is None or infill_pattern == pywim.am.InfillType.unknown: infill_pattern = pywim.am.InfillType.grid infill_pattern_name = SmartSliceJobHandler.INFILL_SMARTSLICE_CURA[ infill_pattern] extruder_dict = { "wall_line_count": analysis.print_config.walls, "top_layers": analysis.print_config.top_layers, "bottom_layers": analysis.print_config.bottom_layers, "infill_sparse_density": analysis.print_config.infill.density, "infill_pattern": infill_pattern_name } Logger.log("d", "Optimized extruder settings: {}".format(extruder_dict)) for key, value in extruder_dict.items(): if value is not None: property_type = type_map.get( active_extruder.getProperty(key, "type")) if property_type: active_extruder.setProperty(key, "value", property_type(value), set_from_cache=True) active_extruder.setProperty(key, "state", InstanceState.User, set_from_cache=True) Application.getInstance().getMachineManager( ).forceUpdateAllSettings() self.optimizationResultAppliedToScene.emit() # Remove any modifier meshes which are present from a previous result mod_meshes = getModifierMeshes() if len(mod_meshes) > 0: for node in mod_meshes: node.addDecorator(SmartSliceRemovedDecorator()) our_only_node.removeChild(node) Application.getInstance().getController().getScene( ).sceneChanged.emit(node) # Add in the new modifier meshes for modifier_mesh in analysis.modifier_meshes: # Building the scene node modifier_mesh_node = CuraSceneNode() modifier_mesh_node.setName("SmartSliceMeshModifier") modifier_mesh_node.setSelectable(True) modifier_mesh_node.setCalculateBoundingBox(True) # Use the data from the SmartSlice engine to translate / rotate / scale the mod mesh modifier_mesh_node.setTransformation( Matrix(modifier_mesh.transform)) # Building the mesh # # Preparing the data from pywim for MeshBuilder modifier_mesh_vertices = [[v.x, v.y, v.z] for v in modifier_mesh.vertices] modifier_mesh_indices = [[triangle.v1, triangle.v2, triangle.v3] for triangle in modifier_mesh.triangles] # Doing the actual build modifier_mesh_data = MeshBuilder() modifier_mesh_data.setVertices( numpy.asarray(modifier_mesh_vertices, dtype=numpy.float32)) modifier_mesh_data.setIndices( numpy.asarray(modifier_mesh_indices, dtype=numpy.int32)) modifier_mesh_data.calculateNormals() modifier_mesh_node.setMeshData(modifier_mesh_data.build()) modifier_mesh_node.calculateBoundingBoxMesh() active_build_plate = Application.getInstance( ).getMultiBuildPlateModel().activeBuildPlate modifier_mesh_node.addDecorator( BuildPlateDecorator(active_build_plate)) modifier_mesh_node.addDecorator(SliceableObjectDecorator()) modifier_mesh_node.addDecorator(SmartSliceAddedDecorator()) bottom = modifier_mesh_node.getBoundingBox().bottom z_offset_decorator = ZOffsetDecorator() z_offset_decorator.setZOffset(bottom) modifier_mesh_node.addDecorator(z_offset_decorator) stack = modifier_mesh_node.callDecoration("getStack") settings = stack.getTop() modifier_mesh_node_infill_pattern = SmartSliceJobHandler.INFILL_SMARTSLICE_CURA[ modifier_mesh.print_config.infill.pattern] definition_dict = { "infill_mesh": True, "infill_pattern": modifier_mesh_node_infill_pattern, "infill_sparse_density": modifier_mesh.print_config.infill.density, "wall_line_count": modifier_mesh.print_config.walls, "top_layers": modifier_mesh.print_config.top_layers, "bottom_layers": modifier_mesh.print_config.bottom_layers, } Logger.log( "d", "Optimized modifier mesh settings: {}".format(definition_dict)) for key, value in definition_dict.items(): if value is not None: definition = stack.getSettingDefinition(key) property_type = type_map.get(stack.getProperty( key, "type")) if property_type: new_instance = SettingInstance(definition, settings) new_instance.setProperty("value", property_type(value)) new_instance.resetState( ) # Ensure that the state is not seen as a user state. settings.addInstance(new_instance) our_only_node.addChild(modifier_mesh_node) # emit changes and connect error tracker Application.getInstance().getController().getScene( ).sceneChanged.emit(modifier_mesh_node)