diff options
Diffstat (limited to 'source/blender/modifiers/intern')
39 files changed, 1240 insertions, 2196 deletions
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 95e16f3bea4..b089fead356 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 f56eda674c5..5b94885f4af 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -28,17 +28,12 @@ * */ -/** \file blender/modifiers/intern/MOD_array.c - * \ingroup modifiers - */ - - /* Array modifier: duplicates the object multiple times along an axis */ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_math.h" #include "BLI_ghash.h" #include "BLI_edgehash.h" @@ -51,10 +46,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) { @@ -107,8 +105,8 @@ static void foreachObjectLink( walk(userData, ob, &amd->offset_ob); } -static void updateDepgraph(ModifierData *md, DagForest *forest, - struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode) +static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), + Object *UNUSED(ob), DagNode *obNode) { ArrayModifierData *amd = (ArrayModifierData*) md; @@ -157,28 +155,116 @@ 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) +/* finds the best possible flipped name. For renaming; check for unique names afterwards */ +/* if strip_number: removes number extensions */ +void vertgroup_flip_name (char *name, int strip_number) { - if(mface->v1 >= maxvert) { - // printf("bad index in array\n"); - mface->v1= maxvert - 1; + int len; + char prefix[128]={""}; /* The part before the facing */ + char suffix[128]={""}; /* The part after the facing */ + char replace[128]={""}; /* The replacement string */ + char number[128]={""}; /* The number extension string */ + char *index=NULL; + + len= strlen(name); + if(len<3) return; // we don't do names like .R or .L + + /* We first check the case with a .### extension, let's find the last period */ + if(isdigit(name[len-1])) { + index= strrchr(name, '.'); // last occurrance + if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! + if(strip_number==0) + strcpy(number, index); + *index= 0; + len= strlen(name); + } } - if(mface->v2 >= maxvert) { - // printf("bad index in array\n"); - mface->v2= maxvert - 1; + + strcpy (prefix, name); + +#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') + + /* first case; separator . - _ with extensions r R l L */ + if( IS_SEPARATOR(name[len-2]) ) { + switch(name[len-1]) { + case 'l': + prefix[len-1]= 0; + strcpy(replace, "r"); + break; + case 'r': + prefix[len-1]= 0; + strcpy(replace, "l"); + break; + case 'L': + prefix[len-1]= 0; + strcpy(replace, "R"); + break; + case 'R': + prefix[len-1]= 0; + strcpy(replace, "L"); + break; + } } - if(mface->v3 >= maxvert) { - // printf("bad index in array\n"); - mface->v3= maxvert - 1; + /* case; beginning with r R l L , with separator after it */ + else if( IS_SEPARATOR(name[1]) ) { + switch(name[0]) { + case 'l': + strcpy(replace, "r"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'r': + strcpy(replace, "l"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'L': + strcpy(replace, "R"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'R': + strcpy(replace, "L"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + } } - if(mface->v4 >= maxvert) { - // printf("bad index in array\n"); - mface->v4= maxvert - 1; + else if(len > 5) { + /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ + index = BLI_strcasestr(prefix, "right"); + if (index==prefix || index==prefix+len-5) { + if(index[0]=='r') + strcpy (replace, "left"); + else { + if(index[1]=='I') + strcpy (replace, "LEFT"); + else + strcpy (replace, "Left"); + } + *index= 0; + strcpy (suffix, index+5); + } + else { + index = BLI_strcasestr(prefix, "left"); + if (index==prefix || index==prefix+len-4) { + if(index[0]=='l') + strcpy (replace, "right"); + else { + if(index[1]=='E') + strcpy (replace, "RIGHT"); + else + strcpy (replace, "Right"); + } + *index= 0; + strcpy (suffix, index+4); + } + } } - - return test_index_face(mface, fdata, mfindex, nr); + +#undef IS_SEPARATOR + + sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); } typedef struct IndexMapEntry { @@ -220,45 +306,34 @@ static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum) } 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, @@ -276,7 +351,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, mul_serie_m4(result_mat, offset, obinv, amd->offset_ob->obmat, - NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); copy_m4_m4(offset, result_mat); } @@ -285,10 +360,10 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if(cu) { float tmp_mat[3][3]; float scale; - + object_to_mat3(amd->curve_ob, tmp_mat); scale = mat3_to_scale(tmp_mat); - + if(!cu->path) { cu->flag |= CU_PATH; // needed for path & bevlist makeDispListCurveTypes(scene, amd->curve_ob, 0); @@ -301,8 +376,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, /* calculate the maximum number of copies which will fit within the prescribed length */ if(amd->fit_type == MOD_ARR_FITLENGTH - || amd->fit_type == MOD_ARR_FITCURVE) { - float dist = sqrt(dot_v3v3(offset[3], offset[3])); + || amd->fit_type == MOD_ARR_FITCURVE) + { + float dist = sqrt(INPR(offset[3], offset[3])); if(dist > 1e-6f) /* this gives length = first copy start to last copy end @@ -316,484 +392,118 @@ 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); + BMO_Init_Op(&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; - for(j=0; j < count - 1; j++) { - mul_m4_m4m4(tmp_mat, final_offset, offset); - copy_m4_m4(final_offset, tmp_mat); - } + BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout"); + BMO_Exec_Op(em->bm, &op); - numVerts = numEdges = numFaces = 0; - mvert = CDDM_get_verts(result); + s1 = BMO_GetSlot(&op, "geom"); + s2 = BMO_GetSlot(&op, "newout"); - for (i = 0; i < maxVerts; i++) { - indexMap[i].merge = -1; /* default to no merge */ - indexMap[i].merge_final = 0; /* default to no merge */ - } + BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout"); - for (i = 0; i < maxVerts; i++) { - MVert *inMV; - MVert *mv = &mvert[numVerts]; - MVert *mv2; - float co[3]; + #define _E(s, i) ((BMVert**)(s)->data.buf)[i] - inMV = &src_mvert[i]; + /*calculate merge mapping*/ + if (j == 0) { + BMOperator findop; + BMOIter oiter; + BMVert *v, *v2; + BMHeader *h; - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv = *inMV; - numVerts++; + BMO_InitOpf(em->bm, &findop, + "finddoubles verts=%av dist=%f keepverts=%s", + amd->merge_dist, &op, "geom"); - 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; - } + i = 0; + BMO_ITER(h, &oiter, em->bm, &op, "geom", BM_ALL) { + BM_SetIndex(h, i); + 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); + 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; + BMO_Exec_Op(em->bm, &findop); - 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; - } - - 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); - } + indexLen = i; + indexMap = MEM_callocN(sizeof(int)*indexLen, "indexMap"); - for(j = 1; j < count; j++) - { - vert1 = calc_mapping(indexMap, inMED.v1, j); - vert2 = calc_mapping(indexMap, inMED.v2, j); + /*element type argument doesn't do anything here*/ + BMO_ITER(v, &oiter, em->bm, &findop, "targetmapout", 0) { + v2 = BMO_IterMapValp(&oiter); - /* edge could collapse to single point after mapping */ - if(vert1 == vert2) continue; - - /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ - if(vert1 >= numVerts) - vert1= numVerts-1; - if(vert2 >= numVerts) - vert2= numVerts-1; - - /* avoid duplicate edges */ - if(!BLI_edgehash_haskey(edges, vert1, vert2)) { - med2 = &medge[numEdges]; - - 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; + /*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) - 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); + for (i=0; i<indexLen; i++) { + if (!indexMap[i]) continue; - numFaces++; + v = E(i); + v2 = E(indexMap[i]-1); - /* 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; - - numVerts++; - } + BMO_Insert_MapPointer(em->bm, &weldop, "targetmap", v, v2); } - 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]; - 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; + #undef E + #undef _E - numEdges++; - } - } - 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; - - 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); - - mul_m4_m4m4(endoffset, final_offset, 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; - - vert_map[i] = numVerts; - - 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]; + if (j > 0) BMO_Finish_Op(em->bm, &op); - 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; - - 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; + if (amd->flags & MOD_ARR_MERGE) + BMO_Exec_Op(em->bm, &weldop); - numFaces++; - } + BMO_Finish_Op(em->bm, &weldop); - MEM_freeN(vert_map); - end_cap->release(end_cap); - } + BMEdit_RecalcTesselation(em); + cddm = CDDM_from_BMEditMesh(em, NULL, 0); - 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, - DerivedMesh *dm, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) +static DerivedMesh *applyModifier( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { DerivedMesh *result; ArrayModifierData *amd = (ArrayModifierData*) md; - result = arrayModifier_doArray(amd, md->scene, ob, dm, 0); + result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0); - if(result != dm) - CDDM_calc_normals(result); + //if(result != derivedData) + // CDDM_calc_normals(result); return result; } -static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), - DerivedMesh *dm) +static DerivedMesh *applyModifierEM( + ModifierData *md, Object *ob, struct BMEditMesh *UNUSED(editData), + DerivedMesh *derivedData) { - return applyModifier(md, ob, dm, 0, 1); + return applyModifier(md, ob, derivedData, 0, 1); } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index c746b10755e..1ae79825d48 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -90,6 +90,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { +#if 1 /*BMESH_TODO*/ + (void)md; + return CDDM_copy(derivedData, 0); +#else DerivedMesh *result; BME_Mesh *bm; @@ -112,12 +116,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), BME_free_mesh(bm); CDDM_calc_normals(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 1828781690b..3b13f1b21c0 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -97,12 +97,12 @@ static DerivedMesh *get_quick_derivedMesh(DerivedMesh *derivedData, DerivedMesh if(derivedData->getNumFaces(derivedData) == 0 || dm->getNumFaces(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); + else result = CDDM_copy(dm, FALSE); break; diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 843501133c5..d83fa0f6c2d 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; @@ -346,14 +346,14 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( DerivedMesh *dm2, Object *ob2) { - DerivedMesh *result, *orig_dm; + DerivedMesh *result, *orig_dm, *dm; GHash *material_hash = NULL; Mesh *me1= (Mesh*)ob1->data; Mesh *me2= (Mesh*)ob2->data; 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]; @@ -433,9 +433,13 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( BLI_ghash_free(material_hash, NULL, NULL); CDDM_calc_edges(result); - CDDM_calc_normals(result); - return result; + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + CDDM_calc_normals(dm); + result->needsFree = 1; + result->release(result); + + return dm; } static void BuildMeshDescriptors( @@ -468,7 +472,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 +504,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 +558,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 +575,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 10c2f6019ed..87989b541f5 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 *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 *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); - + + 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"); @@ -119,6 +128,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* 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); @@ -126,37 +139,40 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *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); @@ -164,26 +180,27 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *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; @@ -203,7 +220,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *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); @@ -239,38 +256,48 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *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; - - 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))); + MPoly *source; + MPoly *dest; + source = mpolys + faceMap[i]; + dest = mpolyd + i; DM_copy_face_data(dm, result, faceMap[i], i, 1); - *dest = source; - test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3)); + *dest = *source; + dest->loopstart = k; + + 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); 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 c91cabd4a37..10b0aebbe39 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -590,7 +590,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_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 0cd3481c899..99d608351d8 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) @@ -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 bdf67c25e74..da676325cd9 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 aba68dc9edc..f533e205fe6 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -82,9 +82,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), int a, numTris; 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 +96,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 +141,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 +156,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]; @@ -167,7 +168,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } CDDM_calc_edges(result); - CDDM_calc_normals(result); } else modifier_setError(md, "Out of memory."); @@ -181,8 +181,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), MEM_freeN(lod.vertex_normal_buffer); MEM_freeN(lod.triangle_index_buffer); -exit: - return result; + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + CDDM_calc_normals(dm); + result->needsFree = 1; + result->release(result); + + 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 a7a25fbb00e..5bb8f0aefbf 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -188,7 +188,8 @@ static void displaceModifier_do( tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, "displaceModifier_do tex_co"); get_texture_coords((MappingInfoModifierData *)dmd, ob, dm, vertexCos, tex_co, numVerts); - + + for(i = 0; i < numVerts; ++i) { TexResult texres; float delta = 0, strength = dmd->strength; @@ -251,7 +252,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 939ce123613..4b78592ffa6 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -36,32 +36,93 @@ /* 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_utildefines.h" #include "BLI_listbase.h" #include "BLI_memarena.h" #include "BLI_edgehash.h" #include "BLI_math.h" -#include "BLI_utildefines.h" +#include "BLI_array.h" +#include "BLI_smallhash.h" #include "BLI_linklist.h" - #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" #include "BKE_particle.h" +#include "BKE_tessmesh.h" +#include "BKE_mesh.h" #include "MEM_guardedalloc.h" -#include "MOD_util.h" +/* EdgeSplit */ +/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag + * or edge angle (can be used to achieve autosmoothing) +*/ + +#define EDGE_MARK 1 + +static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *ob) +{ + BMesh *bm; + BMEditMesh *em; + DerivedMesh *cddm; + BMIter iter, liter; + BMFace *f; + BMLoop *l; + 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; -#if 0 -#define EDGESPLIT_DEBUG_3 -#define EDGESPLIT_DEBUG_2 -#define EDGESPLIT_DEBUG_1 -#define EDGESPLIT_DEBUG_0 -#endif + BM_Compute_Normals(bm); + BMO_push(bm, NULL); + + if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { + BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { + float edge_angle_cos; + + if (l->radial_next == l) + continue; + + edge_angle_cos = INPR(f->no, l->radial_next->f->no); + if (edge_angle_cos < threshold) { + BMO_SetFlag(bm, l->e, EDGE_MARK); + } + } + } + } + + 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); + } + } + + 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 void initData(ModifierData *md) { @@ -82,1192 +143,23 @@ static void copyData(ModifierData *md, ModifierData *target) 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; - - 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); -} - -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) - */ -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; - - 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) -{ - 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); - - /* 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); - } - } - } 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); - - /* 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)++; - } - } - } - - /* 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); - } - } -} - -static int count_bridge_verts(SmoothMesh *mesh) +static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, + Object *ob, DerivedMesh *dm) { - 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++; - } - } - } - - /* each bridge vert will be counted once per face that uses it, - * so count is too high, but it's ok for now - */ - return count; -} - -static void split_bridge_verts(SmoothMesh *mesh) -{ - 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]; - - /* 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); - } - } -} - -static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, 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); @@ -1276,8 +168,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), - DerivedMesh *derivedData) + 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 8dcb6f4b4d9..8c04d7c694e 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -36,11 +36,11 @@ #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" +#include "BLI_utildefines.h" #include "BLI_kdtree.h" #include "BLI_rand.h" #include "BLI_math.h" #include "BLI_edgehash.h" -#include "BLI_utildefines.h" #include "BKE_cdderivedmesh.h" #include "BKE_deform.h" @@ -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"); @@ -628,7 +628,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??) */ @@ -670,7 +670,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: @@ -760,7 +760,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)); } @@ -768,8 +768,11 @@ static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) MEM_freeN(facesplit); MEM_freeN(vertpa); - return splitdm; + dm = CDDM_copy(splitdm, 1); /*builds ngon faces from tess (mface) faces*/ + splitdm->needsFree = 1; + splitdm->release(splitdm); + return dm; } static DerivedMesh * explodeMesh(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Scene *scene, Object *ob, @@ -792,9 +795,9 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, int i, j, v, 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; @@ -839,7 +842,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);*/ @@ -907,8 +910,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; @@ -923,7 +926,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; @@ -947,6 +950,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, /* finalization */ CDDM_calc_edges(explode); + CDDM_tessfaces_to_faces(explode); CDDM_calc_normals(explode); if(psmd->psys->lattice){ @@ -988,7 +992,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 0e9b71c3e6d..5d8471e75dc 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -224,7 +224,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) { @@ -280,7 +280,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]; @@ -505,12 +505,12 @@ static DerivedMesh *fluidsim_read_cache(DerivedMesh *orgdm, FluidsimModifierData } // assign material + flags to new dm - mface = orgdm->getFaceArray(orgdm); + mface = orgdm->getTessFaceArray(orgdm); 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; diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index ad1a636589f..1e356d4557a 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -252,12 +252,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_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 9ef5e501aca..8cfde5e3a4c 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 4145dafce7b..046eb0e5d03 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -117,7 +117,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); + maxFaces= dm->getNumTessFaces(dm); /* check if we can just return the original mesh * - must have verts and therefore verts assigned to vgroups to do anything useful @@ -282,7 +282,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < maxFaces; i++) { MFace mf; - dm->getFace(dm, i, &mf); + dm->getTessFace(dm, i, &mf); /* all verts must be available */ if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) && @@ -299,7 +299,7 @@ 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, numFaces, 0, 0); /* using ghash-iterators, map data into new mesh */ @@ -353,8 +353,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); int orig_v4; - dm->getFace(dm, oldIndex, &source); - dest = CDDM_get_face(result, newIndex); + dm->getTessFace(dm, oldIndex, &source); + dest = CDDM_get_tessface(result, newIndex); orig_v4 = source.v4; @@ -364,13 +364,16 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, 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); + DM_copy_tessface_data(dm, result, oldIndex, newIndex, 1); *dest = source; test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3)); } BLI_ghashIterator_free(hashIter); + /* build polys from tess faces, for now */ + CDDM_tessfaces_to_faces(result); + /* recalculate normals */ CDDM_calc_normals(result); @@ -380,6 +383,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, BLI_ghash_free(faceHash, 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 c211efd64b8..966591a3e56 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; MDeformWeight *dw; @@ -201,10 +202,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; @@ -361,7 +361,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 f551f0f5e7a..2825053050e 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -28,27 +28,26 @@ * */ -/** \file blender/modifiers/intern/MOD_mirror.c - * \ingroup modifiers - */ - - #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "MEM_guardedalloc.h" + #include "BLI_math.h" -#include "BLI_utildefines.h" +#include "BLI_smallhash.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" +/*from MOD_array.c*/ +void vertgroup_flip_name (char *name, int strip_number); static void initData(ModifierData *md) { @@ -76,14 +75,13 @@ static void foreachObjectLink( void *userData) { MirrorModifierData *mmd = (MirrorModifierData*) md; - - walk(userData, ob, &mmd->mirror_ob); + + if (mmd->mirror_ob) + walk(userData, ob, &mmd->mirror_ob); } -static void updateDepgraph(ModifierData *md, DagForest *forest, - struct Scene *UNUSED(scene), - Object *UNUSED(ob), - DagNode *obNode) +static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), + Object *UNUSED(ob), DagNode *obNode) { MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -95,195 +93,193 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } -static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, + +/* Mirror */ +#define VERT_NEW 1 + +DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, Object *ob, DerivedMesh *dm, - int initFlags, + int UNUSED(initFlags), int axis) { - int i; - float tolerance = mmd->tolerance; - 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; - int do_vgroup_mirr= (mmd->flag & MOD_MIR_VGROUP); - int (*indexMap)[2]; - float mtx[4][4], imtx[4][4]; - - numVerts = numEdges = numFaces = 0; - - indexMap = MEM_mallocN(sizeof(*indexMap) * maxVerts, "indexmap"); - - result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2); - - - if (do_vgroup_mirr) { - flip_map= defgroup_flip_map(ob, 0); - if(flip_map == NULL) - do_vgroup_mirr= 0; + float tolerance_sq; + DerivedMesh *cddm, *origdm; + bDeformGroup *def, *defb; + bDeformGroup **vector_def = NULL; + MVert *mv, *ov; + MEdge *me; + MLoop *ml; + MPoly *mp; + float mtx[4][4]; + int i, j, *vtargetmap = NULL; + BLI_array_declare(vtargetmap); + int vector_size=0, a, b, totshape; + + tolerance_sq = mmd->tolerance * mmd->tolerance; + + origdm = dm; + if (!CDDM_Check(dm)) + dm = CDDM_copy(dm, 0); + + if (mmd->flag & MOD_MIR_VGROUP) { + /* calculate the number of deformedGroups */ + for(vector_size = 0, def = ob->defbase.first; def; + def = def->next, vector_size++); + + /* load the deformedGroups for fast access */ + vector_def = + (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size, + "group_index"); + for(a = 0, def = ob->defbase.first; def; def = def->next, a++) { + vector_def[a] = def; + } } + /*mtx is the mirror transformation*/ + unit_m4(mtx); + mtx[axis][axis] = -1.0; + if (mmd->mirror_ob) { - float obinv[4][4]; - - invert_m4_m4(obinv, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, ob->obmat, obinv); - invert_m4_m4(imtx, mtx); + 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); + mul_m4_m4m4(tmp, ob->obmat, tmp); + + /*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*/ + mul_m4_m4m4(mtx, tmp, mtx); + mul_m4_m4m4(mtx, mtx, itmp); } - - 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); + + cddm = CDDM_from_template(dm, dm->numVertData*2, dm->numEdgeData*2, 0, dm->numLoopData*2, dm->numPolyData*2); + + /*copy customdata to original geometry*/ + CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData); + CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData); + CustomData_copy_data(&dm->loopData, &cddm->loopData, 0, 0, dm->numLoopData); + CustomData_copy_data(&dm->polyData, &cddm->polyData, 0, 0, dm->numPolyData); + + /*copy customdata to new geometry*/ + CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, dm->numVertData, dm->numVertData); + CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, dm->numEdgeData, dm->numEdgeData); + CustomData_copy_data(&dm->polyData, &cddm->polyData, 0, dm->numPolyData, dm->numPolyData); + + /*mirror vertex coordinates*/ + ov = CDDM_get_verts(cddm); + mv = ov + dm->numVertData; + for (i=0; i<dm->numVertData; i++, mv++, ov++) { + mul_m4_v3(mtx, mv->co); + /*compare location of the original and mirrored vertex, to see if they + should be mapped for merging*/ + if (len_squared_v3v3(ov->co, mv->co) < tolerance_sq) { + BLI_array_append(vtargetmap, i+dm->numVertData); } - - 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; - numVerts++; - - indexMap[i][0] = numVerts - 1; - indexMap[i][1] = !isShared; - // - if(isShared ) { - co[axis] = 0; - 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); - } - 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); - } - } - - numVerts++; + else { + BLI_array_append(vtargetmap, -1); } } - - 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(initFlags) - med->flag |= ME_EDGEDRAW | ME_EDGERENDER; - - 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(&cddm->vertData, CD_SHAPEKEY); + for (a=0; a<totshape; a++) { + float (*cos)[3] = CustomData_get_layer_n(&cddm->vertData, CD_SHAPEKEY, a); + for (i=dm->numVertData; i<cddm->numVertData; i++) { + mul_m4_v3(mtx, cos[i]); } } - - for(i = 0; i < maxFaces; i++) { - MFace inMF; - MFace *mf = CDDM_get_face(result, numFaces); + + for (i=0; i<dm->numVertData; i++) { + BLI_array_append(vtargetmap, -1); + } + + /*adjust mirrored edge vertex indices*/ + me = CDDM_get_edges(cddm) + dm->numEdgeData; + for (i=0; i<dm->numEdgeData; i++, me++) { + me->v1 += dm->numVertData; + me->v2 += dm->numVertData; + } + + /*adjust mirrored poly loopstart indices, and reverse loop order (normals)*/ + mp = CDDM_get_polys(cddm) + dm->numPolyData; + ml = CDDM_get_loops(cddm); + for (i=0; i<dm->numPolyData; i++, mp++) { + MLoop *ml2; + int e; - dm->getFace(dm, i, &inMF); + for (j=0; j<mp->totloop; j++) { + CustomData_copy_data(&dm->loopData, &cddm->loopData, mp->loopstart+j, + mp->loopstart+dm->numLoopData+mp->totloop-j-1, 1); + } - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf = inMF; - numFaces++; + ml2 = ml + mp->loopstart + dm->numLoopData; + 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; - mf->v1 = indexMap[inMF.v1][0]; - mf->v2 = indexMap[inMF.v2][0]; - mf->v3 = indexMap[inMF.v3][0]; - mf->v4 = indexMap[inMF.v4][0]; + mp->loopstart += dm->numLoopData; + } + + /*adjust mirrored loop vertex and edge indices*/ + ml = CDDM_get_loops(cddm) + dm->numLoopData; + for (i=0; i<dm->numLoopData; i++, ml++) { + ml->v += dm->numVertData; + ml->e += dm->numEdgeData; + } + + CDDM_recalc_tesselation(cddm, 1); + + /*handle vgroup stuff*/ + if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&cddm->vertData, CD_MDEFORMVERT)) { + MDeformVert *dvert = CustomData_get_layer(&cddm->vertData, CD_MDEFORMVERT); - 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]; + for (i=0; i<dm->numVertData; i++, dvert++) { + for(j = 0; j < dvert->totweight; ++j) { + char tmpname[32]; + + if(dvert->dw[j].def_nr < 0 || + dvert->dw[j].def_nr >= vector_size) + continue; + + def = vector_def[dvert->dw[j].def_nr]; + strcpy(tmpname, def->name); + vertgroup_flip_name(tmpname,0); + + for(b = 0, defb = ob->defbase.first; defb; + defb = defb->next, b++) + { + if(!strcmp(defb->name, tmpname)) + { + dvert->dw[j].def_nr = b; + break; } } } - - /* Flip face normal */ - SWAP(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); - - MEM_freeN(indexMap); - - CDDM_lower_num_verts(result, numVerts); - CDDM_lower_num_edges(result, numEdges); - CDDM_lower_num_faces(result, numFaces); - - return result; + + if (!(mmd->flag & MOD_MIR_NO_MERGE)) + cddm = CDDM_merge_verts(cddm, vtargetmap); + + BLI_array_free(vtargetmap); + + if (vector_def) MEM_freeN(vector_def); + + if (dm != origdm) { + dm->needsFree = 1; + dm->release(dm); + } + + return cddm; } static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, @@ -310,10 +306,9 @@ static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, return result; } -static DerivedMesh *applyModifier(ModifierData *md, Object *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; MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -326,9 +321,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, return result; } -static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), - DerivedMesh *derivedData) +static DerivedMesh *applyModifierEM( + ModifierData *md, Object *ob, 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 8bcaf8802b5..51c4a1eae01 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..9043834de82 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_ngoninterp.c @@ -0,0 +1,330 @@ +/* +* $Id: MOD_mask.c 35213 2011-02-27 06:19:40Z joeedh $ +* +* ***** 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 "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_array.h" +#include "BLI_smallhash.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; + + if (nmd->resolution <= 0) + return dm; + + if (!CDDM_Check(dm)) { + dm = copy = CDDM_copy(dm, 0); + } + + CDDM_recalc_tesselation(dm, 1); + + 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); + + /*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->numFaceData; 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[3] = {0, 1, 2}; + + 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_tri_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i]); + } + + 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*/ + dummy = cddm; + cddm = CDDM_copy(cddm, 1); + dummy->needsFree = 1; + dummy->release(dummy); + + if (copy) { + copy->needsFree = 1; + copy->release(dm); + copy = copy; + } + + 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_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index f93e0469686..eae7dcef26d 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -174,7 +174,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 +190,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 +260,8 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, VECADD(mv->co,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; @@ -312,10 +312,14 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, if(size) MEM_freeN(size); - return result; + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + result->needsFree = 1; + result->release(result); + + return dm; } 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..4021a8a8114 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -164,7 +164,7 @@ 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); @@ -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_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 5dc233c78b1..3ab80aecfca 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -174,7 +174,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: @@ -292,17 +292,17 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, maxFaces = totedge * (step_tot-1); } - result= CDDM_from_template(dm, maxVerts, maxEdges, maxFaces); + result= CDDM_from_template(dm, maxVerts, maxEdges, maxFaces, 0, 0); /* copy verts from mesh */ mvert_orig = dm->getVertArray(dm); medge_orig = dm->getEdgeArray(dm); mvert_new = result->getVertArray(result); - mface_new = result->getFaceArray(result); + mface_new = result->getTessFaceArray(result); medge_new = result->getEdgeArray(result); - origindex= result->getFaceDataArray(result, CD_ORIGINDEX); + origindex= result->getTessFaceDataArray(result, CD_ORIGINDEX); DM_copy_vert_data(dm, result, 0, 0, totvert); /* copy first otherwise this overwrites our own vertex normals */ @@ -823,7 +823,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, med_new->crease= med_new_firstloop->crease; med_new++; } - + + /* BMesh implimentation info - need to calculate polys before recalculating + * normals, since normal calc overwrites MFaces from Polys */ + CDDM_tessfaces_to_faces(result); + if((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { CDDM_calc_normals(result); } @@ -862,7 +866,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 6c047a81fa5..66213f38d8d 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 4609ee221a4..6b691ad63aa 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 edd16c045f6..102d325c7fa 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -232,7 +232,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 8d47ad28a86..c9acaf9ff81 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -35,9 +35,11 @@ #include "DNA_meshdata_types.h" +#include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_edgehash.h" -#include "BLI_utildefines.h" +#include "BLI_array.h" +#include "BLI_smallhash.h" #include "BLI_string.h" #include "BKE_cdderivedmesh.h" @@ -59,7 +61,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]; @@ -69,9 +72,10 @@ 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); + 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 +84,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(); @@ -110,27 +114,19 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) edge_ref->f2=i; \ } - 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++) { + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(ml[j].v, ml[(j+1)%mp->totloop].v); } } - + for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) { /* Get the edge vert indices, and edge value (the face indices that use it)*/ BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2); @@ -203,32 +199,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); - + 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); @@ -242,10 +241,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(); @@ -278,28 +286,20 @@ 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++) { + MLoop *ml2 = orig_mloop + mp->loopstart + (j+1)%mp->totloop; + ADD_EDGE_USER(ml->v, ml2->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)); @@ -307,18 +307,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; @@ -333,14 +332,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); + result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, 0, (numLoops*2) + newLoops, (numFaces * 2) + newFaces); - mface = result->getFaceArray(result); - medge = result->getEdgeArray(result); - mvert = result->getVertArray(result); - - 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); @@ -348,30 +345,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}; - 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(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_face_data(dm, result, 0, 0, numFaces); + DM_copy_face_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++) { @@ -425,12 +433,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); 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; } @@ -440,32 +449,31 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, normal_short_to_float_v3(vert_nors[i], mv->no); } } - - 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; - } - else { - angle_tri_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); - j= 2; + BLI_array_empty(face_angles); + for (j=0, ml=mloop+mp->loopstart; j<mp->totloop; j++, ml++) { + MLoop *ml2 = mloop + mp->loopstart + (j+1)%mp->totloop; //next + MLoop *ml3 = mloop + mp->loopstart + (j+mp->totloop-1)%mp->totloop; //previous + float e1[3], e2[3], angle; + + sub_v3_v3v3(e1, mvert[ml2->v].co, mvert[ml->v].co); + sub_v3_v3v3(e2, mvert[ml3->v].co, mvert[ml->v].co); + angle = M_PI - angle_normalized_v3v3(e1, e2); + BLI_array_append(face_angles, angle); } - - 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) { @@ -543,12 +551,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[4][4] = { - {1, 0, 0, 1}, - {2, 1, 1, 2}, - {3, 2, 2, 3}, - {0, 3, 3, 0}}; - /* add faces & edges */ origindex= result->getEdgeDataArray(result, CD_ORIGINDEX); ed= medge + (numEdges * 2); @@ -564,12 +566,17 @@ 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 = CustomData_get_layer(&result->edgeData, CD_ORIGINDEX); + + mp= mpoly + (numFaces * 2); + origindex= result->getTessFaceDataArray(result, CD_ORIGINDEX); + 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 flip, k1, k2; + MLoop *ml2; if(fidx >= numFaces) { fidx -= numFaces; @@ -583,32 +590,77 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* copy most of the face settings */ DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1); - + mp->loopstart = j+numLoops*2; + mp->flag = mpoly[fidx].flag; + mp->totloop = 4; + + ml2 = mloop + mpoly[fidx].loopstart; + for (k1=0; k1<mpoly[fidx].totloop; k1++, ml2++) { + if (ml2->e == eidx) + break; + } + + if (k1 == mpoly[fidx].totloop) { + fprintf(stderr, "%s: solidify bad k1==totloop (bmesh internal error)\n", __func__); + } + + if (ed->v2 == mloop[mpoly[fidx].loopstart+k1].v) { + k2 = (k1 + mp->totloop - 1)%mp->totloop; + SWAP(int, k1, k2); + } else if (ed->v1 == mloop[mpoly[fidx].loopstart+k1].v) { + k2 = (k1+1)%mp->totloop; + } else { + fprintf(stderr, "%s: solidify bad edge/vert\n", __func__); + k2 = k1; + } + + k1 += mpoly[fidx].loopstart; + k2 += mpoly[fidx].loopstart; + if(flip) { - DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); - - mf->v1= ed->v1; - mf->v2= ed->v2; - mf->v3= ed->v2 + numVerts; - mf->v4= ed->v1 + numVerts; + CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops*2+j, 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); + + 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[edge_order[eidx]]); - - mf->v1= ed->v2; - mf->v2= ed->v1; - mf->v3= ed->v1 + numVerts; - mf->v4= ed->v2 + numVerts; + CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops*2+j, 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); + + 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]; + + ml[j].v = ed->v2; + ml[j++].e = eidx; + + ml[j].v = ed->v1; + ml[j++].e = numEdges*2 + old_vert_arr[ed->v1]; } - /* 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 */ - unsigned char *cr= (unsigned char *)&(ed->crease); + unsigned char *cr= (unsigned char *)&(medge[eidx].crease); int tcr= *cr + crease_outer; *cr= tcr > 255 ? 255 : tcr; } @@ -621,7 +673,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); @@ -651,17 +703,27 @@ 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); + } else { + CDDM_recalc_tesselation(result, 1); } - + + if (dm != odm) { + dm->needsFree = 1; + dm->release(dm); + } + return result; } @@ -669,7 +731,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..161bdcaf4ac 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) @@ -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 b7883eea4d8..8d83bbecaac 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -97,11 +97,11 @@ 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 *mface = dm->getTessFaceArray(dm); MFace *mf; char *done = MEM_callocN(sizeof(*done) * numVerts, "get_texture_coords done"); - int numFaces = dm->getNumFaces(dm); + int numFaces = dm->getNumTessFaces(dm); char uvname[32]; MTFace *tf; @@ -196,7 +196,7 @@ void validate_layer_name(const CustomData *data, int type, char *name, char *out } /* 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; @@ -205,7 +205,7 @@ 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); } @@ -216,13 +216,13 @@ DerivedMesh *get_cddm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (* } /* 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) { @@ -296,5 +296,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(WeightVGEdit); INIT_TYPE(WeightVGMix); INIT_TYPE(WeightVGProximity); + 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 4de767358e4..82e04468c86 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -48,8 +48,8 @@ void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *tex 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]); void validate_layer_name(const struct CustomData *data, int type, char *name, char *outname); -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 36d773ad605..2ddbae28cb6 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -273,8 +273,8 @@ 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); - numFaces = dm->getNumFaces(dm); + mface = dm->getTessFaceArray(dm); + numFaces = dm->getNumTessFaces(dm); /* apply coords as UVs, and apply image if tfaces are new */ for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) { @@ -398,7 +398,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 8422916e450..d86e746abbc 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 6aac7077447..5d020cc8a03 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -188,11 +188,11 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob, /* UVs need special handling, since they come from faces */ if(texmapping == MOD_WAV_MAP_UV) { if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) { - MFace *mface = dm->getFaceArray(dm); + MFace *mface = dm->getTessFaceArray(dm); MFace *mf; char *done = MEM_callocN(sizeof(*done) * numVerts, "get_texture_coords done"); - int numFaces = dm->getNumFaces(dm); + int numFaces = dm->getNumTessFaces(dm); char uvname[32]; MTFace *tf; @@ -430,7 +430,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 24d80fe847c..a4c0f0ffa70 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -241,7 +241,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der else ret = dm; #else - ret = CDDM_copy(dm); + ret = CDDM_copy(dm, 0); rel_ret = 1; dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); if (dvert == NULL) { @@ -289,7 +289,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 221deeef1a6..43f503a7624 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -288,7 +288,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der else ret = dm; #else - ret = CDDM_copy(dm); + ret = CDDM_copy(dm, 0); rel_ret = 1; dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); if (dvert == NULL) { @@ -423,7 +423,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 8effe4d7c1b..ad16cbe97a0 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -405,7 +405,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der else ret = dm; #else - ret = CDDM_copy(dm); + ret = CDDM_copy(dm, 0); rel_ret = 1; dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); if (dvert == NULL) { @@ -471,8 +471,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); } @@ -532,7 +532,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); |