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:
-rw-r--r--source/blender/blenkernel/intern/customdata.c2
-rwxr-xr-xsource/blender/blenlib/BLI_smallhash.h42
-rw-r--r--source/blender/bmesh/bmesh.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c38
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c139
-rw-r--r--source/blender/bmesh/operators/bevel.c2
-rwxr-xr-xsource/blender/editors/mesh/knifetool.c29
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c4
-rw-r--r--source/blender/editors/transform/transform.c764
-rw-r--r--source/blender/editors/transform/transform.h15
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 {