Multires: Copy mask from sculpt to multires
Allows to paint mask in sculpt mode, then go out of sculpt mode, come back and see proper mask.
This commit is contained in:
parent
b32832a7e8
commit
cec4c77719
|
@ -153,6 +153,7 @@ typedef struct MultiresReshapeContext {
|
|||
Object *object;
|
||||
const Mesh *coarse_mesh;
|
||||
MDisps *mdisps;
|
||||
GridPaintMask *grid_paint_mask;
|
||||
/* NOTE: This is a grid size on the top level, same for level. */
|
||||
int grid_size;
|
||||
int level;
|
||||
|
@ -192,6 +193,36 @@ static void multires_reshape_ensure_displacement_grids(
|
|||
}
|
||||
}
|
||||
|
||||
static void multires_reshape_ensure_mask_grids(
|
||||
MultiresReshapeContext *ctx)
|
||||
{
|
||||
if (ctx->grid_paint_mask == NULL) {
|
||||
return;
|
||||
}
|
||||
const int num_grids = ctx->coarse_mesh->totloop;
|
||||
const int grid_level = ctx->level;
|
||||
const int grid_area = ctx->grid_size * ctx->grid_size;
|
||||
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
|
||||
GridPaintMask *grid_paint_mask = &ctx->grid_paint_mask[grid_index];
|
||||
if (grid_paint_mask->level == grid_level) {
|
||||
continue;
|
||||
}
|
||||
grid_paint_mask->level = grid_level;
|
||||
if (grid_paint_mask->data) {
|
||||
MEM_freeN(grid_paint_mask->data);
|
||||
}
|
||||
grid_paint_mask->data = MEM_calloc_arrayN(
|
||||
grid_area, sizeof(float), "gpm.data");
|
||||
}
|
||||
}
|
||||
|
||||
static void multires_reshape_ensure_grids(
|
||||
MultiresReshapeContext *ctx)
|
||||
{
|
||||
multires_reshape_ensure_displacement_grids(ctx);
|
||||
multires_reshape_ensure_mask_grids(ctx);
|
||||
}
|
||||
|
||||
static void multires_reshape_vertex_copy_to_next(
|
||||
MultiresReshapeContext *ctx,
|
||||
const MPoly *coarse_poly,
|
||||
|
@ -276,13 +307,13 @@ static void copy_boundary_displacement(
|
|||
}
|
||||
}
|
||||
|
||||
static void multires_reshape_vertex_from_final_coord(
|
||||
static void multires_reshape_vertex_from_final_data(
|
||||
MultiresReshapeContext *ctx,
|
||||
const int ptex_face_index,
|
||||
const float u, const float v,
|
||||
const int coarse_poly_index,
|
||||
const int coarse_corner,
|
||||
const float final_P[3])
|
||||
const float final_P[3], const float final_mask)
|
||||
{
|
||||
Subdiv *subdiv = ctx->subdiv;
|
||||
const int grid_size = ctx->grid_size;
|
||||
|
@ -297,19 +328,26 @@ static void multires_reshape_vertex_from_final_coord(
|
|||
/* Get coordinate and corner configuration. */
|
||||
float grid_u, grid_v;
|
||||
MDisps *displacement_grid;
|
||||
GridPaintMask *grid_paint_mask = NULL;
|
||||
int face_corner = coarse_corner;
|
||||
int grid_corner = 0;
|
||||
int grid_index;
|
||||
if (coarse_poly->totloop == 4) {
|
||||
float corner_u, corner_v;
|
||||
face_corner = rotate_quad_to_corner(u, v, &corner_u, &corner_v);
|
||||
grid_corner = face_corner;
|
||||
displacement_grid = &ctx->mdisps[loop_index + face_corner];
|
||||
grid_index = loop_index + face_corner;
|
||||
ptex_uv_to_grid_uv(corner_u, corner_v, &grid_u, &grid_v);
|
||||
}
|
||||
else {
|
||||
displacement_grid = &ctx->mdisps[loop_index];
|
||||
grid_index = loop_index;
|
||||
ptex_uv_to_grid_uv(u, v, &grid_u, &grid_v);
|
||||
}
|
||||
displacement_grid = &ctx->mdisps[grid_index];
|
||||
if (ctx->grid_paint_mask != NULL) {
|
||||
grid_paint_mask = &ctx->grid_paint_mask[grid_index];
|
||||
BLI_assert(grid_paint_mask->level == displacement_grid->level);
|
||||
}
|
||||
/* Convert object coordinate to a tangent space of displacement grid. */
|
||||
float D[3];
|
||||
sub_v3_v3v3(D, final_P, P);
|
||||
|
@ -324,6 +362,10 @@ static void multires_reshape_vertex_from_final_coord(
|
|||
const int grid_y = (grid_v * (grid_size - 1) + 0.5f);
|
||||
const int index = grid_y * grid_size + grid_x;
|
||||
copy_v3_v3(displacement_grid->disps[index], tangent_D);
|
||||
/* Write mask grid. */
|
||||
if (grid_paint_mask != NULL) {
|
||||
grid_paint_mask->data[index] = final_mask;
|
||||
}
|
||||
/* Copy boundary to the next/previous grids */
|
||||
copy_boundary_displacement(
|
||||
ctx, coarse_poly, face_corner, grid_x, grid_y, displacement_grid);
|
||||
|
@ -579,12 +621,12 @@ static void multires_reshape_vertex(
|
|||
const int subdiv_vertex_index)
|
||||
{
|
||||
const float *final_P = ctx->deformed_verts[subdiv_vertex_index];
|
||||
multires_reshape_vertex_from_final_coord(
|
||||
multires_reshape_vertex_from_final_data(
|
||||
&ctx->reshape_ctx,
|
||||
ptex_face_index, u, v,
|
||||
coarse_poly_index,
|
||||
coarse_corner,
|
||||
final_P);
|
||||
final_P, 0.0f);
|
||||
}
|
||||
|
||||
static void multires_reshape_vertex_inner(
|
||||
|
@ -677,6 +719,7 @@ static bool multires_reshape_from_vertcos(
|
|||
.object = object,
|
||||
.coarse_mesh = coarse_mesh,
|
||||
.mdisps = mdisps,
|
||||
.grid_paint_mask = NULL,
|
||||
/* TODO(sergey): Use grid_size_for_level_get */
|
||||
.grid_size = (1 << (mmd->totlvl - 1)) + 1,
|
||||
.level = mmd->totlvl,
|
||||
|
@ -692,8 +735,7 @@ static bool multires_reshape_from_vertcos(
|
|||
.user_data = &reshape_deformed_verts_ctx,
|
||||
};
|
||||
/* Make sure displacement grids are ready. */
|
||||
multires_reshape_ensure_displacement_grids(
|
||||
&reshape_deformed_verts_ctx.reshape_ctx);
|
||||
multires_reshape_ensure_grids(&reshape_deformed_verts_ctx.reshape_ctx);
|
||||
/* Initialize subdivision surface. */
|
||||
Subdiv *subdiv = multires_subdiv_for_reshape(depsgraph, object, mmd);
|
||||
if (subdiv == NULL) {
|
||||
|
@ -863,13 +905,17 @@ static void reshape_from_ccg_regular_face(ReshapeFromCCGTaskData *data,
|
|||
key_grid_size_1 * grid_u,
|
||||
key_grid_size_1 * grid_v);
|
||||
const float *final_P = CCG_elem_co(key, grid_element);
|
||||
multires_reshape_vertex_from_final_coord(
|
||||
float final_mask = 0.0f;
|
||||
if (key->has_mask) {
|
||||
final_mask = *CCG_elem_mask(key, grid_element);
|
||||
}
|
||||
multires_reshape_vertex_from_final_data(
|
||||
&data->reshape_ctx,
|
||||
ptex_face_index,
|
||||
u, v,
|
||||
coarse_poly_index,
|
||||
0,
|
||||
final_P);
|
||||
final_P, final_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -902,13 +948,17 @@ static void reshape_from_ccg_special_face(ReshapeFromCCGTaskData *data,
|
|||
key_grid_size_1 * grid_u,
|
||||
key_grid_size_1 * grid_v);
|
||||
const float *final_P = CCG_elem_co(key, grid_element);
|
||||
multires_reshape_vertex_from_final_coord(
|
||||
float final_mask = 0.0f;
|
||||
if (key->has_mask) {
|
||||
final_mask = *CCG_elem_mask(key, grid_element);
|
||||
}
|
||||
multires_reshape_vertex_from_final_data(
|
||||
&data->reshape_ctx,
|
||||
ptex_face_index + corner,
|
||||
u, v,
|
||||
coarse_poly_index,
|
||||
corner,
|
||||
final_P);
|
||||
final_P, final_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -945,6 +995,8 @@ bool multiresModifier_reshapeFromCCG(
|
|||
return false;
|
||||
}
|
||||
MDisps *mdisps = CustomData_get_layer(&coarse_mesh->ldata, CD_MDISPS);
|
||||
GridPaintMask *grid_paint_mask =
|
||||
CustomData_get_layer(&coarse_mesh->ldata, CD_GRID_PAINT_MASK);
|
||||
Subdiv *subdiv = subdiv_ccg->subdiv;
|
||||
ReshapeFromCCGTaskData data = {
|
||||
.reshape_ctx = {
|
||||
|
@ -952,6 +1004,7 @@ bool multiresModifier_reshapeFromCCG(
|
|||
.object = object,
|
||||
.coarse_mesh = coarse_mesh,
|
||||
.mdisps = mdisps,
|
||||
.grid_paint_mask = grid_paint_mask,
|
||||
/* TODO(sergey): Use grid_size_for_level_get */
|
||||
.grid_size = (1 << (mmd->totlvl - 1)) + 1,
|
||||
.level = mmd->totlvl},
|
||||
|
@ -959,7 +1012,7 @@ bool multiresModifier_reshapeFromCCG(
|
|||
.key = &key,
|
||||
.grids = subdiv_ccg->grids};
|
||||
/* Make sure displacement grids are ready. */
|
||||
multires_reshape_ensure_displacement_grids(&data.reshape_ctx);
|
||||
multires_reshape_ensure_grids(&data.reshape_ctx);
|
||||
/* Initialize propagation to higher levels. */
|
||||
MultiresPropagateData propagate_data;
|
||||
multires_reshape_propagate_prepare(
|
||||
|
|
Loading…
Reference in New Issue