Merge branch '5.11' into CURA-12742_add-message-when-painted-with-disabled-extruder
Some checks failed
conan-package-resources / conan-package (push) Has been cancelled
conan-package / conan-package (push) Has been cancelled
printer-linter-format / Printer linter auto format (push) Has been cancelled
unit-test / Run unit tests (push) Has been cancelled
conan-package-resources / signal-curator (push) Has been cancelled

This commit is contained in:
HellAholic 2025-10-17 13:57:44 +02:00 committed by GitHub
commit d1aee97ea2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 197 additions and 106 deletions

View file

@ -1,16 +1,16 @@
version: "5.11.0-beta.1"
version: "5.11.0"
commit: "unknown"
requirements:
- "cura_resources/5.11.0-beta.1"
- "uranium/5.11.0-beta.1"
- "curaengine/5.11.0-beta.1"
- "cura_binary_data/5.11.0-beta.1"
- "fdm_materials/5.11.0-beta.1"
- "cura_resources/5.11.0"
- "uranium/5.11.0"
- "curaengine/5.11.0"
- "cura_binary_data/5.11.0"
- "fdm_materials/5.11.0"
- "dulcificum/5.10.0"
- "pysavitar/5.11.0-alpha.0"
- "pynest2d/5.10.0"
requirements_internal:
- "fdm_materials/5.11.0-beta.1"
- "fdm_materials/5.11.0"
- "cura_private_data/5.11.0-alpha.0@internal/testing"
requirements_enterprise:
- "native_cad_plugin/2.0.0"

View file

@ -116,7 +116,8 @@ class BuildVolume(SceneNode):
self._application.engineCreatedSignal.connect(self._onEngineCreated)
self._has_errors = False
self._application.getController().getScene().sceneChanged.connect(self._onSceneChanged)
scene = self._application.getController().getScene()
scene.sceneChanged.connect(self._onSceneChanged)
# Objects loaded at the moment. We are connected to the property changed events of these objects.
self._scene_objects = set() # type: Set[SceneNode]
@ -645,7 +646,7 @@ class BuildVolume(SceneNode):
extra_z = retraction_hop
return extra_z
def _onStackChanged(self):
def _onStackChanged(self, *args) -> None:
self._stack_change_timer.start()
def _onStackChangeTimerFinished(self) -> None:

View file

@ -1,9 +1,12 @@
# Copyright (c) 2025 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
import copy
import json
import numpy
from typing import Optional, Dict
from typing import Optional, Dict, List
from PyQt6.QtCore import QBuffer
from PyQt6.QtCore import QBuffer, QTimer
from PyQt6.QtGui import QImage, QImageWriter
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
@ -25,6 +28,14 @@ class SliceableObjectDecorator(SceneNodeDecorator):
from cura.CuraApplication import CuraApplication
application = CuraApplication.getInstance()
application.getMachineManager().extruderChanged.connect(self._updateIsAssignedToDisabledExtruder)
self._painted_extruders: Optional[List[int]] = None
self.paintTextureChanged = Signal()
self._texture_change_timer = QTimer()
self._texture_change_timer.setInterval(500) # Long interval to avoid triggering during painting
self._texture_change_timer.setSingleShot(True)
self._texture_change_timer.timeout.connect(self._onTextureChangeTimerFinished)
def isSliceable(self) -> bool:
return True
@ -35,6 +46,32 @@ class SliceableObjectDecorator(SceneNodeDecorator):
def getPaintTextureChangedSignal(self) -> Signal:
return self.paintTextureChanged
def setPaintedExtrudersCountDirty(self) -> None:
self._texture_change_timer.start()
def _onTextureChangeTimerFinished(self) -> None:
self._painted_extruders = None
if (self._paint_texture is None or self._paint_texture.getImage() is None or
"extruder" not in self._texture_data_mapping):
return
image = self._paint_texture.getImage()
image_bits = image.constBits()
image_bits.setsize(image.sizeInBytes())
image_array = numpy.frombuffer(image_bits, dtype=numpy.uint32)
bit_range_start, bit_range_end = self._texture_data_mapping["extruder"]
full_int32 = 0xffffffff
bit_mask = (((full_int32 << (32 - 1 - (bit_range_end - bit_range_start))) & full_int32) >> (
32 - 1 - bit_range_end))
texel_counts = numpy.bincount((image_array & bit_mask) >> bit_range_start)
self._painted_extruders = [extruder_nr for extruder_nr, count in enumerate(texel_counts) if count > 0]
from cura.CuraApplication import CuraApplication
CuraApplication.getInstance().globalContainerStackChanged.emit()
def setPaintTexture(self, texture: Texture) -> None:
self._paint_texture = texture
self.paintTextureChanged.emit()
@ -84,6 +121,8 @@ class SliceableObjectDecorator(SceneNodeDecorator):
pass
self._is_assigned_to_disabled_extruder = new_is_assigned_to_disabled_extruder
def getPaintedExtruders(self) -> Optional[List[int]]:
return self._painted_extruders
def __deepcopy__(self, memo) -> "SliceableObjectDecorator":
copied_decorator = SliceableObjectDecorator()

View file

@ -1,4 +1,4 @@
# Copyright (c) 2022 Ultimaker B.V.
# Copyright (c) 2025 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
@ -254,6 +254,11 @@ class ExtruderManager(QObject):
if not support_roof_enabled:
support_roof_enabled |= stack_to_use.getProperty("support_roof_enable", "value")
painted_extruders = node.callDecoration("getPaintedExtruders")
if painted_extruders is not None:
for extruder_nr in painted_extruders:
used_extruder_stack_ids.add(self.extruderIds[str(extruder_nr)])
# Check limit to extruders
limit_to_extruder_feature_list = ["wall_0_extruder_nr",
"wall_x_extruder_nr",

View file

@ -416,7 +416,7 @@ class StartSliceJob(Job):
# Only check if the printing extruder is enabled for printing meshes
is_non_printing_mesh = node.callDecoration("evaluateIsNonPrintingMesh")
if not is_non_printing_mesh:
for used_extruder in StartSliceJob._getUsedExtruders(node):
for used_extruder in StartSliceJob._getMainExtruders(node):
if not extruders_enabled[used_extruder]:
skip_group = True
has_model_with_disabled_extruders = True
@ -762,28 +762,11 @@ class StartSliceJob(Job):
self._addRelations(relations_set, relation.target.relations)
@staticmethod
def _getUsedExtruders(node: SceneNode) -> List[int]:
used_extruders = []
# Look at extruders used in painted texture
node_texture = node.callDecoration("getPaintTexture")
texture_data_mapping = node.callDecoration("getTextureDataMapping")
if node_texture is not None and texture_data_mapping is not None and "extruder" in texture_data_mapping:
texture_image = node_texture.getImage()
image_ptr = texture_image.constBits()
image_ptr.setsize(texture_image.sizeInBytes())
image_size = texture_image.height(), texture_image.width()
image_array = numpy.frombuffer(image_ptr, dtype=numpy.uint32).reshape(image_size)
bit_range_start, bit_range_end = texture_data_mapping["extruder"]
full_int32 = 0xffffffff
bit_mask = (((full_int32 << (32 - 1 - (bit_range_end - bit_range_start))) & full_int32) >> (
32 - 1 - bit_range_end))
used_extruders = (numpy.unique(image_array & bit_mask) >> bit_range_start).tolist()
def _getMainExtruders(node: SceneNode) -> List[int]:
used_extruders = node.callDecoration("getPaintedExtruders")
# There is no relevant painting data, just take the extruder associated to the model
if not used_extruders:
used_extruders = [int(node.callDecoration("getActiveExtruderPosition"))]
return used_extruders
return used_extruders

View file

@ -109,4 +109,6 @@ class MultiMaterialExtruderConverter:
texture.updateImagePart(image.rect())
node.callDecoration("setPaintedExtrudersCountDirty")
self.mainExtruderChanged.emit(node)

View file

@ -5,6 +5,7 @@ from typing import Optional
from PyQt6.QtGui import QUndoCommand, QImage, QPainter, QBrush
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
from UM.View.GL.Texture import Texture
from .PaintCommand import PaintCommand
@ -13,8 +14,12 @@ from .PaintCommand import PaintCommand
class PaintClearCommand(PaintCommand):
"""Provides the command that clears all the painting for the current mode"""
def __init__(self, texture: Texture, bit_range: tuple[int, int], set_value: int) -> None:
super().__init__(texture, bit_range)
def __init__(self,
texture: Texture,
bit_range: tuple[int, int],
set_value: int,
sliceable_object_decorator: Optional[SliceableObjectDecorator] = None) -> None:
super().__init__(texture, bit_range, sliceable_object_decorator=sliceable_object_decorator)
self._set_value = set_value
def id(self) -> int:
@ -22,13 +27,12 @@ class PaintClearCommand(PaintCommand):
def redo(self) -> None:
painter = self._makeClearedTexture()
if self._set_value > 0:
painter.setCompositionMode(QPainter.CompositionMode.RasterOp_SourceOrDestination)
painter.fillRect(self._texture.getImage().rect(), QBrush(self._set_value))
painter.end()
self._setPaintedExtrudersCountDirty()
self._texture.updateImagePart(self._bounding_rect)
def mergeWith(self, command: QUndoCommand) -> bool:
@ -38,6 +42,6 @@ class PaintClearCommand(PaintCommand):
# There is actually nothing more to do here, both clear commands already have the same original texture
return True
def _clearTextureBits(self, painter: QPainter):
def _clearTextureBits(self, painter: QPainter, extended = False):
painter.setCompositionMode(QPainter.CompositionMode.RasterOp_NotSourceAndDestination)
painter.fillRect(self._texture.getImage().rect(), QBrush(self._getBitRangeMask()))

View file

@ -1,12 +1,14 @@
# Copyright (c) 2025 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Tuple, Optional
from typing import Tuple, Optional, Dict
from PyQt6.QtCore import QRect
import numpy
from PyQt6.QtGui import QUndoCommand, QImage, QPainter, QBrush
from UM.View.GL.Texture import Texture
from cura.CuraApplication import CuraApplication
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
class PaintCommand(QUndoCommand):
@ -14,7 +16,11 @@ class PaintCommand(QUndoCommand):
FULL_INT32 = 0xffffffff
def __init__(self, texture: Texture, bit_range: tuple[int, int], make_original_image = True) -> None:
def __init__(self,
texture: Texture,
bit_range: tuple[int, int],
make_original_image = True,
sliceable_object_decorator: Optional[SliceableObjectDecorator] = None) -> None:
super().__init__()
self._texture: Texture = texture
@ -22,6 +28,8 @@ class PaintCommand(QUndoCommand):
self._original_texture_image = None
self._bounding_rect = texture.getImage().rect()
self._sliceable_object_decorator: Optional[SliceableObjectDecorator] = sliceable_object_decorator
if make_original_image:
self._original_texture_image = self._texture.getImage().copy()
painter = QPainter(self._original_texture_image)
@ -35,21 +43,26 @@ class PaintCommand(QUndoCommand):
if self._original_texture_image is None:
return
painter = self._makeClearedTexture()
painter = self._makeClearedTexture(extended=True)
painter.setCompositionMode(QPainter.CompositionMode.RasterOp_SourceOrDestination)
painter.drawImage(0, 0, self._original_texture_image)
painter.end()
self._setPaintedExtrudersCountDirty()
self._texture.updateImagePart(self._bounding_rect)
def _makeClearedTexture(self) -> QPainter:
def _setPaintedExtrudersCountDirty(self) -> None:
if self._sliceable_object_decorator is not None:
self._sliceable_object_decorator.setPaintedExtrudersCountDirty()
def _makeClearedTexture(self, extended = False) -> QPainter:
painter = QPainter(self._texture.getImage())
painter.setRenderHint(QPainter.RenderHint.Antialiasing, False)
self._clearTextureBits(painter)
self._clearTextureBits(painter, extended)
return painter
def _clearTextureBits(self, painter: QPainter):
def _clearTextureBits(self, painter: QPainter, extended = False):
raise NotImplementedError()
@staticmethod

View file

@ -7,6 +7,7 @@ import math
from PyQt6.QtCore import QRect, QRectF, QPoint
from PyQt6.QtGui import QUndoCommand, QImage, QPainter, QPainterPath, QPen, QBrush
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
from UM.View.GL.Texture import Texture
from UM.Math.Polygon import Polygon
@ -16,14 +17,16 @@ class PaintStrokeCommand(PaintCommand):
"""Provides the command that does the actual painting on objects with undo/redo mechanisms"""
PEN_OVERLAP_WIDTH = 2.5
PEN_OVERLAP_WIDTH_EXTENDED = PEN_OVERLAP_WIDTH + 0.5
def __init__(self,
texture: Texture,
stroke_polygons: List[Polygon],
set_value: int,
bit_range: tuple[int, int],
mergeable: bool) -> None:
super().__init__(texture, bit_range, make_original_image = not mergeable)
mergeable: bool,
sliceable_object_decorator: Optional[SliceableObjectDecorator] = None) -> None:
super().__init__(texture, bit_range, make_original_image = not mergeable, sliceable_object_decorator=sliceable_object_decorator)
self._stroke_polygons: List[Polygon] = stroke_polygons
self._calculateBoundingRect()
self._set_value: int = set_value
@ -40,6 +43,7 @@ class PaintStrokeCommand(PaintCommand):
painter.drawPath(self._makePainterPath())
painter.end()
self._setPaintedExtrudersCountDirty()
self._texture.updateImagePart(self._bounding_rect)
def mergeWith(self, command: QUndoCommand) -> bool:
@ -55,9 +59,9 @@ class PaintStrokeCommand(PaintCommand):
return True
def _clearTextureBits(self, painter: QPainter):
def _clearTextureBits(self, painter: QPainter, extended = False):
painter.setBrush(QBrush(self._getBitRangeMask()))
painter.setPen(QPen(painter.brush(), self.PEN_OVERLAP_WIDTH))
painter.setPen(QPen(painter.brush(), self.PEN_OVERLAP_WIDTH_EXTENDED if extended else self.PEN_OVERLAP_WIDTH))
painter.setCompositionMode(QPainter.CompositionMode.RasterOp_NotSourceAndDestination)
painter.drawPath(self._makePainterPath())

View file

@ -412,7 +412,7 @@ class PaintTool(Tool):
Logger.logException("e", "Error when adding paint stroke")
self._last_world_coords = world_coords
self._updateScene(painted_object, update_node = self._mouse_held)
self._updateScene(painted_object, update_node = event_caught)
return event_caught
return False

View file

@ -23,6 +23,7 @@ from UM.View.GL.OpenGL import OpenGL
from UM.i18n import i18nCatalog
from UM.Math.Color import Color
from UM.Math.Polygon import Polygon
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
from .PaintStrokeCommand import PaintStrokeCommand
from .PaintClearCommand import PaintClearCommand
@ -242,7 +243,14 @@ class PaintView(CuraView):
stroke_path,
set_value,
self._current_bits_ranges,
merge_with_previous))
merge_with_previous,
self._getSliceableObjectDecorator()))
def _getSliceableObjectDecorator(self) -> Optional[SliceableObjectDecorator]:
if self._painted_object is None or self._current_paint_type != "extruder":
return None
return self._painted_object.getDecorator(SliceableObjectDecorator)
def _makeClearCommand(self) -> Optional[PaintClearCommand]:
if self._painted_object is None or self._paint_texture is None or self._current_bits_ranges is None:
@ -254,7 +262,10 @@ class PaintView(CuraView):
if extruder_stack is not None:
set_value = extruder_stack.getValue("extruder_nr")
return PaintClearCommand(self._paint_texture, self._current_bits_ranges, set_value)
return PaintClearCommand(self._paint_texture,
self._current_bits_ranges,
set_value,
self._getSliceableObjectDecorator())
def clearPaint(self):
self._prepareDataMapping()

View file

@ -1 +1 @@
version: "5.11.0-beta.1"
version: "5.11.0"

View file

@ -1542,6 +1542,19 @@
"enabled": "roofing_pattern != 'concentric' and roofing_layer_count > 0 and top_layers > 0",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
},
"roofing_extension":
{
"label": "Top Surface Extension",
"description": "Determines how much the top surfaces are extended beneath overlapping surfaces. By adjusting this value, you can ensure that the outer edges of the top surfaces are concealed by the layers above, resulting in a better visual quality, particularly for models with curved surfaces.",
"type": "float",
"default_value": "0",
"value": "0",
"minimum_value": "0",
"maximum_value_warning": "roofing_line_width * 10",
"enabled": "roofing_layer_count > 0 and top_layers > 0",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
}
}
},
@ -2053,7 +2066,7 @@
"unit": "mm",
"type": "float",
"default_value": 1,
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"value": "max(-skin_preshrink, wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x)",
"minimum_value": "-skin_preshrink",
"limit_to_extruder": "top_bottom_extruder_nr",
"enabled": "top_layers > 0 or bottom_layers > 0",

View file

@ -200,6 +200,7 @@
"value": "skin_material_flow"
},
"roofing_monotonic": { "value": "True" },
"seam_overhang_angle": { "value": 30 },
"skin_angles": { "value": "[-40, 50]" },
"skin_material_flow":
{
@ -362,7 +363,7 @@
"value": "(wall_material_flow + roofing_material_flow) / 2"
},
"z_seam_position": { "value": "'backleft'" },
"z_seam_type": { "value": "'back'" },
"z_seam_type": { "value": "'sharpest_corner'" },
"zig_zaggify_infill": { "value": "True" }
}
}

View file

@ -236,7 +236,7 @@
"flooring_layer_count": { "value": 1 },
"flooring_material_flow": { "value": "skin_material_flow * 110/93" },
"flooring_monotonic": { "value": false },
"gradual_flow_discretisation_step_size": { "value": 1 },
"gradual_flow_discretisation_step_size": { "value": 0.3 },
"gradual_flow_enabled": { "value": true },
"hole_xy_offset": { "value": 0.075 },
"infill_material_flow": { "value": "material_flow if infill_sparse_density < 95 else 95" },
@ -244,7 +244,7 @@
"infill_pattern": { "value": "'zigzag' if infill_sparse_density > 50 else 'grid'" },
"infill_sparse_density": { "value": 15 },
"infill_wall_line_count": { "value": "1 if infill_sparse_density > 80 else 0" },
"initial_bottom_layers": { "value": 2 },
"initial_bottom_layers": { "value": "2 if extruderValueFromContainer(extruder_nr, 'bottom_layers', 2) == bottom_layers else bottom_layers" },
"jerk_flooring":
{
"maximum_value_warning": "machine_max_jerk_xy / 2",
@ -446,8 +446,7 @@
"retraction_hop_after_extruder_switch_height": { "value": 2 },
"retraction_hop_enabled": { "value": true },
"retraction_min_travel": { "value": "2.5 if support_enable and support_structure=='tree' else line_width * 2.5" },
"retraction_prime_speed": { "value": 15 },
"roofing_monotonic": { "value": false },
"roofing_extension": { "value": 1.2 },
"roofing_pattern": { "value": "'lines'" },
"seam_overhang_angle": { "value": 35 },
"skin_edge_support_thickness": { "value": 0.8 },

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = AA+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -13,10 +13,11 @@ type = intent
variant = CC+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -13,10 +13,11 @@ type = intent
variant = CC+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -13,10 +13,11 @@ type = intent
variant = CC+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -13,10 +13,11 @@ type = intent
variant = CC+ 0.4
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = CC+ 0.6
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -12,10 +12,11 @@ type = intent
variant = CC+ 0.6
[values]
hole_xy_offset = 0.075
hole_xy_offset = 0.1
infill_sparse_density = 20
inset_direction = outside_in
initial_bottom_layers = =bottom_layers
inset_direction = inside_out
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 4
xy_offset = 0.075
xy_offset = 0.025

View file

@ -16,7 +16,6 @@ cool_min_layer_time = 4
cool_min_layer_time_fan_speed_max = 9
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
retraction_prime_speed = 15
speed_roofing = =speed_topbottom * 1/3
speed_wall_x = =speed_wall

View file

@ -14,7 +14,6 @@ weight = -2
[values]
cool_min_layer_time = 4
hole_xy_offset = 0.1
inset_direction = inside_out
material_print_temperature = =default_material_print_temperature + 5
retraction_prime_speed = 15
speed_roofing = =speed_topbottom * 1/3

View file

@ -14,7 +14,6 @@ weight = -1
[values]
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
material_final_print_temperature = =material_print_temperature - 15
material_initial_print_temperature = =material_print_temperature - 15
retraction_prime_speed = =retraction_speed

View file

@ -14,7 +14,6 @@ weight = 0
[values]
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
material_final_print_temperature = =material_print_temperature - 15
material_initial_print_temperature = =material_print_temperature - 15
retraction_prime_speed = =retraction_speed

View file

@ -14,7 +14,6 @@ weight = -2
[values]
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
material_final_print_temperature = =material_print_temperature - 15
material_initial_print_temperature = =material_print_temperature - 15
retraction_prime_speed = =retraction_speed

View file

@ -14,7 +14,6 @@ weight = -1
[values]
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
retraction_prime_speed = =retraction_speed
retraction_speed = 25
speed_roofing = =speed_topbottom * 1/3

View file

@ -14,7 +14,6 @@ weight = 0
[values]
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
retraction_prime_speed = =retraction_speed
speed_roofing = =speed_topbottom * 1/3
speed_wall_x = =speed_wall

View file

@ -14,7 +14,6 @@ weight = -2
[values]
cool_min_temperature = =material_print_temperature - 20
hole_xy_offset = 0.1
inset_direction = inside_out
retraction_prime_speed = =retraction_speed
speed_roofing = =speed_topbottom * 1/3
speed_wall_x = =speed_wall

View file

@ -49,6 +49,7 @@ z_seam_corner
z_seam_relative
[top_bottom]
roofing_extension
roofing_layer_count
flooring_layer_count
top_bottom_extruder_nr

View file

@ -112,6 +112,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = =retraction_speed
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -112,6 +112,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = 15
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -123,6 +123,7 @@ retraction_hop_only_when_collides = True
retraction_min_travel = 5
retraction_prime_speed = 15
retraction_speed = 25
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -111,6 +111,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = =retraction_speed
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -111,6 +111,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = =retraction_speed
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -112,6 +112,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = =retraction_speed
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -112,6 +112,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = 15
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -123,6 +123,7 @@ retraction_hop_only_when_collides = True
retraction_min_travel = 5
retraction_prime_speed = 15
retraction_speed = 25
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -111,6 +111,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = =retraction_speed
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle

View file

@ -111,6 +111,7 @@ retraction_hop_after_extruder_switch_height = =retraction_hop
retraction_hop_enabled = =extruders_enabled_count > 1
retraction_min_travel = 5
retraction_prime_speed = =retraction_speed
roofing_extension = 0
roofing_monotonic = True
roofing_pattern = =top_bottom_pattern
seam_overhang_angle = =support_angle