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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2020-03-17 19:34:04 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2020-03-17 19:40:54 +0300
commitf958560a990a8974446c2c63def7ba387dcfb275 (patch)
treedcb00295a6a75e2c6268424eb92a7e598efe7ba5 /source
parent1504cb26b0aa4e91b5c0ec432d2702d9e9c5275f (diff)
Multires: Properly support virtual modifiers for Apply Base
The initial code from earlier from today didn't really work reliable since it is not possible to apply virtual modifiers but not the real multires one (in a situation like mesh with shapekeys and multires). New code uses less memory and has better performance for the case when there are actual modifiers leading the multires. The case when there is only multires will not be as performant as possible at this moment.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_multires.h9
-rw-r--r--source/blender/blenkernel/intern/multires.c50
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_apply_base.c19
3 files changed, 53 insertions, 25 deletions
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index cccb5547603..a7a5e7b8bd5 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -96,11 +96,12 @@ struct Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
struct Object *object,
struct MultiresModifierData *mmd);
-/* Creates mesh with all deform modifiers leading the multires one applied.
+/* Get coordinates of a deformed base mesh which is an ionput to the given multires modifier.
* NOTE: The modifiers will be re-evaluated. */
-struct Mesh *BKE_multires_create_deformed_base_mesh(struct Depsgraph *depsgraph,
- struct Object *object,
- struct MultiresModifierData *mmd);
+float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *depsgraph,
+ struct Object *object,
+ struct MultiresModifierData *mmd,
+ int *r_num_deformed_verts))[3];
void multiresModifier_del_levels(struct MultiresModifierData *mmd,
struct Scene *scene,
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index fd91f80b047..234273b5158 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -293,23 +293,55 @@ Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
return result;
}
-Mesh *BKE_multires_create_deformed_base_mesh(struct Depsgraph *depsgraph,
- Object *object,
- MultiresModifierData *mmd)
+float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *depsgraph,
+ struct Object *object,
+ struct MultiresModifierData *mmd,
+ int *r_num_deformed_verts))[3]
{
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
- const int mmd_index = BLI_findindex(&object->modifiers, &mmd->modifier);
- BLI_assert(mmd_index != -1);
-
Object object_for_eval = *object_eval;
object_for_eval.data = object->data;
- Mesh *base_mesh = mesh_create_eval_final_view_index(
- depsgraph, scene_eval, object, &CD_MASK_BAREMESH, mmd_index - 1);
+ const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ ModifierEvalContext mesh_eval_context = {depsgraph, &object_for_eval, 0};
+ if (use_render) {
+ mesh_eval_context.flag |= MOD_APPLY_RENDER;
+ }
+ const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+
+ VirtualModifierData virtual_modifier_data;
+ ModifierData *first_md = modifiers_getVirtualModifierList(&object_for_eval,
+ &virtual_modifier_data);
+
+ Mesh *base_mesh = object->data;
+
+ int num_deformed_verts;
+ float(*deformed_verts)[3] = BKE_mesh_vert_coords_alloc(base_mesh, &num_deformed_verts);
+
+ for (ModifierData *md = first_md; md != NULL; md = md->next) {
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (md == &mmd->modifier) {
+ break;
+ }
+
+ if (!modifier_isEnabled(scene_eval, md, required_mode)) {
+ continue;
+ }
- return base_mesh;
+ if (mti->type != eModifierTypeType_OnlyDeform) {
+ break;
+ }
+
+ modwrap_deformVerts(md, &mesh_eval_context, base_mesh, deformed_verts, num_deformed_verts);
+ }
+
+ if (r_num_deformed_verts != NULL) {
+ *r_num_deformed_verts = num_deformed_verts;
+ }
+ return deformed_verts;
}
MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
index 958fb60bbdc..62418150ff1 100644
--- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c
+++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
@@ -189,16 +189,11 @@ void multires_reshape_apply_base_refine_from_deform(MultiresReshapeContext *resh
BLI_assert(object != NULL);
BLI_assert(mmd != NULL);
- /* If there are no modifiers prior to the multires can use base mesh as it have all the updated
- * vertices already. */
- if (mmd->modifier.prev == NULL) {
- BKE_subdiv_eval_update_from_mesh(reshape_context->subdiv, reshape_context->base_mesh, NULL);
- }
- else {
- /* TODO(sergey): Possible optimization is to only evaluate new verticies positions without
- * construction of the entire mesh. */
- Mesh *deformed_base_mesh = BKE_multires_create_deformed_base_mesh(depsgraph, object, mmd);
- BKE_subdiv_eval_update_from_mesh(reshape_context->subdiv, deformed_base_mesh, NULL);
- BKE_id_free(NULL, deformed_base_mesh);
- }
+ float(*deformed_verts)[3] = BKE_multires_create_deformed_base_mesh_vert_coords(
+ depsgraph, object, mmd, NULL);
+
+ BKE_subdiv_eval_update_from_mesh(
+ reshape_context->subdiv, reshape_context->base_mesh, deformed_verts);
+
+ MEM_freeN(deformed_verts);
}