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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/mesh.c')
-rw-r--r--source/blender/blenkernel/intern/mesh.c492
1 files changed, 369 insertions, 123 deletions
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 5758e00a28d..6a00aaf576b 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -32,8 +32,10 @@
#include "DNA_object_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
+#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
@@ -41,15 +43,15 @@
#include "BLI_string.h"
#include "BKE_animsys.h"
+#include "BKE_idcode.h"
#include "BKE_main.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_library.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
-#include "BKE_depsgraph.h"
#include "BKE_object.h"
#include "BKE_editmesh.h"
@@ -109,7 +111,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
for (i = 0; i < c1->totlayer; i++) {
if (ELEM(c1->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i1++;
}
@@ -117,7 +119,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
for (i = 0; i < c2->totlayer; i++) {
if (ELEM(c2->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i2++;
}
@@ -131,14 +133,14 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
i1 = 0; i2 = 0;
for (i = 0; i < tot; i++) {
while (i1 < c1->totlayer && !ELEM(l1->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i1++;
l1++;
}
while (i2 < c2->totlayer && !ELEM(l2->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
- CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+ CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
{
i2++;
l2++;
@@ -306,7 +308,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
* Callers could also check but safer to do here - campbell */
}
else {
- const int tottex_original = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+ const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
@@ -317,16 +319,16 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
{
BKE_mesh_tessface_clear(me);
- CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface);
+ CustomData_from_bmeshpoly(&me->fdata, &me->ldata, me->totface);
/* TODO - add some --debug-mesh option */
if (G.debug & G_DEBUG) {
/* note: this warning may be un-called for if we are initializing the mesh for the
* first time from bmesh, rather then giving a warning about this we could be smarter
* and check if there was any data to begin with, for now just print the warning with
- * some info to help troubleshoot whats going on - campbell */
+ * some info to help troubleshoot what's going on - campbell */
printf("%s: warning! Tessellation uvs or vcol data got out of sync, "
- "had to reset!\n CD_MTFACE: %d != CD_MTEXPOLY: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
+ "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
__func__, tottex_tessface, tottex_original, totcol_tessface, totcol_original);
}
}
@@ -372,6 +374,49 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
}
}
+bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me)
+{
+ BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
+ bool changed = false;
+ if (bm) {
+ if (!CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
+ BM_data_layer_add(bm, &bm->pdata, CD_FACEMAP);
+ changed = true;
+ }
+ }
+ else {
+ if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+ CustomData_add_layer(
+ &me->pdata,
+ CD_FACEMAP,
+ CD_DEFAULT,
+ NULL,
+ me->totpoly);
+ changed = true;
+ }
+ }
+ return changed;
+}
+
+bool BKE_mesh_clear_facemap_customdata(struct Mesh *me)
+{
+ BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
+ bool changed = false;
+ if (bm) {
+ if (CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
+ BM_data_layer_free(bm, &bm->pdata, CD_FACEMAP);
+ changed = true;
+ }
+ }
+ else {
+ if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+ CustomData_free_layers(&me->pdata, CD_FACEMAP, me->totpoly);
+ changed = true;
+ }
+ }
+ return changed;
+}
+
/* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
* mloopcol and mcol) have the same relative active/render/clone/mask indices.
*
@@ -380,14 +425,11 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
* versions of the mesh. - campbell*/
static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
{
- if (me->edit_btmesh)
- BKE_editmesh_update_linked_customdata(me->edit_btmesh);
-
if (do_ensure_tess_cd) {
mesh_ensure_tessellation_customdata(me);
}
- CustomData_bmesh_update_active_layers(&me->fdata, &me->pdata, &me->ldata);
+ CustomData_bmesh_update_active_layers(&me->fdata, &me->ldata);
}
void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
@@ -406,7 +448,6 @@ void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
me->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
me->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
- me->mtpoly = CustomData_get_layer(&me->pdata, CD_MTEXPOLY);
me->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
me->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
}
@@ -426,6 +467,8 @@ void BKE_mesh_free(Mesh *me)
{
BKE_animdata_free(&me->id, false);
+ BKE_mesh_runtime_clear_cache(me);
+
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
@@ -460,12 +503,7 @@ void BKE_mesh_init(Mesh *me)
me->size[0] = me->size[1] = me->size[2] = 1.0;
me->smoothresh = DEG2RADF(30);
me->texflag = ME_AUTOSPACE;
-
- /* disable because its slow on many GPU's, see [#37518] */
-#if 0
- me->flag = ME_TWOSIDED;
-#endif
- me->drawflag = ME_DRAWEDGES | ME_DRAWFACES | ME_DRAWCREASES;
+ me->drawflag = 0;
CustomData_reset(&me->vdata);
CustomData_reset(&me->edata);
@@ -496,15 +534,22 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int flag)
{
const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */
+ CustomDataMask mask = CD_MASK_MESH;
+
+ if (me_src->id.tag & LIB_TAG_NO_MAIN) {
+ /* For copies in depsgraph, keep data like origindex and orco. */
+ mask |= CD_MASK_DERIVEDMESH;
+ }
me_dst->mat = MEM_dupallocN(me_src->mat);
- CustomData_copy(&me_src->vdata, &me_dst->vdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totvert);
- CustomData_copy(&me_src->edata, &me_dst->edata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totedge);
- CustomData_copy(&me_src->ldata, &me_dst->ldata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totloop);
- CustomData_copy(&me_src->pdata, &me_dst->pdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totpoly);
+ const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
+ CustomData_copy(&me_src->vdata, &me_dst->vdata, mask, alloc_type, me_dst->totvert);
+ CustomData_copy(&me_src->edata, &me_dst->edata, mask, alloc_type, me_dst->totedge);
+ CustomData_copy(&me_src->ldata, &me_dst->ldata, mask, alloc_type, me_dst->totloop);
+ CustomData_copy(&me_src->pdata, &me_dst->pdata, mask, alloc_type, me_dst->totpoly);
if (do_tessface) {
- CustomData_copy(&me_src->fdata, &me_dst->fdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totface);
+ CustomData_copy(&me_src->fdata, &me_dst->fdata, mask, alloc_type, me_dst->totface);
}
else {
mesh_tessface_clear_intern(me_dst, false);
@@ -514,37 +559,223 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int
me_dst->edit_btmesh = NULL;
+ /* Call BKE_mesh_runtime_reset? */
+ me_dst->runtime.batch_cache = NULL;
+ me_dst->runtime.looptris.array = NULL;
+ me_dst->runtime.bvh_cache = NULL;
+ me_dst->runtime.shrinkwrap_data = NULL;
+
+ if (me_src->id.tag & LIB_TAG_NO_MAIN) {
+ me_dst->runtime.deformed_only = me_src->runtime.deformed_only;
+ }
+ else {
+ /* This is a direct copy of a main mesh, so for now it has the same topology. */
+ me_dst->runtime.deformed_only = 1;
+ }
+ me_dst->runtime.is_original = false;
+
me_dst->mselect = MEM_dupallocN(me_dst->mselect);
me_dst->bb = MEM_dupallocN(me_dst->bb);
/* TODO Do we want to add flag to prevent this? */
- if (me_src->key) {
+ if (me_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
BKE_id_copy_ex(bmain, &me_src->key->id, (ID **)&me_dst->key, flag, false);
}
}
+/* Custom data layer functions; those assume that totXXX are set correctly. */
+static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
+{
+ if (!CustomData_get_layer(&mesh->vdata, CD_MVERT))
+ CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
+ if (!CustomData_get_layer(&mesh->edata, CD_MEDGE))
+ CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
+ if (!CustomData_get_layer(&mesh->ldata, CD_MLOOP))
+ CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
+ if (!CustomData_get_layer(&mesh->pdata, CD_MPOLY))
+ CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+
+ if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_MFACE))
+ CustomData_add_layer(&mesh->fdata, CD_MFACE, CD_CALLOC, NULL, mesh->totface);
+}
+static void mesh_ensure_cdlayers_origindex(Mesh *mesh, bool do_tessface)
+{
+ if (!CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
+ if (!CustomData_get_layer(&mesh->edata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
+ if (!CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totpoly);
+
+ if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->fdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
+}
+
+Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
+{
+ Mesh *mesh = BKE_libblock_alloc(
+ NULL, ID_ME,
+ BKE_idcode_to_name(ID_ME),
+ LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG);
+ BKE_libblock_init_empty(&mesh->id);
+
+ /* don't use CustomData_reset(...); because we dont want to touch customdata */
+ copy_vn_i(mesh->vdata.typemap, CD_NUMTYPES, -1);
+ copy_vn_i(mesh->edata.typemap, CD_NUMTYPES, -1);
+ copy_vn_i(mesh->fdata.typemap, CD_NUMTYPES, -1);
+ copy_vn_i(mesh->ldata.typemap, CD_NUMTYPES, -1);
+ copy_vn_i(mesh->pdata.typemap, CD_NUMTYPES, -1);
+
+ mesh->totvert = verts_len;
+ mesh->totedge = edges_len;
+ mesh->totface = tessface_len;
+ mesh->totloop = loops_len;
+ mesh->totpoly = polys_len;
+
+ mesh_ensure_cdlayers_primary(mesh, true);
+ mesh_ensure_cdlayers_origindex(mesh, true);
+ BKE_mesh_update_customdata_pointers(mesh, false);
+
+ return mesh;
+}
+
+static Mesh *mesh_new_nomain_from_template_ex(
+ const Mesh *me_src,
+ int verts_len, int edges_len, int tessface_len,
+ int loops_len, int polys_len,
+ CustomDataMask mask)
+{
+ /* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */
+ const bool do_tessface = (tessface_len ||
+ ((me_src->totface != 0) && (me_src->totpoly == 0)));
+
+ Mesh *me_dst = BKE_id_new_nomain(ID_ME, NULL);
+
+ me_dst->mat = MEM_dupallocN(me_src->mat);
+ me_dst->mselect = MEM_dupallocN(me_dst->mselect);
+
+ me_dst->totvert = verts_len;
+ me_dst->totedge = edges_len;
+ me_dst->totface = tessface_len;
+ me_dst->totloop = loops_len;
+ me_dst->totpoly = polys_len;
+
+ CustomData_copy(&me_src->vdata, &me_dst->vdata, mask, CD_CALLOC, verts_len);
+ CustomData_copy(&me_src->edata, &me_dst->edata, mask, CD_CALLOC, edges_len);
+ CustomData_copy(&me_src->ldata, &me_dst->ldata, mask, CD_CALLOC, loops_len);
+ CustomData_copy(&me_src->pdata, &me_dst->pdata, mask, CD_CALLOC, polys_len);
+ if (do_tessface) {
+ CustomData_copy(&me_src->fdata, &me_dst->fdata, mask, CD_CALLOC, tessface_len);
+ }
+ else {
+ mesh_tessface_clear_intern(me_dst, false);
+ }
+
+ /* The destination mesh should at least have valid primary CD layers,
+ * even in cases where the source mesh does not. */
+ mesh_ensure_cdlayers_primary(me_dst, do_tessface);
+ mesh_ensure_cdlayers_origindex(me_dst, false);
+ BKE_mesh_update_customdata_pointers(me_dst, false);
+
+ return me_dst;
+}
+
+Mesh *BKE_mesh_new_nomain_from_template(
+ const Mesh *me_src,
+ int verts_len, int edges_len, int tessface_len,
+ int loops_len, int polys_len)
+{
+ return mesh_new_nomain_from_template_ex(
+ me_src,
+ verts_len, edges_len, tessface_len,
+ loops_len, polys_len,
+ CD_MASK_EVERYTHING);
+}
+
+Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
+{
+ int flags = (LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_NO_PREVIEW);
+
+ if (reference) {
+ flags |= LIB_ID_COPY_CD_REFERENCE;
+ }
+
+ Mesh *result;
+ BKE_id_copy_ex(NULL, &source->id, (ID **)&result, flags, false);
+ return result;
+}
+
Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
{
Mesh *me_copy;
- BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, 0, false);
+ BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, LIB_ID_COPY_SHAPEKEY, false);
return me_copy;
}
+BMesh *BKE_mesh_to_bmesh_ex(
+ Mesh *me,
+ const struct BMeshCreateParams *create_params,
+ const struct BMeshFromMeshParams *convert_params)
+{
+ BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
+
+ bm = BM_mesh_create(&allocsize, create_params);
+ BM_mesh_bm_from_me(bm, me, convert_params);
+
+ return bm;
+}
+
BMesh *BKE_mesh_to_bmesh(
Mesh *me, Object *ob,
const bool add_key_index, const struct BMeshCreateParams *params)
{
- BMesh *bm;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
+ return BKE_mesh_to_bmesh_ex(
+ me, params,
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = false,
+ .add_key_index = add_key_index,
+ .use_shapekey = true,
+ .active_shapekey = ob->shapenr,
+ });
+}
- bm = BM_mesh_create(&allocsize, params);
+Mesh *BKE_mesh_from_bmesh_nomain(BMesh *bm, const struct BMeshToMeshParams *params)
+{
+ BLI_assert(params->calc_object_remap == false);
+ Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
+ BM_mesh_bm_to_me(NULL, bm, mesh, params);
+ return mesh;
+}
- BM_mesh_bm_from_me(
- bm, me, (&(struct BMeshFromMeshParams){
- .add_key_index = add_key_index, .use_shapekey = true, .active_shapekey = ob->shapenr,
- }));
+Mesh *BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const int64_t cd_mask_extra)
+{
+ Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
+ BM_mesh_bm_to_me_for_eval(bm, mesh, cd_mask_extra);
+ return mesh;
+}
- return bm;
+/**
+ * TODO(campbell): support mesh with only an edit-mesh which is lazy initialized.
+ */
+Mesh *BKE_mesh_from_editmesh_with_coords_thin_wrap(
+ BMEditMesh *em, CustomDataMask data_mask, float (*vertexCos)[3])
+{
+ Mesh *me = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, data_mask);
+ /* Use editmesh directly where possible. */
+ me->runtime.is_original = true;
+ if (vertexCos) {
+ /* We will own this array in the future. */
+ BKE_mesh_apply_vert_coords(me, vertexCos);
+ MEM_freeN(vertexCos);
+ me->runtime.is_original = false;
+ }
+ return me;
}
void BKE_mesh_make_local(Main *bmain, Mesh *me, const bool lib_local)
@@ -553,121 +784,82 @@ void BKE_mesh_make_local(Main *bmain, Mesh *me, const bool lib_local)
}
bool BKE_mesh_uv_cdlayer_rename_index(
- Mesh *me, const int poly_index, const int loop_index, const int face_index,
+ Mesh *me, const int loop_index, const int face_index,
const char *new_name, const bool do_tessface)
{
- CustomData *pdata, *ldata, *fdata;
- CustomDataLayer *cdlp, *cdlu, *cdlf;
- const int step = do_tessface ? 3 : 2;
- int i;
+ CustomData *ldata, *fdata;
+ CustomDataLayer *cdlu, *cdlf;
if (me->edit_btmesh) {
- pdata = &me->edit_btmesh->bm->pdata;
ldata = &me->edit_btmesh->bm->ldata;
fdata = NULL; /* No tessellated data in BMesh! */
}
else {
- pdata = &me->pdata;
ldata = &me->ldata;
fdata = &me->fdata;
}
- cdlp = &pdata->layers[poly_index];
+
cdlu = &ldata->layers[loop_index];
- cdlf = fdata && do_tessface ? &fdata->layers[face_index] : NULL;
+ cdlf = (face_index != -1) && fdata && do_tessface ? &fdata->layers[face_index] : NULL;
- if (cdlp->name != new_name) {
+ if (cdlu->name != new_name) {
/* Mesh validate passes a name from the CD layer as the new name,
* Avoid memcpy from self to self in this case.
*/
- BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name));
- CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+ BLI_strncpy(cdlu->name, new_name, sizeof(cdlu->name));
+ CustomData_set_layer_unique_name(ldata, loop_index);
}
- /* Loop until we do have exactly the same name for all layers! */
- for (i = 1; !STREQ(cdlp->name, cdlu->name) || (cdlf && !STREQ(cdlp->name, cdlf->name)); i++) {
- switch (i % step) {
- case 0:
- BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
- CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
- break;
- case 1:
- BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
- CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers);
- break;
- case 2:
- if (cdlf) {
- BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
- CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
- }
- break;
- }
+ if (cdlf == NULL) {
+ return false;
}
+ BLI_strncpy(cdlf->name, cdlu->name, sizeof(cdlf->name));
+ CustomData_set_layer_unique_name(fdata, face_index);
+
return true;
}
bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface)
{
- CustomData *pdata, *ldata, *fdata;
+ CustomData *ldata, *fdata;
if (me->edit_btmesh) {
- pdata = &me->edit_btmesh->bm->pdata;
ldata = &me->edit_btmesh->bm->ldata;
/* No tessellated data in BMesh! */
fdata = NULL;
do_tessface = false;
}
else {
- pdata = &me->pdata;
ldata = &me->ldata;
fdata = &me->fdata;
do_tessface = (do_tessface && fdata->totlayer);
}
{
- const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY);
const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV);
const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1;
- int pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name);
int lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name);
int fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1;
/* None of those cases should happen, in theory!
* Note this assume we have the same number of mtexpoly, mloopuv and mtface layers!
*/
- if (pidx == -1) {
- if (lidx == -1) {
- if (fidx == -1) {
- /* No layer found with this name! */
- return false;
- }
- else {
- lidx = fidx;
- }
- }
- pidx = lidx;
- }
- else {
- if (lidx == -1) {
- lidx = pidx;
+ if (lidx == -1) {
+ if (fidx == -1) {
+ /* No layer found with this name! */
+ return false;
}
- if (fidx == -1 && do_tessface) {
- fidx = pidx;
+ else {
+ lidx = fidx;
}
}
-#if 0
- /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */
- else if (pidx != lidx) {
- lidx = pidx;
- }
-#endif
/* Go back to absolute indices! */
- pidx += pidx_start;
lidx += lidx_start;
if (fidx != -1)
fidx += fidx_start;
- return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface);
+ return BKE_mesh_uv_cdlayer_rename_index(me, lidx, fidx, new_name, do_tessface);
}
}
@@ -745,6 +937,18 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz
if (r_size) copy_v3_v3(r_size, me->size);
}
+void BKE_mesh_texspace_get_reference(Mesh *me, short **r_texflag, float **r_loc, float **r_rot, float **r_size)
+{
+ if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
+ BKE_mesh_texspace_calc(me);
+ }
+
+ if (r_texflag != NULL) *r_texflag = &me->texflag;
+ if (r_loc != NULL) *r_loc = me->loc;
+ if (r_rot != NULL) *r_rot = me->rot;
+ if (r_size != NULL) *r_size = me->size;
+}
+
void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob)
{
float *texloc, *texrot, *texsize;
@@ -904,7 +1108,6 @@ void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *me)
test_object_modifiers(ob);
}
-
void BKE_mesh_material_index_remove(Mesh *me, short index)
{
MPoly *mp;
@@ -999,15 +1202,15 @@ void BKE_mesh_smooth_flag_set(Object *meshOb, int enableSmooth)
/**
* Return a newly MEM_malloc'd array of all the mesh vertex locations
- * \note \a r_numVerts may be NULL
+ * \note \a r_verts_len may be NULL
*/
-float (*BKE_mesh_vertexCos_get(const Mesh *me, int *r_numVerts))[3]
+float (*BKE_mesh_vertexCos_get(const Mesh *me, int *r_verts_len))[3]
{
- int i, numVerts = me->totvert;
- float (*cos)[3] = MEM_malloc_arrayN(numVerts, sizeof(*cos), "vertexcos1");
+ int i, verts_len = me->totvert;
+ float (*cos)[3] = MEM_malloc_arrayN(verts_len, sizeof(*cos), "vertexcos1");
- if (r_numVerts) *r_numVerts = numVerts;
- for (i = 0; i < numVerts; i++)
+ if (r_verts_len) *r_verts_len = verts_len;
+ for (i = 0; i < verts_len; i++)
copy_v3_v3(cos[i], me->mvert[i].co);
return cos;
@@ -1046,10 +1249,6 @@ int poly_get_adj_loops_from_vert(
vert);
if (corner != -1) {
-#if 0 /* unused - this loop */
- const MLoop *ml = &mloop[poly->loopstart + corner];
-#endif
-
/* vertex was found */
r_adj[0] = ME_POLY_LOOP_PREV(mloop, poly, corner)->v;
r_adj[1] = ME_POLY_LOOP_NEXT(mloop, poly, corner)->v;
@@ -1072,6 +1271,21 @@ int BKE_mesh_edge_other_vert(const MEdge *e, int v)
return -1;
}
+/**
+ * Sets each output array element to the edge index if it is a real edge, or -1.
+ */
+void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, int r_edges[3])
+{
+ for (int i = 2, i_next = 0; i_next < 3; i = i_next++) {
+ const MLoop *l1 = &mesh->mloop[looptri->tri[i]], *l2 = &mesh->mloop[looptri->tri[i_next]];
+ const MEdge *e = &mesh->medge[l1->e];
+
+ bool is_real = (l1->v == e->v1 && l2->v == e->v2) || (l1->v == e->v2 && l2->v == e->v1);
+
+ r_edges[i] = is_real ? l1->e : -1;
+ }
+}
+
/* basic vertex data functions */
bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
{
@@ -1139,13 +1353,13 @@ void BKE_mesh_ensure_navmesh(Mesh *me)
{
if (!CustomData_has_layer(&me->pdata, CD_RECAST)) {
int i;
- int numFaces = me->totpoly;
+ int polys_len = me->totpoly;
int *recastData;
- recastData = (int *)MEM_malloc_arrayN(numFaces, sizeof(int), __func__);
- for (i = 0; i < numFaces; i++) {
+ recastData = (int *)MEM_malloc_arrayN(polys_len, sizeof(int), __func__);
+ for (i = 0; i < polys_len; i++) {
recastData[i] = i + 1;
}
- CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_ASSIGN, recastData, numFaces, "recastData");
+ CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_ASSIGN, recastData, polys_len, "recastData");
}
}
@@ -1337,6 +1551,37 @@ void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
(me->mselect[me->totselect - 1].type == type));
}
+
+void BKE_mesh_apply_vert_coords(Mesh *mesh, float (*vertCoords)[3])
+{
+ MVert *vert;
+ int i;
+
+ /* this will just return the pointer if it wasn't a referenced layer */
+ vert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
+ mesh->mvert = vert;
+
+ for (i = 0; i < mesh->totvert; ++i, ++vert)
+ copy_v3_v3(vert->co, vertCoords[i]);
+
+ mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+}
+
+void BKE_mesh_apply_vert_normals(Mesh *mesh, short (*vertNormals)[3])
+{
+ MVert *vert;
+ int i;
+
+ /* this will just return the pointer if it wasn't a referenced layer */
+ vert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
+ mesh->mvert = vert;
+
+ for (i = 0; i < mesh->totvert; ++i, ++vert)
+ copy_v3_v3_short(vert->no, vertNormals[i]);
+
+ mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+}
+
/**
* Compute 'split' (aka loop, or per face corner's) normals.
*
@@ -1388,6 +1633,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac
if (free_polynors) {
MEM_freeN(polynors);
}
+
+ mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
}
void BKE_mesh_calc_normals_split(Mesh *mesh)
@@ -1421,25 +1668,25 @@ static int split_faces_prepare_new_verts(
* dealing with smooth/flat faces one can find cases that no simple algorithm can handle properly. */
BLI_assert(lnors_spacearr != NULL);
- const int num_loops = mesh->totloop;
- int num_verts = mesh->totvert;
+ const int loops_len = mesh->totloop;
+ int verts_len = mesh->totvert;
MVert *mvert = mesh->mvert;
MLoop *mloop = mesh->mloop;
- BLI_bitmap *verts_used = BLI_BITMAP_NEW(num_verts, __func__);
- BLI_bitmap *done_loops = BLI_BITMAP_NEW(num_loops, __func__);
+ BLI_bitmap *verts_used = BLI_BITMAP_NEW(verts_len, __func__);
+ BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_len, __func__);
MLoop *ml = mloop;
MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX);
- for (int loop_idx = 0; loop_idx < num_loops; loop_idx++, ml++, lnor_space++) {
+ for (int loop_idx = 0; loop_idx < loops_len; loop_idx++, ml++, lnor_space++) {
if (!BLI_BITMAP_TEST(done_loops, loop_idx)) {
const int vert_idx = ml->v;
const bool vert_used = BLI_BITMAP_TEST_BOOL(verts_used, vert_idx);
/* If vert is already used by another smooth fan, we need a new vert for this one. */
- const int new_vert_idx = vert_used ? num_verts++ : vert_idx;
+ const int new_vert_idx = vert_used ? verts_len++ : vert_idx;
BLI_assert(*lnor_space);
@@ -1484,7 +1731,7 @@ static int split_faces_prepare_new_verts(
MEM_freeN(done_loops);
MEM_freeN(verts_used);
- return num_verts - mesh->totvert;
+ return verts_len - mesh->totvert;
}
/* Detect needed new edges, and update accordingly loops' edge indices.
@@ -1552,12 +1799,12 @@ static int split_faces_prepare_new_edges(
static void split_faces_split_new_verts(
Mesh *mesh, SplitFaceNewVert *new_verts, const int num_new_verts)
{
- const int num_verts = mesh->totvert - num_new_verts;
+ const int verts_len = mesh->totvert - num_new_verts;
MVert *mvert = mesh->mvert;
/* Remember new_verts is a single linklist, so its items are in reversed order... */
MVert *new_mv = &mvert[mesh->totvert - 1];
- for (int i = mesh->totvert - 1; i >= num_verts ; i--, new_mv--, new_verts = new_verts->next) {
+ for (int i = mesh->totvert - 1; i >= verts_len ; i--, new_mv--, new_verts = new_verts->next) {
BLI_assert(new_verts->new_index == i);
BLI_assert(new_verts->new_index != new_verts->orig_index);
CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1);
@@ -1652,14 +1899,13 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
#endif
}
-
/* **** Depsgraph evaluation **** */
void BKE_mesh_eval_geometry(
- EvaluationContext *UNUSED(eval_ctx),
+ Depsgraph *depsgraph,
Mesh *mesh)
{
- DEG_debug_print_eval(__func__, mesh->id.name, mesh);
+ DEG_debug_print_eval(depsgraph, __func__, mesh->id.name, mesh);
if (mesh->bb == NULL || (mesh->bb->flag & BOUNDBOX_DIRTY)) {
BKE_mesh_texspace_calc(mesh);
}