diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-30 13:56:20 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-30 15:29:05 +0300 |
commit | 29f9a197088e0e1ea56cae675803f61165d790c1 (patch) | |
tree | f7aca888fbee23933705e213c4f2731883c316f4 | |
parent | da16cb1511f71b552b5746269544ed595e308c29 (diff) |
Modifier stack: Avoid roundtrip from mesh to DM back to mesh
Saves quite a bit of CPU ticks per mesh update, giving measurable
speedup for file from T55228.
Memory usage goes up a it, most likely due to evaluated mesh having
more custom data layers than corresponding DM does.
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 54 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_update.c | 56 |
2 files changed, 52 insertions, 58 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d2a3732a31d..c8d5bb5ffd7 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2916,6 +2916,47 @@ static bool calc_modifiers_skip_orco(Depsgraph *depsgraph, } #endif +static void mesh_finalize_eval(Object *object) +{ + if (!DEG_depsgraph_use_copy_on_write()) { + return; + } + Mesh *mesh = (Mesh *)object->data; + Mesh *mesh_eval = object->runtime.mesh_eval; + /* Special Tweaks for cases when evaluated mesh came from + * BKE_mesh_new_nomain_from_template(). + */ + BLI_strncpy(mesh_eval->id.name, mesh->id.name, sizeof(mesh_eval->id.name)); + if (mesh_eval->mat != NULL) { + MEM_freeN(mesh_eval->mat); + } + mesh_eval->mat = MEM_dupallocN(mesh->mat); + mesh_eval->totcol = mesh->totcol; + /* Make evaluated mesh to share same edit mesh pointer as original + * and copied meshes. + */ + mesh_eval->edit_btmesh = mesh->edit_btmesh; + /* Special flags to help debugging and also to allow copy-on-write core + * to understand that on re-evaluation this mesh is to be preserved and + * to be remapped back to copied original mesh when used as object data. + */ + mesh_eval->id.tag |= LIB_TAG_COPY_ON_WRITE_EVAL; + mesh_eval->id.orig_id = &mesh->id; + /* Copy autosmooth settings from original mesh. + * This is not done by BKE_mesh_new_nomain_from_template(), so need to take + * extra care here. + */ + mesh_eval->flag |= (mesh->flag & ME_AUTOSMOOTH); + mesh_eval->smoothresh = mesh->smoothresh; + /* Replace evaluated object's data with fully evaluated mesh. */ + /* TODO(sergey): There was statement done by Sybren and Mai that this + * caused modifiers to be applied twice. which is weirtd and shouldn't + * really happen. But since there is no reference to the report, can not + * do much about this. + */ + object->data = mesh_eval; +} + static void mesh_build_data( struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask, const bool build_shapekey_layers, const bool need_mapping) @@ -2931,12 +2972,21 @@ static void mesh_build_data( } #endif - mesh_calc_modifiers_dm( + mesh_calc_modifiers( depsgraph, scene, ob, NULL, 1, need_mapping, dataMask, -1, true, build_shapekey_layers, true, - &ob->derivedDeform, &ob->derivedFinal); + &ob->runtime.mesh_deform_eval, &ob->runtime.mesh_eval); + + mesh_finalize_eval(ob); + + ob->derivedDeform = CDDM_from_mesh_ex(ob->runtime.mesh_deform_eval, CD_REFERENCE, CD_MASK_MESH); + ob->derivedFinal = CDDM_from_mesh_ex(ob->runtime.mesh_eval, CD_REFERENCE, CD_MASK_MESH); DM_set_object_boundbox(ob, ob->derivedFinal); + /* TODO(sergey): Convert bounding box calculation to use mesh, then + * we can skip this copy. + */ + BKE_mesh_texspace_copy_from_object(ob->runtime.mesh_eval, ob); ob->derivedFinal->needsFree = 0; ob->derivedDeform->needsFree = 0; diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 5848de3aa87..e953185b726 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -330,62 +330,6 @@ void BKE_object_eval_uber_data(Depsgraph *depsgraph, BKE_mball_batch_cache_dirty(ob->data, BKE_MBALL_BATCH_DIRTY_ALL); break; } - - if (DEG_depsgraph_use_copy_on_write()) { - if (ob->type == OB_MESH) { - /* Quick hack to convert evaluated derivedMesh to Mesh. */ - DerivedMesh *dm = ob->derivedFinal; - if (dm != NULL) { - Mesh *mesh = (Mesh *)ob->data; - Mesh *new_mesh = BKE_libblock_alloc_notest(ID_ME); - BKE_mesh_init(new_mesh); - /* Copy ID name so GS(new_mesh->id) works correct later on. */ - BLI_strncpy(new_mesh->id.name, mesh->id.name, sizeof(new_mesh->id.name)); - /* Copy materials so render engines can access them. */ - new_mesh->mat = MEM_dupallocN(mesh->mat); - new_mesh->totcol = mesh->totcol; - DM_to_mesh(dm, new_mesh, ob, CD_MASK_MESH, true); - new_mesh->edit_btmesh = mesh->edit_btmesh; - /* Store result mesh as derived_mesh of object. This way we have - * explicit way to query final object evaluated data and know for sure - * who owns the newly created mesh datablock. - */ - ob->runtime.mesh_eval = new_mesh; - /* TODO(sergey): This is kind of compatibility thing, so all render - * engines can use object->data for mesh data for display. This is - * something what we might want to change in the future. - * XXX: This can sometimes cause modifiers to be applied twice! - */ - ob->data = new_mesh; - /* Special flags to help debugging. */ - new_mesh->id.tag |= LIB_TAG_COPY_ON_WRITE_EVAL; - /* Save some memory by throwing DerivedMesh away. */ - /* NOTE: Watch out, some tools might need it! - * So keep around for now.. - */ - /* Store original ID as a pointer in evaluated ID. - * This way we can restore original object data when we are freeing - * evaluated mesh. - */ - new_mesh->id.orig_id = &mesh->id; - /* Copy autosmooth settings from original mesh. */ - new_mesh->flag |= (mesh->flag & ME_AUTOSMOOTH); - new_mesh->smoothresh = mesh->smoothresh; - } -#if 0 - if (ob->derivedFinal != NULL) { - ob->derivedFinal->needsFree = 1; - ob->derivedFinal->release(ob->derivedFinal); - ob->derivedFinal = NULL; - } - if (ob->derivedDeform != NULL) { - ob->derivedDeform->needsFree = 1; - ob->derivedDeform->release(ob->derivedDeform); - ob->derivedDeform = NULL; - } -#endif - } - } } void BKE_object_eval_cloth(Depsgraph *depsgraph, |