mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-06 08:26:07 +08:00
Merge remote-tracking branch 'upstream/master' into UM3NPP_merge
This commit is contained in:
commit
a0ba393673
@ -24,7 +24,7 @@ if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
|
||||
CREATE_TRANSLATION_TARGETS()
|
||||
endif()
|
||||
|
||||
find_package(PythonInterp 3.4.0 REQUIRED)
|
||||
find_package(PythonInterp 3.5.0 REQUIRED)
|
||||
|
||||
install(DIRECTORY resources
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
|
||||
|
@ -5,6 +5,7 @@ Name[de]=Cura
|
||||
GenericName=3D Printing Software
|
||||
GenericName[de]=3D-Druck-Software
|
||||
Comment=Cura converts 3D models into paths for a 3D printer. It prepares your print for maximum accuracy, minimum printing time and good reliability with many extra features that make your print come out great.
|
||||
Comment[de]=Cura wandelt 3D-Modelle in Pfade für einen 3D-Drucker um. Es bereitet Ihren Druck für maximale Genauigkeit, minimale Druckzeit und guter Zuverlässigkeit mit vielen zusätzlichen Funktionen vor, damit Ihr Druck großartig wird.
|
||||
Exec=@CMAKE_INSTALL_FULL_BINDIR@/cura %F
|
||||
TryExec=@CMAKE_INSTALL_FULL_BINDIR@/cura
|
||||
Icon=@CMAKE_INSTALL_FULL_DATADIR@/cura/resources/images/cura-icon.png
|
||||
|
@ -27,7 +27,7 @@ import UM.Settings.ContainerRegistry
|
||||
|
||||
|
||||
# Setting for clearance around the prime
|
||||
PRIME_CLEARANCE = 1.5
|
||||
PRIME_CLEARANCE = 6.5
|
||||
|
||||
|
||||
## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas.
|
||||
@ -75,8 +75,8 @@ class BuildVolume(SceneNode):
|
||||
self._has_errors = False
|
||||
Application.getInstance().getController().getScene().sceneChanged.connect(self._onSceneChanged)
|
||||
|
||||
# Number of objects loaded at the moment.
|
||||
self._number_of_objects = 0
|
||||
#Objects loaded at the moment. We are connected to the property changed events of these objects.
|
||||
self._scene_objects = set()
|
||||
|
||||
self._change_timer = QTimer()
|
||||
self._change_timer.setInterval(100)
|
||||
@ -102,14 +102,33 @@ class BuildVolume(SceneNode):
|
||||
|
||||
def _onChangeTimerFinished(self):
|
||||
root = Application.getInstance().getController().getScene().getRoot()
|
||||
new_number_of_objects = len([node for node in BreadthFirstIterator(root) if node.getMeshData() and type(node) is SceneNode])
|
||||
if new_number_of_objects != self._number_of_objects:
|
||||
recalculate = False
|
||||
if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time":
|
||||
recalculate = (new_number_of_objects < 2 and self._number_of_objects > 1) or (new_number_of_objects > 1 and self._number_of_objects < 2)
|
||||
self._number_of_objects = new_number_of_objects
|
||||
if recalculate:
|
||||
self._onSettingPropertyChanged("print_sequence", "value") # Create fake event, so right settings are triggered.
|
||||
new_scene_objects = set(node for node in BreadthFirstIterator(root) if node.getMeshData() and type(node) is SceneNode)
|
||||
if new_scene_objects != self._scene_objects:
|
||||
for node in new_scene_objects - self._scene_objects: #Nodes that were added to the scene.
|
||||
node.decoratorsChanged.connect(self._onNodeDecoratorChanged)
|
||||
for node in self._scene_objects - new_scene_objects: #Nodes that were removed from the scene.
|
||||
per_mesh_stack = node.callDecoration("getStack")
|
||||
if per_mesh_stack:
|
||||
per_mesh_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
||||
active_extruder_changed = node.callDecoration("getActiveExtruderChangedSignal")
|
||||
if active_extruder_changed is not None:
|
||||
node.callDecoration("getActiveExtruderChangedSignal").disconnect(self._updateDisallowedAreasAndRebuild)
|
||||
node.decoratorsChanged.disconnect(self._onNodeDecoratorChanged)
|
||||
|
||||
self._scene_objects = new_scene_objects
|
||||
self._onSettingPropertyChanged("print_sequence", "value") # Create fake event, so right settings are triggered.
|
||||
|
||||
## Updates the listeners that listen for changes in per-mesh stacks.
|
||||
#
|
||||
# \param node The node for which the decorators changed.
|
||||
def _onNodeDecoratorChanged(self, node):
|
||||
per_mesh_stack = node.callDecoration("getStack")
|
||||
if per_mesh_stack:
|
||||
per_mesh_stack.propertyChanged.connect(self._onSettingPropertyChanged)
|
||||
active_extruder_changed = node.callDecoration("getActiveExtruderChangedSignal")
|
||||
if active_extruder_changed is not None:
|
||||
active_extruder_changed.connect(self._updateDisallowedAreasAndRebuild)
|
||||
self._updateDisallowedAreasAndRebuild()
|
||||
|
||||
def setWidth(self, width):
|
||||
if width: self._width = width
|
||||
@ -324,7 +343,7 @@ class BuildVolume(SceneNode):
|
||||
|
||||
self._width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_height = self._global_container_stack.getProperty("machine_height", "value")
|
||||
if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time" and self._number_of_objects > 1:
|
||||
if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
|
||||
self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
|
||||
if self._height < machine_height:
|
||||
self._build_volume_message.show()
|
||||
@ -347,7 +366,7 @@ class BuildVolume(SceneNode):
|
||||
rebuild_me = False
|
||||
if setting_key == "print_sequence":
|
||||
machine_height = self._global_container_stack.getProperty("machine_height", "value")
|
||||
if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and self._number_of_objects > 1:
|
||||
if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
|
||||
self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
|
||||
if self._height < machine_height:
|
||||
self._build_volume_message.show()
|
||||
@ -358,7 +377,7 @@ class BuildVolume(SceneNode):
|
||||
self._build_volume_message.hide()
|
||||
rebuild_me = True
|
||||
|
||||
if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence" or setting_key in self._ooze_shield_settings or setting_key in self._distance_settings:
|
||||
if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence" or setting_key in self._ooze_shield_settings or setting_key in self._distance_settings or setting_key in self._extruder_settings:
|
||||
self._updateDisallowedAreas()
|
||||
rebuild_me = True
|
||||
|
||||
@ -372,24 +391,109 @@ class BuildVolume(SceneNode):
|
||||
def hasErrors(self):
|
||||
return self._has_errors
|
||||
|
||||
## Calls _updateDisallowedAreas and makes sure the changes appear in the
|
||||
# scene.
|
||||
#
|
||||
# This is required for a signal to trigger the update in one go. The
|
||||
# ``_updateDisallowedAreas`` method itself shouldn't call ``rebuild``,
|
||||
# since there may be other changes before it needs to be rebuilt, which
|
||||
# would hit performance.
|
||||
def _updateDisallowedAreasAndRebuild(self):
|
||||
self._updateDisallowedAreas()
|
||||
self.rebuild()
|
||||
|
||||
def _updateDisallowedAreas(self):
|
||||
if not self._global_container_stack:
|
||||
return
|
||||
|
||||
self._has_errors = False # Reset.
|
||||
self._error_areas = []
|
||||
disallowed_areas = copy.deepcopy(
|
||||
self._global_container_stack.getProperty("machine_disallowed_areas", "value"))
|
||||
areas = []
|
||||
|
||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||
prime_tower_area = None
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
used_extruders = extruder_manager.getUsedExtruderStacks()
|
||||
disallowed_border_size = self._getEdgeDisallowedSize()
|
||||
|
||||
result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) #Normal machine disallowed areas can always be added.
|
||||
prime_areas = self._computeDisallowedAreasPrime(disallowed_border_size, used_extruders)
|
||||
prime_disallowed_areas = self._computeDisallowedAreasStatic(0, used_extruders) #Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
|
||||
|
||||
#Check if prime positions intersect with disallowed areas.
|
||||
for extruder in used_extruders:
|
||||
extruder_id = extruder.getId()
|
||||
|
||||
collision = False
|
||||
for prime_polygon in prime_areas[extruder_id]:
|
||||
for disallowed_polygon in prime_disallowed_areas[extruder_id]:
|
||||
if prime_polygon.intersectsPolygon(disallowed_polygon) is not None:
|
||||
collision = True
|
||||
break
|
||||
if collision:
|
||||
break
|
||||
|
||||
#Also check other prime positions (without additional offset).
|
||||
for other_extruder_id in prime_areas:
|
||||
if extruder_id == other_extruder_id: #It is allowed to collide with itself.
|
||||
continue
|
||||
for other_prime_polygon in prime_areas[other_extruder_id]:
|
||||
if prime_polygon.intersectsPolygon(other_prime_polygon):
|
||||
collision = True
|
||||
break
|
||||
if collision:
|
||||
break
|
||||
if collision:
|
||||
break
|
||||
|
||||
|
||||
if not collision:
|
||||
#Prime areas are valid. Add as normal.
|
||||
result_areas[extruder_id].extend(prime_areas[extruder_id])
|
||||
|
||||
nozzle_disallowed_areas = extruder.getProperty("nozzle_disallowed_areas", "value")
|
||||
for area in nozzle_disallowed_areas:
|
||||
polygon = Polygon(numpy.array(area, numpy.float32))
|
||||
polygon = polygon.getMinkowskiHull(Polygon.approximatedCircle(disallowed_border_size))
|
||||
result_areas[extruder_id].append(polygon) #Don't perform the offset on these.
|
||||
|
||||
# Add prime tower location as disallowed area.
|
||||
prime_tower_collision = False
|
||||
prime_tower_areas = self._computeDisallowedAreasPrinted(used_extruders)
|
||||
for extruder_id in prime_tower_areas:
|
||||
for prime_tower_area in prime_tower_areas[extruder_id]:
|
||||
for area in result_areas[extruder_id]:
|
||||
if prime_tower_area.intersectsPolygon(area) is not None:
|
||||
prime_tower_collision = True
|
||||
break
|
||||
if prime_tower_collision: #Already found a collision.
|
||||
break
|
||||
if not prime_tower_collision:
|
||||
result_areas[extruder_id].extend(prime_tower_areas[extruder_id])
|
||||
else:
|
||||
self._error_areas.extend(prime_tower_areas[extruder_id])
|
||||
|
||||
self._has_errors = len(self._error_areas) > 0
|
||||
|
||||
self._disallowed_areas = []
|
||||
for extruder_id in result_areas:
|
||||
self._disallowed_areas.extend(result_areas[extruder_id])
|
||||
|
||||
## Computes the disallowed areas for objects that are printed with print
|
||||
# features.
|
||||
#
|
||||
# This means that the brim, travel avoidance and such will be applied to
|
||||
# these features.
|
||||
#
|
||||
# \return A dictionary with for each used extruder ID the disallowed areas
|
||||
# where that extruder may not print.
|
||||
def _computeDisallowedAreasPrinted(self, used_extruders):
|
||||
result = {}
|
||||
for extruder in used_extruders:
|
||||
result[extruder.getId()] = []
|
||||
|
||||
#Currently, the only normally printed object is the prime tower.
|
||||
if ExtruderManager.getInstance().getResolveOrValue("prime_tower_enable") == True:
|
||||
prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value")
|
||||
prime_tower_x = self._global_container_stack.getProperty("prime_tower_position_x", "value") - machine_width / 2
|
||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||
prime_tower_x = self._global_container_stack.getProperty("prime_tower_position_x", "value") - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
|
||||
prime_tower_y = - self._global_container_stack.getProperty("prime_tower_position_y", "value") + machine_depth / 2
|
||||
|
||||
prime_tower_area = Polygon([
|
||||
@ -398,118 +502,118 @@ class BuildVolume(SceneNode):
|
||||
[prime_tower_x, prime_tower_y],
|
||||
[prime_tower_x - prime_tower_size, prime_tower_y],
|
||||
])
|
||||
disallowed_polygons = []
|
||||
prime_tower_area = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(0))
|
||||
for extruder in used_extruders:
|
||||
result[extruder.getId()].append(prime_tower_area) #The prime tower location is the same for each extruder, regardless of offset.
|
||||
|
||||
# Check if prime positions intersect with disallowed areas
|
||||
prime_collision = False
|
||||
if disallowed_areas:
|
||||
for area in disallowed_areas:
|
||||
poly = Polygon(numpy.array(area, numpy.float32))
|
||||
return result
|
||||
|
||||
# Minkowski with zero, to ensure that the polygon is correct & watertight.
|
||||
poly = poly.getMinkowskiHull(Polygon.approximatedCircle(0))
|
||||
disallowed_polygons.append(poly)
|
||||
## Computes the disallowed areas for the prime locations.
|
||||
#
|
||||
# These are special because they are not subject to things like brim or
|
||||
# travel avoidance. They do get a dilute with the border size though
|
||||
# because they may not intersect with brims and such of other objects.
|
||||
#
|
||||
# \param border_size The size with which to offset the disallowed areas
|
||||
# due to skirt, brim, travel avoid distance, etc.
|
||||
# \param used_extruders The extruder stacks to generate disallowed areas
|
||||
# for.
|
||||
# \return A dictionary with for each used extruder ID the prime areas.
|
||||
def _computeDisallowedAreasPrime(self, border_size, used_extruders):
|
||||
result = {}
|
||||
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
extruders = extruder_manager.getMachineExtruders(self._global_container_stack.getId())
|
||||
prime_polygons = []
|
||||
# Each extruder has it's own prime location
|
||||
for extruder in extruders:
|
||||
prime_x = extruder.getProperty("extruder_prime_pos_x", "value") - machine_width / 2
|
||||
prime_y = machine_depth / 2 - extruder.getProperty("extruder_prime_pos_y", "value")
|
||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||
for extruder in used_extruders:
|
||||
prime_x = extruder.getProperty("extruder_prime_pos_x", "value") - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
|
||||
prime_y = machine_depth / 2 - extruder.getProperty("extruder_prime_pos_y", "value")
|
||||
|
||||
prime_polygon = Polygon([
|
||||
[prime_x - PRIME_CLEARANCE, prime_y - PRIME_CLEARANCE],
|
||||
[prime_x + PRIME_CLEARANCE, prime_y - PRIME_CLEARANCE],
|
||||
[prime_x + PRIME_CLEARANCE, prime_y + PRIME_CLEARANCE],
|
||||
[prime_x - PRIME_CLEARANCE, prime_y + PRIME_CLEARANCE],
|
||||
])
|
||||
prime_polygon = prime_polygon.getMinkowskiHull(Polygon.approximatedCircle(0))
|
||||
collision = False
|
||||
prime_polygon = Polygon.approximatedCircle(PRIME_CLEARANCE)
|
||||
prime_polygon = prime_polygon.translate(prime_x, prime_y)
|
||||
prime_polygon = prime_polygon.getMinkowskiHull(Polygon.approximatedCircle(border_size))
|
||||
result[extruder.getId()] = [prime_polygon]
|
||||
|
||||
# Check if prime polygon is intersecting with any of the other disallowed areas.
|
||||
# Note that we check the prime area without bed adhesion.
|
||||
for poly in disallowed_polygons:
|
||||
if prime_polygon.intersectsPolygon(poly) is not None:
|
||||
collision = True
|
||||
break
|
||||
return result
|
||||
|
||||
# Also collide with other prime positions
|
||||
for poly in prime_polygons:
|
||||
if prime_polygon.intersectsPolygon(poly) is not None:
|
||||
collision = True
|
||||
break
|
||||
## Computes the disallowed areas that are statically placed in the machine.
|
||||
#
|
||||
# It computes different disallowed areas depending on the offset of the
|
||||
# extruder. The resulting dictionary will therefore have an entry for each
|
||||
# extruder that is used.
|
||||
#
|
||||
# \param border_size The size with which to offset the disallowed areas
|
||||
# due to skirt, brim, travel avoid distance, etc.
|
||||
# \param used_extruders The extruder stacks to generate disallowed areas
|
||||
# for.
|
||||
# \return A dictionary with for each used extruder ID the disallowed areas
|
||||
# where that extruder may not print.
|
||||
def _computeDisallowedAreasStatic(self, border_size, used_extruders):
|
||||
#Convert disallowed areas to polygons and dilate them.
|
||||
machine_disallowed_polygons = []
|
||||
for area in self._global_container_stack.getProperty("machine_disallowed_areas", "value"):
|
||||
polygon = Polygon(numpy.array(area, numpy.float32))
|
||||
polygon = polygon.getMinkowskiHull(Polygon.approximatedCircle(border_size))
|
||||
machine_disallowed_polygons.append(polygon)
|
||||
|
||||
if not collision:
|
||||
# Prime area is valid. Add as normal.
|
||||
# Once it's added like this, it will recieve a bed adhesion offset, just like the others.
|
||||
prime_polygons.append(prime_polygon)
|
||||
else:
|
||||
self._error_areas.append(prime_polygon)
|
||||
prime_collision = collision or prime_collision
|
||||
result = {}
|
||||
for extruder in used_extruders:
|
||||
extruder_id = extruder.getId()
|
||||
offset_x = extruder.getProperty("machine_nozzle_offset_x", "value")
|
||||
if offset_x is None:
|
||||
offset_x = 0
|
||||
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
|
||||
if offset_y is None:
|
||||
offset_y = 0
|
||||
result[extruder_id] = []
|
||||
|
||||
disallowed_polygons.extend(prime_polygons)
|
||||
for polygon in machine_disallowed_polygons:
|
||||
result[extruder_id].append(polygon.translate(offset_x, offset_y)) #Compensate for the nozzle offset of this extruder.
|
||||
|
||||
disallowed_border_size = self._getEdgeDisallowedSize()
|
||||
|
||||
# Extend every area already in the disallowed_areas with the skirt size.
|
||||
if disallowed_areas:
|
||||
for poly in disallowed_polygons:
|
||||
poly = poly.getMinkowskiHull(Polygon.approximatedCircle(disallowed_border_size))
|
||||
areas.append(poly)
|
||||
|
||||
# Add the skirt areas around the borders of the build plate.
|
||||
if disallowed_border_size > 0:
|
||||
#Add the border around the edge of the build volume.
|
||||
left_unreachable_border = 0
|
||||
right_unreachable_border = 0
|
||||
top_unreachable_border = 0
|
||||
bottom_unreachable_border = 0
|
||||
#The build volume is defined as the union of the area that all extruders can reach, so we need to know the relative offset to all extruders.
|
||||
for other_extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||
other_offset_x = other_extruder.getProperty("machine_nozzle_offset_x", "value")
|
||||
other_offset_y = other_extruder.getProperty("machine_nozzle_offset_y", "value")
|
||||
left_unreachable_border = min(left_unreachable_border, other_offset_x - offset_x)
|
||||
right_unreachable_border = max(right_unreachable_border, other_offset_x - offset_x)
|
||||
top_unreachable_border = min(top_unreachable_border, other_offset_y - offset_y)
|
||||
bottom_unreachable_border = max(bottom_unreachable_border, other_offset_y - offset_y)
|
||||
half_machine_width = self._global_container_stack.getProperty("machine_width", "value") / 2
|
||||
half_machine_depth = self._global_container_stack.getProperty("machine_depth", "value") / 2
|
||||
if border_size - left_unreachable_border > 0:
|
||||
result[extruder_id].append(Polygon(numpy.array([
|
||||
[-half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width, half_machine_depth],
|
||||
[-half_machine_width + border_size - left_unreachable_border, half_machine_depth - border_size - bottom_unreachable_border],
|
||||
[-half_machine_width + border_size - left_unreachable_border, -half_machine_depth + border_size - top_unreachable_border]
|
||||
], numpy.float32)))
|
||||
if border_size + right_unreachable_border > 0:
|
||||
result[extruder_id].append(Polygon(numpy.array([
|
||||
[half_machine_width, half_machine_depth],
|
||||
[half_machine_width, -half_machine_depth],
|
||||
[half_machine_width - border_size - right_unreachable_border, -half_machine_depth + border_size - top_unreachable_border],
|
||||
[half_machine_width - border_size - right_unreachable_border, half_machine_depth - border_size - bottom_unreachable_border]
|
||||
], numpy.float32)))
|
||||
if border_size + bottom_unreachable_border > 0:
|
||||
result[extruder_id].append(Polygon(numpy.array([
|
||||
[-half_machine_width, half_machine_depth],
|
||||
[half_machine_width, half_machine_depth],
|
||||
[half_machine_width - border_size - right_unreachable_border, half_machine_depth - border_size - bottom_unreachable_border],
|
||||
[-half_machine_width + border_size - left_unreachable_border, half_machine_depth - border_size - bottom_unreachable_border]
|
||||
], numpy.float32)))
|
||||
if border_size - top_unreachable_border > 0:
|
||||
result[extruder_id].append(Polygon(numpy.array([
|
||||
[half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width + border_size - left_unreachable_border, -half_machine_depth + border_size - top_unreachable_border],
|
||||
[half_machine_width - border_size - right_unreachable_border, -half_machine_depth + border_size - top_unreachable_border]
|
||||
], numpy.float32)))
|
||||
|
||||
areas.append(Polygon(numpy.array([
|
||||
[-half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width, half_machine_depth],
|
||||
[-half_machine_width + disallowed_border_size, half_machine_depth - disallowed_border_size],
|
||||
[-half_machine_width + disallowed_border_size, -half_machine_depth + disallowed_border_size]
|
||||
], numpy.float32)))
|
||||
|
||||
areas.append(Polygon(numpy.array([
|
||||
[half_machine_width, half_machine_depth],
|
||||
[half_machine_width, -half_machine_depth],
|
||||
[half_machine_width - disallowed_border_size, -half_machine_depth + disallowed_border_size],
|
||||
[half_machine_width - disallowed_border_size, half_machine_depth - disallowed_border_size]
|
||||
], numpy.float32)))
|
||||
|
||||
areas.append(Polygon(numpy.array([
|
||||
[-half_machine_width, half_machine_depth],
|
||||
[half_machine_width, half_machine_depth],
|
||||
[half_machine_width - disallowed_border_size, half_machine_depth - disallowed_border_size],
|
||||
[-half_machine_width + disallowed_border_size, half_machine_depth - disallowed_border_size]
|
||||
], numpy.float32)))
|
||||
|
||||
areas.append(Polygon(numpy.array([
|
||||
[half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width, -half_machine_depth],
|
||||
[-half_machine_width + disallowed_border_size, -half_machine_depth + disallowed_border_size],
|
||||
[half_machine_width - disallowed_border_size, -half_machine_depth + disallowed_border_size]
|
||||
], numpy.float32)))
|
||||
|
||||
# Check if the prime tower area intersects with any of the other areas.
|
||||
# If this is the case, add it to the error area's so it can be drawn in red.
|
||||
# If not, add it back to disallowed area's, so it's rendered as normal.
|
||||
prime_tower_collision = False
|
||||
if prime_tower_area:
|
||||
# Using Minkowski of 0 fixes the prime tower area so it's rendered correctly
|
||||
prime_tower_area = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(0))
|
||||
for area in areas:
|
||||
if prime_tower_area.intersectsPolygon(area) is not None:
|
||||
prime_tower_collision = True
|
||||
break
|
||||
|
||||
if not prime_tower_collision:
|
||||
areas.append(prime_tower_area)
|
||||
else:
|
||||
self._error_areas.append(prime_tower_area)
|
||||
# The buildplate has errors if either prime tower or prime has a colission.
|
||||
self._has_errors = prime_tower_collision or prime_collision
|
||||
self._disallowed_areas = areas
|
||||
return result
|
||||
|
||||
## Private convenience function to get a setting from the adhesion
|
||||
# extruder.
|
||||
@ -520,6 +624,15 @@ class BuildVolume(SceneNode):
|
||||
def _getSettingFromAdhesionExtruder(self, setting_key, property = "value"):
|
||||
return self._getSettingFromExtruder(setting_key, "adhesion_extruder_nr", property)
|
||||
|
||||
## Private convenience function to get a setting from every extruder.
|
||||
#
|
||||
# For single extrusion machines, this gets the setting from the global
|
||||
# stack.
|
||||
#
|
||||
# \return A sequence of setting values, one for each extruder.
|
||||
def _getSettingFromAllExtruders(self, setting_key, property = "value"):
|
||||
return ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property)
|
||||
|
||||
## Private convenience function to get a setting from the support infill
|
||||
# extruder.
|
||||
#
|
||||
@ -588,6 +701,8 @@ class BuildVolume(SceneNode):
|
||||
bed_adhesion_size += value
|
||||
elif adhesion_type == "raft":
|
||||
bed_adhesion_size = self._getSettingFromAdhesionExtruder("raft_margin")
|
||||
elif adhesion_type == "none":
|
||||
bed_adhesion_size = 0
|
||||
else:
|
||||
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
|
||||
|
||||
@ -602,10 +717,12 @@ class BuildVolume(SceneNode):
|
||||
farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("ooze_shield_dist", "value"))
|
||||
|
||||
move_from_wall_radius = 0 # Moves that start from outer wall.
|
||||
if self._getSettingFromAdhesionExtruder("infill_wipe_dist"):
|
||||
move_from_wall_radius = max(move_from_wall_radius, self._getSettingFromAdhesionExtruder("infill_wipe_dist"))
|
||||
if self._getSettingFromAdhesionExtruder("travel_avoid_distance") and self._getSettingFromAdhesionExtruder("travel_avoid_other_parts"):
|
||||
move_from_wall_radius = max(move_from_wall_radius, self._getSettingFromAdhesionExtruder("travel_avoid_distance"))
|
||||
move_from_wall_radius = max(move_from_wall_radius, max(self._getSettingFromAllExtruders("infill_wipe_dist")))
|
||||
avoid_enabled_per_extruder = self._getSettingFromAllExtruders(("travel_avoid_other_parts"))
|
||||
avoid_distance_per_extruder = self._getSettingFromAllExtruders("travel_avoid_distance")
|
||||
for index, avoid_other_parts_enabled in enumerate(avoid_enabled_per_extruder): #For each extruder (or just global).
|
||||
if avoid_other_parts_enabled:
|
||||
move_from_wall_radius = max(move_from_wall_radius, avoid_distance_per_extruder[index]) #Index of the same extruder.
|
||||
|
||||
#Now combine our different pieces of data to get the final border size.
|
||||
#Support expansion is added to the bed adhesion, since the bed adhesion goes around support.
|
||||
@ -622,3 +739,4 @@ class BuildVolume(SceneNode):
|
||||
_tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y"]
|
||||
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
|
||||
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts"]
|
||||
_extruder_settings = ["support_enable", "support_interface_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_interface_extruder_nr", "brim_line_count", "adhesion_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used.
|
@ -236,6 +236,8 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
||||
extra_margin = max(0, self._getSettingProperty("raft_margin", "value"))
|
||||
elif adhesion_type == "brim":
|
||||
extra_margin = max(0, self._getSettingProperty("brim_line_count", "value") * self._getSettingProperty("skirt_brim_line_width", "value"))
|
||||
elif adhesion_type == "none":
|
||||
extra_margin = 0
|
||||
elif adhesion_type == "skirt":
|
||||
extra_margin = max(
|
||||
0, self._getSettingProperty("skirt_gap", "value") +
|
||||
|
@ -258,7 +258,7 @@ class CuraApplication(QtApplication):
|
||||
|
||||
Preferences.getInstance().setDefault("general/visible_settings", """
|
||||
machine_settings
|
||||
resolution
|
||||
resolution
|
||||
layer_height
|
||||
shell
|
||||
wall_thickness
|
||||
@ -558,7 +558,9 @@ class CuraApplication(QtApplication):
|
||||
|
||||
qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager)
|
||||
|
||||
qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions")
|
||||
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
|
||||
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
|
||||
qmlRegisterSingletonType(actions_url, "Cura", 1, 0, "Actions")
|
||||
|
||||
engine.rootContext().setContextProperty("ExtruderManager", cura.Settings.ExtruderManager.getInstance())
|
||||
|
||||
@ -571,11 +573,19 @@ class CuraApplication(QtApplication):
|
||||
|
||||
def onSelectionChanged(self):
|
||||
if Selection.hasSelection():
|
||||
if not self.getController().getActiveTool():
|
||||
if self.getController().getActiveTool():
|
||||
# If the tool has been disabled by the new selection
|
||||
if not self.getController().getActiveTool().getEnabled():
|
||||
# Default
|
||||
self.getController().setActiveTool("TranslateTool")
|
||||
else:
|
||||
if self._previous_active_tool:
|
||||
self.getController().setActiveTool(self._previous_active_tool)
|
||||
if not self.getController().getActiveTool().getEnabled():
|
||||
self.getController().setActiveTool("TranslateTool")
|
||||
self._previous_active_tool = None
|
||||
else:
|
||||
# Default
|
||||
self.getController().setActiveTool("TranslateTool")
|
||||
if Preferences.getInstance().getValue("view/center_on_select"):
|
||||
self._center_after_select = True
|
||||
@ -686,10 +696,9 @@ class CuraApplication(QtApplication):
|
||||
while current_node.getParent() and current_node.getParent().callDecoration("isGroup"):
|
||||
current_node = current_node.getParent()
|
||||
|
||||
new_node = copy.deepcopy(current_node)
|
||||
|
||||
op = GroupedOperation()
|
||||
for _ in range(count):
|
||||
new_node = copy.deepcopy(current_node)
|
||||
op.addOperation(AddSceneNodeOperation(new_node, current_node.getParent()))
|
||||
op.push()
|
||||
|
||||
@ -770,7 +779,11 @@ class CuraApplication(QtApplication):
|
||||
for node in nodes:
|
||||
# Ensure that the object is above the build platform
|
||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0)))
|
||||
if node.getBoundingBox():
|
||||
center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
|
||||
else:
|
||||
center_y = 0
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0)))
|
||||
op.push()
|
||||
|
||||
## Reset all transformations on nodes with mesh data.
|
||||
@ -792,11 +805,10 @@ class CuraApplication(QtApplication):
|
||||
for node in nodes:
|
||||
# Ensure that the object is above the build platform
|
||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||
center_y = 0
|
||||
if node.callDecoration("isGroup"):
|
||||
if node.getBoundingBox():
|
||||
center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
|
||||
else:
|
||||
center_y = node.getMeshData().getCenterPosition().y
|
||||
center_y = 0
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1)))
|
||||
op.push()
|
||||
|
||||
@ -865,8 +877,15 @@ class CuraApplication(QtApplication):
|
||||
Logger.log("d", "mergeSelected: Exception:", e)
|
||||
return
|
||||
|
||||
# Compute the center of the objects when their origins are aligned.
|
||||
object_centers = [node.getMeshData().getCenterPosition().scale(node.getScale()) for node in group_node.getChildren() if node.getMeshData()]
|
||||
meshes = [node.getMeshData() for node in group_node.getAllChildren() if node.getMeshData()]
|
||||
|
||||
# Compute the center of the objects
|
||||
object_centers = []
|
||||
for mesh, node in zip(meshes, group_node.getChildren()):
|
||||
orientation = node.getOrientation().toMatrix()
|
||||
rotated_mesh = mesh.getTransformed(orientation)
|
||||
center = rotated_mesh.getCenterPosition().scale(node.getScale())
|
||||
object_centers.append(center)
|
||||
if object_centers and len(object_centers) > 0:
|
||||
middle_x = sum([v.x for v in object_centers]) / len(object_centers)
|
||||
middle_y = sum([v.y for v in object_centers]) / len(object_centers)
|
||||
@ -876,9 +895,13 @@ class CuraApplication(QtApplication):
|
||||
offset = Vector(0, 0, 0)
|
||||
|
||||
# Move each node to the same position.
|
||||
for center, node in zip(object_centers, group_node.getChildren()):
|
||||
# Align the object and also apply the offset to center it inside the group.
|
||||
node.setPosition(center - offset)
|
||||
for mesh, node in zip(meshes, group_node.getChildren()):
|
||||
orientation = node.getOrientation().toMatrix()
|
||||
rotated_mesh = mesh.getTransformed(orientation)
|
||||
|
||||
# Align the object around its zero position
|
||||
# and also apply the offset to center it inside the group.
|
||||
node.setPosition(-rotated_mesh.getZeroPosition().scale(node.getScale()) - offset)
|
||||
|
||||
# Use the previously found center of the group bounding box as the new location of the group
|
||||
group_node.setPosition(group_node.getBoundingBox().center)
|
||||
@ -932,15 +955,16 @@ class CuraApplication(QtApplication):
|
||||
fileLoaded = pyqtSignal(str)
|
||||
|
||||
def _onFileLoaded(self, job):
|
||||
node = job.getResult()
|
||||
if node != None:
|
||||
self.fileLoaded.emit(job.getFileName())
|
||||
node.setSelectable(True)
|
||||
node.setName(os.path.basename(job.getFileName()))
|
||||
op = AddSceneNodeOperation(node, self.getController().getScene().getRoot())
|
||||
op.push()
|
||||
nodes = job.getResult()
|
||||
for node in nodes:
|
||||
if node is not None:
|
||||
self.fileLoaded.emit(job.getFileName())
|
||||
node.setSelectable(True)
|
||||
node.setName(os.path.basename(job.getFileName()))
|
||||
op = AddSceneNodeOperation(node, self.getController().getScene().getRoot())
|
||||
op.push()
|
||||
|
||||
self.getController().getScene().sceneChanged.emit(node) #Force scene change.
|
||||
self.getController().getScene().sceneChanged.emit(node) #Force scene change.
|
||||
|
||||
def _onJobFinished(self, job):
|
||||
if type(job) is not ReadMeshJob or not job.getResult():
|
||||
|
@ -134,6 +134,20 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
||||
def _setJobState(self, job_state):
|
||||
Logger.log("w", "_setJobState is not implemented by this output device")
|
||||
|
||||
@pyqtSlot()
|
||||
def startCamera(self):
|
||||
self._startCamera()
|
||||
|
||||
def _startCamera(self):
|
||||
Logger.log("w", "_startCamera is not implemented by this output device")
|
||||
|
||||
@pyqtSlot()
|
||||
def stopCamera(self):
|
||||
self._stopCamera()
|
||||
|
||||
def _stopCamera(self):
|
||||
Logger.log("w", "_stopCamera is not implemented by this output device")
|
||||
|
||||
@pyqtProperty(str, notify = jobNameChanged)
|
||||
def jobName(self):
|
||||
return self._job_name
|
||||
|
@ -27,10 +27,17 @@ class QualityManager:
|
||||
# specified then the currently selected machine definition is used.
|
||||
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
|
||||
# the current set of selected materials is used.
|
||||
# \return the matching quality containers \type{List[ContainerInstance]}
|
||||
# \return the matching quality container \type{ContainerInstance}
|
||||
def findQualityByName(self, quality_name, machine_definition=None, material_containers=None):
|
||||
criteria = {"type": "quality", "name": quality_name}
|
||||
return self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
||||
result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
||||
|
||||
# Fall back to using generic materials and qualities if nothing could be found.
|
||||
if not result and material_containers and len(material_containers) == 1:
|
||||
basic_materials = self._getBasicMaterials(material_containers[0])
|
||||
result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria)
|
||||
|
||||
return result[0] if result else None
|
||||
|
||||
## Find a quality changes container by name.
|
||||
#
|
||||
|
@ -4,7 +4,7 @@
|
||||
import os.path
|
||||
import urllib
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal, QUrl
|
||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal, QUrl, QVariant
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
import UM.PluginRegistry
|
||||
@ -261,8 +261,9 @@ class ContainerManager(QObject):
|
||||
|
||||
@pyqtSlot(str, result = bool)
|
||||
def isContainerUsed(self, container_id):
|
||||
UM.Logger.log("d", "Checking if container %s is currently used in the active stacks", container_id)
|
||||
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
UM.Logger.log("d", "Checking if container %s is currently used", container_id)
|
||||
containers = self._container_registry.findContainerStacks()
|
||||
for stack in containers:
|
||||
if container_id in [child.getId() for child in stack.getContainers()]:
|
||||
UM.Logger.log("d", "The container is in use by %s", stack.getId())
|
||||
return True
|
||||
@ -611,13 +612,12 @@ class ContainerManager(QObject):
|
||||
|
||||
if base_name is None:
|
||||
base_name = quality_name
|
||||
|
||||
# Try to find a Quality with the name.
|
||||
containers = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances)
|
||||
if containers:
|
||||
container = containers[0]
|
||||
container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances)
|
||||
if container:
|
||||
UM.Logger.log("d", "We found a quality to duplicate.")
|
||||
return self._duplicateQualityForMachineType(container, base_name, machine_definition)
|
||||
|
||||
UM.Logger.log("d", "We found a quality_changes to duplicate.")
|
||||
# Assume it is a quality changes.
|
||||
return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition)
|
||||
|
||||
@ -791,7 +791,6 @@ class ContainerManager(QObject):
|
||||
|
||||
# Create a new quality_changes container for the quality.
|
||||
quality_changes = UM.Settings.InstanceContainer(self._createUniqueId(base_id, new_name))
|
||||
print(quality_changes.getId())
|
||||
quality_changes.setName(new_name)
|
||||
quality_changes.addMetaDataEntry("type", "quality_changes")
|
||||
quality_changes.addMetaDataEntry("quality_type", quality_container.getMetaDataEntry("quality_type"))
|
||||
@ -806,3 +805,50 @@ class ContainerManager(QObject):
|
||||
else:
|
||||
quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition))
|
||||
return quality_changes
|
||||
|
||||
|
||||
## Import profiles from a list of file_urls.
|
||||
# Each QUrl item must end with .curaprofile, or it will not be imported.
|
||||
#
|
||||
# \param QVariant<QUrl>, essentially a list with QUrl objects.
|
||||
# \return Dict with keys status, text
|
||||
@pyqtSlot(QVariant, result="QVariantMap")
|
||||
def importProfiles(self, file_urls):
|
||||
status = "ok"
|
||||
results = {"ok": [], "error": []}
|
||||
for file_url in file_urls:
|
||||
if not file_url.isValid():
|
||||
continue
|
||||
path = file_url.toLocalFile()
|
||||
if not path:
|
||||
continue
|
||||
if not path.endswith(".curaprofile"):
|
||||
continue
|
||||
|
||||
single_result = UM.Settings.ContainerRegistry.getInstance().importProfile(path)
|
||||
if single_result["status"] == "error":
|
||||
status = "error"
|
||||
results[single_result["status"]].append(single_result["message"])
|
||||
|
||||
return {
|
||||
"status": status,
|
||||
"message": "\n".join(results["ok"] + results["error"])}
|
||||
|
||||
## Import single profile, file_url does not have to end with curaprofile
|
||||
@pyqtSlot(QUrl, result="QVariantMap")
|
||||
def importProfile(self, file_url):
|
||||
if not file_url.isValid():
|
||||
return
|
||||
path = file_url.toLocalFile()
|
||||
if not path:
|
||||
return
|
||||
return UM.Settings.ContainerRegistry.getInstance().importProfile(path)
|
||||
|
||||
@pyqtSlot("QVariantList", QUrl, str)
|
||||
def exportProfile(self, instance_id, file_url, file_type):
|
||||
if not file_url.isValid():
|
||||
return
|
||||
path = file_url.toLocalFile()
|
||||
if not path:
|
||||
return
|
||||
UM.Settings.ContainerRegistry.getInstance().exportProfile(instance_id, path, file_type)
|
||||
|
@ -210,7 +210,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||
return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())}
|
||||
|
||||
# If it hasn't returned by now, none of the plugins loaded the profile successfully.
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type.", file_name)}
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name)}
|
||||
|
||||
def _configureProfile(self, profile, id_seed, new_name):
|
||||
profile.setReadOnly(False)
|
||||
|
@ -5,6 +5,8 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject, QVariant #
|
||||
|
||||
import UM.Application #To get the global container stack to find the current machine.
|
||||
import UM.Logger
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator #To find which extruders are used in the scene.
|
||||
from UM.Scene.SceneNode import SceneNode #To find which extruders are used in the scene.
|
||||
import UM.Settings.ContainerRegistry #Finding containers by ID.
|
||||
import UM.Settings.SettingFunction
|
||||
|
||||
@ -268,18 +270,78 @@ class ExtruderManager(QObject):
|
||||
container_registry.addContainer(container_stack)
|
||||
|
||||
def getAllExtruderValues(self, setting_key):
|
||||
return self.getAllExtruderSettings(setting_key, "value")
|
||||
|
||||
## Gets a property of a setting for all extruders.
|
||||
#
|
||||
# \param setting_key \type{str} The setting to get the property of.
|
||||
# \param property \type{str} The property to get.
|
||||
# \return \type{List} the list of results
|
||||
def getAllExtruderSettings(self, setting_key, property):
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||
if not multi_extrusion:
|
||||
return [global_container_stack.getProperty(setting_key, "value")]
|
||||
if global_container_stack.getProperty("machine_extruder_count", "value") <= 1:
|
||||
return [global_container_stack.getProperty(setting_key, property)]
|
||||
|
||||
result = []
|
||||
for index in self.extruderIds:
|
||||
extruder_stack_id = self.extruderIds[str(index)]
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id=extruder_stack_id)[0]
|
||||
result.append(stack.getProperty(setting_key, "value"))
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
result.append(stack.getProperty(setting_key, property))
|
||||
return result
|
||||
|
||||
## Gets the extruder stacks that are actually being used at the moment.
|
||||
#
|
||||
# An extruder stack is being used if it is the extruder to print any mesh
|
||||
# with, or if it is the support infill extruder, the support interface
|
||||
# extruder, or the bed adhesion extruder.
|
||||
#
|
||||
# If there are no extruders, this returns the global stack as a singleton
|
||||
# list.
|
||||
#
|
||||
# \return A list of extruder stacks.
|
||||
def getUsedExtruderStacks(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
|
||||
if global_stack.getProperty("machine_extruder_count", "value") <= 1: #For single extrusion.
|
||||
return [global_stack]
|
||||
|
||||
used_extruder_stack_ids = set()
|
||||
|
||||
#Get the extruders of all meshes in the scene.
|
||||
support_enabled = False
|
||||
support_interface_enabled = False
|
||||
scene_root = UM.Application.getInstance().getController().getScene().getRoot()
|
||||
meshes = [node for node in DepthFirstIterator(scene_root) if type(node) is SceneNode and node.isSelectable()] #Only use the nodes that will be printed.
|
||||
for mesh in meshes:
|
||||
extruder_stack_id = mesh.callDecoration("getActiveExtruder")
|
||||
if not extruder_stack_id: #No per-object settings for this node.
|
||||
extruder_stack_id = self.extruderIds["0"]
|
||||
used_extruder_stack_ids.add(extruder_stack_id)
|
||||
|
||||
#Get whether any of them use support.
|
||||
per_mesh_stack = mesh.callDecoration("getStack")
|
||||
if per_mesh_stack:
|
||||
support_enabled |= per_mesh_stack.getProperty("support_enable", "value")
|
||||
support_interface_enabled |= per_mesh_stack.getProperty("support_interface_enable", "value")
|
||||
else: #Take the setting from the build extruder stack.
|
||||
extruder_stack = container_registry.findContainerStacks(id = extruder_stack_id)[0]
|
||||
support_enabled |= extruder_stack.getProperty("support_enable", "value")
|
||||
support_interface_enabled |= extruder_stack.getProperty("support_enable", "value")
|
||||
|
||||
#The support extruders.
|
||||
if support_enabled:
|
||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_infill_extruder_nr", "value"))])
|
||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_extruder_nr_layer_0", "value"))])
|
||||
if support_interface_enabled:
|
||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_interface_extruder_nr", "value"))])
|
||||
|
||||
#The platform adhesion extruder. Not used if using none.
|
||||
if global_stack.getProperty("adhesion_type", "value") != "none":
|
||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("adhesion_extruder_nr", "value"))])
|
||||
|
||||
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
|
||||
|
||||
## Removes the container stack and user profile for the extruders for a specific machine.
|
||||
#
|
||||
# \param machine_id The machine to remove the extruders for.
|
||||
|
@ -34,7 +34,7 @@ class MachineManager(QObject):
|
||||
self.globalContainerChanged.connect(self.activeVariantChanged)
|
||||
self.globalContainerChanged.connect(self.activeQualityChanged)
|
||||
|
||||
self._active_stack_valid = None
|
||||
self._stacks_have_errors = None
|
||||
self._onGlobalContainerChanged()
|
||||
|
||||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
|
||||
@ -85,6 +85,7 @@ class MachineManager(QObject):
|
||||
globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed.
|
||||
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
|
||||
activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed
|
||||
stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed
|
||||
|
||||
blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly
|
||||
|
||||
@ -246,9 +247,15 @@ class MachineManager(QObject):
|
||||
quality.nameChanged.connect(self._onQualityNameChanged)
|
||||
|
||||
|
||||
## Update self._stacks_valid according to _checkStacksForErrors and emit if change.
|
||||
def _updateStacksHaveErrors(self):
|
||||
old_stacks_have_errors = self._stacks_have_errors
|
||||
self._stacks_have_errors = self._checkStacksHaveErrors()
|
||||
if old_stacks_have_errors != self._stacks_have_errors:
|
||||
self.stacksValidationChanged.emit()
|
||||
|
||||
def _onActiveExtruderStackChanged(self):
|
||||
self.blurSettings.emit() # Ensure no-one has focus.
|
||||
|
||||
old_active_container_stack = self._active_container_stack
|
||||
|
||||
if self._active_container_stack and self._active_container_stack != self._global_container_stack:
|
||||
@ -261,10 +268,7 @@ class MachineManager(QObject):
|
||||
else:
|
||||
self._active_container_stack = self._global_container_stack
|
||||
|
||||
old_active_stack_valid = self._active_stack_valid
|
||||
self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack)
|
||||
if old_active_stack_valid != self._active_stack_valid:
|
||||
self.activeStackValidationChanged.emit()
|
||||
self._updateStacksHaveErrors()
|
||||
|
||||
if old_active_container_stack != self._active_container_stack:
|
||||
# Many methods and properties related to the active quality actually depend
|
||||
@ -287,18 +291,18 @@ class MachineManager(QObject):
|
||||
self.activeStackValueChanged.emit()
|
||||
|
||||
if property_name == "validationState":
|
||||
if self._active_stack_valid:
|
||||
if not self._stacks_have_errors:
|
||||
# fast update, we only have to look at the current changed property
|
||||
if self._active_container_stack.getProperty(key, "settable_per_extruder"):
|
||||
changed_validation_state = self._active_container_stack.getProperty(key, property_name)
|
||||
else:
|
||||
changed_validation_state = self._global_container_stack.getProperty(key, property_name)
|
||||
if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError):
|
||||
self._active_stack_valid = False
|
||||
self.activeStackValidationChanged.emit()
|
||||
self._stacks_have_errors = True
|
||||
self.stacksValidationChanged.emit()
|
||||
else:
|
||||
if not self._checkStackForErrors(self._active_container_stack) and not self._checkStackForErrors(self._global_container_stack):
|
||||
self._active_stack_valid = True
|
||||
self.activeStackValidationChanged.emit()
|
||||
# Normal check
|
||||
self._updateStacksHaveErrors()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def setActiveMachine(self, stack_id):
|
||||
@ -352,15 +356,17 @@ class MachineManager(QObject):
|
||||
def _createUniqueName(self, container_type, current_name, new_name, fallback_name):
|
||||
return UM.Settings.ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name)
|
||||
|
||||
## Convenience function to check if a stack has errors.
|
||||
def _checkStackForErrors(self, stack):
|
||||
if stack is None:
|
||||
return False
|
||||
def _checkStacksHaveErrors(self):
|
||||
if self._global_container_stack is not None and self._global_container_stack.hasErrors():
|
||||
return True
|
||||
|
||||
for key in stack.getAllKeys():
|
||||
validation_state = stack.getProperty(key, "validationState")
|
||||
if validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError):
|
||||
if self._global_container_stack is None:
|
||||
return False
|
||||
stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
||||
for stack in stacks:
|
||||
if stack.hasErrors():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
## Remove all instances from the top instanceContainer (effectively removing all user-changed settings)
|
||||
@ -420,12 +426,12 @@ class MachineManager(QObject):
|
||||
for container in send_emits_containers:
|
||||
container.sendPostponedEmits()
|
||||
|
||||
## Check if the global profile does not contain error states
|
||||
# Note that the _active_stack_valid is cached due to performance issues
|
||||
# Calling _checkStackForErrors on every change is simply too expensive
|
||||
@pyqtProperty(bool, notify = activeStackValidationChanged)
|
||||
def isActiveStackValid(self):
|
||||
return bool(self._active_stack_valid)
|
||||
## Check if none of the stacks contain error states
|
||||
# Note that the _stacks_have_errors is cached due to performance issues
|
||||
# Calling _checkStack(s)ForErrors on every change is simply too expensive
|
||||
@pyqtProperty(bool, notify = stacksValidationChanged)
|
||||
def stacksHaveErrors(self):
|
||||
return bool(self._stacks_have_errors)
|
||||
|
||||
@pyqtProperty(str, notify = activeStackChanged)
|
||||
def activeUserProfileId(self):
|
||||
|
@ -28,7 +28,7 @@ class MachineNameValidator(QObject):
|
||||
# special character, and that up to [machine_name_max_length / 12] times.
|
||||
maximum_special_characters = int(machine_name_max_length / 12)
|
||||
unescaped = r"[a-zA-Z0-9_\-\.\/]"
|
||||
self.machine_name_regex = r"((" + unescaped + "){0,12}|.){0," + str(maximum_special_characters) + r"}"
|
||||
self.machine_name_regex = r"^((" + unescaped + "){0,12}|.){0," + str(maximum_special_characters) + r"}$"
|
||||
|
||||
validationChanged = pyqtSignal()
|
||||
|
||||
@ -56,14 +56,11 @@ class MachineNameValidator(QObject):
|
||||
def updateValidation(self, new_name):
|
||||
is_valid = self.validate(new_name, 0)
|
||||
if is_valid == QValidator.Acceptable:
|
||||
print("VALID")
|
||||
self.validation_regex = "^.*$" #Matches anything.
|
||||
else:
|
||||
print("BROKEN!")
|
||||
self.validation_regex = "a^" #Never matches (unless you manage to get "a" before the start of the string... good luck).
|
||||
self.validationChanged.emit()
|
||||
|
||||
@pyqtProperty("QRegExp", notify=validationChanged)
|
||||
def machineNameRegex(self):
|
||||
print(self.machine_name_regex)
|
||||
return QRegExp(self.machine_name_regex)
|
@ -163,13 +163,15 @@ class SettingInheritanceManager(QObject):
|
||||
for container in containers:
|
||||
try:
|
||||
value = container.getProperty(key, "value")
|
||||
if value is not None:
|
||||
has_setting_function = isinstance(value, UM.Settings.SettingFunction)
|
||||
if has_setting_function is False:
|
||||
has_non_function_value = True
|
||||
continue
|
||||
except AttributeError:
|
||||
continue
|
||||
if value is not None:
|
||||
# If a setting doesn't use any keys, it won't change it's value, so treat it as if it's a fixed value
|
||||
has_setting_function = isinstance(value, UM.Settings.SettingFunction) and len(value.getUsedSettingKeys()) > 0
|
||||
if has_setting_function is False:
|
||||
has_non_function_value = True
|
||||
continue
|
||||
|
||||
if has_setting_function:
|
||||
break # There is a setting function somewhere, stop looking deeper.
|
||||
return has_setting_function and has_non_function_value
|
||||
|
@ -61,6 +61,12 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||
def getActiveExtruder(self):
|
||||
return self._extruder_stack
|
||||
|
||||
## Gets the signal that emits if the active extruder changed.
|
||||
#
|
||||
# This can then be accessed via a decorator.
|
||||
def getActiveExtruderChangedSignal(self):
|
||||
return self.activeExtruderChanged
|
||||
|
||||
## Gets the currently active extruders position
|
||||
#
|
||||
# \return An extruder's position, or None if no position info is available.
|
||||
|
BIN
docs/Cura_Data_Model.odg
Normal file
BIN
docs/Cura_Data_Model.odg
Normal file
Binary file not shown.
@ -10,7 +10,10 @@ from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Scene.GroupDecorator import GroupDecorator
|
||||
import UM.Application
|
||||
from UM.Job import Job
|
||||
|
||||
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
|
||||
from UM.Application import Application
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.QualityManager import QualityManager
|
||||
|
||||
import os.path
|
||||
import zipfile
|
||||
@ -18,6 +21,7 @@ import zipfile
|
||||
try:
|
||||
import xml.etree.cElementTree as ET
|
||||
except ImportError:
|
||||
Logger.log("w", "Unable to load cElementTree, switching to slower version")
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
## Base implementation for reading 3MF files. Has no support for textures. Only loads meshes!
|
||||
@ -55,6 +59,46 @@ class ThreeMFReader(MeshReader):
|
||||
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
|
||||
Job.yieldThread()
|
||||
|
||||
xml_settings = list(object.findall(".//cura:setting", self._namespaces))
|
||||
|
||||
# Add the setting override decorator, so we can add settings to this node.
|
||||
if xml_settings:
|
||||
node.addDecorator(SettingOverrideDecorator())
|
||||
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
# Ensure the correct next container for the SettingOverride decorator is set.
|
||||
if global_container_stack:
|
||||
multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||
# Ensure that all extruder data is reset
|
||||
if not multi_extrusion:
|
||||
default_stack_id = global_container_stack.getId()
|
||||
else:
|
||||
default_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
||||
if default_stack:
|
||||
default_stack_id = default_stack.getId()
|
||||
else:
|
||||
default_stack_id = global_container_stack.getId()
|
||||
node.callDecoration("setActiveExtruder", default_stack_id)
|
||||
|
||||
# Get the definition & set it
|
||||
definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
|
||||
node.callDecoration("getStack").getTop().setDefinition(definition)
|
||||
|
||||
setting_container = node.callDecoration("getStack").getTop()
|
||||
for setting in xml_settings:
|
||||
setting_key = setting.get("key")
|
||||
setting_value = setting.text
|
||||
|
||||
# Extruder_nr is a special case.
|
||||
if setting_key == "extruder_nr":
|
||||
extruder_stack = ExtruderManager.getInstance().getExtruderStack(int(setting_value))
|
||||
if extruder_stack:
|
||||
node.callDecoration("setActiveExtruder", extruder_stack.getId())
|
||||
else:
|
||||
Logger.log("w", "Unable to find extruder in position %s", setting_value)
|
||||
continue
|
||||
setting_container.setProperty(setting_key,"value", setting_value)
|
||||
|
||||
if len(node.getChildren()) > 0:
|
||||
group_decorator = GroupDecorator()
|
||||
node.addDecorator(group_decorator)
|
||||
@ -112,7 +156,7 @@ class ThreeMFReader(MeshReader):
|
||||
return temp_mat
|
||||
|
||||
def read(self, file_name):
|
||||
result = SceneNode()
|
||||
result = []
|
||||
# The base object of 3mf is a zipped archive.
|
||||
archive = zipfile.ZipFile(file_name, "r")
|
||||
self._base_name = os.path.basename(file_name)
|
||||
@ -125,33 +169,58 @@ class ThreeMFReader(MeshReader):
|
||||
for build_item in build_items:
|
||||
id = build_item.get("objectid")
|
||||
object = self._root.find("./3mf:resources/3mf:object[@id='{0}']".format(id), self._namespaces)
|
||||
if "type" in object.attrib:
|
||||
if object.attrib["type"] == "support" or object.attrib["type"] == "other":
|
||||
# Ignore support objects, as cura does not support these.
|
||||
# We can't guarantee that they wont be made solid.
|
||||
# We also ignore "other", as I have no idea what to do with them.
|
||||
Logger.log("w", "3MF file contained an object of type %s which is not supported by Cura", object.attrib["type"])
|
||||
continue
|
||||
elif object.attrib["type"] == "solidsupport" or object.attrib["type"] == "model":
|
||||
pass # Load these as normal
|
||||
else:
|
||||
# We should technically fail at this point because it's an invalid 3MF, but try to continue anyway.
|
||||
Logger.log("e", "3MF file contained an object of type %s which is not supported by the 3mf spec",
|
||||
object.attrib["type"])
|
||||
continue
|
||||
|
||||
build_item_node = self._createNodeFromObject(object, self._base_name + "_" + str(id))
|
||||
transform = build_item.get("transform")
|
||||
if transform is not None:
|
||||
build_item_node.setTransformation(self._createMatrixFromTransformationString(transform))
|
||||
result.addChild(build_item_node)
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
# Create a transformation Matrix to convert from 3mf worldspace into ours.
|
||||
# First step: flip the y and z axis.
|
||||
transformation_matrix = Matrix()
|
||||
transformation_matrix._data[1, 1] = 0
|
||||
transformation_matrix._data[1, 2] = 1
|
||||
transformation_matrix._data[2, 1] = -1
|
||||
transformation_matrix._data[2, 2] = 0
|
||||
|
||||
# Second step: 3MF defines the left corner of the machine as center, whereas cura uses the center of the
|
||||
# build volume.
|
||||
if global_container_stack:
|
||||
translation_vector = Vector(x = -global_container_stack.getProperty("machine_width", "value") / 2,
|
||||
y = -global_container_stack.getProperty("machine_depth", "value") / 2,
|
||||
z = 0)
|
||||
translation_matrix = Matrix()
|
||||
translation_matrix.setByTranslation(translation_vector)
|
||||
transformation_matrix.multiply(translation_matrix)
|
||||
|
||||
# Third step: 3MF also defines a unit, wheras Cura always assumes mm.
|
||||
scale_matrix = Matrix()
|
||||
scale_matrix.setByScaleVector(self._getScaleFromUnit(self._unit))
|
||||
transformation_matrix.multiply(scale_matrix)
|
||||
|
||||
# Pre multiply the transformation with the loaded transformation, so the data is handled correctly.
|
||||
build_item_node.setTransformation(build_item_node.getLocalTransformation().preMultiply(transformation_matrix))
|
||||
|
||||
result.append(build_item_node)
|
||||
|
||||
except Exception as e:
|
||||
Logger.log("e", "exception occured in 3mf reader: %s", e)
|
||||
try: # Selftest - There might be more functions that should fail
|
||||
bounding_box = result.getBoundingBox()
|
||||
bounding_box.isValid()
|
||||
except:
|
||||
return None
|
||||
Logger.log("e", "An exception occurred in 3mf reader: %s", e)
|
||||
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
flip_matrix = Matrix()
|
||||
flip_matrix._data[1, 1] = 0
|
||||
flip_matrix._data[1, 2] = 1
|
||||
flip_matrix._data[2, 1] = -1
|
||||
flip_matrix._data[2, 2] = 0
|
||||
result.setTransformation(flip_matrix)
|
||||
if global_container_stack:
|
||||
translation = Vector(x=-global_container_stack.getProperty("machine_width", "value") / 2, z=0,
|
||||
y=-global_container_stack.getProperty("machine_depth", "value") / 2)
|
||||
result.translate(translation)
|
||||
result.scale(self._getScaleFromUnit(self._unit))
|
||||
result.setEnabled(False) # The result should not be moved in any way, so disable it.
|
||||
return result
|
||||
|
||||
## Create a scale vector based on a unit string.
|
||||
|
@ -1,14 +1,14 @@
|
||||
[2.3.1]
|
||||
*Layer Height in Profile Selection
|
||||
The layer height of each profile is now shown in the profile selection menu.
|
||||
Added the layer height to the profile selection menu.
|
||||
|
||||
*Bug fixes
|
||||
Editing material settings has actual effect on the prints again
|
||||
Upgrading from version 2.1 on OSX works again
|
||||
You can import g-code from related machines as profile
|
||||
Fixed inheritance taking from the wrong extruder
|
||||
The i-symbol is updated properly
|
||||
Fixed a freeze that could sometimes occur while printing via Wi-Fi
|
||||
Fixed the option to import g-code from related machines as a profile
|
||||
Fixed a bug where editing material settings has no effect on 3D prints
|
||||
Fixed an issue with automatic profile importing on Cura 2.1 on Mac OSX
|
||||
Fixed an inheritance issue for dual extrusion
|
||||
Fixed an issue with "i" symbol updates
|
||||
Fixed a freeze that can occur while printing via Wi-Fi
|
||||
|
||||
[2.3.0]
|
||||
*Multi Extrusion Support
|
||||
|
@ -220,6 +220,9 @@ class CuraEngineBackend(Backend):
|
||||
#
|
||||
# \param job The start slice job that was just finished.
|
||||
def _onStartSliceCompleted(self, job):
|
||||
if self._error_message:
|
||||
self._error_message.hide()
|
||||
|
||||
# Note that cancelled slice jobs can still call this method.
|
||||
if self._start_slice_job is job:
|
||||
self._start_slice_job = None
|
||||
@ -239,13 +242,33 @@ class CuraEngineBackend(Backend):
|
||||
|
||||
if job.getResult() == StartSliceJob.StartJobResult.SettingError:
|
||||
if Application.getInstance().getPlatformActivity:
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. Please check your settings for errors."))
|
||||
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
||||
error_keys = []
|
||||
for extruder in extruders:
|
||||
error_keys.extend(extruder.getErrorKeys())
|
||||
if not extruders:
|
||||
error_keys = self._global_container_stack.getErrorKeys()
|
||||
error_labels = set()
|
||||
definition_container = self._global_container_stack.getBottom()
|
||||
for key in error_keys:
|
||||
error_labels.add(definition_container.findDefinitions(key = key)[0].label)
|
||||
|
||||
error_labels = ", ".join(error_labels)
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}".format(error_labels)))
|
||||
self._error_message.show()
|
||||
self.backendStateChange.emit(BackendState.Error)
|
||||
else:
|
||||
self.backendStateChange.emit(BackendState.NotStarted)
|
||||
return
|
||||
|
||||
if job.getResult() == StartSliceJob.StartJobResult.BuildPlateError:
|
||||
if Application.getInstance().getPlatformActivity:
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because the prime tower or prime position(s) are invalid."))
|
||||
self._error_message.show()
|
||||
self.backendStateChange.emit(BackendState.Error)
|
||||
else:
|
||||
self.backendStateChange.emit(BackendState.NotStarted)
|
||||
|
||||
if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice:
|
||||
if Application.getInstance().getPlatformActivity:
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."))
|
||||
@ -296,7 +319,7 @@ class CuraEngineBackend(Backend):
|
||||
self._terminate()
|
||||
|
||||
if error.getErrorCode() not in [Arcus.ErrorCode.BindFailedError, Arcus.ErrorCode.ConnectionResetError, Arcus.ErrorCode.Debug]:
|
||||
Logger.log("e", "A socket error caused the connection to be reset")
|
||||
Logger.log("w", "A socket error caused the connection to be reset")
|
||||
|
||||
## A setting has changed, so check if we must reslice.
|
||||
#
|
||||
|
@ -25,6 +25,7 @@ class StartJobResult(IntEnum):
|
||||
SettingError = 3
|
||||
NothingToSlice = 4
|
||||
MaterialIncompatible = 5
|
||||
BuildPlateError = 6
|
||||
|
||||
|
||||
## Formatter class that handles token expansion in start/end gcod
|
||||
@ -75,12 +76,12 @@ class StartSliceJob(Job):
|
||||
return
|
||||
|
||||
# Don't slice if there is a setting with an error value.
|
||||
if not Application.getInstance().getMachineManager().isActiveStackValid:
|
||||
if Application.getInstance().getMachineManager().stacksHaveErrors:
|
||||
self.setResult(StartJobResult.SettingError)
|
||||
return
|
||||
|
||||
if Application.getInstance().getBuildVolume().hasErrors():
|
||||
self.setResult(StartJobResult.SettingError)
|
||||
self.setResult(StartJobResult.BuildPlateError)
|
||||
return
|
||||
|
||||
for extruder_stack in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
|
||||
@ -164,7 +165,12 @@ class StartSliceJob(Job):
|
||||
indices = mesh_data.getIndices()
|
||||
if indices is not None:
|
||||
#TODO: This is a very slow way of doing it! It also locks up the GUI.
|
||||
verts = numpy.array([verts[vert_index] for face in indices for vert_index in face])
|
||||
flat_vert_list = []
|
||||
for face in indices:
|
||||
for vert_index in face:
|
||||
flat_vert_list.append(verts[vert_index])
|
||||
Job.yieldThread()
|
||||
verts = numpy.array(flat_vert_list)
|
||||
else:
|
||||
verts = numpy.array(verts)
|
||||
|
||||
@ -238,6 +244,7 @@ class StartSliceJob(Job):
|
||||
else:
|
||||
# Normal case
|
||||
settings[key] = stack.getProperty(key, "value")
|
||||
Job.yieldThread()
|
||||
|
||||
start_gcode = settings["machine_start_gcode"]
|
||||
settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material material_bed_temp_prepend and material_print_temp_prepend
|
||||
@ -250,6 +257,7 @@ class StartSliceJob(Job):
|
||||
setting_message.value = self._expandGcodeTokens(key, value, settings)
|
||||
else:
|
||||
setting_message.value = str(value).encode("utf-8")
|
||||
Job.yieldThread()
|
||||
|
||||
## Sends for some settings which extruder they should fallback to if not
|
||||
# set.
|
||||
@ -266,6 +274,7 @@ class StartSliceJob(Job):
|
||||
setting_extruder = self._slice_message.addRepeatedMessage("limit_to_extruder")
|
||||
setting_extruder.name = key
|
||||
setting_extruder.extruder = extruder
|
||||
Job.yieldThread()
|
||||
|
||||
## Check if a node has per object settings and ensure that they are set correctly in the message
|
||||
# \param node \type{SceneNode} Node to check.
|
||||
|
@ -99,4 +99,6 @@ class CuraProfileReader(ProfileReader):
|
||||
return []
|
||||
|
||||
filenames, outputs = profile_convert_funcs[0](serialized, profile_id)
|
||||
if filenames is None and outputs is None:
|
||||
return []
|
||||
return list(zip(outputs, filenames))
|
||||
|
@ -70,10 +70,19 @@ class GCodeProfileReader(ProfileReader):
|
||||
|
||||
json_data = json.loads(serialized)
|
||||
|
||||
profile_strings = [json_data["global_quality"]]
|
||||
profile_strings.extend(json_data.get("extruder_quality", []))
|
||||
profiles = []
|
||||
global_profile = readQualityProfileFromString(json_data["global_quality"])
|
||||
|
||||
return [readQualityProfileFromString(profile_string) for profile_string in profile_strings]
|
||||
# This is a fix for profiles created with 2.3.0 For some reason it added the "extruder" property to the
|
||||
# global profile.
|
||||
# The fix is simple and safe, as a global profile should never have the extruder entry.
|
||||
if global_profile.getMetaDataEntry("extruder", None) is not None:
|
||||
global_profile.setMetaDataEntry("extruder", None)
|
||||
profiles.append(global_profile)
|
||||
|
||||
for profile_string in json_data.get("extruder_quality", []):
|
||||
profiles.append(readQualityProfileFromString(profile_string))
|
||||
return profiles
|
||||
|
||||
## Unescape a string which has been escaped for use in a gcode comment.
|
||||
#
|
||||
|
@ -401,7 +401,7 @@ Item {
|
||||
}
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||
expanded: [ "*" ]
|
||||
exclude: [ "machine_settings" ]
|
||||
exclude: [ "machine_settings", "command_line_settings" ]
|
||||
}
|
||||
delegate:Loader
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ class PerObjectSettingsTool(Tool):
|
||||
|
||||
self._advanced_mode = False
|
||||
self._multi_extrusion = False
|
||||
self._single_model_selected = False
|
||||
|
||||
Selection.selectionChanged.connect(self.propertyChanged)
|
||||
|
||||
@ -30,6 +31,8 @@ class PerObjectSettingsTool(Tool):
|
||||
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
self._onGlobalContainerChanged()
|
||||
Selection.selectionChanged.connect(self._updateEnabled)
|
||||
|
||||
|
||||
def event(self, event):
|
||||
super().event(event)
|
||||
@ -102,4 +105,11 @@ class PerObjectSettingsTool(Tool):
|
||||
self._updateEnabled()
|
||||
|
||||
def _updateEnabled(self):
|
||||
Application.getInstance().getController().toolEnabledChanged.emit(self._plugin_id, self._advanced_mode or self._multi_extrusion)
|
||||
selected_objects = Selection.getAllSelectedObjects()
|
||||
if len(selected_objects)> 1:
|
||||
self._single_model_selected = False
|
||||
elif len(selected_objects) == 1 and selected_objects[0].callDecoration("isGroup"):
|
||||
self._single_model_selected = False # Group is selected, so tool needs to be disabled
|
||||
else:
|
||||
self._single_model_selected = True
|
||||
Application.getInstance().getController().toolEnabledChanged.emit(self._plugin_id, (self._advanced_mode or self._multi_extrusion) and self._single_model_selected)
|
@ -20,7 +20,7 @@ class RemovableDriveOutputDevice(OutputDevice):
|
||||
super().__init__(device_id)
|
||||
|
||||
self.setName(device_name)
|
||||
self.setShortDescription(catalog.i18nc("@action:button", "Save to Removable Drive"))
|
||||
self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Save to Removable Drive"))
|
||||
self.setDescription(catalog.i18nc("@item:inlistbox", "Save to Removable Drive {0}").format(device_name))
|
||||
self.setIconName("save_sd")
|
||||
self.setPriority(1)
|
||||
|
@ -19,13 +19,12 @@ from PyQt5.QtCore import QUrl, pyqtSlot, pyqtSignal, pyqtProperty
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
class USBPrinterOutputDevice(PrinterOutputDevice):
|
||||
|
||||
def __init__(self, serial_port):
|
||||
super().__init__(serial_port)
|
||||
self.setName(catalog.i18nc("@item:inmenu", "USB printing"))
|
||||
self.setShortDescription(catalog.i18nc("@action:button", "Print via USB"))
|
||||
self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB"))
|
||||
self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB"))
|
||||
self.setIconName("print")
|
||||
self.setConnectionText(catalog.i18nc("@info:status", "Connected via USB"))
|
||||
|
@ -5,6 +5,7 @@ See: http://en.wikipedia.org/wiki/Intel_HEX
|
||||
This is a python 3 conversion of the code created by David Braam for the Cura project.
|
||||
"""
|
||||
import io
|
||||
from UM.Logger import Logger
|
||||
|
||||
def readHex(filename):
|
||||
"""
|
||||
@ -41,6 +42,6 @@ def readHex(filename):
|
||||
elif rec_type == 2: #Extended Segment Address Record
|
||||
extra_addr = int(line[9:13], 16) * 16
|
||||
else:
|
||||
print(rec_type, rec_len, addr, check_sum, line)
|
||||
Logger.log("d", "%s, %s, %s, %s, %s", rec_type, rec_len, addr, check_sum, line)
|
||||
f.close()
|
||||
return data
|
||||
|
@ -8,6 +8,7 @@ The ISP AVR programmer can load firmware into AVR chips. Which are commonly used
|
||||
"""
|
||||
|
||||
from . import chipDB
|
||||
from UM.Logger import Logger
|
||||
|
||||
class IspBase():
|
||||
"""
|
||||
@ -22,11 +23,11 @@ class IspBase():
|
||||
raise IspError("Chip with signature: " + str(self.getSignature()) + "not found")
|
||||
self.chipErase()
|
||||
|
||||
print("Flashing %i bytes" % len(flash_data))
|
||||
Logger.log("d", "Flashing %i bytes", len(flash_data))
|
||||
self.writeFlash(flash_data)
|
||||
print("Verifying %i bytes" % len(flash_data))
|
||||
Logger.log("d", "Verifying %i bytes", len(flash_data))
|
||||
self.verifyFlash(flash_data)
|
||||
print("Completed")
|
||||
Logger.log("d", "Completed")
|
||||
|
||||
def getSignature(self):
|
||||
"""
|
||||
|
@ -3,7 +3,6 @@ STK500v2 protocol implementation for programming AVR chips.
|
||||
The STK500v2 protocol is used by the ArduinoMega2560 and a few other Arduino platforms to load firmware.
|
||||
This is a python 3 conversion of the code created by David Braam for the Cura project.
|
||||
"""
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
@ -11,6 +10,7 @@ import time
|
||||
from serial import Serial
|
||||
from serial import SerialException
|
||||
from serial import SerialTimeoutException
|
||||
from UM.Logger import Logger
|
||||
|
||||
from . import ispBase, intelHex
|
||||
|
||||
@ -27,7 +27,7 @@ class Stk500v2(ispBase.IspBase):
|
||||
self.close()
|
||||
try:
|
||||
self.serial = Serial(str(port), speed, timeout=1, writeTimeout=10000)
|
||||
except SerialException as e:
|
||||
except SerialException:
|
||||
raise ispBase.IspError("Failed to open serial port")
|
||||
except:
|
||||
raise ispBase.IspError("Unexpected error while connecting to serial port:" + port + ":" + str(sys.exc_info()[0]))
|
||||
@ -84,14 +84,14 @@ class Stk500v2(ispBase.IspBase):
|
||||
#Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
|
||||
page_size = self.chip["pageSize"] * 2
|
||||
flash_size = page_size * self.chip["pageCount"]
|
||||
print("Writing flash")
|
||||
Logger.log("d", "Writing flash")
|
||||
if flash_size > 0xFFFF:
|
||||
self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
|
||||
else:
|
||||
self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
|
||||
load_count = (len(flash_data) + page_size - 1) / page_size
|
||||
for i in range(0, int(load_count)):
|
||||
recv = self.sendMessage([0x13, page_size >> 8, page_size & 0xFF, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flash_data[(i * page_size):(i * page_size + page_size)])
|
||||
self.sendMessage([0x13, page_size >> 8, page_size & 0xFF, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flash_data[(i * page_size):(i * page_size + page_size)])
|
||||
if self.progress_callback is not None:
|
||||
if self._has_checksum:
|
||||
self.progress_callback(i + 1, load_count)
|
||||
@ -151,7 +151,6 @@ class Stk500v2(ispBase.IspBase):
|
||||
raise ispBase.IspError("Timeout")
|
||||
b = struct.unpack(">B", s)[0]
|
||||
checksum ^= b
|
||||
#print(hex(b))
|
||||
if state == "Start":
|
||||
if b == 0x1B:
|
||||
state = "GetSeq"
|
||||
@ -183,11 +182,11 @@ class Stk500v2(ispBase.IspBase):
|
||||
def portList():
|
||||
ret = []
|
||||
import _winreg
|
||||
key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM")
|
||||
key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM") #@UndefinedVariable
|
||||
i=0
|
||||
while True:
|
||||
try:
|
||||
values = _winreg.EnumValue(key, i)
|
||||
values = _winreg.EnumValue(key, i) #@UndefinedVariable
|
||||
except:
|
||||
return ret
|
||||
if "USBSER" in values[0]:
|
||||
@ -206,7 +205,7 @@ def main():
|
||||
""" Entry point to call the stk500v2 programmer from the commandline. """
|
||||
import threading
|
||||
if sys.argv[1] == "AUTO":
|
||||
print(portList())
|
||||
Logger.log("d", "portList(): ", repr(portList()))
|
||||
for port in portList():
|
||||
threading.Thread(target=runProgrammer, args=(port,sys.argv[2])).start()
|
||||
time.sleep(5)
|
||||
|
@ -5,6 +5,7 @@ import configparser #To read config files.
|
||||
import io #To write config files to strings as if they were files.
|
||||
|
||||
import UM.VersionUpgrade
|
||||
from UM.Logger import Logger
|
||||
|
||||
## Creates a new profile instance by parsing a serialised profile in version 1
|
||||
# of the file format.
|
||||
|
@ -165,7 +165,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
machine_container_map = {}
|
||||
machine_nozzle_map = {}
|
||||
|
||||
all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"))
|
||||
all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = self._id)
|
||||
for container in all_containers:
|
||||
definition_id = container.getDefinition().id
|
||||
if definition_id == "fdmprinter":
|
||||
@ -209,7 +209,17 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
if not variant_containers:
|
||||
continue
|
||||
|
||||
builder.start("hotend", { "id": variant_containers[0].getName() })
|
||||
builder.start("hotend", {"id": variant_containers[0].getName()})
|
||||
|
||||
# Compatible is a special case, as it's added as a meta data entry (instead of an instance).
|
||||
compatible = hotend.getMetaDataEntry("compatible")
|
||||
if compatible is not None:
|
||||
builder.start("setting", {"key": "hardware compatible"})
|
||||
if compatible:
|
||||
builder.data("yes")
|
||||
else:
|
||||
builder.data("no")
|
||||
builder.end("setting")
|
||||
|
||||
for instance in hotend.findInstances():
|
||||
if container.getInstance(instance.definition.key) and container.getProperty(instance.definition.key, "value") == instance.value:
|
||||
|
40
resources/definitions/bfb.def.json
Normal file
40
resources/definitions/bfb.def.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"id": "bfb",
|
||||
"name": "BFB",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "BFB",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"speed_topbottom": { "default_value": 40 },
|
||||
"speed_print": { "default_value": 40 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
||||
"machine_name": { "default_value": "BFB_Test" },
|
||||
"machine_heated_bed": { "default_value": false },
|
||||
"machine_nozzle_size": { "default_value": 0.5 },
|
||||
"speed_layer_0": { "default_value": 25 },
|
||||
"machine_width": { "default_value": 275 },
|
||||
"machine_gcode_flavor": { "default_value": "BFB" },
|
||||
"machine_depth": { "default_value": 265 },
|
||||
"speed_infill": { "default_value": 30 },
|
||||
"material_diameter": { "default_value": 1.7 },
|
||||
"machine_center_is_zero": { "default_value": true },
|
||||
"machine_height": { "default_value": 240 },
|
||||
"layer_height": { "default_value": 0.25 },
|
||||
"material_print_temperature": { "default_value": 200 },
|
||||
"retraction_amount": { "default_value": 0.05 },
|
||||
"speed_wall_0": { "default_value": 25 },
|
||||
"speed_travel": { "default_value": 50 },
|
||||
"infill_sparse_density": { "default_value": 10 },
|
||||
"layer_height_0": { "default_value": 0.5 },
|
||||
"speed_wall_x": { "default_value": 20 }
|
||||
}
|
||||
}
|
35
resources/definitions/deltabot.def.json
Normal file
35
resources/definitions/deltabot.def.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"id": "deltabot",
|
||||
"name": "DeltaBot",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Danny Lu",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"speed_travel": { "default_value": 150 },
|
||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
||||
"infill_sparse_density": { "default_value": 10 },
|
||||
"speed_wall_x": { "default_value": 30 },
|
||||
"speed_wall_0": { "default_value": 30 },
|
||||
"speed_topbottom": { "default_value": 30 },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"machine_nozzle_size": { "default_value": 0.5 },
|
||||
"speed_print": { "default_value": 30 },
|
||||
"speed_infill": { "default_value": 30 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": true },
|
||||
"machine_height": { "default_value": 150 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 150 },
|
||||
"machine_width": { "default_value": 150 },
|
||||
"machine_name": { "default_value": "DeltaBot style" }
|
||||
}
|
||||
}
|
@ -169,7 +169,7 @@
|
||||
},
|
||||
"machine_extruder_count":
|
||||
{
|
||||
"label": "Number extruders",
|
||||
"label": "Number of Extruders",
|
||||
"description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.",
|
||||
"default_value": 1,
|
||||
"minimum_value": "1",
|
||||
@ -283,6 +283,18 @@
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
},
|
||||
"nozzle_disallowed_areas":
|
||||
{
|
||||
"label": "Nozzle Disallowed Areas",
|
||||
"description": "A list of polygons with areas the nozzle is not allowed to enter.",
|
||||
"type": "polygons",
|
||||
"default_value":
|
||||
[
|
||||
],
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
},
|
||||
"machine_head_polygon":
|
||||
{
|
||||
"label": "Machine head polygon",
|
||||
@ -756,6 +768,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"wall_0_wipe_dist":
|
||||
{
|
||||
"label": "Outer Wall Wipe Distance",
|
||||
"description": "Distance of a travel move inserted after the outer wall, to hide the Z seam better.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.2,
|
||||
"value": "machine_nozzle_size / 2",
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "machine_nozzle_size",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"top_bottom_thickness":
|
||||
{
|
||||
"label": "Top/Bottom Thickness",
|
||||
@ -897,6 +921,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fill_perimeter_gaps": {
|
||||
"label": "Fill Gaps Between Walls",
|
||||
"description": "Fills the gaps between walls where no walls fit.",
|
||||
"type": "enum",
|
||||
"options": {
|
||||
"nowhere": "Nowhere",
|
||||
"everywhere": "Everywhere"
|
||||
},
|
||||
"default_value": "everywhere",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"xy_offset":
|
||||
{
|
||||
"label": "Horizontal Expansion",
|
||||
@ -979,6 +1014,7 @@
|
||||
"cubic": "Cubic",
|
||||
"tetrahedral": "Tetrahedral",
|
||||
"concentric": "Concentric",
|
||||
"concentric_3d": "Concentric 3D",
|
||||
"zigzag": "Zig Zag"
|
||||
},
|
||||
"default_value": "grid",
|
||||
@ -1135,7 +1171,22 @@
|
||||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "260",
|
||||
"enabled": "not (material_flow_dependent_temperature)",
|
||||
"enabled": "not (material_flow_dependent_temperature) and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"material_print_temperature_layer_0":
|
||||
{
|
||||
"label": "Printing Temperature Initial Layer",
|
||||
"description": "The temperature used for printing the first layer. Set at 0 to disable special handling of the initial layer.",
|
||||
"unit": "°C",
|
||||
"type": "float",
|
||||
"default_value": 215,
|
||||
"value": "material_print_temperature + 5",
|
||||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "260",
|
||||
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -1176,7 +1227,23 @@
|
||||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "260",
|
||||
"enabled": "machine_heated_bed",
|
||||
"enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
},
|
||||
"material_bed_temperature_layer_0":
|
||||
{
|
||||
"label": "Build Plate Temperature Initial Layer",
|
||||
"description": "The temperature used for the heated build plate at the first layer.",
|
||||
"unit": "°C",
|
||||
"type": "float",
|
||||
"resolve": "max(extruderValues('material_bed_temperature_layer_0'))",
|
||||
"default_value": 60,
|
||||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "260",
|
||||
"enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
@ -1191,6 +1258,7 @@
|
||||
"minimum_value": "0.0001",
|
||||
"minimum_value_warning": "0.4",
|
||||
"maximum_value_warning": "3.5",
|
||||
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -1204,6 +1272,7 @@
|
||||
"minimum_value": "5",
|
||||
"minimum_value_warning": "50",
|
||||
"maximum_value_warning": "150",
|
||||
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"retraction_enable":
|
||||
@ -1215,6 +1284,14 @@
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"retract_at_layer_change":{
|
||||
"label": "Retract at Layer Change",
|
||||
"description": "Retract the filament when the nozzle is moving to the next layer.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"retraction_amount":
|
||||
{
|
||||
"label": "Retraction Distance",
|
||||
@ -1224,7 +1301,7 @@
|
||||
"default_value": 6.5,
|
||||
"minimum_value_warning": "-0.0001",
|
||||
"maximum_value_warning": "10.0",
|
||||
"enabled": "retraction_enable",
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -1239,7 +1316,7 @@
|
||||
"minimum_value_warning": "1",
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
"maximum_value_warning": "70",
|
||||
"enabled": "retraction_enable",
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
@ -1255,7 +1332,7 @@
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
"minimum_value_warning": "1",
|
||||
"maximum_value_warning": "70",
|
||||
"enabled": "retraction_enable",
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"value": "retraction_speed",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
@ -1271,7 +1348,7 @@
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
"minimum_value_warning": "1",
|
||||
"maximum_value_warning": "70",
|
||||
"enabled": "retraction_enable",
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"value": "retraction_speed",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
@ -1341,6 +1418,7 @@
|
||||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "260",
|
||||
"enabled": "machine_extruder_count > 1 and machine_gcode_flavor != \"UltiGCode\"",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -2179,7 +2257,7 @@
|
||||
"retraction_combing":
|
||||
{
|
||||
"label": "Combing Mode",
|
||||
"description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.",
|
||||
"description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.",
|
||||
"type": "enum",
|
||||
"options":
|
||||
{
|
||||
@ -2217,6 +2295,42 @@
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"start_layers_at_same_position":
|
||||
{
|
||||
"label": "Start Layers Near Same Point",
|
||||
"description": "Start printing the objects in each layer near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
},
|
||||
"layer_start_x":
|
||||
{
|
||||
"label": "Layer Start X",
|
||||
"description": "The X coordinate of the position near where to start printing objects each layer.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.0,
|
||||
"minimum_value": "0",
|
||||
"enabled": "start_layers_at_same_position",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
},
|
||||
"layer_start_y":
|
||||
{
|
||||
"label": "Layer Start Y",
|
||||
"description": "The Y coordinate of the position near where to start printing objects each layer.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.0,
|
||||
"minimum_value": "0",
|
||||
"enabled": "start_layers_at_same_position",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
},
|
||||
"retraction_hop_enabled": {
|
||||
"label": "Z Hop when Retracted",
|
||||
"description": "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.",
|
||||
@ -2290,6 +2404,20 @@
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
{
|
||||
"cool_fan_speed_0":
|
||||
{
|
||||
"label": "Initial Fan Speed",
|
||||
"description": "The speed at which the fans spin at the start of the print. In subsequent layers the fan speed is gradually increased up to the layer corresponding to Regular Fan Speed at Height.",
|
||||
"unit": "%",
|
||||
"type": "float",
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "100",
|
||||
"value": "cool_fan_speed",
|
||||
"default_value": 100,
|
||||
"enabled": "cool_fan_enabled",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"cool_fan_speed_min":
|
||||
{
|
||||
"label": "Regular Fan Speed",
|
||||
@ -2335,7 +2463,7 @@
|
||||
"cool_fan_full_at_height":
|
||||
{
|
||||
"label": "Regular Fan Speed at Height",
|
||||
"description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.",
|
||||
"description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from Initial Fan Speed to Regular Fan Speed.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.5,
|
||||
@ -2498,6 +2626,7 @@
|
||||
"grid": "Grid",
|
||||
"triangles": "Triangles",
|
||||
"concentric": "Concentric",
|
||||
"concentric_3d": "Concentric 3D",
|
||||
"zigzag": "Zig Zag"
|
||||
},
|
||||
"default_value": "zigzag",
|
||||
@ -2767,7 +2896,7 @@
|
||||
"type": "float",
|
||||
"default_value": 0.4,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "support_interface_line_width",
|
||||
"minimum_value_warning": "support_interface_line_width - 0.0001",
|
||||
"value": "0 if support_interface_density == 0 else (support_interface_line_width * 100) / support_interface_density * (2 if support_interface_pattern == 'grid' else (3 if support_interface_pattern == 'triangles' else 1))",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
@ -2787,6 +2916,7 @@
|
||||
"grid": "Grid",
|
||||
"triangles": "Triangles",
|
||||
"concentric": "Concentric",
|
||||
"concentric_3d": "Concentric 3D",
|
||||
"zigzag": "Zig Zag"
|
||||
},
|
||||
"default_value": "concentric",
|
||||
@ -2892,7 +3022,8 @@
|
||||
{
|
||||
"skirt": "Skirt",
|
||||
"brim": "Brim",
|
||||
"raft": "Raft"
|
||||
"raft": "Raft",
|
||||
"none": "None"
|
||||
},
|
||||
"default_value": "brim",
|
||||
"resolve": "'raft' if 'raft' in extruderValues('adhesion_type') else ('brim' if 'brim' in extruderValues('adhesion_type') else 'skirt')",
|
||||
@ -2905,7 +3036,7 @@
|
||||
"description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.",
|
||||
"type": "extruder",
|
||||
"default_value": "0",
|
||||
"enabled": "machine_extruder_count > 1",
|
||||
"enabled": "machine_extruder_count > 1 and resolveOrValue('adhesion_type') != 'none'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false
|
||||
},
|
||||
@ -3635,13 +3766,24 @@
|
||||
"carve_multiple_volumes":
|
||||
{
|
||||
"label": "Remove Mesh Intersection",
|
||||
"description": "Remove areas where multiple objecs are overlapping with each other. This is may be used if merged dual material objects overlap with each other.",
|
||||
"description": "Remove areas where multiple objects are overlapping with each other. This may be used if merged dual material objects overlap with each other.",
|
||||
"type": "bool",
|
||||
"default_value": true,
|
||||
"value": "machine_extruder_count > 1",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
},
|
||||
"alternate_carve_order":
|
||||
{
|
||||
"label": "Alternate Mesh Removal",
|
||||
"description": "With every layer switch from which model intersecting volumes are removed, so that the overlapping volumes become interwoven.",
|
||||
"type": "bool",
|
||||
"default_value": true,
|
||||
"enabled": "carve_multiple_volumes",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3664,6 +3806,7 @@
|
||||
"one_at_a_time": "One at a Time"
|
||||
},
|
||||
"default_value": "all_at_once",
|
||||
"enabled": "machine_extruder_count == 1",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
@ -3902,6 +4045,14 @@
|
||||
"limit_to_extruder": "support_infill_extruder_nr",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"infill_hollow":
|
||||
{
|
||||
"label": "Hollow Out Objects",
|
||||
"description": "Remove all infill and make the inside of the object eligible for support.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"magic_fuzzy_skin_enabled":
|
||||
{
|
||||
"label": "Fuzzy Skin",
|
||||
@ -4309,6 +4460,49 @@
|
||||
"settable_per_meshgroup": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"command_line_settings": {
|
||||
"label": "Command Line Settings",
|
||||
"description": "Settings which are only used if CuraEngine isn't called from the Cura frontend.",
|
||||
"type": "category",
|
||||
"enabled": false,
|
||||
"children": {
|
||||
"center_object": {
|
||||
"description": "Whether to center the object on the middle of the build platform (0,0), instead of using the coordinate system in which the object was saved.",
|
||||
"type": "bool",
|
||||
"label": "Center object",
|
||||
"default_value": false,
|
||||
"enabled": false
|
||||
},
|
||||
"mesh_position_x": {
|
||||
"description": "Offset applied to the object in the x direction.",
|
||||
"type": "float",
|
||||
"label": "Mesh position x",
|
||||
"default_value": 0,
|
||||
"enabled": false
|
||||
},
|
||||
"mesh_position_y": {
|
||||
"description": "Offset applied to the object in the y direction.",
|
||||
"type": "float",
|
||||
"label": "Mesh position y",
|
||||
"default_value": 0,
|
||||
"enabled": false
|
||||
},
|
||||
"mesh_position_z": {
|
||||
"description": "Offset applied to the object in the z direction. With this you can perform what was used to be called 'Object Sink'.",
|
||||
"type": "float",
|
||||
"label": "Mesh position z",
|
||||
"default_value": 0,
|
||||
"enabled": false
|
||||
},
|
||||
"mesh_rotation_matrix": {
|
||||
"label": "Mesh Rotation Matrix",
|
||||
"description": "Transformation matrix to be applied to the model when loading it from file.",
|
||||
"type": "str",
|
||||
"default_value": "[[1,0,0], [0,1,0], [0,0,1]]",
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
||||
"default_value": "RepRap (Marlin/Sprinter)"
|
||||
},
|
||||
"machine_start_gcode": {
|
||||
"default_value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position"
|
||||
"default_value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\nM190 S{material_bed_temperature}\nM104 T0 S{material_print_temperature}\nM109 T0 S{material_print_temperature}\nM104 T1 S{material_print_temperature}\nM109 T1 S{material_print_temperature}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": "M104 S0 ; turn off extruders\nM140 S0 ; heated bed heater off\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors"
|
||||
|
52
resources/definitions/julia.def.json
Normal file
52
resources/definitions/julia.def.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"id": "julia",
|
||||
"name": "Julia",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Fracktal",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_start_gcode": {
|
||||
"default_value": " ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n ;metric values\n M107\n G28\n G29\n G90 ;absolute positioning\n G92 E0; reset extruder distance\n G1 Z5 F300 ;move nozzle up 5mm for safe homing\n G1 X0 Y0 Z0 F5000; move nozzle to home\n M300 S600P200\n M300 S800 P200\n M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n M109 S{material_print_temperature} ;Uncomment to add your own temperature line\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E3 ;extrude 3mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel}\n ;Put printing message on LCD screen\n M117 Printing...\n"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n"
|
||||
},
|
||||
"material_bed_temperature": { "default_value": 100 },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"support_angle": { "default_value": 30 },
|
||||
"infill_overlap": { "default_value": 30 },
|
||||
"layer_height_0": { "default_value": 0.2 },
|
||||
"speed_print": { "default_value": 80 },
|
||||
"speed_wall_0": { "default_value": 30 },
|
||||
"speed_travel": { "default_value": 150 },
|
||||
"brim_line_count": { "default_value": 15 },
|
||||
"skin_overlap": { "default_value": 30 },
|
||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"bottom_thickness": { "default_value": 0.8 },
|
||||
"retraction_amount": { "default_value": 3 },
|
||||
"speed_topbottom": { "default_value": 80 },
|
||||
"material_print_temperature": { "default_value": 230 },
|
||||
"support_pattern": { "default_value": "grid" },
|
||||
"speed_infill": { "default_value": 80 },
|
||||
"infill_sparse_density": { "default_value": 10 },
|
||||
"top_thickness": { "default_value": 0.8 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"retraction_combing": { "default_value": "off" },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 260 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 250 },
|
||||
"machine_width": { "default_value": 210 },
|
||||
"machine_name": { "default_value": "Julia V2" }
|
||||
}
|
||||
}
|
38
resources/definitions/kupido.def.json
Normal file
38
resources/definitions/kupido.def.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"id": "kupido",
|
||||
"name": "Kupido",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Kupido",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_name": { "default_value": "Kupido" },
|
||||
"machine_start_gcode": {
|
||||
"default_value": " ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n ;M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n ;M109 S{material_print_temperature} ;Uncomment to add your own temperature line\n G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X Y to endstops\n G28 Z0 ;move Z to endstops\n G1 Z20.0 F40 ;move the platform down 20mm\n G1 Y0 X170 F{speed_travel}\n G92 E0 ;zero the extruded length\n G1 F200 E10 ;extrude 3mm of feed stock\n G92 E0 ;zero the extruded length again\n G4 P7000\n G1 F{speed_travel}\n ;Put printing message on LCD screen\n M117 Printing...\n"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n"
|
||||
},
|
||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
||||
"retraction_speed": { "default_value": 60 },
|
||||
"material_bed_temperature": { "default_value": 60 },
|
||||
"speed_wall_x": { "default_value": 40 },
|
||||
"skirt_line_count": { "default_value": 2 },
|
||||
"retraction_min_travel": { "default_value": 2 },
|
||||
"speed_wall_0": { "default_value": 30 },
|
||||
"material_print_temperature": { "default_value": 220 },
|
||||
"brim_line_count": { "default_value": 15 },
|
||||
"retraction_amount": { "default_value": 3.6 },
|
||||
"speed_topbottom": { "default_value": 20 },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"speed_print": { "default_value": 30 },
|
||||
"speed_infill": { "default_value": 30 }
|
||||
}
|
||||
}
|
31
resources/definitions/makerbotreplicator.def.json
Normal file
31
resources/definitions/makerbotreplicator.def.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"id": "makerbotreplicator",
|
||||
"name": "MakerBotReplicator",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "MakerBot",
|
||||
"category": "Other",
|
||||
"file_formats": "application/x3g",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"prime_tower_size": { "default_value": 10.0 },
|
||||
"infill_sparse_density": { "default_value": 10 },
|
||||
"speed_travel": { "default_value": 150 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"layer_height": { "default_value": 0.15 },
|
||||
"material_print_temperature": { "default_value": 220 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 150 },
|
||||
"machine_gcode_flavor": { "default_value": "MakerBot" },
|
||||
"machine_depth": { "default_value": 145 },
|
||||
"machine_width": { "default_value": 225 },
|
||||
"machine_name": { "default_value": "MakerBot Replicator" }
|
||||
}
|
||||
}
|
41
resources/definitions/ord.def.json
Normal file
41
resources/definitions/ord.def.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"id": "ord",
|
||||
"name": "RoVa3D",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "ORD Solutions",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
"0": "ord_extruder_0",
|
||||
"1": "ord_extruder_1",
|
||||
"2": "ord_extruder_2",
|
||||
"3": "ord_extruder_3",
|
||||
"4": "ord_extruder_4"
|
||||
},
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"material_bed_temperature": { "default_value": 60 },
|
||||
"prime_tower_size": { "default_value": 7.0710678118654755 },
|
||||
"infill_sparse_density": { "default_value": 15 },
|
||||
"speed_travel": { "default_value": 150 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"layer_height": { "default_value": 0.3 },
|
||||
"machine_nozzle_size": { "default_value": 0.35 },
|
||||
"material_print_temperature": { "default_value": 240 },
|
||||
"machine_extruder_count": { "default_value": 5 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 200 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 250 },
|
||||
"machine_width": { "default_value": 215 },
|
||||
"machine_name": { "default_value": "RoVa3D" }
|
||||
}
|
||||
}
|
41
resources/definitions/punchtec_connect_xl.def.json
Normal file
41
resources/definitions/punchtec_connect_xl.def.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"id": "punchtec_connect_xl",
|
||||
"name": "Punchtec Connect XL",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Punchtec",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
"0": "punchtec_connect_xl_extruder_0",
|
||||
"1": "punchtec_connect_xl_extruder_1"
|
||||
},
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_head_polygon": { "default_value": [[ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0]] },
|
||||
"speed_travel": { "default_value": 150 },
|
||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
||||
"speed_wall_x": { "default_value": 40 },
|
||||
"speed_wall_0": { "default_value": 40 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"speed_topbottom": { "default_value": 40 },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"material_print_temperature": { "default_value": 195 },
|
||||
"speed_print": { "default_value": 40 },
|
||||
"speed_infill": { "default_value": 40 },
|
||||
"machine_extruder_count": { "default_value": 2 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 200 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 304 },
|
||||
"machine_width": { "default_value": 304 },
|
||||
"machine_name": { "default_value": "Punchtec Connect XL" }
|
||||
}
|
||||
}
|
53
resources/definitions/rigid3d.def.json
Normal file
53
resources/definitions/rigid3d.def.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"id": "rigid3d",
|
||||
"name": "Rigid3D",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Rigid3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_start_gcode": {
|
||||
"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
|
||||
},
|
||||
"machine_head_polygon": { "default_value": [[ 22, 67], [ 22, 51], [ 36, 51], [ 36, 67]] },
|
||||
"skirt_gap": { "default_value": 5.0 },
|
||||
"cool_min_layer_time": { "default_value": 10 },
|
||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
||||
"speed_wall_x": { "default_value": 40 },
|
||||
"speed_travel": { "default_value": 100 },
|
||||
"bottom_thickness": { "default_value": 0.75 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"layer_height_0": { "default_value": 0.25 },
|
||||
"support_angle": { "default_value": 45 },
|
||||
"material_bed_temperature": { "default_value": 100 },
|
||||
"top_thickness": { "default_value": 0.75 },
|
||||
"material_print_temperature": { "default_value": 235 },
|
||||
"retraction_speed": { "default_value": 60.0 },
|
||||
"wall_thickness": { "default_value": 0.8 },
|
||||
"retraction_min_travel": { "default_value": 2 },
|
||||
"speed_wall_0": { "default_value": 30 },
|
||||
"retraction_amount": { "default_value": 1 },
|
||||
"speed_topbottom": { "default_value": 30 },
|
||||
"layer_height": { "default_value": 0.25 },
|
||||
"speed_print": { "default_value": 40 },
|
||||
"speed_infill": { "default_value": 40 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 210 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 250 },
|
||||
"machine_width": { "default_value": 250 },
|
||||
"machine_name": { "default_value": "Rigid3D" }
|
||||
}
|
||||
}
|
50
resources/definitions/rigid3d_3rdgen.def.json
Normal file
50
resources/definitions/rigid3d_3rdgen.def.json
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
"id": "rigid3d_3rdgen",
|
||||
"name": "Rigid3D 3rdGen",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Rigid3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_start_gcode": {
|
||||
"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn extruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
|
||||
},
|
||||
"machine_head_polygon": { "default_value": [[ 18, 0], [ 18, 65], [ 32, 65], [ 32, 0]] },
|
||||
"cool_min_layer_time": { "default_value": 10 },
|
||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
||||
"skirt_gap": { "default_value": 5.0 },
|
||||
"speed_travel": { "default_value": 120 },
|
||||
"bottom_thickness": { "default_value": 0.75 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"layer_height_0": { "default_value": 0.25 },
|
||||
"support_angle": { "default_value": 45 },
|
||||
"material_bed_temperature": { "default_value": 100 },
|
||||
"retraction_min_travel": { "default_value": 2 },
|
||||
"speed_wall_0": { "default_value": 30 },
|
||||
"retraction_speed": { "default_value": 60.0 },
|
||||
"wall_thickness": { "default_value": 0.8 },
|
||||
"material_print_temperature": { "default_value": 235 },
|
||||
"retraction_amount": { "default_value": 1 },
|
||||
"speed_topbottom": { "default_value": 25 },
|
||||
"layer_height": { "default_value": 0.25 },
|
||||
"top_thickness": { "default_value": 0.75 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 240 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 290 },
|
||||
"machine_width": { "default_value": 275 },
|
||||
"machine_name": { "default_value": "Rigid3D 3rd Geneartion" }
|
||||
}
|
||||
}
|
47
resources/definitions/rigid3d_hobby.def.json
Normal file
47
resources/definitions/rigid3d_hobby.def.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "rigid3d_hobby",
|
||||
"name": "Rigid3D Hobby",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Rigid3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_head_polygon": { "default_value": [[ 16, 30], [ 16, 45], [ 16, 45], [ 16, 30]] },
|
||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
||||
"speed_travel": { "default_value": 40 },
|
||||
"skirt_gap": { "default_value": 5.0 },
|
||||
"cool_min_layer_time": { "default_value": 15 },
|
||||
"support_pattern": { "default_value": "grid" },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"layer_height_0": { "default_value": 0.25 },
|
||||
"speed_wall_x": { "default_value": 30 },
|
||||
"skirt_line_count": { "default_value": 2 },
|
||||
"support_angle": { "default_value": 45 },
|
||||
"speed_topbottom": { "default_value": 20 },
|
||||
"material_print_temperature": { "default_value": 205 },
|
||||
"retraction_speed": { "default_value": 80 },
|
||||
"wall_thickness": { "default_value": 0.8 },
|
||||
"retraction_min_travel": { "default_value": 2 },
|
||||
"speed_wall_0": { "default_value": 20 },
|
||||
"retraction_amount": { "default_value": 2 },
|
||||
"speed_layer_0": { "default_value": 15 },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"speed_print": { "default_value": 30 },
|
||||
"speed_infill": { "default_value": 30 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_heated_bed": { "default_value": false },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 150 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 150 },
|
||||
"machine_width": { "default_value": 150 },
|
||||
"machine_name": { "default_value": "Rigid3D Hobby" }
|
||||
}
|
||||
}
|
53
resources/definitions/rigid3d_zero.def.json
Normal file
53
resources/definitions/rigid3d_zero.def.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"id": "rigid3d_zero",
|
||||
"name": "Rigid3D Zero",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Rigid3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_start_gcode": {
|
||||
"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
|
||||
},
|
||||
"machine_head_polygon": { "default_value": [[ 40, 15], [ 40, 60], [ 30, 60], [ 30, 15]] },
|
||||
"support_pattern": { "default_value": "grid" },
|
||||
"cool_min_layer_time": { "default_value": 10 },
|
||||
"speed_travel": { "default_value": 80 },
|
||||
"support_angle": { "default_value": 45 },
|
||||
"retraction_min_travel": { "default_value": 2 },
|
||||
"speed_wall_0": { "default_value": 20 },
|
||||
"speed_layer_0": { "default_value": 15 },
|
||||
"speed_infill": { "default_value": 30 },
|
||||
"speed_topbottom": { "default_value": 30 },
|
||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
||||
"skirt_line_count": { "default_value": 2 },
|
||||
"speed_wall_x": { "default_value": 30 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"bottom_thickness": { "default_value": 0.75 },
|
||||
"layer_height_0": { "default_value": 0.25 },
|
||||
"top_thickness": { "default_value": 0.75 },
|
||||
"wall_thickness": { "default_value": 0.8 },
|
||||
"material_print_temperature": { "default_value": 195 },
|
||||
"retraction_amount": { "default_value": 1.5 },
|
||||
"skirt_gap": { "default_value": 5.0 },
|
||||
"layer_height": { "default_value": 0.25 },
|
||||
"speed_print": { "default_value": 30 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 190 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 250 },
|
||||
"machine_width": { "default_value": 250 },
|
||||
"machine_name": { "default_value": "Rigid3D Zero" }
|
||||
}
|
||||
}
|
@ -39,10 +39,10 @@
|
||||
"default_value": "RepRap (Marlin/Sprinter)"
|
||||
},
|
||||
"machine_start_gcode": {
|
||||
"default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..."
|
||||
"default_value": ";Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{material_print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\n;Put printing message on LCD screen\nM117 Rigibot Printing..."
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}"
|
||||
"default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning"
|
||||
},
|
||||
"layer_height": {
|
||||
"default_value": 0.2
|
||||
|
@ -42,10 +42,10 @@
|
||||
"default_value": "RepRap (Marlin/Sprinter)"
|
||||
},
|
||||
"machine_start_gcode": {
|
||||
"default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..."
|
||||
"default_value": ";Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{material_print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{speed_travel} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\n;Put printing message on LCD screen\nM117 Rigibot Printing..."
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}"
|
||||
"default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning"
|
||||
},
|
||||
"layer_height": {
|
||||
"default_value": 0.2
|
||||
|
61
resources/definitions/robo_3d_r1.def.json
Normal file
61
resources/definitions/robo_3d_r1.def.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"id": "robo_3d_r1",
|
||||
"name": "Robo 3D R1",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Robo 3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_start_gcode": {
|
||||
"default_value": " G92 E0 ;\n M565 Z-1 ;\n G1 Z5 F5000 ;\n G29 ;\n"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n"
|
||||
},
|
||||
"cool_min_layer_time": { "default_value": 7 },
|
||||
"speed_topbottom": { "default_value": 40 },
|
||||
"retraction_speed": { "default_value": 50 },
|
||||
"layer_0_z_overlap": { "default_value": 0.2 },
|
||||
"cool_min_speed": { "default_value": 19 },
|
||||
"material_bed_temperature": { "default_value": 60 },
|
||||
"support_angle": { "default_value": 50 },
|
||||
"speed_layer_0": { "default_value": 30 },
|
||||
"line_width": { "default_value": 0.4 },
|
||||
"speed_infill": { "default_value": 60 },
|
||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
||||
"support_enable": { "default_value": true },
|
||||
"cool_fan_full_at_height": { "default_value": 0.1 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"bottom_thickness": { "default_value": 1.2 },
|
||||
"raft_airgap": { "default_value": 0.2 },
|
||||
"layer_height_0": { "default_value": 0.15 },
|
||||
"top_thickness": { "default_value": 1.2 },
|
||||
"speed_wall_0": { "default_value": 40 },
|
||||
"retraction_min_travel": { "default_value": 5 },
|
||||
"material_flow": { "default_value": 100 },
|
||||
"infill_sparse_density": { "default_value": 10 },
|
||||
"wall_thickness": { "default_value": 1.2 },
|
||||
"material_print_temperature": { "default_value": 190 },
|
||||
"retraction_amount": { "default_value": 3 },
|
||||
"layer_height": { "default_value": 0.2 },
|
||||
"speed_print": { "default_value": 40 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"retraction_combing": { "default_value": "off" },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 210 },
|
||||
"adhesion_type": { "default_value": "raft" },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 245 },
|
||||
"machine_width": { "default_value": 225 },
|
||||
"support_z_distance": { "default_value": 0.22 },
|
||||
"machine_name": { "default_value": "ROBO 3D R1" }
|
||||
}
|
||||
}
|
@ -86,12 +86,6 @@
|
||||
"machine_nozzle_expansion_angle": {
|
||||
"default_value": 45
|
||||
},
|
||||
"material_print_temperature": {
|
||||
"enabled": "not (material_flow_dependent_temperature) and machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"material_bed_temperature": {
|
||||
"enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"machine_max_feedrate_x": {
|
||||
"default_value": 300
|
||||
},
|
||||
@ -106,24 +100,6 @@
|
||||
},
|
||||
"machine_acceleration": {
|
||||
"default_value": 3000
|
||||
},
|
||||
"material_diameter": {
|
||||
"enabled": "machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"material_flow": {
|
||||
"enabled": "machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"retraction_amount": {
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"retraction_speed": {
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"retraction_retract_speed": {
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\""
|
||||
},
|
||||
"retraction_prime_speed": {
|
||||
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
"overrides": {
|
||||
"machine_name": { "default_value": "Ultimaker 3" },
|
||||
"machine_width": { "default_value": 215 },
|
||||
"machine_width": { "default_value": 233 },
|
||||
"machine_depth": { "default_value": 215 },
|
||||
"machine_height": { "default_value": 200 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
@ -44,10 +44,10 @@
|
||||
{
|
||||
"default_value":
|
||||
[
|
||||
[ -40, 10 ],
|
||||
[ -40, -30 ],
|
||||
[ 60, 10 ],
|
||||
[ 60, -30 ]
|
||||
[ -29, 6.1 ],
|
||||
[ -29, -33.9 ],
|
||||
[ 71, 6.1 ],
|
||||
[ 71, -33.9 ]
|
||||
]
|
||||
},
|
||||
"machine_gcode_flavor": { "default_value": "Griffin" },
|
||||
@ -57,15 +57,12 @@
|
||||
"machine_acceleration": { "default_value": 3000 },
|
||||
"gantry_height": { "default_value": 60 },
|
||||
"machine_disallowed_areas": { "default_value": [
|
||||
[[-91.5, -115], [-115, -115], [-115, -104.6], [-91.5, -104.6]],
|
||||
[[-99.5, -104.6], [-115, -104.6], [-115, 104.6], [-99.5, 104.6]],
|
||||
[[-94.5, 104.6], [-115, 104.6], [-115, 105.5], [-94.5, 105.5]],
|
||||
[[-91.4, 105.5], [-115, 105.5], [-115, 115], [-91.4, 115]],
|
||||
|
||||
[[77.3, -115], [77.3, -98.6], [115, -98.6], [115, -115]],
|
||||
[[97.2, -98.6], [97.2, -54.5], [113, -54.5], [113, -98.6]],
|
||||
[[100.5, -54.5], [100.5, 99.3], [115, 99.3], [115, -54.5]],
|
||||
[[77, 99.3], [77, 115], [115, 115], [115, 99.3]]
|
||||
[[92.8, -53.4], [92.8, -97.5], [116.5, -97.5], [116.5, -53.4]],
|
||||
[[73.8, 107.5], [73.8, 100.5], [116.5, 100.5], [116.5, 107.5]],
|
||||
[[74.6, 107.5], [74.6, 100.5], [116.5, 100.5], [116.5, 107.5]],
|
||||
[[74.9, -97.5], [74.9, -107.5], [116.5, -107.5], [116.5, -97.5]],
|
||||
[[-116.5, -103.5], [-116.5, -107.5], [-100.9, -107.5], [-100.9, -103.5]],
|
||||
[[-116.5, 105.8], [-96.9, 105.8], [-96.9, 107.5], [-116.5, 107.5]]
|
||||
]},
|
||||
"machine_extruder_count": { "default_value": 2 },
|
||||
"extruder_prime_pos_abs": { "default_value": true },
|
||||
@ -74,10 +71,6 @@
|
||||
"prime_tower_position_x": { "default_value": 175 },
|
||||
"prime_tower_position_y": { "default_value": 179 },
|
||||
|
||||
"extruder_prime_pos_x": { "enabled": false },
|
||||
"extruder_prime_pos_y": { "enabled": false },
|
||||
"print_sequence": {"enabled": false},
|
||||
|
||||
"acceleration_enabled": { "value": "True" },
|
||||
"acceleration_layer_0": { "value": "acceleration_topbottom" },
|
||||
"acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
|
||||
@ -106,6 +99,8 @@
|
||||
"jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
|
||||
"jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
|
||||
"layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" },
|
||||
"layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
|
||||
"layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
|
||||
"line_width": { "value": "machine_nozzle_size * 0.875" },
|
||||
"machine_min_cool_heat_time_window": { "value": "15" },
|
||||
"material_print_temperature": { "value": "200" },
|
||||
|
@ -14,7 +14,7 @@
|
||||
"platform_texture": "Ultimaker3Extendedbackplate.png",
|
||||
"platform_offset": [0, 0, 0],
|
||||
"has_machine_quality": true,
|
||||
"has_machine_materials": true,
|
||||
"has_machine_materials": true,
|
||||
"has_variant_materials": true,
|
||||
"has_materials": true,
|
||||
"has_variants": true,
|
||||
|
@ -72,9 +72,6 @@
|
||||
"machine_extruder_count": {
|
||||
"default_value": 2
|
||||
},
|
||||
"print_sequence": {
|
||||
"enabled": false
|
||||
},
|
||||
"prime_tower_position_x": {
|
||||
"default_value": 185
|
||||
},
|
||||
|
30
resources/definitions/zone3d_printer.def.json
Normal file
30
resources/definitions/zone3d_printer.def.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"id": "zone3d_printer",
|
||||
"name": "Zone3d Printer",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Unknown",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [ 0, 0, 0]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"prime_tower_size": { "default_value": 10.350983390135314 },
|
||||
"material_print_temperature": { "default_value": 260 },
|
||||
"layer_height": { "default_value": 0.14 },
|
||||
"speed_travel": { "default_value": 150 },
|
||||
"machine_extruder_count": { "default_value": 1 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_height": { "default_value": 210 },
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
"machine_depth": { "default_value": 220 },
|
||||
"machine_width": { "default_value": 240 },
|
||||
"machine_name": { "default_value": "Zone3D Printer" }
|
||||
}
|
||||
}
|
19
resources/extruders/ord_extruder_0.def.json
Normal file
19
resources/extruders/ord_extruder_0.def.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "ord_extruder_0",
|
||||
"version": 2,
|
||||
"name": "0",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "ord",
|
||||
"position": "0"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 0,
|
||||
"maximum_value": "4"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0.0 }
|
||||
}
|
||||
}
|
19
resources/extruders/ord_extruder_1.def.json
Normal file
19
resources/extruders/ord_extruder_1.def.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "ord_extruder_1",
|
||||
"version": 2,
|
||||
"name": "1",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "ord",
|
||||
"position": "1"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 1,
|
||||
"maximum_value": "4"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 62.95 },
|
||||
"machine_nozzle_offset_y": { "default_value": 2.05 }
|
||||
}
|
||||
}
|
19
resources/extruders/ord_extruder_2.def.json
Normal file
19
resources/extruders/ord_extruder_2.def.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "ord_extruder_2",
|
||||
"version": 2,
|
||||
"name": "2",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "ord",
|
||||
"position": "2"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 2,
|
||||
"maximum_value": "4"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 27.7 }
|
||||
}
|
||||
}
|
19
resources/extruders/ord_extruder_3.def.json
Normal file
19
resources/extruders/ord_extruder_3.def.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "ord_extruder_3",
|
||||
"version": 2,
|
||||
"name": "3",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "ord",
|
||||
"position": "3"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 3,
|
||||
"maximum_value": "4"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 63.18 },
|
||||
"machine_nozzle_offset_y": { "default_value": 28.65 }
|
||||
}
|
||||
}
|
19
resources/extruders/ord_extruder_4.def.json
Normal file
19
resources/extruders/ord_extruder_4.def.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "ord_extruder_4",
|
||||
"version": 2,
|
||||
"name": "4",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "ord",
|
||||
"position": "4"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 4,
|
||||
"maximum_value": "4"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 31.6 },
|
||||
"machine_nozzle_offset_y": { "default_value": 28.2 }
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "punchtec_connect_xl_extruder_0",
|
||||
"version": 2,
|
||||
"name": "0",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "punchtec_connect_xl",
|
||||
"position": "0"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 0,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0.0 }
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"id": "punchtec_connect_xl_extruder_1",
|
||||
"version": 2,
|
||||
"name": "1",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "punchtec_connect_xl",
|
||||
"position": "1"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 1,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0.0 }
|
||||
}
|
||||
}
|
@ -13,8 +13,8 @@
|
||||
"default_value": 0,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": -11.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 3.9 },
|
||||
"machine_nozzle_offset_x": { "default_value": 0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0 },
|
||||
|
||||
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||
"machine_extruder_start_pos_x": { "default_value": 213 },
|
||||
@ -23,8 +23,8 @@
|
||||
"machine_extruder_end_pos_x": { "default_value": 213 },
|
||||
"machine_extruder_end_pos_y": { "default_value": 207 },
|
||||
"machine_nozzle_head_distance": { "default_value": 2.7 },
|
||||
"extruder_prime_pos_x": { "default_value": 170, "enabled": false },
|
||||
"extruder_prime_pos_y": { "default_value": 6, "enabled": false },
|
||||
"extruder_prime_pos_z": { "default_value": 2, "enabled": false }
|
||||
"extruder_prime_pos_x": { "default_value": 170 },
|
||||
"extruder_prime_pos_y": { "default_value": 6 },
|
||||
"extruder_prime_pos_z": { "default_value": 2 }
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
"default_value": 1,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 7.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 3.9 },
|
||||
"machine_nozzle_offset_x": { "default_value": 18 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0 },
|
||||
|
||||
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||
"machine_extruder_start_pos_x": { "default_value": 213 },
|
||||
@ -23,8 +23,8 @@
|
||||
"machine_extruder_end_pos_x": { "default_value": 213 },
|
||||
"machine_extruder_end_pos_y": { "default_value": 189 },
|
||||
"machine_nozzle_head_distance": { "default_value": 4.2 },
|
||||
"extruder_prime_pos_x": { "default_value": 182, "enabled": false },
|
||||
"extruder_prime_pos_y": { "default_value": 6, "enabled": false },
|
||||
"extruder_prime_pos_z": { "default_value": 2, "enabled": false }
|
||||
"extruder_prime_pos_x": { "default_value": 182 },
|
||||
"extruder_prime_pos_y": { "default_value": 6 },
|
||||
"extruder_prime_pos_z": { "default_value": 2 }
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
"default_value": 0,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": -11.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 3.9 },
|
||||
"machine_nozzle_offset_x": { "default_value": 0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0 },
|
||||
|
||||
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||
"machine_extruder_start_pos_x": { "default_value": 213 },
|
||||
@ -23,8 +23,8 @@
|
||||
"machine_extruder_end_pos_x": { "default_value": 213 },
|
||||
"machine_extruder_end_pos_y": { "default_value": 207 },
|
||||
"machine_nozzle_head_distance": { "default_value": 2.7 },
|
||||
"extruder_prime_pos_x": { "default_value": 170, "enabled": false },
|
||||
"extruder_prime_pos_y": { "default_value": 6, "enabled": false },
|
||||
"extruder_prime_pos_z": { "default_value": 2, "enabled": false }
|
||||
"extruder_prime_pos_x": { "default_value": 170 },
|
||||
"extruder_prime_pos_y": { "default_value": 6 },
|
||||
"extruder_prime_pos_z": { "default_value": 2 }
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
"default_value": 1,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_offset_x": { "default_value": 7.0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 3.9 },
|
||||
"machine_nozzle_offset_x": { "default_value": 18 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0 },
|
||||
|
||||
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||
"machine_extruder_start_pos_x": { "default_value": 213 },
|
||||
@ -23,8 +23,8 @@
|
||||
"machine_extruder_end_pos_x": { "default_value": 213 },
|
||||
"machine_extruder_end_pos_y": { "default_value": 189 },
|
||||
"machine_nozzle_head_distance": { "default_value": 4.2 },
|
||||
"extruder_prime_pos_x": { "default_value": 182, "enabled": false },
|
||||
"extruder_prime_pos_y": { "default_value": 6, "enabled": false },
|
||||
"extruder_prime_pos_z": { "default_value": 2, "enabled": false }
|
||||
"extruder_prime_pos_x": { "default_value": 182 },
|
||||
"extruder_prime_pos_y": { "default_value": 6 },
|
||||
"extruder_prime_pos_z": { "default_value": 2 }
|
||||
}
|
||||
}
|
||||
|
@ -160,13 +160,13 @@ msgstr "Salvato su unità rimovibile {0} come {1}"
|
||||
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:103
|
||||
msgctxt "@action:button"
|
||||
msgid "Eject"
|
||||
msgstr "Espelli"
|
||||
msgstr "Rimuovi"
|
||||
|
||||
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:103
|
||||
#, python-brace-format
|
||||
msgctxt "@action"
|
||||
msgid "Eject removable device {0}"
|
||||
msgstr "Espelli il dispositivo rimovibile {0}"
|
||||
msgstr "Rimuovi il dispositivo rimovibile {0}"
|
||||
|
||||
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:108
|
||||
#, python-brace-format
|
||||
@ -2008,7 +2008,7 @@ msgstr "Sel&eziona tutti i modelli"
|
||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:248
|
||||
msgctxt "@action:inmenu menubar:edit"
|
||||
msgid "&Clear Build Plate"
|
||||
msgstr "&Cancella piano di stampa"
|
||||
msgstr "&Cancellare piano di stampa"
|
||||
|
||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
|
||||
msgctxt "@action:inmenu menubar:file"
|
||||
|
@ -2257,12 +2257,12 @@ msgstr "Regola il posizionamento delle strutture di supporto. Il posizionamento
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_type option buildplate"
|
||||
msgid "Touching Buildplate"
|
||||
msgstr "Sostegno solo delle pareti esterne"
|
||||
msgstr "Contatto con il Piano di Stampa"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_type option everywhere"
|
||||
msgid "Everywhere"
|
||||
msgstr "In tutti i possibili punti"
|
||||
msgstr "In Tutti i Possibili Punti"
|
||||
|
||||
#: fdmprinter.def.json
|
||||
msgctxt "support_angle label"
|
||||
|
@ -121,7 +121,7 @@ Item
|
||||
Action
|
||||
{
|
||||
id: updateProfileAction;
|
||||
enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId)
|
||||
enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId)
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings");
|
||||
onTriggered: Cura.ContainerManager.updateQualityChanges();
|
||||
}
|
||||
@ -130,14 +130,18 @@ Item
|
||||
{
|
||||
id: resetProfileAction;
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Discard current settings");
|
||||
onTriggered: Cura.ContainerManager.clearUserContainers();
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Discard current changes");
|
||||
onTriggered:
|
||||
{
|
||||
forceActiveFocus();
|
||||
Cura.ContainerManager.clearUserContainers();
|
||||
}
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: addProfileAction;
|
||||
enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings
|
||||
enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings...");
|
||||
}
|
||||
|
||||
@ -228,7 +232,7 @@ Item
|
||||
Action
|
||||
{
|
||||
id: multiplyObjectAction;
|
||||
text: catalog.i18nc("@action:inmenu","&Duplicate Model");
|
||||
text: catalog.i18nc("@action:inmenu","&Multiply Model...");
|
||||
iconName: "edit-duplicate"
|
||||
}
|
||||
|
||||
|
@ -246,15 +246,35 @@ UM.MainWindow
|
||||
{
|
||||
if(drop.urls.length > 0)
|
||||
{
|
||||
// Import models
|
||||
for(var i in drop.urls)
|
||||
{
|
||||
UM.MeshFileHandler.readLocalFile(drop.urls[i]);
|
||||
if (i == drop.urls.length - 1)
|
||||
{
|
||||
var meshName = backgroundItem.getMeshName(drop.urls[i].toString())
|
||||
backgroundItem.hasMesh(decodeURIComponent(meshName))
|
||||
// There is no endsWith in this version of JS...
|
||||
if ((drop.urls[i].length <= 12) || (drop.urls[i].substring(drop.urls[i].length-12) !== ".curaprofile")) {
|
||||
// Drop an object
|
||||
UM.MeshFileHandler.readLocalFile(drop.urls[i]);
|
||||
if (i == drop.urls.length - 1)
|
||||
{
|
||||
var meshName = backgroundItem.getMeshName(drop.urls[i].toString());
|
||||
backgroundItem.hasMesh(decodeURIComponent(meshName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Import profiles
|
||||
var import_result = Cura.ContainerManager.importProfiles(drop.urls);
|
||||
if (import_result.message !== "") {
|
||||
messageDialog.text = import_result.message
|
||||
if(import_result.status == "ok")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information
|
||||
}
|
||||
else
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
}
|
||||
messageDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -402,6 +422,20 @@ UM.MainWindow
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2
|
||||
visible: base.monitoringPrint
|
||||
onVisibleChanged:
|
||||
{
|
||||
if(Cura.MachineManager.printerOutputDevices.length == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(visible)
|
||||
{
|
||||
Cura.MachineManager.printerOutputDevices[0].startCamera()
|
||||
} else
|
||||
{
|
||||
Cura.MachineManager.printerOutputDevices[0].stopCamera()
|
||||
}
|
||||
}
|
||||
source:
|
||||
{
|
||||
if(!base.monitoringPrint)
|
||||
@ -539,7 +573,7 @@ UM.MainWindow
|
||||
target: Cura.MachineManager
|
||||
onBlurSettings:
|
||||
{
|
||||
contentItem.focus = true
|
||||
contentItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,6 +609,11 @@ UM.MainWindow
|
||||
}
|
||||
}
|
||||
|
||||
MultiplyObjectOptions
|
||||
{
|
||||
id: multiplyObjectOptions
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: Cura.Actions.multiplyObject
|
||||
@ -582,7 +621,9 @@ UM.MainWindow
|
||||
{
|
||||
if(objectContextMenu.objectId != 0)
|
||||
{
|
||||
Printer.multiplyObject(objectContextMenu.objectId, 1);
|
||||
multiplyObjectOptions.objectId = objectContextMenu.objectId;
|
||||
multiplyObjectOptions.visible = true;
|
||||
multiplyObjectOptions.reset();
|
||||
objectContextMenu.objectId = 0;
|
||||
}
|
||||
}
|
||||
|
@ -153,6 +153,7 @@ Menu
|
||||
else
|
||||
{
|
||||
result.definition = "fdmprinter";
|
||||
result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
66
resources/qml/MultiplyObjectOptions.qml
Normal file
66
resources/qml/MultiplyObjectOptions.qml
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
id: base
|
||||
|
||||
//: Dialog title
|
||||
title: catalog.i18nc("@title:window", "Multiply Model")
|
||||
|
||||
minimumWidth: 400 * Screen.devicePixelRatio
|
||||
minimumHeight: 80 * Screen.devicePixelRatio
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
|
||||
property var objectId: 0;
|
||||
onAccepted: Printer.multiplyObject(base.objectId, parseInt(copiesField.text))
|
||||
|
||||
property variant catalog: UM.I18nCatalog { name: "cura" }
|
||||
|
||||
signal reset()
|
||||
onReset: {
|
||||
copiesField.text = "1";
|
||||
copiesField.selectAll();
|
||||
copiesField.focus = true;
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Label {
|
||||
text: "Number of copies:"
|
||||
anchors.verticalCenter: copiesField.verticalCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: copiesField
|
||||
validator: RegExpValidator { regExp: /^\d{0,2}/ }
|
||||
maximumLength: 2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rightButtons:
|
||||
[
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button","OK")
|
||||
onClicked: base.accept()
|
||||
enabled: base.objectId != 0 && parseInt(copiesField.text) > 0
|
||||
},
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button","Cancel")
|
||||
onClicked: base.reject()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -251,6 +251,8 @@ UM.ManagementPage
|
||||
{
|
||||
id: renameDialog;
|
||||
object: base.currentItem && base.currentItem.name ? base.currentItem.name : "";
|
||||
property var machine_name_validator: Cura.MachineNameValidator { }
|
||||
validName: renameDialog.newName.match(renameDialog.machine_name_validator.machineNameRegex) != null;
|
||||
onAccepted:
|
||||
{
|
||||
Cura.MachineManager.renameMachine(base.currentItem.id, newName.trim());
|
||||
|
@ -22,7 +22,7 @@ TabView
|
||||
|
||||
Tab
|
||||
{
|
||||
title: "Information"
|
||||
title: catalog.i18nc("@title","Information")
|
||||
anchors
|
||||
{
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
|
@ -29,7 +29,8 @@ UM.ManagementPage
|
||||
}
|
||||
else
|
||||
{
|
||||
result.definition = "fdmprinter"
|
||||
result.definition = "fdmprinter";
|
||||
result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ UM.ManagementPage
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@label", "Create")
|
||||
enabled: base.canCreateProfile()
|
||||
enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors
|
||||
visible: base.canCreateProfile()
|
||||
iconName: "list-add";
|
||||
|
||||
@ -170,7 +170,7 @@ UM.ManagementPage
|
||||
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Discard current settings");
|
||||
text: catalog.i18nc("@action:button", "Discard current changes");
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
onClicked: Cura.ContainerManager.clearUserContainers();
|
||||
}
|
||||
@ -310,7 +310,7 @@ UM.ManagementPage
|
||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||
onAccepted:
|
||||
{
|
||||
var result = base.model.importProfile(fileUrl)
|
||||
var result = Cura.ContainerManager.importProfile(fileUrl);
|
||||
messageDialog.text = result.message
|
||||
if(result.status == "ok")
|
||||
{
|
||||
@ -339,7 +339,7 @@ UM.ManagementPage
|
||||
onAccepted:
|
||||
{
|
||||
var containers = Cura.ContainerManager.findInstanceContainers({"type": "quality_changes", "name": base.currentItem.name})
|
||||
var result = base.model.exportProfile(containers, fileUrl, selectedNameFilter)
|
||||
var result = Cura.ContainerManager.exportProfile(containers, fileUrl, selectedNameFilter)
|
||||
|
||||
if(result && result.status == "error")
|
||||
{
|
||||
|
@ -116,7 +116,8 @@ UM.PreferencesPage
|
||||
id: definitionsModel
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
showAll: true
|
||||
exclude: ["machine_settings"]
|
||||
exclude: ["machine_settings", "command_line_settings"]
|
||||
showAncestors: true
|
||||
expanded: ["*"]
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||
}
|
||||
|
@ -29,11 +29,11 @@ SettingItem
|
||||
// 4: variant
|
||||
// 5: machine
|
||||
var value;
|
||||
if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
value = propertyProvider.properties.resolve;
|
||||
value = base.resolve;
|
||||
} else {
|
||||
value = propertyProvider.properties.value;
|
||||
}
|
||||
|
@ -96,11 +96,11 @@ SettingItem
|
||||
{
|
||||
// FIXME this needs to go away once 'resolve' is combined with 'value' in our data model.
|
||||
var value;
|
||||
if ((propertyProvider.properties.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
|
||||
if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
value = propertyProvider.properties.resolve;
|
||||
value = base.resolve;
|
||||
} else {
|
||||
value = propertyProvider.properties.value;
|
||||
}
|
||||
|
@ -21,7 +21,11 @@ SettingItem
|
||||
id: extruders_model
|
||||
onModelChanged: control.color = extruders_model.getItem(control.currentIndex).color
|
||||
}
|
||||
property string color: extruders_model.getItem(control.currentIndex).color
|
||||
property string color:
|
||||
{
|
||||
var model_color = extruders_model.getItem(control.currentIndex).color;
|
||||
return (model_color) ? model_color : "";
|
||||
}
|
||||
|
||||
textRole: "name"
|
||||
|
||||
|
@ -27,7 +27,8 @@ Item {
|
||||
|
||||
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
|
||||
property var state: propertyProvider.properties.state
|
||||
property var resolve: propertyProvider.properties.resolve
|
||||
// There is no resolve property if there is only one stack.
|
||||
property var resolve: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId ? propertyProvider.properties.resolve : "None"
|
||||
property var stackLevels: propertyProvider.stackLevels
|
||||
property var stackLevel: stackLevels[0]
|
||||
|
||||
|
@ -114,11 +114,11 @@ SettingItem
|
||||
// 3: material -> user changed material in materialspage
|
||||
// 4: variant
|
||||
// 5: machine
|
||||
if ((propertyProvider.properties.resolve != "None" && propertyProvider.properties.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
return propertyProvider.properties.resolve;
|
||||
return base.resolve;
|
||||
} else {
|
||||
return propertyProvider.properties.value;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ ScrollView
|
||||
id: definitionsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||
exclude: ["machine_settings", "infill_mesh", "infill_mesh_order"]
|
||||
exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
|
||||
expanded: Printer.expandedCategories
|
||||
onExpandedChanged: Printer.setExpandedCategories(expanded)
|
||||
onVisibilityChanged: Cura.SettingInheritanceManager.forceUpdate()
|
||||
|
@ -222,6 +222,7 @@ Column
|
||||
width: materialSelection.visible ? (parent.width - UM.Theme.getSize("default_margin").width) / 2 : parent.width
|
||||
anchors.left: parent.left
|
||||
style: UM.Theme.styles.sidebar_header_button
|
||||
activeFocusOnPress: true;
|
||||
|
||||
menu: NozzleMenu { extruderIndex: base.currentExtruderIndex }
|
||||
}
|
||||
@ -252,6 +253,7 @@ Column
|
||||
width: variantSelection.visible ? (parent.width - UM.Theme.getSize("default_margin").width) / 2 : parent.width
|
||||
anchors.right: parent.right
|
||||
style: UM.Theme.styles.sidebar_header_button
|
||||
activeFocusOnPress: true;
|
||||
|
||||
menu: MaterialMenu { extruderIndex: base.currentExtruderIndex }
|
||||
}
|
||||
@ -301,6 +303,7 @@ Column
|
||||
height: UM.Theme.getSize("setting_control").height
|
||||
tooltip: Cura.MachineManager.activeQualityName
|
||||
style: UM.Theme.styles.sidebar_header_button
|
||||
activeFocusOnPress: true;
|
||||
property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported
|
||||
menu: ProfileMenu { }
|
||||
|
||||
@ -319,7 +322,11 @@ Column
|
||||
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button");
|
||||
iconSource: UM.Theme.getIcon("star");
|
||||
|
||||
onClicked: Cura.Actions.manageProfiles.trigger()
|
||||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
Cura.Actions.manageProfiles.trigger()
|
||||
}
|
||||
onEntered:
|
||||
{
|
||||
var content = catalog.i18nc("@tooltip","Some setting values are different from the values stored in the profile.\n\nClick to open the profile manager.")
|
||||
|
@ -126,7 +126,7 @@ Item
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_disabled_text")
|
||||
}
|
||||
return UM.Theme.getColor("text")
|
||||
return UM.Theme.getColor("setting_control_disabled_text")
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ Item
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: supportHelperLabel.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
width: parent.width / 100 * 45
|
||||
width: parent.width / 100 * 65
|
||||
|
||||
style: UM.Theme.styles.combobox
|
||||
enabled: base.settingsEnabled
|
||||
|
Loading…
x
Reference in New Issue
Block a user