diff options
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 2 | ||||
-rwxr-xr-x | source/blender/blenlib/BLI_smallhash.h | 42 | ||||
-rw-r--r-- | source/blender/bmesh/bmesh.h | 8 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_interp.c | 38 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 139 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bevel.c | 2 | ||||
-rwxr-xr-x | source/blender/editors/mesh/knifetool.c | 29 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 4 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 764 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 15 |
11 files changed, 333 insertions, 714 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index f94cb3ec347..98d33e208bc 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -589,6 +589,7 @@ static void layerCopy_mdisps(const void *source, void *dest, int count) static void layerValidate_mdisps(void *data, int sub_elements) { +#if 0 MDisps *disps = data; if(disps->disps) { int corners = multires_mdisp_corners(disps); @@ -599,6 +600,7 @@ static void layerValidate_mdisps(void *data, int sub_elements) disps->disps = BLI_cellalloc_calloc(3*disps->totdisp*sizeof(float), "layerValidate_mdisps"); } } +#endif } static void layerFree_mdisps(void *data, int count, int UNUSED(size)) diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h index a9b0e34bf89..1c1cd2a0ed3 100755 --- a/source/blender/blenlib/BLI_smallhash.h +++ b/source/blender/blenlib/BLI_smallhash.h @@ -36,11 +36,13 @@ #include "MEM_guardedalloc.h" #include "BLO_sys_types.h" #include "BLI_utildefines.h" +#include <string.h> extern unsigned int hashsizes[]; #define NONHASH -25436536 -typedef struct entry {intptr_t key; void *val;} entry; +typedef struct entry {uintptr_t key; void *val;} entry; +/*how much stack space to use before dynamically allocating memory*/ #define SMSTACKSIZE 521 typedef struct SmallHash { entry *table, _stacktable[SMSTACKSIZE], _copytable[SMSTACKSIZE]; @@ -50,6 +52,11 @@ typedef struct SmallHash { int size; } SmallHash; +typedef struct SmallHashIter { + SmallHash *hash; + int i; +} SmallHashIter; + /*CELL_UNUSED means this cell is inside a key series, while CELL_FREE means this cell terminates a key series. @@ -89,7 +96,7 @@ BM_INLINE void BLI_smallhash_release(SmallHash *hash) MEM_freeN(hash->table); } -BM_INLINE void BLI_smallhash_insert(SmallHash *hash, intptr_t key, void *item) +BM_INLINE void BLI_smallhash_insert(SmallHash *hash, uintptr_t key, void *item) { int h, hoff=1; @@ -145,7 +152,7 @@ BM_INLINE void BLI_smallhash_insert(SmallHash *hash, intptr_t key, void *item) hash->used++; } -BM_INLINE void BLI_smallhash_remove(SmallHash *hash, intptr_t key) +BM_INLINE void BLI_smallhash_remove(SmallHash *hash, uintptr_t key) { int h, hoff=1; @@ -165,7 +172,7 @@ BM_INLINE void BLI_smallhash_remove(SmallHash *hash, intptr_t key) hash->table[h].val = CELL_UNUSED; } -BM_INLINE void *BLI_smallhash_lookup(SmallHash *hash, intptr_t key) +BM_INLINE void *BLI_smallhash_lookup(SmallHash *hash, uintptr_t key) { int h, hoff=1; @@ -187,7 +194,7 @@ BM_INLINE void *BLI_smallhash_lookup(SmallHash *hash, intptr_t key) } -BM_INLINE int BLI_smallhash_haskey(SmallHash *hash, intptr_t key) +BM_INLINE int BLI_smallhash_haskey(SmallHash *hash, uintptr_t key) { int h = ABS(key), hoff=1; key = ABS(key); @@ -211,4 +218,29 @@ BM_INLINE int BLI_smallhash_count(SmallHash *hash) return hash->used; } +BM_INLINE void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) +{ + while (iter->i < iter->hash->size) { + if (iter->hash->table[iter->i].val != CELL_UNUSED && iter->hash->table[iter->i].val != CELL_FREE) { + if (key) + *key = iter->hash->table[iter->i].key; + + iter->i++; + return iter->hash->table[iter->i-1].val; + } + + iter->i++; + } + + return NULL; +} + +BM_INLINE void *BLI_smallhash_iternew(SmallHash *hash, SmallHashIter *iter, uintptr_t *key) +{ + iter->hash = hash; + iter->i = 0; + + return BLI_smallhash_iternext(iter, key); +} + #endif // BLI_SMALLHASH_H diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 08457db4a40..daaf14ee243 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -219,6 +219,11 @@ int BM_Dissolve_Disk ( BMesh *bm, BMVert *v ); (e.g. if the vert is part of a wire edge, etc).*/ int BM_Dissolve_Vert ( BMesh *bm, BMVert *v ); +/*Projects co onto face f, and returns true if it is inside + the face bounds. Note that this uses a best-axis projection + test, instead of projecting co directly into f's orientation + space, so there might be accuracy issues.*/ +int BM_Point_In_Face(BMesh *bm, BMFace *f, float co[3]); /*Interpolation*/ @@ -228,7 +233,8 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source); /*projects a single loop, target, onto source for customdata interpolation. multires is handled. if do_vertex is true, target's vert data will also get interpolated.*/ -void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, int do_vertex); +void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, + int do_vertex, int do_multires); /*smoothes boundaries between multires grids, including some borders in adjacent faces*/ void BM_multires_smooth_bounds(BMesh *bm, BMFace *f); diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 864ff3a94fc..e33d7fd9862 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -657,17 +657,18 @@ void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source) bmesh_loop_interp_mdisps(bm, target, source); } -void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, int do_vertex) +void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, + int do_vertex, int do_multires) { BMLoop *l; void **blocks=NULL; void **vblocks=NULL; - float (*cos)[3]=NULL, *w=NULL, cent[3] = {0.0f, 0.0f, 0.0f}; + float (*cos)[3]=NULL, co[3], *w=NULL, cent[3] = {0.0f, 0.0f, 0.0f}; BLI_array_staticdeclare(cos, 64); BLI_array_staticdeclare(w, 64); BLI_array_staticdeclare(blocks, 64); BLI_array_staticdeclare(vblocks, 64); - int i; + int i, xn, yn, zn, ax, ay; BM_Copy_Attributes(bm, bm, source, target->f); @@ -686,18 +687,37 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, int do_ l = l->next; } while (l != bm_firstfaceloop(source)); + /* find best projection of face XY, XZ or YZ: barycentric weights of + the 2d projected coords are the same and faster to compute */ + xn= (float)fabs(source->no[0]); + yn= (float)fabs(source->no[1]); + zn= (float)fabs(source->no[2]); + if(zn>=xn && zn>=yn) {ax= 0; ay= 1;} + else if(yn>=xn && yn>=zn) {ax= 0; ay= 2;} + else {ax= 1; ay= 2;} + /*scale source face coordinates a bit, so points sitting directonly on an edge will work.*/ mul_v3_fl(cent, 1.0f/(float)source->len); for (i=0; i<source->len; i++) { - float vec[3]; + float vec[3], tmp[3]; sub_v3_v3v3(vec, cent, cos[i]); - mul_v3_fl(vec, 0.0001); + mul_v3_fl(vec, 0.001); add_v3_v3(cos[i], vec); + + copy_v3_v3(tmp, cos[i]); + cos[i][0] = tmp[ax]; + cos[i][1] = tmp[ay]; + cos[i][2] = 0.0; } + /*interpolate*/ - interp_weights_poly_v3(w, cos, source->len, target->v->co); + co[0] = target->v->co[ax]; + co[1] = target->v->co[ay]; + co[2] = 0.0f; + + interp_weights_poly_v3(w, cos, source->len, co); CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data); if (do_vertex) CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data); @@ -706,8 +726,10 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, int do_ BLI_array_free(w); BLI_array_free(blocks); - if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { - bmesh_loop_interp_mdisps(bm, target, source); + if (do_multires) { + if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { + bmesh_loop_interp_mdisps(bm, target, source); + } } } diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 1ebfd481a4d..68be8e8127b 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -310,13 +310,13 @@ BMFace *BM_Split_Face(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl, l = bm_firstfaceloop(f); do { - BM_loop_interp_from_face(bm, l, of, 0); + BM_loop_interp_from_face(bm, l, of, 0, 1); l = l->next; } while (l != bm_firstfaceloop(f)); l = bm_firstfaceloop(nf); do { - BM_loop_interp_from_face(bm, l, of, 0); + BM_loop_interp_from_face(bm, l, of, 0, 1); l = l->next; } while (l != bm_firstfaceloop(nf)); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index acdbc6473f8..b33e708f7eb 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -547,69 +547,106 @@ int linecrosses(double *v1, double *v2, double *v3, double *v4) int linecrossesf(float *v1, float *v2, float *v3, float *v4) { int w1, w2, w3, w4, w5 /*, ret*/; + float mv1[2], mv2[2], mv3[2], mv4[2]; -/* int test1_a, test1_a, test2_a, test2_a; - - test1_a = check_tri_clock_dir(l1p1, l1p2, l2p1); - test1_b = check_tri_clock_dir(l1p1, l1p2, l2p2); - if (test1_a != test1_b) - { - test2_a = check_tri_clock_dir(l2p1, l2p2, l1p1); - test2_b = check_tri_clock_dir(l2p1, l2p2, l1p2); - if (test2_a != test2_b) - { - return 1; - } - }*/ - /*w1 = testedgesidef(v1, v2, v3); - w2 = testedgesidef(v1, v2, v4); - if(w1 != w2) { - w3 = testedgesidef(v3, v4, v1); - w4 = testedgesidef(v3, v4, v2); - if (w3 != w4) return 1; - } - - return 0;*/ - - /*w1 = testedgesidef(v1, v3, v4); - w2 = testedgesidef(v2, v3, v4); - w3 = testedgesidef(v3, v1, v2); - w4 = testedgesidef(v4, v1, v2); + /*now test winding*/ + w1 = testedgesidef(v1, v3, v2); + w2 = testedgesidef(v2, v4, v1); + w3 = !testedgesidef(v1, v2, v3); + w4 = testedgesidef(v3, v2, v4); + w5 = !testedgesidef(v3, v1, v4); + + if (w1 == w2 && w2 == w3 && w3 == w4 && w4==w5) + return 1; + +#define GETMIN2_AXIS(a, b, ma, mb, axis) ma[axis] = MIN2(a[axis], b[axis]), mb[axis] = MAX2(a[axis], b[axis]) +#define GETMIN2(a, b, ma, mb) GETMIN2_AXIS(a, b, ma, mb, 0); GETMIN2_AXIS(a, b, ma, mb, 1); + + GETMIN2(v1, v2, mv1, mv2); + GETMIN2(v3, v4, mv3, mv4); - return (w1 == w2) && (w2 == w3) && (w3 == w4);*/ - /*do an interval test on the x and y axes*/ /*first do x axis*/ - #define T 0.01 + #define T FLT_EPSILON*15 if (ABS(v1[1]-v2[1]) < T && ABS(v3[1]-v4[1]) < T && - ABS(v1[1]-v3[1]) < T) { - if (v3[0] >= v1[0] && v3[0] <= v2[0]) - return 1; - if (v4[0] >= v1[0] && v4[0] <= v2[0]) - return 1; - if (v3[0] <= v1[0] && v4[0] >= v2[0]) - return 1; + ABS(v1[1]-v3[1]) < T) + { + return (mv4[0] >= mv1[0] && mv3[0] <= mv2[0]); } /*now do y axis*/ if (ABS(v1[0]-v2[0]) < T && ABS(v3[0]-v4[0]) < T && - ABS(v1[0]-v3[0]) < T) { - if (v3[1] >= v1[1] && v3[1] <= v2[1]) - return 1; - if (v4[1] >= v1[1] && v4[1] <= v2[1]) - return 1; - if (v3[1] <= v1[1] && v4[1] >= v2[1]) - return 1; + ABS(v1[0]-v3[0]) < T) + { + return (mv4[1] >= mv1[1] && mv3[1] <= mv2[1]); } - /*now test winding*/ - w1 = testedgesidef(v1, v3, v2); - w2 = testedgesidef(v2, v4, v1); - w3 = !testedgesidef(v1, v2, v3); - w4 = testedgesidef(v3, v2, v4); - w5 = !testedgesidef(v3, v1, v4); + return 0; +} - return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5; +/* + BM POINT IN FACE + + Projects co onto face f, and returns true if it is inside + the face bounds. Note that this uses a best-axis projection + test, instead of projecting co directly into f's orientation + space, so there might be accuracy issues. +*/ +int BM_Point_In_Face(BMesh *bm, BMFace *f, float co[3]) +{ + int xn, yn, zn, ax, ay; + float co2[3], cent[3] = {0.0f, 0.0f}, out[3] = {FLT_MAX*0.5f, FLT_MAX*0.5f, 0}; + BMLoop *l; + int crosses = 0; + float eps = 1.0+FLT_EPSILON*150; + + if (dot_v3v3(f->no, f->no) <= FLT_EPSILON*10) + BM_Face_UpdateNormal(bm, f); + + /* find best projection of face XY, XZ or YZ: barycentric weights of + the 2d projected coords are the same and faster to compute + + this probably isn't all that accurate, but it has the advantage of + being fast (especially compared to projecting into the face orientation) + */ + xn= (float)fabs(f->no[0]); + yn= (float)fabs(f->no[1]); + zn= (float)fabs(f->no[2]); + if(zn>=xn && zn>=yn) {ax= 0; ay= 1;} + else if(yn>=xn && yn>=zn) {ax= 0; ay= 2;} + else {ax= 1; ay= 2;} + + co2[0] = co[ax]; + co2[1] = co[ay]; + co2[2] = 0; + + l = bm_firstfaceloop(f); + do { + cent[0] += l->v->co[ax]; + cent[1] += l->v->co[ay]; + l = l->next; + } while (l != bm_firstfaceloop(f)); + + mul_v2_fl(cent, 1.0/(float)f->len); + + l = bm_firstfaceloop(f); + do { + float v1[3], v2[3]; + + v1[0] = (l->prev->v->co[ax] - cent[ax])*eps + cent[ax]; + v1[1] = (l->prev->v->co[ay] - cent[ay])*eps + cent[ay]; + v1[2] = 0.0f; + + v2[0] = (l->v->co[ax] - cent[ax])*eps + cent[ax]; + v2[1] = (l->v->co[ay] - cent[ay])*eps + cent[ay]; + v2[2] = 0.0f; + + crosses += linecrossesf(v1, v2, co2, out) != 0; + + l = l->next; + } while (l != bm_firstfaceloop(f)); + + return crosses%2 != 0; } int goodline(float (*projectverts)[3], BMFace *f, int v1i, diff --git a/source/blender/bmesh/operators/bevel.c b/source/blender/bmesh/operators/bevel.c index 8a5738a12d2..a48faa1e9f3 100644 --- a/source/blender/bmesh/operators/bevel.c +++ b/source/blender/bmesh/operators/bevel.c @@ -646,7 +646,7 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op) if (tag->newv != l->v || HasMDisps) { BM_Copy_Attributes(bm, bm, l->f, l2->f); - BM_loop_interp_from_face(bm, l2, l->f, 1); + BM_loop_interp_from_face(bm, l2, l->f, 1, 1); } else { BM_Copy_Attributes(bm, bm, l->f, l2->f); BM_Copy_Attributes(bm, bm, l, l2); diff --git a/source/blender/editors/mesh/knifetool.c b/source/blender/editors/mesh/knifetool.c index 3f4a5c0b2a7..abb22f56cbb 100755 --- a/source/blender/editors/mesh/knifetool.c +++ b/source/blender/editors/mesh/knifetool.c @@ -513,7 +513,6 @@ static int verge_linehit(const void *vlh1, const void *vlh2) static void knife_add_cut(knifetool_opdata *kcd) { BMEditMesh *em = kcd->em; - BMesh *bm = em->bm; knifetool_opdata oldkcd = *kcd; if (kcd->linehits) { @@ -738,7 +737,7 @@ void _print_smhash(SmallHash *hash) } else if (hash->table[i].val == CELL_FREE) { printf("--f-"); } else { - printf("%2x", (intptr_t)hash->table[i].key); + printf("%2x", (unsigned int)hash->table[i].key); } if (i != hash->size-1) @@ -1284,13 +1283,13 @@ static void remerge_faces(knifetool_opdata *kcd) if (!BMO_TestFlag(bm, f, FACE_NEW)) continue; - if (BLI_smallhash_haskey(visit, f)) + if (BLI_smallhash_haskey(visit, (intptr_t)f)) continue; BLI_array_empty(stack); BLI_array_empty(faces); BLI_array_append(stack, f); - BLI_smallhash_insert(visit, f, NULL); + BLI_smallhash_insert(visit, (intptr_t)f, NULL); do { f2 = BLI_array_pop(stack); @@ -1307,10 +1306,10 @@ static void remerge_faces(knifetool_opdata *kcd) BM_ITER(f3, &fiter, bm, BM_FACES_OF_EDGE, e) { if (!BMO_TestFlag(bm, f3, FACE_NEW)) continue; - if (BLI_smallhash_haskey(visit, f3)) + if (BLI_smallhash_haskey(visit, (intptr_t)f3)) continue; - BLI_smallhash_insert(visit, f3, NULL); + BLI_smallhash_insert(visit, (intptr_t)f3, NULL); BLI_array_append(stack, f3); } } @@ -1451,36 +1450,36 @@ void knifenet_fill_faces(knifetool_opdata *kcd) BMO_SetFlag(bm, f, DEL); for (entry=face_nets[i].first; entry; entry=entry->next) { - if (!BLI_smallhash_haskey(hash, entry->kfe->v1)) { + if (!BLI_smallhash_haskey(hash, (intptr_t)entry->kfe->v1)) { eve = BLI_addfillvert(entry->kfe->v1->v->co); eve->xs = 0; rnd_offset_co(eve->co, rndscale); eve->tmp.p = entry->kfe->v1->v; - BLI_smallhash_insert(hash, entry->kfe->v1, eve); + BLI_smallhash_insert(hash, (intptr_t)entry->kfe->v1, eve); } - if (!BLI_smallhash_haskey(hash, entry->kfe->v2)) { + if (!BLI_smallhash_haskey(hash, (intptr_t)entry->kfe->v2)) { eve = BLI_addfillvert(entry->kfe->v2->v->co); eve->xs = 0; rnd_offset_co(eve->co, rndscale); eve->tmp.p = entry->kfe->v2->v; - BLI_smallhash_insert(hash, entry->kfe->v2, eve); + BLI_smallhash_insert(hash, (intptr_t)entry->kfe->v2, eve); } } for (j=0, entry=face_nets[i].first; entry; entry=entry->next, j++) { EditEdge *eed; - lasteve = BLI_smallhash_lookup(hash, entry->kfe->v1); - eve = BLI_smallhash_lookup(hash, entry->kfe->v2); + lasteve = BLI_smallhash_lookup(hash, (intptr_t)entry->kfe->v1); + eve = BLI_smallhash_lookup(hash, (intptr_t)entry->kfe->v2); eve->xs++; lasteve->xs++; } for (j=0, entry=face_nets[i].first; entry; entry=entry->next, j++) { - lasteve = BLI_smallhash_lookup(hash, entry->kfe->v1); - eve = BLI_smallhash_lookup(hash, entry->kfe->v2); + lasteve = BLI_smallhash_lookup(hash, (intptr_t)entry->kfe->v1); + eve = BLI_smallhash_lookup(hash, (intptr_t)entry->kfe->v2); if (eve->xs > 1 && lasteve->xs > 1) { BLI_addfilledge(lasteve, eve); @@ -1547,7 +1546,7 @@ void knifenet_fill_faces(knifetool_opdata *kcd) BM_Copy_Attributes(bm, bm, f2, f); BM_ITER(l1, &liter1, bm, BM_LOOPS_OF_FACE, f) { - BM_loop_interp_from_face(bm, l1, f2, 1); + BM_loop_interp_from_face(bm, l1, f2, 1, 1); } } diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index a7257d02bda..456e1a390ff 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -434,7 +434,7 @@ static int draw_tface__set_draw_legacy(MTFace *tface, int has_vcol, int matnr) return 1; /* Set color from mcol */ } } -static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) +static int draw_tface__set_draw(MTFace *tface, int has_vcol, int matnr) { if (tface && (tface->mode&TF_INVISIBLE)) return 0; @@ -442,7 +442,7 @@ static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) return 2; /* Don't set color */ } else if (tface && tface->mode&TF_OBCOL) { return 2; /* Don't set color */ - } else if (!mcol) { + } else if (!has_vcol) { return 1; /* Don't set color */ } else { return 1; /* Set color from mcol */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index f4ef67234e0..32ab2ffeb4b 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -94,6 +94,7 @@ #include "BLI_ghash.h" #include "BLI_linklist.h" #include "BLI_smallhash.h" +#include "BLI_array.h" #include "UI_resources.h" @@ -103,6 +104,8 @@ #include "transform.h" +#include <stdio.h> + void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg); int doEdgeSlide(TransInfo *t, float perc); @@ -4275,9 +4278,6 @@ int BoneEnvelope(TransInfo *t, short UNUSED(mval[2])) } /* ******************** Edge Slide *************** */ -#if 0 -static int createSlideVerts(TransInfo *t) { -#else static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e) { BMIter iter; @@ -4375,6 +4375,8 @@ static int createSlideVerts(TransInfo *t) view3d_get_object_project_mat(v3d, t->obedit, projectMat); } + BLI_smallhash_init(&sld->vhash); + BLI_smallhash_init(&sld->origfaces); BLI_smallhash_init(&table); /*ensure valid selection*/ @@ -4408,7 +4410,7 @@ static int createSlideVerts(TransInfo *t) BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { if (BM_TestHFlag(v, BM_SELECT)) { BMINDEX_SET(v, 1); - BLI_smallhash_insert(&table, (intptr_t)v, SET_INT_IN_POINTER(j)); + BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j)); j += 1; } else BMINDEX_SET(v, 0); } @@ -4558,7 +4560,7 @@ static int createSlideVerts(TransInfo *t) continue; - j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (intptr_t)v)); + j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); if (tempsv[j].down) { view3d_project_float_v3(ar, tempsv[j].down->co, vec1, projectMat); @@ -4586,6 +4588,39 @@ static int createSlideVerts(TransInfo *t) } } + em->bm->ob = t->obedit; + bmesh_begin_edit(em->bm, BMOP_UNTAN_MULTIRES); + + /*create copies of faces for customdata projection*/ + tempsv = sld->sv; + for (i=0; i<sld->totsv; i++, tempsv++) { + BMIter fiter, liter; + BMFace *f; + BMLoop *l; + + BM_ITER(f, &fiter, em->bm, BM_FACES_OF_VERT, tempsv->v) { + + if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) { + BMFace *copyf = BM_Copy_Face(em->bm, f, 1, 1); + + BM_Select(em->bm, copyf, 0); + BM_SetHFlag(copyf, BM_HIDDEN); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, copyf) { + BM_Select(em->bm, l->v, 0); + BM_SetHFlag(l->v, BM_HIDDEN); + BM_Select(em->bm, l->e, 0); + BM_SetHFlag(l->e, BM_HIDDEN); + } + + BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf); + } + } + + BLI_smallhash_insert(&sld->vhash, (uintptr_t)tempsv->v, tempsv); + } + + sld->em = em; + /*zero out start*/ zero_v3(start); @@ -4599,515 +4634,100 @@ static int createSlideVerts(TransInfo *t) sld->end[0] = t->mval[0] + end[0]; sld->end[1] = t->mval[1] + end[1]; + sld->perc = 0.0f; + t->customData = sld; BLI_smallhash_release(&table); BMBVH_FreeBVH(btree); return 1; -#endif -#if 0 - Mesh *me = t->obedit->data; - BMEditMesh *em = me->edit_btmesh; - EditFace *efa; - EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL; - EditVert *ev, *nearest = NULL; - LinkNode *edgelist = NULL, *vertlist=NULL, *look; - GHash *vertgh; - TransDataSlideVert *tempsv; - float vertdist; // XXX, projectMat[4][4]; - int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0; - /* UV correction vars */ - GHash **uvarray= NULL; - SlideData *sld = MEM_callocN(sizeof(*sld), "sld"); - int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); - int uvlay_idx; - TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL; - RegionView3D *v3d = t->ar->regiondata; - float projectMat[4][4]; - float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f}; - float vec[3]; - float totvec=0.0; +} - if (!v3d) { - /*ok, let's try to survive this*/ - unit_m4(projectMat); - } else { - view3d_get_object_project_mat(v3d, t->obedit, projectMat); - } +void projectSVData(TransInfo *t, int final) +{ + SlideData *sld = t->customData; + TransDataSlideVert *tempsv; + BMEditMesh *em = sld->em; + SmallHash visit; + int i; - numsel =0; - - // Get number of selected edges and clear some flags - for(eed=em->edges.first;eed;eed=eed->next) { - eed->f1 = 0; - eed->f2 = 0; - if(eed->f & SELECT) numsel++; - } - - for(ev=em->verts.first;ev;ev=ev->next) { - ev->f1 = 0; - } - - //Make sure each edge only has 2 faces - // make sure loop doesn't cross face - for(efa=em->faces.first;efa;efa=efa->next) { - int ct = 0; - if(efa->e1->f & SELECT) { - ct++; - efa->e1->f1++; - if(efa->e1->f1 > 2) { - //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - MEM_freeN(sld); - return 0; - } - } - if(efa->e2->f & SELECT) { - ct++; - efa->e2->f1++; - if(efa->e2->f1 > 2) { - //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - MEM_freeN(sld); - return 0; - } - } - if(efa->e3->f & SELECT) { - ct++; - efa->e3->f1++; - if(efa->e3->f1 > 2) { - //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - MEM_freeN(sld); - return 0; - } - } - if(efa->e4 && efa->e4->f & SELECT) { - ct++; - efa->e4->f1++; - if(efa->e4->f1 > 2) { - //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); - MEM_freeN(sld); - return 0; - } - } - // Make sure loop is not 2 edges of same face - if(ct > 1) { - //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself"); - MEM_freeN(sld); - return 0; - } - } - - // Get # of selected verts - for(ev=em->verts.first;ev;ev=ev->next) { - if(ev->f & SELECT) vertsel++; - } - - // Test for multiple segments - if(vertsel > numsel+1) { - //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop"); - MEM_freeN(sld); - return 0; - } - - // Get the edgeloop in order - mark f1 with SELECT once added - for(eed=em->edges.first;eed;eed=eed->next) { - if((eed->f & SELECT) && !(eed->f1 & SELECT)) { - // If this is the first edge added, just put it in - if(!edgelist) { - BLI_linklist_prepend(&edgelist,eed); - numadded++; - first = eed; - last = eed; - eed->f1 = SELECT; - } else { - if(editedge_getSharedVert(eed, last)) { - BLI_linklist_append(&edgelist,eed); - eed->f1 = SELECT; - numadded++; - last = eed; - } else if(editedge_getSharedVert(eed, first)) { - BLI_linklist_prepend(&edgelist,eed); - eed->f1 = SELECT; - numadded++; - first = eed; - } - } - } - if(eed->next == NULL && numadded != numsel) { - eed=em->edges.first; - timesthrough++; - } - - // It looks like there was an unexpected case - Hopefully should not happen - if(timesthrough >= numsel*2) { - BLI_linklist_free(edgelist,NULL); - //BKE_report(op->reports, RPT_ERROR, "Could not order loop"); - MEM_freeN(sld); - return 0; - } - } - - // Put the verts in order in a linklist - look = edgelist; - while(look) { - eed = look->link; - if(!vertlist) { - if(look->next) { - temp = look->next->link; - - //This is the first entry takes care of extra vert - if(eed->v1 != temp->v1 && eed->v1 != temp->v2) { - BLI_linklist_append(&vertlist,eed->v1); - eed->v1->f1 = 1; - } else { - BLI_linklist_append(&vertlist,eed->v2); - eed->v2->f1 = 1; - } - } else { - //This is the case that we only have 1 edge - BLI_linklist_append(&vertlist,eed->v1); - eed->v1->f1 = 1; - } - } - // for all the entries - if(eed->v1->f1 != 1) { - BLI_linklist_append(&vertlist,eed->v1); - eed->v1->f1 = 1; - } else if(eed->v2->f1 != 1) { - BLI_linklist_append(&vertlist,eed->v2); - eed->v2->f1 = 1; - } - look = look->next; - } - - // populate the SlideVerts - - vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createSlideVerts gh"); - look = vertlist; - while(look) { - i=0; - j=0; - ev = look->link; - tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert"); - tempsv->up = NULL; - tempsv->down = NULL; - tempsv->origvert.co[0] = ev->co[0]; - tempsv->origvert.co[1] = ev->co[1]; - tempsv->origvert.co[2] = ev->co[2]; - tempsv->origvert.no[0] = ev->no[0]; - tempsv->origvert.no[1] = ev->no[1]; - tempsv->origvert.no[2] = ev->no[2]; - // i is total edges that vert is on - // j is total selected edges that vert is on - - for(eed=em->edges.first;eed;eed=eed->next) { - if(eed->v1 == ev || eed->v2 == ev) { - i++; - if(eed->f & SELECT) { - j++; - } - } - } - // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges - if(i == 4 && j == 2) { - for(eed=em->edges.first;eed;eed=eed->next) { - if(editedge_containsVert(eed, ev)) { - if(!(eed->f & SELECT)) { - if(!tempsv->up) { - tempsv->up = eed; - } else if (!(tempsv->down)) { - tempsv->down = eed; - } + if (!em) + return; + + BLI_smallhash_init(&visit); + + for (i=0, tempsv=sld->sv; i<sld->totsv; i++, tempsv++) { + BMIter fiter; + BMFace *f; + + BM_ITER(f, &fiter, em->bm, BM_FACES_OF_VERT, tempsv->v) { + BMIter liter2, fiter2; + BMFace *f2, *copyf, *copyf2; + BMLoop *l2; + int sel, ok, do_vdata; + + if (BLI_smallhash_haskey(&visit, (uintptr_t)f)) + continue; + + BLI_smallhash_insert(&visit, (uintptr_t)f, NULL); + + /*the face attributes of the copied face will get + copied over, so its necessary to save the selection state*/ + sel = BM_TestHFlag(f, BM_SELECT); + + copyf2 = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)f); + + /*project onto copied projection face*/ + BM_ITER(l2, &liter2, em->bm, BM_LOOPS_OF_FACE, f) { + copyf = copyf2; + do_vdata = l2->v==tempsv->v; + + if (BM_TestHFlag(l2->e, BM_SELECT) || BM_TestHFlag(l2->prev->e, BM_SELECT)) { + BMLoop *l3 = l2; + + do_vdata = 1; + + if (!BM_TestHFlag(l2->e, BM_SELECT)) + l3 = l3->prev; + + if (sld->perc < 0.0 && BM_Vert_In_Face(l3->radial_next->f, tempsv->down)) { + copyf = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l3->radial_next->f); + } else if (sld->perc > 0.0 && BM_Vert_In_Face(l3->radial_next->f, tempsv->up)) { + copyf = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l3->radial_next->f); } } - } - } - // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected - if(i >= 3 && j == 1) { - for(eed=em->edges.first;eed;eed=eed->next) { - if(editedge_containsVert(eed, ev) && eed->f & SELECT) { - for(efa = em->faces.first;efa;efa=efa->next) { - if(editface_containsEdge(efa, eed)) { - if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e1; - } else if (!(tempsv->down)) { - tempsv->down = efa->e1; - } - } - if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e2; - } else if (!(tempsv->down)) { - tempsv->down = efa->e2; - } - } - if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e3; - } else if (!(tempsv->down)) { - tempsv->down = efa->e3; - } - } - if(efa->e4) { - if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) { - if(!tempsv->up) { - tempsv->up = efa->e4; - } else if (!(tempsv->down)) { - tempsv->down = efa->e4; - } - } - } + + BM_loop_interp_from_face(em->bm, l2, copyf, do_vdata, 0); - } + if (final) { + BM_loop_interp_multires(em->bm, l2, copyf); + if (copyf2 != copyf) { + BM_loop_interp_multires(em->bm, l2, copyf2); } } } - } - if(i > 4 && j == 2) { - BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(vertlist,NULL); - BLI_linklist_free(edgelist,NULL); - return 0; - } - BLI_ghash_insert(vertgh,ev,tempsv); - - look = look->next; - } - - // make sure the UPs and DOWNs are 'faceloops' - // Also find the nearest slidevert to the cursor - - look = vertlist; - nearest = NULL; - vertdist = -1; - while(look) { - tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); - - if(!tempsv->up || !tempsv->down) { - //BKE_report(op->reports, RPT_ERROR, "Missing rails"); - BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(vertlist,NULL); - BLI_linklist_free(edgelist,NULL); - return 0; - } - - if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { - if(!(tempsv->up->f & SELECT)) { - tempsv->up->f |= SELECT; - tempsv->up->f2 |= 16; - } else { - tempsv->up->f2 |= ~16; - } - if(!(tempsv->down->f & SELECT)) { - tempsv->down->f |= SELECT; - tempsv->down->f2 |= 16; - } else { - tempsv->down->f2 |= ~16; - } - } - - if(look->next != NULL) { - TransDataSlideVert *sv; - ev = (EditVert*)look->next->link; - sv = BLI_ghash_lookup(vertgh, ev); - - if(sv) { - float co[3], co2[3], tvec[3]; - - ev = (EditVert*)look->link; - - if(!sharesFace(em, tempsv->up,sv->up)) { - EditEdge *swap; - swap = sv->up; - sv->up = sv->down; - sv->down = swap; - } - - if (v3d) { - view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat); - view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat); - } - - if (ev == tempsv->up->v1) { - sub_v3_v3v3(tvec, co, co2); - } else { - sub_v3_v3v3(tvec, co2, co); - } - - add_v3_v3(start, tvec); - - if (v3d) { - view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat); - view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat); - } - - if (ev == tempsv->down->v1) { - sub_v3_v3v3(tvec, co2, co); - } else { - sub_v3_v3v3(tvec, co, co2); - } - - add_v3_v3(end, tvec); - - totvec += 1.0f; - nearest = (EditVert*)look->link; - } - } - - - - look = look->next; - } - - add_v3_v3(start, end); - mul_v3_fl(start, 0.5*(1.0/totvec)); - VECCOPY(vec, start); - start[0] = t->mval[0]; - start[1] = t->mval[1]; - add_v3_v3v3(end, start, vec); - - - /* Ensure minimum screen distance, when looking top down on edge loops */ -#define EDGE_SLIDE_MIN 30 - if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) { - if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) { - /* even more exceptional case, points are ontop of eachother */ - end[0]= start[0]; - end[1]= start[1] + EDGE_SLIDE_MIN; - } - else { - sub_v2_v2(end, start); - normalize_v2(end); - mul_v2_fl(end, EDGE_SLIDE_MIN); - add_v2_v2(end, start); + /*make sure face-attributes are correct (e.g. MTexPoly)*/ + BM_Copy_Attributes(em->bm, em->bm, copyf2, f); + + /*restore selection, and undo hidden flag*/ + BM_ClearHFlag(f, BM_HIDDEN); + if (sel) + BM_Select(em->bm, f, sel); } } -#undef EDGE_SLIDE_MIN - - - sld->start[0] = (short) start[0]; - sld->start[1] = (short) start[1]; - sld->end[0] = (short) end[0]; - sld->end[1] = (short) end[1]; - if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) { - int maxnum = 0; - - uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array"); - sld->totuv = uvlay_tot; - suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */ - suv = NULL; - - for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { - - uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createSlideVerts2 gh"); - - for(ev=em->verts.first;ev;ev=ev->next) { - ev->tmp.l = 0; - } - look = vertlist; - while(look) { - float *uv_new; - tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); - - ev = look->link; - suv = NULL; - for(efa = em->faces.first;efa;efa=efa->next) { - if (ev->tmp.l != -1) { /* test for self, in this case its invalid */ - int k=-1; /* face corner */ - - /* Is this vert in the faces corner? */ - if (efa->v1==ev) k=0; - else if (efa->v2==ev) k=1; - else if (efa->v3==ev) k=2; - else if (efa->v4 && efa->v4==ev) k=3; - - if (k != -1) { - MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx); - EditVert *ev_up, *ev_down; - - uv_new = tf->uv[k]; - - if (ev->tmp.l) { - if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001f || fabs(suv->origuv[1]-uv_new[1]) > 0.0001f) { - ev->tmp.l = -1; /* Tag as invalid */ - BLI_linklist_free(suv->fuv_list,NULL); - suv->fuv_list = NULL; - BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL); - suv = NULL; - break; - } - } else { - ev->tmp.l = 1; - suv = suv_last; - - suv->fuv_list = NULL; - suv->uv_up = suv->uv_down = NULL; - suv->origuv[0] = uv_new[0]; - suv->origuv[1] = uv_new[1]; - - BLI_linklist_prepend(&suv->fuv_list, uv_new); - BLI_ghash_insert(uvarray[uvlay_idx],ev,suv); - - suv_last++; /* advance to next slide UV */ - maxnum++; - } - - /* Now get the uvs along the up or down edge if we can */ - if (suv) { - if (!suv->uv_up) { - ev_up = editedge_getOtherVert(tempsv->up,ev); - if (efa->v1==ev_up) suv->uv_up = tf->uv[0]; - else if (efa->v2==ev_up) suv->uv_up = tf->uv[1]; - else if (efa->v3==ev_up) suv->uv_up = tf->uv[2]; - else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3]; - } - if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */ - ev_down = editedge_getOtherVert(tempsv->down,ev); - if (efa->v1==ev_down) suv->uv_down = tf->uv[0]; - else if (efa->v2==ev_down) suv->uv_down = tf->uv[1]; - else if (efa->v3==ev_down) suv->uv_down = tf->uv[2]; - else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3]; - } - - /* Copy the pointers to the face UV's */ - BLI_linklist_prepend(&suv->fuv_list, uv_new); - } - } - } - } - look = look->next; - } - } /* end uv layer loop */ - } /* end uvlay_tot */ - - sld->uvhash = uvarray; - sld->slideuv = slideuvs; - sld->vhash = vertgh; - sld->nearest = nearest; - sld->vertlist = vertlist; - sld->edgelist = edgelist; - sld->suv_last = suv_last; - sld->uvlay_tot = uvlay_tot; - - // we should have enough info now to slide - - t->customData = sld; - - return 1; -#endif + BLI_smallhash_release(&visit); } void freeSlideVerts(TransInfo *t) { -#if 0 - TransDataSlideUv *suv; SlideData *sld = t->customData; - Mesh *me = t->obedit->data; - int uvlay_idx; - + SmallHashIter hiter; + BMFace *copyf; + +#if 0 if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { TransDataSlideVert *tempsv; LinkNode *look = sld->vertlist; @@ -5121,32 +4741,36 @@ void freeSlideVerts(TransInfo *t) look = look->next; } } - - //BLI_ghash_free(edgesgh, freeGHash, NULL); - BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(sld->vertlist, NULL); - BLI_linklist_free(sld->edgelist, NULL); - - if (sld->uvlay_tot) { - for (uvlay_idx=0; uvlay_idx<sld->uvlay_tot; uvlay_idx++) { - BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL); - } - - suv = sld->suv_last-1; - while (suv >= sld->slideuv) { - if (suv->fuv_list) { - BLI_linklist_free(suv->fuv_list,NULL); - } - suv--; - } - - MEM_freeN(sld->slideuv); - MEM_freeN(sld->uvhash); +#endif + + if (!sld) + return; + + /*handle multires reprojection, done + on transform completion since it's + really slow -joeedh*/ + if (t->state != TRANS_CANCEL) { + projectSVData(t, 1); + } else { + sld->perc = 0.0; + projectSVData(t, 0); + } + + copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL); + for (; copyf; copyf=BLI_smallhash_iternext(&hiter, NULL)) { + BM_Kill_Face_Verts(sld->em->bm, copyf); } + + sld->em->bm->ob = t->obedit; + bmesh_end_edit(sld->em->bm, BMOP_UNTAN_MULTIRES); + BLI_smallhash_release(&sld->vhash); + BLI_smallhash_release(&sld->origfaces); + + MEM_freeN(sld->sv); MEM_freeN(sld); + t->customData = NULL; -#endif } void initEdgeSlide(TransInfo *t) @@ -5190,6 +4814,8 @@ int doEdgeSlide(TransInfo *t, float perc) float vec[3]; int i; + sld->perc = perc; + sv = svlist; for (i=0; i<sld->totsv; i++, sv++) { if (perc > 0.0f) { @@ -5202,116 +4828,10 @@ int doEdgeSlide(TransInfo *t, float perc) add_v3_v3v3(sv->v->co, sv->origvert.co, vec); } } - - return 1; -#if 0 - Mesh *me= t->obedit->data; - EditMesh *em = me->edit_mesh; - SlideData *sld = t->customData; - EditVert *ev, *nearest = sld->nearest; - EditVert *centerVert, *upVert, *downVert; - LinkNode *vertlist=sld->vertlist, *look; - GHash *vertgh = sld->vhash; - TransDataSlideVert *tempsv; - float len; - int prop=1, flip=0; - /* UV correction vars */ - GHash **uvarray= sld->uvhash; - int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); - int uvlay_idx; - TransDataSlideUv *suv; - float uv_tmp[2]; - LinkNode *fuv_link; - - tempsv = BLI_ghash_lookup(vertgh,nearest); - - centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); - upVert = editedge_getOtherVert(tempsv->up, centerVert); - downVert = editedge_getOtherVert(tempsv->down, centerVert); - - len = MIN2(perc, len_v3v3(upVert->co,downVert->co)); - len = MAX2(len, 0); - - //Adjust Edgeloop - if(prop) { - look = vertlist; - while(look) { - EditVert *tempev; - ev = look->link; - tempsv = BLI_ghash_lookup(vertgh,ev); - - tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev); - interp_v3_v3v3(ev->co, tempsv->origvert.co, tempev->co, fabs(perc)); - - if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { - for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { - suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev ); - if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) { - interp_v2_v2v2(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc)); - fuv_link = suv->fuv_list; - while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); - fuv_link = fuv_link->next; - } - } - } - } - - look = look->next; - } - } - else { - //Non prop code - look = vertlist; - while(look) { - float newlen, edgelen; - ev = look->link; - tempsv = BLI_ghash_lookup(vertgh,ev); - edgelen = len_v3v3(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co); - newlen = (edgelen != 0.0f)? (len / edgelen): 0.0f; - if(newlen > 1.0) {newlen = 1.0;} - if(newlen < 0.0) {newlen = 0.0;} - if(flip == 0) { - interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen)); - if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { - /* dont do anything if no UVs */ - for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { - suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev ); - if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) { - interp_v2_v2v2(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen)); - fuv_link = suv->fuv_list; - while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); - fuv_link = fuv_link->next; - } - } - } - } - } else{ - interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen)); - - if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { - /* dont do anything if no UVs */ - for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { - suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev ); - if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) { - interp_v2_v2v2(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen)); - fuv_link = suv->fuv_list; - while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); - fuv_link = fuv_link->next; - } - } - } - } - } - look = look->next; - } - - } - + + projectSVData(t, 0); + return 1; -#endif } int EdgeSlide(TransInfo *t, short UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index c01aa89d717..9c9400d034e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -36,6 +36,7 @@ #include "DNA_listBase.h" #include "BLI_editVert.h" +#include "BLI_smallhash.h" #include "BKE_tessmesh.h" /* ************************** Types ***************************** */ @@ -62,6 +63,7 @@ struct wmEvent; struct wmTimer; struct ARegion; struct ReportList; +struct SmallHash; typedef struct NDofInput { int flag; @@ -195,12 +197,6 @@ struct LinkNode; struct EditEdge; struct EditVert; struct GHash; -typedef struct TransDataSlideUv { - float origuv[2]; - float *uv_up, *uv_down; - //float *fuv[4]; - struct LinkNode *fuv_list; -} TransDataSlideUv; typedef struct TransDataSlideVert { struct BMVert vup, vdown; @@ -215,7 +211,10 @@ typedef struct TransDataSlideVert { typedef struct SlideData { TransDataSlideVert *sv; int totsv; - + + struct SmallHash vhash; + struct SmallHash origfaces; + /* TransDataSlideUv *slideuv, *suv_last; int totuv, uvlay_tot; @@ -224,6 +223,8 @@ typedef struct SlideData { struct LinkNode *edgelist, *vertlist; */ short start[2], end[2]; + struct BMEditMesh *em; + float perc; } SlideData; typedef struct TransData { |