Merge remote-tracking branch 'origin/CURA-12543_painting_ux' into CURA-12528_unwrap_uvs

This commit is contained in:
Remco Burema 2025-06-19 15:03:33 +02:00
commit fbf3c1395d
13 changed files with 1180 additions and 56 deletions

View file

@ -1,6 +1,8 @@
import copy import copy
from typing import Optional from typing import Optional, Dict
from PyQt6.QtGui import QImage
import UM.View.GL.Texture import UM.View.GL.Texture
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
@ -16,6 +18,7 @@ class SliceableObjectDecorator(SceneNodeDecorator):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self._paint_texture = None self._paint_texture = None
self._texture_data_mapping: Dict[str, tuple[int, int]] = {}
def isSliceable(self) -> bool: def isSliceable(self) -> bool:
return True return True
@ -23,12 +26,22 @@ class SliceableObjectDecorator(SceneNodeDecorator):
def getPaintTexture(self, create_if_required: bool = True) -> Optional[UM.View.GL.Texture.Texture]: def getPaintTexture(self, create_if_required: bool = True) -> Optional[UM.View.GL.Texture.Texture]:
if self._paint_texture is None and create_if_required: if self._paint_texture is None and create_if_required:
self._paint_texture = OpenGL.getInstance().createTexture(TEXTURE_WIDTH, TEXTURE_HEIGHT) self._paint_texture = OpenGL.getInstance().createTexture(TEXTURE_WIDTH, TEXTURE_HEIGHT)
image = QImage(TEXTURE_WIDTH, TEXTURE_HEIGHT, QImage.Format.Format_RGB32)
image.fill(0)
self._paint_texture.setImage(image)
return self._paint_texture return self._paint_texture
def setPaintTexture(self, texture: UM.View.GL.Texture) -> None: def setPaintTexture(self, texture: UM.View.GL.Texture) -> None:
self._paint_texture = texture self._paint_texture = texture
def getTextureDataMapping(self) -> Dict[str, tuple[int, int]]:
return self._texture_data_mapping
def setTextureDataMapping(self, mapping: Dict[str, tuple[int, int]]) -> None:
self._texture_data_mapping = mapping
def __deepcopy__(self, memo) -> "SliceableObjectDecorator": def __deepcopy__(self, memo) -> "SliceableObjectDecorator":
copied_decorator = SliceableObjectDecorator() copied_decorator = SliceableObjectDecorator()
copied_decorator.setPaintTexture(copy.deepcopy(self.getPaintTexture())) copied_decorator.setPaintTexture(copy.deepcopy(self.getPaintTexture()))
copied_decorator.setTextureDataMapping(copy.deepcopy(self.getTextureDataMapping()))
return copied_decorator return copied_decorator

View file

@ -39,14 +39,6 @@ class PaintTool(Tool):
self._mesh_transformed_cache = None self._mesh_transformed_cache = None
self._cache_dirty: bool = True self._cache_dirty: bool = True
# TODO: Colors will need to be replaced on a 'per type of painting' basis.
self._color_str_to_rgba: Dict[str, List[int]] = {
"A": [192, 0, 192, 255],
"B": [232, 128, 0, 255],
"C": [0, 255, 0, 255],
"D": [255, 255, 255, 255],
}
self._brush_size: int = 10 self._brush_size: int = 10
self._brush_color: str = "A" self._brush_color: str = "A"
self._brush_shape: PaintTool.BrushShape = PaintTool.BrushShape.SQUARE self._brush_shape: PaintTool.BrushShape = PaintTool.BrushShape.SQUARE
@ -61,8 +53,8 @@ class PaintTool(Tool):
def _createBrushPen(self) -> QPen: def _createBrushPen(self) -> QPen:
pen = QPen() pen = QPen()
pen.setWidth(self._brush_size) pen.setWidth(self._brush_size)
color = self._color_str_to_rgba[self._brush_color] pen.setColor(Qt.GlobalColor.white)
pen.setColor(QColor(color[0], color[1], color[2], color[3]))
match self._brush_shape: match self._brush_shape:
case PaintTool.BrushShape.SQUARE: case PaintTool.BrushShape.SQUARE:
pen.setCapStyle(Qt.PenCapStyle.SquareCap) pen.setCapStyle(Qt.PenCapStyle.SquareCap)
@ -78,8 +70,8 @@ class PaintTool(Tool):
start_x = int(min(x0, x1) - half_brush_size) start_x = int(min(x0, x1) - half_brush_size)
start_y = int(min(y0, y1) - half_brush_size) start_y = int(min(y0, y1) - half_brush_size)
stroke_image = QImage(abs(xdiff) + self._brush_size, abs(ydiff) + self._brush_size, QImage.Format.Format_RGBA8888) stroke_image = QImage(abs(xdiff) + self._brush_size, abs(ydiff) + self._brush_size, QImage.Format.Format_RGB32)
stroke_image.fill(QColor(0,0,0,0)) stroke_image.fill(0)
painter = QPainter(stroke_image) painter = QPainter(stroke_image)
painter.setRenderHint(QPainter.RenderHint.Antialiasing, False) painter.setRenderHint(QPainter.RenderHint.Antialiasing, False)
@ -93,8 +85,14 @@ class PaintTool(Tool):
return stroke_image, (start_x, start_y) return stroke_image, (start_x, start_y)
def setPaintType(self, paint_type: str) -> None: def setPaintType(self, paint_type: str) -> None:
Logger.warning(f"TODO: Implement paint-types ({paint_type}).") paint_view = self._get_paint_view()
pass # FIXME: ... and also please call `self._brush_pen = self._createBrushPen()` (see other funcs). if paint_view is None:
return
paint_view.setPaintType(paint_type)
self._brush_pen = self._createBrushPen()
self._updateScene()
def setBrushSize(self, brush_size: float) -> None: def setBrushSize(self, brush_size: float) -> None:
if brush_size != self._brush_size: if brush_size != self._brush_size:
@ -102,9 +100,7 @@ class PaintTool(Tool):
self._brush_pen = self._createBrushPen() self._brush_pen = self._createBrushPen()
def setBrushColor(self, brush_color: str) -> None: def setBrushColor(self, brush_color: str) -> None:
if brush_color != self._brush_color:
self._brush_color = brush_color self._brush_color = brush_color
self._brush_pen = self._createBrushPen()
def setBrushShape(self, brush_shape: int) -> None: def setBrushShape(self, brush_shape: int) -> None:
if brush_shape != self._brush_shape: if brush_shape != self._brush_shape:
@ -112,19 +108,25 @@ class PaintTool(Tool):
self._brush_pen = self._createBrushPen() self._brush_pen = self._createBrushPen()
def undoStackAction(self, redo_instead: bool) -> bool: def undoStackAction(self, redo_instead: bool) -> bool:
paintview = Application.getInstance().getController().getActiveView() paint_view = self._get_paint_view()
if paintview is None or paintview.getPluginId() != "PaintTool": if paint_view is None:
return False return False
paintview = cast(PaintView, paintview)
if redo_instead: if redo_instead:
paintview.redoStroke() paint_view.redoStroke()
else: else:
paintview.undoStroke() paint_view.undoStroke()
node = Selection.getSelectedObject(0)
if node is not None: self._updateScene()
Application.getInstance().getController().getScene().sceneChanged.emit(node)
return True return True
@staticmethod
def _get_paint_view() -> Optional[PaintView]:
paint_view = Application.getInstance().getController().getActiveView()
if paint_view is None or paint_view.getPluginId() != "PaintTool":
return None
return cast(PaintView, paint_view)
@staticmethod @staticmethod
def _get_intersect_ratio_via_pt(a: numpy.ndarray, pt: numpy.ndarray, b: numpy.ndarray, c: numpy.ndarray) -> float: def _get_intersect_ratio_via_pt(a: numpy.ndarray, pt: numpy.ndarray, b: numpy.ndarray, c: numpy.ndarray) -> float:
# compute the intersection of (param) A - pt with (param) B - (param) C # compute the intersection of (param) A - pt with (param) B - (param) C
@ -314,12 +316,19 @@ class PaintTool(Tool):
end_coords[0] * w, end_coords[0] * w,
end_coords[1] * h end_coords[1] * h
) )
paintview.addStroke(sub_image, start_x, start_y) paintview.addStroke(sub_image, start_x, start_y, self._brush_color)
self._last_text_coords = texcoords self._last_text_coords = texcoords
self._last_mouse_coords = (mouse_evt.x, mouse_evt.y) self._last_mouse_coords = (mouse_evt.x, mouse_evt.y)
self._last_face_id = face_id self._last_face_id = face_id
Application.getInstance().getController().getScene().sceneChanged.emit(node) self._updateScene(node)
return True return True
return False return False
@staticmethod
def _updateScene(node: SceneNode = None):
if node is None:
node = Selection.getSelectedObject(0)
if node is not None:
Application.getInstance().getController().getScene().sceneChanged.emit(node)

View file

@ -2,10 +2,12 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import os import os
from typing import Optional, List, Tuple from PyQt6.QtCore import QRect
from typing import Optional, List, Tuple, Dict
from PyQt6.QtGui import QImage, QColor, QPainter from PyQt6.QtGui import QImage, QColor, QPainter
from cura.CuraApplication import CuraApplication
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from UM.View.GL.ShaderProgram import ShaderProgram from UM.View.GL.ShaderProgram import ShaderProgram
from UM.View.GL.Texture import Texture from UM.View.GL.Texture import Texture
@ -13,6 +15,7 @@ from UM.View.View import View
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
from UM.View.GL.OpenGL import OpenGL from UM.View.GL.OpenGL import OpenGL
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Math.Color import Color
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -22,10 +25,24 @@ class PaintView(View):
UNDO_STACK_SIZE = 1024 UNDO_STACK_SIZE = 1024
class PaintType:
def __init__(self, icon: str, display_color: Color, value: int):
self.icon: str = icon
self.display_color: Color = display_color
self.value: int = value
class PaintMode:
def __init__(self, icon: str, types: Dict[str, "PaintView.PaintType"]):
self.icon: str = icon
self.types = types
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self._paint_shader: Optional[ShaderProgram] = None self._paint_shader: Optional[ShaderProgram] = None
self._current_paint_texture: Optional[Texture] = None self._current_paint_texture: Optional[Texture] = None
self._current_bits_ranges: tuple[int, int] = (0, 0)
self._current_paint_type = ""
self._paint_modes: Dict[str, PaintView.PaintMode] = {}
self._stroke_undo_stack: List[Tuple[QImage, int, int]] = [] self._stroke_undo_stack: List[Tuple[QImage, int, int]] = []
self._stroke_redo_stack: List[Tuple[QImage, int, int]] = [] self._stroke_redo_stack: List[Tuple[QImage, int, int]] = []
@ -33,6 +50,18 @@ class PaintView(View):
self._force_opaque_mask = QImage(2, 2, QImage.Format.Format_Mono) self._force_opaque_mask = QImage(2, 2, QImage.Format.Format_Mono)
self._force_opaque_mask.fill(1) self._force_opaque_mask.fill(1)
CuraApplication.getInstance().engineCreatedSignal.connect(self._makePaintModes)
def _makePaintModes(self):
theme = CuraApplication.getInstance().getTheme()
usual_types = {"A": self.PaintType("Buildplate", Color(*theme.getColor("paint_normal_area").getRgb()), 0),
"B": self.PaintType("BlackMagic", Color(*theme.getColor("paint_preferred_area").getRgb()), 1),
"C": self.PaintType("Eye", Color(*theme.getColor("paint_avoid_area").getRgb()), 2)}
self._paint_modes = {
"A": self.PaintMode("MeshTypeNormal", usual_types),
"B": self.PaintMode("CircleOutline", usual_types),
}
def _checkSetup(self): def _checkSetup(self):
if not self._paint_shader: if not self._paint_shader:
shader_filename = os.path.join(PluginRegistry.getInstance().getPluginPath("PaintTool"), "paint.shader") shader_filename = os.path.join(PluginRegistry.getInstance().getPluginPath("PaintTool"), "paint.shader")
@ -49,14 +78,43 @@ class PaintView(View):
res.setAlphaChannel(self._force_opaque_mask.scaled(image.width(), image.height())) res.setAlphaChannel(self._force_opaque_mask.scaled(image.width(), image.height()))
return res return res
def addStroke(self, stroke_image: QImage, start_x: int, start_y: int) -> None: def addStroke(self, stroke_image: QImage, start_x: int, start_y: int, brush_color: str) -> None:
if self._current_paint_texture is None: if self._current_paint_texture is None or self._current_paint_texture.getImage() is None:
return return
actual_image = self._current_paint_texture.getImage()
bit_range_start, bit_range_end = self._current_bits_ranges
set_value = self._paint_modes[self._current_paint_type].types[brush_color].value << self._current_bits_ranges[0]
full_int32 = 0xffffffff
clear_mask = full_int32 ^ (((full_int32 << (32 - 1 - (bit_range_end - bit_range_start))) & full_int32) >> (32 - 1 - bit_range_end))
image_rect = QRect(0, 0, stroke_image.width(), stroke_image.height())
clear_bits_image = stroke_image.copy()
clear_bits_image.invertPixels()
painter = QPainter(clear_bits_image)
painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_Lighten)
painter.fillRect(image_rect, clear_mask)
painter.end()
set_value_image = stroke_image.copy()
painter = QPainter(set_value_image)
painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_Multiply)
painter.fillRect(image_rect, set_value)
painter.end()
stroked_image = actual_image.copy(start_x, start_y, stroke_image.width(), stroke_image.height())
painter = QPainter(stroked_image)
painter.setCompositionMode(QPainter.CompositionMode.RasterOp_SourceAndDestination)
painter.drawImage(0, 0, clear_bits_image)
painter.setCompositionMode(QPainter.CompositionMode.RasterOp_SourceOrDestination)
painter.drawImage(0, 0, set_value_image)
painter.end()
self._stroke_redo_stack.clear() self._stroke_redo_stack.clear()
if len(self._stroke_undo_stack) >= PaintView.UNDO_STACK_SIZE: if len(self._stroke_undo_stack) >= PaintView.UNDO_STACK_SIZE:
self._stroke_undo_stack.pop(0) self._stroke_undo_stack.pop(0)
undo_image = self._forceOpaqueDeepCopy(self._current_paint_texture.setSubImage(stroke_image, start_x, start_y)) undo_image = self._forceOpaqueDeepCopy(self._current_paint_texture.setSubImage(stroked_image, start_x, start_y))
if undo_image is not None: if undo_image is not None:
self._stroke_undo_stack.append((undo_image, start_x, start_y)) self._stroke_undo_stack.append((undo_image, start_x, start_y))
@ -83,6 +141,31 @@ class PaintView(View):
return self._current_paint_texture.getWidth(), self._current_paint_texture.getHeight() return self._current_paint_texture.getWidth(), self._current_paint_texture.getHeight()
return 0, 0 return 0, 0
def setPaintType(self, paint_type: str) -> None:
node = Selection.getAllSelectedObjects()[0]
if node is None:
return
paint_data_mapping = node.callDecoration("getTextureDataMapping")
if paint_type not in paint_data_mapping:
new_mapping = self._add_mapping(paint_data_mapping, len(self._paint_modes[paint_type].types))
paint_data_mapping[paint_type] = new_mapping
node.callDecoration("setTextureDataMapping", paint_data_mapping)
self._current_paint_type = paint_type
self._current_bits_ranges = paint_data_mapping[paint_type]
@staticmethod
def _add_mapping(actual_mapping: Dict[str, tuple[int, int]], nb_storable_values: int) -> tuple[int, int]:
start_index = 0
if actual_mapping:
start_index = max(end_index for _, end_index in actual_mapping.values()) + 1
end_index = start_index + int.bit_length(nb_storable_values - 1) - 1
return start_index, end_index
def beginRendering(self) -> None: def beginRendering(self) -> None:
renderer = self.getRenderer() renderer = self.getRenderer()
self._checkSetup() self._checkSetup()
@ -93,6 +176,17 @@ class PaintView(View):
if node is None: if node is None:
return return
if self._current_paint_type == "":
self.setPaintType("A")
self._paint_shader.setUniformValue("u_bitsRangesStart", self._current_bits_ranges[0])
self._paint_shader.setUniformValue("u_bitsRangesEnd", self._current_bits_ranges[1])
colors = [paint_type_obj.display_color for paint_type_obj in self._paint_modes[self._current_paint_type].types.values()]
colors_values = [[int(color_part * 255) for color_part in [color.r, color.g, color.b]] for color in colors]
self._paint_shader.setUniformValueArray("u_renderColors", colors_values)
self._current_paint_texture = node.callDecoration("getPaintTexture") self._current_paint_texture = node.callDecoration("getPaintTexture")
self._paint_shader.setTexture(0, self._current_paint_texture) self._paint_shader.setTexture(0, self._current_paint_texture)
paint_batch.addItem(node.getWorldTransformation(copy=False), node.getMeshData(), normal_transformation=node.getCachedNormalMatrix()) paint_batch.addItem(node.getWorldTransformation(copy=False), node.getMeshData(), normal_transformation=node.getCachedNormalMatrix())

View file

@ -27,11 +27,13 @@ vertex =
fragment = fragment =
uniform mediump vec4 u_ambientColor; uniform mediump vec4 u_ambientColor;
uniform mediump vec4 u_diffuseColor;
uniform highp vec3 u_lightPosition; uniform highp vec3 u_lightPosition;
uniform highp vec3 u_viewPosition; uniform highp vec3 u_viewPosition;
uniform mediump float u_opacity; uniform mediump float u_opacity;
uniform sampler2D u_texture; uniform sampler2D u_texture;
uniform mediump int u_bitsRangesStart;
uniform mediump int u_bitsRangesEnd;
uniform mediump vec3 u_renderColors[16];
varying highp vec3 v_vertex; varying highp vec3 v_vertex;
varying highp vec3 v_normal; varying highp vec3 v_normal;
@ -48,15 +50,17 @@ fragment =
highp vec3 light_dir = normalize(u_lightPosition - v_vertex); highp vec3 light_dir = normalize(u_lightPosition - v_vertex);
/* Diffuse Component */ /* Diffuse Component */
ivec4 texture = ivec4(texture(u_texture, v_uvs) * 255.0);
uint color_index = (texture.r << 16) | (texture.g << 8) | texture.b;
color_index = (color_index << (32 - 1 - u_bitsRangesEnd)) >> 32 - 1 - (u_bitsRangesEnd - u_bitsRangesStart);
vec4 diffuse_color = vec4(u_renderColors[color_index] / 255.0, 1.0);
highp float n_dot_l = clamp(dot(normal, light_dir), 0.0, 1.0); highp float n_dot_l = clamp(dot(normal, light_dir), 0.0, 1.0);
final_color += (n_dot_l * u_diffuseColor); final_color += (n_dot_l * diffuse_color);
final_color.a = u_opacity; final_color.a = u_opacity;
lowp vec4 texture = texture2D(u_texture, v_uvs); frag_color = final_color;
final_color = mix(final_color, texture, texture.a);
gl_FragColor = final_color;
} }
vertex41core = vertex41core =
@ -89,11 +93,13 @@ vertex41core =
fragment41core = fragment41core =
#version 410 #version 410
uniform mediump vec4 u_ambientColor; uniform mediump vec4 u_ambientColor;
uniform mediump vec4 u_diffuseColor;
uniform highp vec3 u_lightPosition; uniform highp vec3 u_lightPosition;
uniform highp vec3 u_viewPosition; uniform highp vec3 u_viewPosition;
uniform mediump float u_opacity; uniform mediump float u_opacity;
uniform sampler2D u_texture; uniform sampler2D u_texture;
uniform mediump int u_bitsRangesStart;
uniform mediump int u_bitsRangesEnd;
uniform mediump vec3 u_renderColors[16];
in highp vec3 v_vertex; in highp vec3 v_vertex;
in highp vec3 v_normal; in highp vec3 v_normal;
@ -111,20 +117,21 @@ fragment41core =
highp vec3 light_dir = normalize(u_lightPosition - v_vertex); highp vec3 light_dir = normalize(u_lightPosition - v_vertex);
/* Diffuse Component */ /* Diffuse Component */
ivec4 texture = ivec4(texture(u_texture, v_uvs) * 255.0);
uint color_index = (texture.r << 16) | (texture.g << 8) | texture.b;
color_index = (color_index << (32 - 1 - u_bitsRangesEnd)) >> 32 - 1 - (u_bitsRangesEnd - u_bitsRangesStart);
vec4 diffuse_color = vec4(u_renderColors[color_index] / 255.0, 1.0);
highp float n_dot_l = clamp(dot(normal, light_dir), 0.0, 1.0); highp float n_dot_l = clamp(dot(normal, light_dir), 0.0, 1.0);
final_color += (n_dot_l * u_diffuseColor); final_color += (n_dot_l * diffuse_color);
final_color.a = u_opacity; final_color.a = u_opacity;
lowp vec4 texture = texture(u_texture, v_uvs);
final_color = mix(final_color, texture, texture.a);
frag_color = final_color; frag_color = final_color;
} }
[defaults] [defaults]
u_ambientColor = [0.3, 0.3, 0.3, 1.0] u_ambientColor = [0.3, 0.3, 0.3, 1.0]
u_diffuseColor = [1.0, 1.0, 1.0, 1.0]
u_opacity = 0.5 u_opacity = 0.5
u_texture = 0 u_texture = 0

View file

@ -103,8 +103,8 @@ geometry41core =
vec4 g_vertex_offset_vert; vec4 g_vertex_offset_vert;
vec3 g_vertex_normal_horz_head; vec3 g_vertex_normal_horz_head;
vec4 g_vertex_offset_horz_head; vec4 g_vertex_offset_horz_head;
vec3 g_axial_plan_vector; vec3 g_axial_plane_vector;
vec3 g_radial_plan_vector; vec3 g_radial_plane_vector;
float size_x; float size_x;
float size_y; float size_y;
@ -143,25 +143,25 @@ geometry41core =
if (g_vertex_delta.y == 0.0) if (g_vertex_delta.y == 0.0)
{ {
// vector is in the horizontal plan, radial vector is a simple rotation around Y axis // vector is in the horizontal plane, radial vector is a simple rotation around Y axis
g_radial_plan_vector = vec3(g_vertex_delta.z, 0.0, -g_vertex_delta.x); g_radial_plane_vector = vec3(g_vertex_delta.z, 0.0, -g_vertex_delta.x);
} }
else if(g_vertex_delta.x == 0.0 && g_vertex_delta.z == 0.0) else if(g_vertex_delta.x == 0.0 && g_vertex_delta.z == 0.0)
{ {
// delta vector is purely vertical, display the line rotated vertically so that it is visible in front and side views // delta vector is purely vertical, display the line rotated vertically so that it is visible in front and side views
g_radial_plan_vector = vec3(1.0, 0.0, -1.0); g_radial_plane_vector = vec3(1.0, 0.0, -1.0);
} }
else else
{ {
// delta vector is completely 3D // delta vector is completely 3D
g_axial_plan_vector = vec3(g_vertex_delta.x, 0.0, g_vertex_delta.z); // Vector projected in the horizontal plan g_axial_plane_vector = vec3(g_vertex_delta.x, 0.0, g_vertex_delta.z); // Vector projected in the horizontal plane
g_radial_plan_vector = cross(g_vertex_delta, g_axial_plan_vector); // Radial vector in the horizontal plan, pointing right. g_radial_plane_vector = cross(g_vertex_delta, g_axial_plane_vector); // Radial vector in the horizontal plane, pointing right.
} }
g_vertex_normal_horz_head = normalize(g_vertex_delta); //Lengthwise normal vector g_vertex_normal_horz_head = normalize(g_vertex_delta); //Lengthwise normal vector
g_vertex_offset_horz_head = vec4(g_vertex_normal_horz_head * size_x, 0.0); //Lengthwise offset vector g_vertex_offset_horz_head = vec4(g_vertex_normal_horz_head * size_x, 0.0); //Lengthwise offset vector
g_vertex_normal_horz = normalize(g_radial_plan_vector); //Normal vector pointing right. g_vertex_normal_horz = normalize(g_radial_plane_vector); //Normal vector pointing right.
g_vertex_offset_horz = vec4(g_vertex_normal_horz * size_x, 0.0); //Offset vector pointing right. g_vertex_offset_horz = vec4(g_vertex_normal_horz * size_x, 0.0); //Offset vector pointing right.
g_vertex_normal_vert = vec3(0.0, 1.0, 0.0); //Upwards normal vector. g_vertex_normal_vert = vec3(0.0, 1.0, 0.0); //Upwards normal vector.

View file

@ -0,0 +1,15 @@
[general]
definition = ultimaker_s8
name = Extra Fine
version = 4
[metadata]
global_quality = True
quality_type = high
setting_version = 25
type = quality
weight = 1
[values]
layer_height = =round(0.06 * material_shrinkage_percentage_z / 100, 5)

View file

@ -0,0 +1,15 @@
[general]
definition = ultimaker_s8
name = Sprint
version = 4
[metadata]
global_quality = True
quality_type = superdraft
setting_version = 25
type = quality
weight = -4
[values]
layer_height = =round(0.4 * material_shrinkage_percentage_z / 100, 5)

View file

@ -1 +1,26 @@
{"metadata": {"name": "Colorblind Assist Dark", "inherits": "cura-dark"}, "colors": {"x_axis": [212, 0, 0, 255], "y_axis": [64, 64, 255, 255], "model_overhang": [200, 0, 255, 255], "xray": [26, 26, 62, 255], "xray_error": [255, 0, 0, 255], "layerview_inset_0": [255, 64, 0, 255], "layerview_inset_x": [0, 156, 128, 255], "layerview_skin": [255, 255, 86, 255], "layerview_support": [255, 255, 0, 255], "layerview_infill": [0, 255, 255, 255], "layerview_support_infill": [0, 200, 200, 255], "layerview_move_retraction": [0, 100, 255, 255], "main_window_header_background": [192, 199, 65, 255]}} {
"metadata": {
"name": "Colorblind Assist Dark",
"inherits": "cura-dark"
},
"colors": {
"x_axis": [212, 0, 0, 255],
"y_axis": [64, 64, 255, 255],
"model_overhang": [200, 0, 255, 255],
"xray": [26, 26, 62, 255],
"xray_error": [255, 0, 0, 255],
"layerview_inset_0": [255, 64, 0, 255],
"layerview_inset_x": [0, 156, 128, 255],
"layerview_skin": [255, 255, 86, 255],
"layerview_support": [255, 255, 0, 255],
"layerview_infill": [0, 255, 255, 255],
"layerview_support_infill": [0, 200, 200, 255],
"layerview_move_retraction": [0, 100, 255, 255]
}
}

File diff suppressed because one or more lines are too long

View file

@ -1 +1,29 @@
{"metadata": {"name": "Colorblind Assist Light", "inherits": "cura-light"}, "colors": {"x_axis": [200, 0, 0, 255], "y_axis": [64, 64, 255, 255], "model_overhang": [200, 0, 255, 255], "model_selection_outline": [12, 169, 227, 255], "xray_error_dark": [255, 0, 0, 255], "xray_error_light": [255, 255, 0, 255], "xray": [26, 26, 62, 255], "xray_error": [255, 0, 0, 255], "layerview_inset_0": [255, 64, 0, 255], "layerview_inset_x": [0, 156, 128, 255], "layerview_skin": [255, 255, 86, 255], "layerview_support": [255, 255, 0, 255], "layerview_infill": [0, 255, 255, 255], "layerview_support_infill": [0, 200, 200, 255], "layerview_move_retraction": [0, 100, 255, 255], "main_window_header_background": [192, 199, 65, 255]}} {
"metadata": {
"name": "Colorblind Assist Light",
"inherits": "cura-light"
},
"colors": {
"x_axis": [200, 0, 0, 255],
"y_axis": [64, 64, 255, 255],
"model_overhang": [200, 0, 255, 255],
"model_selection_outline": [12, 169, 227, 255],
"xray_error_dark": [255, 0, 0, 255],
"xray_error_light": [255, 255, 0, 255],
"xray": [26, 26, 62, 255],
"xray_error": [255, 0, 0, 255],
"layerview_inset_0": [255, 64, 0, 255],
"layerview_inset_x": [0, 156, 128, 255],
"layerview_skin": [255, 255, 86, 255],
"layerview_support": [255, 255, 0, 255],
"layerview_infill": [0, 255, 255, 255],
"layerview_support_infill": [0, 200, 200, 255],
"layerview_move_retraction": [0, 100, 255, 255]
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
[
[ 62, 33, 55, 255],
[126, 196, 193, 255],
[126, 196, 193, 255],
[215, 155, 125, 255],
[228, 148, 58, 255],
[192, 199, 65, 255],
[157, 48, 59, 255],
[140, 143, 174, 255],
[ 23, 67, 75, 255],
[ 23, 67, 75, 255],
[154, 99, 72, 255],
[112, 55, 127, 255],
[100, 125, 52, 255],
[210, 100, 113, 255]
]

View file

@ -11,6 +11,7 @@ type = variant
[values] [values]
machine_nozzle_heat_up_speed = 1.5 machine_nozzle_heat_up_speed = 1.5
machine_nozzle_id = BB 0.4 machine_nozzle_id = BB 0.4
machine_nozzle_size = 0.4
machine_nozzle_tip_outer_diameter = 1.0 machine_nozzle_tip_outer_diameter = 1.0
retraction_amount = 4.5 retraction_amount = 4.5
support_bottom_height = =layer_height * 2 support_bottom_height = =layer_height * 2