diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-20 12:21:45 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-20 16:39:41 +0300 |
commit | 13820ec5c1d3602e546b24d30a0c3e66c08d27ed (patch) | |
tree | 737dad7841503eedf6006fe4f11cd7017590e8cf /source/blender/blenkernel/intern/multires_reshape.c | |
parent | 0a596eda2a654d99a25c2b66ecfde0518e8bedfa (diff) |
Subdiv: CCG, fix crash going from sculpt to edit mode
Was happening for "new" objects, which did not have MDisps
allocated yet.
Diffstat (limited to 'source/blender/blenkernel/intern/multires_reshape.c')
-rw-r--r-- | source/blender/blenkernel/intern/multires_reshape.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c index 530f5388da6..4940ffb1ce6 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.c @@ -155,8 +155,43 @@ typedef struct MultiresReshapeContext { MDisps *mdisps; /* NOTE: This is a grid size on th top level. */ int grid_size; + int top_level; } MultiresReshapeContext; +static void multires_reshape_allocate_displacement_grid( + MDisps *displacement_grid, const int level) +{ + /* TODO(sergey): Use grid_size_for_level_get() somehow. */ + const int grid_size = (1 << (level - 1)) + 1; + const int grid_area = grid_size * grid_size; + float (*disps)[3] = MEM_calloc_arrayN( + grid_area, 3 * sizeof(float), "multires disps"); + displacement_grid->disps = disps; + displacement_grid->totdisp = grid_area; + displacement_grid->level = level; +} + +static void multires_reshape_ensure_displacement_grid( + MDisps *displacement_grid, const int level) +{ + if (displacement_grid->disps != NULL) { + return; + } + multires_reshape_allocate_displacement_grid( + displacement_grid, level); +} + +static void multires_reshape_ensure_displacement_grids( + MultiresReshapeContext *ctx) +{ + const int num_grids = ctx->coarse_mesh->totloop; + const int grid_level = ctx->top_level; + for (int grid_index = 0; grid_index < num_grids; grid_index++) { + multires_reshape_ensure_displacement_grid( + &ctx->mdisps[grid_index], grid_level); + } +} + static void multires_reshape_vertex_copy_to_next( MultiresReshapeContext *ctx, const MPoly *coarse_poly, @@ -425,7 +460,9 @@ static bool multires_reshape_from_vertcos( .object = object, .coarse_mesh = coarse_mesh, .mdisps = mdisps, + /* TODO(sergey): Use grid_size_for_level_get */ .grid_size = (1 << (mmd->totlvl - 1)) + 1, + .top_level = mmd->totlvl, }, .deformed_verts = deformed_verts, .num_deformed_verts = num_deformed_verts, @@ -437,6 +474,9 @@ static bool multires_reshape_from_vertcos( .vertex_every_corner = multires_reshape_vertex_every_corner, .user_data = &reshape_deformed_verts_ctx, }; + /* Make sure displacement grids are ready. */ + multires_reshape_ensure_displacement_grids( + &reshape_deformed_verts_ctx.reshape_ctx); /* Initialize subdivision surface. */ Subdiv *subdiv = multires_subdiv_for_reshape(depsgraph, object, mmd); if (subdiv == NULL) { @@ -673,8 +713,8 @@ bool multiresModifier_reshapeFromCCG( return false; } MDisps *mdisps = CustomData_get_layer(&coarse_mesh->ldata, CD_MDISPS); - /* XXX: Key has grid size for the current level. Need to access top - * top level somehow. + /* TODO(sergey): Key has grid size for the current level. Need to access top + * level somehow. */ Subdiv *subdiv = subdiv_ccg->subdiv; ReshapeFromCCGTaskData data = { @@ -683,10 +723,13 @@ bool multiresModifier_reshapeFromCCG( .object = dst, .coarse_mesh = coarse_mesh, .mdisps = mdisps, - .grid_size = key.grid_size}, + .grid_size = key.grid_size, + .top_level = key.level}, .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); /* Threaded grids iteration. */ ParallelRangeSettings parallel_range_settings; BLI_parallel_range_settings_defaults(¶llel_range_settings); |