Merge branch 'master' into CURA-7717_Add_Essentials_subscription_information_in_slice_data

This commit is contained in:
Kostas Karmas 2020-10-14 11:34:42 +02:00
commit 095e34fe8d
104 changed files with 1781 additions and 156 deletions

View file

@ -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 Optional from typing import Optional
from UM.Decorators import deprecated
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Logger import Logger from UM.Logger import Logger
from UM.Math.Polygon import Polygon from UM.Math.Polygon import Polygon
@ -32,6 +33,7 @@ class Arrange:
build_volume = None # type: Optional[BuildVolume] build_volume = None # type: Optional[BuildVolume]
@deprecated("Use the functions in Nest2dArrange instead", "4.8")
def __init__(self, x, y, offset_x, offset_y, scale = 0.5): def __init__(self, x, y, offset_x, offset_y, scale = 0.5):
self._scale = scale # convert input coordinates to arrange coordinates self._scale = scale # convert input coordinates to arrange coordinates
world_x, world_y = int(x * self._scale), int(y * self._scale) world_x, world_y = int(x * self._scale), int(y * self._scale)
@ -45,6 +47,7 @@ class Arrange:
self._is_empty = True self._is_empty = True
@classmethod @classmethod
@deprecated("Use the functions in Nest2dArrange instead", "4.8")
def create(cls, scene_root = None, fixed_nodes = None, scale = 0.5, x = 350, y = 250, min_offset = 8) -> "Arrange": def create(cls, scene_root = None, fixed_nodes = None, scale = 0.5, x = 350, y = 250, min_offset = 8) -> "Arrange":
"""Helper to create an :py:class:`cura.Arranging.Arrange.Arrange` instance """Helper to create an :py:class:`cura.Arranging.Arrange.Arrange` instance
@ -101,6 +104,7 @@ class Arrange:
self._last_priority = 0 self._last_priority = 0
@deprecated("Use the functions in Nest2dArrange instead", "4.8")
def findNodePlacement(self, node: SceneNode, offset_shape_arr: ShapeArray, hull_shape_arr: ShapeArray, step = 1) -> bool: def findNodePlacement(self, node: SceneNode, offset_shape_arr: ShapeArray, hull_shape_arr: ShapeArray, step = 1) -> bool:
"""Find placement for a node (using offset shape) and place it (using hull shape) """Find placement for a node (using offset shape) and place it (using hull shape)

View file

@ -1,24 +1,16 @@
# 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.
from PyQt5.QtCore import QCoreApplication from typing import List
from UM.Application import Application from UM.Application import Application
from UM.Job import Job from UM.Job import Job
from UM.Scene.SceneNode import SceneNode
from UM.Math.Vector import Vector
from UM.Operations.TranslateOperation import TranslateOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Logger import Logger
from UM.Message import Message from UM.Message import Message
from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from cura.Arranging.Nest2DArrange import arrange
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
from cura.Scene.ZOffsetDecorator import ZOffsetDecorator
from cura.Arranging.Arrange import Arrange
from cura.Arranging.ShapeArray import ShapeArray
from typing import List
class ArrangeObjectsJob(Job): class ArrangeObjectsJob(Job):
def __init__(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], min_offset = 8) -> None: def __init__(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], min_offset = 8) -> None:
@ -30,80 +22,18 @@ class ArrangeObjectsJob(Job):
def run(self): def run(self):
status_message = Message(i18n_catalog.i18nc("@info:status", "Finding new location for objects"), status_message = Message(i18n_catalog.i18nc("@info:status", "Finding new location for objects"),
lifetime = 0, lifetime = 0,
dismissable=False, dismissable = False,
progress = 0, progress = 0,
title = i18n_catalog.i18nc("@info:title", "Finding Location")) title = i18n_catalog.i18nc("@info:title", "Finding Location"))
status_message.show() status_message.show()
global_container_stack = Application.getInstance().getGlobalContainerStack()
machine_width = global_container_stack.getProperty("machine_width", "value")
machine_depth = global_container_stack.getProperty("machine_depth", "value")
arranger = Arrange.create(x = machine_width, y = machine_depth, fixed_nodes = self._fixed_nodes, min_offset = self._min_offset) found_solution_for_all = arrange(self._nodes, Application.getInstance().getBuildVolume(), self._fixed_nodes)
# Build set to exclude children (those get arranged together with the parents).
included_as_child = set()
for node in self._nodes:
included_as_child.update(node.getAllChildren())
# Collect nodes to be placed
nodes_arr = [] # fill with (size, node, offset_shape_arr, hull_shape_arr)
for node in self._nodes:
if node in included_as_child:
continue
offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(node, min_offset = self._min_offset, include_children = True)
if offset_shape_arr is None:
Logger.log("w", "Node [%s] could not be converted to an array for arranging...", str(node))
continue
nodes_arr.append((offset_shape_arr.arr.shape[0] * offset_shape_arr.arr.shape[1], node, offset_shape_arr, hull_shape_arr))
# Sort the nodes with the biggest area first.
nodes_arr.sort(key=lambda item: item[0])
nodes_arr.reverse()
# Place nodes one at a time
start_priority = 0
last_priority = start_priority
last_size = None
grouped_operation = GroupedOperation()
found_solution_for_all = True
not_fit_count = 0
for idx, (size, node, offset_shape_arr, hull_shape_arr) in enumerate(nodes_arr):
# For performance reasons, we assume that when a location does not fit,
# it will also not fit for the next object (while what can be untrue).
if last_size == size: # This optimization works if many of the objects have the same size
start_priority = last_priority
else:
start_priority = 0
best_spot = arranger.bestSpot(hull_shape_arr, start_prio = start_priority)
x, y = best_spot.x, best_spot.y
node.removeDecorator(ZOffsetDecorator)
if node.getBoundingBox():
center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
else:
center_y = 0
if x is not None: # We could find a place
last_size = size
last_priority = best_spot.priority
arranger.place(x, y, offset_shape_arr) # take place before the next one
grouped_operation.addOperation(TranslateOperation(node, Vector(x, center_y, y), set_position = True))
else:
Logger.log("d", "Arrange all: could not find spot!")
found_solution_for_all = False
grouped_operation.addOperation(TranslateOperation(node, Vector(200, center_y, -not_fit_count * 20), set_position = True))
not_fit_count += 1
status_message.setProgress((idx + 1) / len(nodes_arr) * 100)
Job.yieldThread()
QCoreApplication.processEvents()
grouped_operation.push()
status_message.hide() status_message.hide()
if not found_solution_for_all: if not found_solution_for_all:
no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"), no_full_solution_message = Message(
title = i18n_catalog.i18nc("@info:title", "Can't Find Location")) i18n_catalog.i18nc("@info:status",
"Unable to find a location within the build volume for all objects"),
title = i18n_catalog.i18nc("@info:title", "Can't Find Location"))
no_full_solution_message.show() no_full_solution_message.show()
self.finished.emit(self) self.finished.emit(self)

View file

@ -0,0 +1,140 @@
import numpy
from pynest2d import Point, Box, Item, NfpConfig, nest
from typing import List, TYPE_CHECKING, Optional, Tuple
from UM.Application import Application
from UM.Math.Matrix import Matrix
from UM.Math.Polygon import Polygon
from UM.Math.Quaternion import Quaternion
from UM.Math.Vector import Vector
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.RotateOperation import RotateOperation
from UM.Operations.TranslateOperation import TranslateOperation
if TYPE_CHECKING:
from UM.Scene.SceneNode import SceneNode
from cura.BuildVolume import BuildVolume
def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: Optional[List["SceneNode"]] = None, factor = 10000) -> Tuple[bool, List[Item]]:
"""
Find placement for a set of scene nodes, but don't actually move them just yet.
:param nodes_to_arrange: The list of nodes that need to be moved.
:param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this.
:param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
are placed.
:param factor: The library that we use is int based. This factor defines how accurate we want it to be.
:return: tuple (found_solution_for_all, node_items)
WHERE
found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
node_items: A list of the nodes return by libnest2d, which contain the new positions on the buildplate
"""
machine_width = build_volume.getWidth()
machine_depth = build_volume.getDepth()
build_plate_bounding_box = Box(machine_width * factor, machine_depth * factor)
if fixed_nodes is None:
fixed_nodes = []
# Add all the items we want to arrange
node_items = []
for node in nodes_to_arrange:
hull_polygon = node.callDecoration("getConvexHull")
converted_points = []
for point in hull_polygon.getPoints():
converted_points.append(Point(point[0] * factor, point[1] * factor))
item = Item(converted_points)
node_items.append(item)
# Use a tiny margin for the build_plate_polygon (the nesting doesn't like overlapping disallowed areas)
half_machine_width = 0.5 * machine_width - 1
half_machine_depth = 0.5 * machine_depth - 1
build_plate_polygon = Polygon(numpy.array([
[half_machine_width, -half_machine_depth],
[-half_machine_width, -half_machine_depth],
[-half_machine_width, half_machine_depth],
[half_machine_width, half_machine_depth]
], numpy.float32))
disallowed_areas = build_volume.getDisallowedAreas()
num_disallowed_areas_added = 0
for area in disallowed_areas:
converted_points = []
# Clip the disallowed areas so that they don't overlap the bounding box (The arranger chokes otherwise)
clipped_area = area.intersectionConvexHulls(build_plate_polygon)
if clipped_area.getPoints() is not None: # numpy array has to be explicitly checked against None
for point in clipped_area.getPoints():
converted_points.append(Point(point[0] * factor, point[1] * factor))
disallowed_area = Item(converted_points)
disallowed_area.markAsDisallowedAreaInBin(0)
node_items.append(disallowed_area)
num_disallowed_areas_added += 1
for node in fixed_nodes:
converted_points = []
hull_polygon = node.callDecoration("getConvexHull")
if hull_polygon.getPoints() is not None: # numpy array has to be explicitly checked against None
for point in hull_polygon.getPoints():
converted_points.append(Point(point[0] * factor, point[1] * factor))
item = Item(converted_points)
item.markAsFixedInBin(0)
node_items.append(item)
num_disallowed_areas_added += 1
config = NfpConfig()
config.accuracy = 1.0
num_bins = nest(node_items, build_plate_bounding_box, 10000, config)
# Strip the fixed items (previously placed) and the disallowed areas from the results again.
node_items = list(filter(lambda item: not item.isFixed(), node_items))
found_solution_for_all = num_bins == 1
return found_solution_for_all, node_items
def arrange(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: Optional[List["SceneNode"]] = None, factor = 10000, add_new_nodes_in_scene: bool = False) -> bool:
"""
Find placement for a set of scene nodes, and move them by using a single grouped operation.
:param nodes_to_arrange: The list of nodes that need to be moved.
:param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this.
:param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
are placed.
:param factor: The library that we use is int based. This factor defines how accuracte we want it to be.
:param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
:return: found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
"""
scene_root = Application.getInstance().getController().getScene().getRoot()
found_solution_for_all, node_items = findNodePlacement(nodes_to_arrange, build_volume, fixed_nodes, factor)
not_fit_count = 0
grouped_operation = GroupedOperation()
for node, node_item in zip(nodes_to_arrange, node_items):
if add_new_nodes_in_scene:
grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root))
if node_item.binId() == 0:
# We found a spot for it
rotation_matrix = Matrix()
rotation_matrix.setByRotationAxis(node_item.rotation(), Vector(0, -1, 0))
grouped_operation.addOperation(RotateOperation(node, Quaternion.fromMatrix(rotation_matrix)))
grouped_operation.addOperation(TranslateOperation(node, Vector(node_item.translation().x() / factor, 0,
node_item.translation().y() / factor)))
else:
# We didn't find a spot
grouped_operation.addOperation(
TranslateOperation(node, Vector(200, node.getWorldPosition().y, -not_fit_count * 20), set_position = True))
not_fit_count += 1
grouped_operation.push()
return found_solution_for_all

View file

@ -180,12 +180,21 @@ class BuildVolume(SceneNode):
def setWidth(self, width: float) -> None: def setWidth(self, width: float) -> None:
self._width = width self._width = width
def getWidth(self) -> float:
return self._width
def setHeight(self, height: float) -> None: def setHeight(self, height: float) -> None:
self._height = height self._height = height
def getHeight(self) -> float:
return self._height
def setDepth(self, depth: float) -> None: def setDepth(self, depth: float) -> None:
self._depth = depth self._depth = depth
def getDepth(self) -> float:
return self._depth
def setShape(self, shape: str) -> None: def setShape(self, shape: str) -> None:
if shape: if shape:
self._shape = shape self._shape = shape

View file

@ -36,6 +36,7 @@ from UM.Scene.Camera import Camera
from UM.Scene.GroupDecorator import GroupDecorator from UM.Scene.GroupDecorator import GroupDecorator
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.Scene.SceneNodeSettings import SceneNodeSettings
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
from UM.Scene.ToolHandle import ToolHandle from UM.Scene.ToolHandle import ToolHandle
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
@ -52,7 +53,7 @@ from cura.API.Account import Account
from cura.Arranging.Arrange import Arrange from cura.Arranging.Arrange import Arrange
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
from cura.Arranging.ShapeArray import ShapeArray from cura.Arranging.Nest2DArrange import arrange
from cura.Machines.MachineErrorChecker import MachineErrorChecker from cura.Machines.MachineErrorChecker import MachineErrorChecker
from cura.Machines.Models.BuildPlateModel import BuildPlateModel from cura.Machines.Models.BuildPlateModel import BuildPlateModel
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
@ -801,6 +802,8 @@ class CuraApplication(QtApplication):
self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing build volume...")) self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing build volume..."))
root = self.getController().getScene().getRoot() root = self.getController().getScene().getRoot()
self._volume = BuildVolume.BuildVolume(self, root) self._volume = BuildVolume.BuildVolume(self, root)
# Ensure that the old style arranger still works.
Arrange.build_volume = self._volume Arrange.build_volume = self._volume
# initialize info objects # initialize info objects
@ -1379,6 +1382,7 @@ class CuraApplication(QtApplication):
def arrangeAll(self) -> None: def arrangeAll(self) -> None:
nodes_to_arrange = [] nodes_to_arrange = []
active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate
locked_nodes = []
for node in DepthFirstIterator(self.getController().getScene().getRoot()): for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, SceneNode): if not isinstance(node, SceneNode):
continue continue
@ -1400,8 +1404,12 @@ class CuraApplication(QtApplication):
# Skip nodes that are too big # Skip nodes that are too big
bounding_box = node.getBoundingBox() bounding_box = node.getBoundingBox()
if bounding_box is None or bounding_box.width < self._volume.getBoundingBox().width or bounding_box.depth < self._volume.getBoundingBox().depth: if bounding_box is None or bounding_box.width < self._volume.getBoundingBox().width or bounding_box.depth < self._volume.getBoundingBox().depth:
nodes_to_arrange.append(node) # Arrange only the unlocked nodes and keep the locked ones in place
self.arrange(nodes_to_arrange, fixed_nodes = []) if UM.Util.parseBool(node.getSetting(SceneNodeSettings.LockPosition)):
locked_nodes.append(node)
else:
nodes_to_arrange.append(node)
self.arrange(nodes_to_arrange, locked_nodes)
def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode]) -> None: def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode]) -> None:
"""Arrange a set of nodes given a set of fixed nodes """Arrange a set of nodes given a set of fixed nodes
@ -1815,17 +1823,21 @@ class CuraApplication(QtApplication):
for node_ in DepthFirstIterator(root): for node_ in DepthFirstIterator(root):
if node_.callDecoration("isSliceable") and node_.callDecoration("getBuildPlateNumber") == target_build_plate: if node_.callDecoration("isSliceable") and node_.callDecoration("getBuildPlateNumber") == target_build_plate:
fixed_nodes.append(node_) fixed_nodes.append(node_)
machine_width = global_container_stack.getProperty("machine_width", "value")
machine_depth = global_container_stack.getProperty("machine_depth", "value")
arranger = Arrange.create(x = machine_width, y = machine_depth, fixed_nodes = fixed_nodes)
min_offset = 8
default_extruder_position = self.getMachineManager().defaultExtruderPosition default_extruder_position = self.getMachineManager().defaultExtruderPosition
default_extruder_id = self._global_container_stack.extruderList[int(default_extruder_position)].getId() default_extruder_id = self._global_container_stack.extruderList[int(default_extruder_position)].getId()
select_models_on_load = self.getPreferences().getValue("cura/select_models_on_load") select_models_on_load = self.getPreferences().getValue("cura/select_models_on_load")
for original_node in nodes: nodes_to_arrange = [] # type: List[CuraSceneNode]
fixed_nodes = []
for node_ in DepthFirstIterator(self.getController().getScene().getRoot()):
# Only count sliceable objects
if node_.callDecoration("isSliceable"):
fixed_nodes.append(node_)
for original_node in nodes:
# Create a CuraSceneNode just if the original node is not that type # Create a CuraSceneNode just if the original node is not that type
if isinstance(original_node, CuraSceneNode): if isinstance(original_node, CuraSceneNode):
node = original_node node = original_node
@ -1833,8 +1845,8 @@ class CuraApplication(QtApplication):
node = CuraSceneNode() node = CuraSceneNode()
node.setMeshData(original_node.getMeshData()) node.setMeshData(original_node.getMeshData())
#Setting meshdata does not apply scaling. # Setting meshdata does not apply scaling.
if(original_node.getScale() != Vector(1.0, 1.0, 1.0)): if original_node.getScale() != Vector(1.0, 1.0, 1.0):
node.scale(original_node.getScale()) node.scale(original_node.getScale())
node.setSelectable(True) node.setSelectable(True)
@ -1865,19 +1877,15 @@ class CuraApplication(QtApplication):
if file_extension != "3mf": if file_extension != "3mf":
if node.callDecoration("isSliceable"): if node.callDecoration("isSliceable"):
# Only check position if it's not already blatantly obvious that it won't fit. # Ensure that the bottom of the bounding box is on the build plate
if node.getBoundingBox() is None or self._volume.getBoundingBox() is None or node.getBoundingBox().width < self._volume.getBoundingBox().width or node.getBoundingBox().depth < self._volume.getBoundingBox().depth: if node.getBoundingBox():
# Find node location center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(node, min_offset = min_offset) else:
center_y = 0
# If a model is to small then it will not contain any points node.translate(Vector(0, center_y, 0))
if offset_shape_arr is None and hull_shape_arr is None:
Message(self._i18n_catalog.i18nc("@info:status", "The selected model was too small to load."),
title = self._i18n_catalog.i18nc("@info:title", "Warning")).show()
return
# Step is for skipping tests to make it a lot faster. it also makes the outcome somewhat rougher nodes_to_arrange.append(node)
arranger.findNodePlacement(node, offset_shape_arr, hull_shape_arr, step = 10)
# 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
@ -1897,6 +1905,8 @@ class CuraApplication(QtApplication):
if select_models_on_load: if select_models_on_load:
Selection.add(node) Selection.add(node)
arrange(nodes_to_arrange, self.getBuildVolume(), fixed_nodes)
self.fileCompleted.emit(file_name) self.fileCompleted.emit(file_name)
def addNonSliceableExtension(self, extension): def addNonSliceableExtension(self, extension):

View file

@ -4,21 +4,16 @@
import copy import copy
from typing import List from typing import List
from PyQt5.QtCore import QCoreApplication from UM.Application import Application
from UM.Job import Job from UM.Job import Job
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Message import Message from UM.Message import Message
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from cura.Arranging.Nest2DArrange import arrange
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
from cura.Arranging.Arrange import Arrange
from cura.Arranging.ShapeArray import ShapeArray
from UM.Application import Application
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
class MultiplyObjectsJob(Job): class MultiplyObjectsJob(Job):
def __init__(self, objects, count, min_offset = 8): def __init__(self, objects, count, min_offset = 8):
@ -28,28 +23,27 @@ class MultiplyObjectsJob(Job):
self._min_offset = min_offset self._min_offset = min_offset
def run(self) -> None: def run(self) -> None:
status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0, status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime = 0,
dismissable=False, progress=0, title = i18n_catalog.i18nc("@info:title", "Placing Objects")) dismissable = False, progress = 0,
title = i18n_catalog.i18nc("@info:title", "Placing Objects"))
status_message.show() status_message.show()
scene = Application.getInstance().getController().getScene() scene = Application.getInstance().getController().getScene()
total_progress = len(self._objects) * self._count
current_progress = 0
global_container_stack = Application.getInstance().getGlobalContainerStack() global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack is None: if global_container_stack is None:
return # We can't do anything in this case. return # We can't do anything in this case.
machine_width = global_container_stack.getProperty("machine_width", "value")
machine_depth = global_container_stack.getProperty("machine_depth", "value")
root = scene.getRoot() root = scene.getRoot()
scale = 0.5
arranger = Arrange.create(x = machine_width, y = machine_depth, scene_root = root, scale = scale, min_offset = self._min_offset)
processed_nodes = [] # type: List[SceneNode] processed_nodes = [] # type: List[SceneNode]
nodes = [] nodes = []
not_fit_count = 0 fixed_nodes = []
found_solution_for_all = False for node_ in DepthFirstIterator(root):
# Only count sliceable objects
if node_.callDecoration("isSliceable"):
fixed_nodes.append(node_)
for node in self._objects: for node in self._objects:
# If object is part of a group, multiply group # If object is part of a group, multiply group
current_node = node current_node = node
@ -60,31 +54,8 @@ class MultiplyObjectsJob(Job):
continue continue
processed_nodes.append(current_node) processed_nodes.append(current_node)
node_too_big = False
if node.getBoundingBox().width < machine_width or node.getBoundingBox().depth < machine_depth:
offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(current_node, min_offset = self._min_offset, scale = scale)
else:
node_too_big = True
found_solution_for_all = True
arranger.resetLastPriority()
for _ in range(self._count): for _ in range(self._count):
# We do place the nodes one by one, as we want to yield in between.
new_node = copy.deepcopy(node) new_node = copy.deepcopy(node)
solution_found = False
if not node_too_big:
if offset_shape_arr is not None and hull_shape_arr is not None:
solution_found = arranger.findNodePlacement(new_node, offset_shape_arr, hull_shape_arr)
else:
# The node has no shape, so no need to arrange it. The solution is simple: Do nothing.
solution_found = True
if node_too_big or not solution_found:
found_solution_for_all = False
new_location = new_node.getPosition()
new_location = new_location.set(z = - not_fit_count * 20)
new_node.setPosition(new_location)
not_fit_count += 1
# Same build plate # Same build plate
build_plate_number = current_node.callDecoration("getBuildPlateNumber") build_plate_number = current_node.callDecoration("getBuildPlateNumber")
@ -93,20 +64,15 @@ class MultiplyObjectsJob(Job):
child.callDecoration("setBuildPlateNumber", build_plate_number) child.callDecoration("setBuildPlateNumber", build_plate_number)
nodes.append(new_node) nodes.append(new_node)
current_progress += 1
status_message.setProgress((current_progress / total_progress) * 100)
QCoreApplication.processEvents()
Job.yieldThread()
QCoreApplication.processEvents()
Job.yieldThread()
found_solution_for_all = True
if nodes: if nodes:
operation = GroupedOperation() found_solution_for_all = arrange(nodes, Application.getInstance().getBuildVolume(), fixed_nodes,
for new_node in nodes: factor = 10000, add_new_nodes_in_scene = True)
operation.addOperation(AddSceneNodeOperation(new_node, current_node.getParent()))
operation.push()
status_message.hide() status_message.hide()
if not found_solution_for_all: if not found_solution_for_all:
no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"), title = i18n_catalog.i18nc("@info:title", "Placing Object")) no_full_solution_message = Message(
i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"),
title = i18n_catalog.i18nc("@info:title", "Placing Object"))
no_full_solution_message.show() no_full_solution_message.show()

View file

@ -269,7 +269,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
if mesh is None: if mesh is None:
return Polygon([]) # Node has no mesh data, so just return an empty Polygon. return Polygon([]) # Node has no mesh data, so just return an empty Polygon.
world_transform = self._node.getWorldTransformation(copy = False) world_transform = self._node.getWorldTransformation(copy = True)
# Check the cache # Check the cache
if mesh is self._2d_convex_hull_mesh and world_transform == self._2d_convex_hull_mesh_world_transform: if mesh is self._2d_convex_hull_mesh and world_transform == self._2d_convex_hull_mesh_world_transform:

View file

@ -22,6 +22,7 @@ import os
# tries to create PyQt objects on a non-main thread. # tries to create PyQt objects on a non-main thread.
import Arcus # @UnusedImport import Arcus # @UnusedImport
import Savitar # @UnusedImport import Savitar # @UnusedImport
import pynest2d # @UnusedImport
from PyQt5.QtNetwork import QSslConfiguration, QSslSocket from PyQt5.QtNetwork import QSslConfiguration, QSslSocket

View file

@ -0,0 +1,265 @@
{
"name": "Artillery Base Printer",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"visible": false,
"author": "3D-Nexus.com, cataclism, Wondro",
"manufacturer": "Artillery",
"file_formats": "text/x-gcode",
"first_start_actions": ["MachineSettingsAction"],
"machine_extruder_trains": {
"0": "artillery_base_extruder_0"
},
"has_materials": true,
"has_variants": true,
"has_machine_quality": true,
"variants_name": "Nozzle Size",
"preferred_variant_name": "0.4mm Nozzle",
"preferred_quality_type": "standard",
"preferred_material": "generic_pla",
"exclude_materials": [
"Vertex_Delta_ABS",
"Vertex_Delta_PET",
"Vertex_Delta_PLA",
"Vertex_Delta_TPU",
"chromatik_pla",
"dsm_arnitel2045_175",
"dsm_novamid1070_175",
"fabtotum_abs",
"fabtotum_nylon",
"fabtotum_pla",
"fabtotum_tpu",
"fiberlogy_hd_pla",
"filo3d_pla",
"filo3d_pla_green",
"filo3d_pla_red",
"generic_bam",
"generic_cffcpe",
"generic_cffpa",
"generic_cpe",
"generic_cpe_plus",
"generic_gffcpe",
"generic_gffpa",
"generic_hips",
"generic_nylon",
"generic_pc",
"generic_pp",
"generic_pva",
"generic_tough_pla",
"imade3d_petg_green",
"imade3d_petg_pink",
"imade3d_pla_green",
"imade3d_pla_pink",
"innofill_innoflex60_175",
"octofiber_pla",
"polyflex_pla",
"polymax_pla",
"polyplus_pla",
"polywood_pla",
"structur3d_dap100silicone",
"tizyx_abs",
"tizyx_pla",
"tizyx_pla_bois",
"ultimaker_abs_black",
"ultimaker_abs_blue",
"ultimaker_abs_green",
"ultimaker_abs_grey",
"ultimaker_abs_orange",
"ultimaker_abs_pearl-gold",
"ultimaker_abs_red",
"ultimaker_abs_silver-metallic",
"ultimaker_abs_white",
"ultimaker_abs_yellow",
"ultimaker_bam",
"ultimaker_cpe_black",
"ultimaker_cpe_blue",
"ultimaker_cpe_dark-grey",
"ultimaker_cpe_green",
"ultimaker_cpe_light-grey",
"ultimaker_cpe_plus_black",
"ultimaker_cpe_plus_transparent",
"ultimaker_cpe_plus_white",
"ultimaker_cpe_red",
"ultimaker_cpe_transparent",
"ultimaker_cpe_white",
"ultimaker_cpe_yellow",
"ultimaker_nylon_black",
"ultimaker_nylon_transparent",
"ultimaker_pc_black",
"ultimaker_pc_transparent",
"ultimaker_pc_white",
"ultimaker_pla_black",
"ultimaker_pla_blue",
"ultimaker_pla_green",
"ultimaker_pla_magenta",
"ultimaker_pla_orange",
"ultimaker_pla_pearl-white",
"ultimaker_pla_red",
"ultimaker_pla_silver-metallic",
"ultimaker_pla_transparent",
"ultimaker_pla_white",
"ultimaker_pla_yellow",
"ultimaker_pp_transparent",
"ultimaker_pva",
"ultimaker_tough_pla_black",
"ultimaker_tough_pla_green",
"ultimaker_tough_pla_red",
"ultimaker_tough_pla_white",
"ultimaker_tpu_black",
"ultimaker_tpu_blue",
"ultimaker_tpu_red",
"ultimaker_tpu_white",
"verbatim_bvoh_175",
"zyyx_pro_flex",
"zyyx_pro_pla"
]
},
"overrides": {
"machine_name": { "default_value": "Artillery Base Printer" },
"machine_start_gcode": { "default_value": "G28 ; home all axes\n M117 Purge extruder\n G92 E0 ; reset extruder\n G1 Z1.0 F3000 ; move z up little to prevent scratching of surface\n G1 X2 Y20 Z0.3 F5000.0 ; move to start-line position\n G1 X2 Y200.0 Z0.3 F1500.0 E15 ; draw 1st line\n G1 X2 Y200.0 Z0.4 F5000.0 ; move to side a little\n G1 X2 Y20 Z0.4 F1500.0 E30 ; draw 2nd line\n G92 E0 ; reset extruder\n G1 Z1.0 F3000 ; move z up little to prevent scratching of surface"},
"machine_end_gcode": { "default_value": "G91; relative positioning\n G1 Z1.0 F3000 ; move z up little to prevent scratching of print\n G90; absolute positioning\n G1 X0 Y200 F1000 ; prepare for part removal\n M104 S0; turn off extruder\n M140 S0 ; turn off bed\n G1 X0 Y300 F1000 ; prepare for part removal\n M84 ; disable motors\n M106 S0 ; turn off fan" },
"machine_max_feedrate_x": { "value": 500 },
"machine_max_feedrate_y": { "value": 500 },
"machine_max_feedrate_z": { "value": 10 },
"machine_max_feedrate_e": { "value": 50 },
"machine_max_acceleration_x": { "value": 500 },
"machine_max_acceleration_y": { "value": 500 },
"machine_max_acceleration_z": { "value": 100 },
"machine_max_acceleration_e": { "value": 5000 },
"machine_acceleration": { "value": 500 },
"machine_max_jerk_xy": { "value": 10 },
"machine_max_jerk_z": { "value": 0.4 },
"machine_max_jerk_e": { "value": 5 },
"machine_heated_bed": { "default_value": true },
"material_diameter": { "default_value": 1.75 },
"acceleration_print": { "value": 500 },
"acceleration_travel": { "value": 500 },
"acceleration_travel_layer_0": { "value": "acceleration_travel" },
"acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
"jerk_print": { "value": 8 },
"jerk_travel": { "value": "jerk_print" },
"jerk_travel_layer_0": { "value": "jerk_travel" },
"acceleration_enabled": { "value": false },
"jerk_enabled": { "value": false },
"speed_print": { "value": 60.0 } ,
"speed_infill": { "value": "speed_print" },
"speed_wall": { "value": "speed_print / 2" },
"speed_wall_0": { "value": "speed_wall" },
"speed_wall_x": { "value": "speed_wall" },
"speed_topbottom": { "value": "speed_print / 2" },
"speed_roofing": { "value": "speed_topbottom" },
"speed_travel": { "value": "150.0 if speed_print < 60 else 250.0 if speed_print > 100 else speed_print * 2.5" },
"speed_layer_0": { "value": 20.0 },
"speed_print_layer_0": { "value": "speed_layer_0" },
"speed_travel_layer_0": { "value": "100 if speed_layer_0 < 20 else 150 if speed_layer_0 > 30 else speed_layer_0 * 5" },
"speed_prime_tower": { "value": "speed_topbottom" },
"speed_support": { "value": "speed_wall_0" },
"speed_support_interface": { "value": "speed_topbottom" },
"speed_z_hop": { "value": 5 },
"skirt_brim_speed": { "value": "speed_layer_0" },
"line_width": { "value": "machine_nozzle_size * 1.1" },
"optimize_wall_printing_order": { "value": "True" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
"material_final_print_temperature": { "value": "material_print_temperature" },
"material_flow": { "value": 100 },
"travel_compensate_overlapping_walls_0_enabled": { "value": "False" },
"z_seam_type": { "value": "'back'" },
"z_seam_corner": { "value": "'z_seam_corner_none'" },
"infill_sparse_density": { "value": "20" },
"infill_pattern": { "value": "'lines' if infill_sparse_density > 50 else 'cubic'" },
"infill_before_walls": { "value": false },
"infill_overlap": { "value": 30.0 },
"skin_overlap": { "value": 10.0 },
"infill_wipe_dist": { "value": 0.0 },
"wall_0_wipe_dist": { "value": 0.0 },
"fill_perimeter_gaps": { "value": "'everywhere'" },
"fill_outline_gaps": { "value": false },
"filter_out_tiny_gaps": { "value": false },
"retraction_speed": {
"maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value": 200
},
"retraction_retract_speed": {
"maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value": 200
},
"retraction_prime_speed": {
"maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value": 200
},
"retraction_hop_enabled": { "value": "support_enable" },
"retraction_hop": { "value": 0.2 },
"retraction_combing": { "value": "'off' if retraction_hop_enabled else 'infill'" },
"retraction_combing_max_distance": { "value": 30 },
"travel_avoid_other_parts": { "value": true },
"travel_avoid_supports": { "value": true },
"travel_retract_before_outer_wall": { "value": true },
"retraction_amount": { "value": 2 },
"retraction_enable": { "value": true },
"retraction_count_max": { "value": 100 },
"retraction_extrusion_window": { "value": 10 },
"retraction_min_travel": { "value": 1.5 },
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
"cool_fan_enabled": { "value": true },
"cool_min_layer_time": { "value": 10 },
"adhesion_type": { "value": "'none' if support_enable else 'skirt'" },
"brim_replaces_support": { "value": false },
"skirt_gap": { "value": 10.0 },
"skirt_line_count": { "value": 4 },
"adaptive_layer_height_variation": { "value": 0.04 },
"adaptive_layer_height_variation_step": { "value": 0.04 },
"meshfix_maximum_resolution": { "value": "0.05" },
"meshfix_maximum_travel_resolution": { "value": "meshfix_maximum_resolution" },
"support_angle": { "value": "math.floor(math.degrees(math.atan(line_width / 2.0 / layer_height)))" },
"support_pattern": { "value": "'zigzag'" },
"support_infill_rate": { "value": "0 if support_enable and support_structure == 'tree' else 20" },
"support_use_towers": { "value": false },
"support_xy_distance": { "value": "wall_line_width_0 * 2" },
"support_xy_distance_overhang": { "value": "wall_line_width_0" },
"support_z_distance": { "value": "layer_height if layer_height >= 0.16 else layer_height * 2" },
"support_xy_overrides_z": { "value": "'xy_overrides_z'" },
"support_wall_count": { "value": 1 },
"support_brim_enable": { "value": true },
"support_brim_width": { "value": 4 },
"support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" },
"support_interface_density": { "value": 33.333 },
"support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"minimum_support_area": { "value": 2 },
"minimum_interface_area": { "value": 10 },
"top_bottom_thickness": {"value": "layer_height_0 + layer_height * 3" },
"wall_thickness": {"value": "line_width * 2" }
}
}

View file

@ -0,0 +1,19 @@
{
"name": "Artillery Genius",
"version": 2,
"inherits": "artillery_base",
"overrides": {
"machine_name": { "default_value": "Artillery Genius" },
"machine_width": { "default_value": 220 },
"machine_depth": { "default_value": 220 },
"machine_height": { "default_value": 250 },
"gantry_height": { "value": 25 }
},
"metadata": {
"quality_definition": "artillery_base",
"visible": true,
"platform": "artillery_genius.stl",
"platform_offset": [ -0, -72, -20]
}
}

View file

@ -0,0 +1,19 @@
{
"name": "Artillery Sidewinder X1",
"version": 2,
"inherits": "artillery_base",
"overrides": {
"machine_name": { "default_value": "Artillery Sidewinder X1" },
"machine_width": { "default_value": 300 },
"machine_depth": { "default_value": 300 },
"machine_height": { "default_value": 400 },
"gantry_height": { "value": 25 }
},
"metadata": {
"quality_definition": "artillery_base",
"visible": true,
"platform": "artillery_swx1.stl",
"platform_offset": [ -200, -100, 250]
}
}

View file

@ -0,0 +1,16 @@
{
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "artillery_base",
"position": "0"
},
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 }
}
}

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_abs
variant = 0.2mm Nozzle
[values]
wall_thickness = =line_width*8

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Ultra Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = ultra
material = generic_abs
variant = 0.2mm Nozzle
[values]
wall_thickness = =line_width*8

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_abs
variant = 0.3mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_abs
variant = 0.3mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_abs
variant = 0.3mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_abs
variant = 0.3mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_abs
variant = 0.4mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_abs
variant = 0.4mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_abs
variant = 0.4mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_abs
variant = 0.4mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_abs
variant = 0.5mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_abs
variant = 0.5mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_abs
variant = 0.5mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_abs
variant = 0.5mm Nozzle
[values]
wall_thickness = =line_width*4

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_abs
variant = 0.6mm Nozzle
[values]
wall_thickness = =line_width*3

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_abs
variant = 0.8mm Nozzle
[values]
wall_thickness = =line_width*3

View file

@ -0,0 +1,14 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_abs
variant = 1.0mm Nozzle
[values]
wall_thickness = =line_width*3

View file

@ -0,0 +1,15 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_petg
variant = 0.2mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*8

View file

@ -0,0 +1,15 @@
[general]
version = 4
name = Ultra Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = ultra
material = generic_petg
variant = 0.2mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*8

View file

@ -0,0 +1,15 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_petg
variant = 0.3mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4

View file

@ -0,0 +1,15 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_petg
variant = 0.3mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_petg
variant = 0.3mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_petg
variant = 0.3mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_petg
variant = 0.4mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_petg
variant = 0.4mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_petg
variant = 0.4mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_petg
variant = 0.4mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_petg
variant = 0.5mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_petg
variant = 0.5mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_petg
variant = 0.5mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_petg
variant = 0.5mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*4
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_petg
variant = 0.6mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*3
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_petg
variant = 0.8mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*3
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,16 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_petg
variant = 1.0mm Nozzle
[values]
speed_layer_0 = 15
wall_thickness = =line_width*3
#retraction_extra_prime_amount = 0.5

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_pla
variant = 0.2mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Ultra Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = ultra
material = generic_pla
variant = 0.2mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_pla
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_pla
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_pla
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_pla
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_pla
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_pla
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_pla
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_pla
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_pla
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_pla
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_pla
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_pla
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_pla
variant = 0.6mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
material = generic_pla
variant = 0.6mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_pla
variant = 0.6mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_pla
variant = 0.8mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_pla
variant = 1.0mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_tpu
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_tpu
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_tpu
variant = 0.3mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_tpu
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_tpu
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_tpu
variant = 0.4mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
material = generic_tpu
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_tpu
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
material = generic_tpu
variant = 0.5mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
material = generic_tpu
variant = 0.6mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_tpu
variant = 0.8mm Nozzle
[values]

View file

@ -0,0 +1,13 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
material = generic_tpu
variant = 1.0mm Nozzle
[values]

View file

@ -0,0 +1,19 @@
[general]
version = 4
name = Dynamic Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = adaptive
weight = -2
global_quality = True
[values]
layer_height = 0.16
layer_height_0 = 0.20
top_bottom_thickness = =layer_height_0+layer_height*4
wall_thickness = =line_width*3
support_interface_height = =layer_height*6
adaptive_layer_height_enabled = true

View file

@ -0,0 +1,18 @@
[general]
version = 4
name = Draft Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = draft
weight = -5
global_quality = True
[values]
layer_height = 0.32
layer_height_0 = 0.32
top_bottom_thickness = =layer_height_0+layer_height*3
wall_thickness = =line_width*2
support_interface_height = =layer_height*4

View file

@ -0,0 +1,18 @@
[general]
version = 4
name = Low Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = low
weight = -4
global_quality = True
[values]
layer_height = 0.28
layer_height_0 = 0.28
top_bottom_thickness = =layer_height_0+layer_height*3
wall_thickness = =line_width*2
support_interface_height = =layer_height*4

View file

@ -0,0 +1,18 @@
[general]
version = 4
name = Standard Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = standard
weight = -3
global_quality = True
[values]
layer_height = 0.2
layer_height_0 = 0.2
top_bottom_thickness = =layer_height_0+layer_height*3
wall_thickness = =line_width*3
support_interface_height = =layer_height*5

View file

@ -0,0 +1,18 @@
[general]
version = 4
name = Super Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = super
weight = -1
global_quality = True
[values]
layer_height = 0.12
layer_height_0 = 0.12
top_bottom_thickness = =layer_height_0+layer_height*6
wall_thickness = =line_width*3
support_interface_height = =layer_height*8

View file

@ -0,0 +1,18 @@
[general]
version = 4
name = Ultra Quality
definition = artillery_base
[metadata]
setting_version = 16
type = quality
quality_type = ultra
weight = 0
global_quality = True
[values]
layer_height = 0.08
layer_height_0 = 0.12
top_bottom_thickness = =layer_height_0+layer_height*10
wall_thickness = =line_width*3
support_interface_height = =layer_height*12

View file

@ -0,0 +1,12 @@
[general]
name = 0.2mm Nozzle
version = 4
definition = artillery_base
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.2

View file

@ -0,0 +1,12 @@
[general]
name = 0.3mm Nozzle
version = 4
definition = artillery_base
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.3

View file

@ -0,0 +1,12 @@
[general]
name = 0.4mm Nozzle
version = 4
definition = artillery_base
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.4

View file

@ -0,0 +1,12 @@
[general]
name = 0.6mm Nozzle
version = 4
definition = artillery_base
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.6

View file

@ -0,0 +1,12 @@
[general]
name = 0.8mm Nozzle
version = 4
definition = artillery_base
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.8

View file

@ -0,0 +1,12 @@
[general]
name = 1.0mm Nozzle
version = 4
definition = artillery_base
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 1.0

View file

@ -0,0 +1,12 @@
[general]
name = 0.2mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.2

View file

@ -0,0 +1,12 @@
[general]
name = 0.3mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.3

View file

@ -0,0 +1,12 @@
[general]
name = 0.4mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.4

View file

@ -0,0 +1,12 @@
[general]
name = 0.5mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.5

View file

@ -0,0 +1,12 @@
[general]
name = 0.6mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.6

View file

@ -0,0 +1,12 @@
[general]
name = 0.8mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.8

View file

@ -0,0 +1,12 @@
[general]
name = 1.0mm Nozzle
version = 4
definition = artillery_genius
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 1.0

View file

@ -0,0 +1,12 @@
[general]
name = 0.2mm Nozzle
version = 4
definition = artillery_sidewinder_x1
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.2

View file

@ -0,0 +1,12 @@
[general]
name = 0.3mm Nozzle
version = 4
definition = artillery_sidewinder_x1
[metadata]
setting_version = 16
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.3

Some files were not shown because too many files have changed in this diff Show more