temp-sculpt-colors: commit patch
This commit is contained in:
parent
6cf734a2e5
commit
1dcc741f43
|
@ -1 +1 @@
|
|||
Subproject commit 62e82958a760dad775d9b3387d7fb535fd6de4c6
|
||||
Subproject commit 326997b913d04bc5bc4656973d1e1a819f860dd2
|
|
@ -1 +1 @@
|
|||
Subproject commit 4475cbd11a636382d57571e0f5dfeff1f90bd6b7
|
||||
Subproject commit 59c8409947c4174983a36ec28dfeda2be9e254d2
|
|
@ -1 +1 @@
|
|||
Subproject commit 788441f2930465bbfba8f0797b12dcef1d46694d
|
||||
Subproject commit 98f6085e9d71ba35d41e5aafbcb7981bd7c48275
|
|
@ -461,44 +461,6 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
|
|||
col.operator("mesh.vertex_color_add", icon='ADD', text="")
|
||||
col.operator("mesh.vertex_color_remove", icon='REMOVE', text="")
|
||||
|
||||
|
||||
class DATA_PT_sculpt_vertex_colors(MeshButtonsPanel, Panel):
|
||||
bl_label = "Sculpt Vertex Colors"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return super().poll(context) and context.preferences.experimental.use_sculpt_vertex_colors
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
me = context.mesh
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list(
|
||||
"MESH_UL_vcols",
|
||||
"svcols",
|
||||
me,
|
||||
"sculpt_vertex_colors",
|
||||
me.sculpt_vertex_colors,
|
||||
"active_index",
|
||||
rows=2,
|
||||
)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("mesh.sculpt_vertex_color_add", icon='ADD', text="")
|
||||
col.operator("mesh.sculpt_vertex_color_remove", icon='REMOVE', text="")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.operator("sculpt.vertex_to_loop_colors", text="Store Sculpt Vertex Color")
|
||||
col.operator("sculpt.loop_to_vertex_colors", text="Load Sculpt Vertex Color")
|
||||
|
||||
|
||||
class DATA_PT_remesh(MeshButtonsPanel, Panel):
|
||||
bl_label = "Remesh"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
@ -522,8 +484,7 @@ 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")
|
||||
if context.preferences.experimental.use_sculpt_vertex_colors:
|
||||
col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
|
||||
col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
|
||||
|
||||
col.operator("object.voxel_remesh", text="Voxel Remesh")
|
||||
else:
|
||||
|
@ -614,6 +575,12 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
|
|||
col.operator("geometry.attribute_add", icon='ADD', text="")
|
||||
col.operator("geometry.attribute_remove", icon='REMOVE', text="")
|
||||
|
||||
active = mesh.attributes.active
|
||||
print(active.domain, active.data_type)
|
||||
if active.domain == "POINT" and active.data_type == "FLOAT_COLOR":
|
||||
layout.operator("sculpt.vertex_to_loop_colors", text="Save To Corners")
|
||||
layout.operator("sculpt.loop_to_vertex_colors", text="Load From Corners")
|
||||
|
||||
self.draw_attribute_warnings(context, layout)
|
||||
|
||||
def draw_attribute_warnings(self, context, layout):
|
||||
|
@ -663,7 +630,6 @@ classes = (
|
|||
DATA_PT_shape_keys,
|
||||
DATA_PT_uv_texture,
|
||||
DATA_PT_vertex_colors,
|
||||
DATA_PT_sculpt_vertex_colors,
|
||||
DATA_PT_face_maps,
|
||||
DATA_PT_mesh_attributes,
|
||||
DATA_PT_normals,
|
||||
|
|
|
@ -1293,8 +1293,6 @@ class _defs_sculpt:
|
|||
exclude_filter = {}
|
||||
# Use 'bpy.context' instead of 'context' since it can be None.
|
||||
prefs = bpy.context.preferences
|
||||
if not prefs.experimental.use_sculpt_vertex_colors:
|
||||
exclude_filter = {'PAINT', 'SMEAR'}
|
||||
|
||||
return generate_from_enum_ex(
|
||||
context,
|
||||
|
@ -2851,17 +2849,13 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
_defs_sculpt.cloth_filter,
|
||||
lambda context: (
|
||||
(_defs_sculpt.color_filter,)
|
||||
if context is None or (
|
||||
context.preferences.view.show_developer_ui and
|
||||
context.preferences.experimental.use_sculpt_vertex_colors)
|
||||
if context is None
|
||||
else ()
|
||||
),
|
||||
None,
|
||||
lambda context: (
|
||||
(_defs_sculpt.mask_by_color,)
|
||||
if context is None or (
|
||||
context.preferences.view.show_developer_ui and
|
||||
context.preferences.experimental.use_sculpt_vertex_colors)
|
||||
if context is None
|
||||
else ()
|
||||
),
|
||||
None,
|
||||
|
|
|
@ -2247,7 +2247,6 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
|
|||
def draw(self, context):
|
||||
self._draw_items(
|
||||
context, (
|
||||
({"property": "use_sculpt_vertex_colors"}, "T71947"),
|
||||
({"property": "use_sculpt_tools_tilt"}, "T82877"),
|
||||
({"property": "use_extended_asset_browser"}, ("project/view/130/", "Project Page")),
|
||||
({"property": "use_override_templates"}, ("T73318", "Milestone 4")),
|
||||
|
|
|
@ -837,8 +837,7 @@ 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")
|
||||
if context.preferences.experimental.use_sculpt_vertex_colors:
|
||||
col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
|
||||
col.prop(mesh, "use_remesh_preserve_vertex_colors", text="Vertex Colors")
|
||||
|
||||
layout.operator("object.voxel_remesh", text="Remesh")
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 22
|
||||
#define BLENDER_FILE_SUBVERSION 26
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
|
|
@ -54,9 +54,11 @@ enum {
|
|||
DT_TYPE_UV = 1 << 24,
|
||||
DT_TYPE_SHARP_FACE = 1 << 25,
|
||||
DT_TYPE_FREESTYLE_FACE = 1 << 26,
|
||||
#define DT_TYPE_MAX 27
|
||||
DT_TYPE_PROPCOL = 1 << 27,
|
||||
#define DT_TYPE_MAX 28
|
||||
|
||||
DT_TYPE_VERT_ALL = DT_TYPE_MDEFORMVERT | DT_TYPE_SHAPEKEY | DT_TYPE_SKIN | DT_TYPE_BWEIGHT_VERT,
|
||||
DT_TYPE_VERT_ALL = DT_TYPE_MDEFORMVERT | DT_TYPE_SHAPEKEY | DT_TYPE_SKIN | DT_TYPE_BWEIGHT_VERT |
|
||||
DT_TYPE_PROPCOL,
|
||||
DT_TYPE_EDGE_ALL = DT_TYPE_SHARP_EDGE | DT_TYPE_SEAM | DT_TYPE_CREASE | DT_TYPE_BWEIGHT_EDGE |
|
||||
DT_TYPE_FREESTYLE_EDGE,
|
||||
DT_TYPE_LOOP_ALL = DT_TYPE_VCOL | DT_TYPE_LNOR | DT_TYPE_UV,
|
||||
|
@ -74,7 +76,12 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type);
|
|||
int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type);
|
||||
|
||||
#define DT_DATATYPE_IS_VERT(_dt) \
|
||||
ELEM(_dt, DT_TYPE_MDEFORMVERT, DT_TYPE_SHAPEKEY, DT_TYPE_SKIN, DT_TYPE_BWEIGHT_VERT)
|
||||
ELEM(_dt, \
|
||||
DT_TYPE_MDEFORMVERT, \
|
||||
DT_TYPE_SHAPEKEY, \
|
||||
DT_TYPE_SKIN, \
|
||||
DT_TYPE_BWEIGHT_VERT, \
|
||||
DT_TYPE_PROPCOL)
|
||||
#define DT_DATATYPE_IS_EDGE(_dt) \
|
||||
ELEM(_dt, \
|
||||
DT_TYPE_CREASE, \
|
||||
|
@ -94,7 +101,8 @@ enum {
|
|||
DT_MULTILAYER_INDEX_SHAPEKEY = 1,
|
||||
DT_MULTILAYER_INDEX_VCOL = 2,
|
||||
DT_MULTILAYER_INDEX_UV = 3,
|
||||
DT_MULTILAYER_INDEX_MAX = 4,
|
||||
DT_MULTILAYER_INDEX_PROPCOL = 4,
|
||||
DT_MULTILAYER_INDEX_MAX = 5,
|
||||
};
|
||||
|
||||
/* Below we keep positive values for real layers idx (generated dynamically). */
|
||||
|
|
|
@ -467,6 +467,12 @@ typedef struct SculptSession {
|
|||
|
||||
struct KeyBlock *shapekey_active;
|
||||
struct MPropCol *vcol;
|
||||
float (*f3col)[3];
|
||||
struct MLoopCol *mcol;
|
||||
|
||||
int vcol_domain;
|
||||
int vcol_type;
|
||||
|
||||
float *vmask;
|
||||
|
||||
/* Mesh connectivity maps. */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "BLI_ghash.h"
|
||||
|
||||
/* For embedding CCGKey in iterator. */
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_ccg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -358,7 +359,6 @@ typedef struct PBVHVertexIter {
|
|||
struct MVert *mverts;
|
||||
int totvert;
|
||||
const int *vert_indices;
|
||||
struct MPropCol *vcol;
|
||||
float *vmask;
|
||||
|
||||
/* bmesh */
|
||||
|
@ -375,7 +375,6 @@ typedef struct PBVHVertexIter {
|
|||
short *no;
|
||||
float *fno;
|
||||
float *mask;
|
||||
float *col;
|
||||
bool visible;
|
||||
} PBVHVertexIter;
|
||||
|
||||
|
@ -431,9 +430,6 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
|
|||
if (vi.vmask) { \
|
||||
vi.mask = &vi.vmask[vi.index]; \
|
||||
} \
|
||||
if (vi.vcol) { \
|
||||
vi.col = vi.vcol[vi.index].color; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \
|
||||
|
@ -489,6 +485,9 @@ struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh);
|
|||
|
||||
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
|
||||
void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
|
||||
bool BKE_pbvh_get_color_layer(const struct Mesh *me,
|
||||
CustomDataLayer **cl_out,
|
||||
AttributeDomain *attr_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1843,6 +1843,8 @@ void BKE_brush_sculpt_reset(Brush *br)
|
|||
br->density = 1.0f;
|
||||
br->flag &= ~BRUSH_SPACE_ATTEN;
|
||||
zero_v3(br->rgb);
|
||||
add_v3_fl(br->rgb, 1.0f);
|
||||
zero_v3(br->secondary_rgb);
|
||||
break;
|
||||
case SCULPT_TOOL_SMEAR:
|
||||
br->alpha = 1.0f;
|
||||
|
|
|
@ -150,6 +150,7 @@ bool BKE_object_data_transfer_get_dttypes_capacity(const int dtdata_types,
|
|||
case DT_TYPE_UV:
|
||||
ret = true;
|
||||
break;
|
||||
case DT_TYPE_PROPCOL:
|
||||
case DT_TYPE_VCOL:
|
||||
*r_advanced_mixing = true;
|
||||
*r_threshold = true;
|
||||
|
@ -230,12 +231,12 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
|
|||
return CD_FAKE_SHARP;
|
||||
case DT_TYPE_FREESTYLE_FACE:
|
||||
return CD_FREESTYLE_FACE;
|
||||
|
||||
case DT_TYPE_VCOL:
|
||||
return CD_MLOOPCOL;
|
||||
case DT_TYPE_LNOR:
|
||||
return CD_FAKE_LNOR;
|
||||
|
||||
case DT_TYPE_PROPCOL:
|
||||
return CD_PROP_COLOR;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
|
@ -253,6 +254,8 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
|
|||
return DT_MULTILAYER_INDEX_UV;
|
||||
case DT_TYPE_VCOL:
|
||||
return DT_MULTILAYER_INDEX_VCOL;
|
||||
case DT_TYPE_PROPCOL:
|
||||
return DT_MULTILAYER_INDEX_PROPCOL;
|
||||
default:
|
||||
return DT_MULTILAYER_INDEX_INVALID;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
@ -1673,7 +1674,31 @@ static void sculpt_update_object(Depsgraph *depsgraph,
|
|||
ss->multires.modifier = NULL;
|
||||
ss->multires.level = 0;
|
||||
ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
|
||||
ss->vcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
|
||||
|
||||
CustomDataLayer *cl;
|
||||
AttributeDomain domain;
|
||||
|
||||
ss->vcol = NULL;
|
||||
ss->mcol = NULL;
|
||||
ss->f3col = NULL;
|
||||
|
||||
if (BKE_pbvh_get_color_layer(me, &cl, &domain)) {
|
||||
if (cl->type == CD_PROP_COLOR) {
|
||||
ss->vcol = cl->data;
|
||||
}
|
||||
else if (cl->type == CD_PROP_FLOAT3) {
|
||||
ss->f3col = cl->data;
|
||||
}
|
||||
else {
|
||||
ss->mcol = cl->data;
|
||||
}
|
||||
|
||||
ss->vcol_domain = domain;
|
||||
ss->vcol_type = cl->type;
|
||||
}
|
||||
else {
|
||||
ss->vcol_type = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sculpt Face Sets. */
|
||||
|
@ -1798,17 +1823,53 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
|
|||
void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
|
||||
{
|
||||
Mesh *orig_me = BKE_object_get_original_mesh(object);
|
||||
if (!U.experimental.use_sculpt_vertex_colors) {
|
||||
return;
|
||||
|
||||
int types[] = {CD_PROP_COLOR, CD_PROP_FLOAT3, CD_MLOOPCOL};
|
||||
bool has_color = false;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
bool ok = CustomData_has_layer(&orig_me->vdata, types[i]);
|
||||
ok = ok || CustomData_has_layer(&orig_me->ldata, types[i]);
|
||||
|
||||
if (ok) {
|
||||
has_color = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
|
||||
return;
|
||||
CustomDataLayer *cl;
|
||||
if (has_color) {
|
||||
cl = BKE_id_attributes_active_get(&orig_me->id);
|
||||
if (!ELEM(cl->type, CD_PROP_COLOR, CD_MLOOPCOL, CD_PROP_FLOAT3)) {
|
||||
cl = NULL;
|
||||
|
||||
/* find a color layer */
|
||||
for (int step = 0; !cl && step < 2; step++) {
|
||||
CustomData *cdata = step ? &orig_me->ldata : &orig_me->vdata;
|
||||
|
||||
for (int i = 0; i < cdata->totlayer; i++) {
|
||||
if (ELEM(cdata->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL, CD_PROP_FLOAT3)) {
|
||||
cl = cdata->layers + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cl = NULL; /* no need to update active layer */
|
||||
}
|
||||
}
|
||||
else {
|
||||
CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
|
||||
cl = orig_me->vdata.layers + CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR);
|
||||
|
||||
BKE_mesh_update_customdata_pointers(orig_me, true);
|
||||
}
|
||||
|
||||
CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
|
||||
BKE_mesh_update_customdata_pointers(orig_me, true);
|
||||
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
|
||||
if (cl) {
|
||||
BKE_id_attributes_active_set(&orig_me->id, cl);
|
||||
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
|
||||
}
|
||||
}
|
||||
|
||||
/** \warning Expects a fully evaluated depsgraph. */
|
||||
|
@ -2026,8 +2087,8 @@ void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv
|
|||
const bool is_hidden = (face_sets[face_index] < 0);
|
||||
|
||||
/* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
|
||||
* there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
|
||||
* visible. */
|
||||
* there is not bitmap for the grid. This is because missing grid_hidden implies grid is
|
||||
* fully visible. */
|
||||
if (is_hidden) {
|
||||
BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg, i);
|
||||
}
|
||||
|
@ -2066,8 +2127,8 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
|
|||
object->sculpt->face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
|
||||
|
||||
/* NOTE: In theory we could add that on the fly when required by sculpt code.
|
||||
* But this then requires proper update of depsgraph etc. For now we play safe, optimization is
|
||||
* always possible later if it's worth it. */
|
||||
* But this then requires proper update of depsgraph etc. For now we play safe, optimization
|
||||
* is always possible later if it's worth it. */
|
||||
BKE_sculpt_mask_layers_ensure(object, mmd);
|
||||
}
|
||||
|
||||
|
@ -2075,8 +2136,8 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
|
|||
BKE_mesh_tessface_clear(mesh);
|
||||
|
||||
/* We always need to flush updates from depsgraph here, since at the very least
|
||||
* `BKE_sculpt_face_sets_ensure_from_base_mesh_visibility()` will have updated some data layer of
|
||||
* the mesh.
|
||||
* `BKE_sculpt_face_sets_ensure_from_base_mesh_visibility()` will have updated some data layer
|
||||
* of the mesh.
|
||||
*
|
||||
* All known potential sources of updates:
|
||||
* - Addition of, or changes to, the `CD_SCULPT_FACE_SETS` data layer
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
|
||||
#include "BKE_paint.h"
|
||||
|
@ -1258,6 +1259,33 @@ static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh))
|
|||
return update_flags;
|
||||
}
|
||||
|
||||
bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_cl, AttributeDomain *r_attr)
|
||||
{
|
||||
CustomDataLayer *cl = BKE_id_attributes_active_get((ID *)me);
|
||||
AttributeDomain domain;
|
||||
|
||||
if (!cl || !ELEM(cl->type, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_MLOOPCOL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
domain = BKE_id_attribute_domain((ID *)me, cl);
|
||||
|
||||
if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cl) {
|
||||
*r_cl = cl;
|
||||
*r_attr = domain;
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
*r_cl = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
|
@ -1308,17 +1336,23 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
|
|||
&pbvh->gridkey,
|
||||
update_flags);
|
||||
break;
|
||||
case PBVH_FACES:
|
||||
case PBVH_FACES: {
|
||||
CustomDataLayer *cl = NULL;
|
||||
AttributeDomain domain;
|
||||
|
||||
BKE_pbvh_get_color_layer(pbvh->mesh, &cl, &domain);
|
||||
|
||||
GPU_pbvh_mesh_buffers_update(node->draw_buffers,
|
||||
pbvh->verts,
|
||||
CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
|
||||
CustomData_get_layer(pbvh->ldata, CD_MLOOPCOL),
|
||||
cl ? cl->data : NULL,
|
||||
cl ? cl->type : -1,
|
||||
cl ? domain : ATTR_DOMAIN_AUTO,
|
||||
CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
|
||||
pbvh->face_sets_color_seed,
|
||||
pbvh->face_sets_color_default,
|
||||
CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR),
|
||||
update_flags);
|
||||
break;
|
||||
} break;
|
||||
case PBVH_BMESH:
|
||||
GPU_pbvh_bmesh_buffers_update(node->draw_buffers,
|
||||
pbvh->bm,
|
||||
|
@ -1445,7 +1479,9 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
|
|||
}
|
||||
|
||||
if (flag & (PBVH_UpdateColor)) {
|
||||
/* Do nothing */
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
nodes[i]->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag & (PBVH_UpdateVisibility)) {
|
||||
|
@ -2981,7 +3017,6 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
|
|||
vi->mask = NULL;
|
||||
if (pbvh->type == PBVH_FACES) {
|
||||
vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK);
|
||||
vi->vcol = CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1250,6 +1250,19 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 300, 26)) {
|
||||
LISTBASE_FOREACH (Brush *, br, &bmain->brushes) {
|
||||
/* buggy code in wm_toolsystem broke smear in old files,
|
||||
reset to defaults*/
|
||||
if (br->sculpt_tool == SCULPT_TOOL_SMEAR) {
|
||||
br->alpha = 1.0f;
|
||||
br->spacing = 5;
|
||||
br->flag &= ~BRUSH_ALPHA_PRESSURE;
|
||||
br->flag &= ~BRUSH_SPACE_ATTEN;
|
||||
br->curve_preset = BRUSH_CURVE_SPHERE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
|
|
@ -186,12 +186,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
|
|||
geom = DRW_cache_mesh_surface_vertpaint_get(ob);
|
||||
}
|
||||
else {
|
||||
if (U.experimental.use_sculpt_vertex_colors) {
|
||||
geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
|
||||
}
|
||||
else {
|
||||
geom = DRW_cache_mesh_surface_vertpaint_get(ob);
|
||||
}
|
||||
geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -272,15 +267,8 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
|
|||
}
|
||||
}
|
||||
else if (color_type == V3D_SHADING_VERTEX_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;
|
||||
}
|
||||
if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
|
||||
color_type = V3D_SHADING_OBJECT_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -374,10 +374,8 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
|
|||
type = CD_MTFACE;
|
||||
|
||||
if (layer == -1) {
|
||||
if (U.experimental.use_sculpt_vertex_colors) {
|
||||
layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
|
||||
type = CD_PROP_COLOR;
|
||||
}
|
||||
layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
|
||||
type = CD_PROP_COLOR;
|
||||
}
|
||||
|
||||
if (layer == -1) {
|
||||
|
|
|
@ -74,28 +74,26 @@ static void extract_vcol_init(const MeshRenderData *mr,
|
|||
}
|
||||
|
||||
/* Sculpt Vertex Colors */
|
||||
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);
|
||||
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);
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +138,7 @@ static void extract_vcol_init(const MeshRenderData *mr,
|
|||
}
|
||||
}
|
||||
|
||||
if (svcol_layers & (1 << i) && U.experimental.use_sculpt_vertex_colors) {
|
||||
if (svcol_layers & (1 << i)) {
|
||||
if (mr->extract_type == MR_EXTRACT_BMESH) {
|
||||
int cd_ofs = CustomData_get_n_offset(cd_vdata, CD_PROP_COLOR, i);
|
||||
BMIter f_iter;
|
||||
|
|
|
@ -763,9 +763,11 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
|
|||
brush.sculpt.mask
|
||||
brush.sculpt.multiplane_scrape
|
||||
brush.sculpt.nudge
|
||||
brush.sculpt.paint
|
||||
brush.sculpt.pinch
|
||||
brush.sculpt.pose
|
||||
brush.sculpt.rotate
|
||||
brush.sculpt.smear
|
||||
brush.sculpt.scrape
|
||||
brush.sculpt.simplify
|
||||
brush.sculpt.smooth
|
||||
|
|
|
@ -919,6 +919,7 @@ DEF_ICON_COLOR(BRUSH_TEXFILL)
|
|||
DEF_ICON_COLOR(BRUSH_TEXMASK)
|
||||
DEF_ICON_COLOR(BRUSH_THUMB)
|
||||
DEF_ICON_COLOR(BRUSH_ROTATE)
|
||||
DEF_ICON_COLOR(BRUSH_PAINT)
|
||||
|
||||
/* grease pencil sculpt */
|
||||
DEF_ICON_COLOR(GPBRUSH_SMOOTH)
|
||||
|
|
|
@ -451,7 +451,7 @@ static bool bake_object_check(ViewLayer *view_layer,
|
|||
|
||||
if (target == R_BAKE_TARGET_VERTEX_COLORS) {
|
||||
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
|
||||
const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
|
||||
const bool mcol_valid = (mcol != NULL);
|
||||
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
|
||||
if (mloopcol == NULL && !mcol_valid) {
|
||||
BKE_reportf(reports,
|
||||
|
@ -937,7 +937,7 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re
|
|||
|
||||
Mesh *me = ob->data;
|
||||
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
|
||||
const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
|
||||
const bool mcol_valid = (mcol != NULL);
|
||||
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
|
||||
if (mloopcol == NULL && !mcol_valid) {
|
||||
BKE_report(reports, RPT_ERROR, "No vertex colors layer found to bake to");
|
||||
|
@ -1092,7 +1092,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
|
|||
{
|
||||
Mesh *me = ob->data;
|
||||
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
|
||||
const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
|
||||
const bool mcol_valid = (mcol != NULL);
|
||||
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
|
||||
const int num_channels = targets->num_channels;
|
||||
const float *result = targets->result;
|
||||
|
|
|
@ -392,7 +392,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* End undo. */
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
/* Ensure that edges and faces get hidden as well (not used by
|
||||
* sculpt but it looks wrong when entering editmode otherwise). */
|
||||
|
|
|
@ -189,7 +189,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
|||
|
||||
BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
|
@ -723,7 +723,7 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext)
|
|||
|
||||
operation->sculpt_gesture_end(C, sgcontext);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(CTX_data_active_object(C));
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
@ -154,19 +155,141 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, int index)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const float *SCULPT_vertex_color_get(SculptSession *ss, int index)
|
||||
bool SCULPT_has_colors(const SculptSession *ss)
|
||||
{
|
||||
return ss->vcol || ss->mcol || ss->f3col;
|
||||
}
|
||||
|
||||
bool SCULPT_vertex_color_get(SculptSession *ss, int index, float out[4])
|
||||
{
|
||||
switch (BKE_pbvh_type(ss->pbvh)) {
|
||||
case PBVH_FACES:
|
||||
if (ss->vcol) {
|
||||
return ss->vcol[index].color;
|
||||
if (!(ss->vcol || ss->mcol || ss->f3col)) {
|
||||
zero_v4(out);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
|
||||
zero_v4(out);
|
||||
|
||||
int count = ss->pmap[index].count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
MPoly *mp = ss->mpoly + ss->pmap[index].indices[i];
|
||||
MLoop *ml = ss->mloop + mp->loopstart;
|
||||
int li = mp->loopstart;
|
||||
|
||||
for (int j = 0; j < mp->totloop; j++, li++, ml++) {
|
||||
if (ml->v != index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ss->vcol_type == CD_MLOOPCOL) {
|
||||
MLoopCol *col = ss->mcol + li;
|
||||
|
||||
float tmp[4];
|
||||
|
||||
rgba_uchar_to_float(tmp, (const char *)col);
|
||||
add_v4_v4(out, tmp);
|
||||
}
|
||||
else if (ss->vcol_type == CD_PROP_FLOAT3) {
|
||||
add_v3_v3(out, ss->f3col[li]);
|
||||
out[3] += 1.0f;
|
||||
}
|
||||
else {
|
||||
add_v4_v4(out, ss->vcol[li].color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count) {
|
||||
mul_v4_fl(out, 1.0f / (float)count);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ss->vcol_type == CD_MLOOPCOL) {
|
||||
MLoopCol *col = ss->mcol + index;
|
||||
|
||||
float tmp[4];
|
||||
rgba_uchar_to_float(tmp, (const char *)col);
|
||||
copy_v4_v4(out, tmp);
|
||||
}
|
||||
else if (ss->vcol_type == CD_PROP_FLOAT3) {
|
||||
copy_v3_v3(out, ss->f3col[index]);
|
||||
out[3] = 1.0f;
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(out, ss->vcol[index].color);
|
||||
}
|
||||
}
|
||||
|
||||
return ss->vcol || ss->mcol || ss->f3col;
|
||||
case PBVH_BMESH:
|
||||
case PBVH_GRIDS:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCULPT_vertex_color_set(SculptSession *ss, int index, float color[4])
|
||||
{
|
||||
switch (BKE_pbvh_type(ss->pbvh)) {
|
||||
case PBVH_FACES:
|
||||
if (!(ss->vcol || ss->mcol || ss->f3col)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
|
||||
int count = ss->pmap[index].count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
MPoly *mp = ss->mpoly + ss->pmap[index].indices[i];
|
||||
MLoop *ml = ss->mloop + mp->loopstart;
|
||||
int li = mp->loopstart;
|
||||
|
||||
for (int j = 0; j < mp->totloop; j++, li++, ml++) {
|
||||
if (ml->v != index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ss->vcol_type == CD_MLOOPCOL) {
|
||||
MLoopCol *col = ss->mcol + li;
|
||||
|
||||
col->r = (unsigned char)(color[0] * 255.0f);
|
||||
col->g = (unsigned char)(color[1] * 255.0f);
|
||||
col->b = (unsigned char)(color[2] * 255.0f);
|
||||
col->a = (unsigned char)(color[3] * 255.0f);
|
||||
}
|
||||
else if (ss->vcol_type == CD_PROP_FLOAT3) {
|
||||
copy_v3_v3(ss->f3col[li], color);
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(ss->vcol[li].color, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ss->vcol_type == CD_MLOOPCOL) {
|
||||
MLoopCol *col = ss->mcol + index;
|
||||
|
||||
col->r = (unsigned char)(color[0] * 255.0f);
|
||||
col->g = (unsigned char)(color[1] * 255.0f);
|
||||
col->b = (unsigned char)(color[2] * 255.0f);
|
||||
col->a = (unsigned char)(color[3] * 255.0f);
|
||||
}
|
||||
else if (ss->vcol_type == CD_PROP_FLOAT3) {
|
||||
copy_v3_v3(ss->f3col[index], color);
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(ss->vcol[index].color, color);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case PBVH_BMESH:
|
||||
case PBVH_GRIDS:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
|
||||
|
@ -1506,7 +1629,10 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
|
|||
*vd.mask = orig_data.mask;
|
||||
}
|
||||
else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
|
||||
copy_v4_v4(vd.col, orig_data.col);
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
|
||||
copy_v4_v4(col, orig_data.col);
|
||||
}
|
||||
|
||||
if (vd.mvert) {
|
||||
|
@ -6584,9 +6710,6 @@ bool SCULPT_mode_poll(bContext *C)
|
|||
|
||||
bool SCULPT_vertex_colors_poll(bContext *C)
|
||||
{
|
||||
if (!U.experimental.use_sculpt_vertex_colors) {
|
||||
return false;
|
||||
}
|
||||
return SCULPT_mode_poll(C);
|
||||
}
|
||||
|
||||
|
@ -7285,7 +7408,8 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd,
|
|||
return ((stroke_mode == BRUSH_STROKE_SMOOTH) || (ss && ss->cache && ss->cache->alt_smooth) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) ||
|
||||
((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_POSE) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_POSE) || (brush->sculpt_tool == SCULPT_TOOL_PAINT) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
|
||||
|
@ -8022,7 +8146,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
|
|||
SCULPT_cache_free(ss->cache);
|
||||
ss->cache = NULL;
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||
|
@ -8272,7 +8396,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* Finish undo. */
|
||||
BM_log_all_added(ss->bm, ss->bm_log);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
break;
|
||||
case PBVH_FACES:
|
||||
|
@ -8434,7 +8558,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
|
|||
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
|
||||
if (has_undo) {
|
||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -8697,15 +8821,25 @@ static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
bool SCULPT_convert_colors_poll(bContext *C)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
bool ok = ob && ob->data && ob->type == OB_MESH;
|
||||
ok = ok && ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_OBJECT);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Sculpt Vertex Color to Vertex Color";
|
||||
ot->description = "Copy the Sculpt Vertex Color to a regular color layer";
|
||||
ot->description = "Copy to active face corner color attribute";
|
||||
ot->idname = "SCULPT_OT_vertex_to_loop_colors";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = SCULPT_vertex_colors_poll;
|
||||
ot->poll = SCULPT_convert_colors_poll;
|
||||
ot->exec = vertex_to_loop_colors_exec;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -8764,11 +8898,11 @@ static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
|
|||
{
|
||||
/* identifiers */
|
||||
ot->name = "Vertex Color to Sculpt Vertex Color";
|
||||
ot->description = "Copy the active loop color layer to the vertex color";
|
||||
ot->description = "Load from active face corner color attribute";
|
||||
ot->idname = "SCULPT_OT_loop_to_vertex_colors";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = SCULPT_vertex_colors_poll;
|
||||
ot->poll = SCULPT_convert_colors_poll;
|
||||
ot->exec = loop_to_vertex_colors_exec;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -8784,8 +8918,9 @@ static int sculpt_sample_color_invoke(bContext *C,
|
|||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
int active_vertex = SCULPT_active_vertex_get(ss);
|
||||
const float *active_vertex_color = SCULPT_vertex_color_get(ss, active_vertex);
|
||||
if (!active_vertex_color) {
|
||||
float active_vertex_color[4];
|
||||
|
||||
if (!SCULPT_vertex_color_get(ss, active_vertex, active_vertex_color)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
@ -9180,7 +9315,9 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb(
|
|||
SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
|
||||
{
|
||||
MaskByColorContiguousFloodFillData *data = userdata;
|
||||
const float *current_color = SCULPT_vertex_color_get(ss, to_v);
|
||||
float current_color[4];
|
||||
SCULPT_vertex_color_get(ss, to_v, current_color);
|
||||
|
||||
float new_vertex_mask = sculpt_mask_by_color_delta_get(
|
||||
current_color, data->initial_color, data->threshold, data->invert);
|
||||
data->new_mask[to_v] = new_vertex_mask;
|
||||
|
@ -9219,7 +9356,7 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
|||
ffd.threshold = threshold;
|
||||
ffd.invert = invert;
|
||||
ffd.new_mask = new_mask;
|
||||
copy_v3_v3(ffd.initial_color, SCULPT_vertex_color_get(ss, vertex));
|
||||
SCULPT_vertex_color_get(ss, vertex, ffd.initial_color);
|
||||
|
||||
SCULPT_floodfill_execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill_cb, &ffd);
|
||||
SCULPT_floodfill_free(&flood);
|
||||
|
@ -9261,12 +9398,17 @@ static void do_mask_by_color_task_cb(void *__restrict userdata,
|
|||
const float threshold = data->mask_by_color_threshold;
|
||||
const bool invert = data->mask_by_color_invert;
|
||||
const bool preserve_mask = data->mask_by_color_preserve_mask;
|
||||
const float *active_color = SCULPT_vertex_color_get(ss, data->mask_by_color_vertex);
|
||||
float active_color[4];
|
||||
|
||||
SCULPT_vertex_color_get(ss, data->mask_by_color_vertex, active_color);
|
||||
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
|
||||
const float current_mask = *vd.mask;
|
||||
const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert);
|
||||
const float new_mask = sculpt_mask_by_color_delta_get(active_color, col, threshold, invert);
|
||||
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
|
||||
|
||||
if (current_mask == *vd.mask) {
|
||||
|
@ -9324,7 +9466,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (!ss->vcol) {
|
||||
if (!SCULPT_has_colors(ss)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
@ -9353,7 +9495,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
|
|||
}
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||
|
||||
|
|
|
@ -1519,7 +1519,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
|
||||
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
SCULPT_filter_cache_free(ss);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
/* Force rebuild of PBVH for better BB placement. */
|
||||
SCULPT_pbvh_clear(ob);
|
||||
|
|
|
@ -290,7 +290,7 @@ void sculpt_dynamic_topology_disable_with_undo(Main *bmain,
|
|||
}
|
||||
SCULPT_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, NULL);
|
||||
if (use_undo) {
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ static void sculpt_dynamic_topology_enable_with_undo(Main *bmain,
|
|||
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
|
||||
if (use_undo) {
|
||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1144,7 +1144,7 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp
|
|||
PBVHNode *node = nodes[n];
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
copy_v4_v4(vd.col, expand_cache->original_colors[vd.index]);
|
||||
SCULPT_vertex_color_set(ss, vd.index, expand_cache->original_colors[vd.index]);
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
|
@ -1208,7 +1208,7 @@ static void sculpt_expand_cancel(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
sculpt_expand_restore_original_state(C, ob, ss->expand_cache);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
sculpt_expand_cache_free(ss);
|
||||
}
|
||||
|
||||
|
@ -1303,7 +1303,7 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata,
|
|||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) {
|
||||
float initial_color[4];
|
||||
copy_v4_v4(initial_color, vd.col);
|
||||
SCULPT_vertex_color_get(ss, vd.index, initial_color);
|
||||
|
||||
const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.index);
|
||||
float fade;
|
||||
|
@ -1330,7 +1330,8 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata,
|
|||
continue;
|
||||
}
|
||||
|
||||
copy_v4_v4(vd.col, final_color);
|
||||
SCULPT_vertex_color_set(ss, vd.index, final_color);
|
||||
|
||||
any_changed = true;
|
||||
if (vd.mvert) {
|
||||
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
|
@ -1386,7 +1387,7 @@ static void sculpt_expand_original_state_store(Object *ob, ExpandCache *expand_c
|
|||
if (expand_cache->target == SCULPT_EXPAND_TARGET_COLORS) {
|
||||
expand_cache->original_colors = MEM_malloc_arrayN(totvert, sizeof(float[4]), "initial colors");
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
copy_v4_v4(expand_cache->original_colors[i], SCULPT_vertex_color_get(ss, i));
|
||||
SCULPT_vertex_color_get(ss, i, expand_cache->original_colors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1542,7 +1543,7 @@ static void sculpt_expand_finish(bContext *C)
|
|||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
/* Tag all nodes to redraw to avoid artifacts after the fast partial updates. */
|
||||
PBVHNode **nodes;
|
||||
|
|
|
@ -412,7 +412,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
|||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
|
@ -749,7 +749,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
|||
break;
|
||||
}
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
|
||||
SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
|
||||
|
@ -939,7 +939,7 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
|
|||
/* Sync face sets visibility and vertex visibility. */
|
||||
SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_update_visibility(nodes[i]);
|
||||
|
@ -1365,7 +1365,7 @@ static void sculpt_face_set_edit_modify_face_sets(Object *ob,
|
|||
SCULPT_undo_push_begin(ob, "face set edit");
|
||||
SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS);
|
||||
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
face_set_edit_do_post_visibility_updates(ob, nodes, totnode);
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
@ -1393,7 +1393,7 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
|
|||
}
|
||||
SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
|
|
|
@ -197,12 +197,19 @@ static void color_filter_task_cb(void *__restrict userdata,
|
|||
fade = clamp_f(fade, -1.0f, 1.0f);
|
||||
float smooth_color[4];
|
||||
SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
|
||||
blend_color_interpolate_float(final_color, vd.col, smooth_color, fade);
|
||||
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
|
||||
blend_color_interpolate_float(final_color, col, smooth_color, fade);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
copy_v3_v3(vd.col, final_color);
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
|
||||
copy_v3_v3(col, final_color);
|
||||
|
||||
if (vd.mvert) {
|
||||
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
|
@ -221,7 +228,7 @@ static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
float filter_strength = RNA_float_get(op->ptr, "strength");
|
||||
|
||||
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
SCULPT_filter_cache_free(ss);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COLOR);
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -285,7 +292,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (!ss->vcol) {
|
||||
if (!SCULPT_has_colors(ss)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
|
@ -470,7 +470,7 @@ static int sculpt_dirty_mask_exec(bContext *C, wmOperator *op)
|
|||
|
||||
BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
ED_region_tag_redraw(region);
|
||||
|
||||
|
|
|
@ -615,7 +615,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||
|
||||
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
SCULPT_filter_cache_free(ss);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
@ -98,10 +98,14 @@ char SCULPT_mesh_symmetry_xyz_get(Object *object);
|
|||
void SCULPT_vertex_random_access_ensure(struct SculptSession *ss);
|
||||
|
||||
int SCULPT_vertex_count_get(struct SculptSession *ss);
|
||||
|
||||
const float *SCULPT_vertex_co_get(struct SculptSession *ss, int index);
|
||||
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]);
|
||||
float SCULPT_vertex_mask_get(struct SculptSession *ss, int index);
|
||||
const float *SCULPT_vertex_color_get(SculptSession *ss, int index);
|
||||
|
||||
bool SCULPT_vertex_color_get(SculptSession *ss, int index, float out[4]);
|
||||
void SCULPT_vertex_color_set(SculptSession *ss, int index, float color[4]);
|
||||
bool SCULPT_has_colors(const SculptSession *ss);
|
||||
|
||||
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index);
|
||||
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]);
|
||||
|
@ -1306,8 +1310,8 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
|
|||
SculptUndoNode *SCULPT_undo_get_node(PBVHNode *node);
|
||||
SculptUndoNode *SCULPT_undo_get_first_node(void);
|
||||
void SCULPT_undo_push_begin(struct Object *ob, const char *name);
|
||||
void SCULPT_undo_push_end(void);
|
||||
void SCULPT_undo_push_end_ex(const bool use_nested_undo);
|
||||
void SCULPT_undo_push_end(struct Object *ob);
|
||||
void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo);
|
||||
|
||||
void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]);
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
|
|||
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
|
||||
}
|
||||
SCULPT_filter_cache_free(ss);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||
ED_workspace_status_text(C, NULL);
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
|||
|
||||
SCULPT_filter_cache_free(ss);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||
ED_workspace_status_text(C, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -166,7 +166,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
|||
|
||||
multires_stitch_grids(ob);
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
|
|
@ -101,7 +101,11 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
|
|||
|
||||
float smooth_color[4];
|
||||
SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
|
||||
blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
|
||||
float col[4];
|
||||
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
blend_color_interpolate_float(col, col, smooth_color, fade);
|
||||
SCULPT_vertex_color_set(ss, vd.index, col);
|
||||
|
||||
if (vd.mvert) {
|
||||
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
|
@ -193,9 +197,11 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
|
|||
/* Final mix over the original color using brush alpha. */
|
||||
mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
|
||||
|
||||
IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
|
||||
|
||||
CLAMP4(vd.col, 0.0f, 1.0f);
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
IMB_blend_color_float(col, orig_data.col, buffer_color, brush->blend);
|
||||
CLAMP4(col, 0.0f, 1.0f);
|
||||
SCULPT_vertex_color_set(ss, vd.index, col);
|
||||
|
||||
if (vd.mvert) {
|
||||
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
|
@ -230,7 +236,10 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
|
|||
continue;
|
||||
}
|
||||
|
||||
add_v4_v4(swptd->color, vd.col);
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
|
||||
add_v4_v4(swptd->color, col);
|
||||
swptd->tot_samples++;
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
|
@ -252,7 +261,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
if (!ss->vcol) {
|
||||
if (!SCULPT_has_colors(ss)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -305,7 +314,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, false, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
|
||||
return;
|
||||
}
|
||||
|
@ -361,7 +370,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, false, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
|
@ -433,7 +442,10 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
|
|||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
|
||||
blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
blend_color_interpolate_float(col, ss->cache->prev_colors[vd.index], interp_color, fade);
|
||||
SCULPT_vertex_color_set(ss, vd.index, col);
|
||||
|
||||
if (vd.mvert) {
|
||||
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
|
@ -451,7 +463,10 @@ static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
|
|||
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||
copy_v4_v4(ss->cache->prev_colors[vd.index], SCULPT_vertex_color_get(ss, vd.index));
|
||||
float tmp[4] = {0};
|
||||
|
||||
SCULPT_vertex_color_get(ss, vd.index, tmp);
|
||||
copy_v4_v4(ss->cache->prev_colors[vd.index], tmp);
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
@ -461,7 +476,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
if (!ss->vcol) {
|
||||
if (!SCULPT_has_colors(ss)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -471,7 +486,10 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
if (!ss->cache->prev_colors) {
|
||||
ss->cache->prev_colors = MEM_callocN(sizeof(float[4]) * totvert, "prev colors");
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
copy_v4_v4(ss->cache->prev_colors[i], SCULPT_vertex_color_get(ss, i));
|
||||
float tmp[4] = {0};
|
||||
|
||||
SCULPT_vertex_color_get(ss, i, tmp);
|
||||
copy_v4_v4(ss->cache->prev_colors[i], tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,7 +197,11 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
|
|||
|
||||
SculptVertexNeighborIter ni;
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
|
||||
add_v4_v4(avg, SCULPT_vertex_color_get(ss, ni.index));
|
||||
float tmp[4] = {0};
|
||||
|
||||
SCULPT_vertex_color_get(ss, ni.index, tmp);
|
||||
|
||||
add_v4_v4(avg, tmp);
|
||||
total++;
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
|
@ -206,7 +210,7 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
|
|||
mul_v4_v4fl(result, avg, 1.0f / total);
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(result, SCULPT_vertex_color_get(ss, index));
|
||||
SCULPT_vertex_color_get(ss, index, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ void ED_sculpt_end_transform(struct bContext *C, Object *ob)
|
|||
* undo system works separate from regular undo and this is require to properly
|
||||
* finish an undo step also when canceling. */
|
||||
const bool use_nested_undo = true;
|
||||
SCULPT_undo_push_end_ex(use_nested_undo);
|
||||
SCULPT_undo_push_end_ex(ob, use_nested_undo);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_customdata.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "BKE_key.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_mapping.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
|
@ -109,13 +111,36 @@
|
|||
* End of dynamic topology and symmetrize in this mode are handled in a special
|
||||
* manner as well. */
|
||||
|
||||
#define NO_ACTIVE_LAYER ATTR_DOMAIN_AUTO
|
||||
|
||||
typedef struct UndoSculpt {
|
||||
ListBase nodes;
|
||||
|
||||
size_t undo_size;
|
||||
} UndoSculpt;
|
||||
|
||||
typedef struct SculptAttrRef {
|
||||
AttributeDomain domain;
|
||||
int type;
|
||||
char name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
bool was_set;
|
||||
} SculptAttrRef;
|
||||
|
||||
typedef struct SculptUndoStep {
|
||||
UndoStep step;
|
||||
/* NOTE: will split out into list for multi-object-sculpt-mode. */
|
||||
UndoSculpt data;
|
||||
|
||||
// active vcol layer
|
||||
SculptAttrRef active_attr_start;
|
||||
SculptAttrRef active_attr_end;
|
||||
|
||||
bContext *C;
|
||||
} SculptUndoStep;
|
||||
|
||||
static UndoSculpt *sculpt_undo_get_nodes(void);
|
||||
static bool sculpt_attr_ref_equals(SculptAttrRef *a, SculptAttrRef *b);
|
||||
static void sculpt_save_active_attr(Object *ob, SculptAttrRef *attr);
|
||||
|
||||
static void update_cb(PBVHNode *node, void *rebuild)
|
||||
{
|
||||
|
@ -328,14 +353,25 @@ static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode)
|
|||
Object *ob = OBACT(view_layer);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
if (!ss->pmap) {
|
||||
Mesh *me = BKE_object_get_original_mesh(ob);
|
||||
|
||||
BKE_mesh_vert_poly_map_create(
|
||||
&ss->pmap, &ss->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
|
||||
}
|
||||
|
||||
if (unode->maxvert) {
|
||||
/* regular mesh restore */
|
||||
int *index = unode->index;
|
||||
MVert *mvert = ss->mvert;
|
||||
MPropCol *vcol = ss->vcol;
|
||||
|
||||
for (int i = 0; i < unode->totvert; i++) {
|
||||
copy_v4_v4(vcol[index[i]].color, unode->col[i]);
|
||||
float tmp[4];
|
||||
|
||||
SCULPT_vertex_color_get(ss, index[i], tmp);
|
||||
SCULPT_vertex_color_set(ss, index[i], unode->col[i]);
|
||||
copy_v4_v4(unode->col[i], tmp);
|
||||
|
||||
mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
|
||||
}
|
||||
}
|
||||
|
@ -859,6 +895,9 @@ static void sculpt_undo_free_list(ListBase *lb)
|
|||
if (unode->co) {
|
||||
MEM_freeN(unode->co);
|
||||
}
|
||||
if (unode->col) {
|
||||
MEM_freeN(unode->col);
|
||||
}
|
||||
if (unode->no) {
|
||||
MEM_freeN(unode->no);
|
||||
}
|
||||
|
@ -1033,7 +1072,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
|
|||
usculpt->undo_size += alloc_size;
|
||||
|
||||
/* FIXME: Should explain why this is allocated here, to be freed in
|
||||
* `SCULPT_undo_push_end_ex()`? */
|
||||
* `SCULPT_undo_push_end_ex(ob)`? */
|
||||
alloc_size = sizeof(*unode->no) * (size_t)allvert;
|
||||
unode->no = MEM_callocN(alloc_size, "SculptUndoNode.no");
|
||||
usculpt->undo_size += alloc_size;
|
||||
|
@ -1158,7 +1197,10 @@ static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode)
|
|||
PBVHVertexIter vd;
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
|
||||
copy_v4_v4(unode->col[vd.i], vd.col);
|
||||
float col[4];
|
||||
SCULPT_vertex_color_get(ss, vd.index, col);
|
||||
|
||||
copy_v4_v4(unode->col[vd.i], col);
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
@ -1378,10 +1420,36 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
|
|||
return unode;
|
||||
}
|
||||
|
||||
static bool sculpt_attr_ref_equals(SculptAttrRef *a, SculptAttrRef *b)
|
||||
{
|
||||
return a->domain == b->domain && a->type == b->type && STREQ(a->name, b->name);
|
||||
}
|
||||
|
||||
static void sculpt_save_active_attr(Object *ob, SculptAttrRef *attr)
|
||||
{
|
||||
Mesh *me = BKE_object_get_original_mesh(ob);
|
||||
CustomDataLayer *cl;
|
||||
|
||||
if (ob && me && (cl = BKE_id_attributes_active_get((ID *)me))) {
|
||||
attr->domain = BKE_id_attribute_domain((ID *)me, cl);
|
||||
BLI_strncpy(attr->name, cl->name, sizeof(attr->name));
|
||||
attr->type = cl->type;
|
||||
}
|
||||
else {
|
||||
attr->domain = NO_ACTIVE_LAYER;
|
||||
attr->name[0] = 0;
|
||||
}
|
||||
|
||||
attr->was_set = true;
|
||||
}
|
||||
|
||||
void SCULPT_undo_push_begin(Object *ob, const char *name)
|
||||
{
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
SculptUndoStep *us;
|
||||
|
||||
if (!ob->sculpt->pmap && ob->sculpt->pbvh && BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_FACES) {
|
||||
}
|
||||
if (ob != NULL) {
|
||||
/* If possible, we need to tag the object and its geometry data as 'changed in the future' in
|
||||
* the previous undo step if it's a memfile one. */
|
||||
|
@ -1392,15 +1460,20 @@ void SCULPT_undo_push_begin(Object *ob, const char *name)
|
|||
/* Special case, we never read from this. */
|
||||
bContext *C = NULL;
|
||||
|
||||
BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT);
|
||||
us = (SculptUndoStep *)BKE_undosys_step_push_init_with_type(
|
||||
ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT);
|
||||
|
||||
if (!us->active_attr_start.was_set) {
|
||||
sculpt_save_active_attr(ob, &us->active_attr_start);
|
||||
}
|
||||
}
|
||||
|
||||
void SCULPT_undo_push_end(void)
|
||||
void SCULPT_undo_push_end(Object *ob)
|
||||
{
|
||||
SCULPT_undo_push_end_ex(false);
|
||||
SCULPT_undo_push_end_ex(ob, false);
|
||||
}
|
||||
|
||||
void SCULPT_undo_push_end_ex(const bool use_nested_undo)
|
||||
void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo)
|
||||
{
|
||||
UndoSculpt *usculpt = sculpt_undo_get_nodes();
|
||||
SculptUndoNode *unode;
|
||||
|
@ -1424,28 +1497,53 @@ void SCULPT_undo_push_end_ex(const bool use_nested_undo)
|
|||
}
|
||||
WM_file_tag_modified();
|
||||
}
|
||||
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
SculptUndoStep *us = (SculptUndoStep *)BKE_undosys_stack_init_or_active_with_type(
|
||||
ustack, BKE_UNDOSYS_TYPE_SCULPT);
|
||||
|
||||
sculpt_save_active_attr(ob, &us->active_attr_end);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Implements ED Undo System
|
||||
* \{ */
|
||||
|
||||
typedef struct SculptUndoStep {
|
||||
UndoStep step;
|
||||
/* NOTE: will split out into list for multi-object-sculpt-mode. */
|
||||
UndoSculpt data;
|
||||
} SculptUndoStep;
|
||||
static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Mesh *me = BKE_object_get_original_mesh(ob);
|
||||
|
||||
static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
|
||||
if (attr->domain == NO_ACTIVE_LAYER) {
|
||||
// from reading the code, it appears you cannot set
|
||||
// the active layer to NULL, so don't worry about it.
|
||||
// BKE_id_attributes_active_set(&me->id, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
SculptAttrRef existing;
|
||||
sculpt_save_active_attr(ob, &existing);
|
||||
|
||||
if (!sculpt_attr_ref_equals(&existing, attr) && ob->sculpt && ob->sculpt->pbvh) {
|
||||
BKE_pbvh_update_vertex_data(ob->sculpt->pbvh, PBVH_UpdateColor);
|
||||
}
|
||||
|
||||
CustomDataLayer *cl;
|
||||
cl = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
|
||||
|
||||
if (cl) {
|
||||
BKE_id_attributes_active_set(&me->id, cl);
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_undosys_step_encode_init(struct bContext *C, UndoStep *us_p)
|
||||
{
|
||||
SculptUndoStep *us = (SculptUndoStep *)us_p;
|
||||
/* Dummy, memory is cleared anyway. */
|
||||
BLI_listbase_clear(&us->data.nodes);
|
||||
}
|
||||
|
||||
static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C),
|
||||
struct Main *bmain,
|
||||
UndoStep *us_p)
|
||||
static bool sculpt_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
|
||||
{
|
||||
/* Dummy, encoding is done along the way by adding tiles
|
||||
* to the current 'SculptUndoStep' added by encode_init. */
|
||||
|
@ -1472,12 +1570,16 @@ static void sculpt_undosys_step_decode_undo_impl(struct bContext *C,
|
|||
BLI_assert(us->step.is_applied == true);
|
||||
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
|
||||
us->step.is_applied = false;
|
||||
|
||||
// sculpt_undo_load_vcol_layer(C, us);
|
||||
}
|
||||
|
||||
static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
|
||||
Depsgraph *depsgraph,
|
||||
SculptUndoStep *us)
|
||||
{
|
||||
// sculpt_undo_load_vcol_layer(C, us);
|
||||
|
||||
BLI_assert(us->step.is_applied == false);
|
||||
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
|
||||
us->step.is_applied = true;
|
||||
|
@ -1500,10 +1602,18 @@ static void sculpt_undosys_step_decode_undo(struct bContext *C,
|
|||
|
||||
while ((us_iter != us) || (!is_final && us_iter == us)) {
|
||||
BLI_assert(us_iter->step.type == us->step.type); /* Previous loop ensures this. */
|
||||
|
||||
sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_start);
|
||||
sculpt_undosys_step_decode_undo_impl(C, depsgraph, us_iter);
|
||||
// sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_start);
|
||||
|
||||
if (us_iter == us) {
|
||||
if (us_iter->step.prev && us_iter->step.prev->type == BKE_UNDOSYS_TYPE_SCULPT) {
|
||||
sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter->step.prev)->active_attr_end);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
us_iter = (SculptUndoStep *)us_iter->step.prev;
|
||||
}
|
||||
}
|
||||
|
@ -1520,8 +1630,14 @@ static void sculpt_undosys_step_decode_redo(struct bContext *C,
|
|||
us_iter = (SculptUndoStep *)us_iter->step.prev;
|
||||
}
|
||||
while (us_iter && (us_iter->step.is_applied == false)) {
|
||||
sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_start);
|
||||
sculpt_undosys_step_decode_redo_impl(C, depsgraph, us_iter);
|
||||
|
||||
if (us_iter == us) {
|
||||
sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_attr_end);
|
||||
// if (us_iter->step.next && us_iter->step.next->type == BKE_UNDOSYS_TYPE_SCULPT) {
|
||||
// sculpt_undo_load_vcol_layer(C, (SculptUndoStep *)us_iter->step.next);
|
||||
//}
|
||||
break;
|
||||
}
|
||||
us_iter = (SculptUndoStep *)us_iter->step.next;
|
||||
|
@ -1595,7 +1711,7 @@ void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
|
|||
void ED_sculpt_undo_geometry_end(struct Object *ob)
|
||||
{
|
||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY);
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(ob);
|
||||
}
|
||||
|
||||
/* Export for ED_undo_sys. */
|
||||
|
@ -1722,7 +1838,7 @@ void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str)
|
|||
SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY);
|
||||
geometry_unode->geometry_clear_pbvh = false;
|
||||
|
||||
SCULPT_undo_push_end();
|
||||
SCULPT_undo_push_end(object);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -977,8 +977,7 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer
|
|||
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
|
||||
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
|
||||
|
||||
if (U.experimental.use_sculpt_vertex_colors &&
|
||||
RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
|
||||
if (RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
|
||||
uiItemPointerR(
|
||||
layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -78,11 +80,12 @@ enum {
|
|||
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
||||
const struct MVert *mvert,
|
||||
const float *vmask,
|
||||
const struct MLoopCol *vcol,
|
||||
const void *vcol_data,
|
||||
const int vcol_type,
|
||||
const AttributeDomain vcol_domain,
|
||||
const int *sculpt_face_sets,
|
||||
const int face_sets_color_seed,
|
||||
const int face_sets_color_default,
|
||||
const struct MPropCol *vtcol,
|
||||
const int update_flags);
|
||||
|
||||
void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
||||
|
|
|
@ -41,7 +41,9 @@
|
|||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
|
@ -208,18 +210,25 @@ static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
|
|||
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
||||
const MVert *mvert,
|
||||
const float *vmask,
|
||||
const MLoopCol *vcol,
|
||||
const void *vcol_data,
|
||||
const int vcol_type,
|
||||
const AttributeDomain vcol_domain,
|
||||
const int *sculpt_face_sets,
|
||||
const int face_sets_color_seed,
|
||||
const int face_sets_color_default,
|
||||
const MPropCol *vtcol,
|
||||
const int update_flags)
|
||||
{
|
||||
const MPropCol *vtcol = vcol_type == CD_PROP_COLOR ? vcol_data : NULL;
|
||||
const MLoopCol *vcol = vcol_type == CD_MLOOPCOL ? vcol_data : NULL;
|
||||
const float(*f3col)[3] = vcol_type == CD_PROP_FLOAT3 ? vcol_data : NULL;
|
||||
|
||||
const bool color_loops = vcol_domain == ATTR_DOMAIN_CORNER;
|
||||
const bool show_vcol = (vtcol || vcol || f3col) &&
|
||||
(update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
|
||||
|
||||
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 && U.experimental.use_sculpt_vertex_colors)) &&
|
||||
(update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
|
||||
bool empty_mask = true;
|
||||
bool default_face_set = true;
|
||||
|
||||
|
@ -302,16 +311,40 @@ 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 && 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]);
|
||||
scol[3] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[3]);
|
||||
if (vtcol) {
|
||||
if (color_loops) {
|
||||
scol[0] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[0]);
|
||||
scol[1] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[1]);
|
||||
scol[2] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[2]);
|
||||
scol[3] = unit_float_to_ushort_clamp(vtcol[lt->tri[j]].color[3]);
|
||||
}
|
||||
else {
|
||||
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]);
|
||||
scol[3] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[3]);
|
||||
}
|
||||
memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
|
||||
}
|
||||
else {
|
||||
else if (f3col) {
|
||||
if (color_loops) {
|
||||
scol[0] = unit_float_to_ushort_clamp(f3col[lt->tri[j]][0]);
|
||||
scol[1] = unit_float_to_ushort_clamp(f3col[lt->tri[j]][1]);
|
||||
scol[2] = unit_float_to_ushort_clamp(f3col[lt->tri[j]][2]);
|
||||
scol[3] = USHRT_MAX;
|
||||
}
|
||||
else {
|
||||
scol[0] = unit_float_to_ushort_clamp(f3col[vtri[j]][0]);
|
||||
scol[1] = unit_float_to_ushort_clamp(f3col[vtri[j]][1]);
|
||||
scol[2] = unit_float_to_ushort_clamp(f3col[vtri[j]][2]);
|
||||
scol[3] = USHRT_MAX;
|
||||
}
|
||||
memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
|
||||
}
|
||||
else if (vcol) {
|
||||
const uint loop_index = lt->tri[j];
|
||||
const MLoopCol *mcol = &vcol[loop_index];
|
||||
const MLoopCol *mcol = vcol + (color_loops ? loop_index : vtri[j]);
|
||||
|
||||
scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
|
||||
scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
|
||||
scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
|
||||
|
|
|
@ -6307,10 +6307,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
|
|||
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");
|
||||
|
||||
prop = RNA_def_property(srna, "use_sculpt_tools_tilt", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_tools_tilt", 1);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
|
@ -369,6 +369,20 @@ static void face_corner_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
uiItemR(layout, ptr, "loop_mapping", 0, IFACE_("Mapping"), ICON_NONE);
|
||||
}
|
||||
|
||||
static void vert_propcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
|
||||
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
uiLayoutSetActive(layout, RNA_enum_get(ptr, "data_types_verts") & DT_TYPE_PROPCOL);
|
||||
|
||||
uiItemR(layout, ptr, "layers_propcol_select_src", 0, IFACE_("Layer Selection"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "layers_propcol_select_dst", 0, IFACE_("Layer Mapping"), ICON_NONE);
|
||||
}
|
||||
|
||||
static void face_corner_vcol_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
|
@ -449,6 +463,9 @@ static void panelRegister(ARegionType *region_type)
|
|||
modifier_subpanel_register(
|
||||
region_type, "vertex_vgroup", "Vertex Groups", NULL, vertex_vgroup_panel_draw, vertex_panel);
|
||||
|
||||
modifier_subpanel_register(
|
||||
region_type, "vert_propcol", "Sculpt Colors", NULL, vert_propcol_panel_draw, vertex_panel);
|
||||
|
||||
modifier_subpanel_register(
|
||||
region_type, "edge", "", edge_panel_draw_header, edge_panel_draw, panel_type);
|
||||
|
||||
|
|
|
@ -39,11 +39,7 @@ 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);
|
||||
GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_PROP_COLOR, vertexColor->layer_name);
|
||||
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
@ -211,6 +212,12 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre
|
|||
}
|
||||
else {
|
||||
brush = BKE_brush_add(bmain, items[i].name, paint->runtime.ob_mode);
|
||||
|
||||
if (paint->runtime.ob_mode == OB_MODE_SCULPT) {
|
||||
brush->sculpt_tool = slot_index;
|
||||
BKE_brush_sculpt_reset(brush);
|
||||
}
|
||||
|
||||
BKE_brush_tool_set(brush, paint, slot_index);
|
||||
}
|
||||
BKE_paint_brush_set(paint, brush);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit c8579c5cf43229843df505da9644b5b0b7201974
|
||||
Subproject commit 548055f40213c775a6b77025525c91e8466e70d6
|
Loading…
Reference in New Issue