diff options
Diffstat (limited to 'source/blender/modifiers/intern')
42 files changed, 1538 insertions, 2371 deletions
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 8c8523f8d2c..55a2cab4a76 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -136,13 +136,13 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { ArmatureModifierData *amd = (ArmatureModifierData*) md; DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ @@ -159,14 +159,14 @@ static void deformVertsEM( } static void deformMatricesEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { ArmatureModifierData *amd = (ArmatureModifierData*) md; DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts, amd->deformflag, NULL, amd->defgrp_name); diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 4602600889c..3c599d6eafd 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -39,6 +39,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_string.h" #include "BLI_ghash.h" #include "BLI_edgehash.h" @@ -51,10 +52,13 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_tessmesh.h" #include "depsgraph_private.h" -#include "MOD_util.h" +#include <ctype.h> +#include <stdlib.h> +#include <string.h> static void initData(ModifierData *md) { @@ -157,30 +161,6 @@ static float vertarray_size(MVert *mvert, int numVerts, int axis) return max_co - min_co; } -/* XXX This function fixes bad merging code, in some cases removing vertices creates indices > maxvert */ - -static int test_index_face_maxvert(MFace *mface, CustomData *fdata, int mfindex, int nr, int maxvert) -{ - if(mface->v1 >= maxvert) { - // printf("bad index in array\n"); - mface->v1= maxvert - 1; - } - if(mface->v2 >= maxvert) { - // printf("bad index in array\n"); - mface->v2= maxvert - 1; - } - if(mface->v3 >= maxvert) { - // printf("bad index in array\n"); - mface->v3= maxvert - 1; - } - if(mface->v4 >= maxvert) { - // printf("bad index in array\n"); - mface->v4= maxvert - 1; - } - - return test_index_face(mface, fdata, mfindex, nr); -} - typedef struct IndexMapEntry { /* the new vert index that this old vert index maps to */ int new; @@ -194,6 +174,8 @@ typedef struct IndexMapEntry { short merge_final; } IndexMapEntry; +#if 0 /* BMESH_TODO, keep this function??? */ + /* indexMap - an array of IndexMap entries * oldIndex - the old index to map * copyNum - the copy number to map to (original = 0, first copy = 1, etc.) @@ -219,46 +201,37 @@ static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum) } } +#endif + static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, - struct Scene *scene, Object *ob, DerivedMesh *dm, - int initFlags) + Scene *scene, Object *ob, DerivedMesh *dm, + int UNUSED(initFlags)) { - int i, j; + DerivedMesh *cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's + BMEditMesh *em = CDDM_To_BMesh(ob, cddm, NULL); + BMOperator op, oldop, weldop; + int i, j, indexLen; /* offset matrix */ float offset[4][4]; - float final_offset[4][4]; - float tmp_mat[4][4]; float length = amd->length; - int count = amd->count; - int numVerts, numEdges, numFaces; - int maxVerts, maxEdges, maxFaces; - int finalVerts, finalEdges, finalFaces; - DerivedMesh *result, *start_cap = NULL, *end_cap = NULL; - MVert *mvert, *src_mvert; - MEdge *medge; - MFace *mface; - - IndexMapEntry *indexMap; - - EdgeHash *edges; + int count = amd->count, maxVerts; + int *indexMap = NULL; + DerivedMesh *start_cap = NULL, *end_cap = NULL; + MVert *src_mvert; /* need to avoid infinite recursion here */ if(amd->start_cap && amd->start_cap != ob) - start_cap = amd->start_cap->derivedFinal; + start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH); if(amd->end_cap && amd->end_cap != ob) - end_cap = amd->end_cap->derivedFinal; + end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH); unit_m4(offset); - indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm), - "indexmap"); - - src_mvert = dm->getVertArray(dm); - - maxVerts = dm->getNumVerts(dm); + src_mvert = cddm->getVertArray(dm); + maxVerts = cddm->getNumVerts(dm); if(amd->offset_type & MOD_ARR_OFF_CONST) - add_v3_v3(offset[3], amd->offset); + add_v3_v3v3(offset[3], offset[3], amd->offset); if(amd->offset_type & MOD_ARR_OFF_RELATIVE) { for(j = 0; j < 3; j++) offset[3][j] += amd->scale[j] * vertarray_size(src_mvert, @@ -316,461 +289,113 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if(count < 1) count = 1; - /* allocate memory for count duplicates (including original) plus - * start and end caps - */ - finalVerts = dm->getNumVerts(dm) * count; - finalEdges = dm->getNumEdges(dm) * count; - finalFaces = dm->getNumFaces(dm) * count; - if(start_cap) { - finalVerts += start_cap->getNumVerts(start_cap); - finalEdges += start_cap->getNumEdges(start_cap); - finalFaces += start_cap->getNumFaces(start_cap); - } - if(end_cap) { - finalVerts += end_cap->getNumVerts(end_cap); - finalEdges += end_cap->getNumEdges(end_cap); - finalFaces += end_cap->getNumFaces(end_cap); - } - result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces); - - /* calculate the offset matrix of the final copy (for merging) */ - unit_m4(final_offset); - - for(j=0; j < count - 1; j++) { - mult_m4_m4m4(tmp_mat, offset, final_offset); - copy_m4_m4(final_offset, tmp_mat); - } - - numVerts = numEdges = numFaces = 0; - mvert = CDDM_get_verts(result); - - for (i = 0; i < maxVerts; i++) { - indexMap[i].merge = -1; /* default to no merge */ - indexMap[i].merge_final = 0; /* default to no merge */ - } - - for (i = 0; i < maxVerts; i++) { - MVert *inMV; - MVert *mv = &mvert[numVerts]; - MVert *mv2; - float co[3]; - - inMV = &src_mvert[i]; - - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv = *inMV; - numVerts++; - - indexMap[i].new = numVerts - 1; - - copy_v3_v3(co, mv->co); - - /* Attempts to merge verts from one duplicate with verts from the - * next duplicate which are closer than amd->merge_dist. - * Only the first such vert pair is merged. - * If verts are merged in the first duplicate pair, they are merged - * in all pairs. - */ - if((count > 1) && (amd->flags & MOD_ARR_MERGE)) { - float tmp_co[3]; - mul_v3_m4v3(tmp_co, offset, mv->co); - - for(j = 0; j < maxVerts; j++) { - /* if vertex already merged, don't use it */ - if( indexMap[j].merge != -1 ) continue; - - inMV = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) { - indexMap[i].merge = j; - - /* test for merging with final copy of merge target */ - if(amd->flags & MOD_ARR_MERGEFINAL) { - copy_v3_v3(tmp_co, inMV->co); - inMV = &src_mvert[i]; - mul_m4_v3(final_offset, tmp_co); - if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) - indexMap[i].merge_final = 1; - } - break; - } + /* BMESH_TODO: bumping up the stack level avoids computing the normals + after every top-level operator execution (and this modifier has the + potential to execute a *lot* of top-level BMOps. There should be a + cleaner way to do this. One possibility: a "mirror" BMOp would + certainly help by compressing it all into one top-level BMOp that + executes a lot of second-level BMOps. */ + BMO_push(em->bm, NULL); + bmesh_begin_edit(em->bm, 0); + + BMO_Init_Op(em->bm, &weldop, "weldverts"); + BMO_InitOpf(em->bm, &op, "dupe geom=%avef"); + oldop = op; + for (j=0; j < count - 1; j++) { + BMVert *v, *v2; + BMOpSlot *s1; + BMOpSlot *s2; + + BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout"); + BMO_Exec_Op(em->bm, &op); + + s1 = BMO_GetSlot(&op, "geom"); + s2 = BMO_GetSlot(&op, "newout"); + + BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout"); + + #define _E(s, i) ((BMVert**)(s)->data.buf)[i] + + /*calculate merge mapping*/ + if (j == 0) { + BMOperator findop; + BMOIter oiter; + BMVert *v, *v2; + BMHeader *h; + + BMO_InitOpf(em->bm, &findop, + "finddoubles verts=%av dist=%f keepverts=%s", + amd->merge_dist, &op, "geom"); + + i = 0; + BMO_ITER(h, &oiter, em->bm, &op, "geom", BM_ALL) { + BM_SetIndex(h, i); /* set_dirty */ + i++; } - } - - /* if no merging, generate copies of this vert */ - if(indexMap[i].merge < 0) { - for(j=0; j < count - 1; j++) { - mv2 = &mvert[numVerts]; - - DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1); - *mv2 = *mv; - numVerts++; - mul_m4_v3(offset, co); - copy_v3_v3(mv2->co, co); + BMO_ITER(h, &oiter, em->bm, &op, "newout", BM_ALL) { + BM_SetIndex(h, i); /* set_dirty */ + i++; } - } else if(indexMap[i].merge != i && indexMap[i].merge_final) { - /* if this vert is not merging with itself, and it is merging - * with the final copy of its merge target, remove the first copy - */ - numVerts--; - DM_free_vert_data(result, numVerts, 1); - } - } - - /* make a hashtable so we can avoid duplicate edges from merging */ - edges = BLI_edgehash_new(); - - maxEdges = dm->getNumEdges(dm); - medge = CDDM_get_edges(result); - for(i = 0; i < maxEdges; i++) { - MEdge inMED; - MEdge med; - MEdge *med2; - int vert1, vert2; - - dm->getEdge(dm, i, &inMED); - - med = inMED; - med.v1 = indexMap[inMED.v1].new; - med.v2 = indexMap[inMED.v2].new; - - /* if vertices are to be merged with the final copies of their - * merge targets, calculate that final copy - */ - if(indexMap[inMED.v1].merge_final) { - med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge, - count - 1); - } - if(indexMap[inMED.v2].merge_final) { - med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge, - count - 1); - } - - if(med.v1 == med.v2) continue; - - /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ - if(med.v1 >= numVerts) - med.v1= numVerts-1; - if(med.v2 >= numVerts) - med.v2= numVerts-1; - - if (initFlags) { - med.flag |= ME_EDGEDRAW | ME_EDGERENDER; - } + /* above loops over all, so set all to dirty, if this is somehow + * setting valid values, this line can be remvoed - campbell */ + em->bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE; - if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) { - DM_copy_edge_data(dm, result, i, numEdges, 1); - medge[numEdges] = med; - numEdges++; - BLI_edgehash_insert(edges, med.v1, med.v2, NULL); - } - - for(j = 1; j < count; j++) - { - vert1 = calc_mapping(indexMap, inMED.v1, j); - vert2 = calc_mapping(indexMap, inMED.v2, j); - - /* edge could collapse to single point after mapping */ - if(vert1 == vert2) continue; + BMO_Exec_Op(em->bm, &findop); - /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ - if(vert1 >= numVerts) - vert1= numVerts-1; - if(vert2 >= numVerts) - vert2= numVerts-1; + indexLen = i; + indexMap = MEM_callocN(sizeof(int)*indexLen, "indexMap"); - /* avoid duplicate edges */ - if(!BLI_edgehash_haskey(edges, vert1, vert2)) { - med2 = &medge[numEdges]; + /*element type argument doesn't do anything here*/ + BMO_ITER(v, &oiter, em->bm, &findop, "targetmapout", 0) { + v2 = BMO_IterMapValp(&oiter); - DM_copy_edge_data(dm, result, i, numEdges, 1); - *med2 = med; - numEdges++; - - med2->v1 = vert1; - med2->v2 = vert2; - - BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL); + indexMap[BM_GetIndex(v)] = BM_GetIndex(v2)+1; } - } - } - - maxFaces = dm->getNumFaces(dm); - mface = CDDM_get_faces(result); - for (i=0; i < maxFaces; i++) { - MFace inMF; - MFace *mf = &mface[numFaces]; - - dm->getFace(dm, i, &inMF); - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf = inMF; - - mf->v1 = indexMap[inMF.v1].new; - mf->v2 = indexMap[inMF.v2].new; - mf->v3 = indexMap[inMF.v3].new; - if(inMF.v4) - mf->v4 = indexMap[inMF.v4].new; - - /* if vertices are to be merged with the final copies of their - * merge targets, calculate that final copy - */ - if(indexMap[inMF.v1].merge_final) - mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1); - if(indexMap[inMF.v2].merge_final) - mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1); - if(indexMap[inMF.v3].merge_final) - mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1); - if(inMF.v4 && indexMap[inMF.v4].merge_final) - mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1); - - if(test_index_face_maxvert(mf, &result->faceData, numFaces, inMF.v4?4:3, numVerts) < 3) - continue; - - numFaces++; - - /* if the face has fewer than 3 vertices, don't create it */ - if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) { - numFaces--; - DM_free_face_data(result, numFaces, 1); + BMO_Finish_Op(em->bm, &findop); } - for(j = 1; j < count; j++) - { - MFace *mf2 = &mface[numFaces]; - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf2 = *mf; - - mf2->v1 = calc_mapping(indexMap, inMF.v1, j); - mf2->v2 = calc_mapping(indexMap, inMF.v2, j); - mf2->v3 = calc_mapping(indexMap, inMF.v3, j); - if (inMF.v4) - mf2->v4 = calc_mapping(indexMap, inMF.v4, j); - - numFaces++; - - /* if the face has fewer than 3 vertices, don't create it */ - if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) { - numFaces--; - DM_free_face_data(result, numFaces, 1); - } - } - } - - /* add start and end caps */ - if(start_cap) { - float startoffset[4][4]; - MVert *cap_mvert; - MEdge *cap_medge; - MFace *cap_mface; - int *origindex; - int *vert_map; - int capVerts, capEdges, capFaces; - - capVerts = start_cap->getNumVerts(start_cap); - capEdges = start_cap->getNumEdges(start_cap); - capFaces = start_cap->getNumFaces(start_cap); - cap_mvert = start_cap->getVertArray(start_cap); - cap_medge = start_cap->getEdgeArray(start_cap); - cap_mface = start_cap->getFaceArray(start_cap); - - invert_m4_m4(startoffset, offset); - - vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, - "arrayModifier_doArray vert_map"); - - origindex = result->getVertDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capVerts; i++) { - MVert *mv = &cap_mvert[i]; - short merged = 0; - - if(amd->flags & MOD_ARR_MERGE) { - float tmp_co[3]; - MVert *in_mv; - int j; - - copy_v3_v3(tmp_co, mv->co); - mul_m4_v3(startoffset, tmp_co); - - for(j = 0; j < maxVerts; j++) { - in_mv = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { - vert_map[i] = calc_mapping(indexMap, j, 0); - merged = 1; - break; - } - } - } - - if(!merged) { - DM_copy_vert_data(start_cap, result, i, numVerts, 1); - mvert[numVerts] = *mv; - mul_m4_v3(startoffset, mvert[numVerts].co); - origindex[numVerts] = ORIGINDEX_NONE; - - vert_map[i] = numVerts; + /*generate merge mappping using index map. we do this by using the + operator slots as lookup arrays.*/ + #define E(i) (i) < s1->len ? _E(s1, i) : _E(s2, (i)-s1->len) - numVerts++; - } - } - origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capEdges; i++) { - int v1, v2; - - v1 = vert_map[cap_medge[i].v1]; - v2 = vert_map[cap_medge[i].v2]; + for (i=0; i<indexLen; i++) { + if (!indexMap[i]) continue; - if(!BLI_edgehash_haskey(edges, v1, v2)) { - DM_copy_edge_data(start_cap, result, i, numEdges, 1); - medge[numEdges] = cap_medge[i]; - medge[numEdges].v1 = v1; - medge[numEdges].v2 = v2; - origindex[numEdges] = ORIGINDEX_NONE; + v = E(i); + v2 = E(indexMap[i]-1); - numEdges++; - } + BMO_Insert_MapPointer(em->bm, &weldop, "targetmap", v, v2); } - origindex = result->getFaceDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capFaces; i++) { - DM_copy_face_data(start_cap, result, i, numFaces, 1); - mface[numFaces] = cap_mface[i]; - mface[numFaces].v1 = vert_map[mface[numFaces].v1]; - mface[numFaces].v2 = vert_map[mface[numFaces].v2]; - mface[numFaces].v3 = vert_map[mface[numFaces].v3]; - if(mface[numFaces].v4) { - mface[numFaces].v4 = vert_map[mface[numFaces].v4]; - - test_index_face_maxvert(&mface[numFaces], &result->faceData, - numFaces, 4, numVerts); - } - else - { - test_index_face(&mface[numFaces], &result->faceData, - numFaces, 3); - } - origindex[numFaces] = ORIGINDEX_NONE; + #undef E + #undef _E - numFaces++; - } - - MEM_freeN(vert_map); - start_cap->release(start_cap); + BMO_Finish_Op(em->bm, &oldop); + oldop = op; } - if(end_cap) { - float endoffset[4][4]; - MVert *cap_mvert; - MEdge *cap_medge; - MFace *cap_mface; - int *origindex; - int *vert_map; - int capVerts, capEdges, capFaces; - - capVerts = end_cap->getNumVerts(end_cap); - capEdges = end_cap->getNumEdges(end_cap); - capFaces = end_cap->getNumFaces(end_cap); - cap_mvert = end_cap->getVertArray(end_cap); - cap_medge = end_cap->getEdgeArray(end_cap); - cap_mface = end_cap->getFaceArray(end_cap); - - mult_m4_m4m4(endoffset, offset, final_offset); - - vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, - "arrayModifier_doArray vert_map"); - - origindex = result->getVertDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capVerts; i++) { - MVert *mv = &cap_mvert[i]; - short merged = 0; - - if(amd->flags & MOD_ARR_MERGE) { - float tmp_co[3]; - MVert *in_mv; - int j; - - copy_v3_v3(tmp_co, mv->co); - mul_m4_v3(offset, tmp_co); - - for(j = 0; j < maxVerts; j++) { - in_mv = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { - vert_map[i] = calc_mapping(indexMap, j, count - 1); - merged = 1; - break; - } - } - } - - if(!merged) { - DM_copy_vert_data(end_cap, result, i, numVerts, 1); - mvert[numVerts] = *mv; - mul_m4_v3(endoffset, mvert[numVerts].co); - origindex[numVerts] = ORIGINDEX_NONE; + if (j > 0) BMO_Finish_Op(em->bm, &op); - vert_map[i] = numVerts; + if (amd->flags & MOD_ARR_MERGE) + BMO_Exec_Op(em->bm, &weldop); - numVerts++; - } - } - origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capEdges; i++) { - int v1, v2; + BMO_Finish_Op(em->bm, &weldop); - v1 = vert_map[cap_medge[i].v1]; - v2 = vert_map[cap_medge[i].v2]; + /* Bump the stack level back down to match the adjustment up above */ + bmesh_end_edit(em->bm, 0); + BMO_pop(em->bm); - if(!BLI_edgehash_haskey(edges, v1, v2)) { - DM_copy_edge_data(end_cap, result, i, numEdges, 1); - medge[numEdges] = cap_medge[i]; - medge[numEdges].v1 = v1; - medge[numEdges].v2 = v2; - origindex[numEdges] = ORIGINDEX_NONE; + BMEdit_RecalcTesselation(em); + cddm = CDDM_from_BMEditMesh(em, NULL, 0); - numEdges++; - } - } - origindex = result->getFaceDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capFaces; i++) { - DM_copy_face_data(end_cap, result, i, numFaces, 1); - mface[numFaces] = cap_mface[i]; - mface[numFaces].v1 = vert_map[mface[numFaces].v1]; - mface[numFaces].v2 = vert_map[mface[numFaces].v2]; - mface[numFaces].v3 = vert_map[mface[numFaces].v3]; - if(mface[numFaces].v4) { - mface[numFaces].v4 = vert_map[mface[numFaces].v4]; - - test_index_face(&mface[numFaces], &result->faceData, - numFaces, 4); - } - else - { - test_index_face(&mface[numFaces], &result->faceData, - numFaces, 3); - } - origindex[numFaces] = ORIGINDEX_NONE; - - numFaces++; - } - - MEM_freeN(vert_map); - end_cap->release(end_cap); - } - - BLI_edgehash_free(edges, NULL); + BMEdit_Free(em); + MEM_freeN(em); MEM_freeN(indexMap); - CDDM_lower_num_verts(result, numVerts); - CDDM_lower_num_edges(result, numEdges); - CDDM_lower_num_faces(result, numFaces); - - return result; + return cddm; } static DerivedMesh *applyModifier(ModifierData *md, Object *ob, @@ -783,14 +408,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = arrayModifier_doArray(amd, md->scene, ob, dm, 0); - if(result != dm) - CDDM_calc_normals(result); + //if(result != dm) + // CDDM_calc_normals_mapping(result); return result; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *dm) { return applyModifier(md, ob, dm, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 160167808fc..1a3f8cdb7f3 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -32,17 +32,20 @@ * \ingroup modifiers */ -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" +#include "BLI_math.h" #include "BLI_string.h" -#include "BKE_bmesh.h" #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" -#include "BKE_particle.h" +#include "BKE_tessmesh.h" +#include "BKE_mesh.h" -#include "MOD_util.h" +#include "BKE_bmesh.h" /* only for defines */ + +#include "DNA_object_types.h" + +#include "MEM_guardedalloc.h" static void initData(ModifierData *md) @@ -85,6 +88,87 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } +#define EDGE_MARK 1 + + +/* BMESH_TODO + * + * this bevel calls the operator which is missing many of the options + * which the bevel modifier in trunk has. + * - width is interpreted as percent (not distance) + * - no vertex bevel + * - no weight bevel + * + * These will need to be added to the bmesh operator. + * - campbell + * + * note: this code is very close to MOD_edgesplit.c. + * note: if 0'd code from trunk included below. + */ +static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, + DerivedMesh *dm, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + BMesh *bm; + BMEditMesh *em; + DerivedMesh *cddm; + BMIter iter; + BMEdge *e; + BevelModifierData *bmd = (BevelModifierData*) md; + /* int allocsize[] = {512, 512, 2048, 512}; */ /* UNUSED */ + float threshold = cos((bmd->bevel_angle + 0.00001) * M_PI / 180.0); + + if (!CDDM_Check(dm)) { + cddm = CDDM_copy(dm, 0); + } else cddm = dm; + + em = CDDM_To_BMesh(ob, dm, NULL); + bm = em->bm; + + BM_Compute_Normals(bm); + BMO_push(bm, NULL); + + if (bmd->lim_flags & BME_BEVEL_ANGLE) { + BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { + /* check for 1 edge having 2 face users */ + BMLoop *l1, *l2; + if ( (l1= e->l) && + (l2= e->l->radial_next) != l1) + { + if (dot_v3v3(l1->f->no, l2->f->no) < threshold) { + BMO_SetFlag(bm, e, EDGE_MARK); + } + } + } + } + else { + /* crummy, is there a way just to operator on all? - campbell */ + BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { + BMO_SetFlag(bm, e, EDGE_MARK); + } + } + + BMO_CallOpf(bm, "bevel geom=%fe percent=%f use_even=%i use_dist=%i", + EDGE_MARK, bmd->value, (bmd->flags & BME_BEVEL_EVEN)!=0, (bmd->flags & BME_BEVEL_DIST)!=0); + BMO_pop(bm); + BMEdit_RecalcTesselation(em); + + if (cddm != dm) { + cddm->needsFree = 1; + cddm->release(cddm); + } + + cddm = CDDM_from_BMEditMesh(em, NULL, 1); + BMEdit_Free(em); + MEM_freeN(em); + + return cddm; +} + + +#if 0 /* from trunk, see note above */ + static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, int UNUSED(useRenderParams), @@ -111,13 +195,15 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), result = BME_bmesh_to_derivedmesh(bm,derivedData); BME_free_mesh(bm); - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); return result; } +#endif + static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 16f0912bd9b..e773b772b2b 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -93,15 +93,15 @@ static DerivedMesh *get_quick_derivedMesh(DerivedMesh *derivedData, DerivedMesh { DerivedMesh *result = NULL; - if(derivedData->getNumFaces(derivedData) == 0 || dm->getNumFaces(dm) == 0) { + if(derivedData->getNumPolys(derivedData) == 0 || dm->getNumPolys(dm) == 0) { switch(operation) { case eBooleanModifierOp_Intersect: - result = CDDM_new(0, 0, 0); + result = CDDM_new(0, 0, 0, 0, 0); break; case eBooleanModifierOp_Union: - if(derivedData->getNumFaces(derivedData)) result = derivedData; - else result = CDDM_copy(dm); + if(derivedData->getNumPolys(derivedData)) result = derivedData; + else result = CDDM_copy(dm, FALSE); break; @@ -136,6 +136,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = get_quick_derivedMesh(derivedData, dm, bmd->operation); if(result == NULL) { + + DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + DM_ensure_tessface(derivedData); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob, 1 + bmd->operation); } diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index afd16b41131..4c17ee54fd2 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -173,14 +173,14 @@ static int FaceIt_Done(CSG_IteratorPtr it) { // assume CSG_IteratorPtr is of the correct type. FaceIt * iterator = (FaceIt *)it; - return(iterator->pos >= iterator->dm->getNumFaces(iterator->dm)); + return(iterator->pos >= iterator->dm->getNumTessFaces(iterator->dm)); } static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face) { // assume CSG_IteratorPtr is of the correct type. FaceIt *face_it = (FaceIt *)it; - MFace *mfaces = face_it->dm->getFaceArray(face_it->dm); + MFace *mfaces = face_it->dm->getTessFaceArray(face_it->dm); MFace *mface = &mfaces[face_it->pos]; /* reverse face vertices if necessary */ @@ -254,7 +254,7 @@ static void FaceIt_Construct( output->Fill = FaceIt_Fill; output->Done = FaceIt_Done; output->Reset = FaceIt_Reset; - output->num_elements = it->dm->getNumFaces(it->dm); + output->num_elements = it->dm->getNumTessFaces(it->dm); output->it = it; } @@ -304,8 +304,8 @@ static void InterpCSGFace( MFace *mface, *orig_mface; int j; - mface = CDDM_get_face(dm, index); - orig_mface = orig_dm->getFaceArray(orig_dm) + orig_index; + mface = CDDM_get_tessface(dm, index); + orig_mface = orig_dm->getTessFaceArray(orig_dm) + orig_index; // get the vertex coordinates from the original mesh orig_co[0] = (orig_dm->getVertArray(orig_dm) + orig_mface->v1)->co; @@ -353,7 +353,7 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( int i; // create a new DerivedMesh - result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements); + result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements, 0, 0); CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH, CD_DEFAULT, face_it->num_elements); CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH, @@ -393,16 +393,16 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( face_it->Step(face_it->it); // find the original mesh and data - orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2; - orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2; + orig_ob = (csgface.orig_face < dm1->getNumTessFaces(dm1))? ob1: ob2; + orig_dm = (csgface.orig_face < dm1->getNumTessFaces(dm1))? dm1: dm2; orig_me = (orig_ob == ob1)? me1: me2; - orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1); + orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumTessFaces(dm1); // copy all face layers, including mface CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1); // set mface - mface = CDDM_get_face(result, i); + mface = CDDM_get_tessface(result, i); mface->v1 = csgface.vertex_index[0]; mface->v2 = csgface.vertex_index[1]; mface->v3 = csgface.vertex_index[2]; @@ -432,8 +432,9 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( if (material_hash) BLI_ghash_free(material_hash, NULL, NULL); - CDDM_calc_edges(result); - CDDM_calc_normals(result); + CDDM_calc_edges_tessface(result); + + CDDM_tessfaces_to_faces(result); /*builds ngon faces from tess (mface) faces*/ return result; } @@ -468,7 +469,7 @@ static DerivedMesh *NewBooleanDerivedMesh_intern( DerivedMesh *result = NULL; if (dm == NULL || dm_select == NULL) return 0; - if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) return 0; + if (!dm->getNumTessFaces(dm) || !dm_select->getNumTessFaces(dm_select)) return 0; // we map the final object back into ob's local coordinate space. For this // we need to compute the inverse transform from global to ob (inv_mat), @@ -500,7 +501,7 @@ static DerivedMesh *NewBooleanDerivedMesh_intern( } BuildMeshDescriptors(dm_select, ob_select, 0, &fd_1, &vd_1); - BuildMeshDescriptors(dm, ob, dm_select->getNumFaces(dm_select) , &fd_2, &vd_2); + BuildMeshDescriptors(dm, ob, dm_select->getNumTessFaces(dm_select) , &fd_2, &vd_2); bool_op = CSG_NewBooleanFunction(); @@ -554,7 +555,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) /* put some checks in for nice user feedback */ if (dm == NULL || dm_select == NULL) return 0; - if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) + if (!dm->getNumTessFaces(dm) || !dm_select->getNumTessFaces(dm_select)) { MEM_freeN(mat); return -1; @@ -571,7 +572,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) ob_new= AddNewBlenderMesh(scene, base_select); me_new= ob_new->data; - DM_to_mesh(result, me_new); + DM_to_mesh(result, me_new, ob_new); result->release(result); dm->release(dm); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 119934ea2f0..16b19e82e97 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -83,10 +83,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *dm = derivedData; DerivedMesh *result; BuildModifierData *bmd = (BuildModifierData*) md; - int i; - int numFaces, numEdges; + int i, j, k; + int numFaces, numEdges, numLoops = 0; int *vertMap, *edgeMap, *faceMap; float frac; + MPoly *mpolys, *mpolyd; + MLoop *mld, *mloops, *mls, *mloopd; GHashIterator *hashIter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, @@ -94,11 +96,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), /* maps edge indices in new mesh to indices in old mesh */ GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build ed apply gh"); + GHash *edgeHash2 = BLI_ghash_new(BLI_ghashutil_inthash, + BLI_ghashutil_intcmp, "build ed apply gh"); const int maxVerts= dm->getNumVerts(dm); const int maxEdges= dm->getNumEdges(dm); - const int maxFaces= dm->getNumFaces(dm); - + const int maxFaces= dm->getNumPolys(dm); + + if (!CDDM_Check(dm)) { + result = CDDM_copy(dm, 0); + dm = result; + } + vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); for(i = 0; i < maxVerts; ++i) vertMap[i] = i; edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap"); @@ -109,11 +118,15 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); - numFaces = dm->getNumFaces(dm) * frac; + numFaces = dm->getNumPolys(dm) * frac; numEdges = dm->getNumEdges(dm) * frac; /* if there's at least one face, build based on faces */ if(numFaces) { + MPoly *mpoly, *mp; + MLoop *ml, *mloop; + MEdge *medge; + if(bmd->randomize) BLI_array_randomize(faceMap, sizeof(*faceMap), maxFaces, bmd->seed); @@ -121,37 +134,40 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ + mpoly = CDDM_get_polys(dm); + mloop = CDDM_get_loops(dm); for(i = 0; i < numFaces; ++i) { - MFace mf; - dm->getFace(dm, faceMap[i], &mf); - - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + mp = mpoly + faceMap[i]; + ml = mloop + mp->loopstart; + + for (j=0; j<mp->totloop; j++, ml++) { + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(ml->v), + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + } + + numLoops += mp->totloop; } /* get the set of edges that will be in the new mesh (i.e. all edges * that have both verts in the new mesh) */ + medge = CDDM_get_edges(dm); for(i = 0; i < maxEdges; ++i) { - MEdge me; - dm->getEdge(dm, i, &me); - - if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) - && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) - BLI_ghash_insert(edgeHash, - SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i)); + MEdge *me = medge + i; + + if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) + && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) + { + j = BLI_ghash_size(edgeHash); + + BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(i)); + BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(j)); + } } } else if(numEdges) { + MEdge *medge, *me; + if(bmd->randomize) BLI_array_randomize(edgeMap, sizeof(*edgeMap), maxEdges, bmd->seed); @@ -159,26 +175,27 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ + medge = CDDM_get_edges(dm); for(i = 0; i < numEdges; ++i) { - MEdge me; - dm->getEdge(dm, edgeMap[i], &me); + me = medge + edgeMap[i]; - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), + if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1))) + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v1), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), + if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v2), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } /* get the set of edges that will be in the new mesh */ for(i = 0; i < numEdges; ++i) { - MEdge me; - dm->getEdge(dm, edgeMap[i], &me); - - BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), + j = BLI_ghash_size(edgeHash); + + BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(edgeMap[i])); + BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(edgeMap[i]), + SET_INT_IN_POINTER(j)); } } else { int numVerts = dm->getNumVerts(dm) * frac; @@ -198,7 +215,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), * the mesh */ result = CDDM_from_template(dm, BLI_ghash_size(vertHash), - BLI_ghash_size(edgeHash), numFaces); + BLI_ghash_size(edgeHash), 0, numLoops, numFaces); /* copy the vertices across */ for( hashIter = BLI_ghashIterator_new(vertHash); @@ -234,38 +251,48 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), *dest = source; } + mpolys = CDDM_get_polys(dm); + mpolyd = CDDM_get_polys(result); + mloops = CDDM_get_loops(dm); + mloopd = mld = CDDM_get_loops(result); + /* copy the faces across, remapping indices */ + k = 0; for(i = 0; i < numFaces; ++i) { - MFace source; - MFace *dest; - int orig_v4; + MPoly *source; + MPoly *dest; - dm->getFace(dm, faceMap[i], &source); - dest = CDDM_get_face(result, i); - - orig_v4 = source.v4; - - source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); - source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); - source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); - if(source.v4) - source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); + source = mpolys + faceMap[i]; + dest = mpolyd + i; + DM_copy_poly_data(dm, result, faceMap[i], i, 1); - DM_copy_face_data(dm, result, faceMap[i], i, 1); - *dest = source; + *dest = *source; + dest->loopstart = k; - test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3)); + DM_copy_loop_data(dm, result, source->loopstart, dest->loopstart, dest->totloop); + + mls = mloops + source->loopstart; + for (j=0; j<source->totloop; j++, k++, mls++, mld++) { + mld->v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(mls->v))); + mld->e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash2, SET_INT_IN_POINTER(mls->e))); + } } - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); + BLI_ghash_free(edgeHash2, NULL, NULL); MEM_freeN(vertMap); MEM_freeN(edgeMap); MEM_freeN(faceMap); + if (dm != derivedData) { + dm->needsFree = 1; + dm->release(dm); + } + return result; } diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 78bebc0b5e2..75aecc4f5af 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -585,7 +585,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 6c9bbd11e9c..78bc64be1cd 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -88,7 +88,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if(result) { - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); return result; } return dm; diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 0cd3481c899..2de7400065f 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -117,7 +117,7 @@ static void deformVerts(ModifierData *md, Object *ob, MVert *tempVert = NULL; /* if possible use/create DerivedMesh */ - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); if(!ob->pd) @@ -132,7 +132,7 @@ static void deformVerts(ModifierData *md, Object *ob, unsigned int numverts = 0; CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + CDDM_calc_normals_mapping(dm); current_time = BKE_curframe(md->scene); @@ -166,8 +166,8 @@ static void deformVerts(ModifierData *md, Object *ob, collmd->numverts = numverts; - collmd->mfaces = dm->dupFaceArray(dm); - collmd->numfaces = dm->getNumFaces(dm); + collmd->mfaces = dm->dupTessFaceArray(dm); + collmd->numfaces = dm->getNumTessFaces(dm); // create bounding box hierarchy collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft); diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 9a7dd3fc898..945c5c5a583 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -124,12 +124,12 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index d1092345930..bb7e1f52062 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -81,10 +81,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), int totvert, totface; int a, numTris; + DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + mvert = dm->getVertArray(dm); - mface = dm->getFaceArray(dm); + mface = dm->getTessFaceArray(dm); totvert = dm->getNumVerts(dm); - totface = dm->getNumFaces(dm); + totface = dm->getNumTessFaces(dm); numTris = 0; for (a=0; a<totface; a++) { @@ -96,7 +98,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), if(numTris<3) { modifier_setError(md, "Modifier requires more than 3 input faces (triangles)."); - goto exit; + dm = CDDM_copy(dm, 0); + return dm; } lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices"); @@ -140,11 +143,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } if(lod.vertex_num>2) { - result = CDDM_new(lod.vertex_num, 0, lod.face_num); + result = CDDM_new(lod.vertex_num, 0, lod.face_num, 0, 0); dmd->faceCount = lod.face_num; } else - result = CDDM_new(lod.vertex_num, 0, 0); + result = CDDM_new(lod.vertex_num, 0, 0, 0, 0); mvert = CDDM_get_verts(result); for(a=0; a<lod.vertex_num; a++) { @@ -155,7 +158,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } if(lod.vertex_num>2) { - mface = CDDM_get_faces(result); + mface = CDDM_get_tessfaces(result); for(a=0; a<lod.face_num; a++) { MFace *mf = &mface[a]; int *tri = &lod.triangle_index_buffer[a*3]; @@ -166,8 +169,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } } - CDDM_calc_edges(result); - CDDM_calc_normals(result); + CDDM_calc_edges_tessface(result); } else modifier_setError(md, "Out of memory."); @@ -181,8 +183,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), MEM_freeN(lod.vertex_normal_buffer); MEM_freeN(lod.triangle_index_buffer); -exit: + if (result) { + CDDM_tessfaces_to_faces(result); /*builds ngon faces from tess (mface) faces*/ + return result; + } + else { + return dm; + } } #else // WITH_MOD_DECIMATE static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 1ac11da25db..e0972ff2d32 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -251,7 +251,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm= get_cddm(ob, editData, derivedData, vertexCos); diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 32ab2c82f90..2984a387fd8 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -36,1252 +36,130 @@ /* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag * or edge angle (can be used to achieve autosmoothing) */ -#include <assert.h> - -#include "DNA_meshdata_types.h" - -#include "BLI_listbase.h" -#include "BLI_memarena.h" -#include "BLI_edgehash.h" -#include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_linklist.h" +#include "BLI_math.h" #include "MEM_guardedalloc.h" #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" -#include "BKE_particle.h" - - -#include "MOD_util.h" - -#if 0 -#define EDGESPLIT_DEBUG_3 -#define EDGESPLIT_DEBUG_2 -#define EDGESPLIT_DEBUG_1 -#define EDGESPLIT_DEBUG_0 -#endif - -static void initData(ModifierData *md) -{ - EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - - /* default to 30-degree split angle, sharpness from both angle & flag - */ - emd->split_angle = 30; - emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG; -} - -static void copyData(ModifierData *md, ModifierData *target) -{ - EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - EdgeSplitModifierData *temd = (EdgeSplitModifierData*) target; - - temd->split_angle = emd->split_angle; - temd->flags = emd->flags; -} - -/* Mesh data for edgesplit operation */ -typedef struct SmoothVert { - LinkNode *faces; /* all faces which use this vert */ - int oldIndex; /* the index of the original DerivedMesh vert */ - int newIndex; /* the index of the new DerivedMesh vert */ -} SmoothVert; - -#define SMOOTHEDGE_NUM_VERTS 2 - -typedef struct SmoothEdge { - SmoothVert *verts[SMOOTHEDGE_NUM_VERTS]; /* the verts used by this edge */ - LinkNode *faces; /* all faces which use this edge */ - int oldIndex; /* the index of the original DerivedMesh edge */ - int newIndex; /* the index of the new DerivedMesh edge */ - short flag; /* the flags from the original DerivedMesh edge */ -} SmoothEdge; - -#define SMOOTHFACE_MAX_EDGES 4 - -typedef struct SmoothFace { - SmoothEdge *edges[SMOOTHFACE_MAX_EDGES]; /* nonexistent edges == NULL */ - int flip[SMOOTHFACE_MAX_EDGES]; /* 1 = flip edge dir, 0 = don't flip */ - float normal[3]; /* the normal of this face */ - int oldIndex; /* the index of the original DerivedMesh face */ - int newIndex; /* the index of the new DerivedMesh face */ -} SmoothFace; - -typedef struct SmoothMesh { - SmoothVert *verts; - SmoothEdge *edges; - SmoothFace *faces; - int num_verts, num_edges, num_faces; - int max_verts, max_edges, max_faces; - DerivedMesh *dm; - float threshold; /* the cosine of the smoothing angle */ - int flags; - MemArena *arena; - ListBase propagatestack, reusestack; -} SmoothMesh; - -static SmoothVert *smoothvert_copy(SmoothVert *vert, SmoothMesh *mesh) -{ - SmoothVert *copy = &mesh->verts[mesh->num_verts]; - - assert(vert != NULL); - - if(mesh->num_verts >= mesh->max_verts) { - printf("Attempted to add a SmoothMesh vert beyond end of array\n"); - return NULL; - } - - *copy = *vert; - copy->faces = NULL; - copy->newIndex = mesh->num_verts; - ++mesh->num_verts; - -#ifdef EDGESPLIT_DEBUG_2 - printf("copied vert %4d to vert %4d\n", vert->newIndex, copy->newIndex); -#endif - return copy; -} - -static SmoothEdge *smoothedge_copy(SmoothEdge *edge, SmoothMesh *mesh) -{ - SmoothEdge *copy = &mesh->edges[mesh->num_edges]; - - if(mesh->num_edges >= mesh->max_edges) { - printf("Attempted to add a SmoothMesh edge beyond end of array\n"); - return NULL; - } - - *copy = *edge; - copy->faces = NULL; - copy->newIndex = mesh->num_edges; - ++mesh->num_edges; - -#ifdef EDGESPLIT_DEBUG_2 - printf("copied edge %4d to edge %4d\n", edge->newIndex, copy->newIndex); -#endif - return copy; -} - -static int smoothedge_has_vert(SmoothEdge *edge, SmoothVert *vert) -{ - int i; - for(i = 0; i < SMOOTHEDGE_NUM_VERTS; i++) - if(edge->verts[i] == vert) return 1; - - return 0; -} - -static SmoothMesh *smoothmesh_new(int num_verts, int num_edges, int num_faces, - int max_verts, int max_edges, int max_faces) -{ - SmoothMesh *mesh = MEM_callocN(sizeof(*mesh), "smoothmesh"); - mesh->verts = MEM_callocN(sizeof(*mesh->verts) * max_verts, - "SmoothMesh.verts"); - mesh->edges = MEM_callocN(sizeof(*mesh->edges) * max_edges, - "SmoothMesh.edges"); - mesh->faces = MEM_callocN(sizeof(*mesh->faces) * max_faces, - "SmoothMesh.faces"); - - mesh->num_verts = num_verts; - mesh->num_edges = num_edges; - mesh->num_faces = num_faces; - - mesh->max_verts = max_verts; - mesh->max_edges = max_edges; - mesh->max_faces = max_faces; - - return mesh; -} - -static void smoothmesh_free(SmoothMesh *mesh) -{ - int i; - - for(i = 0; i < mesh->num_verts; ++i) - BLI_linklist_free(mesh->verts[i].faces, NULL); - - for(i = 0; i < mesh->num_edges; ++i) - BLI_linklist_free(mesh->edges[i].faces, NULL); - - if(mesh->arena) - BLI_memarena_free(mesh->arena); - - MEM_freeN(mesh->verts); - MEM_freeN(mesh->edges); - MEM_freeN(mesh->faces); - MEM_freeN(mesh); -} - -static void smoothmesh_resize_verts(SmoothMesh *mesh, int max_verts) -{ - int i; - SmoothVert *tmp; - - if(max_verts <= mesh->max_verts) return; - - tmp = MEM_callocN(sizeof(*tmp) * max_verts, "SmoothMesh.verts"); - - memcpy(tmp, mesh->verts, sizeof(*tmp) * mesh->num_verts); - - /* remap vert pointers in edges */ - for(i = 0; i < mesh->num_edges; ++i) { - int j; - SmoothEdge *edge = &mesh->edges[i]; - - for(j = 0; j < SMOOTHEDGE_NUM_VERTS; ++j) - /* pointer arithmetic to get vert array index */ - edge->verts[j] = &tmp[edge->verts[j] - mesh->verts]; - } - - MEM_freeN(mesh->verts); - mesh->verts = tmp; - mesh->max_verts = max_verts; -} - -static void smoothmesh_resize_edges(SmoothMesh *mesh, int max_edges) -{ - int i; - SmoothEdge *tmp; - - if(max_edges <= mesh->max_edges) return; - - tmp = MEM_callocN(sizeof(*tmp) * max_edges, "SmoothMesh.edges"); - - memcpy(tmp, mesh->edges, sizeof(*tmp) * mesh->num_edges); - - /* remap edge pointers in faces */ - for(i = 0; i < mesh->num_faces; ++i) { - int j; - SmoothFace *face = &mesh->faces[i]; - - for(j = 0; j < SMOOTHFACE_MAX_EDGES; ++j) - if(face->edges[j]) - /* pointer arithmetic to get edge array index */ - face->edges[j] = &tmp[face->edges[j] - mesh->edges]; - } - - MEM_freeN(mesh->edges); - mesh->edges = tmp; - mesh->max_edges = max_edges; -} - -#ifdef EDGESPLIT_DEBUG_0 -static void smoothmesh_print(SmoothMesh *mesh) -{ - int i, j; - DerivedMesh *dm = mesh->dm; - - printf("--- SmoothMesh ---\n"); - printf("--- Vertices ---\n"); - for(i = 0; i < mesh->num_verts; i++) { - SmoothVert *vert = &mesh->verts[i]; - LinkNode *node; - MVert mv; - - dm->getVert(dm, vert->oldIndex, &mv); - - printf("%3d: ind={%3d, %3d}, pos={% 5.1f, % 5.1f, % 5.1f}", - i, vert->oldIndex, vert->newIndex, - mv.co[0], mv.co[1], mv.co[2]); - printf(", faces={"); - for(node = vert->faces; node != NULL; node = node->next) { - printf(" %d", ((SmoothFace *)node->link)->newIndex); - } - printf("}\n"); - } - - printf("\n--- Edges ---\n"); - for(i = 0; i < mesh->num_edges; i++) { - SmoothEdge *edge = &mesh->edges[i]; - LinkNode *node; - - printf("%4d: indices={%4d, %4d}, verts={%4d, %4d}", - i, - edge->oldIndex, edge->newIndex, - edge->verts[0]->newIndex, edge->verts[1]->newIndex); - if(edge->verts[0] == edge->verts[1]) printf(" <- DUPLICATE VERTEX"); - printf(", faces={"); - for(node = edge->faces; node != NULL; node = node->next) { - printf(" %d", ((SmoothFace *)node->link)->newIndex); - } - printf("}\n"); - } - - printf("\n--- Faces ---\n"); - for(i = 0; i < mesh->num_faces; i++) { - SmoothFace *face = &mesh->faces[i]; - - printf("%4d: indices={%4d, %4d}, edges={", i, - face->oldIndex, face->newIndex); - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - if(face->flip[j]) - printf(" -%-2d", face->edges[j]->newIndex); - else - printf(" %-2d", face->edges[j]->newIndex); - } - printf("}, verts={"); - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - printf(" %d", face->edges[j]->verts[face->flip[j]]->newIndex); - } - printf("}\n"); - } -} -#endif - -static SmoothMesh *smoothmesh_from_derivedmesh(DerivedMesh *dm) -{ - SmoothMesh *mesh; - EdgeHash *edges = BLI_edgehash_new(); - int i; - int totvert, totedge, totface; - - totvert = dm->getNumVerts(dm); - totedge = dm->getNumEdges(dm); - totface = dm->getNumFaces(dm); - - mesh = smoothmesh_new(totvert, totedge, totface, - totvert, totedge, totface); - - mesh->dm = dm; - - for(i = 0; i < totvert; i++) { - SmoothVert *vert = &mesh->verts[i]; - - vert->oldIndex = vert->newIndex = i; - } - - for(i = 0; i < totedge; i++) { - SmoothEdge *edge = &mesh->edges[i]; - MEdge med; - - dm->getEdge(dm, i, &med); - edge->verts[0] = &mesh->verts[med.v1]; - edge->verts[1] = &mesh->verts[med.v2]; - edge->oldIndex = edge->newIndex = i; - edge->flag = med.flag; - - BLI_edgehash_insert(edges, med.v1, med.v2, edge); - } - - for(i = 0; i < totface; i++) { - SmoothFace *face = &mesh->faces[i]; - MFace mf; - MVert v1, v2, v3; - int j; - - dm->getFace(dm, i, &mf); - - dm->getVert(dm, mf.v1, &v1); - dm->getVert(dm, mf.v2, &v2); - dm->getVert(dm, mf.v3, &v3); - face->edges[0] = BLI_edgehash_lookup(edges, mf.v1, mf.v2); - if(face->edges[0]->verts[1]->oldIndex == mf.v1) face->flip[0] = 1; - face->edges[1] = BLI_edgehash_lookup(edges, mf.v2, mf.v3); - if(face->edges[1]->verts[1]->oldIndex == mf.v2) face->flip[1] = 1; - if(mf.v4) { - MVert v4; - dm->getVert(dm, mf.v4, &v4); - face->edges[2] = BLI_edgehash_lookup(edges, mf.v3, mf.v4); - if(face->edges[2]->verts[1]->oldIndex == mf.v3) face->flip[2] = 1; - face->edges[3] = BLI_edgehash_lookup(edges, mf.v4, mf.v1); - if(face->edges[3]->verts[1]->oldIndex == mf.v4) face->flip[3] = 1; - normal_quad_v3( face->normal,v1.co, v2.co, v3.co, v4.co); - } else { - face->edges[2] = BLI_edgehash_lookup(edges, mf.v3, mf.v1); - if(face->edges[2]->verts[1]->oldIndex == mf.v3) face->flip[2] = 1; - face->edges[3] = NULL; - normal_tri_v3( face->normal,v1.co, v2.co, v3.co); - } - - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - SmoothEdge *edge = face->edges[j]; - BLI_linklist_prepend(&edge->faces, face); - BLI_linklist_prepend(&edge->verts[face->flip[j]]->faces, face); - } - - face->oldIndex = face->newIndex = i; - } - - BLI_edgehash_free(edges, NULL); - - return mesh; -} - -static DerivedMesh *CDDM_from_smoothmesh(SmoothMesh *mesh) -{ - DerivedMesh *result = CDDM_from_template(mesh->dm, - mesh->num_verts, - mesh->num_edges, - mesh->num_faces); - MVert *new_verts = CDDM_get_verts(result); - MEdge *new_edges = CDDM_get_edges(result); - MFace *new_faces = CDDM_get_faces(result); - int i; - - for(i = 0; i < mesh->num_verts; ++i) { - SmoothVert *vert = &mesh->verts[i]; - MVert *newMV = &new_verts[vert->newIndex]; - - DM_copy_vert_data(mesh->dm, result, - vert->oldIndex, vert->newIndex, 1); - mesh->dm->getVert(mesh->dm, vert->oldIndex, newMV); - } - - for(i = 0; i < mesh->num_edges; ++i) { - SmoothEdge *edge = &mesh->edges[i]; - MEdge *newME = &new_edges[edge->newIndex]; - - DM_copy_edge_data(mesh->dm, result, - edge->oldIndex, edge->newIndex, 1); - mesh->dm->getEdge(mesh->dm, edge->oldIndex, newME); - newME->v1 = edge->verts[0]->newIndex; - newME->v2 = edge->verts[1]->newIndex; - } - - for(i = 0; i < mesh->num_faces; ++i) { - SmoothFace *face = &mesh->faces[i]; - MFace *newMF = &new_faces[face->newIndex]; - - DM_copy_face_data(mesh->dm, result, - face->oldIndex, face->newIndex, 1); - mesh->dm->getFace(mesh->dm, face->oldIndex, newMF); - - newMF->v1 = face->edges[0]->verts[face->flip[0]]->newIndex; - newMF->v2 = face->edges[1]->verts[face->flip[1]]->newIndex; - newMF->v3 = face->edges[2]->verts[face->flip[2]]->newIndex; - - if(face->edges[3]) { - newMF->v4 = face->edges[3]->verts[face->flip[3]]->newIndex; - } else { - newMF->v4 = 0; - } - } - - return result; -} - -/* returns the other vert in the given edge - */ -static SmoothVert *other_vert(SmoothEdge *edge, SmoothVert *vert) -{ - if(edge->verts[0] == vert) return edge->verts[1]; - else return edge->verts[0]; -} - -/* returns the other edge in the given face that uses the given vert - * returns NULL if no other edge in the given face uses the given vert - * (this should never happen) - */ -static SmoothEdge *other_edge(SmoothFace *face, SmoothVert *vert, - SmoothEdge *edge) -{ - int i,j; - for(i = 0; i < SMOOTHFACE_MAX_EDGES && face->edges[i]; i++) { - SmoothEdge *tmp_edge = face->edges[i]; - if(tmp_edge == edge) continue; - - for(j = 0; j < SMOOTHEDGE_NUM_VERTS; j++) - if(tmp_edge->verts[j] == vert) return tmp_edge; - } - - /* if we get to here, something's wrong (there should always be 2 edges - * which use the same vert in a face) - */ - return NULL; -} - -/* returns a face attached to the given edge which is not the given face. - * returns NULL if no other faces use this edge. - */ -static SmoothFace *other_face(SmoothEdge *edge, SmoothFace *face) -{ - LinkNode *node; - - for(node = edge->faces; node != NULL; node = node->next) - if(node->link != face) return node->link; - - return NULL; -} - -#if 0 -/* copies source list to target, overwriting target (target is not freed) - * nodes in the copy will be in the same order as in source - */ -static void linklist_copy(LinkNode **target, LinkNode *source) -{ - LinkNode *node = NULL; - *target = NULL; - - for(; source; source = source->next) { - if(node) { - node->next = MEM_mallocN(sizeof(*node->next), "nlink_copy"); - node = node->next; - } else { - node = *target = MEM_mallocN(sizeof(**target), "nlink_copy"); - } - node->link = source->link; - node->next = NULL; - } -} -#endif - -/* appends source to target if it's not already in target */ -static void linklist_append_unique(LinkNode **target, void *source) -{ - LinkNode *node; - LinkNode *prev = NULL; - - /* check if source value is already in the list */ - for(node = *target; node; prev = node, node = node->next) - if(node->link == source) return; - - node = MEM_mallocN(sizeof(*node), "nlink"); - node->next = NULL; - node->link = source; - - if(prev) prev->next = node; - else *target = node; -} - -/* appends elements of source which aren't already in target to target */ -static void linklist_append_list_unique(LinkNode **target, LinkNode *source) -{ - for(; source; source = source->next) - linklist_append_unique(target, source->link); -} - -#if 0 /* this is no longer used, it should possibly be removed */ -/* prepends prepend to list - doesn't copy nodes, just joins the lists */ -static void linklist_prepend_linklist(LinkNode **list, LinkNode *prepend) -{ - if(prepend) { - LinkNode *node = prepend; - while(node->next) node = node->next; - - node->next = *list; - *list = prepend; - } -} -#endif - -/* returns 1 if the linked list contains the given pointer, 0 otherwise - */ -static int linklist_contains(LinkNode *list, void *ptr) -{ - LinkNode *node; - - for(node = list; node; node = node->next) - if(node->link == ptr) return 1; - - return 0; -} - -/* returns 1 if the first linked list is a subset of the second (comparing - * pointer values), 0 if not - */ -static int linklist_subset(LinkNode *list1, LinkNode *list2) -{ - for(; list1; list1 = list1->next) - if(!linklist_contains(list2, list1->link)) - return 0; +#include "BKE_tessmesh.h" +#include "BKE_mesh.h" - return 1; -} - -#if 0 -/* empties the linked list - * frees pointers with freefunc if freefunc is not NULL - */ -static void linklist_empty(LinkNode **list, LinkNodeFreeFP freefunc) -{ - BLI_linklist_free(*list, freefunc); - *list = NULL; -} -#endif - -/* removes the first instance of value from the linked list - * frees the pointer with freefunc if freefunc is not NULL - */ -static void linklist_remove_first(LinkNode **list, void *value, - LinkNodeFreeFP freefunc) -{ - LinkNode *node = *list; - LinkNode *prev = NULL; - - while(node && node->link != value) { - prev = node; - node = node->next; - } - - if(node) { - if(prev) - prev->next = node->next; - else - *list = node->next; - - if(freefunc) - freefunc(node->link); - - MEM_freeN(node); - } -} - -/* removes all elements in source from target */ -static void linklist_remove_list(LinkNode **target, LinkNode *source, - LinkNodeFreeFP freefunc) -{ - for(; source; source = source->next) - linklist_remove_first(target, source->link, freefunc); -} - -#ifdef EDGESPLIT_DEBUG_0 -static void print_ptr(void *ptr) -{ - printf("%p\n", ptr); -} - -static void print_edge(void *ptr) -{ - SmoothEdge *edge = ptr; - printf(" %4d", edge->newIndex); -} +#include "DNA_object_types.h" -static void print_face(void *ptr) -{ - SmoothFace *face = ptr; - printf(" %4d", face->newIndex); -} -#endif - -typedef struct ReplaceData { - void *find; - void *replace; -} ReplaceData; - -static void edge_replace_vert(void *ptr, void *userdata) -{ - SmoothEdge *edge = ptr; - SmoothVert *find = ((ReplaceData *)userdata)->find; - SmoothVert *replace = ((ReplaceData *)userdata)->replace; - int i; - -#ifdef EDGESPLIT_DEBUG_3 - printf("replacing vert %4d with %4d in edge %4d", - find->newIndex, replace->newIndex, edge->newIndex); - printf(": {%4d, %4d}", edge->verts[0]->newIndex, edge->verts[1]->newIndex); -#endif - - for(i = 0; i < SMOOTHEDGE_NUM_VERTS; i++) { - if(edge->verts[i] == find) { - linklist_append_list_unique(&replace->faces, edge->faces); - linklist_remove_list(&find->faces, edge->faces, NULL); - - edge->verts[i] = replace; - } - } - -#ifdef EDGESPLIT_DEBUG_3 - printf(" -> {%4d, %4d}\n", edge->verts[0]->newIndex, edge->verts[1]->newIndex); -#endif -} - -static void face_replace_vert(void *ptr, void *userdata) -{ - SmoothFace *face = ptr; - int i; - - for(i = 0; i < SMOOTHFACE_MAX_EDGES && face->edges[i]; i++) - edge_replace_vert(face->edges[i], userdata); -} - -static void face_replace_edge(void *ptr, void *userdata) -{ - SmoothFace *face = ptr; - SmoothEdge *find = ((ReplaceData *)userdata)->find; - SmoothEdge *replace = ((ReplaceData *)userdata)->replace; - int i; - -#ifdef EDGESPLIT_DEBUG_3 - printf("replacing edge %4d with %4d in face %4d", - find->newIndex, replace->newIndex, face->newIndex); - if(face->edges[3]) - printf(": {%2d %2d %2d %2d}", - face->edges[0]->newIndex, face->edges[1]->newIndex, - face->edges[2]->newIndex, face->edges[3]->newIndex); - else - printf(": {%2d %2d %2d}", - face->edges[0]->newIndex, face->edges[1]->newIndex, - face->edges[2]->newIndex); -#endif - - for(i = 0; i < SMOOTHFACE_MAX_EDGES && face->edges[i]; i++) { - if(face->edges[i] == find) { - linklist_remove_first(&face->edges[i]->faces, face, NULL); - BLI_linklist_prepend(&replace->faces, face); - face->edges[i] = replace; - } - } - -#ifdef EDGESPLIT_DEBUG_3 - if(face->edges[3]) - printf(" -> {%2d %2d %2d %2d}\n", - face->edges[0]->newIndex, face->edges[1]->newIndex, - face->edges[2]->newIndex, face->edges[3]->newIndex); - else - printf(" -> {%2d %2d %2d}\n", - face->edges[0]->newIndex, face->edges[1]->newIndex, - face->edges[2]->newIndex); -#endif -} - -static int edge_is_loose(SmoothEdge *edge) -{ - return !(edge->faces && edge->faces->next); -} - -static int edge_is_sharp(SmoothEdge *edge) -{ -#ifdef EDGESPLIT_DEBUG_1 - printf("edge %d: ", edge->newIndex); -#endif - if(edge->flag & ME_SHARP) { - /* edge can only be sharp if it has at least 2 faces */ - if(!edge_is_loose(edge)) { -#ifdef EDGESPLIT_DEBUG_1 - printf("sharp\n"); -#endif - return 1; - } else { - /* edge is loose, so it can't be sharp */ - edge->flag &= ~ME_SHARP; - } - } - -#ifdef EDGESPLIT_DEBUG_1 - printf("not sharp\n"); -#endif - return 0; -} - -/* finds another sharp edge which uses vert, by traversing faces around the - * vert until it does one of the following: - * - hits a loose edge (the edge is returned) - * - hits a sharp edge (the edge is returned) - * - returns to the start edge (NULL is returned) +/* EdgeSplit */ +/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag + * or edge angle (can be used to achieve autosmoothing) + * + * note: this code is very close to MOD_bevel.c */ -static SmoothEdge *find_other_sharp_edge(SmoothVert *vert, SmoothEdge *edge, LinkNode **visited_faces) -{ - SmoothFace *face = NULL; - SmoothEdge *edge2 = NULL; - /* holds the edges we've seen so we can avoid looping indefinitely */ - LinkNode *visited_edges = NULL; -#ifdef EDGESPLIT_DEBUG_1 - printf("=== START === find_other_sharp_edge(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif - - /* get a face on which to start */ - if(edge->faces) face = edge->faces->link; - else return NULL; - - /* record this edge as visited */ - BLI_linklist_prepend(&visited_edges, edge); - - /* get the next edge */ - edge2 = other_edge(face, vert, edge); - - /* record this face as visited */ - if(visited_faces) - BLI_linklist_prepend(visited_faces, face); - - /* search until we hit a loose edge or a sharp edge or an edge we've - * seen before - */ - while(face && !edge_is_sharp(edge2) - && !linklist_contains(visited_edges, edge2)) { -#ifdef EDGESPLIT_DEBUG_3 - printf("current face %4d; current edge %4d\n", face->newIndex, - edge2->newIndex); -#endif - /* get the next face */ - face = other_face(edge2, face); - - /* if face == NULL, edge2 is a loose edge */ - if(face) { - /* record this face as visited */ - if(visited_faces) - BLI_linklist_prepend(visited_faces, face); - - /* record this edge as visited */ - BLI_linklist_prepend(&visited_edges, edge2); - - /* get the next edge */ - edge2 = other_edge(face, vert, edge2); -#ifdef EDGESPLIT_DEBUG_3 - printf("next face %4d; next edge %4d\n", - face->newIndex, edge2->newIndex); - } else { - printf("loose edge: %4d\n", edge2->newIndex); -#endif - } - } - /* either we came back to the start edge or we found a sharp/loose edge */ - if(linklist_contains(visited_edges, edge2)) - /* we came back to the start edge */ - edge2 = NULL; +#define EDGE_MARK 1 - BLI_linklist_free(visited_edges, NULL); - -#ifdef EDGESPLIT_DEBUG_1 - printf("=== END === find_other_sharp_edge(edge = %4d, vert = %4d), " - "returning edge %d\n", - edge->newIndex, vert->newIndex, edge2 ? edge2->newIndex : -1); -#endif - return edge2; -} - -static void split_single_vert(SmoothVert *vert, SmoothFace *face, - SmoothMesh *mesh) -{ - SmoothVert *copy_vert; - ReplaceData repdata; - - copy_vert = smoothvert_copy(vert, mesh); - - if(copy_vert == NULL) { - /* bug [#26316], this prevents a segfault - * but this still needs fixing */ - return; - } - - repdata.find = vert; - repdata.replace = copy_vert; - face_replace_vert(face, &repdata); -} - -typedef struct PropagateEdge { - struct PropagateEdge *next, *prev; - SmoothEdge *edge; - SmoothVert *vert; -} PropagateEdge; - -static void push_propagate_stack(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh) +static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *ob) { - PropagateEdge *pedge = mesh->reusestack.first; - - if(pedge) { - BLI_remlink(&mesh->reusestack, pedge); - } - else { - if(!mesh->arena) { - mesh->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "edgesplit arena"); - BLI_memarena_use_calloc(mesh->arena); - } - - pedge = BLI_memarena_alloc(mesh->arena, sizeof(PropagateEdge)); - } - - pedge->edge = edge; - pedge->vert = vert; - BLI_addhead(&mesh->propagatestack, pedge); -} - -static void pop_propagate_stack(SmoothEdge **edge, SmoothVert **vert, SmoothMesh *mesh) -{ - PropagateEdge *pedge = mesh->propagatestack.first; - - if(pedge) { - *edge = pedge->edge; - *vert = pedge->vert; - BLI_remlink(&mesh->propagatestack, pedge); - BLI_addhead(&mesh->reusestack, pedge); - } - else { - *edge = NULL; - *vert = NULL; - } -} - -static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh); - -static void propagate_split(SmoothEdge *edge, SmoothVert *vert, - SmoothMesh *mesh) -{ - SmoothEdge *edge2; - LinkNode *visited_faces = NULL; -#ifdef EDGESPLIT_DEBUG_1 - printf("=== START === propagate_split(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif - - edge2 = find_other_sharp_edge(vert, edge, &visited_faces); - - if(!edge2) { - /* didn't find a sharp or loose edge, so we've hit a dead end */ - } else if(!edge_is_loose(edge2)) { - /* edge2 is not loose, so it must be sharp */ - if(edge_is_loose(edge)) { - /* edge is loose, so we can split edge2 at this vert */ - split_edge(edge2, vert, mesh); - } else if(edge_is_sharp(edge)) { - /* both edges are sharp, so we can split the pair at vert */ - split_edge(edge, vert, mesh); - } else { - /* edge is not sharp, so try to split edge2 at its other vert */ - split_edge(edge2, other_vert(edge2, vert), mesh); - } - } else { /* edge2 is loose */ - if(edge_is_loose(edge)) { - SmoothVert *vert2; - ReplaceData repdata; - - /* can't split edge, what should we do with vert? */ - if(linklist_subset(vert->faces, visited_faces)) { - /* vert has only one fan of faces attached; don't split it */ - } else { - /* vert has more than one fan of faces attached; split it */ - vert2 = smoothvert_copy(vert, mesh); + BMesh *bm; + BMEditMesh *em; + DerivedMesh *cddm; + BMIter iter; + BMEdge *e; + /* int allocsize[] = {512, 512, 2048, 512}; */ /* UNUSED */ + float threshold = cos((emd->split_angle + 0.00001) * M_PI / 180.0); + + if (!CDDM_Check(dm)) { + cddm = CDDM_copy(dm, 0); + } else cddm = dm; + + em = CDDM_To_BMesh(ob, dm, NULL); + bm = em->bm; - /* fails in rare cases, see [#26993] */ - if(vert2) { - /* replace vert with its copy in visited_faces */ - repdata.find = vert; - repdata.replace = vert2; - BLI_linklist_apply(visited_faces, face_replace_vert, &repdata); + BM_Compute_Normals(bm); + BMO_push(bm, NULL); + + if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { + BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { + /* check for 1 edge having 2 face users */ + BMLoop *l1, *l2; + if ( (l1= e->l) && + (l2= e->l->radial_next) != l1) + { + if (dot_v3v3(l1->f->no, l2->f->no) < threshold) { + BMO_SetFlag(bm, e, EDGE_MARK); } } - } else { - /* edge is not loose, so it must be sharp; split it */ - split_edge(edge, vert, mesh); } } - - BLI_linklist_free(visited_faces, NULL); -#ifdef EDGESPLIT_DEBUG_1 - printf("=== END === propagate_split(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif -} - -static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh) -{ - SmoothEdge *edge2; - SmoothVert *vert2; - ReplaceData repdata; - /* the list of faces traversed while looking for a sharp edge */ - LinkNode *visited_faces = NULL; -#ifdef EDGESPLIT_DEBUG_1 - printf("=== START === split_edge(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif - - edge2 = find_other_sharp_edge(vert, edge, &visited_faces); - - if(!edge2) { - /* didn't find a sharp or loose edge, so try the other vert */ - vert2 = other_vert(edge, vert); - push_propagate_stack(edge, vert2, mesh); - } else if(!edge_is_loose(edge2)) { - /* edge2 is not loose, so it must be sharp */ - SmoothEdge *copy_edge = smoothedge_copy(edge, mesh); - SmoothEdge *copy_edge2 = smoothedge_copy(edge2, mesh); - SmoothVert *vert2; - - /* replace edge with its copy in visited_faces */ - repdata.find = edge; - repdata.replace = copy_edge; - BLI_linklist_apply(visited_faces, face_replace_edge, &repdata); - - /* replace edge2 with its copy in visited_faces */ - repdata.find = edge2; - repdata.replace = copy_edge2; - BLI_linklist_apply(visited_faces, face_replace_edge, &repdata); - - vert2 = smoothvert_copy(vert, mesh); - - /* replace vert with its copy in visited_faces (must be done after - * edge replacement so edges have correct vertices) - */ - repdata.find = vert; - repdata.replace = vert2; - BLI_linklist_apply(visited_faces, face_replace_vert, &repdata); - - /* all copying and replacing is done; the mesh should be consistent. - * now propagate the split to the vertices at either end - */ - push_propagate_stack(copy_edge, other_vert(copy_edge, vert2), mesh); - push_propagate_stack(copy_edge2, other_vert(copy_edge2, vert2), mesh); - - if(smoothedge_has_vert(edge, vert)) - push_propagate_stack(edge, vert, mesh); - } else { - /* edge2 is loose */ - SmoothEdge *copy_edge = smoothedge_copy(edge, mesh); - SmoothVert *vert2; - - /* replace edge with its copy in visited_faces */ - repdata.find = edge; - repdata.replace = copy_edge; - BLI_linklist_apply(visited_faces, face_replace_edge, &repdata); - - vert2 = smoothvert_copy(vert, mesh); - - /* bug [#29205] which is caused by exactly the same reason as [#26316] - this check will only prevent crash without fixing actual issue and - some vertices can stay unsplitted when they should (sergey) */ - if(vert2) { - /* replace vert with its copy in visited_faces (must be done after - * edge replacement so edges have correct vertices) - */ - repdata.find = vert; - repdata.replace = vert2; - BLI_linklist_apply(visited_faces, face_replace_vert, &repdata); - } - - /* copying and replacing is done; the mesh should be consistent. - * now propagate the split to the vertex at the other end - */ - push_propagate_stack(copy_edge, other_vert(copy_edge, vert2), mesh); - - if(smoothedge_has_vert(edge, vert)) - push_propagate_stack(edge, vert, mesh); - } - - BLI_linklist_free(visited_faces, NULL); -#ifdef EDGESPLIT_DEBUG_1 - printf("=== END === split_edge(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif -} - -static void tag_and_count_extra_edges(SmoothMesh *mesh, float split_angle, - int flags, int *extra_edges) -{ - /* if normal1 dot normal2 < threshold, angle is greater, so split */ - /* FIXME not sure if this always works */ - /* 0.00001 added for floating-point rounding */ - float threshold = cos((split_angle + 0.00001f) * (float)M_PI / 180.0f); - int i; - - *extra_edges = 0; - - /* loop through edges, counting potential new ones */ - for(i = 0; i < mesh->num_edges; i++) { - SmoothEdge *edge = &mesh->edges[i]; - int sharp = 0; - - /* treat all non-manifold edges (3 or more faces) as sharp */ - if(edge->faces && edge->faces->next && edge->faces->next->next) { - LinkNode *node; - - /* this edge is sharp */ - sharp = 1; - - /* add an extra edge for every face beyond the first */ - *extra_edges += 2; - for(node = edge->faces->next->next->next; node; node = node->next) - (*extra_edges)++; - } else if((flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)) - && !edge_is_loose(edge)) { - /* (the edge can only be sharp if we're checking angle or flag, - * and it has at least 2 faces) */ - - /* if we're checking the sharp flag and it's set, good */ - if((flags & MOD_EDGESPLIT_FROMFLAG) && (edge->flag & ME_SHARP)) { - /* this edge is sharp */ - sharp = 1; - - (*extra_edges)++; - } else if(flags & MOD_EDGESPLIT_FROMANGLE) { - /* we know the edge has 2 faces, so check the angle */ - SmoothFace *face1 = edge->faces->link; - SmoothFace *face2 = edge->faces->next->link; - float edge_angle_cos = dot_v3v3(face1->normal, - face2->normal); - - if(edge_angle_cos < threshold) { - /* this edge is sharp */ - sharp = 1; - - (*extra_edges)++; - } - } + + if (emd->flags & MOD_EDGESPLIT_FROMFLAG) { + BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { + if (BM_TestHFlag(e, BM_SHARP)) + BMO_SetFlag(bm, e, EDGE_MARK); } - - /* set/clear sharp flag appropriately */ - if(sharp) edge->flag |= ME_SHARP; - else edge->flag &= ~ME_SHARP; } -} - -static void split_sharp_edges(SmoothMesh *mesh, float split_angle, int flags) -{ - SmoothVert *vert; - int i; - /* if normal1 dot normal2 < threshold, angle is greater, so split */ - /* FIXME not sure if this always works */ - /* 0.00001 added for floating-point rounding */ - mesh->threshold = cosf((split_angle + 0.00001f) * (float)M_PI / 180.0f); - mesh->flags = flags; - - /* loop through edges, splitting sharp ones */ - /* can't use an iterator here, because we'll be adding edges */ - for(i = 0; i < mesh->num_edges; i++) { - SmoothEdge *edge = &mesh->edges[i]; - - if(edge_is_sharp(edge)) { - split_edge(edge, edge->verts[0], mesh); - - do { - pop_propagate_stack(&edge, &vert, mesh); - if(edge && smoothedge_has_vert(edge, vert)) - propagate_split(edge, vert, mesh); - } while(edge); - } + + BMO_CallOpf(bm, "edgesplit edges=%fe", EDGE_MARK); + + BMO_pop(bm); + BMEdit_RecalcTesselation(em); + + if (cddm != dm) { + cddm->needsFree = 1; + cddm->release(cddm); } + + cddm = CDDM_from_BMEditMesh(em, NULL, 1); + BMEdit_Free(em); + MEM_freeN(em); + + return cddm; } -static int count_bridge_verts(SmoothMesh *mesh) +static void initData(ModifierData *md) { - int i, j, count = 0; - - for(i = 0; i < mesh->num_faces; i++) { - SmoothFace *face = &mesh->faces[i]; - - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - SmoothEdge *edge = face->edges[j]; - SmoothEdge *next_edge; - SmoothVert *vert = edge->verts[1 - face->flip[j]]; - int next = (j + 1) % SMOOTHFACE_MAX_EDGES; - - /* wrap next around if at last edge */ - if(!face->edges[next]) next = 0; - - next_edge = face->edges[next]; - - /* if there are other faces sharing this vertex but not - * these edges, the vertex will be split, so count it - */ - /* vert has to have at least one face (this one), so faces != 0 */ - if(!edge->faces->next && !next_edge->faces->next - && vert->faces->next) { - count++; - } - } - } + EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - /* each bridge vert will be counted once per face that uses it, - * so count is too high, but it's ok for now + /* default to 30-degree split angle, sharpness from both angle & flag */ - return count; + emd->split_angle = 30; + emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG; } -static void split_bridge_verts(SmoothMesh *mesh) +static void copyData(ModifierData *md, ModifierData *target) { - int i,j; - - for(i = 0; i < mesh->num_faces; i++) { - SmoothFace *face = &mesh->faces[i]; - - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - SmoothEdge *edge = face->edges[j]; - SmoothEdge *next_edge; - SmoothVert *vert = edge->verts[1 - face->flip[j]]; - int next = (j + 1) % SMOOTHFACE_MAX_EDGES; - - /* wrap next around if at last edge */ - if(!face->edges[next]) next = 0; - - next_edge = face->edges[next]; + EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; + EdgeSplitModifierData *temd = (EdgeSplitModifierData*) target; - /* if there are other faces sharing this vertex but not - * these edges, split the vertex - */ - /* vert has to have at least one face (this one), so faces != 0 */ - if(!edge->faces->next && !next_edge->faces->next - && vert->faces->next) - /* FIXME this needs to find all faces that share edges with - * this one and split off together - */ - split_single_vert(vert, face, mesh); - } - } + temd->split_angle = emd->split_angle; + temd->flags = emd->flags; } -static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, DerivedMesh *dm) +static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, + Object *ob, DerivedMesh *dm) { - SmoothMesh *mesh; - DerivedMesh *result; - int max_verts, max_edges; - if(!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG))) return dm; - /* 1. make smoothmesh with initial number of elements */ - mesh = smoothmesh_from_derivedmesh(dm); - - /* 2. count max number of elements to add */ - tag_and_count_extra_edges(mesh, emd->split_angle, emd->flags, &max_edges); - max_verts = max_edges * 2 + mesh->max_verts; - max_verts += count_bridge_verts(mesh); - max_edges += mesh->max_edges; - - /* 3. reallocate smoothmesh arrays & copy elements across */ - /* 4. remap copied elements' pointers to point into the new arrays */ - smoothmesh_resize_verts(mesh, max_verts); - smoothmesh_resize_edges(mesh, max_edges); - -#ifdef EDGESPLIT_DEBUG_1 - printf("********** Pre-split **********\n"); - smoothmesh_print(mesh); -#endif - - split_sharp_edges(mesh, emd->split_angle, emd->flags); -#ifdef EDGESPLIT_DEBUG_1 - printf("********** Post-edge-split **********\n"); - smoothmesh_print(mesh); -#endif - - split_bridge_verts(mesh); - -#ifdef EDGESPLIT_DEBUG_1 - printf("********** Post-vert-split **********\n"); - smoothmesh_print(mesh); -#endif - -#ifdef EDGESPLIT_DEBUG_0 - printf("Edgesplit: Estimated %d verts & %d edges, " - "found %d verts & %d edges\n", max_verts, max_edges, - mesh->num_verts, mesh->num_edges); -#endif - - result = CDDM_from_smoothmesh(mesh); - smoothmesh_free(mesh); - - return result; + return doEdgeSplit(dm, emd, ob); } -static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), - DerivedMesh *derivedData, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) +static DerivedMesh *applyModifier( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { DerivedMesh *result; EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - result = edgesplitModifier_do(emd, derivedData); + result = edgesplitModifier_do(emd, ob, derivedData); if(result != derivedData) - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); return result; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index b18be28ac7f..75d9e7e0782 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -108,8 +108,8 @@ static void createFacepa(ExplodeModifierData *emd, int i,p,v1,v2,v3,v4=0; mvert = dm->getVertArray(dm); - mface = dm->getFaceArray(dm); - totface= dm->getNumFaces(dm); + mface = dm->getTessFaceArray(dm); + totface= dm->getNumTessFaces(dm); totvert= dm->getNumVerts(dm); totpart= psmd->psys->totpart; @@ -198,8 +198,8 @@ static const short add_faces[24] = { static MFace *get_dface(DerivedMesh *dm, DerivedMesh *split, int cur, int i, MFace *mf) { - MFace *df = CDDM_get_face(split, cur); - DM_copy_face_data(dm, split, i, cur, 1); + MFace *df = CDDM_get_tessface(split, cur); + DM_copy_tessface_data(dm, split, i, cur, 1); *df = *mf; return df; } @@ -545,12 +545,12 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) { DerivedMesh *splitdm; MFace *mf=NULL,*df1=NULL; - MFace *mface=dm->getFaceArray(dm); + MFace *mface=dm->getTessFaceArray(dm); MVert *dupve, *mv; EdgeHash *edgehash; EdgeHashIterator *ehi; int totvert=dm->getNumVerts(dm); - int totface=dm->getNumFaces(dm); + int totface=dm->getNumTessFaces(dm); int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit"); int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2"); @@ -629,7 +629,7 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) for(i=0,fs=facesplit; i<totface; i++,fs++) totfsplit += add_faces[*fs]; - splitdm= CDDM_from_template(dm, totesplit, 0, totface+totfsplit); + splitdm= CDDM_from_template(dm, totesplit, 0, totface+totfsplit, 0, 0); numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE); /* copy new faces & verts (is it really this painful with custom data??) */ @@ -644,7 +644,12 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) } /* override original facepa (original pointer is saved in caller function) */ - facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa"); + + /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are + * later interpreted as tri's, for this to work right I think we probably + * have to stop using tessface - campbell */ + + facepa= MEM_callocN(sizeof(int)*(totface+(totfsplit * 2)),"explode_facepa"); //memcpy(facepa,emd->facepa,totface*sizeof(int)); emd->facepa=facepa; @@ -671,7 +676,7 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) curdupface=0;//=totface; //curdupin=totesplit; for(i=0,fs=facesplit; i<totface; i++,fs++){ - mf = dm->getFaceData(dm, i, CD_MFACE); + mf = dm->getTessFaceData(dm, i, CD_MFACE); switch(*fs) { case 3: @@ -761,7 +766,7 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) } for(i=0; i<curdupface; i++) { - mf = CDDM_get_face(splitdm, i); + mf = CDDM_get_tessface(splitdm, i); test_index_face(mf, &splitdm->faceData, i, (mf->flag & ME_FACE_SEL ? 4 : 3)); } @@ -769,8 +774,9 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) MEM_freeN(facesplit); MEM_freeN(vertpa); - return splitdm; + CDDM_tessfaces_to_faces(splitdm); /*builds ngon faces from tess (mface) faces*/ + return splitdm; } static DerivedMesh * explodeMesh(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Scene *scene, Object *ob, @@ -794,9 +800,9 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, unsigned int ed_v1, ed_v2, mindex=0; MTFace *mtface = NULL, *mtf; - totface= dm->getNumFaces(dm); + totface= dm->getNumTessFaces(dm); totvert= dm->getNumVerts(dm); - mface= dm->getFaceArray(dm); + mface= dm->getTessFaceArray(dm); totpart= psmd->psys->totpart; sim.scene= scene; @@ -838,7 +844,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, BLI_edgehashIterator_free(ehi); /* the final duplicated vertices */ - explode= CDDM_from_template(dm, totdup, 0,totface); + explode= CDDM_from_template(dm, totdup, 0,totface, 0, 0); mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname); /*dupvert= CDDM_get_verts(explode);*/ @@ -906,8 +912,8 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, if(pa->alive==PARS_DEAD && (emd->flag&eExplodeFlag_Dead)==0) continue; } - dm->getFace(dm,i,&source); - mf=CDDM_get_face(explode,i); + dm->getTessFace(dm,i,&source); + mf=CDDM_get_tessface(explode,i); orig_v4 = source.v4; @@ -922,7 +928,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, if(source.v4) source.v4 = edgecut_get(vertpahash, source.v4, mindex); - DM_copy_face_data(dm,explode,i,i,1); + DM_copy_tessface_data(dm,explode,i,i,1); *mf = source; @@ -945,8 +951,9 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, BLI_edgehash_free(vertpahash, NULL); /* finalization */ - CDDM_calc_edges(explode); - CDDM_calc_normals(explode); + CDDM_calc_edges_tessface(explode); + CDDM_tessfaces_to_faces(explode); + CDDM_calc_normals_mapping(explode); if(psmd->psys->lattice){ end_latt_deform(psmd->psys->lattice); @@ -976,6 +983,8 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, ExplodeModifierData *emd= (ExplodeModifierData*) md; ParticleSystemModifierData *psmd=findPrecedingParticlesystem(ob,md); + DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + if(psmd){ ParticleSystem * psys=psmd->psys; @@ -987,7 +996,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, if(emd->facepa == NULL || psmd->flag&eParticleSystemFlag_Pars || emd->flag&eExplodeFlag_CalcFaces - || MEM_allocN_len(emd->facepa)/sizeof(int) != dm->getNumFaces(dm)) + || MEM_allocN_len(emd->facepa)/sizeof(int) != dm->getNumTessFaces(dm)) { if(psmd->flag & eParticleSystemFlag_Pars) psmd->flag &= ~eParticleSystemFlag_Pars; diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index 0452c6a4e73..0aea2650895 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -223,7 +223,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename) return NULL; } - dm = CDDM_new(numverts, 0, numfaces); + dm = CDDM_new(numverts, 0, numfaces, 0, 0); if(!dm) { @@ -279,7 +279,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename) } // read triangles from file - mf = CDDM_get_faces(dm); + mf = CDDM_get_tessfaces(dm); for(i=numfaces; i>0; i--, mf++) { int face[3]; @@ -306,12 +306,12 @@ static DerivedMesh *fluidsim_read_obj(const char *filename) gzclose( gzf ); - CDDM_calc_edges(dm); + CDDM_calc_edges_tessface(dm); CDDM_apply_vert_normals(dm, (short (*)[3])normals); MEM_freeN(normals); - // CDDM_calc_normals(result); + // CDDM_calc_normals_mapping(result); return dm; } @@ -499,20 +499,18 @@ static DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, Fluidsim } // assign material + flags to new dm - // if there's no faces in original dm, keep materials and flags unchanged - mface = orgdm->getFaceArray(orgdm); - + mface = orgdm->getTessFaceArray(orgdm); if(mface) { mat_nr = mface[0].mat_nr; flag = mface[0].flag; - mface = dm->getFaceArray(dm); - numfaces = dm->getNumFaces(dm); + mface = dm->getTessFaceArray(dm); + numfaces = dm->getNumTessFaces(dm); for(i=0; i<numfaces; i++) - { - mface[i].mat_nr = mat_nr; - mface[i].flag = flag; - } + { + mface[i].mat_nr = mat_nr; + mface[i].flag = flag; + } } // load vertex velocities, if they exist... diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 9d5bc46810b..97e406c6960 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -260,7 +260,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, dm->release(dm); } -static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, +static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { HookModifierData *hmd = (HookModifierData*) md; diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index ac0a3a0c052..605c057c855 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -119,12 +119,12 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; - if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); + if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data, 0); deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 1fbe0eef6f3..b4f76ede545 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -101,13 +101,24 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, { MaskModifierData *mmd= (MaskModifierData *)md; DerivedMesh *dm= derivedData, *result= NULL; - GHash *vertHash=NULL, *edgeHash, *faceHash; + GHash *vertHash=NULL, *edgeHash, *polyHash; GHashIterator *hashIter; MDeformVert *dvert= NULL, *dv; - int numFaces=0, numEdges=0, numVerts=0; - int maxVerts, maxEdges, maxFaces; + int numPolys=0, numLoops=0, numEdges=0, numVerts=0; + int maxVerts, maxEdges, maxPolys; int i; - + + MPoly *mpoly; + MLoop *mloop; + + MPoly *mpoly_new; + MLoop *mloop_new; + MEdge *medge_new; + MVert *mvert_new; + + + int *loop_mapping; + /* Overview of Method: * 1. Get the vertices that are in the vertexgroup of interest * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices @@ -117,7 +128,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* get original number of verts, edges, and faces */ maxVerts= dm->getNumVerts(dm); maxEdges= dm->getNumEdges(dm); - maxFaces= dm->getNumFaces(dm); + maxPolys= dm->getNumPolys(dm); /* check if we can just return the original mesh * - must have verts and therefore verts assigned to vgroups to do anything useful @@ -138,7 +149,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, char *bone_select_array; int bone_select_tot= 0; const int defbase_tot= BLI_countlist(&ob->defbase); - + /* check that there is armature object with bones to use, otherwise return original mesh */ if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first)) return derivedData; @@ -259,11 +270,16 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, numVerts++; } } - + /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask ed2 gh"); - faceHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask fa2 gh"); + polyHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask fa2 gh"); + mpoly = dm->getPolyArray(dm); + mloop = dm->getLoopArray(dm); + + loop_mapping = MEM_callocN(sizeof(int) * maxPolys, "mask loopmap"); /* overalloc, assume all polys are seen */ + /* loop over edges and faces, and do the same thing to * ensure that they only reference existing verts */ @@ -280,19 +296,27 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, numEdges++; } } - for (i = 0; i < maxFaces; i++) + for (i = 0; i < maxPolys; i++) { - MFace mf; - dm->getFace(dm, i, &mf); + MPoly *mp = &mpoly[i]; + MLoop *ml = mloop + mp->loopstart; + int ok = TRUE; + int j; + + for (j = 0; j < mp->totloop; j++, ml++) { + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) { + ok = FALSE; + break; + } + } /* all verts must be available */ - if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) && - BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)) && - BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)) && - (mf.v4==0 || BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) ) + if (ok) { - BLI_ghash_insert(faceHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numFaces)); - numFaces++; + BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys)); + loop_mapping[numPolys] = numLoops; + numPolys++; + numLoops += mp->totloop; } } @@ -300,8 +324,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* now we know the number of verts, edges and faces, * we can create the new (reduced) mesh */ - result = CDDM_from_template(dm, numVerts, numEdges, numFaces); + result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys); + mpoly_new = CDDM_get_polys(result); + mloop_new = CDDM_get_loops(result); + medge_new = CDDM_get_edges(result); + mvert_new = CDDM_get_verts(result); /* using ghash-iterators, map data into new mesh */ /* vertices */ @@ -315,7 +343,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getVert(dm, oldIndex, &source); - dest = CDDM_get_vert(result, newIndex); + dest = &mvert_new[newIndex]; DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); *dest = source; @@ -333,7 +361,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getEdge(dm, oldIndex, &source); - dest = CDDM_get_edge(result, newIndex); + dest = &medge_new[newIndex]; source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); @@ -344,42 +372,43 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, BLI_ghashIterator_free(hashIter); /* faces */ - for ( hashIter = BLI_ghashIterator_new(faceHash); + for ( hashIter = BLI_ghashIterator_new(polyHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { - MFace source; - MFace *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); - int orig_v4; + MPoly *source = &mpoly[oldIndex]; + MPoly *dest = &mpoly_new[newIndex]; + int oldLoopIndex = source->loopstart; + int newLoopIndex = loop_mapping[newIndex]; + MLoop *source_loop = &mloop[oldLoopIndex]; + MLoop *dest_loop = &mloop_new[newLoopIndex]; - dm->getFace(dm, oldIndex, &source); - dest = CDDM_get_face(result, newIndex); - - orig_v4 = source.v4; - - source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); - source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); - source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); - if (source.v4) - source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); - - DM_copy_face_data(dm, result, oldIndex, newIndex, 1); - *dest = source; - - test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3)); + DM_copy_poly_data(dm, result, oldIndex, newIndex, 1); + DM_copy_loop_data(dm, result, oldLoopIndex, newLoopIndex, source->totloop); + + *dest = *source; + dest->loopstart = newLoopIndex; + for (i = 0; i < source->totloop; i++) { + dest_loop[i].v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source_loop[i].v))); + dest_loop[i].e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(source_loop[i].e))); + } } + BLI_ghashIterator_free(hashIter); - + + MEM_freeN(loop_mapping); + + /* why is this needed? - campbell */ /* recalculate normals */ - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); /* free hashes */ BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); - BLI_ghash_free(faceHash, NULL, NULL); - + BLI_ghash_free(polyHash, NULL, NULL); + /* return the new mesh */ return result; } diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index e6e2c0fd621..8d2dc32e47c 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -32,7 +32,7 @@ * \ingroup modifiers */ - +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -45,6 +45,7 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_deform.h" +#include "BKE_tessmesh.h" #include "depsgraph_private.h" @@ -185,7 +186,7 @@ static void meshdeformModifier_do( { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; struct Mesh *me= (mmd->object)? mmd->object->data: NULL; - struct EditMesh *em = (me)? BKE_mesh_get_editmesh(me): NULL; + BMEditMesh *em = me ? me->edit_btmesh : NULL; DerivedMesh *tmpdm, *cagedm; MDeformVert *dvert = NULL; MDefInfluence *influences; @@ -200,10 +201,9 @@ static void meshdeformModifier_do( /* get cage derivedmesh */ if(em) { - tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0); + tmpdm= editbmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0); if(tmpdm) tmpdm->release(tmpdm); - BKE_mesh_end_editmesh(me, em); } else cagedm= mmd->object->derivedFinal; @@ -353,7 +353,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index c130af158bb..70e7d6c0d48 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -37,19 +37,18 @@ #include "DNA_object_types.h" #include "BLI_math.h" -#include "BLI_utildefines.h" +#include "BLI_array.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_deform.h" - +#include "BKE_utildefines.h" +#include "BKE_tessmesh.h" #include "MEM_guardedalloc.h" #include "depsgraph_private.h" -#include "MOD_util.h" - static void initData(ModifierData *md) { MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -69,10 +68,9 @@ static void copyData(ModifierData *md, ModifierData *target) tmmd->mirror_ob = mmd->mirror_ob; } -static void foreachObjectLink( - ModifierData *md, Object *ob, - void (*walk)(void *userData, Object *ob, Object **obpoin), - void *userData) +static void foreachObjectLink(ModifierData *md, Object *ob, + void (*walk)(void *userData, Object *ob, Object **obpoin), + void *userData) { MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -80,9 +78,9 @@ static void foreachObjectLink( } static void updateDepgraph(ModifierData *md, DagForest *forest, - struct Scene *UNUSED(scene), - Object *UNUSED(ob), - DagNode *obNode) + struct Scene *UNUSED(scene), + Object *UNUSED(ob), + DagNode *obNode) { MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -99,194 +97,197 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, DerivedMesh *dm, int axis) { - int i; - float tolerance = mmd->tolerance; + const float tolerance_sq = mmd->tolerance * mmd->tolerance; + const int do_vtargetmap = !(mmd->flag & MOD_MIR_NO_MERGE); + int is_vtargetmap = FALSE; /* true when it should be used */ + DerivedMesh *result; - int numVerts, numEdges, numFaces; - int maxVerts = dm->getNumVerts(dm); - int maxEdges = dm->getNumEdges(dm); - int maxFaces = dm->getNumFaces(dm); - int *flip_map= NULL, flip_map_len= 0; - int do_vgroup_mirr= (mmd->flag & MOD_MIR_VGROUP); - unsigned int (*indexMap)[2]; - float mtx[4][4], imtx[4][4]; + const int maxVerts = dm->getNumVerts(dm); + const int maxEdges = dm->getNumEdges(dm); + const int maxLoops = dm->getNumLoops(dm); + const int maxPolys = dm->getNumPolys(dm); + MVert *mv, *mv_prev; + MEdge *me; + MLoop *ml; + MPoly *mp; + float mtx[4][4]; + int i, j; + int a, totshape; + int *vtargetmap, *vtmap_a = NULL, *vtmap_b = NULL; + + /* mtx is the mirror transformation */ + unit_m4(mtx); + mtx[axis][axis] = -1.0f; - numVerts = numEdges = numFaces = 0; + if (mmd->mirror_ob) { + float tmp[4][4]; + float itmp[4][4]; + + /* tmp is a transform from coords relative to the object's own origin, + * to coords relative to the mirror object origin */ + invert_m4_m4(tmp, mmd->mirror_ob->obmat); + mult_m4_m4m4(tmp, tmp, ob->obmat); + + /* itmp is the reverse transform back to origin-relative coordiantes */ + invert_m4_m4(itmp, tmp); + + /* combine matrices to get a single matrix that translates coordinates into + * mirror-object-relative space, does the mirror, and translates back to + * origin-relative space */ + mult_m4_m4m4(mtx, mtx, tmp); + mult_m4_m4m4(mtx, itmp, mtx); + } - indexMap = MEM_mallocN(sizeof(*indexMap) * maxVerts, "indexmap"); + result = CDDM_from_template(dm, maxVerts*2, maxEdges*2, 0, maxLoops*2, maxPolys*2); - result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2); + /*copy customdata to original geometry*/ + DM_copy_vert_data(dm, result, 0, 0, maxVerts); + DM_copy_edge_data(dm, result, 0, 0, maxEdges); + DM_copy_loop_data(dm, result, 0, 0, maxLoops); + DM_copy_poly_data(dm, result, 0, 0, maxPolys); - if (do_vgroup_mirr) { - flip_map= defgroup_flip_map(ob, &flip_map_len, FALSE); - if(flip_map == NULL) - do_vgroup_mirr= 0; + /* subsurf for eg wont have mesh data in the */ + /* now add mvert/medge/mface layers */ + + if (!CustomData_has_layer(&dm->vertData, CD_MVERT)) { + dm->copyVertArray(dm, CDDM_get_verts(result)); + } + if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE)) { + dm->copyEdgeArray(dm, CDDM_get_edges(result)); + } + if (!CustomData_has_layer(&dm->polyData, CD_MPOLY)) { + dm->copyLoopArray(dm, CDDM_get_loops(result)); + dm->copyPolyArray(dm, CDDM_get_polys(result)); } - if (mmd->mirror_ob) { - float obinv[4][4]; - - invert_m4_m4(obinv, mmd->mirror_ob->obmat); - mult_m4_m4m4(mtx, obinv, ob->obmat); - invert_m4_m4(imtx, mtx); + /* copy customdata to new geometry, + * copy from its self becayse this data may have been created in the checks above */ + DM_copy_vert_data(result, result, 0, maxVerts, maxVerts); + DM_copy_edge_data(result, result, 0, maxEdges, maxEdges); + /* loops are copied later */ + DM_copy_poly_data(result, result, 0, maxPolys, maxPolys); + + if (do_vtargetmap) { + /* second half is filled with -1 */ + vtargetmap = MEM_mallocN(sizeof(int) * maxVerts * 2, "MOD_mirror tarmap"); + + vtmap_a = vtargetmap; + vtmap_b = vtargetmap + maxVerts; } - for(i = 0; i < maxVerts; i++) { - MVert inMV; - MVert *mv = CDDM_get_vert(result, numVerts); - int isShared; - float co[3]; - - dm->getVert(dm, i, &inMV); - - copy_v3_v3(co, inMV.co); - - if (mmd->mirror_ob) { - mul_m4_v3(mtx, co); - } - - if(mmd->flag & MOD_MIR_NO_MERGE) - isShared = 0; - else - isShared = ABS(co[axis])<=tolerance; - - /* Because the topology result (# of vertices) must be the same if - * the mesh data is overridden by vertex cos, have to calc sharedness - * based on original coordinates. This is why we test before copy. - */ - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv = inMV; - - indexMap[i][0] = numVerts; - indexMap[i][1] = !isShared; - - numVerts++; - - if(isShared ) { - co[axis] = 0.0f; - if (mmd->mirror_ob) { - mul_m4_v3(imtx, co); - } - copy_v3_v3(mv->co, co); - - mv->flag |= ME_VERT_MERGED; - } - else { - MVert *mv2 = CDDM_get_vert(result, numVerts); - - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv2 = *mv; - - co[axis] = -co[axis]; - if (mmd->mirror_ob) { - mul_m4_v3(imtx, co); + /* mirror vertex coordinates */ + mv_prev = CDDM_get_verts(result); + mv = mv_prev + maxVerts; + for (i = 0; i < maxVerts; i++, mv++, mv_prev++) { + mul_m4_v3(mtx, mv->co); + + if (do_vtargetmap) { + /* compare location of the original and mirrored vertex, to see if they + * should be mapped for merging */ + if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) { + *vtmap_a = maxVerts + i; + is_vtargetmap = TRUE; } - copy_v3_v3(mv2->co, co); - - if (do_vgroup_mirr) { - MDeformVert *dvert= DM_get_vert_data(result, numVerts, CD_MDEFORMVERT); - if(dvert) { - defvert_flip(dvert, flip_map, flip_map_len); - } + else { + *vtmap_a = -1; } - numVerts++; + *vtmap_b = -1; /* fill here to avoid 2x loops */ + + vtmap_a++; + vtmap_b++; } } - - for(i = 0; i < maxEdges; i++) { - MEdge inMED; - MEdge *med = CDDM_get_edge(result, numEdges); - - dm->getEdge(dm, i, &inMED); - - DM_copy_edge_data(dm, result, i, numEdges, 1); - *med = inMED; - numEdges++; - - med->v1 = indexMap[inMED.v1][0]; - med->v2 = indexMap[inMED.v2][0]; - - if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) { - MEdge *med2 = CDDM_get_edge(result, numEdges); - - DM_copy_edge_data(dm, result, i, numEdges, 1); - *med2 = *med; - numEdges++; - - med2->v1 += indexMap[inMED.v1][1]; - med2->v2 += indexMap[inMED.v2][1]; + + /* handle shape keys */ + totshape = CustomData_number_of_layers(&result->vertData, CD_SHAPEKEY); + for (a = 0; a < totshape; a++) { + float (*cos)[3] = CustomData_get_layer_n(&result->vertData, CD_SHAPEKEY, a); + for (i = maxVerts; i < result->numVertData; i++) { + mul_m4_v3(mtx, cos[i]); } } + + /* adjust mirrored edge vertex indices */ + me = CDDM_get_edges(result) + maxEdges; + for (i = 0; i < maxEdges; i++, me++) { + me->v1 += maxVerts; + me->v2 += maxVerts; + } + + /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */ + mp = CDDM_get_polys(result) + maxPolys; + ml = CDDM_get_loops(result); + for (i = 0; i < maxPolys; i++, mp++) { + MLoop *ml2; + int e; + + /* reverse the loop */ + for (j = 0; j < mp->totloop; j++) { + DM_copy_loop_data(result, result, mp->loopstart + j, mp->loopstart + maxLoops + mp->totloop - j - 1, 1); + } - for(i = 0; i < maxFaces; i++) { - MFace inMF; - MFace *mf = CDDM_get_face(result, numFaces); - - dm->getFace(dm, i, &inMF); - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf = inMF; - numFaces++; - - mf->v1 = indexMap[inMF.v1][0]; - mf->v2 = indexMap[inMF.v2][0]; - mf->v3 = indexMap[inMF.v3][0]; - mf->v4 = indexMap[inMF.v4][0]; + ml2 = ml + mp->loopstart + maxLoops; + e = ml2[0].e; + for (j = 0; j < mp->totloop-1; j++) { + ml2[j].e = ml2[j+1].e; + } + ml2[mp->totloop-1].e = e; - if ( indexMap[inMF.v1][1] || - indexMap[inMF.v2][1] || - indexMap[inMF.v3][1] || - (mf->v4 && indexMap[inMF.v4][1])) - { - MFace *mf2 = CDDM_get_face(result, numFaces); - static int corner_indices[4] = {2, 1, 0, 3}; - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf2 = *mf; - - mf2->v1 += indexMap[inMF.v1][1]; - mf2->v2 += indexMap[inMF.v2][1]; - mf2->v3 += indexMap[inMF.v3][1]; - if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1]; - - /* mirror UVs if enabled */ - if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) { - MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE); - if(tf) { - int j; - for(j = 0; j < 4; ++j) { - if(mmd->flag & MOD_MIR_MIRROR_U) - tf->uv[j][0] = 1.0f - tf->uv[j][0]; - if(mmd->flag & MOD_MIR_MIRROR_V) - tf->uv[j][1] = 1.0f - tf->uv[j][1]; - } - } + mp->loopstart += maxLoops; + } + + /* adjust mirrored loop vertex and edge indices */ + ml = CDDM_get_loops(result) + maxLoops; + for (i = 0; i < maxLoops; i++, ml++) { + ml->v += maxVerts; + ml->e += maxEdges; + } + + /* handle uvs, + * let tessface recalc handle updating the MTFace data */ + if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) { + const int do_mirr_u= (mmd->flag & MOD_MIR_MIRROR_U) != 0; + const int do_mirr_v= (mmd->flag & MOD_MIR_MIRROR_V) != 0; + + const int totuv = CustomData_number_of_layers(&result->loopData, CD_MLOOPUV); + + for (a = 0; a < totuv; a++) { + MLoopUV *dmloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, a); + int j = maxLoops; + dmloopuv += j; /* second set of loops only */ + for ( ; i-- > 0; dmloopuv++) { + if (do_mirr_u) dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0]; + if (do_mirr_v) dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1]; } - - /* Flip face normal */ - SWAP(unsigned int, mf2->v1, mf2->v3); - DM_swap_face_data(result, numFaces, corner_indices); - - test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3); - numFaces++; } } - if (flip_map) MEM_freeN(flip_map); + /* handle vgroup stuff */ + if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vertData, CD_MDEFORMVERT)) { + MDeformVert *dvert = CustomData_get_layer(&result->vertData, CD_MDEFORMVERT); + int *flip_map= NULL, flip_map_len= 0; - MEM_freeN(indexMap); + flip_map= defgroup_flip_map(ob, &flip_map_len, FALSE); + + for (i = maxVerts; i-- > 0; dvert++) { + defvert_flip(dvert, flip_map, flip_map_len); + } + } - CDDM_lower_num_verts(result, numVerts); - CDDM_lower_num_edges(result, numEdges); - CDDM_lower_num_faces(result, numFaces); + if (do_vtargetmap) { + if (is_vtargetmap) { /* slow - so only call if one or more merge verts are found */ + result = CDDM_merge_verts(result, vtargetmap); + } + MEM_freeN(vtargetmap); + } return result; } static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, - Object *ob, DerivedMesh *dm) + Object *ob, DerivedMesh *dm) { DerivedMesh *result = dm; @@ -309,9 +310,9 @@ static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, } static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) { DerivedMesh *result; MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -319,14 +320,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = mirrorModifier__doMirror(mmd, ob, derivedData); if(result != derivedData) - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); return result; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), - DerivedMesh *derivedData) + struct BMEditMesh *UNUSED(editData), + DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); } diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 55f29137eb9..de3989dfe38 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -78,9 +78,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, Mesh *me= (Mesh*)ob->data; if(mmd->totlvl) { - if(!CustomData_get_layer(&me->fdata, CD_MDISPS)) { + if(!CustomData_get_layer(&me->ldata, CD_MDISPS)) { /* multires always needs a displacement layer */ - CustomData_add_layer(&me->fdata, CD_MDISPS, CD_CALLOC, NULL, me->totface); + CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); } } @@ -90,7 +90,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, return dm; if(useRenderParams || !isFinalCalc) { - DerivedMesh *cddm= CDDM_copy(result); + DerivedMesh *cddm= CDDM_copy(result, 0); result->release(result); result= cddm; } diff --git a/source/blender/modifiers/intern/MOD_ngoninterp.c b/source/blender/modifiers/intern/MOD_ngoninterp.c new file mode 100644 index 00000000000..08d83016e18 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_ngoninterp.c @@ -0,0 +1,329 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 by the Blender Foundation. + * All rights reserved. + * + * Contributor(s): Daniel Dunbar + * Ton Roosendaal, + * Ben Batt, + * Brecht Van Lommel, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_mask.c + * \ingroup modifiers + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_array.h" +#include "BLI_edgehash.h" +#include "BLI_math.h" + +#include "DNA_armature_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_deform.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + +static void copyData(ModifierData *md, ModifierData *target) +{ + NgonInterpModifierData *mmd = (NgonInterpModifierData*) md; + NgonInterpModifierData *tmmd = (NgonInterpModifierData*) target; + + tmmd->resolution = mmd->resolution; +} + +static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + NgonInterpModifierData *nmd= (NgonInterpModifierData *)md; + DerivedMesh *dm= derivedData; + DerivedMesh *cddm, *dummy; + MFace *mf; + MPoly *mpoly; + MLoop *mloop; + MFace *mface = NULL, *mf2; + MVert *mvert = NULL, *omvert; + BLI_array_declare(mface); + BLI_array_declare(mvert); + int *verts=NULL, *loops=NULL; + BLI_array_declare(verts); + BLI_array_declare(loops); + float *w = NULL, (*cos)[3] = NULL; + BLI_array_declare(w); + BLI_array_declare(cos); + int *origv = NULL, *origf = NULL, *of, *ov; + BLI_array_declare(origv); + BLI_array_declare(origf); + DerivedMesh *copy = NULL; + int i; + + int numTex; + int numCol; + int hasWCol; + + if (nmd->resolution <= 0) + return dm; + + if (!CDDM_Check(dm)) { + dm = copy = CDDM_copy(dm, 0); + } + + CDDM_recalc_tesselation(dm); + + mf = dm->getTessFaceArray(dm); + of = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + mpoly = CDDM_get_polys(dm); + mloop = CDDM_get_loops(dm); + + /*eek!*/ + if (!of) + return dm; + + /*create a dummy mesh to compute interpolated loops on*/ + dummy = CDDM_from_template(dm, 0, 0, 0, 3, 0); + + /* CustomData we check must match what is passed to mesh_loops_to_mface_corners() */ + numTex = CustomData_number_of_layers(&dm->polyData, CD_MTEXPOLY); + numCol = CustomData_number_of_layers(&dummy->loopData, CD_MLOOPCOL); + hasWCol = CustomData_has_layer(&dummy->loopData, CD_WEIGHT_MLOOPCOL); + + /*copy original verts here, so indices stay correct*/ + omvert = dm->getVertArray(dm); + ov = dm->getVertDataArray(dm, CD_ORIGINDEX); + for (i=0; i<dm->numVertData; i++) { + BLI_array_append(mvert, omvert[i]); + BLI_array_append(origv, ov ? ov[i] : i); + } + + for (i=0; i<dm->numTessFaceData; i++, mf++, of++) { + int x, y, x2; + float fac; + + BLI_array_empty(verts); + +#define NG_MAKE_VERT(orig)\ + BLI_array_append(mvert, omvert[orig]);\ + BLI_array_append(origv, ov ? ov[orig] : orig);\ + BLI_array_append(verts, BLI_array_count(mvert)-1); + +#define NG_MAKE_VERTCO(orig, coord) NG_MAKE_VERT(orig); copy_v3_v3(mvert[BLI_array_count(mvert)-1].co, coord) + + y = 0; + fac = 1.0f / (float)(nmd->resolution + 1); + for (x=0; x<nmd->resolution+2; x++) { + float co1[3], co2[3], co3[3]; + + sub_v3_v3v3(co1, omvert[mf->v1].co, omvert[mf->v3].co); + sub_v3_v3v3(co2, omvert[mf->v2].co, omvert[mf->v3].co); + + mul_v3_fl(co1, 1.0f - fac*x); + mul_v3_fl(co2, 1.0f - fac*x); + + add_v3_v3(co1, omvert[mf->v3].co); + add_v3_v3(co2, omvert[mf->v3].co); + + if (x == 0) { + BLI_array_append(verts, mf->v1); + } else if (x == nmd->resolution+1) { + BLI_array_append(verts, mf->v3); + } else { + NG_MAKE_VERTCO(mf->v1, co1); + } + + for (x2=0; x2<(nmd->resolution-x); x2++) { + sub_v3_v3v3(co3, co1, co2); + mul_v3_fl(co3, 1.0f - (1.0f/(float)(nmd->resolution-x+1))*(x2+1)); + add_v3_v3(co3, co2); + + NG_MAKE_VERTCO(mf->v2, co3); + } + + if (x == 0) { + BLI_array_append(verts, mf->v2); + } else if (x != nmd->resolution+1) { + NG_MAKE_VERTCO(mf->v1, co2); + } + } + + y = 0; + for (x=0; x<BLI_array_count(verts)-2; x++) { + int v1, v2, v3; + + if (x2 == nmd->resolution-y+1) { + x2 = 0; + y++; + continue; + } else { + /*int lindex[3] = {0, 1, 2};*/ /*UNUSED*/ + + v1 = verts[x]; + v2 = verts[x+1]; + v3 = verts[x+(nmd->resolution-y)+2]; + + BLI_array_growone(mface); + BLI_array_growone(origf); + + /*make first face*/ + origf[BLI_array_count(origf)-1] = *of; + mf2 = mface + BLI_array_count(mface)-1; + *mf2 = *mf; + + mf2->v1 = v1; + mf2->v2 = v2; + mf2->v3 = v3; + mf2->v4 = 0; + + if (x2 != nmd->resolution-y) { + /*make second face*/ + BLI_array_growone(mface); + BLI_array_growone(origf); + + origf[BLI_array_count(origf)-1] = *of; + mf2 = mface + BLI_array_count(mface)-1; + *mf2 = *mf; + + mf2->v1 = verts[x+(nmd->resolution-y)+3]; + mf2->v2 = v3; + mf2->v3 = v2; + mf2->v4 = 0; + } + } + + x2++; + } + } + + cddm = CDDM_from_template(dm, BLI_array_count(mvert), dm->numEdgeData, BLI_array_count(mface), 0, 0); + + mf2 = mface; + for (i=0; i<BLI_array_count(mface); i++, mf2++) { + MPoly *mp = mpoly + *of; + MLoop *ml; + float co[3], cent[3] = {0.0f, 0.0f, 0.0f}; + int j, lindex[4] = {0, 1, 2}; /* only ever use 3 in this case */ + + BLI_array_empty(w); + BLI_array_empty(cos); + BLI_array_empty(loops); + + mp = mpoly + origf[i]; + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + BLI_array_growone(cos); + BLI_array_growone(w); + BLI_array_append(loops, j+mp->loopstart); + copy_v3_v3(cos[j], mvert[ml->v].co); + } + + /*scale source face coordinates a bit, so points sitting directly on an + edge will work.*/ + mul_v3_fl(cent, 1.0f/(float)(mp->totloop)); + for (j=0; j<mp->totloop; j++) { + sub_v3_v3(cos[j], cent); + mul_v3_fl(cos[j], 1.0f+FLT_EPSILON*1500.0f); + add_v3_v3(cos[j], cent); + } + + copy_v3_v3(co, (mvert + mf2->v1)->co); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 0); + + copy_v3_v3(co, (mvert + mf2->v2)->co); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 1); + + copy_v3_v3(co, (mvert + mf2->v3)->co); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 2); + + mesh_loops_to_mface_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, + lindex, i, origf[i], 3, + numTex, numCol, hasWCol); + } + + CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData); + CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData); + + CDDM_set_mface(cddm, mface); + CDDM_set_mvert(cddm, mvert); + + /*set origindex pointer*/ + MEM_freeN(CustomData_get_layer(&cddm->faceData, CD_ORIGINDEX)); + CustomData_set_layer(&cddm->faceData, CD_MFACE, mface); + + if (CustomData_has_layer(&cddm->vertData, CD_ORIGINDEX)) + CustomData_set_layer(&cddm->vertData, CD_ORIGINDEX, origv); + + CustomData_set_layer(&cddm->faceData, CD_ORIGINDEX, origf); + + BLI_array_free(cos); + BLI_array_free(w); + + dummy->needsFree = 1; + dummy->release(dummy); + + /*create polys from mface triangles*/ + CDDM_tessfaces_to_faces(cddm); /*builds ngon faces from tess (mface) faces*/ + + return cddm; +} + + +ModifierTypeInfo modifierType_NgonInterp = { + /* name */ "NgonInterp", + /* structName */ "NgonInterpModifierData", + /* structSize */ sizeof(NgonInterpModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping|eModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + /* deformVerts */ 0, + /* deformMatrices */ 0, + /* deformVertsEM */ 0, + /* deformMatricesEM */ 0, + /* applyModifier */ applyModifier, + /* applyModifierEM */ 0, + /* initData */ 0, + /* requiredDataMask */ 0, + /* freeData */ 0, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* dependsOnNormals */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index f79ee0ca5fb..2910fd515ec 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -269,7 +269,8 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) DerivedMesh *result; MVert *mverts; - MFace *mfaces; + MPoly *mpolys; + MLoop *mloops; int *origindex; int cdlayer; @@ -280,7 +281,7 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) const int res_y = ry * omd->repeat_y; const int num_verts = (res_x + 1) * (res_y + 1); - const int num_edges = (res_x * res_y * 2) + res_x + res_y; + /* const int num_edges = (res_x * res_y * 2) + res_x + res_y; */ /* UNUSED BMESH */ const int num_faces = res_x * res_y; float sx = omd->size * omd->spatial_size; @@ -295,11 +296,17 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) sx /= rx; sy /= ry; - result = CDDM_new(num_verts, num_edges, num_faces); + result = CDDM_new(num_verts, 0, 0, num_faces * 4, num_faces); mverts = CDDM_get_verts(result); - mfaces = CDDM_get_faces(result); + mpolys = CDDM_get_polys(result); + mloops = CDDM_get_loops(result); + +#if 0 // trunk origindex= result->getFaceDataArray(result, CD_ORIGINDEX); +#else // bmesh + origindex= CustomData_get_layer(&result->polyData, CD_ORIGINDEX); +#endif /* create vertices */ #pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES) @@ -319,13 +326,22 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) for (x=0; x < res_x; x++) { const int fi = y*res_x + x; const int vi = y*(res_x+1) + x; - MFace *mf= &mfaces[fi]; - mf->v1 = vi; - mf->v2 = vi + 1; - mf->v3 = vi + 1 + res_x+1; - mf->v4 = vi + res_x+1; + MPoly *mp= &mpolys[fi]; + MLoop *ml= &mloops[fi * 4]; + + ml->v = vi; + ml++; + ml->v = vi + 1; + ml++; + ml->v = vi + 1 + res_x + 1; + ml++; + ml->v = vi + res_x + 1; + ml++; + + mp->loopstart= fi * 4; + mp->totloop= 4; - mf->flag |= ME_SMOOTH; + mp->flag |= ME_SMOOTH; /* generated geometry does not map to original faces */ origindex[fi] = ORIGINDEX_NONE; @@ -335,28 +351,35 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) CDDM_calc_edges(result); /* add uvs */ - cdlayer= CustomData_number_of_layers(&result->faceData, CD_MTFACE); + cdlayer= CustomData_number_of_layers(&result->loopData, CD_MLOOPUV); if(cdlayer < MAX_MTFACE) { - MTFace *tfaces= CustomData_add_layer(&result->faceData, CD_MTFACE, CD_CALLOC, NULL, num_faces); + MLoopUV *mloopuvs= CustomData_add_layer(&result->loopData, CD_MLOOPUV, CD_CALLOC, NULL, num_faces * 4); - if (tfaces) { /* unlikely to fail */ + if (mloopuvs) { /* unlikely to fail */ ix = 1.0 / rx; iy = 1.0 / ry; #pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES) for (y=0; y < res_y; y++) { for (x=0; x < res_x; x++) { const int i = y*res_x + x; - tfaces[i].uv[0][0] = x * ix; - tfaces[i].uv[0][1] = y * iy; + MLoopUV *luv= &mloopuvs[i * 4]; - tfaces[i].uv[1][0] = (x+1) * ix; - tfaces[i].uv[1][1] = y * iy; + luv->uv[0] = x * ix; + luv->uv[1] = y * iy; + luv++; - tfaces[i].uv[2][0] = (x+1) * ix; - tfaces[i].uv[2][1] = (y+1) * iy; + luv->uv[0] = (x+1) * ix; + luv->uv[1] = y * iy; + luv++; + + luv->uv[0] = (x+1) * ix; + luv->uv[1] = (y+1) * iy; + luv++; + + luv->uv[0] = x * ix; + luv->uv[1] = (y+1) * iy; + luv++; - tfaces[i].uv[3][0] = x * ix; - tfaces[i].uv[3][1] = (y+1) * iy; } } } @@ -375,6 +398,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob, OceanResult ocr; MVert *mverts, *mv; + MLoop *mloops; int i, j; @@ -413,7 +437,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob, if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) dm = generate_ocean_geometry(omd); else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { - dm = CDDM_copy(derivedData); + dm = CDDM_copy(derivedData, 0); } cfra = md->scene->r.cfra; @@ -421,29 +445,34 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob, cfra -= omd->bakestart; // shift to 0 based num_verts = dm->getNumVerts(dm); - num_faces = dm->getNumFaces(dm); + num_faces = dm->getNumPolys(dm); mverts = dm->getVertArray(dm); + mloops = dm->getLoopArray(dm); /* add vcols before displacement - allows lookup based on position */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { - int cdlayer= CustomData_number_of_layers(&dm->faceData, CD_MCOL); + int cdlayer= CustomData_number_of_layers(&dm->loopData, CD_MLOOPCOL); if(cdlayer < MAX_MCOL) { - MCol *mcols= CustomData_add_layer_named(&dm->faceData, CD_MCOL, CD_CALLOC, NULL, num_faces, omd->foamlayername); + MLoopCol *mloopcols= CustomData_add_layer_named(&dm->loopData, CD_MLOOPCOL, CD_CALLOC, NULL, num_faces * 4, omd->foamlayername); - if (mcols) { /* unlikely to fail */ - MCol *mc; - MFace *mfaces= dm->getFaceArray(dm); - MFace *mf; + if (mloopcols) { /* unlikely to fail */ + MLoopCol *mlcol; + MPoly *mpolys= dm->getPolyArray(dm); + MPoly *mp; float foam; - for (i = 0, mf= mfaces; i < num_faces; i++, mf++) { - j= mf->v4 ? 3 : 2; + for (i = 0, mp= mpolys; i < num_faces; i++, mp++) { + j= mp->totloop - 1; + + /* highly unlikely */ + if (j <= 0) continue; + do { - const float *co= mverts[*(&mf->v1 + j)].co; + const float *co= mverts[mloops[mp->loopstart + j].v].co; const float u = OCEAN_CO(size_co_inv, co[0]); const float v = OCEAN_CO(size_co_inv, co[1]); @@ -457,8 +486,8 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob, foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage); } - mc= &mcols[i*4 + j]; - mc->r = mc->g = mc->b = (char)(foam * 255); + mlcol= &mloopcols[mp->loopstart + j]; + mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255); /* mc->a = 255; */ /* no need to set */ } while (j--); } @@ -512,13 +541,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, result = doOcean(md, ob, derivedData, 0); if(result != derivedData) - CDDM_calc_normals(result); + CDDM_calc_normals_mapping(result); return result; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 509c916941f..aaa3088f747 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -122,6 +122,8 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, float max_co=0.0, min_co=0.0, temp_co[3], cross[3]; float *size=NULL; + DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + trackneg=((ob->trackflag>2)?1:0); if(pimd->ob==ob){ @@ -174,7 +176,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, pars=psys->particles; totvert=dm->getNumVerts(dm); - totface=dm->getNumFaces(dm); + totface=dm->getNumTessFaces(dm); maxvert=totvert*totpart; maxface=totface*totpart; @@ -190,7 +192,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, max_co=max_r[track]; } - result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface); + result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface, 0, 0); mvert=result->getVertArray(result); orig_mvert=dm->getVertArray(dm); @@ -260,8 +262,8 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, add_v3_v3(mv->co, state.co); } - mface=result->getFaceArray(result); - orig_mface=dm->getFaceArray(dm); + mface=result->getTessFaceArray(result); + orig_mface=dm->getTessFaceArray(dm); for(i=0; i<maxface; i++){ MFace *inMF; @@ -291,7 +293,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, } inMF = orig_mface + i%totface; - DM_copy_face_data(dm, result, i%totface, i, 1); + DM_copy_poly_data(dm, result, i%totface, i, 1); *mf = *inMF; mf->v1+=(i/totface)*totvert; @@ -301,8 +303,8 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, mf->v4+=(i/totface)*totvert; } - CDDM_calc_edges(result); - CDDM_calc_normals(result); + CDDM_calc_edges_tessface(result); + CDDM_calc_normals_mapping(result); if(psys->lattice){ end_latt_deform(psys->lattice); @@ -312,10 +314,12 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, if(size) MEM_freeN(size); + CDDM_tessfaces_to_faces(result); /*builds ngon faces from tess (mface) faces*/ + return result; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 5ce2437b8ea..42061222156 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -164,9 +164,9 @@ static void deformVerts(ModifierData *md, Object *ob, } /* make new dm */ - psmd->dm=CDDM_copy(dm); + psmd->dm=CDDM_copy(dm, 0); CDDM_apply_vert_coords(psmd->dm, vertexCos); - CDDM_calc_normals(psmd->dm); + CDDM_calc_normals_mapping(psmd->dm); if(needsFree){ dm->needsFree = 1; @@ -179,13 +179,13 @@ static void deformVerts(ModifierData *md, Object *ob, /* report change in mesh structure */ if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert || psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge || - psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){ + psmd->dm->getNumTessFaces(psmd->dm)!=psmd->totdmface){ psys->recalc |= PSYS_RECALC_RESET; psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm); psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm); - psmd->totdmface= psmd->dm->getNumFaces(psmd->dm); + psmd->totdmface= psmd->dm->getNumTessFaces(psmd->dm); } if(psys) { diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index bc67237fb40..f1f09e1db1e 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -82,9 +82,9 @@ static void init_dualcon_mesh(DualConInput *mesh, DerivedMesh *dm) mesh->co_stride = sizeof(MVert); mesh->totco = dm->getNumVerts(dm); - mesh->faces = (void*)dm->getFaceArray(dm); + mesh->faces = (void*)dm->getTessFaceArray(dm); mesh->face_stride = sizeof(MFace); - mesh->totface = dm->getNumFaces(dm); + mesh->totface = dm->getNumTessFaces(dm); dm->getMinMax(dm, mesh->min, mesh->max); } @@ -105,7 +105,7 @@ static void *dualcon_alloc_output(int totvert, int totquad) "DualConOutput"))) return NULL; - output->dm = CDDM_new(totvert, 0, totquad); + output->dm = CDDM_new(totvert, 0, totquad, 0, 0); return output; } @@ -126,9 +126,9 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4]) DerivedMesh *dm = output->dm; MFace *mface; - assert(output->curface < dm->getNumFaces(dm)); + assert(output->curface < dm->getNumTessFaces(dm)); - mface = &CDDM_get_faces(dm)[output->curface]; + mface = &CDDM_get_tessfaces(dm)[output->curface]; mface->v1 = vert_indices[0]; mface->v2 = vert_indices[1]; mface->v3 = vert_indices[2]; @@ -151,6 +151,8 @@ static DerivedMesh *applyModifier(ModifierData *md, DualConFlags flags = 0; DualConMode mode = 0; + DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + rmd = (RemeshModifierData*)md; init_dualcon_mesh(&input, dm); @@ -181,13 +183,29 @@ static DerivedMesh *applyModifier(ModifierData *md, rmd->scale, rmd->depth); result = output->dm; - CDDM_lower_num_faces(result, output->curface); + CDDM_lower_num_tessfaces(result, output->curface); MEM_freeN(output); - CDDM_calc_edges(result); - CDDM_calc_normals(result); + CDDM_calc_edges_tessface(result); + CDDM_calc_normals_mapping(result); + + /* BMESH_TODO - create polygons */ + +#if 0 return result; + +#else /* BMESH ONLY */ + + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + CDDM_calc_normals_mapping(dm); + result->needsFree = 1; + result->release(result); + + return dm; + +#endif + } #else /* !WITH_MOD_REMESH */ diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 93abbb1780c..c5d99a939b9 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -132,6 +132,23 @@ static void copyData(ModifierData *md, ModifierData *target) tltmd->iter= sltmd->iter; } +#if 0 +static int findEd(MEdge *medge_new, int toted, int v1, int v2) +{ + int i; + + for (i = 0; i < toted; i++) { + if ( (medge_new[i].v1 == v1 && medge_new[i].v2 == v2) || + (medge_new[i].v1 == v2 && medge_new[i].v2 == v1) ) + { + return i; + } + } + + return -1; +} +#endif + static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, int useRenderParams, @@ -142,13 +159,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, ScrewModifierData *ltmd= (ScrewModifierData*) md; int *origindex; - int mface_index=0; + int mpoly_index=0; int step; int i, j; unsigned int i1, i2; int step_tot= useRenderParams ? ltmd->render_steps : ltmd->steps; const int do_flip = ltmd->flag & MOD_SCREW_NORMAL_FLIP ? 1 : 0; - int maxVerts=0, maxEdges=0, maxFaces=0; + int maxVerts=0, maxEdges=0, maxPolys=0; const unsigned int totvert= dm->getNumVerts(dm); const unsigned int totedge= dm->getNumEdges(dm); @@ -165,8 +182,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int vc_tot_linked= 0; short other_axis_1, other_axis_2; float *tmpf1, *tmpf2; + + int edge_offset; - MFace *mface_new, *mf_new; + MPoly *mpoly_new, *mp_new; + MLoop *mloop_new, *ml_new; MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new; MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base; @@ -174,7 +194,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* dont do anything? */ if (!totvert) - return CDDM_from_template(dm, 0, 0, 0); + return CDDM_from_template(dm, 0, 0, 0, 0, 0); switch(ltmd->axis) { case 0: @@ -278,7 +298,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, maxVerts = totvert * step_tot; /* -1 because we're joining back up */ maxEdges = (totvert * step_tot) + /* these are the edges between new verts */ (totedge * step_tot); /* -1 because vert edges join */ - maxFaces = totedge * step_tot; + maxPolys = totedge * step_tot; screw_ofs= 0.0f; } @@ -289,20 +309,29 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, maxVerts = totvert * step_tot; /* -1 because we're joining back up */ maxEdges = (totvert * (step_tot-1)) + /* these are the edges between new verts */ (totedge * step_tot); /* -1 because vert edges join */ - maxFaces = totedge * (step_tot-1); + maxPolys = totedge * (step_tot-1); } - result= CDDM_from_template(dm, maxVerts, maxEdges, maxFaces); + result= CDDM_from_template(dm, maxVerts, maxEdges, 0, maxPolys * 4, maxPolys); /* copy verts from mesh */ mvert_orig = dm->getVertArray(dm); medge_orig = dm->getEdgeArray(dm); mvert_new = result->getVertArray(result); - mface_new = result->getFaceArray(result); + mpoly_new = result->getPolyArray(result); + mloop_new = result->getLoopArray(result); medge_new = result->getEdgeArray(result); - - origindex= result->getFaceDataArray(result, CD_ORIGINDEX); + + if (!CustomData_has_layer(&result->polyData, CD_ORIGINDEX)) { + CustomData_add_layer(&result->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, maxPolys); + } + +#if 0 // trunk + origindex = result->getPolyDataArray(result, CD_ORIGINDEX); +#else // bmesh + origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX); +#endif DM_copy_vert_data(dm, result, 0, 0, totvert); /* copy first otherwise this overwrites our own vertex normals */ @@ -746,9 +775,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } } - mf_new= mface_new; + mp_new= mpoly_new; + ml_new= mloop_new; med_new_firstloop= medge_new; + /* more of an offset in this case */ + edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1))); + for (i=0; i < totedge; i++, med_new_firstloop++) { /* for each edge, make a cylinder of quads */ i1= med_new_firstloop->v1; @@ -758,26 +791,36 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* new face */ if(do_flip) { - mf_new->v4= i1; - mf_new->v3= i2; - mf_new->v2= i2 + totvert; - mf_new->v1= i1 + totvert; + ml_new[3].v = i1; + ml_new[2].v = i2; + ml_new[1].v = i2 + totvert; + ml_new[0].v = i1 + totvert; + + ml_new[2].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1; + ml_new[1].e = totedge + i2; + ml_new[0].e = edge_offset + step + (i * (step_tot - 1)); + ml_new[3].e = totedge + i1; } else { - mf_new->v1= i1; - mf_new->v2= i2; - mf_new->v3= i2 + totvert; - mf_new->v4= i1 + totvert; - } - - if( !mf_new->v3 || !mf_new->v4 ) { - SWAP(unsigned int, mf_new->v1, mf_new->v3); - SWAP(unsigned int, mf_new->v2, mf_new->v4); + ml_new[0].v = i1; + ml_new[1].v = i2; + ml_new[2].v = i2 + totvert; + ml_new[3].v = i1 + totvert; + + ml_new[0].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1; + ml_new[1].e = totedge + i2; + ml_new[2].e = edge_offset + step + (i * (step_tot - 1)); + ml_new[3].e = totedge + i1; } - mf_new->flag= ME_SMOOTH; - origindex[mface_index]= ORIGINDEX_NONE; - mf_new++; - mface_index++; + + + mp_new->loopstart = mpoly_index * 4; + mp_new->totloop = 4; + mp_new->flag= ME_SMOOTH; + origindex[mpoly_index]= ORIGINDEX_NONE; + mp_new++; + ml_new += 4; + mpoly_index++; /* new vertical edge */ if (step) { /* The first set is already dome */ @@ -794,26 +837,35 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* close the loop*/ if (close) { if(do_flip) { - mf_new->v4= i1; - mf_new->v3= i2; - mf_new->v2= med_new_firstloop->v2; - mf_new->v1= med_new_firstloop->v1; + ml_new[3].v = i1; + ml_new[2].v = i2; + ml_new[1].v = med_new_firstloop->v2; + ml_new[0].v = med_new_firstloop->v1; + + ml_new[2].e = (edge_offset + step + (i * (step_tot - 1))) - 1; + ml_new[1].e = totedge + i2; + ml_new[0].e = i; + ml_new[3].e = totedge + i1; } else { - mf_new->v1= i1; - mf_new->v2= i2; - mf_new->v3= med_new_firstloop->v2; - mf_new->v4= med_new_firstloop->v1; + ml_new[0].v = i1; + ml_new[1].v = i2; + ml_new[2].v = med_new_firstloop->v2; + ml_new[3].v = med_new_firstloop->v1; + + ml_new[0].e = (edge_offset + step + (i * (step_tot - 1))) - 1; + ml_new[1].e = totedge + i2; + ml_new[2].e = i; + ml_new[3].e = totedge + i1; } - if( !mf_new->v3 || !mf_new->v4 ) { - SWAP(unsigned int, mf_new->v1, mf_new->v3); - SWAP(unsigned int, mf_new->v2, mf_new->v4); - } - mf_new->flag= ME_SMOOTH; - origindex[mface_index]= ORIGINDEX_NONE; - mf_new++; - mface_index++; + mp_new->loopstart = mpoly_index * 4; + mp_new->totloop = 4; + mp_new->flag= ME_SMOOTH; + origindex[mpoly_index]= ORIGINDEX_NONE; + mp_new++; + ml_new += 4; + mpoly_index++; } /* new vertical edge */ @@ -823,9 +875,38 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, med_new->crease= med_new_firstloop->crease; med_new++; } - + + /* validate loop edges */ +#if 0 + { + i = 0; + printf("\n"); + for ( ; i < maxPolys * 4; i += 4) { + int ii; + ml_new = mloop_new + i; + ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v); + printf("%d %d -- ", ii, ml_new[0].e); + ml_new[0].e = ii; + + ii = findEd(medge_new, maxEdges, ml_new[1].v, ml_new[2].v); + printf("%d %d -- ", ii, ml_new[1].e); + ml_new[1].e = ii; + + ii = findEd(medge_new, maxEdges, ml_new[2].v, ml_new[3].v); + printf("%d %d -- ", ii, ml_new[2].e); + ml_new[2].e = ii; + + ii = findEd(medge_new, maxEdges, ml_new[3].v, ml_new[0].v); + printf("%d %d\n", ii, ml_new[3].e); + ml_new[3].e = ii; + + } + } +#endif + if((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { - CDDM_calc_normals(result); + /* BMESH_TODO, we only need to get vertex normals here, this is way overkill */ + CDDM_calc_normals_mapping(result); } return result; @@ -862,7 +943,7 @@ static void foreachObjectLink( static DerivedMesh *applyModifierEM( ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index 9080ca39ebf..8a93a8a6d6f 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -90,7 +90,7 @@ static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedDat } static void deformVertsEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) @@ -102,7 +102,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, } static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], float (*defMats)[3][3], diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index e8f099785f9..1d68e201dc0 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -128,7 +128,7 @@ static void deformVerts(ModifierData *md, Object *ob, dm->release(dm); } -static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) +static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; CustomDataMask dataMask = requiredDataMask(ob, md); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 2c056ad4021..4485346bf55 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -336,7 +336,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM(ModifierData *md, Object *ob, - struct EditMesh *editData, + struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index e43304bc4b9..01b012655d0 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -226,7 +226,7 @@ static void deformVerts( } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm= get_dm(ob, editData, derivedData, NULL, 0); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 99f5117e3cd..3f058aa9a0a 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -35,13 +35,14 @@ #include "DNA_meshdata_types.h" +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_edgehash.h" -#include "BLI_utildefines.h" +#include "BLI_array.h" #include "BLI_string.h" -#include "MEM_guardedalloc.h" - #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" #include "BKE_particle.h" @@ -59,7 +60,8 @@ typedef struct EdgeFaceRef { static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) { int i, numVerts, numEdges, numFaces; - MFace *mface, *mf; + MPoly *mpoly, *mp; + MLoop *mloop, *ml; MVert *mvert, *mv; float (*face_nors)[3]; @@ -68,10 +70,11 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) numVerts = dm->getNumVerts(dm); numEdges = dm->getNumEdges(dm); - numFaces = dm->getNumFaces(dm); - mface = dm->getFaceArray(dm); + numFaces = dm->getNumPolys(dm); + mpoly = CDDM_get_polys(dm); mvert = dm->getVertArray(dm); - + mloop = CDDM_get_loops(dm); + /* we don't want to overwrite any referenced layers */ /* @@ -80,14 +83,14 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) cddm->mvert = mv; */ - face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); if(!face_nors) { calc_face_nors = 1; - face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, numFaces); + face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, numFaces); } mv = mvert; - mf = mface; + mp = mpoly; { EdgeHash *edge_hash = BLI_edgehash_new(); @@ -116,24 +119,16 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) } /* --- end define --- */ - for(i = 0; i < numFaces; i++, mf++) { + for(i = 0; i < numFaces; i++, mp++) { + int j; + f_no = face_nors[i]; + if(calc_face_nors) + mesh_calc_poly_normal(mp, mloop+mp->loopstart, mvert, f_no); - if(mf->v4) { - if(calc_face_nors) - normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); - - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2); - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3); - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v4); - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v4, mf->v1); - } else { - if(calc_face_nors) - normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); - - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2); - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3); - NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v1); + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(ml->v, ME_POLY_LOOP_NEXT(mloop, mp, j)->v); } } @@ -209,32 +204,35 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int UNUSED(isFinalCalc)) { int i; - DerivedMesh *result; + DerivedMesh *result, *odm = dm; const SolidifyModifierData *smd = (SolidifyModifierData*) md; - MFace *mf, *mface, *orig_mface; - MEdge *ed, *medge, *orig_medge; MVert *mv, *mvert, *orig_mvert; - + MEdge *ed, *medge, *orig_medge; + MLoop *ml, *mloop, *orig_mloop; + MPoly *mp, *mpoly, *orig_mpoly; const int numVerts = dm->getNumVerts(dm); const int numEdges = dm->getNumEdges(dm); - const int numFaces = dm->getNumFaces(dm); - + const int numFaces = dm->getNumPolys(dm); + int numLoops=0, newLoops=0, newFaces=0, newEdges=0; + int j; + /* only use material offsets if we have 2 or more materials */ const short mat_nr_max= ob->totcol > 1 ? ob->totcol - 1 : 0; const short mat_ofs= mat_nr_max ? smd->mat_ofs : 0; - const short mat_ofs_rim= mat_nr_max ? smd->mat_ofs_rim : 0; + /* const short mat_ofs_rim= mat_nr_max ? smd->mat_ofs_rim : 0; */ /* UNUSED */ /* use for edges */ int *new_vert_arr= NULL; - int newFaces = 0; - + BLI_array_declare(new_vert_arr); int *new_edge_arr= NULL; - int newEdges = 0; + BLI_array_declare(new_edge_arr); + int *old_vert_arr = MEM_callocN(sizeof(int)*numVerts, "old_vert_arr in solidify"); int *edge_users= NULL; char *edge_order= NULL; - + int *edge_origIndex; + float (*vert_nors)[3]= NULL; const float ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); @@ -248,10 +246,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int defgrp_index; modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index); - - orig_mface = dm->getFaceArray(dm); - orig_medge = dm->getEdgeArray(dm); - orig_mvert = dm->getVertArray(dm); + + if (!CDDM_Check(dm)) { + DerivedMesh *dm2 = CDDM_copy(dm, 0); + dm = dm2; + } + + numLoops = dm->numLoopData; + newLoops = 0; + + orig_mvert = CDDM_get_verts(dm); + orig_medge = CDDM_get_edges(dm); + orig_mloop = CDDM_get_loops(dm); + orig_mpoly = CDDM_get_polys(dm); if(smd->flag & MOD_SOLIDIFY_RIM) { EdgeHash *edgehash = BLI_edgehash_new(); @@ -289,28 +296,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges"); edge_order= MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder"); memset(edge_users, INVALID_UNUSED, sizeof(int) * numEdges); - - for(i=0, mf=orig_mface; i<numFaces; i++, mf++) { - if(mf->v4) { - ADD_EDGE_USER(mf->v1, mf->v2, 0); - ADD_EDGE_USER(mf->v2, mf->v3, 1); - ADD_EDGE_USER(mf->v3, mf->v4, 2); - ADD_EDGE_USER(mf->v4, mf->v1, 3); - } - else { - ADD_EDGE_USER(mf->v1, mf->v2, 0); - ADD_EDGE_USER(mf->v2, mf->v3, 1); - ADD_EDGE_USER(mf->v3, mf->v1, 2); - } + + for (i=0, mp=orig_mpoly; i<numFaces; i++, mp++) { + MLoop *ml; + + for (ml=orig_mloop + mp->loopstart, j=0; j<mp->totloop; ml++, j++) { + ADD_EDGE_USER(ml->v, ME_POLY_LOOP_NEXT(orig_mloop, mp, j)->v, j); + } } #undef ADD_EDGE_USER #undef INVALID_UNUSED #undef INVALID_PAIR - - new_edge_arr= MEM_callocN(sizeof(int) * numEdges, "solid_mod arr"); - ehi= BLI_edgehashIterator_new(edgehash); for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { eidx= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); @@ -318,18 +316,17 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, BLI_edgehashIterator_getKey(ehi, &v1, &v2); orig_mvert[v1].flag |= ME_VERT_TMP_TAG; orig_mvert[v2].flag |= ME_VERT_TMP_TAG; - new_edge_arr[newFaces]= eidx; + BLI_array_append(new_edge_arr, eidx); newFaces++; + newLoops += 4; } } BLI_edgehashIterator_free(ehi); - - - new_vert_arr= MEM_callocN(sizeof(int) * numVerts, "solid_mod new_varr"); for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) { if(mv->flag & ME_VERT_TMP_TAG) { - new_vert_arr[newEdges] = i; + old_vert_arr[i] = BLI_array_count(new_vert_arr); + BLI_array_append(new_vert_arr, i); newEdges++; mv->flag &= ~ME_VERT_TMP_TAG; @@ -344,14 +341,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, dm_calc_normal(dm, vert_nors); } - result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, (numFaces * 2) + newFaces); - - mface = result->getFaceArray(result); - medge = result->getEdgeArray(result); - mvert = result->getVertArray(result); + result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, 0, (numLoops*2) + newLoops, (numFaces * 2) + newFaces); - DM_copy_face_data(dm, result, 0, 0, numFaces); - DM_copy_face_data(dm, result, 0, numFaces, numFaces); + mpoly = CDDM_get_polys(result); + mloop = CDDM_get_loops(result); + medge = CDDM_get_edges(result); + mvert = CDDM_get_verts(result); DM_copy_edge_data(dm, result, 0, 0, numEdges); DM_copy_edge_data(dm, result, 0, numEdges, numEdges); @@ -359,30 +354,41 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DM_copy_vert_data(dm, result, 0, 0, numVerts); DM_copy_vert_data(dm, result, 0, numVerts, numVerts); - { - static int corner_indices[4] = {2, 1, 0, 3}; - unsigned int is_quad; - - for(i=0, mf=mface+numFaces; i<numFaces; i++, mf++) { - mf->v1 += numVerts; - mf->v2 += numVerts; - mf->v3 += numVerts; - if(mf->v4) - mf->v4 += numVerts; - - /* Flip face normal */ - { - is_quad = mf->v4; - SWAP(unsigned int, mf->v1, mf->v3); - DM_swap_face_data(result, i+numFaces, corner_indices); - test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3); - } + DM_copy_loop_data(dm, result, 0, 0, numLoops); + DM_copy_loop_data(dm, result, 0, numLoops, numLoops); + + DM_copy_poly_data(dm, result, 0, 0, numFaces); + DM_copy_poly_data(dm, result, 0, numFaces, numFaces); + + /*flip normals*/ + mp = mpoly + numFaces; + for (i=0; i<dm->numPolyData; i++, mp++) { + MLoop *ml2; + int e; + + ml2 = mloop + mp->loopstart + dm->numLoopData; + for (j=0; j<mp->totloop; j++) { + CustomData_copy_data(&dm->loopData, &result->loopData, mp->loopstart+j, + mp->loopstart+(mp->totloop-j-1)+dm->numLoopData, 1); if(mat_ofs) { - mf->mat_nr += mat_ofs; - CLAMP(mf->mat_nr, 0, mat_nr_max); + mp->mat_nr += mat_ofs; + CLAMP(mp->mat_nr, 0, mat_nr_max); } } + + e = ml2[0].e; + for (j=0; j<mp->totloop-1; j++) { + ml2[j].e = ml2[j+1].e; + } + ml2[mp->totloop-1].e = e; + + mp->loopstart += dm->numLoopData; + + for (j=0; j<mp->totloop; j++) { + ml2[j].e += numEdges; + ml2[j].v += numVerts; + } } for(i=0, ed=medge+numEdges; i<numEdges; i++, ed++) { @@ -436,12 +442,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ float *vert_accum= vert_angles + numVerts; - float face_angles[4]; + float *face_angles = NULL; + BLI_array_staticdeclare(face_angles, 16); /* BM_NGON_STACK_SIZE */ int j, vidx; - face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); if(!face_nors) { - face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numFaceData); + face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData); face_nors_calc= 1; } @@ -452,31 +459,31 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } } - for(i=0, mf=mface; i<numFaces; i++, mf++) { - + for (i=0, mp=mpoly; i<numFaces; i++, mp++) { + mesh_calc_poly_normal(mp, &mloop[mp->loopstart], mvert, face_nors[i]); + /* just added, calc the normal */ - if(face_nors_calc) { - if(mf->v4) - normal_quad_v3(face_nors[i], mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); - else - normal_tri_v3(face_nors[i] , mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); - } - - if(mf->v4) { - angle_quad_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); - j= 3; + BLI_array_empty(face_angles); + for (j=0, ml=mloop+mp->loopstart; j<mp->totloop; j++, ml++) { + MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j); + MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j); + + float e1[3], e2[3], angle; + + sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co); + sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co); + angle = M_PI - angle_normalized_v3v3(e1, e2); + BLI_array_append(face_angles, angle); } - else { - angle_tri_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); - j= 2; - } - - do { - vidx = *(&mf->v1 + j); + + for (j=0, ml=mloop+mp->loopstart; j<mp->totloop; j++, ml++) { + vidx = ml->v; vert_accum[vidx] += face_angles[j]; vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * face_angles[j]; - } while(j--); + } } + + BLI_array_free(face_angles); /* vertex group support */ if(dvert) { @@ -554,19 +561,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, const unsigned char crease_outer= smd->crease_outer * 255.0f; const unsigned char crease_inner= smd->crease_inner * 255.0f; - const int edge_indices[2][4][4] = { - /* quad */ - {{1, 0, 0, 1}, - {2, 1, 1, 2}, - {3, 2, 2, 3}, - {0, 3, 3, 0}}, - /* tri */ - {{1, 0, 0, 1}, - {2, 1, 1, 2}, - {0, 2, 2, 0}, - {0, 0, 0, 0}} /* unused for tris */ - }; - /* add faces & edges */ origindex= result->getEdgeDataArray(result, CD_ORIGINDEX); ed= medge + (numEdges * 2); @@ -582,13 +576,16 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* faces */ - mf= mface + (numFaces * 2); - origindex= result->getFaceDataArray(result, CD_ORIGINDEX); - for(i=0; i<newFaces; i++, mf++) { + edge_origIndex = origindex; + origindex = DM_get_poly_data_layer(result, CD_ORIGINDEX); + + mp = mpoly + (numFaces * 2); + ml = mloop + (numLoops * 2); + j = 0; + for(i=0; i<newFaces; i++, mp++) { int eidx= new_edge_arr[i]; int fidx= edge_users[eidx]; - int flip; - int is_tri; + int flip, k1, k2; if(fidx >= numFaces) { fidx -= numFaces; @@ -601,31 +598,53 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, ed= medge + eidx; /* copy most of the face settings */ - DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1); + DM_copy_poly_data(dm, result, fidx, (numFaces * 2) + i, 1); + mp->loopstart = j+numLoops*2; + mp->flag = mpoly[fidx].flag; - is_tri = (orig_mface[fidx].v4 == 0); + /* notice we use 'mp->totloop' which is later overwritten, + * we could lookup the original face but theres no point since this is a copy + * and will have the same value, just take care when changing order of assignment */ + k1 = mpoly[fidx].loopstart + ((edge_order[eidx] + 1) % mp->totloop); + k2 = mpoly[fidx].loopstart + (edge_order[eidx]); - if(flip) { - DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[is_tri][edge_order[eidx]]); + mp->totloop = 4; + + CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops*2+j+0, 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops*2+j+1, 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops*2+j+2, 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops*2+j+3, 1); - mf->v1= ed->v1; - mf->v2= ed->v2; - mf->v3= ed->v2 + numVerts; - mf->v4= ed->v1 + numVerts; + if(flip) { + ml[j].v = ed->v1; + ml[j++].e = eidx; + + ml[j].v = ed->v2; + ml[j++].e = numEdges*2 + old_vert_arr[ed->v2]; + + ml[j].v = ed->v2+numVerts; + ml[j++].e = eidx+numEdges; + + ml[j].v = ed->v1+numVerts; + ml[j++].e = numEdges*2 + old_vert_arr[ed->v1]; } else { - DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[is_tri][edge_order[eidx]]); + ml[j].v = ed->v2; + ml[j++].e = eidx; + + ml[j].v = ed->v1; + ml[j++].e = numEdges*2 + old_vert_arr[ed->v1]; - mf->v1= ed->v2; - mf->v2= ed->v1; - mf->v3= ed->v1 + numVerts; - mf->v4= ed->v2 + numVerts; + ml[j].v = ed->v1+numVerts; + ml[j++].e = eidx+numEdges; + + ml[j].v = ed->v2+numVerts; + ml[j++].e = numEdges*2 + old_vert_arr[ed->v2]; } - /* use the next material index if option enabled */ - if(mat_ofs_rim) { - mf->mat_nr += mat_ofs_rim; - CLAMP(mf->mat_nr, 0, mat_nr_max); + if (edge_origIndex) { + edge_origIndex[ml[j-3].e] = ORIGINDEX_NONE; + edge_origIndex[ml[j-1].e] = ORIGINDEX_NONE; } if(crease_outer) { /* crease += crease_outer; without wrapping */ @@ -642,7 +661,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } #ifdef SOLIDIFY_SIDE_NORMALS - normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + normal_quad_v3(nor, mvert[ml[j-4].v].co, mvert[ml[j-3].v].co, mvert[ml[j-2].v].co, mvert[ml[j-1].v].co); add_v3_v3(edge_vert_nos[ed->v1], nor); add_v3_v3(edge_vert_nos[ed->v2], nor); @@ -671,17 +690,26 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, MEM_freeN(edge_vert_nos); #endif - MEM_freeN(new_vert_arr); - MEM_freeN(new_edge_arr); + BLI_array_free(new_vert_arr); + BLI_array_free(new_edge_arr); MEM_freeN(edge_users); MEM_freeN(edge_order); } + if (old_vert_arr) + MEM_freeN(old_vert_arr); + /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ if(dvert) { - CDDM_calc_normals(result); + /* BMESH_TODO, we only need to get vertex normals here, this is way overkill */ + CDDM_calc_normals_mapping(result); } - + + if (dm != odm) { + dm->needsFree = 1; + dm->release(dm); + } + return result; } @@ -689,7 +717,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index d42c95a4ce8..7fd2d4c31ca 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -101,7 +101,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, useRenderParams, NULL, isFinalCalc, 0, (ob->flag & OB_MODE_EDIT)); if(useRenderParams || !isFinalCalc) { - DerivedMesh *cddm= CDDM_copy(result); + DerivedMesh *cddm= CDDM_copy(result, 0); result->release(result); result= cddm; } @@ -110,7 +110,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob), - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { SubsurfModifierData *smd = (SubsurfModifierData*) md; diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 258627e8481..830cdb9ebb0 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -99,7 +99,7 @@ static void deformVerts(ModifierData *md, Object *ob, surmd->dm->release(surmd->dm); /* if possible use/create DerivedMesh */ - if(derivedData) surmd->dm = CDDM_copy(derivedData); + if(derivedData) surmd->dm = CDDM_copy(derivedData, 0); else surmd->dm = get_dm(ob, NULL, NULL, NULL, 0); if(!ob->pd) @@ -116,7 +116,7 @@ static void deformVerts(ModifierData *md, Object *ob, MVert *x, *v; CDDM_apply_vert_coords(surmd->dm, vertexCos); - CDDM_calc_normals(surmd->dm); + CDDM_calc_normals_mapping(surmd->dm); numverts = surmd->dm->getNumVerts ( surmd->dm ); @@ -158,7 +158,7 @@ static void deformVerts(ModifierData *md, Object *ob, else surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh"); - if(surmd->dm->getNumFaces(surmd->dm)) + if(surmd->dm->getNumTessFaces(surmd->dm)) bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6); else bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6); diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index aa8f578942c..7fdbea19cfb 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -93,29 +93,31 @@ void get_texture_coords(MappingInfoModifierData *dmd, Object *ob, /* UVs need special handling, since they come from faces */ if(texmapping == MOD_DISP_MAP_UV) { - if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) { - MFace *mface = dm->getFaceArray(dm); - MFace *mf; + if(CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { + MPoly *mpoly = dm->getPolyArray(dm); + MPoly *mp; + MLoop *mloop = dm->getLoopArray(dm); char *done = MEM_callocN(sizeof(*done) * numVerts, "get_texture_coords done"); - int numFaces = dm->getNumFaces(dm); + int numPolys = dm->getNumPolys(dm); char uvname[MAX_CUSTOMDATA_LAYER_NAME]; - MTFace *tf; + MLoopUV *mloop_uv; - CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname); - tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, dmd->uvlayer_name, uvname); + mloop_uv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname); /* verts are given the UV from the first face that uses them */ - for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { - unsigned int fidx= mf->v4 ? 3:2; + for(i = 0, mp = mpoly; i < numPolys; ++i, ++mp) { + unsigned int fidx= mp->totloop - 1; do { - unsigned int vidx = *(&mf->v1 + fidx); + unsigned int lidx= mp->loopstart + fidx; + unsigned int vidx= mloop[lidx].v; if (done[vidx] == 0) { /* remap UVs from [0, 1] to [-1, 1] */ - texco[vidx][0] = (tf->uv[fidx][0] * 2.0f) - 1.0f; - texco[vidx][1] = (tf->uv[fidx][1] * 2.0f) - 1.0f; + texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f; + texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f; done[vidx] = 1; } @@ -157,7 +159,7 @@ void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3]) } /* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */ -DerivedMesh *get_cddm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3]) +DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3]) { if(dm && dm->type == DM_TYPE_CDDM) return dm; @@ -166,29 +168,29 @@ DerivedMesh *get_cddm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (* dm= get_dm(ob, em, dm, vertexCos, 0); } else { - dm= CDDM_copy(dm); + dm= CDDM_copy(dm, 0); CDDM_apply_vert_coords(dm, vertexCos); } if(dm) - CDDM_calc_normals(dm); + CDDM_calc_normals_mapping(dm); return dm; } /* returns a derived mesh if dm == NULL, for deforming modifiers that need it */ -DerivedMesh *get_dm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco) +DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco) { if(dm) return dm; if(ob->type==OB_MESH) { - if(em) dm= CDDM_from_editmesh(em, ob->data); + if(em) dm= CDDM_from_BMEditMesh(em, ob->data, 0); else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob); if(vertexCos) { CDDM_apply_vert_coords(dm, vertexCos); - //CDDM_calc_normals(dm); + //CDDM_calc_normals_mapping(dm); } if(orco) @@ -260,5 +262,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(WeightVGProximity); INIT_TYPE(DynamicPaint); INIT_TYPE(Remesh); + INIT_TYPE(NgonInterp); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index 86909efb96c..f1f6252c255 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -44,8 +44,8 @@ struct TexResult; void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *texres); void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm, float (*co)[3], float (*texco)[3], int numVerts); void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]); -struct DerivedMesh *get_cddm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]); -struct DerivedMesh *get_dm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco); +struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]); +struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco); void modifier_get_vgroup(struct Object *ob, struct DerivedMesh *dm, const char *name, struct MDeformVert **dvert, int *defgrp_index); #endif /* MOD_UTIL_H */ diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 77ce879bbf6..603d379c357 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -47,6 +47,7 @@ #include "BKE_camera.h" +#include "BKE_mesh.h" #include "BKE_DerivedMesh.h" #include "MOD_modifiertypes.h" @@ -147,10 +148,12 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, Object *ob, DerivedMesh *dm) { float (*coords)[3], (*co)[3]; - MTFace *tface; - int i, numVerts, numFaces; + MLoopUV *mloop_uv; + MTexPoly *mtexpoly, *mt; + int i, numVerts, numPolys, numLoops; Image *image = umd->image; - MFace *mface, *mf; + MPoly *mpoly, *mp; + MLoop *mloop; int override_image = ((umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0); Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; int num_projectors = 0; @@ -172,10 +175,10 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, /* make sure there are UV Maps available */ - if(!CustomData_has_layer(&dm->faceData, CD_MTFACE)) return dm; + if(!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) return dm; /* make sure we're using an existing layer */ - CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname); + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname); /* calculate a projection matrix and normal for each projector */ for(i = 0; i < num_projectors; ++i) { @@ -259,11 +262,16 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal); } - numFaces = dm->getNumFaces(dm); + numPolys = dm->getNumPolys(dm); + numLoops = dm->getNumLoops(dm); /* make sure we are not modifying the original UV map */ - tface = CustomData_duplicate_referenced_layer_named(&dm->faceData, - CD_MTFACE, uvname, numFaces); + mloop_uv = CustomData_duplicate_referenced_layer_named(&dm->loopData, + CD_MLOOPUV, uvname, numLoops); + + /* can be NULL */ + mtexpoly = CustomData_duplicate_referenced_layer_named(&dm->polyData, + CD_MTEXPOLY, uvname, numPolys); numVerts = dm->getNumVerts(dm); @@ -280,25 +288,28 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, for(i = 0, co = coords; i < numVerts; ++i, ++co) mul_project_m4_v3(projectors[0].projmat, *co); - mface = dm->getFaceArray(dm); + mpoly = dm->getPolyArray(dm); + mloop = dm->getLoopArray(dm); /* apply coords as UVs, and apply image if tfaces are new */ - for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) { - if(override_image || !image || tface->tpage == image) { + for(i = 0, mp = mpoly; i < numPolys; ++i, ++mp, ++mt) { + if(override_image || !image || (mtexpoly == NULL || mt->tpage == image)) { if(num_projectors == 1) { if(projectors[0].uci) { - unsigned int fidx= mf->v4 ? 3:2; + unsigned int fidx= mp->totloop - 1; do { - unsigned int vidx= *(&mf->v1 + fidx); - project_from_camera(tface->uv[fidx], coords[vidx], projectors[0].uci); + unsigned int lidx= mp->loopstart + fidx; + unsigned int vidx= mloop[lidx].v; + project_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci); } while (fidx--); } else { /* apply transformed coords as UVs */ - unsigned int fidx= mf->v4 ? 3:2; + unsigned int fidx= mp->totloop - 1; do { - unsigned int vidx= *(&mf->v1 + fidx); - copy_v2_v2(tface->uv[fidx], coords[vidx]); + unsigned int lidx= mp->loopstart + fidx; + unsigned int vidx= mloop[lidx].v; + copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]); } while (fidx--); } } else { @@ -311,11 +322,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, float best_dot; /* get the untransformed face normal */ - if(mf->v4) { - normal_quad_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3], coords[mf->v4]); - } else { - normal_tri_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3]); - } + mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no); /* find the projector which the face points at most directly * (projector normal with largest dot product is best) @@ -333,29 +340,31 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, } if(best_projector->uci) { - unsigned int fidx= mf->v4 ? 3:2; + unsigned int fidx= mp->totloop - 1; do { - unsigned int vidx= *(&mf->v1 + fidx); - project_from_camera(tface->uv[fidx], coords[vidx], best_projector->uci); + unsigned int lidx= mp->loopstart + fidx; + unsigned int vidx= mloop[lidx].v; + project_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci); } while (fidx--); } else { - unsigned int fidx= mf->v4 ? 3:2; + unsigned int fidx= mp->totloop - 1; do { - unsigned int vidx= *(&mf->v1 + fidx); + unsigned int lidx= mp->loopstart + fidx; + unsigned int vidx= mloop[lidx].v; float tco[3]; copy_v3_v3(tco, coords[vidx]); mul_project_m4_v3(best_projector->projmat, tco); - copy_v2_v2(tface->uv[fidx], tco); + copy_v2_v2(mloop_uv[lidx].uv, tco); } while (fidx--); } } } - if(override_image) { - tface->tpage = image; + if(override_image && mtexpoly) { + mt->tpage = image; } } @@ -386,7 +395,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 41702a74cc1..5961fae1aba 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -330,7 +330,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, } } -static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, +static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; @@ -338,7 +338,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editDat if(use_dm) { if(!derivedData) - dm = CDDM_from_editmesh(editData, ob->data); + dm = CDDM_from_BMEditMesh(editData, ob->data, 0); } deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index f4377e82408..15f78e15073 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -345,7 +345,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm= derivedData; diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index bdd7ab7486b..473692f123d 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -243,7 +243,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 17316d891da..316080ba4a7 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -375,7 +375,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 8e0949f2a22..732a46cb8b6 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -450,8 +450,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der target_dm = CDDM_from_curve(obr); else if (obr->type == OB_MESH) { Mesh *me = (Mesh*)obr->data; - if (me->edit_mesh) - target_dm = CDDM_from_editmesh((EditMesh*)me->edit_mesh, me); + if (me->edit_btmesh) + target_dm = CDDM_from_BMEditMesh(me->edit_btmesh, me, 0); else target_dm = CDDM_from_mesh(me, obr); } @@ -518,7 +518,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), + struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData) { return applyModifier(md, ob, derivedData, 0, 1); |