diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-11-02 17:23:06 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-11-02 17:24:54 +0300 |
commit | c7d20949fb57c2f7e2801361305bfc8c8a6af5ea (patch) | |
tree | 95f4cab9ddfd2fc2c7c2266c732c3ac830a3c8e1 /source/blender/blenkernel/intern/multires.c | |
parent | c75a25e9e16692dde2efe902aba2b4a834eec8fe (diff) |
Multires: Apply uniform scale on displacement when applying scale on object
This is sued by both object joinig and object apply scale operations.
Currently only uniform scale is working correct. Non-uniform gets averaged
and will produce slightly distorted results. This is something we should
fix, but priority of this particular case is not so high.
Diffstat (limited to 'source/blender/blenkernel/intern/multires.c')
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 0138cd4cfff..8f02b51fd5f 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -2125,9 +2125,46 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) } } -static void multires_apply_smat(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float smat[3][3]) +static void multires_apply_uniform_scale(Object *object, const float scale) +{ + Mesh *mesh = (Mesh *)object->data; + MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); + for (int i = 0; i < mesh->totloop; ++i) { + MDisps *grid = &mdisps[i]; + for (int j = 0; j < grid->totdisp; ++j) { + mul_v3_fl(grid->disps[j], scale); + } + } +} + +static void multires_apply_smat( + struct Depsgraph *UNUSED(depsgraph), + Scene *scene, + Object *object, + float smat[3][3]) { - UNUSED_VARS(depsgraph, scene, ob, smat); + const MultiresModifierData *mmd = get_multires_modifier(scene, object, true); + if (mmd == NULL || mmd->totlvl == 0) { + return; + } + /* Make sure layer present. */ + Mesh *mesh = (Mesh *)object->data; + CustomData_external_read( + &mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop); + if (!CustomData_get_layer(&mesh->ldata, CD_MDISPS)) { + return; + } + if (is_uniform_scaled_m3(smat)) { + const float scale = mat3_to_scale(smat); + multires_apply_uniform_scale(object, scale); + } + else { + /* TODO(sergey): This branch of code actually requires more work to + * preserve all the details. + */ + const float scale = mat3_to_scale(smat); + multires_apply_uniform_scale(object, scale); + } } int multires_mdisp_corners(MDisps *s) |