diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 25ffcb53144..1d65d254ae6 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -62,6 +62,9 @@ struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me); /* creates a CDDerivedMesh from the given BMEditMesh */ DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me); +/* merge verts */ +DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap); + /* creates a CDDerivedMesh from the given curve object */ struct DerivedMesh *CDDM_from_curve(struct Object *ob); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 6ad43d72177..c3404e35c05 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -51,6 +51,8 @@ #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_pbvh.h" +#include "BLI_array.h" +#include "BLI_smallhash.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -2219,6 +2221,279 @@ void CDDM_calc_normals(DerivedMesh *dm) face_nors, dm->numFaceData); } +#if 0 +/*merge verts + + vtargetmap is a table that maps vertices to target vertices. a value of -1 + indicates a vertex is a target, and is to be kept. + + this is a really horribly written function. ger. - joeedh + + */ +DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CDDerivedMesh *cddm2 = NULL; + MVert *mv, *mvert = NULL; + BLI_array_declare(mvert); + MEdge *me, *medge = NULL; + BLI_array_declare(medge); + MPoly *mp, *mpoly = NULL; + BLI_array_declare(mpoly); + MLoop *ml, *mloop = NULL; + BLI_array_declare(mloop); + SmallHash _hash, *hash=&_hash; + SmallHash _hash2, *hash2=&_hash2; + int *newv = NULL, *newe = NULL, *newl = NULL; + int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL; + BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp); + int i, j, c, totloop, totpoly; + + BLI_smallhash_init(hash); + BLI_smallhash_init(hash2); + +#if 0 + /*split off ngon faces with merges in them*/ + mp = cddm->mpoly; + for (i=0; inumPolyData; i++, mp++) { + ml = cddm->mloop + mp->loopstart; + for (j=0; jtotloop; j++, ml++) { + MLoop *ml2 = NULL; + int k, k1, a; + + if (ml->v == -1) + continue; + + for (k1=0; k1totloop; k1++) { + k = (j + k1) % mp->totloop; + ml2 = cddm->mloop + mp->loopstart + k; + + if (ml == ml2 || ml2->v == -1) + continue; + + if (vtargetmap[ml->v] == ml2->v || vtargetmap[ml2->v] == ml->v) { + MLoop *ml3; + MPoly *mp2; + int s, e, l, tot; + + if (k < j) + SWAP(int, k, j); + + s = j; e = k; tot = 0; + l = BLI_array_count(mloop); + ml3 = cddm->mloop + mp->loopstart + s; + for (a=s; av == -1) + continue; + + BLI_smallhash_insert(hash, dm->numLoopData + BLI_array_count(mloop), SET_INT_IN_POINTER(mp->loopstart + a - s)); + BLI_array_append(mloop, *ml3); + + ml3->v = -1; + ml3->e = -1; + tot++; + } + + if (!tot) + continue; + + BLI_smallhash_insert(hash2, dm->numPolyData + BLI_array_count(mpoly), SET_INT_IN_POINTER(i)); + + mp2 = BLI_array_append(mpoly, *mp); + mp2->loopstart = l + dm->numLoopData; + mp2->totloop = tot; + } + } + } + } + + ml = MEM_callocN(sizeof(MLoop)*(dm->numLoopData + BLI_array_count(mloop)), "merge mloop"); + mp = MEM_callocN(sizeof(MPoly)*(dm->numPolyData + BLI_array_count(mloop)), "merge mpoly"); + + memcpy(ml, cddm->mloop, sizeof(MLoop)*dm->numLoopData); + memcpy(mp, cddm->mpoly, sizeof(MPoly)*dm->numPolyData); + + cddm->mloop = ml; cddm->mpoly = mp; + + memcpy(cddm->mloop+dm->numLoopData, mloop, sizeof(MLoop)*BLI_array_count(mloop)); + memcpy(cddm->mpoly+dm->numPolyData, mpoly, sizeof(MPoly)*BLI_array_count(mpoly)); + + totloop = dm->numLoopData + BLI_array_count(mloop); + totpoly = dm->numPolyData + BLI_array_count(mpoly); + + BLI_array_empty(mloop); + BLI_array_empty(mpoly); +#else + totloop = dm->numLoopData; + totpoly = dm->numPolyData; +#endif + + newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts"); + newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts"); + newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts"); + + mv = cddm->mvert; + c = 0; + for (i=0; inumVertData; i++, mv++) { + if (vtargetmap[i] == -1) { + BLI_array_append(oldv, i); + newv[i] = c++; + BLI_array_append(mvert, *mv); + } + } + + /*find-replace merged vertices with target vertices*/ + ml = cddm->mloop; + c = 0; + for (i=0; iv == -1) + continue; + + if (vtargetmap[ml->v] != -1) { + me = &cddm->medge[ml->e]; + if (me->v1 == ml->v) + me->v1 = vtargetmap[ml->v]; + else + me->v2 = vtargetmap[ml->v]; + + ml->v = vtargetmap[ml->v]; + } + } + + /*now go through and fix edges and faces*/ + me = cddm->medge; + c = 0; + for (i=0; inumEdgeData; i++, me++) { + if (me->v1 == me->v2) + continue; + + BLI_array_append(olde, i); + newe[i] = c++; + BLI_array_append(medge, *me); + } + + mp = cddm->mpoly; + for (i=0; imloop + mp->loopstart; + + c = 0; + for (j=0; jtotloop; j++, ml++) { + if (ml->v == -1) + continue; + + me = cddm->medge + ml->e; + if (me->v1 != me->v2) { + BLI_array_append(oldl, j); + BLI_array_append(mloop, *ml); + newl[c] = BLI_array_count(mloop)-1; + c++; + } + } + + if (!c) + continue; + + mp2 = BLI_array_append(mpoly, *mp); + mp2->totloop = c; + mp2->loopstart = BLI_array_count(mloop) - c; + + BLI_array_append(oldp, i); + } + + /*create new cddm*/ + cddm2 = (CDDerivedMesh*) CDDM_new(BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly)); + + /*copy over data. CustomData_add_layer can do this, need to look it up.*/ + memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert)); + memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge)); + memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop)); + memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly)); + + BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly); + mvert = cddm2->mvert; medge = cddm2->medge; mloop = cddm2->mloop; mpoly = cddm2->mpoly; + + /*update edge indices and copy customdata*/ + me = cddm2->medge; + for (i=0; idm.numEdgeData; i++, me++) { + MEdge cpy; + + me->v1 = newv[me->v1]; + me->v2 = newv[me->v2]; + + cpy = *me; + CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1); + *me = cpy; + } + + /*update loop indices and copy customdata*/ + ml = cddm2->mloop; + for (i=0; idm.numLoopData; i++, ml++) { + MLoop cpy; + + ml->e = newe[ml->e]; + ml->v = newv[ml->v]; + + cpy = *ml; + + if (oldl[i] >= dm->numLoopData) + oldl[i] = GET_INT_FROM_POINTER(BLI_smallhash_lookup(hash, (intptr_t)oldl[i])); + + CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1); + *ml = cpy; + } + + /*copy vertex customdata*/ + mv = cddm2->mvert; + for (i=0; idm.numVertData; i++, mv++) { + MVert cpy = *mv; + + CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1); + *mv = cpy; + } + + /*copy poly customdata*/ + mp = cddm2->mpoly; + for (i=0; idm.numPolyData; i++, mp++) { + MPoly cpy = *mp; + + if (oldl[i] >= dm->numPolyData) + oldl[i] = GET_INT_FROM_POINTER(BLI_smallhash_lookup(hash, (intptr_t)oldl[i])); + + CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1); + *mp = cpy; + } + + /*eek! not sure what to do with ORIGINDEX stuff here!!*/ + cddm2->dm.numFaceData = mesh_recalcTesselation(&cddm2->dm.faceData, &cddm2->dm.loopData, &cddm2->dm.polyData, cddm2->mvert, 0, cddm2->dm.numLoopData, cddm2->dm.numPolyData, 1, 0); + cddm2->mface = CustomData_get_layer(&cddm->dm.faceData, CD_MFACE); + + if (newv) + MEM_freeN(newv); + if (newe) + MEM_freeN(newe); + if (newl) + MEM_freeN(newl); + if (oldv) + MEM_freeN(oldv); + if (olde) + MEM_freeN(olde); + if (oldl) + MEM_freeN(oldl); + if (oldp) + MEM_freeN(oldp); + + BLI_smallhash_release(hash); + BLI_smallhash_release(hash2); + + dm->needsFree = 1; + dm->release(dm); + + return (DerivedMesh*)cddm2; +} +#endif + void CDDM_calc_edges(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index fee140809e3..1dde62ded83 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -370,7 +370,7 @@ BMEdge *EDBM_get_edge_for_index(BMEditMesh *tm, int index) BMFace *EDBM_get_face_for_index(BMEditMesh *tm, int index) { - return tm->face_index?tm->face_index[index]:NULL; + return (tm->face_index && indexbm->totface && index>=0) ? tm->face_index[index] : NULL; } /* this replaces the active flag used in uv/face mode */ diff --git a/source/blender/editors/mesh/editbmesh_bvh.c b/source/blender/editors/mesh/editbmesh_bvh.c index 9649576b95e..dfa703512d2 100644 --- a/source/blender/editors/mesh/editbmesh_bvh.c +++ b/source/blender/editors/mesh/editbmesh_bvh.c @@ -652,6 +652,13 @@ static BMFace *edge_ray_cast(BMBVHTree *tree, float *co, float *dir, float *hito return f; } +void scale_point(float *c1, float *p, float s) +{ + sub_v3_v3(c1, p); + mul_v3_fl(c1, s); + add_v3_v3(c1, p); +} + int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d, Object *obedit) { BMFace *f; @@ -668,6 +675,9 @@ int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d, Object *obe mul_v3_fl(co2, 0.5f); VECCOPY(co3, e->v2->co); + scale_point(co1, co2, 0.99); + scale_point(co3, co2, 0.99); + /*ok, idea is to generate rays going from the camera origin to the three points on the edge (v1, mid, v2)*/ sub_v3_v3v3(dir1, origin, co1); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index b26b2af5166..887eeb8c330 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2415,7 +2415,7 @@ static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth { BMFace *efa = EDBM_get_face_for_index(userData, index); - if (!BM_TestHFlag(efa, BM_HIDDEN)) { + if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) { GPU_enable_material(efa->mat_nr+1, NULL); return 1; } diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index 331d6e3a444..7a92242ba74 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -106,11 +106,12 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, BMOIter siter1; BMOperator op; BMVert *v1; - int vector_size=0, a, b; + BMIter iter; bDeformGroup *def, *defb; bDeformGroup **vector_def = NULL; float mtx[4][4], imtx[4][4]; int j; + int vector_size=0, a, b; cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's em = CDDM_To_BMesh(dm, NULL); @@ -133,7 +134,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } if (mmd->mirror_ob) { - float mtx2[4][4], vec[3]; + float mtx2[4][4]; invert_m4_m4(mtx2, mmd->mirror_ob->obmat); mul_m4_m4m4(mtx, ob->obmat, mtx2); @@ -147,7 +148,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, BMO_Exec_Op(bm, &op); BMO_CallOpf(bm, "reversefaces faces=%s", &op, "newout"); - + /*handle vgroup stuff*/ if (mmd->flag & MOD_MIR_VGROUP) { BMO_ITER(v1, &siter1, bm, &op, "newout", BM_VERT) { @@ -181,14 +182,14 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, BMO_Finish_Op(bm, &op); + if (vector_def) MEM_freeN(vector_def); + BMEdit_RecalcTesselation(em); - result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL), 0); + result = CDDM_from_BMEditMesh(em, NULL); BMEdit_Free(em); MEM_freeN(em); - - if (vector_def) MEM_freeN(vector_def); - + return result; }