diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-21 12:43:42 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-21 12:43:42 +0300 |
commit | 12372e8d8b0e2c6015b8f68fb01e5aef9b5c22cd (patch) | |
tree | c8d8835e1eaedb86f5b49cab1577630cd92a6a89 /source | |
parent | 619c55027f718c1018051da41bcd89943445e663 (diff) |
Multires: Support sculpting on a lover levels
Added propagation of displacement to a higher levels.
Has the same limitation as reshape from object, which makes
grids somewhat choppy due to linear interpolation nature.
This is to be addressed next.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_multires.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires_reshape.c | 62 |
3 files changed, 45 insertions, 28 deletions
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 26173643cbf..eb6d6151254 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -129,7 +129,8 @@ bool multiresModifier_reshapeFromDeformModifier( struct Object *ob, struct ModifierData *md); bool multiresModifier_reshapeFromCCG( - struct Object *dst, + struct MultiresModifierData *mmd, + struct Object *object, struct SubdivCCG *subdiv_ccg); /* Subdivision integration, defined in multires_subdiv.c */ diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 0a6d7f99237..abd4e0d9e7f 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -422,10 +422,12 @@ void multires_force_update(Object *ob) if (ob == NULL) { return; } - if (ob->sculpt && ob->sculpt->pbvh) { - PBVH *pbvh = ob->sculpt->pbvh; + SculptSession *sculpt_session = ob->sculpt; + if (sculpt_session != NULL && sculpt_session->pbvh != NULL) { + PBVH *pbvh = sculpt_session->pbvh; if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) { - multiresModifier_reshapeFromCCG(ob, ob->sculpt->subdiv_ccg); + multiresModifier_reshapeFromCCG( + sculpt_session->multires, ob, sculpt_session->subdiv_ccg); } else { /* NOTE: Disabled for until OpenSubdiv is enabled by default. */ diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c index 63def8055b0..cd92b4b77da 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.c @@ -153,9 +153,9 @@ typedef struct MultiresReshapeContext { Object *object; const Mesh *coarse_mesh; MDisps *mdisps; - /* NOTE: This is a grid size on th top level. */ + /* NOTE: This is a grid size on the top level, same for level. */ int grid_size; - int top_level; + int level; } MultiresReshapeContext; static void multires_reshape_allocate_displacement_grid( @@ -185,7 +185,7 @@ static void multires_reshape_ensure_displacement_grids( MultiresReshapeContext *ctx) { const int num_grids = ctx->coarse_mesh->totloop; - const int grid_level = ctx->top_level; + const int grid_level = ctx->level; for (int grid_index = 0; grid_index < num_grids; grid_index++) { multires_reshape_ensure_displacement_grid( &ctx->mdisps[grid_index], grid_level); @@ -679,7 +679,7 @@ static bool multires_reshape_from_vertcos( .mdisps = mdisps, /* TODO(sergey): Use grid_size_for_level_get */ .grid_size = (1 << (mmd->totlvl - 1)) + 1, - .top_level = mmd->totlvl, + .level = mmd->totlvl, }, .deformed_verts = deformed_verts, .num_deformed_verts = num_deformed_verts, @@ -705,9 +705,9 @@ static bool multires_reshape_from_vertcos( BKE_multires_subdiv_mesh_settings_init( &mesh_settings, scene_eval, object, mmd, use_render_params, true); /* Initialize propagation to higher levels. */ - MultiresPropagateData data; + MultiresPropagateData propagate_data; multires_reshape_propagate_prepare_from_mmd( - &data, depsgraph, object, mmd, use_render_params); + &propagate_data, depsgraph, object, mmd, use_render_params); /* Run all the callbacks. */ BKE_subdiv_foreach_subdiv_geometry( subdiv, @@ -715,8 +715,9 @@ static bool multires_reshape_from_vertcos( &mesh_settings, coarse_mesh); BKE_subdiv_free(subdiv); - multires_reshape_propagate(&data); - multires_reshape_propagate_free(&data); + /* Update higher levels if needed. */ + multires_reshape_propagate(&propagate_data); + multires_reshape_propagate_free(&propagate_data); return true; } @@ -839,9 +840,9 @@ static void reshape_from_ccg_regular_face(ReshapeFromCCGTaskData *data, /*const*/ CCGElem **grids = data->grids; const Mesh *coarse_mesh = data->reshape_ctx.coarse_mesh; const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const int grid_size = data->reshape_ctx.grid_size; - const int grid_size_1 = grid_size - 1; - const int resolution = 2 * grid_size - 1; + const int key_grid_size = key->grid_size; + const int key_grid_size_1 = key_grid_size - 1; + const int resolution = 2 * key_grid_size - 1; const float resolution_1_inv = 1.0f / (float)(resolution - 1); const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = data->face_ptex_offset[coarse_poly_index]; @@ -857,7 +858,10 @@ static void reshape_from_ccg_regular_face(ReshapeFromCCGTaskData *data, /*const*/ CCGElem *grid = grids[coarse_poly->loopstart + face_corner]; /*const*/ CCGElem *grid_element = CCG_grid_elem( - key, grid, grid_size_1 * grid_u, grid_size_1 * grid_v); + key, + grid, + 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( &data->reshape_ctx, @@ -877,9 +881,9 @@ static void reshape_from_ccg_special_face(ReshapeFromCCGTaskData *data, /*const*/ CCGElem **grids = data->grids; const Mesh *coarse_mesh = data->reshape_ctx.coarse_mesh; const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const int grid_size = data->reshape_ctx.grid_size; - const int grid_size_1 = grid_size - 1; - const int resolution = grid_size; + const int key_grid_size = key->grid_size; + const int key_grid_size_1 = key_grid_size - 1; + const int resolution = key_grid_size; const float resolution_1_inv = 1.0f / (float)(resolution - 1); const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = data->face_ptex_offset[coarse_poly_index]; @@ -893,7 +897,10 @@ static void reshape_from_ccg_special_face(ReshapeFromCCGTaskData *data, /*const*/ CCGElem *grid = grids[coarse_poly->loopstart + corner]; /*const*/ CCGElem *grid_element = CCG_grid_elem( - key, grid, grid_size_1 * grid_u, grid_size_1 * grid_v); + key, + grid, + 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( &data->reshape_ctx, @@ -925,9 +932,11 @@ static void reshape_from_ccg_task( } bool multiresModifier_reshapeFromCCG( - Object *dst, SubdivCCG *subdiv_ccg) + MultiresModifierData *mmd, + Object *object, + SubdivCCG *subdiv_ccg) { - Mesh *coarse_mesh = dst->data; + Mesh *coarse_mesh = object->data; CCGKey key; BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg); /* Sanity checks. */ @@ -936,23 +945,25 @@ bool multiresModifier_reshapeFromCCG( return false; } MDisps *mdisps = CustomData_get_layer(&coarse_mesh->ldata, CD_MDISPS); - /* TODO(sergey): Key has grid size for the current level. Need to access top - * level somehow. - */ Subdiv *subdiv = subdiv_ccg->subdiv; ReshapeFromCCGTaskData data = { .reshape_ctx = { .subdiv = subdiv, - .object = dst, + .object = object, .coarse_mesh = coarse_mesh, .mdisps = mdisps, - .grid_size = key.grid_size, - .top_level = key.level}, + /* TODO(sergey): Use grid_size_for_level_get */ + .grid_size = (1 << (mmd->totlvl - 1)) + 1, + .level = mmd->totlvl}, .face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv), .key = &key, .grids = subdiv_ccg->grids}; /* Make sure displacement grids are ready. */ multires_reshape_ensure_displacement_grids(&data.reshape_ctx); + /* Initialize propagation to higher levels. */ + MultiresPropagateData propagate_data; + multires_reshape_propagate_prepare( + &propagate_data, object, key.level, mmd->totlvl); /* Threaded grids iteration. */ ParallelRangeSettings parallel_range_settings; BLI_parallel_range_settings_defaults(¶llel_range_settings); @@ -960,5 +971,8 @@ bool multiresModifier_reshapeFromCCG( &data, reshape_from_ccg_task, ¶llel_range_settings); + /* Update higher levels if needed. */ + multires_reshape_propagate(&propagate_data); + multires_reshape_propagate_free(&propagate_data); return true; } |