Got sculpt colors to work, needs more testing

This commit is contained in:
Joseph Eagar 2020-10-25 22:35:02 -07:00
parent 6da9fa1bf2
commit f9859a3b2a
14 changed files with 140 additions and 41 deletions

View File

@ -525,6 +525,7 @@ typedef struct SculptSession {
struct RegionView3D *rv3d;
struct View3D *v3d;
struct Scene *scene;
int cd_origvcol_offset;
int cd_origco_offset;
int cd_origno_offset;

View File

@ -45,6 +45,7 @@ BLI_INLINE SculptVertRef BKE_pbvh_make_vref(intptr_t i)
struct BMLog;
struct BMesh;
struct BMVert;
struct CCGElem;
struct CCGKey;
struct CustomData;
@ -212,23 +213,29 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_origco_offset,
const int cd_origno_offset);
const int cd_origno_offset,
const int cd_origvcol_offset);
void BKE_pbvh_update_offsets(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_origco_offset,
const int cd_origno_offset);
const int cd_origno_offset,
const int cd_origvcol_offset);
void BKE_pbvh_free(PBVH *pbvh);
/* Hierarchical Search in the BVH, two methods:
* - for each hit calling a callback
* - gather nodes in an array (easy to multithread) */
/** update original data, only data whose r_** parameters are passed in will be updated*/
void BKE_pbvh_bmesh_update_origvert(
PBVH *pbvh, struct BMVert *v, float **r_co, float **r_no, float **r_color);
void BKE_pbvh_search_callback(PBVH *pbvh,
BKE_pbvh_SearchCallback scb,
void *search_data,
BKE_pbvh_HitCallback hcb,
void *hit_data);
/* Hierarchical Search in the BVH, two methods:
* - for each hit calling a callback
* - gather nodes in an array (easy to multithread) */
void BKE_pbvh_search_callback(PBVH *pbvh,
BKE_pbvh_SearchCallback scb,
void *search_data,
BKE_pbvh_HitCallback hcb,
void *hit_data);
void BKE_pbvh_search_gather(
PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot);

View File

@ -1977,7 +1977,8 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
ob->sculpt->cd_vert_node_offset,
ob->sculpt->cd_face_node_offset,
ob->sculpt->cd_origco_offset,
ob->sculpt->cd_origno_offset);
ob->sculpt->cd_origno_offset,
ob->sculpt->cd_origvcol_offset);
pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
pbvh_show_face_sets_set(pbvh, false);
return pbvh;
@ -2068,7 +2069,8 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
if (subdiv_ccg != NULL) {
BKE_sculpt_bvh_update_from_ccg(pbvh, subdiv_ccg);
}
} else if (BKE_pbvh_type(pbvh) == PBVH_BMESH) {
}
else if (BKE_pbvh_type(pbvh) == PBVH_BMESH) {
SCULPT_dynamic_topology_sync_layers(ob);
}
return pbvh;

View File

@ -2259,7 +2259,8 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh,
copy_v3_v3(nearest_vertex_co, co[j]);
*r_active_vertex_index = BKE_pbvh_make_vref(gridkey->grid_area * grid_index +
(y + y_it[j]) * gridkey->grid_size + (x + x_it[j]));
(y + y_it[j]) * gridkey->grid_size +
(x + x_it[j]));
}
}
}
@ -2322,7 +2323,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
face_normal);
break;
case PBVH_BMESH:
//BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
// BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
hit = pbvh_bmesh_node_raycast(node,
ray_start,
ray_normal,
@ -2911,9 +2912,17 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node)
{
unsigned int totvert;
if (node->bm_unique_verts) {
totvert = BLI_table_gset_len(node->bm_unique_verts);
}
else {
totvert = node->uniq_verts;
}
if (!node->color_buffer.color) {
node->color_buffer.color = MEM_callocN(sizeof(float[4]) * node->uniq_verts, "Color buffer");
node->color_buffer.color = MEM_callocN(sizeof(float[4]) * totvert, "Color buffer");
}
return &node->color_buffer;
}
@ -2977,7 +2986,9 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->bm_other_verts = node->bm_other_verts;
vi->bm_vdata = &pbvh->bm->vdata;
vi->bm_vert = NULL;
vi->cd_vcol_offset = CustomData_get_offset(vi->bm_vdata, CD_PROP_COLOR);
// we ensure pbvh->cd_vcol_offset is up to date here too
vi->cd_vcol_offset = pbvh->cd_vcol_offset = CustomData_get_offset(vi->bm_vdata, CD_PROP_COLOR);
vi->cd_vert_mask_offset = CustomData_get_offset(vi->bm_vdata, CD_PAINT_MASK);
}
@ -3007,7 +3018,8 @@ bool pbvh_has_mask(PBVH *pbvh)
return false;
}
SculptVertRef BKE_pbvh_table_index_to_vertex(PBVH *pbvh, int idx) {
SculptVertRef BKE_pbvh_table_index_to_vertex(PBVH *pbvh, int idx)
{
if (pbvh->type == PBVH_BMESH) {
SculptVertRef ref = {(intptr_t)pbvh->bm->vtable[idx]};
return ref;

View File

@ -1784,15 +1784,42 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BM_vert_kill(pbvh->bm, v_del);
}
void BKE_pbvh_bmesh_update_origvert(PBVH *pbvh, BMVert *v)
void BKE_pbvh_bmesh_update_origvert(
PBVH *pbvh, BMVert *v, float **r_co, float **r_no, float **r_color)
{
BM_log_vert_before_modified(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
float *co = NULL, *no = NULL;
float *co = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origco_offset);
float *no = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origno_offset);
if (r_co || r_no) {
BM_log_vert_before_modified(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
copy_v3_v3(co, v->co);
copy_v3_v3(no, v->no);
co = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origco_offset);
no = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origno_offset);
copy_v3_v3(co, v->co);
copy_v3_v3(no, v->no);
if (r_co) {
*r_co = co;
}
if (r_no) {
*r_no = no;
}
}
if (r_color && pbvh->cd_vcol_offset >= 0 && pbvh->cd_origvcol_offset >= 0) {
MPropCol *ml1 = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_vcol_offset);
MPropCol *ml2 = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origvcol_offset);
copy_v4_v4(ml2->color, ml1->color);
if (r_color) {
*r_color = ml2->color;
}
}
else if (r_color) {
*r_color = NULL;
}
}
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
@ -2268,13 +2295,15 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_origco_offset,
const int cd_origno_offset)
const int cd_origno_offset,
const int cd_origvcol_offset)
{
pbvh->cd_vert_node_offset = cd_vert_node_offset;
pbvh->cd_face_node_offset = cd_face_node_offset;
pbvh->cd_origco_offset = cd_origco_offset;
pbvh->cd_origno_offset = cd_origno_offset;
pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
pbvh->cd_origvcol_offset = cd_origvcol_offset;
pbvh->bm = bm;
@ -2282,6 +2311,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
pbvh->type = PBVH_BMESH;
pbvh->bm_log = log;
pbvh->cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR);
/* TODO: choose leaf limit better */
pbvh->leaf_limit = 3000;
@ -3141,11 +3171,13 @@ void BKE_pbvh_update_offsets(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_origco_offset,
const int cd_origno_offset)
const int cd_origno_offset,
const int cd_origvcol_offset)
{
pbvh->cd_face_node_offset = cd_face_node_offset;
pbvh->cd_vert_node_offset = cd_vert_node_offset;
pbvh->cd_vert_mask_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK);
pbvh->cd_origco_offset = cd_origco_offset;
pbvh->cd_origno_offset = cd_origno_offset;
pbvh->cd_origvcol_offset = cd_origvcol_offset;
}

View File

@ -177,8 +177,10 @@ struct PBVH {
int cd_vert_node_offset;
int cd_face_node_offset;
int cd_vert_mask_offset;
int cd_vcol_offset;
int cd_origco_offset;
int cd_origno_offset;
int cd_origvcol_offset;
float planes[6][4];
int num_planes;

View File

@ -234,7 +234,7 @@ static BLI_freenode *mempool_chunk_add(BLI_mempool *pool,
while (j--) {
curnode->next = NODE_STEP_NEXT(curnode);
BLI_freenode *next = curnode->next;
//BLI_asan_poison(curnode, pool->esize);
////BLI_asan_poison(curnode, pool->esize);
curnode = next;
}
}
@ -451,7 +451,7 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
j = pool->pchunk;
while (j--) {
BLI_freenode *next ; NODE_STEP_NEXT(curnode);
BLI_freenode *next = NODE_STEP_NEXT(curnode);
curnode->next = next;
//BLI_asan_poison(curnode, pool->esize);
curnode = next;

View File

@ -112,10 +112,12 @@ typedef struct {
short no[3];
char hflag;
float mask;
void *customdata;
} BMLogVert;
typedef struct {
uint v_ids[3];
void *customdata[3];
char hflag;
} BMLogFace;

View File

@ -1325,6 +1325,8 @@ void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, Scul
memset(data, 0, sizeof(*data));
data->unode = unode;
data->pbvh = ss->pbvh;
if (bm) {
data->bm_log = ss->bm_log;
}
@ -1354,7 +1356,10 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter
{
if (orig_data->unode->type == SCULPT_UNDO_COORDS) {
if (orig_data->bm_log) {
BM_log_original_vert_data(orig_data->bm_log, iter->bm_vert, &orig_data->co, &orig_data->no);
BKE_pbvh_bmesh_update_origvert(
orig_data->pbvh, iter->bm_vert, &orig_data->co, &orig_data->no, NULL);
// BM_log_original_vert_data(orig_data->bm_log, iter->bm_vert, &orig_data->co,
// &orig_data->no);
}
else {
orig_data->co = orig_data->coords[iter->i];
@ -1362,7 +1367,12 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter
}
}
else if (orig_data->unode->type == SCULPT_UNDO_COLOR) {
orig_data->col = orig_data->colors[iter->i];
if (orig_data->bm_log) {
BKE_pbvh_bmesh_update_origvert(orig_data->pbvh, iter->bm_vert, NULL, NULL, &orig_data->col);
}
else {
orig_data->col = orig_data->colors[iter->i];
}
}
else if (orig_data->unode->type == SCULPT_UNDO_MASK) {
if (orig_data->bm_log) {
@ -5751,11 +5761,8 @@ 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 (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) {
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR) &&
!ELEM(type, PBVH_BMESH, PBVH_FACES)) {
return;
}

View File

@ -154,6 +154,8 @@ static void sculpt_boundary_index_add(SculptSession *ss,
{
boundary->vertices[boundary->num_vertices] = new_index;
boundary->vertex_indices[boundary->num_vertices] = BKE_pbvh_vertex_index_to_table(ss->pbvh, new_index);
if (boundary->distance) {
boundary->distance[BKE_pbvh_vertex_index_to_table(ss->pbvh, new_index)] = distance;
}

View File

@ -128,6 +128,7 @@ void SCULPT_dyntopo_save_origverts(SculptSession *ss)
static char layer_id[] = "_dyntopo_node_id";
static char origco_id[] = "_dyntopop_orig_co";
static char origno_id[] = "_dyntopop_orig_no";
static char origcolor_id[] = "_dyntopo_orig_vcol";
void SCULPT_dyntopo_node_layers_update_offsets(SculptSession *ss)
{
@ -138,7 +139,17 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
{
int cd_node_layer_index, cd_face_node_layer_index;
int cd_origco_index, cd_origno_index;
int cd_origco_index, cd_origno_index, cd_origvcol_index = -1;
bool have_vcol = CustomData_has_layer(&ss->bm->vdata, CD_PROP_COLOR);
if (have_vcol) {
cd_origvcol_index = CustomData_get_named_layer_index(
&ss->bm->vdata, CD_PROP_COLOR, origcolor_id);
if (cd_origvcol_index == -1) {
BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_COLOR, origcolor_id);
}
}
cd_origco_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3, origco_id);
if (cd_origco_index == -1) {
@ -168,6 +179,17 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
cd_face_node_layer_index = CustomData_get_named_layer_index(
&ss->bm->pdata, CD_PROP_INT32, layer_id);
if (have_vcol) {
cd_origvcol_index = CustomData_get_named_layer_index(
&ss->bm->vdata, CD_PROP_COLOR, origcolor_id);
ss->cd_origvcol_offset = CustomData_get_n_offset(
&ss->bm->vdata,
CD_PROP_COLOR,
cd_origvcol_index - CustomData_get_layer_index(&ss->bm->vdata, CD_PROP_COLOR));
ss->bm->vdata.layers[cd_origvcol_index].flag |= CD_FLAG_TEMPORARY;
}
ss->cd_origco_offset = CustomData_get_n_offset(
&ss->bm->vdata,
CD_PROP_FLOAT3,
@ -224,6 +246,10 @@ void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me)
CustomData *data1 = cd1[i];
CustomData *data2 = cd2[i];
if (!data1->layers) {
continue;
}
for (int j = 0; j < data1->totlayer; j++) {
CustomDataLayer *cl1 = data1->layers + j;
int idx = CustomData_get_named_layer_index(data2, cl1->type, cl1->name);
@ -285,7 +311,8 @@ void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me)
ss->cd_vert_node_offset,
ss->cd_face_node_offset,
ss->cd_origco_offset,
ss->cd_origno_offset);
ss->cd_origno_offset,
ss->cd_origvcol_offset);
}
}

View File

@ -236,6 +236,7 @@ typedef struct {
const short *no;
float mask;
const float *col;
struct PBVH *pbvh;
} SculptOrigVertData;
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node);

View File

@ -1211,7 +1211,9 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
* original positions are logged. */
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
{
BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
void *dummy;
BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, &dummy, &dummy, &dummy);
//BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
}
BKE_pbvh_vertex_iter_end;
break;

View File

@ -1094,10 +1094,12 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
MPropCol *mp = BM_ELEM_CD_GET_VOID_P(l[i]->v, cd_vcol_offset);
ushort vcol[4];
vcol[0] = (ushort)(mp->color[0] * 65535.0f);
vcol[1] = (ushort)(mp->color[1] * 65535.0f);
vcol[2] = (ushort)(mp->color[2] * 65535.0f);
vcol[3] = (ushort)(mp->color[3] * 65535.0f);
//printf(
// "%.2f %.2f %.2f %.2f\n", mp->color[0], mp->color[1], mp->color[2], mp->color[3]);
vcol[0] = unit_float_to_ushort_clamp(mp->color[0]);
vcol[1] = unit_float_to_ushort_clamp(mp->color[1]);
vcol[2] = unit_float_to_ushort_clamp(mp->color[2]);
vcol[3] = unit_float_to_ushort_clamp(mp->color[3]);
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, v_index, vcol);
}