diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index b9f37ec6f8..3444da249f 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -32,14 +32,19 @@ class MultiplyObjectsJob(Job): root = scene.getRoot() arranger = Arrange.create(scene_root=root) + processed_nodes = [] nodes = [] for node in self._objects: # If object is part of a group, multiply group current_node = node - while current_node.getParent() and current_node.getParent().callDecoration("isGroup"): + while current_node.getParent() and (current_node.getParent().callDecoration("isGroup") or current_node.getParent().callDecoration("isSliceable")): current_node = current_node.getParent() + if current_node in processed_nodes: + continue + processed_nodes.append(current_node) + node_too_big = False if node.getBoundingBox().width < 300 or node.getBoundingBox().depth < 300: offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(current_node, min_offset=self._min_offset) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index d0e9e43e3f..1d66916b52 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -323,16 +323,21 @@ class PrintInformation(QObject): # when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its # extension. This cuts the extension off if necessary. name = os.path.splitext(name)[0] + filename_parts = os.path.basename(base_name).split(".") + + # If it's a gcode, also always update the job name + is_gcode = False + if len(filename_parts) > 1: + # Only check the extension(s) + is_gcode = "gcode" in filename_parts[1:] # if this is a profile file, always update the job name # name is "" when I first had some meshes and afterwards I deleted them so the naming should start again is_empty = name == "" - if is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)): - # remove ".curaproject" suffix from (imported) the file name - if name.endswith(".curaproject"): - name = name[:name.rfind(".curaproject")] - self._base_name = name - self._updateJobName() + if is_gcode or is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)): + # Only take the file name part + self._base_name = filename_parts[0] + self._updateJobName() @pyqtProperty(str, fset = setBaseName, notify = baseNameChanged) def baseName(self): diff --git a/cura/Scene/CuraSceneNode.py b/cura/Scene/CuraSceneNode.py index 48d271a2f2..428a59f554 100644 --- a/cura/Scene/CuraSceneNode.py +++ b/cura/Scene/CuraSceneNode.py @@ -103,6 +103,25 @@ class CuraSceneNode(SceneNode): return True return False + ## Override of SceneNode._calculateAABB to exclude non-printing-meshes from bounding box + def _calculateAABB(self): + aabb = None + if self._mesh_data: + aabb = self._mesh_data.getExtents(self.getWorldTransformation()) + else: # If there is no mesh_data, use a boundingbox that encompasses the local (0,0,0) + position = self.getWorldPosition() + aabb = AxisAlignedBox(minimum = position, maximum = position) + + for child in self._children: + if child.callDecoration("isNonPrintingMesh"): + # Non-printing-meshes inside a group should not affect push apart or drop to build plate + continue + if aabb is None: + aabb = child.getBoundingBox() + else: + aabb = aabb + child.getBoundingBox() + self._aabb = aabb + ## Taken from SceneNode, but replaced SceneNode with CuraSceneNode def __deepcopy__(self, memo): copy = CuraSceneNode(no_setting_override = True) # Setting override will be added later diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index 7884ca30c7..06d9fc3707 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -19,8 +19,10 @@ from cura.Scene.CuraSceneNode import CuraSceneNode from cura.PickingPass import PickingPass +from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation +from cura.Operations.SetParentOperation import SetParentOperation from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator from cura.Scene.BuildPlateDecorator import BuildPlateDecorator @@ -56,7 +58,7 @@ class SupportEraser(Tool): modifiers = QApplication.keyboardModifiers() ctrl_is_active = modifiers & Qt.ControlModifier - if event.type == Event.MousePressEvent and self._controller.getToolsEnabled(): + if event.type == Event.MousePressEvent and MouseEvent.LeftButton in event.buttons and self._controller.getToolsEnabled(): if ctrl_is_active: self._controller.setActiveTool("TranslateTool") return @@ -117,7 +119,10 @@ class SupportEraser(Tool): new_instance.resetState() # Ensure that the state is not seen as a user state. settings.addInstance(new_instance) - op = AddSceneNodeOperation(node, parent) + 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) diff --git a/resources/definitions/zyyx_agile.def.json b/resources/definitions/zyyx_agile.def.json new file mode 100644 index 0000000000..bd08ee4a2d --- /dev/null +++ b/resources/definitions/zyyx_agile.def.json @@ -0,0 +1,58 @@ +{ + "name": "ZYYX Agile", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Magicfirm Europe", + "manufacturer": "Magicfirm Europe", + "file_formats": "application/x3g", + "platform": "zyyx_platform.stl", + "has_machine_quality": true, + "quality_definition": "zyyx_agile", + "preferred_material": "zyyx_pro_pla", + "preferred_quality_type": "normal", + "machine_x3g_variant": "z" + }, + + "overrides": { + "machine_name": { "default_value": "ZYYX Agile" }, + "machine_start_gcode": { + "default_value": "; ZYYX 3D Printer start gcode\nM73 P0; enable build progress\nG21; set units to mm\nG90; set positioning to absolute\nG130 X80 Y80 A127 B127 ; Set Stepper Vref to default value\nG162 X Y F3000; home XY axes maximum\nM133 T0 ; stabilize extruder temperature\nG161 Z F450\nG161 Z F450; home Z axis minimum\nG92 X0 Y0 Z0 E0\nG1 X0 Y0 Z5 F200\nG161 Z F200; home Z axis minimum again\nG92 X0 Y0 Z0 E0\nM131 A; store surface calibration point 1\nG1 X0 Y0 Z5 F200\nG1 X-177 Y0 Z5 F3000; move to 2nd probing point\nG161 Z F200\nM131 B; store surface calibration point 2\nG92 X-177 Y0 Z0 E0\nG1 X-177 Y0 Z5 F200\nG1 X0 Y0 Z5 F3000; move to home point\nG161 Z F200; home Z axis minimum again\nG92 X0 Y0 Z0 E0; set reference again\nG1 X0 Y0 Z5 F200; clear Z\nG1 X0 Y-225 Z5 F3000; move to 3rd calibration point\nG161 Z F200\nM131 AB; store surface calibration point 3\nM132 AB; activate auto leveling\nG92 X0 Y-225 Z0 E0\nG1 X0 Y-225 Z5 F200\nG162 X Y F3000\nG161 Z F200\nG92 X135 Y115 Z0 E0\nM132 Z; Recall stored home offset for Z axis\nG1 X135 Y115 Z5 F450; clear nozzle from hole\nG1 X0 Y115 Z5 F3000; clear nozzle from hole\nG92 E0 ; Set E to 0" + }, + "machine_end_gcode": { + "default_value": "; ZYYX 3D Printer end gcode\nM73 P100 ; end build progress\nG0 Z195 F1000 ; send Z axis to bottom of machine\nM104 S0 T0 ; cool down extruder\nM127 ; stop blower fan\nG162 X Y F3000 ; home XY maximum\nM18 ; disable stepper\nM70 P5 (ZYYX Print Finished!)\nM72 P1 ; play Ta-Da song\n" + }, + "machine_width": { "default_value": 265 }, + "machine_depth": { "default_value": 225 }, + "machine_height": { "default_value": 195 }, + "machine_center_is_zero": { "default_value": true }, + "machine_gcode_flavor": { "default_value": "Makerbot" }, + "machine_head_with_fans_polygon": { "default_value": [ [ -37, 50 ], [ 25, 50 ], [ 25, -40 ], [ -37, -40 ] ] }, + "gantry_height": { "default_value": 10 }, + "machine_steps_per_mm_x": { "default_value": 88.888889 }, + "machine_steps_per_mm_y": { "default_value": 88.888889 }, + "machine_steps_per_mm_z": { "default_value": 400 }, + "machine_steps_per_mm_e": { "default_value": 96.27520187033366 }, + "retraction_amount": { "default_value": 0.7 }, + "retraction_speed": { "default_value": 15 }, + "speed_print": { "default_value": 50 }, + "speed_wall": { "value": 25 }, + "speed_wall_x": { "value": 35 }, + "speed_travel": { "value": 80 }, + "speed_layer_0": { "value": 15 }, + "support_interface_enable": { "default_value": true }, + "support_interface_height": { "default_value": 0.8 }, + "support_interface_density": { "default_value": 80 }, + "support_interface_pattern": { "default_value": "grid" }, + "infill_overlap": { "value": "12 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0" }, + "retract_at_layer_change": { "default_value": true }, + "travel_retract_before_outer_wall": { "default_value": true }, + "material_initial_print_temperature": { "value": "material_print_temperature" }, + "material_final_print_temperature": { "value": "material_print_temperature" }, + "travel_avoid_other_parts": { "default_value": false }, + "raft_airgap": { "default_value": 0.15 }, + "raft_margin": { "default_value": 6 }, + "material_diameter": { "default_value": 1.75 } + } +} diff --git a/resources/meshes/zyyx_platform.stl b/resources/meshes/zyyx_platform.stl new file mode 100644 index 0000000000..fd2a768ee9 Binary files /dev/null and b/resources/meshes/zyyx_platform.stl differ diff --git a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg new file mode 100644 index 0000000000..b2a27a7d38 --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg @@ -0,0 +1,14 @@ +[general] +version = 3 +name = Fast +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = fast +weight = 1 +global_quality = True + +[values] +layer_height = 0.3 diff --git a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg new file mode 100644 index 0000000000..77a513ceab --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg @@ -0,0 +1,14 @@ +[general] +version = 3 +name = Fine +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = fine +weight = 3 +global_quality = True + +[values] +layer_height = 0.1 diff --git a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg new file mode 100644 index 0000000000..bb342715ba --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg @@ -0,0 +1,14 @@ +[general] +version = 3 +name = Normal +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = 2 +global_quality = True + +[values] +layer_height = 0.2 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg new file mode 100644 index 0000000000..ec51eb5cc2 --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg @@ -0,0 +1,27 @@ +[general] +version = 3 +name = Fast +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = fast +weight = 1 +material = zyyx_pro_flex + +[values] +layer_height = 0.3 +wall_thickness = 0.8 +top_bottom_thickness = 1.0 +infill_sparse_density = 10 +default_material_print_temperature = 220 +material_print_temperature_layer_0 = 235 +retraction_amount = 1.0 +retraction_speed = 15 +speed_print = 20 +speed_wall = 20 +speed_wall_x = 20 +adhesion_type = brim +material_flow = 105 +raft_airgap = 0.2 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg new file mode 100644 index 0000000000..d1aacd309f --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg @@ -0,0 +1,27 @@ +[general] +version = 3 +name = Fine +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = fine +weight = 3 +material = zyyx_pro_flex + +[values] +layer_height = 0.12 +wall_thickness = 1.2 +top_bottom_thickness = 1.0 +infill_sparse_density = 15 +default_material_print_temperature = 205 +material_print_temperature_layer_0 = 235 +retraction_amount = 0.2 +retraction_speed = 15 +speed_print = 15 +speed_wall = 15 +speed_wall_x = 15 +adhesion_type = brim +material_flow = 105 +raft_airgap = 0.1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg new file mode 100644 index 0000000000..998a457d4a --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg @@ -0,0 +1,27 @@ +[general] +version = 3 +name = Normal +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = 2 +material = zyyx_pro_flex + +[values] +layer_height = 0.2 +wall_thickness = 1.2 +top_bottom_thickness = 1.0 +infill_sparse_density = 15 +default_material_print_temperature = 210 +material_print_temperature_layer_0 = 235 +retraction_amount = 1.0 +retraction_speed = 15 +speed_print = 20 +speed_wall = 15 +speed_wall_x = 20 +adhesion_type = brim +material_flow = 105 +raft_airgap = 0.2 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg new file mode 100644 index 0000000000..8e53930c8d --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg @@ -0,0 +1,27 @@ +[general] +version = 3 +name = Fast +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = fast +weight = 1 +material = zyyx_pro_pla + +[values] +layer_height = 0.3 +wall_thickness = 0.8 +top_bottom_thickness = 1.0 +infill_sparse_density = 10 +default_material_print_temperature = 220 +material_print_temperature_layer_0 = 225 +retraction_amount = 1.5 +retraction_speed = 20 +speed_print = 40 +speed_wall = 40 +speed_wall_x = 40 +adhesion_type = brim +material_flow = 95 +raft_airgap = 0.15 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg new file mode 100644 index 0000000000..07a70a7a5c --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg @@ -0,0 +1,27 @@ +[general] +version = 3 +name = Fine +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = fine +weight = 3 +material = zyyx_pro_pla + +[values] +layer_height = 0.1 +wall_thickness = 1.2 +top_bottom_thickness = 1.0 +infill_sparse_density = 15 +default_material_print_temperature = 205 +material_print_temperature_layer_0 = 225 +retraction_amount = 0.4 +retraction_speed = 20 +speed_print = 35 +speed_wall = 18 +speed_wall_x = 25 +adhesion_type = brim +material_flow = 95 +raft_airgap = 0.08 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg new file mode 100644 index 0000000000..dc035605b1 --- /dev/null +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg @@ -0,0 +1,27 @@ +[general] +version = 3 +name = Normal +definition = zyyx_agile + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = 2 +material = zyyx_pro_pla + +[values] +layer_height = 0.2 +wall_thickness = 1.2 +top_bottom_thickness = 1.0 +infill_sparse_density = 15 +default_material_print_temperature = 210 +material_print_temperature_layer_0 = 225 +retraction_amount = 1.2 +retraction_speed = 20 +speed_print = 50 +speed_wall = 22 +speed_wall_x = 33 +adhesion_type = brim +material_flow = 95 +raft_airgap = 0.15