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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-09-21 16:30:55 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-09-21 16:31:44 +0300
commit5ee0200d439f5b5697541bb8e7d6ec945c86298e (patch)
treec30764439830190afd3d4e56135a1ad1536dfb0c /source/blender
parentcec4c77719905ccbfdc4c34f0f4925f120b56758 (diff)
Multires: Support masks propagation to higher levels
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.c207
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c12
2 files changed, 158 insertions, 61 deletions
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index f0757a492c9..c051ea3ea22 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -228,21 +228,30 @@ static void multires_reshape_vertex_copy_to_next(
const MPoly *coarse_poly,
const int current_corner,
const MDisps *current_displacement_grid,
+ const GridPaintMask *current_mask_grid,
const int current_grid_x, const int current_grid_y)
{
const int grid_size = ctx->grid_size;
const int next_current_corner = (current_corner + 1) % coarse_poly->totloop;
- MDisps *next_displacement_grid = &ctx->mdisps[
- coarse_poly->loopstart + next_current_corner];
const int next_grid_x = 0;
const int next_grid_y = current_grid_x;
const int current_index = current_grid_y * grid_size + current_grid_x;
const int next_index = next_grid_y * grid_size + next_grid_x;
+ /* Copy displacement. */
+ MDisps *next_displacement_grid = &ctx->mdisps[
+ coarse_poly->loopstart + next_current_corner];
float *next_displacement = next_displacement_grid->disps[next_index];
copy_v3_v3(next_displacement,
current_displacement_grid->disps[current_index]);
SWAP(float, next_displacement[0], next_displacement[1]);
next_displacement[0] = -next_displacement[0];
+ /* Copy mask, if exists. */
+ if (current_mask_grid != NULL) {
+ GridPaintMask *next_mask_grid = &ctx->grid_paint_mask[
+ coarse_poly->loopstart + next_current_corner];
+ next_mask_grid->data[next_index] =
+ current_mask_grid->data[current_index];
+ }
}
static void multires_reshape_vertex_copy_to_prev(
@@ -250,22 +259,31 @@ static void multires_reshape_vertex_copy_to_prev(
const MPoly *coarse_poly,
const int current_corner,
const MDisps *current_displacement_grid,
+ const GridPaintMask *current_mask_grid,
const int current_grid_x, const int current_grid_y)
{
const int grid_size = ctx->grid_size;
const int prev_current_corner =
(current_corner - 1 + coarse_poly->totloop) % coarse_poly->totloop;
- MDisps *prev_displacement_grid = &ctx->mdisps[
- coarse_poly->loopstart + prev_current_corner];
const int prev_grid_x = current_grid_y;
const int prev_grid_y = 0;
const int current_index = current_grid_y * grid_size + current_grid_x;
const int prev_index = prev_grid_y * grid_size + prev_grid_x;
+ /* Copy displacement. */
+ MDisps *prev_displacement_grid = &ctx->mdisps[
+ coarse_poly->loopstart + prev_current_corner];
float *prev_displacement = prev_displacement_grid->disps[prev_index];
copy_v3_v3(prev_displacement,
current_displacement_grid->disps[current_index]);
SWAP(float, prev_displacement[0], prev_displacement[1]);
prev_displacement[1] = -prev_displacement[1];
+ /* Copy mask, if exists. */
+ if (current_mask_grid != NULL) {
+ GridPaintMask *prev_mask_grid = &ctx->grid_paint_mask[
+ coarse_poly->loopstart + prev_current_corner];
+ prev_mask_grid->data[prev_index] =
+ current_mask_grid->data[current_index];
+ }
}
static void copy_boundary_displacement(
@@ -273,19 +291,24 @@ static void copy_boundary_displacement(
const MPoly *coarse_poly,
const int corner,
const int grid_x, const int grid_y,
- const MDisps *displacement_grid)
+ const MDisps *displacement_grid,
+ const GridPaintMask *mask_grid)
{
if (grid_x == 0 && grid_y == 0) {
for (int i = 0; i < coarse_poly->totloop; i++) {
const int current_face_corner =
(corner + i) % coarse_poly->totloop;
- MDisps *current_displacement_grid = &ctx->mdisps[
- coarse_poly->loopstart + current_face_corner];
+ const int grid_index = coarse_poly->loopstart + current_face_corner;
+ MDisps *current_displacement_grid = &ctx->mdisps[grid_index];
+ GridPaintMask *current_mask_grid =
+ mask_grid != NULL ? &ctx->grid_paint_mask[grid_index]
+ : NULL;
multires_reshape_vertex_copy_to_next(
ctx,
coarse_poly,
current_face_corner,
current_displacement_grid,
+ current_mask_grid,
0, 0);
}
}
@@ -295,6 +318,7 @@ static void copy_boundary_displacement(
coarse_poly,
corner,
displacement_grid,
+ mask_grid,
grid_x, grid_y);
}
else if (grid_y == 0) {
@@ -303,6 +327,7 @@ static void copy_boundary_displacement(
coarse_poly,
corner,
displacement_grid,
+ mask_grid,
grid_x, grid_y);
}
}
@@ -368,7 +393,8 @@ static void multires_reshape_vertex_from_final_data(
}
/* Copy boundary to the next/previous grids */
copy_boundary_displacement(
- ctx, coarse_poly, face_corner, grid_x, grid_y, displacement_grid);
+ ctx, coarse_poly, face_corner, grid_x, grid_y,
+ displacement_grid, grid_paint_mask);
}
/* =============================================================================
@@ -383,8 +409,16 @@ typedef struct MultiresPropagateData {
int top_grid_size;
MDisps *old_displacement_grids;
MDisps *new_displacement_grids;
+ GridPaintMask *grid_paint_mask;
} MultiresPropagateData;
+typedef struct MultiresPropagateCornerData {
+ float old_coord[3];
+ float new_coord[3];
+ float coord_delta[3];
+ float mask;
+} MultiresPropagateCornerData;
+
static void multires_reshape_propagate_prepare(
MultiresPropagateData *data,
Object *object,
@@ -423,6 +457,8 @@ static void multires_reshape_propagate_prepare(
data->top_grid_size = (1 << (top_level - 1)) + 1;
data->old_displacement_grids = old_mdisps;
data->new_displacement_grids = mdisps;
+ data->grid_paint_mask =
+ CustomData_get_layer(&coarse_mesh->ldata, CD_GRID_PAINT_MASK);
}
static void multires_reshape_propagate_prepare_from_mmd(
@@ -438,40 +474,97 @@ static void multires_reshape_propagate_prepare_from_mmd(
multires_reshape_propagate_prepare(data, object, level, mmd->totlvl);
}
-static void multires_reshape_propagate_calc_simple_delta(
- float r_delta[3],
+static void multires_reshape_propagate_corner_data(
+ MultiresPropagateCornerData* corner,
const MDisps *old_displacement_grid,
const MDisps *new_displacement_grid,
+ const GridPaintMask *grid_paint_mask,
const int grid_size,
- const int x, const int y)
+ const int grid_skip,
+ const int reshape_x, const int reshape_y)
{
- copy_v3_v3(r_delta, new_displacement_grid->disps[y * grid_size + x]);
+ const int x = reshape_x * grid_skip;
+ const int y = reshape_y * grid_skip;
+ const int grid_index = y * grid_size + x;
if (old_displacement_grid->disps != NULL) {
- sub_v3_v3(r_delta, old_displacement_grid->disps[y * grid_size + x]);
+ copy_v3_v3(corner->old_coord, old_displacement_grid->disps[grid_index]);
+ }
+ else {
+ zero_v3(corner->old_coord);
+ }
+ copy_v3_v3(corner->new_coord, new_displacement_grid->disps[grid_index]);
+ sub_v3_v3v3(corner->coord_delta, corner->new_coord, corner->old_coord);
+ if (grid_paint_mask != NULL) {
+ corner->mask = grid_paint_mask->data[grid_index];
+ }
+ else {
+ corner->mask = 0.0f;
}
}
-static void multires_reshape_propagate_calc_reshape_delta(
- float r_delta[3],
+static void multires_reshape_propagate_all_corners_data(
+ MultiresPropagateCornerData corners[4],
const MDisps *old_displacement_grid,
const MDisps *new_displacement_grid,
+ const GridPaintMask *grid_paint_mask,
const int grid_size,
const int grid_skip,
const int reshape_x, const int reshape_y)
{
- const int x = reshape_x * grid_skip;
- const int y = reshape_y * grid_skip;
- multires_reshape_propagate_calc_simple_delta(
- r_delta,
- old_displacement_grid, new_displacement_grid,
- grid_size,
- x, y);
+ int corner_index = 0;
+ for (int dy = 0; dy <= 1; dy++) {
+ for (int dx = 0; dx <= 1; dx++) {
+ multires_reshape_propagate_corner_data(
+ &corners[corner_index],
+ old_displacement_grid,
+ new_displacement_grid,
+ grid_paint_mask,
+ grid_size,
+ grid_skip,
+ reshape_x + dx, reshape_y + dy);
+ corner_index++;
+ }
+ }
+}
+
+static void multires_reshape_propagate_interpolate_coord(
+ MDisps *new_displacement_grid,
+ const MultiresPropagateCornerData corners[4],
+ const float weights[4],
+ const int x, const int y,
+ const int grid_size)
+{
+ float delta[3];
+ interp_v3_v3v3v3v3(
+ delta,
+ corners[0].coord_delta, corners[1].coord_delta,
+ corners[2].coord_delta, corners[3].coord_delta,
+ weights);
+ const int index = y * grid_size + x;
+ float *new_displacement = new_displacement_grid->disps[index];
+ add_v3_v3(new_displacement, delta);
+}
+
+static void multires_reshape_propagate_interpolate_mask(
+ GridPaintMask *grid_paint_mask,
+ const MultiresPropagateCornerData corners[4],
+ const float weights[4],
+ const int x, const int y,
+ const int grid_size)
+{
+ const int index = y * grid_size + x;
+ grid_paint_mask->data[index] =
+ corners[0].mask * weights[0] +
+ corners[1].mask * weights[1] +
+ corners[2].mask * weights[2] +
+ corners[3].mask * weights[3];
}
static void multires_reshape_propagate_grid(
MultiresPropagateData *data,
const MDisps *old_displacement_grid,
- MDisps *new_displacement_grid)
+ MDisps *new_displacement_grid,
+ GridPaintMask *grid_paint_mask)
{
const int reshape_grid_size = data->reshape_grid_size;
const int top_grid_size = data->top_grid_size;
@@ -485,32 +578,14 @@ static void multires_reshape_propagate_grid(
reshape_x < reshape_grid_size - 1;
reshape_x++)
{
- /* Calculate delta from the reshape. */
- float delta_corners[4][3];
- multires_reshape_propagate_calc_reshape_delta(
- delta_corners[0],
+ MultiresPropagateCornerData corners[4];
+ multires_reshape_propagate_all_corners_data(
+ corners,
old_displacement_grid, new_displacement_grid,
+ grid_paint_mask,
top_grid_size,
grid_skip,
reshape_x, reshape_y);
- multires_reshape_propagate_calc_reshape_delta(
- delta_corners[1],
- old_displacement_grid, new_displacement_grid,
- top_grid_size,
- grid_skip,
- reshape_x + 1, reshape_y);
- multires_reshape_propagate_calc_reshape_delta(
- delta_corners[2],
- old_displacement_grid, new_displacement_grid,
- top_grid_size,
- grid_skip,
- reshape_x + 1, reshape_y + 1);
- multires_reshape_propagate_calc_reshape_delta(
- delta_corners[3],
- old_displacement_grid, new_displacement_grid,
- top_grid_size,
- grid_skip,
- reshape_x, reshape_y + 1);
/* Propagate to higher levels. */
for (int y = 0; y <= grid_skip; y++) {
const float v = (float)y * grid_skip_inv;
@@ -536,20 +611,26 @@ static void multires_reshape_propagate_grid(
continue;
}
const float u = (float)x * grid_skip_inv;
- const float weights[4] = {(1.0f - u) * (1.0f - v),
- u * (1.0f - v),
- u * v,
- (1.0f - u) * v};
- float delta[3];
- interp_v3_v3v3v3v3(
- delta,
- delta_corners[0], delta_corners[1],
- delta_corners[2], delta_corners[3],
- weights);
- float *new_displacement = new_displacement_grid->disps[
- (reshape_y * grid_skip + y) * top_grid_size +
- (reshape_x * grid_skip) + x];
- add_v3_v3(new_displacement, delta);
+ const int final_x = reshape_x * grid_skip + x;
+ const int final_y = reshape_y * grid_skip + y;
+ const float linear_weights[4] = {(1.0f - u) * (1.0f - v),
+ u * (1.0f - v),
+ (1.0f - u) * v,
+ u * v};
+ multires_reshape_propagate_interpolate_coord(
+ new_displacement_grid,
+ corners,
+ linear_weights,
+ final_x, final_y,
+ top_grid_size);
+ if (grid_paint_mask != NULL) {
+ multires_reshape_propagate_interpolate_mask(
+ grid_paint_mask,
+ corners,
+ linear_weights,
+ final_x, final_y,
+ top_grid_size);
+ }
}
}
}
@@ -569,8 +650,14 @@ static void multires_reshape_propagate(MultiresPropagateData *data) {
if (old_displacement_grid->level != new_displacement_grid->level) {
continue;
}
+ GridPaintMask *grid_paint_mask =
+ data->grid_paint_mask != NULL
+ ? &data->grid_paint_mask[grid_index]
+ : NULL;
multires_reshape_propagate_grid(
- data, old_displacement_grid, new_displacement_grid);
+ data, old_displacement_grid,
+ new_displacement_grid,
+ grid_paint_mask);
}
}
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index 5ec675494f5..c05bf8ad76d 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -215,7 +215,7 @@ static void subdiv_ccg_eval_grid_element(
data->mask_evaluator, ptex_face_index, u, v);
}
else {
- *mask_value_ptr = 0;
+ *mask_value_ptr = 0.0f;
}
}
}
@@ -933,6 +933,13 @@ static void average_grid_element(SubdivCCG *subdiv_ccg,
average_grid_element_value_v3(CCG_elem_no(key, grid_element_a),
CCG_elem_no(key, grid_element_b));
}
+ if (subdiv_ccg->has_mask) {
+ float mask =
+ (*CCG_elem_mask(key, grid_element_a) +
+ *CCG_elem_mask(key, grid_element_b)) * 0.5f;
+ *CCG_elem_mask(key, grid_element_a) = mask;
+ *CCG_elem_mask(key, grid_element_b) = mask;
+ }
}
static void copy_grid_element(SubdivCCG *subdiv_ccg,
@@ -944,6 +951,9 @@ static void copy_grid_element(SubdivCCG *subdiv_ccg,
if (subdiv_ccg->has_normal) {
copy_v3_v3(CCG_elem_no(key, destination), CCG_elem_no(key, source));
}
+ if (subdiv_ccg->has_mask) {
+ *CCG_elem_mask(key, destination) = *CCG_elem_mask(key, source);
+ }
}
static void subdiv_ccg_average_inner_face_grids(