Changeset View
Standalone View
source/blender/blenkernel/intern/mesh.c
| Show All 34 Lines | |||||
| #include "BLI_memarena.h" | #include "BLI_memarena.h" | ||||
| #include "BLI_edgehash.h" | #include "BLI_edgehash.h" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BKE_animsys.h" | #include "BKE_animsys.h" | ||||
| #include "BKE_idcode.h" | #include "BKE_idcode.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_key.h" | |||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_mesh_runtime.h" | #include "BKE_mesh_runtime.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_multires.h" | #include "BKE_multires.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| ▲ Show 20 Lines • Show All 423 Lines • ▼ Show 20 Lines | bool BKE_mesh_has_custom_loop_normals(Mesh *me) | ||||
| else { | else { | ||||
| return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL); | return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL); | ||||
| } | } | ||||
| } | } | ||||
| /** Free (or release) any data used by this mesh (does not free the mesh itself). */ | /** Free (or release) any data used by this mesh (does not free the mesh itself). */ | ||||
| void BKE_mesh_free(Mesh *me) | void BKE_mesh_free(Mesh *me) | ||||
| { | { | ||||
| BKE_animdata_free(&me->id, false); | BKE_mesh_clear_geometry(me); | ||||
| MEM_SAFE_FREE(me->mat); | |||||
| } | |||||
| BKE_mesh_runtime_clear_cache(me); | void BKE_mesh_clear_geometry(Mesh *mesh) | ||||
| { | |||||
| BKE_animdata_free(&mesh->id, false); | |||||
| BKE_mesh_runtime_clear_cache(mesh); | |||||
| CustomData_free(&me->vdata, me->totvert); | CustomData_free(&mesh->vdata, mesh->totvert); | ||||
| CustomData_free(&me->edata, me->totedge); | CustomData_free(&mesh->edata, mesh->totedge); | ||||
| CustomData_free(&me->fdata, me->totface); | CustomData_free(&mesh->fdata, mesh->totface); | ||||
| CustomData_free(&me->ldata, me->totloop); | CustomData_free(&mesh->ldata, mesh->totloop); | ||||
| CustomData_free(&me->pdata, me->totpoly); | CustomData_free(&mesh->pdata, mesh->totpoly); | ||||
| MEM_SAFE_FREE(me->mat); | MEM_SAFE_FREE(mesh->bb); | ||||
| MEM_SAFE_FREE(me->bb); | MEM_SAFE_FREE(mesh->mselect); | ||||
| MEM_SAFE_FREE(me->mselect); | MEM_SAFE_FREE(mesh->edit_mesh); | ||||
| MEM_SAFE_FREE(me->edit_mesh); | |||||
| /* Note that materials and shape keys are not freed here. This is intentional, as freeing | |||||
| * shape keys requires tagging the depsgraph for updated relations, which is expensive. | |||||
| * Material slots should be kept in sync with the object.*/ | |||||
| mesh->totvert = 0; | |||||
| mesh->totedge = 0; | |||||
| mesh->totface = 0; | |||||
| mesh->totloop = 0; | |||||
| mesh->totpoly = 0; | |||||
| mesh->act_face = -1; | |||||
| mesh->totselect = 0; | |||||
| BKE_mesh_update_customdata_pointers(mesh, false); | |||||
| } | } | ||||
| static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) | static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) | ||||
| { | { | ||||
| if (free_customdata) { | if (free_customdata) { | ||||
| CustomData_free(&mesh->fdata, mesh->totface); | CustomData_free(&mesh->fdata, mesh->totface); | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 21 Lines | void BKE_mesh_init(Mesh *me) | ||||
| CustomData_reset(&me->ldata); | CustomData_reset(&me->ldata); | ||||
| BKE_mesh_runtime_reset(me); | BKE_mesh_runtime_reset(me); | ||||
| } | } | ||||
| Mesh *BKE_mesh_add(Main *bmain, const char *name) | Mesh *BKE_mesh_add(Main *bmain, const char *name) | ||||
| { | { | ||||
| Mesh *me; | Mesh *me; | ||||
| me = BKE_libblock_alloc(bmain, ID_ME, name, 0); | me = BKE_libblock_alloc(bmain, ID_ME, name, 0); | ||||
| BKE_mesh_init(me); | BKE_mesh_init(me); | ||||
brecht: Don't do this kind of hacking, instead create a shared function that both `BKE_mesh_free` and… | |||||
Done Inline ActionsDone, although I'm not really happy with the name mesh_free_most_data(). It does what it says, but it's not really descriptive either. I could name it mesh_free_data_except_materials_and_shapekeys(), but that's opening the door to code rot (add something to the mesh structure but not this function and the name has already gone bad). sybren: Done, although I'm not really happy with the name `mesh_free_most_data()`. It does what it says… | |||||
Done Inline ActionsYou could make BKE_mesh_free just call BKE_mesh_clear_geometry, the overhead will be negligible. brecht: You could make `BKE_mesh_free` just call `BKE_mesh_clear_geometry`, the overhead will be… | |||||
| return me; | return me; | ||||
| } | } | ||||
| /** | /** | ||||
| * Only copy internal data of Mesh ID from source | * Only copy internal data of Mesh ID from source | ||||
| * to already allocated/initialized destination. | * to already allocated/initialized destination. | ||||
| * You probably never want to use that directly, | * You probably never want to use that directly, | ||||
| * use #BKE_id_copy or #BKE_id_copy_ex for typical needs. | * use #BKE_id_copy or #BKE_id_copy_ex for typical needs. | ||||
| * | * | ||||
| * WARNING! This function will not handle ID user count! | * WARNING! This function will not handle ID user count! | ||||
| * | * | ||||
| * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). | * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). | ||||
| */ | */ | ||||
Done Inline ActionsMost BKE functions don't have depsgraph tagging, better to put it next to the notifier I think since these usually go together. brecht: Most BKE functions don't have depsgraph tagging, better to put it next to the notifier I think… | |||||
| void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int flag) | void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int flag) | ||||
Not Done Inline ActionsThis function misses freeing shape keys. brecht: This function misses freeing shape keys. | |||||
Done Inline ActionsI had a little discussion with @Sergey Sharybin (sergey) and he pointed out that freeing the shapekeys requires tagging the depsgraph for rebuilding relations. Since this is an expensive operation, I'd rather not have it here. The use case for this function is to make it cheaper for Python code to replace one generated mesh with another. I don't think it'll be common to have shape keys in this scenario. I'd rather keep such an expensive operation outside this function, and let people deal with shape keys explicitly when necessary. I added a comment to the code to indicate that shapekeys aren't freed. I also added this to the RNA function description (and also included that materials aren't freed either). sybren: I had a little discussion with @Sergey and he pointed out that freeing the shapekeys requires… | |||||
| { | { | ||||
| BKE_mesh_runtime_reset_on_copy(me_dst, flag); | BKE_mesh_runtime_reset_on_copy(me_dst, flag); | ||||
| if ((me_src->id.tag & LIB_TAG_NO_MAIN) == 0) { | if ((me_src->id.tag & LIB_TAG_NO_MAIN) == 0) { | ||||
| /* This is a direct copy of a main mesh, so for now it has the same topology. */ | /* This is a direct copy of a main mesh, so for now it has the same topology. */ | ||||
| me_dst->runtime.deformed_only = true; | me_dst->runtime.deformed_only = true; | ||||
| } | } | ||||
| /* XXX WHAT? Why? Comment, please! And pretty sure this is not valid for regular Mesh copying? */ | /* XXX WHAT? Why? Comment, please! And pretty sure this is not valid for regular Mesh copying? */ | ||||
| me_dst->runtime.is_original = false; | me_dst->runtime.is_original = false; | ||||
| ▲ Show 20 Lines • Show All 1,476 Lines • Show Last 20 Lines | |||||
Don't do this kind of hacking, instead create a shared function that both BKE_mesh_free and this can call.
Otherwise it's too easy to make a change in BKE_mesh_free that breaks BKE_mesh_clear_geometry. It also helps a little to put these functions next to each other.