Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/DerivedMesh.c
| Show First 20 Lines • Show All 723 Lines • ▼ Show 20 Lines | |||||
| static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer) | static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer) | ||||
| { | { | ||||
| Mesh *mesh; | Mesh *mesh; | ||||
| float(*orco)[3]; | float(*orco)[3]; | ||||
| int free; | int free; | ||||
| if (em) { | if (em) { | ||||
| mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); | mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, me); | ||||
| } | } | ||||
| else { | else { | ||||
| mesh = BKE_mesh_copy_for_eval(me, true); | mesh = BKE_mesh_copy_for_eval(me, true); | ||||
| } | } | ||||
| orco = get_orco_coords(ob, em, layer, &free); | orco = get_orco_coords(ob, em, layer, &free); | ||||
| if (orco) { | if (orco) { | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
| static void editmesh_update_statvis_color(const Scene *scene, Object *ob) | static void editmesh_update_statvis_color(const Scene *scene, Object *ob) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(ob); | BMEditMesh *em = BKE_editmesh_from_object(ob); | ||||
| Mesh *me = ob->data; | Mesh *me = ob->data; | ||||
| BKE_mesh_runtime_ensure_edit_data(me); | BKE_mesh_runtime_ensure_edit_data(me); | ||||
| BKE_editmesh_statvis_calc(em, me->runtime.edit_data, &scene->toolsettings->statvis); | BKE_editmesh_statvis_calc(em, me->runtime.edit_data, &scene->toolsettings->statvis); | ||||
| } | } | ||||
| static void mesh_copy_autosmooth(Mesh *me, Mesh *me_orig) | |||||
| { | |||||
| if (me_orig->flag & ME_AUTOSMOOTH) { | |||||
| me->flag |= ME_AUTOSMOOTH; | |||||
| me->smoothresh = me_orig->smoothresh; | |||||
| } | |||||
| } | |||||
| static void mesh_calc_modifier_final_normals(const Mesh *mesh_input, | static void mesh_calc_modifier_final_normals(const Mesh *mesh_input, | ||||
| const CustomData_MeshMasks *final_datamask, | const CustomData_MeshMasks *final_datamask, | ||||
| const bool sculpt_dyntopo, | const bool sculpt_dyntopo, | ||||
| Mesh *mesh_final) | Mesh *mesh_final) | ||||
| { | { | ||||
| /* Compute normals. */ | /* Compute normals. */ | ||||
| const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 || | const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 || | ||||
| (final_datamask->lmask & CD_MASK_NORMAL) != 0); | (final_datamask->lmask & CD_MASK_NORMAL) != 0); | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
| * This is needed because certain information is not passed along intermediate meshes allocated | * This is needed because certain information is not passed along intermediate meshes allocated | ||||
| * during stack evaluation. | * during stack evaluation. | ||||
| */ | */ | ||||
| static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval) | static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval) | ||||
| { | { | ||||
| /* Make sure the name is the same. This is because mesh allocation from template does not | /* Make sure the name is the same. This is because mesh allocation from template does not | ||||
| * take care of naming. */ | * take care of naming. */ | ||||
| BLI_strncpy(mesh_eval->id.name, mesh_input->id.name, sizeof(mesh_eval->id.name)); | BLI_strncpy(mesh_eval->id.name, mesh_input->id.name, sizeof(mesh_eval->id.name)); | ||||
| /* Make sure materials are preserved from the input. */ | |||||
| if (mesh_eval->mat != NULL) { | |||||
| MEM_freeN(mesh_eval->mat); | |||||
| } | |||||
| mesh_eval->mat = MEM_dupallocN(mesh_input->mat); | |||||
| mesh_eval->totcol = mesh_input->totcol; | |||||
| /* Make evaluated mesh to share same edit mesh pointer as original and copied meshes. */ | /* Make evaluated mesh to share same edit mesh pointer as original and copied meshes. */ | ||||
| mesh_eval->edit_mesh = mesh_input->edit_mesh; | mesh_eval->edit_mesh = mesh_input->edit_mesh; | ||||
| /* Copy auth-smooth settings which are also not taken care about by mesh allocation from a | |||||
| * template. */ | |||||
| mesh_eval->flag |= (mesh_input->flag & ME_AUTOSMOOTH); | |||||
| mesh_eval->smoothresh = mesh_input->smoothresh; | |||||
| } | } | ||||
| static void mesh_calc_modifiers(struct Depsgraph *depsgraph, | static void mesh_calc_modifiers(struct Depsgraph *depsgraph, | ||||
| Scene *scene, | Scene *scene, | ||||
| Object *ob, | Object *ob, | ||||
| int useDeform, | int useDeform, | ||||
| const bool need_mapping, | const bool need_mapping, | ||||
| const CustomData_MeshMasks *dataMask, | const CustomData_MeshMasks *dataMask, | ||||
| ▲ Show 20 Lines • Show All 311 Lines • ▼ Show 20 Lines | else { | ||||
| BKE_id_free(NULL, mesh_final); | BKE_id_free(NULL, mesh_final); | ||||
| } | } | ||||
| mesh_final = mesh_next; | mesh_final = mesh_next; | ||||
| if (deformed_verts) { | if (deformed_verts) { | ||||
| MEM_freeN(deformed_verts); | MEM_freeN(deformed_verts); | ||||
| deformed_verts = NULL; | deformed_verts = NULL; | ||||
| } | } | ||||
| mesh_copy_autosmooth(mesh_final, mesh_input); | |||||
| } | } | ||||
| /* create an orco mesh in parallel */ | /* create an orco mesh in parallel */ | ||||
| if (nextmask.vmask & CD_MASK_ORCO) { | if (nextmask.vmask & CD_MASK_ORCO) { | ||||
| if (!mesh_orco) { | if (!mesh_orco) { | ||||
| mesh_orco = create_orco_mesh(ob, mesh_input, NULL, CD_ORCO); | mesh_orco = create_orco_mesh(ob, mesh_input, NULL, CD_ORCO); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 295 Lines • ▼ Show 20 Lines | static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, | ||||
| CDMaskLink *datamasks = modifiers_calcDataMasks( | CDMaskLink *datamasks = modifiers_calcDataMasks( | ||||
| scene, ob, md, &final_datamask, required_mode, NULL, NULL); | scene, ob, md, &final_datamask, required_mode, NULL, NULL); | ||||
| CDMaskLink *md_datamask = datamasks; | CDMaskLink *md_datamask = datamasks; | ||||
| CustomData_MeshMasks append_mask = CD_MASK_BAREMESH; | CustomData_MeshMasks append_mask = CD_MASK_BAREMESH; | ||||
| /* Evaluate modifiers up to certain index to get the mesh cage. */ | /* Evaluate modifiers up to certain index to get the mesh cage. */ | ||||
| int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); | int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); | ||||
| if (r_cage && cageIndex == -1) { | if (r_cage && cageIndex == -1) { | ||||
| mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap(em_input, &final_datamask, NULL); | mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap( | ||||
| mesh_copy_autosmooth(mesh_cage, mesh_input); | em_input, &final_datamask, NULL, mesh_input); | ||||
| } | } | ||||
| /* Clear errors before evaluation. */ | /* Clear errors before evaluation. */ | ||||
| modifiers_clearErrors(ob); | modifiers_clearErrors(ob); | ||||
| for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) { | for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) { | ||||
| const ModifierTypeInfo *mti = modifierType_getInfo(md->type); | const ModifierTypeInfo *mti = modifierType_getInfo(md->type); | ||||
| Show All 23 Lines | if (mti->type == eModifierTypeType_OnlyDeform) { | ||||
| deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts); | deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts); | ||||
| } | } | ||||
| else { | else { | ||||
| deformed_verts = editbmesh_vert_coords_alloc(em_input, &num_deformed_verts); | deformed_verts = editbmesh_vert_coords_alloc(em_input, &num_deformed_verts); | ||||
| } | } | ||||
| } | } | ||||
| else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { | else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { | ||||
| if (mesh_final == NULL) { | if (mesh_final == NULL) { | ||||
| mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL); | mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL, mesh_input); | ||||
| ASSERT_IS_VALID_MESH(mesh_final); | ASSERT_IS_VALID_MESH(mesh_final); | ||||
| mesh_copy_autosmooth(mesh_final, mesh_input); | |||||
| } | } | ||||
| BLI_assert(deformed_verts != NULL); | BLI_assert(deformed_verts != NULL); | ||||
| BKE_mesh_vert_coords_apply(mesh_final, deformed_verts); | BKE_mesh_vert_coords_apply(mesh_final, deformed_verts); | ||||
| } | } | ||||
| if (mti->deformVertsEM) { | if (mti->deformVertsEM) { | ||||
| modwrap_deformVertsEM( | modwrap_deformVertsEM( | ||||
| md, &mectx, em_input, mesh_final, deformed_verts, num_deformed_verts); | md, &mectx, em_input, mesh_final, deformed_verts, num_deformed_verts); | ||||
| Show All 14 Lines | else { | ||||
| BKE_mesh_vert_coords_apply(mesh_final, deformed_verts); | BKE_mesh_vert_coords_apply(mesh_final, deformed_verts); | ||||
| } | } | ||||
| else if (mesh_final == mesh_cage) { | else if (mesh_final == mesh_cage) { | ||||
| /* 'me' may be changed by this modifier, so we need to copy it. */ | /* 'me' may be changed by this modifier, so we need to copy it. */ | ||||
| mesh_final = BKE_mesh_copy_for_eval(mesh_final, false); | mesh_final = BKE_mesh_copy_for_eval(mesh_final, false); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL); | mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL, mesh_input); | ||||
| ASSERT_IS_VALID_MESH(mesh_final); | ASSERT_IS_VALID_MESH(mesh_final); | ||||
| mesh_copy_autosmooth(mesh_final, mesh_input); | |||||
| if (deformed_verts) { | if (deformed_verts) { | ||||
| BKE_mesh_vert_coords_apply(mesh_final, deformed_verts); | BKE_mesh_vert_coords_apply(mesh_final, deformed_verts); | ||||
| } | } | ||||
| } | } | ||||
| /* create an orco derivedmesh in parallel */ | /* create an orco derivedmesh in parallel */ | ||||
| CustomData_MeshMasks mask = md_datamask->mask; | CustomData_MeshMasks mask = md_datamask->mask; | ||||
| if (mask.vmask & CD_MASK_ORCO) { | if (mask.vmask & CD_MASK_ORCO) { | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | else { | ||||
| BKE_id_free(NULL, mesh_final); | BKE_id_free(NULL, mesh_final); | ||||
| } | } | ||||
| mesh_final = mesh_next; | mesh_final = mesh_next; | ||||
| if (deformed_verts) { | if (deformed_verts) { | ||||
| MEM_freeN(deformed_verts); | MEM_freeN(deformed_verts); | ||||
| deformed_verts = NULL; | deformed_verts = NULL; | ||||
| } | } | ||||
| mesh_copy_autosmooth(mesh_final, mesh_input); | |||||
| } | } | ||||
| mesh_final->runtime.deformed_only = false; | mesh_final->runtime.deformed_only = false; | ||||
| } | } | ||||
| if (r_cage && i == cageIndex) { | if (r_cage && i == cageIndex) { | ||||
| if (mesh_final && deformed_verts) { | if (mesh_final && deformed_verts) { | ||||
| mesh_cage = BKE_mesh_copy_for_eval(mesh_final, false); | mesh_cage = BKE_mesh_copy_for_eval(mesh_final, false); | ||||
| BKE_mesh_vert_coords_apply(mesh_cage, deformed_verts); | BKE_mesh_vert_coords_apply(mesh_cage, deformed_verts); | ||||
| } | } | ||||
| else if (mesh_final) { | else if (mesh_final) { | ||||
| mesh_cage = mesh_final; | mesh_cage = mesh_final; | ||||
| } | } | ||||
| else { | else { | ||||
| Mesh *me_orig = mesh_input; | Mesh *me_orig = mesh_input; | ||||
| if (me_orig->id.tag & LIB_TAG_COPIED_ON_WRITE) { | if (me_orig->id.tag & LIB_TAG_COPIED_ON_WRITE) { | ||||
| BKE_mesh_runtime_ensure_edit_data(me_orig); | BKE_mesh_runtime_ensure_edit_data(me_orig); | ||||
| me_orig->runtime.edit_data->vertexCos = MEM_dupallocN(deformed_verts); | me_orig->runtime.edit_data->vertexCos = MEM_dupallocN(deformed_verts); | ||||
| } | } | ||||
| mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap( | mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap( | ||||
| em_input, &final_datamask, deformed_verts ? MEM_dupallocN(deformed_verts) : NULL); | em_input, | ||||
| mesh_copy_autosmooth(mesh_cage, mesh_input); | &final_datamask, | ||||
| deformed_verts ? MEM_dupallocN(deformed_verts) : NULL, | |||||
| mesh_input); | |||||
| } | } | ||||
| } | } | ||||
| isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); | isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); | ||||
| } | } | ||||
| BLI_linklist_free((LinkNode *)datamasks, NULL); | BLI_linklist_free((LinkNode *)datamasks, NULL); | ||||
| Show All 17 Lines | else if (!deformed_verts && mesh_cage) { | ||||
| /* In this case, we should never have weight-modifying modifiers in stack... */ | /* In this case, we should never have weight-modifying modifiers in stack... */ | ||||
| if (do_init_statvis) { | if (do_init_statvis) { | ||||
| editmesh_update_statvis_color(scene, ob); | editmesh_update_statvis_color(scene, ob); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* this is just a copy of the editmesh, no need to calc normals */ | /* this is just a copy of the editmesh, no need to calc normals */ | ||||
| mesh_final = BKE_mesh_from_editmesh_with_coords_thin_wrap( | mesh_final = BKE_mesh_from_editmesh_with_coords_thin_wrap( | ||||
| em_input, &final_datamask, deformed_verts); | em_input, &final_datamask, deformed_verts, mesh_input); | ||||
| deformed_verts = NULL; | deformed_verts = NULL; | ||||
| mesh_copy_autosmooth(mesh_final, mesh_input); | |||||
| /* In this case, we should never have weight-modifying modifiers in stack... */ | /* In this case, we should never have weight-modifying modifiers in stack... */ | ||||
| if (do_init_statvis) { | if (do_init_statvis) { | ||||
| editmesh_update_statvis_color(scene, ob); | editmesh_update_statvis_color(scene, ob); | ||||
| } | } | ||||
| } | } | ||||
| if (deformed_verts) { | if (deformed_verts) { | ||||
| MEM_freeN(deformed_verts); | MEM_freeN(deformed_verts); | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | mesh_calc_modifiers(depsgraph, | ||||
| dataMask, | dataMask, | ||||
| -1, | -1, | ||||
| true, | true, | ||||
| true, | true, | ||||
| &ob->runtime.mesh_deform_eval, | &ob->runtime.mesh_deform_eval, | ||||
| &ob->runtime.mesh_eval); | &ob->runtime.mesh_eval); | ||||
| BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval); | BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval); | ||||
| /* Only copy texspace from orig mesh if some modifier (hint: smoke sim, see T58492) | |||||
| * did not re-enable that flag (which always get disabled for eval mesh as a start). */ | |||||
| if (!(ob->runtime.mesh_eval->texflag & ME_AUTOSPACE)) { | |||||
| BKE_mesh_texspace_copy_from_object(ob->runtime.mesh_eval, ob); | |||||
| } | |||||
| assign_object_mesh_eval(ob); | assign_object_mesh_eval(ob); | ||||
| ob->runtime.last_data_mask = *dataMask; | ob->runtime.last_data_mask = *dataMask; | ||||
| ob->runtime.last_need_mapping = need_mapping; | ob->runtime.last_need_mapping = need_mapping; | ||||
| if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) { | if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) { | ||||
| if (DEG_is_active(depsgraph)) { | if (DEG_is_active(depsgraph)) { | ||||
| ▲ Show 20 Lines • Show All 614 Lines • Show Last 20 Lines | |||||