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/mesh_mapping.c19
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c67
2 files changed, 61 insertions, 25 deletions
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 8d9fbe46f19..974e8118b15 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -30,7 +30,9 @@
#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
+#include "DNA_vec_types.h"
+#include "BLI_buffer.h"
#include "BLI_utildefines.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
@@ -62,6 +64,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create(struct MPoly *mpoly, struct MLoop *mloop,
int i, totuv, nverts;
totuv = 0;
+ bool *winding;
+ BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, 32);
/* generate UvMapVert array */
mp = mpoly;
@@ -72,7 +76,9 @@ UvVertMap *BKE_mesh_uv_vert_map_create(struct MPoly *mpoly, struct MLoop *mloop,
if (totuv == 0)
return NULL;
+ winding = MEM_callocN(sizeof(*winding) * totpoly, "winding");
vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
+
if (!vmap)
return NULL;
@@ -87,6 +93,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create(struct MPoly *mpoly, struct MLoop *mloop,
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, mp->totloop);
+
nverts = mp->totloop;
for (i = 0; i < nverts; i++) {
@@ -95,8 +103,12 @@ UvVertMap *BKE_mesh_uv_vert_map_create(struct MPoly *mpoly, struct MLoop *mloop,
buf->separate = 0;
buf->next = vmap->vert[mloop[mp->loopstart + i].v];
vmap->vert[mloop[mp->loopstart + i].v] = buf;
+
+ copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i].uv);
buf++;
}
+
+ winding[a] = cross_poly_v2((const float (*)[2])tf_uv, (unsigned int)nverts) > 0;
}
}
@@ -123,7 +135,9 @@ UvVertMap *BKE_mesh_uv_vert_map_create(struct MPoly *mpoly, struct MLoop *mloop,
sub_v2_v2v2(uvdiff, uv2, uv);
- if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1]) {
+ if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] &&
+ winding[iterv->f] == winding[v->f])
+ {
if (lastv) lastv->next = next;
else vlist = next;
iterv->next = newvlist;
@@ -141,6 +155,9 @@ UvVertMap *BKE_mesh_uv_vert_map_create(struct MPoly *mpoly, struct MLoop *mloop,
vmap->vert[a] = newvlist;
}
+ MEM_freeN(winding);
+ BLI_buffer_free(&tf_uv_buf);
+
return vmap;
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 86cd75eed7a..1875689415a 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -37,6 +37,7 @@
#include "BLI_math.h"
#include "BLI_alloca.h"
+#include "BLI_buffer.h"
#include "BLI_listbase.h"
#include "BKE_DerivedMesh.h"
@@ -625,11 +626,14 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, bool use_select, const float limit[2
/* MTexPoly *tf; */ /* UNUSED */
MLoopUV *luv;
unsigned int a;
- int totverts, i, totuv;
+ int totverts, i, totuv, totfaces;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ bool *winding;
+ BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ totfaces = bm->totface;
totverts = bm->totvert;
totuv = 0;
@@ -650,17 +654,18 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, bool use_select, const float limit[2
vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totverts, "UvMapVert_pt");
buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * totuv, "UvMapVert");
+ winding = MEM_callocN(sizeof(*winding) * totfaces, "winding");
if (!vmap->vert || !vmap->buf) {
BKE_mesh_uv_vert_map_free(vmap);
return NULL;
}
- a = 0;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) {
if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa->len);
+
+ BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i) {
buf->tfindex = i;
buf->f = a;
buf->separate = 0;
@@ -668,17 +673,18 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, bool use_select, const float limit[2
buf->next = vmap->vert[BM_elem_index_get(l->v)];
vmap->vert[BM_elem_index_get(l->v)] = buf;
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ copy_v2_v2(tf_uv[i], luv->uv);
+
buf++;
- i++;
}
- }
- a++;
+ winding[a] = cross_poly_v2((const float (*)[2])tf_uv, efa->len) > 0;
+ }
}
/* sort individual uvs for each vert */
- a = 0;
- BM_ITER_MESH (ev, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, a) {
UvMapVert *newvlist = NULL, *vlist = vmap->vert[a];
UvMapVert *iterv, *v, *lastv, *next;
float *uv, *uv2, uvdiff[2];
@@ -710,7 +716,9 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, bool use_select, const float limit[2
sub_v2_v2v2(uvdiff, uv2, uv);
- if (fabsf(uvdiff[0]) < limit[0] && fabsf(uvdiff[1]) < limit[1]) {
+ if (fabsf(uvdiff[0]) < limit[0] && fabsf(uvdiff[1]) < limit[1] &&
+ winding[iterv->f] == winding[v->f])
+ {
if (lastv) lastv->next = next;
else vlist = next;
iterv->next = newvlist;
@@ -727,9 +735,11 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, bool use_select, const float limit[2
}
vmap->vert[a] = newvlist;
- a++;
}
+ MEM_freeN(winding);
+ BLI_buffer_free(&tf_uv_buf);
+
return vmap;
}
@@ -755,9 +765,11 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
UvElement *islandbuf;
/* island number for faces */
int *island_number;
+ bool *winding;
+ BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
MLoopUV *luv;
- int totverts, i, totuv, j, nislands = 0, islandbufsize = 0;
+ int totverts, totfaces, i, totuv, j, nislands = 0, islandbufsize = 0;
unsigned int *map;
BMFace **stack;
@@ -767,13 +779,12 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ totfaces = bm->totface;
totverts = bm->totvert;
totuv = 0;
- island_number = MEM_mallocN(sizeof(*stack) * bm->totface, "uv_island_number_face");
- if (!island_number) {
- return NULL;
- }
+ island_number = MEM_mallocN(sizeof(*stack) * totfaces, "uv_island_number_face");
+ winding = MEM_callocN(sizeof(*winding) * totfaces, "winding");
/* generate UvElement array */
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
@@ -801,10 +812,11 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
return NULL;
}
- j = 0;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- island_number[j++] = INVALID_ISLAND;
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, j) {
+ island_number[j] = INVALID_ISLAND;
if (!selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa->len);
+
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
buf->l = l;
buf->separate = 0;
@@ -814,14 +826,18 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
buf->next = element_map->vert[BM_elem_index_get(l->v)];
element_map->vert[BM_elem_index_get(l->v)] = buf;
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ copy_v2_v2(tf_uv[i], luv->uv);
+
buf++;
}
+
+ winding[j] = cross_poly_v2((const float (*)[2])tf_uv, efa->len) > 0;
}
}
/* sort individual uvs for each vert */
- i = 0;
- BM_ITER_MESH (ev, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, i) {
UvElement *newvlist = NULL, *vlist = element_map->vert[i];
UvElement *iterv, *v, *lastv, *next;
float *uv, *uv2, uvdiff[2];
@@ -848,7 +864,8 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
sub_v2_v2v2(uvdiff, uv2, uv);
- if (fabsf(uvdiff[0]) < STD_UV_CONNECT_LIMIT && fabsf(uvdiff[1]) < STD_UV_CONNECT_LIMIT) {
+ if (fabsf(uvdiff[0]) < STD_UV_CONNECT_LIMIT && fabsf(uvdiff[1]) < STD_UV_CONNECT_LIMIT &&
+ winding[BM_elem_index_get(iterv->l->f)] == winding[BM_elem_index_get(v->l->f)]) {
if (lastv) lastv->next = next;
else vlist = next;
iterv->next = newvlist;
@@ -865,7 +882,6 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
}
element_map->vert[i] = newvlist;
- i++;
}
if (do_islands) {
@@ -958,7 +974,10 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const boo
MEM_freeN(stack);
MEM_freeN(map);
}
+
MEM_freeN(island_number);
+ MEM_freeN(winding);
+ BLI_buffer_free(&tf_uv_buf);
return element_map;
}