Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2020-07-09 18:16:24 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-07-09 19:24:50 +0300
commit03a00bda2b3f6729997ddfa31dfe84cc56e7707e (patch)
tree5b6c4d7837bf10ba6ac78613b9391077c6009043
parent1e3247c0787df31c34e0fdc03c6fa11b35e55d03 (diff)
Sculpt: Make Sculpt Vertex Colors features experimental
This disables all Sculpt Vertex Colors tools, operators, panels and rendering capabilities and puts them under the "Use Sculpt Vertex Colors" experimental option. Reviewed By: brecht Differential Revision: https://developer.blender.org/D8239
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py7
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py23
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py1
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py3
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c18
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c44
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c25
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c6
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.c4
15 files changed, 109 insertions, 41 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index fbd8e2d7cff..27df265d013 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -464,6 +464,10 @@ class DATA_PT_sculpt_vertex_colors(MeshButtonsPanel, Panel):
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+ @classmethod
+ def poll(cls, context):
+ return context.preferences.experimental.use_sculpt_vertex_colors
+
def draw(self, context):
layout = self.layout
@@ -508,7 +512,8 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel):
col.prop(mesh, "use_remesh_preserve_volume", text="Volume")
col.prop(mesh, "use_remesh_preserve_paint_mask", text="Paint Mask")
col.prop(mesh, "use_remesh_preserve_sculpt_face_sets", text="Face Sets")
- col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
+ if context.preferences.experimental.use_sculpt_vertex_colors:
+ col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
col.operator("object.voxel_remesh", text="Voxel Remesh")
else:
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 75e7cc1b9c6..b7852eb92e0 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -50,11 +50,14 @@ def generate_from_enum_ex(
attr,
cursor='DEFAULT',
tooldef_keywords={},
+ exclude_filter = {}
):
tool_defs = []
for enum in type.bl_rna.properties[attr].enum_items_static:
name = enum.name
idname = enum.identifier
+ if idname in exclude_filter:
+ continue
tool_defs.append(
ToolDef.from_dict(
dict(
@@ -1178,12 +1181,18 @@ class _defs_sculpt:
@staticmethod
def generate_from_brushes(context):
+ if bpy.context.preferences.experimental.use_sculpt_vertex_colors:
+ exclude_filter = {}
+ else:
+ exclude_filter = {'PAINT', 'SMEAR'}
+
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.sculpt.",
type=bpy.types.Brush,
attr="sculpt_tool",
+ exclude_filter = exclude_filter,
)
@ToolDef.from_fn
@@ -2485,9 +2494,19 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
None,
_defs_sculpt.mesh_filter,
_defs_sculpt.cloth_filter,
- _defs_sculpt.color_filter,
+ lambda context: (
+ (_defs_sculpt.color_filter,)
+ if bpy.context.preferences.view.show_developer_ui and \
+ bpy.context.preferences.experimental.use_sculpt_vertex_colors
+ else ()
+ ),
None,
- _defs_sculpt.mask_by_color,
+ lambda context: (
+ (_defs_sculpt.mask_by_color,)
+ if bpy.context.preferences.view.show_developer_ui and \
+ bpy.context.preferences.experimental.use_sculpt_vertex_colors
+ else ()
+ ),
None,
_defs_transform.translate,
_defs_transform.rotate,
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index e5171df597a..5392ed9cc25 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -2143,6 +2143,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
self._draw_items(
context, (
({"property": "use_new_particle_system"}, "T73324"),
+ ({"property": "use_sculpt_vertex_colors"}, "T71947"),
),
)
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index f1358d4dd01..3286209bd63 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -812,7 +812,8 @@ class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel):
col.prop(mesh, "use_remesh_preserve_volume", text="Volume")
col.prop(mesh, "use_remesh_preserve_paint_mask", text="Paint Mask")
col.prop(mesh, "use_remesh_preserve_sculpt_face_sets", text="Face Sets")
- col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
+ if preferences.experimental.use_preserver_vertex_colors:
+ col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
layout.operator("object.voxel_remesh", text="Remesh")
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b3ab856468c..dca2022382a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1514,7 +1514,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* Add a color layer if a color tool is used. */
Mesh *orig_me = BKE_object_get_original_mesh(ob);
- if (need_colors) {
+ if (need_colors && U.experimental.use_sculpt_vertex_colors) {
if (!CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
BKE_mesh_update_customdata_pointers(orig_me, true);
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index c8dde4d513b..5b06cb03c59 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -180,7 +180,12 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
geom = DRW_cache_mesh_surface_vertpaint_get(ob);
}
else {
- geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
+ if (U.experimental.use_sculpt_vertex_colors) {
+ geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
+ }
+ else {
+ geom = DRW_cache_mesh_surface_vertpaint_get(ob);
+ }
}
}
else {
@@ -261,8 +266,15 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
}
}
else if (color_type == V3D_SHADING_VERTEX_COLOR) {
- if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
- color_type = V3D_SHADING_OBJECT_COLOR;
+ if (U.experimental.use_sculpt_vertex_colors) {
+ if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
+ }
+ else {
+ if ((me == NULL) || !CustomData_has_layer(&me->ldata, CD_MLOOPCOL)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
}
}
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 98da668f78f..5b7dbf4e6e1 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -2534,26 +2534,28 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
}
/* Sculpt Vertex Colors */
- for (int i = 0; i < 8; i++) {
- if (svcol_layers & (1 << i)) {
- char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *layer_name = CustomData_get_layer_name(cd_vdata, CD_PROP_COLOR, i);
- GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
-
- BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
- GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- if (i == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) {
- GPU_vertformat_alias_add(&format, "c");
- }
- if (i == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) {
- GPU_vertformat_alias_add(&format, "ac");
- }
- /* Gather number of auto layers. */
- /* We only do `vcols` that are not overridden by `uvs`. */
- if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) {
- BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
- GPU_vertformat_alias_add(&format, attr_name);
+ if (U.experimental.use_sculpt_vertex_colors) {
+ for (int i = 0; i < 8; i++) {
+ if (svcol_layers & (1 << i)) {
+ char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
+ const char *layer_name = CustomData_get_layer_name(cd_vdata, CD_PROP_COLOR, i);
+ GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
+
+ BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
+ GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ if (i == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) {
+ GPU_vertformat_alias_add(&format, "c");
+ }
+ if (i == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) {
+ GPU_vertformat_alias_add(&format, "ac");
+ }
+ /* Gather number of auto layers. */
+ /* We only do `vcols` that are not overridden by `uvs`. */
+ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) {
+ BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
+ GPU_vertformat_alias_add(&format, attr_name);
+ }
}
}
}
@@ -2599,7 +2601,7 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
}
}
- if (svcol_layers & (1 << i)) {
+ if (svcol_layers & (1 << i) && U.experimental.use_sculpt_vertex_colors) {
if (mr->extract_type == MR_EXTRACT_BMESH) {
int cd_ofs = CustomData_get_n_offset(cd_vdata, CD_PROP_COLOR, i);
BMIter f_iter;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index ea1717f0684..a22e0014bf5 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -205,8 +205,10 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
}
if (layer == -1) {
- layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
- type = CD_PROP_COLOR;
+ if (U.experimental.use_sculpt_vertex_colors) {
+ layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
+ type = CD_PROP_COLOR;
+ }
}
#if 0 /* Tangents are always from UV's - this will never happen. */
if (layer == -1) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 14a66fb428e..71766a32814 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5461,11 +5461,15 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
/* Check for unsupported features. */
PBVHType type = BKE_pbvh_type(ss->pbvh);
if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) {
- return;
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return;
+ }
}
if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) {
- return;
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return;
+ }
}
/* Build a list of all nodes that are potentially within the brush's area of influence */
@@ -6120,6 +6124,14 @@ bool SCULPT_mode_poll(bContext *C)
return ob && ob->mode & OB_MODE_SCULPT;
}
+bool SCULPT_vertex_colors_poll(bContext *C)
+{
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return false;
+ }
+ return SCULPT_mode_poll(C);
+}
+
bool SCULPT_mode_poll_view3d(bContext *C)
{
return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C));
@@ -8170,7 +8182,7 @@ static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
ot->idname = "SCULPT_OT_vertex_to_loop_colors";
/* api callbacks */
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->exec = vertex_to_loop_colors_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8233,7 +8245,7 @@ static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
ot->idname = "SCULPT_OT_loop_to_vertex_colors";
/* api callbacks */
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->exec = loop_to_vertex_colors_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8273,7 +8285,7 @@ static void SCULPT_OT_sample_color(wmOperatorType *ot)
/* api callbacks */
ot->invoke = sculpt_sample_color_invoke;
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->flag = OPTYPE_REGISTER;
}
@@ -8804,7 +8816,7 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
/* api callbacks */
ot->invoke = sculpt_mask_by_color_invoke;
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->flag = OPTYPE_REGISTER;
@@ -8852,6 +8864,7 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_face_sets_init);
WM_operatortype_append(SCULPT_OT_cloth_filter);
WM_operatortype_append(SCULPT_OT_face_sets_edit);
+
WM_operatortype_append(SCULPT_OT_sample_color);
WM_operatortype_append(SCULPT_OT_loop_to_vertex_colors);
WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors);
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index 5f7805af347..556b73b0ea5 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -308,7 +308,7 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot)
/* api callbacks */
ot->invoke = sculpt_color_filter_invoke;
ot->modal = sculpt_color_filter_modal;
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 90f27bf71a3..e943bd280a3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -51,6 +51,8 @@ bool SCULPT_mode_poll_view3d(struct bContext *C);
bool SCULPT_poll(struct bContext *C);
bool SCULPT_poll_view3d(struct bContext *C);
+bool SCULPT_vertex_colors_poll(struct bContext *C);
+
/* Updates */
typedef enum SculptUpdateType {
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 9c21f9040da..bb9720246ca 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -38,6 +38,7 @@
#include "BLI_utildefines.h"
#include "DNA_meshdata_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
@@ -234,7 +235,8 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
const bool show_face_sets = sculpt_face_sets &&
(update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
- const bool show_vcol = (vcol || vtcol) && (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
+ const bool show_vcol = (vcol || (vtcol && U.experimental.use_sculpt_vertex_colors)) &&
+ (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
bool empty_mask = true;
bool default_face_set = true;
@@ -317,7 +319,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Vertex Colors. */
if (show_vcol) {
ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- if (vtcol) {
+ if (vtcol && U.experimental.use_sculpt_vertex_colors) {
scol[0] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[0]);
scol[1] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[1]);
scol[2] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[2]);
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 911e0ee4893..8ea4d3b6476 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -622,8 +622,9 @@ typedef struct UserDef_Experimental {
char use_new_particle_system;
char use_new_hair_type;
char use_cycles_debug;
+ char use_sculpt_vertex_colors;
/** `makesdna` does not allow empty structs. */
- char _pad0[4];
+ char _pad[3];
} UserDef_Experimental;
#define USER_EXPERIMENTAL_TEST(userdef, member) \
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index c31b313d827..145a505b729 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -6084,6 +6084,10 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "use_cycles_debug", 1);
RNA_def_property_ui_text(prop, "Cycles Debug", "Enable Cycles debugging options for developers");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "use_sculpt_vertex_colors", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_vertex_colors", 1);
+ RNA_def_property_ui_text(prop, "Sculpt Vertex Colors", "Use the new Vertex Painting system");
}
static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop)
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
index 70c924a7f85..40576b68dd5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
@@ -39,6 +39,10 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
+ if (U.experimental.use_sculpt_vertex_colors) {
+ GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_PROP_COLOR, vertexColor->layer_name);
+ return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
+ }
GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name);
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}