diff options
Diffstat (limited to 'source/blender/modifiers')
31 files changed, 1352 insertions, 1903 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index c610a2fbdda..4a02306b443 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -31,6 +31,7 @@ set(INC ../makesdna ../blenkernel ../blenkernel/intern + ../bmesh ../render/extern/include ../../../intern/guardedalloc ../../../intern/elbeem/extern @@ -59,6 +60,7 @@ set(SRC intern/MOD_meshdeform.c intern/MOD_mirror.c intern/MOD_multires.c + intern/MOD_ngoninterp.c intern/MOD_none.c intern/MOD_particleinstance.c intern/MOD_particlesystem.c diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 8486e2b5d29..44d06e3ef47 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -71,6 +71,7 @@ extern ModifierTypeInfo modifierType_Smoke; extern ModifierTypeInfo modifierType_ShapeKey; extern ModifierTypeInfo modifierType_Solidify; extern ModifierTypeInfo modifierType_Screw; +extern ModifierTypeInfo modifierType_NgonInterp; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index d1bb95761ff..9f13aa15851 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c') incs = '. ./intern' incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern' -incs += ' ../render/extern/include ../blenloader' +incs += ' ../render/extern/include ../blenloader ../bmesh' incs += ' ../include ../blenlib ../makesdna ../blenkernel ../blenkernel/intern' incs += ' ' + env['BF_ZLIB_INC'] @@ -22,3 +22,4 @@ if env['BF_NO_ELBEEM']: env.BlenderLib ( libname = 'bf_modifiers', sources = sources, includes = Split(incs), defines=defs, libtype=['core','player'], priority = [80, 40] ) + diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 95579147dbb..27b10f7cbe4 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -137,13 +137,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); armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts, amd->deformflag, NULL, amd->defgrp_name); @@ -152,14 +152,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 3a34b048aa3..54b3d12ad01 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -30,19 +30,14 @@ * */ -/** \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_ghash.h" #include "BLI_edgehash.h" +#include "BLI_utildefines.h" #include "DNA_curve_types.h" #include "DNA_meshdata_types.h" @@ -53,10 +48,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) { @@ -109,8 +107,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 *scene, + Object *ob, DagNode *obNode) { ArrayModifierData *amd = (ArrayModifierData*) md; @@ -159,28 +157,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 { @@ -222,45 +308,37 @@ 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 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 count = amd->count, maxVerts; 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 *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, @@ -278,7 +356,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); } @@ -287,10 +365,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); @@ -303,8 +381,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 @@ -313,489 +392,147 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, else /* if the offset has no translation, just make one copy */ count = 1; - } + } - if(count < 1) - count = 1; + if(count < 1) + count = 1; /* allocate memory for count duplicates (including original) plus * start and end caps */ - finalVerts = dm->getNumVerts(dm) * count; - finalEdges = dm->getNumEdges(dm) * count; - finalFaces = dm->getNumFaces(dm) * count; - if(start_cap) { - finalVerts += start_cap->getNumVerts(start_cap); - finalEdges += start_cap->getNumEdges(start_cap); - finalFaces += start_cap->getNumFaces(start_cap); - } - if(end_cap) { - finalVerts += end_cap->getNumVerts(end_cap); - finalEdges += end_cap->getNumEdges(end_cap); - finalFaces += end_cap->getNumFaces(end_cap); - } - result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces); - - /* calculate the offset matrix of the final copy (for merging) */ - unit_m4(final_offset); - - for(j=0; j < count - 1; j++) { - mul_m4_m4m4(tmp_mat, final_offset, offset); - copy_m4_m4(final_offset, tmp_mat); - } - - numVerts = numEdges = numFaces = 0; - mvert = CDDM_get_verts(result); - - for (i = 0; i < maxVerts; i++) { - indexMap[i].merge = -1; /* default to no merge */ - indexMap[i].merge_final = 0; /* default to no merge */ - } - - for (i = 0; i < maxVerts; i++) { - MVert *inMV; - MVert *mv = &mvert[numVerts]; - MVert *mv2; - float co[3]; - - inMV = &src_mvert[i]; - - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv = *inMV; - numVerts++; - - indexMap[i].new = numVerts - 1; - - copy_v3_v3(co, mv->co); - - /* Attempts to merge verts from one duplicate with verts from the - * next duplicate which are closer than amd->merge_dist. - * Only the first such vert pair is merged. - * If verts are merged in the first duplicate pair, they are merged - * in all pairs. - */ - if((count > 1) && (amd->flags & MOD_ARR_MERGE)) { - float tmp_co[3]; - mul_v3_m4v3(tmp_co, offset, mv->co); - - for(j = 0; j < maxVerts; j++) { - /* if vertex already merged, don't use it */ - if( indexMap[j].merge != -1 ) continue; - - inMV = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) { - indexMap[i].merge = j; - - /* test for merging with final copy of merge target */ - if(amd->flags & MOD_ARR_MERGEFINAL) { - copy_v3_v3(tmp_co, inMV->co); - inMV = &src_mvert[i]; - mul_m4_v3(final_offset, tmp_co); - if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) - indexMap[i].merge_final = 1; - } - break; - } - } - } - - /* 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); - } - } else if(indexMap[i].merge != i && indexMap[i].merge_final) { - /* if this vert is not merging with itself, and it is merging - * with the final copy of its merge target, remove the first copy - */ - numVerts--; - DM_free_vert_data(result, numVerts, 1); - } - } - - /* make a hashtable so we can avoid duplicate edges from merging */ - edges = BLI_edgehash_new(); - - maxEdges = dm->getNumEdges(dm); - medge = CDDM_get_edges(result); - for(i = 0; i < maxEdges; i++) { - MEdge inMED; - MEdge med; - MEdge *med2; - int vert1, vert2; - - dm->getEdge(dm, i, &inMED); - - med = inMED; - med.v1 = indexMap[inMED.v1].new; - med.v2 = indexMap[inMED.v2].new; - - /* if vertices are to be merged with the final copies of their - * merge targets, calculate that final copy - */ - if(indexMap[inMED.v1].merge_final) { - med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge, - count - 1); - } - if(indexMap[inMED.v2].merge_final) { - med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge, - count - 1); - } - - if(med.v1 == med.v2) continue; - - /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ - if(med.v1 >= numVerts) - med.v1= numVerts-1; - if(med.v2 >= numVerts) - med.v2= numVerts-1; - - if (initFlags) { - med.flag |= ME_EDGEDRAW | ME_EDGERENDER; - } - - if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) { - DM_copy_edge_data(dm, result, i, numEdges, 1); - medge[numEdges] = med; - numEdges++; - - BLI_edgehash_insert(edges, med.v1, med.v2, NULL); - } - - for(j = 1; j < count; j++) - { - vert1 = calc_mapping(indexMap, inMED.v1, j); - vert2 = calc_mapping(indexMap, inMED.v2, j); - - /* edge could collapse to single point after mapping */ - if(vert1 == vert2) continue; - - /* 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); - } - } - } - - 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); - } - - for(j = 1; j < count; j++) - { - MFace *mf2 = &mface[numFaces]; - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf2 = *mf; - - mf2->v1 = calc_mapping(indexMap, inMF.v1, j); - mf2->v2 = calc_mapping(indexMap, inMF.v2, j); - mf2->v3 = calc_mapping(indexMap, inMF.v3, j); - if (inMF.v4) - mf2->v4 = calc_mapping(indexMap, inMF.v4, j); - - numFaces++; - - /* if the face has fewer than 3 vertices, don't create it */ - if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) { - numFaces--; - DM_free_face_data(result, numFaces, 1); - } - } - } - - /* add start and end caps */ - if(start_cap) { - float startoffset[4][4]; - MVert *cap_mvert; - MEdge *cap_medge; - MFace *cap_mface; - int *origindex; - int *vert_map; - int capVerts, capEdges, capFaces; - - capVerts = start_cap->getNumVerts(start_cap); - capEdges = start_cap->getNumEdges(start_cap); - capFaces = start_cap->getNumFaces(start_cap); - cap_mvert = start_cap->getVertArray(start_cap); - cap_medge = start_cap->getEdgeArray(start_cap); - cap_mface = start_cap->getFaceArray(start_cap); - - invert_m4_m4(startoffset, offset); - - vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, - "arrayModifier_doArray vert_map"); - - origindex = result->getVertDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capVerts; i++) { - MVert *mv = &cap_mvert[i]; - short merged = 0; - - if(amd->flags & MOD_ARR_MERGE) { - float tmp_co[3]; - MVert *in_mv; - int j; - - copy_v3_v3(tmp_co, mv->co); - mul_m4_v3(startoffset, tmp_co); - - for(j = 0; j < maxVerts; j++) { - in_mv = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { - vert_map[i] = calc_mapping(indexMap, j, 0); - merged = 1; - break; - } - } - } - - if(!merged) { - DM_copy_vert_data(start_cap, result, i, numVerts, 1); - mvert[numVerts] = *mv; - mul_m4_v3(startoffset, mvert[numVerts].co); - origindex[numVerts] = ORIGINDEX_NONE; - - vert_map[i] = numVerts; - - 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(!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; - - 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); - } - - 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(!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; - - numFaces++; - } - - MEM_freeN(vert_map); - end_cap->release(end_cap); - } - - BLI_edgehash_free(edges, NULL); - MEM_freeN(indexMap); - - CDDM_lower_num_verts(result, numVerts); - CDDM_lower_num_edges(result, numEdges); - CDDM_lower_num_faces(result, numFaces); - - return result; + 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); + } + + /* calculate the offset matrix of the final copy (for merging) */ + unit_m4(final_offset); + + for(j=0; j < count - 1; j++) { + mul_m4_m4m4(tmp_mat, final_offset, offset); + copy_m4_m4(final_offset, tmp_mat); + } + + BMO_Init_Op(&weldop, "weldverts"); + BMO_InitOpf(em->bm, &op, "dupe geom=%avef"); + oldop = op; + for (j=0; j < count; j++) { + BMVert *v, *v2; + BMOpSlot *s1; + BMOpSlot *s2; + + BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout"); + BMO_Exec_Op(em->bm, &op); + + s1 = BMO_GetSlot(&op, "geom"); + s2 = BMO_GetSlot(&op, "newout"); + + BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout"); + + #define _E(s, i) ((BMVert**)(s)->data.buf)[i] + + /*calculate merge mapping*/ + if (j == 0) { + BMOperator findop; + BMOIter oiter; + BMVert *v, *v2; + BMHeader *h; + + BMO_InitOpf(em->bm, &findop, + "finddoubles verts=%av dist=%f keepverts=%s", + amd->merge_dist, &op, "geom"); + + i = 0; + BMO_ITER(h, &oiter, em->bm, &op, "geom", BM_ALL) { + BMINDEX_SET(h, i); + i++; + } + + BMO_ITER(h, &oiter, em->bm, &op, "newout", BM_ALL) { + BMINDEX_SET(h, i); + i++; + } + + BMO_Exec_Op(em->bm, &findop); + + indexLen = i; + indexMap = MEM_callocN(sizeof(int)*indexLen, "indexMap"); + + /*element type argument doesn't do anything here*/ + BMO_ITER(v, &oiter, em->bm, &findop, "targetmapout", 0) { + v2 = BMO_IterMapValp(&oiter); + + indexMap[BMINDEX_GET(v)] = BMINDEX_GET(v2)+1; + } + + BMO_Finish_Op(em->bm, &findop); + } + + /*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) + + for (i=0; i<indexLen; i++) { + if (!indexMap[i]) continue; + + v = E(i); + v2 = E(indexMap[i]-1); + + BMO_Insert_MapPointer(em->bm, &weldop, "targetmap", v, v2); + } + + #undef E + #undef _E + + BMO_Finish_Op(em->bm, &oldop); + oldop = op; + } + + if (j > 0) BMO_Finish_Op(em->bm, &op); + + if (amd->flags & MOD_ARR_MERGE) + BMO_Exec_Op(em->bm, &weldop); + + BMO_Finish_Op(em->bm, &weldop); + + BMEdit_RecalcTesselation(em); + cddm = CDDM_from_BMEditMesh(em, NULL, 0); + + BMEdit_Free(em); + MEM_freeN(indexMap); + + 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 useRenderParams, int 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 *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 323ed71dd74..b952e92de4e 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -91,6 +91,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { +#if 0 DerivedMesh *result; BME_Mesh *bm; @@ -113,8 +114,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), BME_free_mesh(bm); CDDM_calc_normals(result); +#endif - return result; + return CDDM_copy(derivedData, 0); } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 9d83e351b2b..cefad37ea26 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -174,14 +174,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 */ @@ -255,7 +255,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; } @@ -305,8 +305,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; @@ -347,14 +347,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, @@ -394,16 +394,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]; @@ -436,7 +436,11 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( CDDM_calc_edges(result); CDDM_calc_normals(result); - return result; + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + result->needsFree = 1; + result->release(result); + + return dm; } static void BuildMeshDescriptors( @@ -469,7 +473,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), @@ -501,7 +505,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(); @@ -555,7 +559,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; diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 1cf67ac8cae..b2817aa11ea 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -99,7 +99,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, const int maxVerts= dm->getNumVerts(dm); const int maxEdges= dm->getNumEdges(dm); - const int maxFaces= dm->getNumFaces(dm); + const int maxFaces= dm->getNumTessFaces(dm); vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); for(i = 0; i < maxVerts; ++i) vertMap[i] = i; @@ -116,7 +116,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } CLAMP(frac, 0.0f, 1.0f); - numFaces = dm->getNumFaces(dm) * frac; + numFaces = dm->getNumTessFaces(dm) * frac; numEdges = dm->getNumEdges(dm) * frac; /* if there's at least one face, build based on faces */ @@ -130,7 +130,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, */ for(i = 0; i < numFaces; ++i) { MFace mf; - dm->getFace(dm, faceMap[i], &mf); + dm->getTessFace(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), @@ -205,7 +205,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), numFaces, 0, 0); /* copy the vertices across */ for( hashIter = BLI_ghashIterator_new(vertHash); @@ -247,8 +247,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, MFace *dest; int orig_v4; - dm->getFace(dm, faceMap[i], &source); - dest = CDDM_get_face(result, i); + dm->getTessFace(dm, faceMap[i], &source); + dest = CDDM_get_tessface(result, i); orig_v4 = source.v4; diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 83ba8a12163..315361ff227 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -119,7 +119,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) @@ -168,8 +168,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 ecd10250c00..da793287520 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -125,12 +125,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 ba9dbfc31ad..22c43d5e46a 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -84,9 +84,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++) { @@ -142,11 +142,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++) { @@ -157,7 +157,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]; @@ -184,7 +184,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), MEM_freeN(lod.triangle_index_buffer); exit: - return result; + + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + 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 d303f3d2516..3ac615d2fc7 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -181,11 +181,11 @@ static void get_texture_coords(DisplaceModifierData *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; diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 09e29d9ed8e..c98905a8be1 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -20,21 +20,12 @@ * 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 +* Contributor(s): Joseph Eagar * * ***** END GPL LICENSE BLOCK ***** * */ -/** \file blender/modifiers/intern/MOD_edgesplit.c - * \ingroup modifiers - */ - - /* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag * or edge angle (can be used to achieve autosmoothing) */ @@ -44,724 +35,300 @@ #include "BLI_memarena.h" #include "BLI_edgehash.h" #include "BLI_math.h" +#include "BLI_array.h" #include "BLI_utildefines.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" - -#if 0 -#define EDGESPLIT_DEBUG_3 -#define EDGESPLIT_DEBUG_2 -#define EDGESPLIT_DEBUG_1 -#define EDGESPLIT_DEBUG_0 -#endif - -static void initData(ModifierData *md) -{ - EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - - /* default to 30-degree split angle, sharpness from both angle & flag - */ - emd->split_angle = 30; - emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG; -} - -static void copyData(ModifierData *md, ModifierData *target) -{ - EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - EdgeSplitModifierData *temd = (EdgeSplitModifierData*) target; - - temd->split_angle = emd->split_angle; - temd->flags = emd->flags; -} - -/* Mesh data for edgesplit operation */ -typedef struct SmoothVert { - LinkNode *faces; /* all faces which use this vert */ - int oldIndex; /* the index of the original DerivedMesh vert */ - int newIndex; /* the index of the new DerivedMesh vert */ -} SmoothVert; - -#define SMOOTHEDGE_NUM_VERTS 2 - -typedef struct SmoothEdge { - SmoothVert *verts[SMOOTHEDGE_NUM_VERTS]; /* the verts used by this edge */ - LinkNode *faces; /* all faces which use this edge */ - int oldIndex; /* the index of the original DerivedMesh edge */ - int newIndex; /* the index of the new DerivedMesh edge */ - short flag; /* the flags from the original DerivedMesh edge */ -} SmoothEdge; - -#define SMOOTHFACE_MAX_EDGES 4 - -typedef struct SmoothFace { - SmoothEdge *edges[SMOOTHFACE_MAX_EDGES]; /* nonexistent edges == NULL */ - int flip[SMOOTHFACE_MAX_EDGES]; /* 1 = flip edge dir, 0 = don't flip */ - float normal[3]; /* the normal of this face */ - int oldIndex; /* the index of the original DerivedMesh face */ - int newIndex; /* the index of the new DerivedMesh face */ -} SmoothFace; - -typedef struct SmoothMesh { - SmoothVert *verts; - SmoothEdge *edges; - SmoothFace *faces; - int num_verts, num_edges, num_faces; - int max_verts, max_edges, max_faces; - DerivedMesh *dm; - float threshold; /* the cosine of the smoothing angle */ - int flags; - MemArena *arena; - ListBase propagatestack, reusestack; -} SmoothMesh; - -static SmoothVert *smoothvert_copy(SmoothVert *vert, SmoothMesh *mesh) -{ - SmoothVert *copy = &mesh->verts[mesh->num_verts]; +/* EdgeSplit */ +/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag + * or edge angle (can be used to achieve autosmoothing) +*/ - if(mesh->num_verts >= mesh->max_verts) { - printf("Attempted to add a SmoothMesh vert beyond end of array\n"); +/*new cddm-based edge split code*/ +typedef struct VertUser { + int ov, v, done; + ListBase users; +} VertUser; + +typedef struct EdgeNode { + struct EdgeNode *next, *prev; + struct EdgeData *edge; +} EdgeNode; + +typedef struct EdgeData { + EdgeNode v1node, v2node; + VertUser *v1user, *v2user; + float fno[3]; /*used to calculate face angles*/ + int has_fno; + int tag; + int v1, v2; + int used; +} EdgeData; + +typedef struct MemBase { + BLI_mempool *vertuserpool; +} MemBase; + +BM_INLINE EdgeData *edge_get_next(EdgeData *e, int ov) { + if (ov == e->v1) + return e->v1node.next ? e->v1node.next->edge : NULL; + else return e->v2node.next ? e->v2node.next->edge : NULL; +} + +BM_INLINE EdgeNode *edge_get_node(EdgeData *e, int ov) +{ + if (ov == e->v1) + return &e->v1node; + else return &e->v2node; 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) +BM_INLINE VertUser *edge_get_vuser(MemBase *b, EdgeData *edge, int ov) { - 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"); + if (ov == edge->v1) + return edge->v1user; + else if (ov == edge->v2) + return edge->v2user; + else { + printf("yeek!!\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 +BM_INLINE void edge_set_vuser(MemBase *b, EdgeData *e, int ov, VertUser *vu) -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]; + VertUser *olduser = edge_get_vuser(b, e, ov); - 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]; -} + if (vu == olduser) + return; -/* 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; + if (olduser) + BLI_remlink(&olduser->users, ov==e->v1 ? &e->v1node : &e->v2node); + BLI_addtail(&vu->users, ov==e->v1 ? &e->v1node : &e->v2node); - 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; + if (ov == e->v1) + e->v1user = vu; + else e->v2user = vu; } -/* 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) +BM_INLINE VertUser *new_vuser(MemBase *base) { - LinkNode *node; - - for(node = edge->faces; node != NULL; node = node->next) - if(node->link != face) return node->link; + VertUser *vusr = BLI_mempool_calloc(base->vertuserpool); - return NULL; + return vusr; } -#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) +BM_INLINE MemBase *new_membase(void) { - 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; + MemBase *b = MEM_callocN(sizeof(MemBase), "MemBase for edgesplit in modifier.c"); + b->vertuserpool = BLI_mempool_create(sizeof(VertUser), 1, 2048, 1, 0); - node = MEM_mallocN(sizeof(*node), "nlink"); - node->next = NULL; - node->link = source; - - if(prev) prev->next = node; - else *target = node; + return b; } -/* appends elements of source which aren't already in target to target */ -static void linklist_append_list_unique(LinkNode **target, LinkNode *source) +BM_INLINE void free_membase(MemBase *b) { - for(; source; source = source->next) - linklist_append_unique(target, source->link); + BLI_mempool_destroy(b->vertuserpool); + MEM_freeN(b); } -#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) +BM_INLINE EdgeData *edge_get_first(VertUser *vu) { - if(prepend) { - LinkNode *node = prepend; - while(node->next) node = node->next; - - node->next = *list; - *list = prepend; -} + return vu->users.first ? ((EdgeNode*)vu->users.first)->edge : NULL; } -#endif -/* returns 1 if the linked list contains the given pointer, 0 otherwise - */ -static int linklist_contains(LinkNode *list, void *ptr) +DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) { - LinkNode *node; + DerivedMesh *cddm = CDDM_copy(dm, 0); + MEdge *medge; + BLI_array_declare(medge); + MLoop *mloop, *ml, *prevl; + MPoly *mpoly, *mp; + MVert *mvert; + BLI_array_declare(mvert); + EdgeData *etags, *e, *enext; + BLI_array_declare(etags); + VertUser *vu, *vu2; + MemBase *membase; + CustomData edata, vdata; + int i, j, curv, cure; + float threshold = cos((emd->split_angle + 0.00001) * M_PI / 180.0); + float no[3], edge_angle_cos; - for(node = list; node; node = node->next) - if(node->link == ptr) return 1; + if (!cddm->numVertData || !cddm->numEdgeData) + return cddm; - return 0; -} + membase = new_membase(); -/* 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; + etags = MEM_callocN(sizeof(EdgeData)*cddm->numEdgeData, "edgedata tag thingies"); + BLI_array_set_length(etags, cddm->numEdgeData); - return 1; -} + mvert = cddm->getVertArray(cddm); + BLI_array_set_length(mvert, cddm->numVertData); + medge = cddm->getEdgeArray(cddm); + BLI_array_set_length(medge, cddm->numEdgeData); + mloop = CustomData_get_layer(&cddm->loopData, CD_MLOOP); + mpoly = CustomData_get_layer(&cddm->polyData, CD_MPOLY); -#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 + for (i=0; i<cddm->numEdgeData; i++) { + etags[i].v1 = medge[i].v1; + etags[i].v2 = medge[i].v2; -/* 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; + etags[i].tag = (medge[i].flag & ME_SHARP) != 0; - while(node && node->link != value) { - prev = node; - node = node->next; + etags[i].v1node.edge = etags+i; + etags[i].v2node.edge = etags+i; } - if(node) { - if(prev) - prev->next = node->next; - else - *list = node->next; - - if(freefunc) - freefunc(node->link); - - MEM_freeN(node); + if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { + mp = mpoly; + for (i=0; i<cddm->numPolyData; i++, mp++) { + mesh_calc_poly_normal(mp, mloop+mp->loopstart, mvert, no); + + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + if (!etags[ml->e].has_fno) { + VECCOPY(etags[ml->e].fno, no); + etags[ml->e].has_fno = 1; + } else if (!etags[ml->e].tag) { + edge_angle_cos = INPR(etags[ml->e].fno, no); + if (edge_angle_cos < threshold) { + etags[ml->e].tag = 1; + } + } + } + } } -} -/* 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); -} + mp = mpoly; + for (i=0; i<cddm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + if (etags[ml->e].tag) + continue; -#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); -} + prevl = mloop + mp->loopstart + ((j-1)+mp->totloop) % mp->totloop; -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 + if (!edge_get_vuser(membase, etags+prevl->e, ml->v)) { + vu = new_vuser(membase); + vu->ov = vu->v = ml->v; + edge_set_vuser(membase, etags+prevl->e, ml->v, vu); + } - 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); + if (!edge_get_vuser(membase, etags+ml->e, ml->v)) { + vu = new_vuser(membase); + vu->ov = vu->v = ml->v; + edge_set_vuser(membase, etags+ml->e, ml->v, vu); + } - edge->verts[i] = replace; + /*continue if previous edge is tagged*/ + if (etags[prevl->e].tag) + continue; + + /*merge together adjacent split vert users*/ + if (edge_get_vuser(membase, etags+prevl->e, ml->v) + != edge_get_vuser(membase, etags+ml->e, ml->v)) + { + vu = edge_get_vuser(membase, etags+prevl->e, ml->v); + vu2 = edge_get_vuser(membase, etags+ml->e, ml->v); + + /*remove from vu2's users list and add to vu's*/ + for (e=edge_get_first(vu2); e; e=enext) { + enext = edge_get_next(e, ml->v); + edge_set_vuser(membase, e, ml->v, vu); + } + } } } -#ifdef EDGESPLIT_DEBUG_3 - printf(" -> {%4d, %4d}\n", edge->verts[0]->newIndex, edge->verts[1]->newIndex); -#endif -} + mp = mpoly; + for (i=0; i<cddm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + if (!etags[ml->e].tag) + continue; -static void face_replace_vert(void *ptr, void *userdata) -{ - SmoothFace *face = ptr; - int i; + prevl = mloop + mp->loopstart + ((j-1)+mp->totloop) % mp->totloop; - for(i = 0; i < SMOOTHFACE_MAX_EDGES && face->edges[i]; i++) - edge_replace_vert(face->edges[i], userdata); -} + if (!etags[prevl->e].tag) { + vu = edge_get_vuser(membase, etags+prevl->e, ml->v); + if (!vu) { + vu = new_vuser(membase); + vu->ov = vu->v = ml->v; + edge_set_vuser(membase, etags+prevl->e, ml->v, vu); + } -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; + edge_set_vuser(membase, etags+ml->e, ml->v, vu); + } else { + vu = new_vuser(membase); + vu->ov = vu->v = ml->v; + edge_set_vuser(membase, etags+ml->e, ml->v, vu); + } } } -#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 -} + curv = cddm->numVertData; + cure = cddm->numEdgeData; + mp = mpoly; + for (i=0; i<cddm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + e = etags + ml->e; + if (e->v1user && !e->v1user->done) { + e->v1user->done = 1; + BLI_array_growone(mvert); + + mvert[curv] = mvert[e->v1user->ov]; + e->v1user->v = curv; + + curv++; + } -static int edge_is_loose(SmoothEdge *edge) -{ - return !(edge->faces && edge->faces->next); -} + if (e->v2user && !e->v2user->done) { + e->v2user->done = 1; + BLI_array_growone(mvert); -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; - } - } + mvert[curv] = mvert[e->v2user->ov]; + e->v2user->v = curv; -#ifdef EDGESPLIT_DEBUG_1 - printf("not sharp\n"); -#endif - return 0; -} + curv++; + } + vu = edge_get_vuser(membase, e, ml->v); + if (!vu) + continue; + ml->v = vu->v; + +#if 0 //BMESH_TODO should really handle edges here, but for now use cddm_calc_edges + /*ok, now we have to deal with edges. . .*/ + if (etags[ml->e].tag) { + if (etags[ml->e].used) { + BLI_array_growone(medge); + BLI_array_growone(etags); + medge[cure] = medge[ml->e]; + + ml->e = cure; + etags[cure].used = 1; + cure++; + } + + vu = etags[ml->e].v1user; + vu2 = etags[ml->e].v2user; + +<<<<<<< .working + if (vu) + medge[ml->e].v1 = vu->v; + if (vu2) + medge[ml->e].v2 = vu2->v; +======= /* 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) @@ -938,330 +505,100 @@ static void propagate_split(SmoothEdge *edge, SmoothVert *vert, /* 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 */ +>>>>>>> .merge-right.r36153 } else { - /* vert has more than one fan of faces attached; split it */ - vert2 = smoothvert_copy(vert, mesh); + etags[ml->e].used = 1; - /* replace vert with its copy in visited_faces */ - repdata.find = vert; - repdata.replace = vert2; - BLI_linklist_apply(visited_faces, face_replace_vert, &repdata); + if (vu->ov == etags[ml->e].v1) + medge[ml->e].v1 = vu->v; + else if (vu->ov == etags[ml->e].v2) + medge[ml->e].v2 = vu->v; } - } else { - /* edge is not loose, so it must be sharp; split it */ - split_edge(edge, vert, mesh); +#endif } } - 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 + /*resize customdata arrays and add new medge/mvert arrays*/ + vdata = cddm->vertData; + edata = cddm->edgeData; - edge2 = find_other_sharp_edge(vert, edge, &visited_faces); + /*make sure we don't copy over mvert/medge layers*/ + CustomData_set_layer(&vdata, CD_MVERT, NULL); + CustomData_set_layer(&edata, CD_MEDGE, NULL); + CustomData_free_layer_active(&vdata, CD_MVERT, cddm->numVertData); + CustomData_free_layer_active(&edata, CD_MEDGE, cddm->numEdgeData); - 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); - } + memset(&cddm->vertData, 0, sizeof(CustomData)); + memset(&cddm->edgeData, 0, sizeof(CustomData)); - BLI_linklist_free(visited_faces, NULL); -#ifdef EDGESPLIT_DEBUG_1 - printf("=== END === split_edge(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif -} + CustomData_copy(&vdata, &cddm->vertData, CD_MASK_DERIVEDMESH, CD_CALLOC, curv); + CustomData_copy_data(&vdata, &cddm->vertData, 0, 0, cddm->numVertData); + CustomData_free(&vdata, cddm->numVertData); + cddm->numVertData = curv; -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; - } -} + CustomData_copy(&edata, &cddm->edgeData, CD_MASK_DERIVEDMESH, CD_CALLOC, cure); + CustomData_copy_data(&edata, &cddm->edgeData, 0, 0, cddm->numEdgeData); + CustomData_free(&edata, cddm->numEdgeData); + cddm->numEdgeData = cure; -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); - } - } + CDDM_set_mvert(cddm, mvert); + CDDM_set_medge(cddm, medge); + + free_membase(membase); + MEM_freeN(etags); + + /*edge calculation isn't working correctly, so just brute force it*/ + cddm->numEdgeData = 0; + CDDM_calc_edges_poly(cddm); + + cddm->numFaceData = mesh_recalcTesselation(&cddm->faceData, + &cddm->loopData, &cddm->polyData, + mvert, cddm->numFaceData, + cddm->numLoopData, cddm->numPolyData, 1, 0); + + CDDM_set_mface(cddm, DM_get_tessface_data_layer(cddm, CD_MFACE)); + CDDM_calc_normals(cddm); + + return cddm; } -static int count_bridge_verts(SmoothMesh *mesh) +static void initData(ModifierData *md) { - int i, j, count = 0; - - for(i = 0; i < mesh->num_faces; i++) { - SmoothFace *face = &mesh->faces[i]; - - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - SmoothEdge *edge = face->edges[j]; - SmoothEdge *next_edge; - SmoothVert *vert = edge->verts[1 - face->flip[j]]; - int next = (j + 1) % SMOOTHFACE_MAX_EDGES; - - /* wrap next around if at last edge */ - if(!face->edges[next]) next = 0; - - next_edge = face->edges[next]; - - /* if there are other faces sharing this vertex but not - * these edges, the vertex will be split, so count it - */ - /* vert has to have at least one face (this one), so faces != 0 */ - if(!edge->faces->next && !next_edge->faces->next - && vert->faces->next) { - count++; - } - } - } + EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; - /* each bridge vert will be counted once per face that uses it, - * so count is too high, but it's ok for now + /* default to 30-degree split angle, sharpness from both angle & flag */ - return count; + emd->split_angle = 30; + emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG; } -static void split_bridge_verts(SmoothMesh *mesh) +static void copyData(ModifierData *md, ModifierData *target) { - int i,j; - - for(i = 0; i < mesh->num_faces; i++) { - SmoothFace *face = &mesh->faces[i]; - - for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) { - SmoothEdge *edge = face->edges[j]; - SmoothEdge *next_edge; - SmoothVert *vert = edge->verts[1 - face->flip[j]]; - int next = (j + 1) % SMOOTHFACE_MAX_EDGES; - - /* wrap next around if at last edge */ - if(!face->edges[next]) next = 0; - - next_edge = face->edges[next]; - - /* 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); - } - } + EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; + EdgeSplitModifierData *temd = (EdgeSplitModifierData*) target; + + temd->split_angle = emd->split_angle; + temd->flags = emd->flags; } -static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, DerivedMesh *dm) +static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, + Object *ob, DerivedMesh *dm) { - SmoothMesh *mesh; - DerivedMesh *result; - int max_verts, max_edges; - if(!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG))) return dm; - /* 1. make smoothmesh with initial number of elements */ - mesh = smoothmesh_from_derivedmesh(dm); - - /* 2. count max number of elements to add */ - tag_and_count_extra_edges(mesh, emd->split_angle, emd->flags, &max_edges); - max_verts = max_edges * 2 + mesh->max_verts; - max_verts += count_bridge_verts(mesh); - max_edges += mesh->max_edges; - - /* 3. reallocate smoothmesh arrays & copy elements across */ - /* 4. remap copied elements' pointers to point into the new arrays */ - smoothmesh_resize_verts(mesh, max_verts); - smoothmesh_resize_edges(mesh, max_edges); - -#ifdef EDGESPLIT_DEBUG_1 - printf("********** Pre-split **********\n"); - smoothmesh_print(mesh); -#endif - - split_sharp_edges(mesh, emd->split_angle, emd->flags); -#ifdef EDGESPLIT_DEBUG_1 - printf("********** Post-edge-split **********\n"); - smoothmesh_print(mesh); -#endif - - split_bridge_verts(mesh); - -#ifdef EDGESPLIT_DEBUG_1 - printf("********** Post-vert-split **********\n"); - smoothmesh_print(mesh); -#endif - -#ifdef EDGESPLIT_DEBUG_0 - printf("Edgesplit: Estimated %d verts & %d edges, " - "found %d verts & %d edges\n", max_verts, max_edges, - mesh->num_verts, mesh->num_edges); -#endif - - result = CDDM_from_smoothmesh(mesh); - smoothmesh_free(mesh); - - return result; + return doEdgeSplit(dm, emd); } -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 useRenderParams, int 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); @@ -1270,8 +607,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, - struct EditMesh *UNUSED(editData), - DerivedMesh *derivedData) + BMEditMesh *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 924035538da..f448331d37f 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -110,8 +110,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; @@ -200,7 +200,7 @@ 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); + MFace *df = CDDM_get_tessface(split, cur); DM_copy_face_data(dm, split, i, cur, 1); *df = *mf; return df; @@ -546,12 +546,12 @@ static void remap_uvs_23(DerivedMesh *dm, DerivedMesh *split, int numlayer, int 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"); @@ -627,7 +627,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??) */ @@ -669,7 +669,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: @@ -759,7 +759,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)); } @@ -767,8 +767,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, @@ -791,9 +794,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; @@ -838,7 +841,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, BLI_edgehashIterator_free(ehi); /* the final duplicated vertices */ - explode= CDDM_from_template(dm, totdup, 0,totface); + explode= CDDM_from_template(dm, totdup, 0,totface, 0, 0); mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname); /*dupvert= CDDM_get_verts(explode);*/ @@ -906,8 +909,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; @@ -953,6 +956,10 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, psmd->psys->lattice= NULL; } + dm = CDDM_copy(explode, 1); /*builds ngon faces from tess (mface) faces*/ + explode->needsFree = 1; + explode->release(explode); + return explode; } @@ -987,7 +994,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 02912e38204..7db1f003146 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -227,7 +227,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) { @@ -283,7 +283,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]; @@ -510,12 +510,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 082c199b16f..7f79f74e7b6 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -267,12 +267,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 694f8fb3e52..0d7c0f1509c 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -120,12 +120,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 b36d6848533..6f0bb27b208 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -116,7 +116,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 @@ -294,7 +294,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)) && @@ -311,7 +311,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 */ @@ -365,8 +365,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; @@ -392,7 +392,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, BLI_ghash_free(faceHash, NULL, NULL); /* return the new mesh */ - return result; + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + result->needsFree = 1; + result->release(result); + + return dm; } diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index ba73f3fa0d1..890121fdd44 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -34,7 +34,7 @@ * \ingroup modifiers */ - +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -47,6 +47,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; diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index b1c765e5c9b..22fba3ceb35 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -30,28 +30,23 @@ * */ -/** \file blender/modifiers/intern/MOD_mirror.c - * \ingroup modifiers - */ - - #include "DNA_meshdata_types.h" #include "DNA_object_types.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" - static void initData(ModifierData *md) { MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -69,7 +64,7 @@ static void copyData(ModifierData *md, ModifierData *target) tmmd->axis = mmd->axis; tmmd->flag = mmd->flag; tmmd->tolerance = mmd->tolerance; - tmmd->mirror_ob = mmd->mirror_ob; + tmmd->mirror_ob = mmd->mirror_ob;; } static void foreachObjectLink( @@ -78,14 +73,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; @@ -97,195 +91,163 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } -static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, + +/* Mirror */ +#define VERT_NEW 1 + +void vertgroup_flip_name (char *name, int strip_number); +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]; + DerivedMesh *cddm, *origdm; + bDeformGroup *def, *defb; + bDeformGroup **vector_def = NULL; + MVert *mv; + MEdge *me; + MLoop *ml; + MPoly *mp; 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; + int i, j, *vtargetmap = NULL; + BLI_array_declare(vtargetmap); + int vector_size=0, a, b; + + 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; + } } 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 mtx2[4][4]; - 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); + invert_m4_m4(mtx2, mmd->mirror_ob->obmat); + mul_m4_m4m4(mtx, ob->obmat, mtx2); + } else { + unit_m4(mtx); + } + + 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*/ + mv = CDDM_get_verts(cddm) + dm->numVertData; + for (i=0; i<dm->numVertData; i++, mv++) { + mv->co[axis] = -mv->co[axis]; + if (fabs(mv->co[axis]) < tolerance) { + BLI_array_append(vtargetmap, i+dm->numVertData); + } else BLI_array_append(vtargetmap, -1); + } + + 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; - if (mmd->mirror_ob) { - mul_m4_v3(mtx, co); + 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); } - 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++; + 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; + + mp->loopstart += dm->numLoopData; } - 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]; - } + /*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; } - for(i = 0; i < maxFaces; i++) { - MFace inMF; - MFace *mf = CDDM_get_face(result, numFaces); - - dm->getFace(dm, i, &inMF); - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf = inMF; - numFaces++; - - mf->v1 = indexMap[inMF.v1][0]; - mf->v2 = indexMap[inMF.v2][0]; - mf->v3 = indexMap[inMF.v3][0]; - mf->v4 = indexMap[inMF.v4][0]; + 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, @@ -312,10 +274,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; @@ -328,9 +289,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 def2020f35f..7296271eeb0 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -80,9 +80,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); } } @@ -92,7 +92,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..deca534f8e1 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_ngoninterp.c @@ -0,0 +1,333 @@ +/* +* $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 *ob, + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + NgonInterpModifierData *nmd= (MaskModifierData *)md; + DerivedMesh *dm= derivedData, *result= NULL; + DerivedMesh *cddm, *dummy; + MFace *mf; + MPoly *mpoly; + MLoop *mloop; + MFace *mface = NULL, *mf2; + MVert *mvert = NULL, *mv2, *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, 0); + + 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.0 - fac*x); + mul_v3_fl(co2, 1.0 - 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.0 - (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 { + float co[3]; + int lindex[3] = {0, 1, 2}; + + 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.0/(float)(mp->totloop)); + for (j=0; j<mp->totloop; j++) { + float vec[3]; + + sub_v3_v3(cos[j], cent); + mul_v3_fl(cos[j], 1.0+FLT_EPSILON*1500.0f); + add_v3_v3(cos[j], cent); + } + + copy_v3_v3(co, mvert + mf2->v1); + 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); + 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); + 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 46d53e0db15..a2aa0e47e54 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -176,7 +176,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, pars=psys->particles; totvert=dm->getNumVerts(dm); - totface=dm->getNumFaces(dm); + totface=dm->getNumTessFaces(dm); maxvert=totvert*totpart; maxface=totface*totpart; @@ -192,7 +192,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, max_co=max_r[track]; } - result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface); + result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface, 0, 0); mvert=result->getVertArray(result); orig_mvert=dm->getVertArray(dm); @@ -262,8 +262,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; @@ -314,7 +314,11 @@ 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), diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 533bfd203b5..7ab23cfd27b 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -166,7 +166,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); @@ -181,13 +181,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 17e350482f0..db7482b79ee 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -176,7 +176,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: @@ -294,17 +294,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 */ @@ -830,7 +830,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, CDDM_calc_normals(result); } - return result; + dm = CDDM_copy(result, 1); /*builds ngon faces from tess (mface) faces*/ + result->needsFree = 1; + result->release(result); + + return dm; } diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 1b7b724835c..c591272c9c4 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -40,6 +40,8 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_utildefines.h" +#include "BLI_array.h" +#include "BLI_smallhash.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.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); @@ -196,24 +192,25 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } - static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { int i; - DerivedMesh *result; + DerivedMesh *result, *copy; 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; @@ -221,10 +218,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* 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; @@ -241,10 +238,21 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (defgrp_index >= 0) dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - - 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->needsFree = 1; + dm->release(dm); + 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(); @@ -277,28 +285,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)); @@ -306,18 +306,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; @@ -332,14 +331,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); @@ -347,30 +344,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++) { @@ -422,12 +430,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; } @@ -437,32 +446,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); + 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); } - - 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; - } - - 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) { @@ -514,8 +522,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } if(smd->flag & MOD_SOLIDIFY_RIM) { - - /* bugger, need to re-calculate the normals for the new edge faces. * This could be done in many ways, but probably the quickest way is to calculate the average normals for side faces only. * Then blend them with the normals of the edge verts. @@ -534,12 +540,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 */ ed= medge + (numEdges * 2); for(i=0; i<newEdges; i++, ed++) { @@ -552,11 +552,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* faces */ - mf= mface + (numFaces * 2); - for(i=0; i<newFaces; i++, mf++) { + mp= mpoly + (numFaces * 2); + ml = mloop + (numLoops * 2); + j = 0; + for(i=0; i<newFaces; i++, mp++) { int eidx= new_edge_arr[i]; int fidx= edge_users[eidx]; - int flip; + int flip, k1, k2; + MLoop *ml2; if(fidx >= numFaces) { fidx -= numFaces; @@ -570,36 +573,75 @@ 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->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) { + printf("eek!!!!\n"); + } + + 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 { + printf("eek!!!\n"); + 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(crease_outer) { /* crease += crease_outer; without wrapping */ - unsigned char *cr= (unsigned char *)&(ed->crease); + unsigned char *cr= (unsigned char *)&(medge[numEdges + eidx].crease); int tcr= *cr + crease_outer; *cr= tcr > 255 ? 255 : tcr; } - if(crease_inner) { /* crease += crease_inner; without wrapping */ unsigned char *cr= (unsigned char *)&(medge[numEdges + eidx].crease); @@ -608,7 +650,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); @@ -643,6 +685,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, MEM_freeN(edge_order); } + if (old_vert_arr) + MEM_freeN(old_vert_arr); + + CDDM_recalc_tesselation(result, 1); + /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ if(dvert) { CDDM_calc_normals(result); @@ -655,7 +702,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 fc9958b08d0..fa3d8ae9a33 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -103,7 +103,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), useRenderParams, NULL, isFinalCalc, 0); 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_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 382358b179e..05ecee6ab29 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -101,7 +101,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) @@ -160,7 +160,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 8c94e6f65bc..323531702fa 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -115,7 +115,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); } @@ -132,7 +132,7 @@ DerivedMesh *get_dm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*ve 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) { @@ -189,5 +189,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(ShapeKey); INIT_TYPE(Solidify); INIT_TYPE(Screw); + INIT_TYPE(NgonInterp); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index b054a5b0a6e..a6ff728af37 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_v4(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) { diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 6d547867ed8..e3ee612374a 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -183,11 +183,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; |