Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_solidify.c')
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c317
1 files changed, 170 insertions, 147 deletions
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index d16fa0c503c..fd6d0f602a9 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -35,13 +35,14 @@
#include "DNA_meshdata_types.h"
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
-#include "BLI_utildefines.h"
+#include "BLI_array.h"
#include "BLI_string.h"
-#include "MEM_guardedalloc.h"
-
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
#include "BKE_particle.h"
@@ -59,7 +60,8 @@ typedef struct EdgeFaceRef {
static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
{
int i, numVerts, numEdges, numFaces;
- MFace *mface, *mf;
+ MPoly *mpoly, *mp;
+ MLoop *mloop, *ml;
MVert *mvert, *mv;
float (*face_nors)[3];
@@ -68,10 +70,11 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
numVerts = dm->getNumVerts(dm);
numEdges = dm->getNumEdges(dm);
- numFaces = dm->getNumFaces(dm);
- mface = dm->getFaceArray(dm);
+ numFaces = dm->getNumPolys(dm);
+ mpoly = dm->getPolyArray(dm);
mvert = dm->getVertArray(dm);
-
+ mloop = dm->getLoopArray(dm);
+
/* we don't want to overwrite any referenced layers */
/*
@@ -80,14 +83,14 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
cddm->mvert = mv;
*/
- face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
+ face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
if(!face_nors) {
calc_face_nors = 1;
- face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, numFaces);
+ face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, numFaces);
}
mv = mvert;
- mf = mface;
+ mp = mpoly;
{
EdgeHash *edge_hash = BLI_edgehash_new();
@@ -116,24 +119,16 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
}
/* --- end define --- */
- for(i = 0; i < numFaces; i++, mf++) {
+ for(i = 0; i < numFaces; i++, mp++) {
+ int j;
+
f_no = face_nors[i];
+ if(calc_face_nors)
+ mesh_calc_poly_normal(mp, mloop+mp->loopstart, mvert, f_no);
- if(mf->v4) {
- if(calc_face_nors)
- normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
-
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v4);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v4, mf->v1);
- } else {
- if(calc_face_nors)
- normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
-
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v1);
+ ml = mloop + mp->loopstart;
+ for (j=0; j<mp->totloop; j++, ml++) {
+ NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(ml->v, ME_POLY_LOOP_NEXT(mloop, mp, j)->v);
}
}
@@ -212,14 +207,16 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *result;
const SolidifyModifierData *smd = (SolidifyModifierData*) md;
- MFace *mf, *mface, *orig_mface;
- MEdge *ed, *medge, *orig_medge;
MVert *mv, *mvert, *orig_mvert;
-
+ MEdge *ed, *medge, *orig_medge;
+ MLoop *ml, *mloop, *orig_mloop;
+ MPoly *mp, *mpoly, *orig_mpoly;
const int numVerts = dm->getNumVerts(dm);
const int numEdges = dm->getNumEdges(dm);
- const int numFaces = dm->getNumFaces(dm);
-
+ const int numFaces = dm->getNumPolys(dm);
+ int numLoops=0, newLoops=0, newFaces=0, newEdges=0;
+ int j;
+
/* only use material offsets if we have 2 or more materials */
const short mat_nr_max= ob->totcol > 1 ? ob->totcol - 1 : 0;
const short mat_ofs= mat_nr_max ? smd->mat_ofs : 0;
@@ -227,14 +224,15 @@ 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;
-
+ int *edge_origIndex;
+
float (*vert_nors)[3]= NULL;
const float ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
@@ -249,9 +247,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index);
- orig_mface = dm->getFaceArray(dm);
- orig_medge = dm->getEdgeArray(dm);
+ numLoops = dm->numLoopData;
+ newLoops = 0;
+
orig_mvert = dm->getVertArray(dm);
+ orig_medge = dm->getEdgeArray(dm);
+ orig_mloop = dm->getLoopArray(dm);
+ orig_mpoly = dm->getPolyArray(dm);
if(smd->flag & MOD_SOLIDIFY_RIM) {
EdgeHash *edgehash = BLI_edgehash_new();
@@ -289,28 +291,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges");
edge_order= MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder");
memset(edge_users, INVALID_UNUSED, sizeof(int) * numEdges);
-
- for(i=0, mf=orig_mface; i<numFaces; i++, mf++) {
- if(mf->v4) {
- ADD_EDGE_USER(mf->v1, mf->v2, 0);
- ADD_EDGE_USER(mf->v2, mf->v3, 1);
- ADD_EDGE_USER(mf->v3, mf->v4, 2);
- ADD_EDGE_USER(mf->v4, mf->v1, 3);
- }
- else {
- ADD_EDGE_USER(mf->v1, mf->v2, 0);
- ADD_EDGE_USER(mf->v2, mf->v3, 1);
- ADD_EDGE_USER(mf->v3, mf->v1, 2);
- }
+
+ for (i=0, mp=orig_mpoly; i<numFaces; i++, mp++) {
+ MLoop *ml;
+
+ for (ml=orig_mloop + mp->loopstart, j=0; j<mp->totloop; ml++, j++) {
+ ADD_EDGE_USER(ml->v, ME_POLY_LOOP_NEXT(orig_mloop, mp, j)->v, j);
+ }
}
#undef ADD_EDGE_USER
#undef INVALID_UNUSED
#undef INVALID_PAIR
-
- new_edge_arr= MEM_callocN(sizeof(int) * numEdges, "solid_mod arr");
-
ehi= BLI_edgehashIterator_new(edgehash);
for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
eidx= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
@@ -318,18 +311,17 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
BLI_edgehashIterator_getKey(ehi, &v1, &v2);
orig_mvert[v1].flag |= ME_VERT_TMP_TAG;
orig_mvert[v2].flag |= ME_VERT_TMP_TAG;
- new_edge_arr[newFaces]= eidx;
+ BLI_array_append(new_edge_arr, eidx);
newFaces++;
+ newLoops += 4;
}
}
BLI_edgehashIterator_free(ehi);
-
-
- new_vert_arr= MEM_callocN(sizeof(int) * numVerts, "solid_mod new_varr");
for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) {
if(mv->flag & ME_VERT_TMP_TAG) {
- new_vert_arr[newEdges] = i;
+ old_vert_arr[i] = BLI_array_count(new_vert_arr);
+ BLI_array_append(new_vert_arr, i);
newEdges++;
mv->flag &= ~ME_VERT_TMP_TAG;
@@ -344,14 +336,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);
@@ -359,29 +349,40 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DM_copy_vert_data(dm, result, 0, 0, numVerts);
DM_copy_vert_data(dm, result, 0, numVerts, numVerts);
- {
- static int corner_indices[4] = {2, 1, 0, 3};
- unsigned int is_quad;
-
- for(i=0, mf=mface+numFaces; i<numFaces; i++, mf++) {
- mf->v1 += numVerts;
- mf->v2 += numVerts;
- mf->v3 += numVerts;
- if(mf->v4)
- mf->v4 += numVerts;
-
- /* Flip face normal */
- {
- is_quad = mf->v4;
- SWAP(unsigned int, mf->v1, mf->v3);
- DM_swap_face_data(result, i+numFaces, corner_indices);
- test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3);
- }
+ DM_copy_loop_data(dm, result, 0, 0, numLoops);
+ DM_copy_loop_data(dm, result, 0, numLoops, numLoops);
+
+ DM_copy_poly_data(dm, result, 0, 0, numFaces);
+ DM_copy_poly_data(dm, result, 0, numFaces, numFaces);
+
+ /*flip normals*/
+ mp = mpoly + numFaces;
+ for (i=0; i<dm->numPolyData; i++, mp++) {
+ MLoop *ml2;
+ int e;
+
+ ml2 = mloop + mp->loopstart + dm->numLoopData;
+ for (j=0; j<mp->totloop; j++) {
+ CustomData_copy_data(&dm->loopData, &result->loopData, mp->loopstart+j,
+ mp->loopstart+(mp->totloop-j-1)+dm->numLoopData, 1);
+ }
- if(mat_ofs) {
- mf->mat_nr += mat_ofs;
- CLAMP(mf->mat_nr, 0, mat_nr_max);
- }
+ if(mat_ofs) {
+ 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;
}
}
@@ -436,12 +437,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* same as EM_solidify() in editmesh_lib.c */
float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
float *vert_accum= vert_angles + numVerts;
- float face_angles[4];
+ float *face_angles = NULL;
+ BLI_array_staticdeclare(face_angles, 16); /* BM_NGON_STACK_SIZE */
int j, vidx;
- face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
+ face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
if(!face_nors) {
- face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numFaceData);
+ face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
face_nors_calc= 1;
}
@@ -452,31 +454,31 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
}
- for(i=0, mf=mface; i<numFaces; i++, mf++) {
-
+ for (i=0, mp=mpoly; i<numFaces; i++, mp++) {
+ mesh_calc_poly_normal(mp, &mloop[mp->loopstart], mvert, face_nors[i]);
+
/* just added, calc the normal */
- if(face_nors_calc) {
- if(mf->v4)
- normal_quad_v3(face_nors[i], mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
- else
- normal_tri_v3(face_nors[i] , mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
+ BLI_array_empty(face_angles);
+ for (j=0, ml=mloop+mp->loopstart; j<mp->totloop; j++, ml++) {
+ MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j);
+ MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j);
+
+ float e1[3], e2[3], angle;
+
+ sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co);
+ sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co);
+ angle = M_PI - angle_normalized_v3v3(e1, e2);
+ BLI_array_append(face_angles, angle);
}
-
- 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) {
@@ -554,19 +556,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
const unsigned char crease_outer= smd->crease_outer * 255.0f;
const unsigned char crease_inner= smd->crease_inner * 255.0f;
- const int edge_indices[2][4][4] = {
- /* quad */
- {{1, 0, 0, 1},
- {2, 1, 1, 2},
- {3, 2, 2, 3},
- {0, 3, 3, 0}},
- /* tri */
- {{1, 0, 0, 1},
- {2, 1, 1, 2},
- {0, 2, 2, 0},
- {0, 0, 0, 0}} /* unused for tris */
- };
-
/* add faces & edges */
origindex= result->getEdgeDataArray(result, CD_ORIGINDEX);
ed= medge + (numEdges * 2);
@@ -582,13 +571,16 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
/* faces */
- mf= mface + (numFaces * 2);
-
- for(i=0; i<newFaces; i++, mf++) {
+ edge_origIndex = origindex;
+ origindex = DM_get_poly_data_layer(result, CD_ORIGINDEX);
+
+ mp = mpoly + (numFaces * 2);
+ ml = mloop + (numLoops * 2);
+ j = 0;
+ for(i=0; i<newFaces; i++, mp++) {
int eidx= new_edge_arr[i];
int fidx= edge_users[eidx];
- int flip;
- int is_tri;
+ int flip, k1, k2;
if(fidx >= numFaces) {
fidx -= numFaces;
@@ -601,31 +593,59 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
ed= medge + eidx;
/* copy most of the face settings */
- DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1);
+ DM_copy_poly_data(dm, result, fidx, (numFaces * 2) + i, 1);
+ mp->loopstart = j+numLoops*2;
+ mp->flag = mpoly[fidx].flag;
- is_tri = (orig_mface[fidx].v4 == 0);
+ /* notice we use 'mp->totloop' which is later overwritten,
+ * we could lookup the original face but theres no point since this is a copy
+ * and will have the same value, just take care when changing order of assignment */
+ k1 = mpoly[fidx].loopstart + ((edge_order[eidx] + 1) % mp->totloop);
+ k2 = mpoly[fidx].loopstart + (edge_order[eidx]);
- if(flip) {
- DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[is_tri][edge_order[eidx]]);
+ mp->totloop = 4;
+
+ CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops*2+j+0, 1);
+ CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops*2+j+1, 1);
+ CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops*2+j+2, 1);
+ CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops*2+j+3, 1);
- mf->v1= ed->v1;
- mf->v2= ed->v2;
- mf->v3= ed->v2 + numVerts;
- mf->v4= ed->v1 + numVerts;
+ if(flip) {
+ ml[j].v = ed->v1;
+ ml[j++].e = eidx;
+
+ ml[j].v = ed->v2;
+ ml[j++].e = numEdges*2 + old_vert_arr[ed->v2];
+
+ ml[j].v = ed->v2+numVerts;
+ ml[j++].e = eidx+numEdges;
+
+ ml[j].v = ed->v1+numVerts;
+ ml[j++].e = numEdges*2 + old_vert_arr[ed->v1];
}
else {
- DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[is_tri][edge_order[eidx]]);
+ ml[j].v = ed->v2;
+ ml[j++].e = eidx;
+
+ ml[j].v = ed->v1;
+ ml[j++].e = numEdges*2 + old_vert_arr[ed->v1];
- mf->v1= ed->v2;
- mf->v2= ed->v1;
- mf->v3= ed->v1 + numVerts;
- mf->v4= ed->v2 + numVerts;
+ ml[j].v = ed->v1+numVerts;
+ ml[j++].e = eidx+numEdges;
+
+ ml[j].v = ed->v2+numVerts;
+ ml[j++].e = numEdges*2 + old_vert_arr[ed->v2];
}
+ if (edge_origIndex) {
+ edge_origIndex[ml[j-3].e] = ORIGINDEX_NONE;
+ edge_origIndex[ml[j-1].e] = ORIGINDEX_NONE;
+ }
+
/* 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);
+ mp->mat_nr += mat_ofs_rim;
+ CLAMP(mp->mat_nr, 0, mat_nr_max);
}
if(crease_outer) {
/* crease += crease_outer; without wrapping */
@@ -642,7 +662,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
#ifdef SOLIDIFY_SIDE_NORMALS
- normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
+ normal_quad_v3(nor, mvert[ml[j-4].v].co, mvert[ml[j-3].v].co, mvert[ml[j-2].v].co, mvert[ml[j-1].v].co);
add_v3_v3(edge_vert_nos[ed->v1], nor);
add_v3_v3(edge_vert_nos[ed->v2], nor);
@@ -671,12 +691,15 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
MEM_freeN(edge_vert_nos);
#endif
- MEM_freeN(new_vert_arr);
- MEM_freeN(new_edge_arr);
+ BLI_array_free(new_vert_arr);
+ BLI_array_free(new_edge_arr);
MEM_freeN(edge_users);
MEM_freeN(edge_order);
}
+ if (old_vert_arr)
+ MEM_freeN(old_vert_arr);
+
/* must recalculate normals with vgroups since they can displace unevenly [#26888] */
if(dvert) {
CDDM_calc_normals(result);
@@ -689,7 +712,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);