Compare commits
137 Commits
temp-keyma
...
soc-2016-u
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2b1ec9c18f | ||
![]() |
5cdd4388ff | ||
![]() |
99c3d1106e | ||
![]() |
2dae9a1596 | ||
![]() |
eb3dab8553 | ||
![]() |
d49a667707 | ||
![]() |
e65b6321f4 | ||
![]() |
e3c00a6ead | ||
![]() |
50fb0ead39 | ||
![]() |
5eb53cc607 | ||
![]() |
c58a276a4f | ||
![]() |
55e60b3a76 | ||
![]() |
ea2331a3dc | ||
![]() |
50aa491f4e | ||
![]() |
f3f2de8d01 | ||
![]() |
120feb30f7 | ||
![]() |
1e2f2ce404 | ||
![]() |
4c3aed02b9 | ||
![]() |
1899762962 | ||
![]() |
3d3e5ae3fd | ||
![]() |
7783ab10b9 | ||
![]() |
969448019e | ||
![]() |
72edbc46ac | ||
![]() |
88388b5bca | ||
![]() |
f7755d6077 | ||
![]() |
e8a902d103 | ||
![]() |
070ab46267 | ||
![]() |
74df8db173 | ||
![]() |
b7224e1392 | ||
![]() |
a36a49c4e8 | ||
![]() |
3dd291fdb6 | ||
![]() |
a5bdf2e2e6 | ||
![]() |
80f71daeb3 | ||
![]() |
c5a2380363 | ||
![]() |
7ad5b81a1c | ||
![]() |
45ed0ee455 | ||
![]() |
51bfcb7f81 | ||
![]() |
1b7b90bd8c | ||
![]() |
245850dc74 | ||
![]() |
dfa8f25de8 | ||
![]() |
f9564ef035 | ||
![]() |
c06f8ee5c8 | ||
![]() |
2233355b98 | ||
![]() |
54d1b151e4 | ||
![]() |
93af992814 | ||
![]() |
0eea6b1556 | ||
![]() |
1829199887 | ||
![]() |
d468e30190 | ||
![]() |
59ca7f55bc | ||
![]() |
366bc79e2a | ||
![]() |
595bb24637 | ||
![]() |
7d69a4f270 | ||
![]() |
6dfd2454d1 | ||
![]() |
7979573bdc | ||
![]() |
ae9f30ee9a | ||
![]() |
923e9d1758 | ||
![]() |
379a57348b | ||
![]() |
9015e4f1f8 | ||
![]() |
d70d5ccf0f | ||
![]() |
39592039be | ||
![]() |
536508f433 | ||
![]() |
a65eef7e95 | ||
![]() |
842ad16b70 | ||
9e5635b8a2 | |||
![]() |
95e2685020 | ||
![]() |
97c2b665ad | ||
![]() |
2c47c627b9 | ||
![]() |
22327e57d7 | ||
![]() |
783e3fe564 | ||
![]() |
bd9978519b | ||
![]() |
2b504a9335 | ||
![]() |
d0cfbc44fe | ||
![]() |
8bccac7ce5 | ||
![]() |
465e381827 | ||
![]() |
e9986e9140 | ||
![]() |
a2f4d70de9 | ||
![]() |
c0b420beb8 | ||
![]() |
177848e73c | ||
![]() |
4c2ead486b | ||
![]() |
a9280bea45 | ||
![]() |
6380451f4b | ||
![]() |
0869346c78 | ||
![]() |
2e690c3f18 | ||
![]() |
dcc8560102 | ||
![]() |
3986f88873 | ||
![]() |
e017975225 | ||
![]() |
cdde7cf132 | ||
![]() |
e456ed0708 | ||
![]() |
f69163f093 | ||
![]() |
c80c28a4da | ||
![]() |
b5f330378c | ||
![]() |
d3f89408c7 | ||
![]() |
36dc52c4d8 | ||
![]() |
d0e5c78095 | ||
![]() |
e9bd9d5efe | ||
![]() |
9519afdec7 | ||
![]() |
0838ca63d3 | ||
![]() |
4eca61a627 | ||
![]() |
2c0fbe86fd | ||
![]() |
aac346662d | ||
![]() |
6a9b37499a | ||
![]() |
1e13733b44 | ||
![]() |
ec48ea9141 | ||
![]() |
a6bfa1c306 | ||
![]() |
3a4a5cc985 | ||
![]() |
a671816e57 | ||
![]() |
22a8a72e6b | ||
![]() |
28db90f9a0 | ||
![]() |
11501865b8 | ||
![]() |
39e21b2a98 | ||
![]() |
f9185c646f | ||
![]() |
8650a733fc | ||
![]() |
61c39a6ed4 | ||
![]() |
a9bf839f22 | ||
![]() |
c8c62bb8b6 | ||
![]() |
106293c16d | ||
![]() |
a2bb48080d | ||
![]() |
2f15dcfa55 | ||
![]() |
4290d75d19 | ||
![]() |
79de3b88f9 | ||
![]() |
2d7ce3a69d | ||
![]() |
76036cd130 | ||
![]() |
a9d0ba4dc2 | ||
![]() |
0ca6fe7e52 | ||
![]() |
d755e8323d | ||
![]() |
4e5693761f | ||
![]() |
087ede5762 | ||
![]() |
b592ca632f | ||
![]() |
eed6abb27d | ||
![]() |
a732f96919 | ||
![]() |
c67be0b14f | ||
![]() |
ecc37c77f8 | ||
![]() |
b7b04095c0 | ||
![]() |
2829ab799f | ||
![]() |
d2d0f8a051 | ||
![]() |
ce1670be25 | ||
![]() |
afa59d100a |
@@ -217,6 +217,8 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
def main(context, operator):
|
||||
obj = context.active_object
|
||||
|
||||
bpy.ops.uv.reveal()
|
||||
|
||||
extend(obj, operator, operator.properties.mode)
|
||||
|
||||
|
||||
@@ -252,4 +254,4 @@ class FollowActiveQuads(Operator):
|
||||
|
||||
classes = (
|
||||
FollowActiveQuads,
|
||||
)
|
||||
)
|
||||
|
@@ -557,7 +557,9 @@ def lightmap_uvpack(meshes,
|
||||
def unwrap(operator, context, **kwargs):
|
||||
|
||||
is_editmode = (context.object.mode == 'EDIT')
|
||||
|
||||
if is_editmode:
|
||||
bpy.ops.uv.reveal()
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
PREF_ACT_ONLY = kwargs.pop("PREF_ACT_ONLY")
|
||||
@@ -672,4 +674,4 @@ class LightMapPack(Operator):
|
||||
|
||||
classes = (
|
||||
LightMapPack,
|
||||
)
|
||||
)
|
||||
|
@@ -750,6 +750,7 @@ def main(context,
|
||||
|
||||
is_editmode = (context.active_object.mode == 'EDIT')
|
||||
if is_editmode:
|
||||
bpy.ops.uv.reveal()
|
||||
obList = [ob for ob in [context.active_object] if ob and ob.type == 'MESH']
|
||||
else:
|
||||
obList = [ob for ob in context.selected_editable_objects if ob and ob.type == 'MESH']
|
||||
|
@@ -130,6 +130,12 @@ class IMAGE_MT_view(Menu):
|
||||
layout.operator("screen.screen_full_area")
|
||||
layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True
|
||||
|
||||
class IMAGE_MT_uvs_select_by_trait(Menu):
|
||||
bl_label = "Select All by Trait"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.operator("uv.select_overlapping")
|
||||
|
||||
class IMAGE_MT_select(Menu):
|
||||
bl_label = "Select"
|
||||
@@ -150,7 +156,10 @@ class IMAGE_MT_select(Menu):
|
||||
|
||||
layout.operator("uv.select_pinned")
|
||||
layout.operator("uv.select_linked").extend = False
|
||||
layout.operator("uv.select_shortest_path")
|
||||
|
||||
layout.separator()
|
||||
layout.menu("IMAGE_MT_uvs_select_by_trait")
|
||||
layout.separator()
|
||||
|
||||
layout.operator("uv.select_less", text="Less")
|
||||
@@ -259,6 +268,16 @@ class IMAGE_MT_uvs_showhide(Menu):
|
||||
layout.operator("uv.hide", text="Hide Selected").unselected = False
|
||||
layout.operator("uv.hide", text="Hide Unselected").unselected = True
|
||||
|
||||
class IMAGE_MT_uvs_deselect_mesh(Menu):
|
||||
bl_label = "De/Select 3D Mesh"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("uv.select_mesh")
|
||||
layout.operator("uv.deselect_mesh", text="Deselect 3D Mesh (Selected)").unselected = False
|
||||
layout.operator("uv.deselect_mesh", text="Deselect 3D Mesh (Unselected)").unselected = True
|
||||
|
||||
|
||||
class IMAGE_MT_uvs_proportional(Menu):
|
||||
bl_label = "Proportional Editing"
|
||||
@@ -357,6 +376,7 @@ class IMAGE_MT_uvs(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("uv.irregular_pack_islands")
|
||||
layout.operator("uv.pack_islands")
|
||||
layout.operator("uv.average_islands_scale")
|
||||
layout.operator("uv.minimize_stretch")
|
||||
@@ -365,6 +385,7 @@ class IMAGE_MT_uvs(Menu):
|
||||
layout.operator("uv.mark_seam", text="Clear Seam").clear = True
|
||||
layout.operator("uv.seams_from_islands")
|
||||
layout.operator("mesh.faces_mirror_uv")
|
||||
layout.operator("uv.scale_to_bounds")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -380,6 +401,9 @@ class IMAGE_MT_uvs(Menu):
|
||||
layout.separator()
|
||||
|
||||
layout.menu("IMAGE_MT_uvs_showhide")
|
||||
|
||||
layout.menu("IMAGE_MT_uvs_deselect_mesh")
|
||||
|
||||
|
||||
|
||||
class IMAGE_MT_uvs_select_mode(Menu):
|
||||
|
@@ -401,6 +401,8 @@ void accumulate_vertex_normals_poly(
|
||||
float **vertnos, const float polyno[3],
|
||||
const float **vertcos, float vdiffs[][3], const int nverts);
|
||||
|
||||
void edge_normal_v2_v2v2(float r[2], const float a[2], const float b[2], const bool left);
|
||||
|
||||
/********************************* Tangents **********************************/
|
||||
|
||||
void tangent_from_uv(
|
||||
|
@@ -4014,6 +4014,23 @@ void accumulate_vertex_normals_poly(float **vertnos, const float polyno[3],
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates the 2d normal for an edge ab.
|
||||
* if left is true calculates the left normal (viewed in winding direction) */
|
||||
void edge_normal_v2_v2v2(float r[2], const float a[2], const float b[2], const bool left)
|
||||
{
|
||||
float dx = b[0] - a[0];
|
||||
float dy = b[1] - a[1];
|
||||
|
||||
if (left) {
|
||||
r[0] = -dy;
|
||||
r[1] = dx;
|
||||
}
|
||||
else {
|
||||
r[0] = dy;
|
||||
r[1] = -dx;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************* Tangents **********************************/
|
||||
|
||||
void tangent_from_uv(
|
||||
|
@@ -128,6 +128,9 @@ void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag);
|
||||
bool BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e,
|
||||
struct ARegion *ar, struct View3D *v3d, struct Object *obedit);
|
||||
|
||||
/* editmesh_path.c*/
|
||||
int EDBM_shortest_path_select(struct bContext *C, struct wmOperator *op);
|
||||
|
||||
/* editmesh_select.c */
|
||||
void EDBM_select_mirrored(
|
||||
struct BMEditMesh *em, const int axis, const bool extend,
|
||||
|
@@ -59,6 +59,8 @@ void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int ma
|
||||
|
||||
bool ED_uvedit_test(struct Object *obedit);
|
||||
|
||||
void ED_uvedit_reveal(struct BMEditMesh *em);
|
||||
|
||||
/* visibility and selection */
|
||||
bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa, struct MTexPoly *tf);
|
||||
bool uvedit_face_select_test(struct Scene *scene, struct BMFace *efa,
|
||||
@@ -106,6 +108,14 @@ void ED_uvedit_unwrap_cube_project(struct Object *ob, struct BMesh *bm, float cu
|
||||
/* single call up unwrap using scene settings, used for edge tag unwrapping */
|
||||
void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel);
|
||||
|
||||
/* select by trait */
|
||||
void ED_uvedit_overlapping_select(struct Scene *scene, struct Object *ob, struct BMesh *bm, const bool extend);
|
||||
|
||||
/* select shortest path */
|
||||
bool ED_uvedit_shortest_path_select(struct Scene *scene, struct Object *ob, struct BMesh *bm, bool topo_dist);
|
||||
|
||||
/* scale to bounds */
|
||||
void ED_uvedit_scale_to_bounds(struct Scene *scene, struct Object *ob, struct BMesh *bm);
|
||||
|
||||
/* uvedit_draw.c */
|
||||
void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]);
|
||||
|
@@ -779,6 +779,11 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
int EDBM_shortest_path_select(struct bContext *C, struct wmOperator *op)
|
||||
{
|
||||
return edbm_shortest_path_select_exec(C, op);
|
||||
}
|
||||
|
||||
void MESH_OT_shortest_path_select(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
|
@@ -222,7 +222,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
|
||||
glBegin(GL_POLYGON);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -260,7 +262,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
|
||||
glBegin(GL_POLYGON);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -323,10 +327,12 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
|
||||
glBegin(GL_POLYGON);
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
|
||||
weight_to_rgb(col, 1.0f - pow2f(1.0f - a));
|
||||
glColor3fv(col);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
|
||||
weight_to_rgb(col, 1.0f - pow2f(1.0f - a));
|
||||
glColor3fv(col);
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -359,7 +365,9 @@ static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset)
|
||||
glBegin(GL_LINE_LOOP);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -372,7 +380,7 @@ static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly)
|
||||
glBegin(GL_LINE_LOOP);
|
||||
mloopuv = &me->mloopuv[mpoly->loopstart];
|
||||
for (i = mpoly->totloop; i != 0; i--, mloopuv++) {
|
||||
glVertex2fv(mloopuv->uv);
|
||||
glVertex2fv(mloopuv->uv); /* We don't check MLOOPUV_HIDDEN here since we always want to see other UVs */
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -537,7 +545,9 @@ static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const i
|
||||
unsigned int j;
|
||||
for (j = 0; j < 3; j++) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while (i != em->tottri && (f == em->looptris[i][0]->f));
|
||||
@@ -813,7 +823,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
|
||||
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -831,9 +843,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
lastsel = sel;
|
||||
}
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
|
||||
glVertex2fv(luv->uv);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
@@ -874,9 +890,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
|
||||
continue;
|
||||
|
||||
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
glVertex2fv(cent);
|
||||
if (uv_poly_visible(efa, cd_loop_uv_offset)) {
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
glVertex2fv(cent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,9 +907,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
|
||||
continue;
|
||||
|
||||
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
glVertex2fv(cent);
|
||||
if (uv_poly_visible(efa, cd_loop_uv_offset)) {
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
glVertex2fv(cent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,7 +935,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
|
||||
if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset) && !(luv->flag & MLOOPUV_HIDDEN))
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
@@ -930,7 +954,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (luv->flag & MLOOPUV_PINNED)
|
||||
if (luv->flag & MLOOPUV_PINNED && !(luv->flag & MLOOPUV_HIDDEN))
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
@@ -948,7 +972,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) && !(luv->flag & MLOOPUV_HIDDEN))
|
||||
glVertex2fv(luv->uv);
|
||||
}
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ bool uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa);
|
||||
/* geometric utilities */
|
||||
void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len);
|
||||
void uv_poly_center(struct BMFace *f, float r_cent[2], const int cd_loop_uv_offset);
|
||||
bool uv_poly_visible(struct BMFace *f, const int cd_loop_uv_offset);
|
||||
|
||||
/* find nearest */
|
||||
|
||||
@@ -59,6 +60,14 @@ typedef struct NearestHit {
|
||||
int lindex; /* index of loop within face */
|
||||
} NearestHit;
|
||||
|
||||
enum {
|
||||
HANDLE_IMPLICIT = (1 << 0),
|
||||
HANDLE_FILL = (1 << 1),
|
||||
HANDLE_SELECTED = (1 << 2),
|
||||
HANDLE_CORRECT_ASPECT = (1 << 3),
|
||||
HANDLE_ALL_FACES = (1 << 4)
|
||||
};
|
||||
|
||||
void uv_find_nearest_vert(struct Scene *scene, struct Image *ima, struct BMEditMesh *em,
|
||||
const float co[2], const float penalty[2], struct NearestHit *hit);
|
||||
void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditMesh *em,
|
||||
@@ -76,9 +85,13 @@ void UV_OT_cylinder_project(struct wmOperatorType *ot);
|
||||
void UV_OT_project_from_view(struct wmOperatorType *ot);
|
||||
void UV_OT_minimize_stretch(struct wmOperatorType *ot);
|
||||
void UV_OT_pack_islands(struct wmOperatorType *ot);
|
||||
void UV_OT_irregular_pack_islands(struct wmOperatorType *ot);
|
||||
void UV_OT_reset(struct wmOperatorType *ot);
|
||||
void UV_OT_sphere_project(struct wmOperatorType *ot);
|
||||
void UV_OT_unwrap(struct wmOperatorType *ot);
|
||||
void UV_OT_stitch(struct wmOperatorType *ot);
|
||||
|
||||
/* XXX (SaphireS): Remove */
|
||||
void UV_OT_test(struct wmOperatorType *ot);
|
||||
|
||||
#endif /* __UVEDIT_INTERN_H__ */
|
||||
|
@@ -407,7 +407,9 @@ bool uvedit_face_select_enable(Scene *scene, BMEditMesh *em, BMFace *efa, const
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -505,8 +507,12 @@ void uvedit_edge_select_enable(BMEditMesh *em, Scene *scene, BMLoop *l, const bo
|
||||
luv1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv2 = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
|
||||
|
||||
luv1->flag |= MLOOPUV_VERTSEL;
|
||||
luv2->flag |= MLOOPUV_VERTSEL;
|
||||
if (!(luv1->flag & MLOOPUV_HIDDEN)) {
|
||||
luv1->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
if (!(luv2->flag & MLOOPUV_HIDDEN)) {
|
||||
luv2->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,7 +588,9 @@ void uvedit_uv_select_enable(BMEditMesh *em, Scene *scene, BMLoop *l,
|
||||
}
|
||||
else {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,6 +639,24 @@ void uv_poly_center(BMFace *f, float r_cent[2], const int cd_loop_uv_offset)
|
||||
mul_v2_fl(r_cent, 1.0f / (float)f->len);
|
||||
}
|
||||
|
||||
bool uv_poly_visible(BMFace *f, const int cd_loop_uv_offset)
|
||||
{
|
||||
BMLoop *l;
|
||||
MLoopUV *luv;
|
||||
BMIter liter;
|
||||
bool visible = false;
|
||||
|
||||
BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return visible;
|
||||
}
|
||||
|
||||
void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len)
|
||||
{
|
||||
int i;
|
||||
@@ -1477,6 +1503,246 @@ static void UV_OT_select_less(wmOperatorType *ot)
|
||||
ot->poll = ED_operator_uvedit_space_image;
|
||||
}
|
||||
|
||||
/*********************** shortest path ***********************/
|
||||
static int uv_shortest_path_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Image *ima = CTX_data_edit_image(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMFace *efa;
|
||||
BMEdge *e;
|
||||
BMIter iter, liter;
|
||||
BMLoop *l;
|
||||
MLoopUV *luv_src = NULL, *luv_dst = NULL;
|
||||
BMElem *elem_src = NULL, *elem_dst = NULL;
|
||||
int elem_sel = 0;
|
||||
const bool topological_distance = RNA_boolean_get(op->ptr, "topological_distance");
|
||||
|
||||
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
return EDBM_shortest_path_select(C, op);
|
||||
}
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
|
||||
|
||||
/* -------- Check for 2 selected elements of same type on the same UV island ---------- */
|
||||
/* Note: Only vertex path computation implemented for now, but Edge/Face checks already there*/
|
||||
if (ts->uv_selectmode & UV_SELECT_FACE) {
|
||||
/* clear tags */
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
}
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
|
||||
if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
|
||||
elem_sel++;
|
||||
|
||||
if (elem_src == NULL) {
|
||||
elem_src = (BMElem *)efa;
|
||||
}
|
||||
else if ((elem_dst == NULL)) {
|
||||
elem_dst = (BMElem *)efa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ts->uv_selectmode & UV_SELECT_EDGE) {
|
||||
/* clear tags */
|
||||
BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
BM_elem_flag_disable(e, BM_ELEM_TAG);
|
||||
}
|
||||
|
||||
BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (uvedit_edge_select_test(scene, e->l, cd_loop_uv_offset)) {
|
||||
|
||||
elem_sel++;
|
||||
|
||||
if (elem_src == NULL) {
|
||||
elem_src = (BMElem *)e;
|
||||
}
|
||||
else if ((elem_dst == NULL)) {
|
||||
elem_dst = (BMElem *)e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (ts->uv_selectmode & UV_SELECT_VERTEX) {
|
||||
/* clear tags */
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_elem_flag_disable(l, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if ((luv->flag & MLOOPUV_VERTSEL) != 0) {
|
||||
if (luv_src == NULL) {
|
||||
luv_src = luv;
|
||||
elem_sel++;
|
||||
}
|
||||
else if ((luv_dst == NULL) && (!compare_v2v2(luv->uv, luv_src->uv, 0.000003f))) {
|
||||
luv_dst = luv;
|
||||
elem_sel++;
|
||||
}
|
||||
else if ((!compare_v2v2(luv->uv, luv_src->uv, 0.000003f)) &&
|
||||
(!compare_v2v2(luv->uv, luv_dst->uv, 0.000003f))) {
|
||||
elem_sel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (elem_sel != 2 || !(ts->uv_selectmode & UV_SELECT_VERTEX)) {
|
||||
/* Not exactly 2 elements of same typ selected */
|
||||
BKE_report(op->reports, RPT_WARNING,
|
||||
"Path selection requires exactly two vertices of the same island to be selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* -------- Now select shortest path between the 2 found elements ---------- */
|
||||
|
||||
if (ED_uvedit_shortest_path_select(scene, obedit, bm, topological_distance)) {
|
||||
|
||||
DAG_id_tag_update(obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
/* No path found because the selected elements aren't part of the same uv island */
|
||||
BKE_report(op->reports, RPT_WARNING,
|
||||
"Path selection requires exactly two vertices of the same island to be selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
static void UV_OT_select_shortest_path(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Select Shortest Vertex Path";
|
||||
ot->description = "Select the shortest path between the current selected vertices";
|
||||
ot->idname = "UV_OT_select_shortest_path";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_shortest_path_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna, "topological_distance", 0, "Topological Distance",
|
||||
"Find the minimum number of steps, ignoring spatial distance");
|
||||
}
|
||||
/* ******************** scale to bounds operator **************** */
|
||||
|
||||
static int uv_scale_to_bounds_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Image *ima = CTX_data_edit_image(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
MTexPoly *tf;
|
||||
float dx, dy, min[2], max[2];
|
||||
|
||||
const bool keep_aspect = RNA_boolean_get(op->ptr, "keep_aspect_ratio");
|
||||
const bool individual = RNA_boolean_get(op->ptr, "individual_islands");
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
|
||||
|
||||
if (individual) {
|
||||
ED_uvedit_scale_to_bounds(scene, obedit, bm);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
INIT_MINMAX2(min, max);
|
||||
|
||||
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (!uvedit_face_visible_test(scene, ima, efa, tf) || !uvedit_face_select_test(scene, efa, cd_loop_uv_offset))
|
||||
continue;
|
||||
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
minmax_v2v2_v2(min, max, luv->uv);
|
||||
}
|
||||
}
|
||||
|
||||
/* rescale UV to be in 1/1 */
|
||||
dx = (max[0] - min[0]);
|
||||
dy = (max[1] - min[1]);
|
||||
|
||||
if (dx > 0.0f)
|
||||
dx = 1.0f / dx;
|
||||
if (dy > 0.0f)
|
||||
dy = 1.0f / dy;
|
||||
|
||||
if (keep_aspect) {
|
||||
if (dx >= dy) dx = dy;
|
||||
else if (dy > dx) dy = dx;
|
||||
}
|
||||
|
||||
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
|
||||
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (!uvedit_face_visible_test(scene, ima, efa, tf) || !uvedit_face_select_test(scene, efa, cd_loop_uv_offset))
|
||||
continue;
|
||||
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
luv->uv[0] = (luv->uv[0] - min[0]) * dx;
|
||||
luv->uv[1] = (luv->uv[1] - min[1]) * dy;
|
||||
}
|
||||
}
|
||||
|
||||
DAG_id_tag_update(obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UV_OT_scale_to_bounds(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Scale To Bounds";
|
||||
ot->description = "Scale the selection to fit UV boundaries";
|
||||
ot->idname = "UV_OT_scale_to_bounds";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_scale_to_bounds_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna, "keep_aspect_ratio", 1, "Keep Aspect Ratio", "Keep the current aspect ratio of the selection");
|
||||
RNA_def_boolean(ot->srna, "individual_islands", 0, "Individual", "Scale individual islands or the selection as a whole");
|
||||
}
|
||||
|
||||
/* ******************** align operator **************** */
|
||||
|
||||
static void uv_weld_align(bContext *C, int tool)
|
||||
@@ -1990,13 +2256,19 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
|
||||
|
||||
switch (action) {
|
||||
case SEL_SELECT:
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) { /* Skip hidden loops */
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
break;
|
||||
case SEL_DESELECT:
|
||||
luv->flag &= ~MLOOPUV_VERTSEL;
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
luv->flag &= ~MLOOPUV_VERTSEL;
|
||||
}
|
||||
break;
|
||||
case SEL_INVERT:
|
||||
luv->flag ^= MLOOPUV_VERTSEL;
|
||||
if (!(luv->flag & MLOOPUV_HIDDEN)) {
|
||||
luv->flag ^= MLOOPUV_VERTSEL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3628,13 +3900,138 @@ static void UV_OT_select_pinned(wmOperatorType *ot)
|
||||
|
||||
/********************** hide operator *********************/
|
||||
|
||||
static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
MLoopUV *luv;
|
||||
MTexPoly *tf;
|
||||
const bool swap = RNA_boolean_get(op->ptr, "unselected");
|
||||
Image *ima = sima ? sima->image : NULL;
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
|
||||
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
EDBM_mesh_hide(em, swap);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
|
||||
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
|
||||
if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if ((luv->flag & MLOOPUV_VERTSEL && !swap) || (!(luv->flag & MLOOPUV_VERTSEL) && swap)) {
|
||||
luv->flag |= MLOOPUV_HIDDEN;
|
||||
luv->flag &= ~MLOOPUV_VERTSEL; /* Deselect after hiding to avoid unwanted behaviour */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BM_select_history_validate(em->bm);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
#undef UV_SEL_TEST
|
||||
|
||||
static void UV_OT_hide(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Hide Selected";
|
||||
ot->description = "Hide (un)selected UV vertices";
|
||||
ot->idname = "UV_OT_hide";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_hide_exec;
|
||||
ot->poll = ED_operator_uvmap;
|
||||
|
||||
/* props */
|
||||
RNA_def_boolean(ot->srna, "unselected", 0, "Hide Unselected", "Hide unselected rather than selected");
|
||||
}
|
||||
|
||||
/****************** reveal operator ******************/
|
||||
|
||||
void ED_uvedit_reveal(BMEditMesh *em)
|
||||
{
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
MLoopUV *luv;
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag &= ~MLOOPUV_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
/* call the mesh function if we are in mesh sync sel */
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
EDBM_mesh_reveal(em);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
ED_uvedit_reveal(em);
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UV_OT_reveal(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Reveal Hidden";
|
||||
ot->description = "Reveal all hidden UV vertices";
|
||||
ot->idname = "UV_OT_reveal";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_reveal_exec;
|
||||
ot->poll = ED_operator_uvmap;
|
||||
}
|
||||
|
||||
/********************** Deselect Mesh operator *********************/
|
||||
|
||||
/* check if we are selected or unselected based on 'bool_test' arg,
|
||||
* needed for select swap support */
|
||||
* needed for select swap support */
|
||||
#define UV_SEL_TEST(luv, bool_test) ((((luv)->flag & MLOOPUV_VERTSEL) == MLOOPUV_VERTSEL) == bool_test)
|
||||
|
||||
/* is every UV vert selected or unselected depending on bool_test */
|
||||
static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test,
|
||||
const int cd_loop_uv_offset)
|
||||
const int cd_loop_uv_offset)
|
||||
{
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
@@ -3650,7 +4047,7 @@ static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
static int uv_deselect_mesh_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -3666,7 +4063,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
Image *ima = sima ? sima->image : NULL;
|
||||
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
|
||||
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
@@ -3676,7 +4073,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
int hide = 0;
|
||||
|
||||
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
|
||||
@@ -3685,7 +4082,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (UV_SEL_TEST(luv, !swap)) {
|
||||
@@ -3696,7 +4093,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
|
||||
if (hide) {
|
||||
/* note, a special case for edges could be used,
|
||||
* for now edges act like verts and get flushed */
|
||||
* for now edges act like verts and get flushed */
|
||||
if (use_face_center) {
|
||||
if (em->selectmode == SCE_SELECT_FACE) {
|
||||
/* check that every UV is selected */
|
||||
@@ -3707,7 +4104,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
else {
|
||||
if (bm_face_is_all_uv_sel(efa, true, cd_loop_uv_offset) == !swap) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (UV_SEL_TEST(luv, !swap)) {
|
||||
BM_vert_select_set(em->bm, l->v, false);
|
||||
@@ -3725,7 +4122,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (UV_SEL_TEST(luv, !swap)) {
|
||||
BM_vert_select_set(em->bm, l->v, false);
|
||||
@@ -3739,7 +4136,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
/* flush vertex selection changes */
|
||||
if (em->selectmode != SCE_SELECT_FACE)
|
||||
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX | SCE_SELECT_EDGE);
|
||||
|
||||
|
||||
BM_select_history_validate(em->bm);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
|
||||
@@ -3748,25 +4145,26 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
|
||||
|
||||
#undef UV_SEL_TEST
|
||||
|
||||
static void UV_OT_hide(wmOperatorType *ot)
|
||||
static void UV_OT_deselect_mesh(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Hide Selected";
|
||||
ot->description = "Hide (un)selected UV vertices";
|
||||
ot->idname = "UV_OT_hide";
|
||||
ot->name = "Deselect 3D Mesh";
|
||||
ot->description = "Deselect 3D mesh vertices corresponding to (un)selected UV vertices";
|
||||
ot->idname = "UV_OT_deselect_mesh";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_hide_exec;
|
||||
ot->exec = uv_deselect_mesh_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
|
||||
/* props */
|
||||
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
|
||||
/* ToDo (SaphireS): Wording ... */
|
||||
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Deselect unselected rather than selected");
|
||||
}
|
||||
|
||||
/****************** reveal operator ******************/
|
||||
/********************** Select Mesh operator *********************/
|
||||
|
||||
static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
static int uv_select_mesh_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -3780,10 +4178,10 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
|
||||
const int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
/* note on tagging, selecting faces needs to be delayed so it doesn't select the verts and
|
||||
* confuse our checks on selected verts. */
|
||||
* confuse our checks on selected verts. */
|
||||
|
||||
/* call the mesh function if we are in mesh sync sel */
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
@@ -3794,10 +4192,10 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
if (use_face_center) {
|
||||
if (em->selectmode == SCE_SELECT_FACE) {
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
@@ -3809,16 +4207,16 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
else {
|
||||
/* enable adjacent faces to have disconnected UV selections if sticky is disabled */
|
||||
if (!stickymode) {
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
int totsel = 0;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
totsel += BM_elem_flag_test(l->v, BM_ELEM_SELECT);
|
||||
}
|
||||
|
||||
|
||||
if (!totsel) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
@@ -3829,10 +4227,10 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT) == 0) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
@@ -3846,10 +4244,10 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
else if (em->selectmode == SCE_SELECT_FACE) {
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
@@ -3859,10 +4257,10 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT) == 0) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
@@ -3873,7 +4271,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* re-select tagged faces */
|
||||
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
|
||||
|
||||
@@ -3882,19 +4280,51 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UV_OT_reveal(wmOperatorType *ot)
|
||||
static void UV_OT_select_mesh(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Reveal Hidden";
|
||||
ot->description = "Reveal all hidden UV vertices";
|
||||
ot->idname = "UV_OT_reveal";
|
||||
ot->name = "Select 3D Mesh";
|
||||
ot->description = "Select all of the 3D mesh vertices";
|
||||
ot->idname = "UV_OT_select_mesh";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_reveal_exec;
|
||||
ot->exec = uv_select_mesh_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
}
|
||||
|
||||
/******************** select overlapping operator ********************/
|
||||
|
||||
static int UV_OT_select_overlapping_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
|
||||
ED_uvedit_overlapping_select(scene, obedit, bm, extend);
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
static void UV_OT_select_overlapping(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Select Overlapping UVs";
|
||||
ot->description = "Select all overlapping UV islands";
|
||||
ot->idname = "UV_OT_select_overlapping";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = UV_OT_select_overlapping_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
|
||||
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend current selection");
|
||||
}
|
||||
|
||||
/******************** set 3d cursor operator ********************/
|
||||
|
||||
static int uv_set_2d_cursor_poll(bContext *C)
|
||||
@@ -4251,10 +4681,13 @@ void ED_operatortypes_uvedit(void)
|
||||
WM_operatortype_append(UV_OT_circle_select);
|
||||
WM_operatortype_append(UV_OT_select_more);
|
||||
WM_operatortype_append(UV_OT_select_less);
|
||||
WM_operatortype_append(UV_OT_select_shortest_path);
|
||||
WM_operatortype_append(UV_OT_select_overlapping);
|
||||
|
||||
WM_operatortype_append(UV_OT_snap_cursor);
|
||||
WM_operatortype_append(UV_OT_snap_selected);
|
||||
|
||||
WM_operatortype_append(UV_OT_scale_to_bounds);
|
||||
WM_operatortype_append(UV_OT_align);
|
||||
|
||||
WM_operatortype_append(UV_OT_stitch);
|
||||
@@ -4271,15 +4704,20 @@ void ED_operatortypes_uvedit(void)
|
||||
WM_operatortype_append(UV_OT_project_from_view);
|
||||
WM_operatortype_append(UV_OT_minimize_stretch);
|
||||
WM_operatortype_append(UV_OT_pack_islands);
|
||||
WM_operatortype_append(UV_OT_irregular_pack_islands);
|
||||
WM_operatortype_append(UV_OT_reset);
|
||||
WM_operatortype_append(UV_OT_sphere_project);
|
||||
WM_operatortype_append(UV_OT_unwrap);
|
||||
|
||||
WM_operatortype_append(UV_OT_reveal);
|
||||
WM_operatortype_append(UV_OT_hide);
|
||||
WM_operatortype_append(UV_OT_deselect_mesh);
|
||||
WM_operatortype_append(UV_OT_select_mesh);
|
||||
|
||||
WM_operatortype_append(UV_OT_cursor_set);
|
||||
WM_operatortype_append(UV_OT_tile_set);
|
||||
|
||||
WM_operatortype_append(UV_OT_test);
|
||||
}
|
||||
|
||||
void ED_keymap_uvedit(wmKeyConfig *keyconf)
|
||||
@@ -4347,6 +4785,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
|
||||
WM_keymap_add_item(keymap, "UV_OT_unwrap", EKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_minimize_stretch", VKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_pack_islands", PKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_irregular_pack_islands", PKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_average_islands_scale", AKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
/* hide */
|
||||
@@ -4355,8 +4794,18 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "unselected", true);
|
||||
|
||||
/* reveal */
|
||||
WM_keymap_add_item(keymap, "UV_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
/* deselect 3d mesh */
|
||||
kmi = WM_keymap_add_item(keymap, "UV_OT_deselect_mesh", HKEY, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_boolean_set(kmi->ptr, "unselected", false);
|
||||
kmi = WM_keymap_add_item(keymap, "UV_OT_deselect_mesh", HKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
|
||||
RNA_boolean_set(kmi->ptr, "unselected", true);
|
||||
|
||||
/* select 3d mesh */
|
||||
WM_keymap_add_item(keymap, "UV_OT_select_mesh", HKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
|
||||
|
||||
/* cursor */
|
||||
WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "UV_OT_tile_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -63,7 +64,8 @@ void param_face_add(ParamHandle *handle,
|
||||
float *uv[4],
|
||||
ParamBool *pin,
|
||||
ParamBool *select,
|
||||
float face_normal[3]);
|
||||
float face_normal[3],
|
||||
int **flag);
|
||||
|
||||
void param_edge_set_seam(ParamHandle *handle,
|
||||
ParamKey *vkeys);
|
||||
@@ -101,6 +103,15 @@ void param_smooth_area(ParamHandle *handle);
|
||||
|
||||
void param_pack(ParamHandle *handle, float margin, bool do_rotate);
|
||||
|
||||
/* Packing 2.0 */
|
||||
|
||||
void param_irregular_pack_begin(ParamHandle *handle, float *w_area, float margin, int rot_step, bool concave);
|
||||
void param_irregular_pack_iter(ParamHandle *handle, float *w_area, unsigned int seed, int rot_step, float margin);
|
||||
void param_irregular_pack_end(ParamHandle *handle);
|
||||
void param_accept_placement_all(ParamHandle *handle);
|
||||
//void param_accept_placement(PChart *chart);
|
||||
void param_restore_placement(ParamHandle *handle, float margin);
|
||||
|
||||
/* Average area for all charts */
|
||||
|
||||
void param_average(ParamHandle *handle);
|
||||
@@ -109,11 +120,26 @@ void param_average(ParamHandle *handle);
|
||||
|
||||
void param_scale(ParamHandle *handle, float x, float y);
|
||||
|
||||
/* Scale to bounds */
|
||||
|
||||
void param_scale_bounds(ParamHandle *handle);
|
||||
|
||||
/* Select shortest Path */
|
||||
|
||||
void param_shortest_path(ParamHandle *handle, bool *p_found, bool topological_distance);
|
||||
|
||||
/* Select Overlapping */
|
||||
|
||||
void param_select_overlapping(ParamHandle *handle, const bool extend);
|
||||
|
||||
/* Flushing */
|
||||
|
||||
void param_flush(ParamHandle *handle);
|
||||
void param_flush_sel(ParamHandle *handle);
|
||||
void param_flush_restore(ParamHandle *handle);
|
||||
|
||||
/* XXX (SaphireS): Remove */
|
||||
void param_test(ParamHandle *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_uvproject.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
@@ -82,6 +83,20 @@
|
||||
#include "uvedit_intern.h"
|
||||
#include "uvedit_parametrizer.h"
|
||||
|
||||
static int set_handle_params(bool implicit, bool fill_holes, bool selected, bool correct_aspect, bool all_faces)
|
||||
{
|
||||
int hparams = 0;
|
||||
|
||||
/* Set flags fpr handle_params */
|
||||
if (implicit) hparams |= HANDLE_IMPLICIT;
|
||||
if (fill_holes) hparams |= HANDLE_FILL;
|
||||
if (selected) hparams |= HANDLE_SELECTED;
|
||||
if (correct_aspect) hparams |= HANDLE_CORRECT_ASPECT;
|
||||
if (all_faces) hparams |= HANDLE_ALL_FACES;
|
||||
|
||||
return hparams;
|
||||
}
|
||||
|
||||
static void modifier_unwrap_state(Object *obedit, Scene *scene, bool *r_use_subsurf)
|
||||
{
|
||||
ModifierData *md;
|
||||
@@ -235,6 +250,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, Scene *scene,
|
||||
ParamBool *select = BLI_array_alloca(select, efa->len);
|
||||
float **co = BLI_array_alloca(co, efa->len);
|
||||
float **uv = BLI_array_alloca(uv, efa->len);
|
||||
int **flag = BLI_array_alloca(flag, efa->len);
|
||||
int i;
|
||||
|
||||
BMIter liter;
|
||||
@@ -251,15 +267,14 @@ static void construct_param_handle_face_add(ParamHandle *handle, Scene *scene,
|
||||
co[i] = l->v->co;
|
||||
uv[i] = luv->uv;
|
||||
pin[i] = (luv->flag & MLOOPUV_PINNED) != 0;
|
||||
flag[i] = &(luv->flag);
|
||||
select[i] = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
|
||||
}
|
||||
|
||||
param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no);
|
||||
param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no, flag);
|
||||
}
|
||||
|
||||
static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm,
|
||||
const bool implicit, const bool fill, const bool sel,
|
||||
const bool correct_aspect)
|
||||
static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm, const int handle_params)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
BMFace *efa;
|
||||
@@ -268,6 +283,12 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm,
|
||||
BMIter iter, liter;
|
||||
int i;
|
||||
|
||||
const bool implicit = handle_params & HANDLE_IMPLICIT;
|
||||
const bool fill = handle_params & HANDLE_FILL;
|
||||
const bool sel = handle_params & HANDLE_SELECTED;
|
||||
const bool correct_aspect = handle_params & HANDLE_CORRECT_ASPECT;
|
||||
const bool all_faces = handle_params & HANDLE_ALL_FACES;
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
|
||||
|
||||
handle = param_construct_begin();
|
||||
@@ -290,7 +311,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (implicit) {
|
||||
if (implicit && !all_faces) {
|
||||
bool is_loopsel = false;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
@@ -325,7 +346,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm,
|
||||
|
||||
|
||||
static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select,
|
||||
Scene *scene, const int cd_loop_uv_offset)
|
||||
int *flag, Scene *scene, const int cd_loop_uv_offset)
|
||||
{
|
||||
BMLoop *l;
|
||||
BMIter liter;
|
||||
@@ -334,6 +355,7 @@ static void texface_from_original_index(BMFace *efa, int index, float **uv, Para
|
||||
*uv = NULL;
|
||||
*pin = 0;
|
||||
*select = 1;
|
||||
*flag = 0;
|
||||
|
||||
if (index == ORIGINDEX_NONE)
|
||||
return;
|
||||
@@ -344,6 +366,7 @@ static void texface_from_original_index(BMFace *efa, int index, float **uv, Para
|
||||
*uv = luv->uv;
|
||||
*pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0;
|
||||
*select = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
|
||||
*flag = luv->flag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -445,6 +468,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
|
||||
ParamBool pin[4], select[4];
|
||||
float *co[4];
|
||||
float *uv[4];
|
||||
int flag[4];
|
||||
BMFace *origFace = faceMap[i];
|
||||
|
||||
if (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
|
||||
@@ -473,12 +497,12 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
|
||||
|
||||
/* This is where all the magic is done. If the vertex exists in the, we pass the original uv pointer to the solver, thus
|
||||
* flushing the solution to the edit mesh. */
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[1].v], &uv[1], &pin[1], &select[1], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[2].v], &uv[2], &pin[2], &select[2], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0], &flag[0], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[1].v], &uv[1], &pin[1], &select[1], &flag[1], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[2].v], &uv[2], &pin[2], &select[2], &flag[2], scene, cd_loop_uv_offset);
|
||||
texface_from_original_index(origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3], &flag[3], scene, cd_loop_uv_offset);
|
||||
|
||||
param_face_add(handle, key, 4, vkeys, co, uv, pin, select, NULL);
|
||||
param_face_add(handle, key, 4, vkeys, co, uv, pin, select, NULL, flag);
|
||||
}
|
||||
|
||||
/* these are calculated from original mesh too */
|
||||
@@ -527,6 +551,8 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op)
|
||||
return false;
|
||||
}
|
||||
|
||||
int hparams = set_handle_params(implicit, fill_holes, true, true, false);
|
||||
|
||||
ms = MEM_callocN(sizeof(MinStretch), "MinStretch");
|
||||
ms->scene = scene;
|
||||
ms->obedit = obedit;
|
||||
@@ -534,7 +560,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op)
|
||||
ms->blend = RNA_float_get(op->ptr, "blend");
|
||||
ms->iterations = RNA_int_get(op->ptr, "iterations");
|
||||
ms->i = 0;
|
||||
ms->handle = construct_param_handle(scene, obedit, em->bm, implicit, fill_holes, 1, 1);
|
||||
ms->handle = construct_param_handle(scene, obedit, em->bm, hparams);
|
||||
ms->lasttime = PIL_check_seconds_timer();
|
||||
|
||||
param_stretch_begin(ms->handle);
|
||||
@@ -712,12 +738,48 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
|
||||
RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively", 0, 100);
|
||||
}
|
||||
|
||||
/* ******************** Select Shortest Path operator **************** */
|
||||
bool ED_uvedit_shortest_path_select(Scene *scene, Object *ob, BMesh *bm, bool topo_dist)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
bool path_found = false;
|
||||
int hparams = set_handle_params(true, false, false, true, true);
|
||||
handle = construct_param_handle(scene, ob, bm, hparams);
|
||||
param_shortest_path(handle, &path_found, topo_dist);
|
||||
param_flush_sel(handle);
|
||||
param_delete(handle);
|
||||
return path_found;
|
||||
}
|
||||
|
||||
/* ******************** Select Overlapping UVs operator **************** */
|
||||
void ED_uvedit_overlapping_select(Scene *scene, Object *ob, BMesh *bm, const bool extend)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
int hparams = set_handle_params(true, false, false, true, true);
|
||||
handle = construct_param_handle(scene, ob, bm, hparams);
|
||||
param_select_overlapping(handle, extend);
|
||||
param_flush_sel(handle);
|
||||
param_delete(handle);
|
||||
}
|
||||
|
||||
/* ******************** Scale To Bounds operator **************** */
|
||||
void ED_uvedit_scale_to_bounds(Scene *scene, Object *ob, BMesh *bm)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
int hparams = set_handle_params(true, false, true, true, false);
|
||||
handle = construct_param_handle(scene, ob, bm, hparams);
|
||||
param_scale_bounds(handle);
|
||||
param_flush(handle);
|
||||
param_delete(handle);
|
||||
}
|
||||
|
||||
/* ******************** Pack Islands operator **************** */
|
||||
|
||||
void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
handle = construct_param_handle(scene, ob, bm, true, false, selected, correct_aspect);
|
||||
int hparams = set_handle_params(true, false, selected, correct_aspect, false);
|
||||
handle = construct_param_handle(scene, ob, bm, hparams);
|
||||
param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate);
|
||||
param_flush(handle);
|
||||
param_delete(handle);
|
||||
@@ -765,6 +827,344 @@ void UV_OT_pack_islands(wmOperatorType *ot)
|
||||
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/* ******************** Pack Islands operator 2.0 **************** */
|
||||
|
||||
typedef struct SimulatedAnnealing {
|
||||
RNG *rng;
|
||||
int seed;
|
||||
float theta;
|
||||
float f;
|
||||
float r;
|
||||
float temperature;
|
||||
int rot_steps;
|
||||
} SimulatedAnnealing;
|
||||
|
||||
typedef struct PackIslands {
|
||||
Scene *scene;
|
||||
Object *obedit;
|
||||
BMEditMesh *em;
|
||||
ParamHandle *handle;
|
||||
double lasttime;
|
||||
int iter_global, iter_local, iter_max;
|
||||
wmTimer *timer;
|
||||
float wasted_area_last, margin;
|
||||
bool use_concave;
|
||||
SimulatedAnnealing *sa;
|
||||
} PackIslands;
|
||||
|
||||
static bool irregular_pack_islands_init(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
PackIslands *pi;
|
||||
SimulatedAnnealing *simann;
|
||||
unsigned int seed = 31415926;
|
||||
float wasted_area;
|
||||
bool average_scale = RNA_boolean_get(op->ptr, "average_islands_scale");
|
||||
|
||||
/* Keep for now, needed when making packing work with current selection */
|
||||
/*if (!uvedit_have_selection(scene, em, implicit)) {
|
||||
return false;
|
||||
}*/
|
||||
|
||||
int hparams = set_handle_params(true, false, false, false, true);
|
||||
|
||||
pi = MEM_callocN(sizeof(PackIslands), "PackIslands");
|
||||
pi->scene = scene;
|
||||
pi->obedit = obedit;
|
||||
pi->em = em;
|
||||
pi->iter_max = RNA_int_get(op->ptr, "iterations");
|
||||
pi->iter_global = 0;
|
||||
pi->iter_local = 0;
|
||||
pi->margin = RNA_float_get(op->ptr, "margin") / 2.0f; /* Only apply half the margin per chart */
|
||||
pi->use_concave = RNA_boolean_get(op->ptr, "concave");
|
||||
pi->handle = construct_param_handle(scene, obedit, em->bm, hparams);
|
||||
pi->lasttime = PIL_check_seconds_timer();
|
||||
|
||||
simann = MEM_callocN(sizeof(SimulatedAnnealing), "SimulatedAnnealing");
|
||||
simann->rng = BLI_rng_new(seed);
|
||||
simann->seed = seed;
|
||||
simann->theta = 0.0f;
|
||||
simann->f = 0.0f;
|
||||
simann->r = 0.0f;
|
||||
simann->temperature = 1.0f;
|
||||
simann->rot_steps = RNA_int_get(op->ptr, "rotation_steps");
|
||||
pi->sa = simann;
|
||||
|
||||
if (average_scale)
|
||||
param_average(pi->handle);
|
||||
|
||||
param_irregular_pack_begin(pi->handle,
|
||||
&wasted_area,
|
||||
pi->margin,
|
||||
pi->sa->rot_steps,
|
||||
pi->use_concave /* SA */);
|
||||
|
||||
param_accept_placement_all(pi->handle);
|
||||
|
||||
pi->wasted_area_last = wasted_area;
|
||||
printf("wasted area currently: %f\n", wasted_area);
|
||||
|
||||
op->customdata = pi;
|
||||
|
||||
DAG_id_tag_update(pi->obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, pi->obedit->data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void irregular_pack_islands_iteration(bContext *C, wmOperator *op, bool interactive)
|
||||
{
|
||||
PackIslands *pi = op->customdata;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
float wasted_area = 0.0f, dE, r1, r2;
|
||||
float a = 0.95f;
|
||||
/* ToDo Saphires: Find optimal parameter */
|
||||
float k = 0.5f; /* Stefan-Boltzman constant-like parameter */
|
||||
int local_iter_max = 50;
|
||||
|
||||
pi->iter_global++;
|
||||
|
||||
/* Cooling Schedule */
|
||||
if (pi->iter_local >= local_iter_max) {
|
||||
pi->sa->temperature = pi->sa->temperature * a;
|
||||
pi->iter_local = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Find neighboring solution */
|
||||
/*ToDo Saphires: Pass SA parameters */
|
||||
param_irregular_pack_iter(pi->handle,
|
||||
&wasted_area,
|
||||
pi->iter_global,
|
||||
pi->sa->rot_steps,
|
||||
pi->margin /* SA */);
|
||||
|
||||
/* delta Energy */
|
||||
dE = wasted_area - pi->wasted_area_last;
|
||||
|
||||
printf("wasted area currently: %f, wasted area last: %f\n", wasted_area, pi->wasted_area_last);
|
||||
|
||||
if (dE < 0) {
|
||||
/* Current solution is new best solution, keep placement */
|
||||
param_accept_placement_all(pi->handle);
|
||||
pi->wasted_area_last = wasted_area;
|
||||
printf("dE < 0\n");
|
||||
}
|
||||
else {
|
||||
r1 = BLI_rng_get_float(pi->sa->rng);
|
||||
|
||||
r2 = (float)exp(-dE/(k * pi->sa->temperature));
|
||||
|
||||
if (0 /*r1 < r2*/) {
|
||||
/* Current solution is new best solution, keep placement */
|
||||
param_accept_placement_all(pi->handle);
|
||||
pi->wasted_area_last = wasted_area;
|
||||
printf("r1 < r2\n");
|
||||
}
|
||||
else {
|
||||
/* no better solution found, "frozen state solution" */
|
||||
printf("frozen state, revert\n");
|
||||
param_restore_placement(pi->handle, pi->margin);
|
||||
pi->iter_local++;
|
||||
}
|
||||
}
|
||||
|
||||
/* RNA_int_set(op->ptr, "iterations", pi->iter_global); */ /* ToDo SaphireS */
|
||||
|
||||
if (interactive /*&& (PIL_check_seconds_timer() - pi->lasttime > 0.5)*/) {
|
||||
char str[UI_MAX_DRAW_STR];
|
||||
|
||||
param_flush(pi->handle);
|
||||
|
||||
if (sa) {
|
||||
BLI_snprintf(str, sizeof(str),
|
||||
IFACE_("Pack Islands (irregular). Iteration: %i, Wasted UV Area (Best Solution): %f"), pi->iter_global, pi->wasted_area_last);
|
||||
ED_area_headerprint(sa, str);
|
||||
}
|
||||
|
||||
pi->lasttime = PIL_check_seconds_timer();
|
||||
|
||||
DAG_id_tag_update(pi->obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, pi->obedit->data);
|
||||
|
||||
printf("done iteration\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void irregular_pack_islands_exit(bContext *C, wmOperator *op, bool cancel)
|
||||
{
|
||||
PackIslands *pi = op->customdata;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
|
||||
if (sa)
|
||||
ED_area_headerprint(sa, NULL);
|
||||
if (pi->timer)
|
||||
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pi->timer);
|
||||
|
||||
if (cancel) {
|
||||
param_flush_restore(pi->handle); /* Restore original UVs */
|
||||
}
|
||||
else {
|
||||
//param_restore_packing_solution(pi->handle); /* Restore best solution*/
|
||||
param_flush(pi->handle); /* Keep new UVs */
|
||||
}
|
||||
|
||||
param_irregular_pack_end(pi->handle);
|
||||
param_delete(pi->handle);
|
||||
|
||||
BLI_rng_free(pi->sa->rng);
|
||||
MEM_freeN(pi->sa);
|
||||
|
||||
DAG_id_tag_update(pi->obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, pi->obedit->data);
|
||||
|
||||
MEM_freeN(pi);
|
||||
op->customdata = NULL;
|
||||
}
|
||||
|
||||
static int irregular_pack_islands_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int i, iterations;
|
||||
|
||||
if (!irregular_pack_islands_init(C, op))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
iterations = RNA_int_get(op->ptr, "iterations");
|
||||
for (i = 0; i < iterations; i++)
|
||||
irregular_pack_islands_iteration(C, op, false);
|
||||
irregular_pack_islands_exit(C, op, false);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int irregular_pack_islands_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
PackIslands *pi;
|
||||
|
||||
if (!irregular_pack_islands_init(C, op))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
irregular_pack_islands_iteration(C, op, true);
|
||||
|
||||
pi = op->customdata;
|
||||
WM_event_add_modal_handler(C, op);
|
||||
pi->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int irregular_pack_islands_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
PackIslands *pi = op->customdata;
|
||||
|
||||
switch (event->type) {
|
||||
case ESCKEY:
|
||||
case RIGHTMOUSE:
|
||||
irregular_pack_islands_exit(C, op, true);
|
||||
return OPERATOR_CANCELLED;
|
||||
case RETKEY:
|
||||
case PADENTER:
|
||||
case LEFTMOUSE:
|
||||
irregular_pack_islands_exit(C, op, false);
|
||||
return OPERATOR_FINISHED;
|
||||
case TIMER:
|
||||
if (pi->timer == event->customdata) {
|
||||
double start = PIL_check_seconds_timer();
|
||||
|
||||
do {
|
||||
irregular_pack_islands_iteration(C, op, true);
|
||||
} while (PIL_check_seconds_timer() - start < 0.01);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pi->iter_max && pi->iter_global >= pi->iter_max) {
|
||||
irregular_pack_islands_exit(C, op, false);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static void irregular_pack_islands_cancel(bContext *C, wmOperator *op)
|
||||
{
|
||||
irregular_pack_islands_exit(C, op, true);
|
||||
}
|
||||
|
||||
void UV_OT_irregular_pack_islands(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Pack Islands (irregular)";
|
||||
ot->idname = "UV_OT_irregular_pack_islands";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR | OPTYPE_BLOCKING;
|
||||
ot->description = "New and improved packing taking into account irregular uv shapes";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = irregular_pack_islands_exec;
|
||||
ot->invoke = irregular_pack_islands_invoke;
|
||||
ot->modal = irregular_pack_islands_modal;
|
||||
ot->cancel = irregular_pack_islands_cancel;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna, "concave", false, "Use concave boundaries", "Use concave boundaries (slower but better results)");
|
||||
RNA_def_float(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", "Border Margin/Padding to apply per UV island", 0.0f, 1.0f);
|
||||
RNA_def_int(ot->srna, "rotation_steps", 4, 0, 360, "Rotation Steps", "Allowed rotations to try during packing. (2=180<38>, 4=90<39>, etc.)", 0, 360);
|
||||
RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively", 0, 10000);
|
||||
RNA_def_boolean(ot->srna, "average_islands_scale", true, "Average Islands Scale", "Average Islands Scale before starting packing");
|
||||
}
|
||||
|
||||
/* ******************** XXX (SaphireS): DEBUG-TEST operator **************** */
|
||||
|
||||
/* XXX (SaphireS): Remove */
|
||||
static void ED_uvedit_test_debug(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
int hparams = set_handle_params(true, false, selected, correct_aspect, true);
|
||||
handle = construct_param_handle(scene, ob, bm, hparams);
|
||||
|
||||
param_test(handle);
|
||||
|
||||
param_flush(handle);
|
||||
param_delete(handle);
|
||||
}
|
||||
|
||||
/* XXX (SaphireS): Remove */
|
||||
static int test_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
/*if (!uvedit_have_selection(scene, em, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}*/
|
||||
|
||||
ED_uvedit_test_debug(scene, obedit, em->bm, false, true);
|
||||
|
||||
DAG_id_tag_update(obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* XXX (SaphireS): Remove */
|
||||
void UV_OT_test(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "DEBUG - TEST";
|
||||
ot->idname = "UV_OT_test";
|
||||
ot->description = "Debug operator to test stuff";
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = test_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
}
|
||||
|
||||
/* ******************** Average Islands Scale operator **************** */
|
||||
|
||||
static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
@@ -774,12 +1174,14 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
ParamHandle *handle;
|
||||
bool implicit = true;
|
||||
|
||||
int hparams = set_handle_params(implicit, false, true, true, false);
|
||||
|
||||
if (!uvedit_have_selection(scene, em, implicit)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
handle = construct_param_handle(scene, obedit, em->bm, implicit, 0, 1, 1);
|
||||
handle = construct_param_handle(scene, obedit, em->bm, hparams);
|
||||
param_average(handle);
|
||||
param_flush(handle);
|
||||
param_delete(handle);
|
||||
@@ -817,6 +1219,8 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
|
||||
|
||||
modifier_unwrap_state(obedit, scene, &use_subsurf);
|
||||
|
||||
int hparams = set_handle_params(false, fillholes, false, true, false);
|
||||
|
||||
if (!ED_uvedit_test(obedit)) {
|
||||
return;
|
||||
}
|
||||
@@ -824,7 +1228,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
|
||||
if (use_subsurf)
|
||||
liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true);
|
||||
else
|
||||
liveHandle = construct_param_handle(scene, obedit, em->bm, false, fillholes, false, true);
|
||||
liveHandle = construct_param_handle(scene, obedit, em->bm, hparams);
|
||||
|
||||
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
|
||||
}
|
||||
@@ -1146,21 +1550,27 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
|
||||
|
||||
const bool fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0;
|
||||
const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0;
|
||||
const bool pack_islands = (scene->toolsettings->uvcalc_flag & UVCALC_PACKISLANDS) != 0;
|
||||
bool use_subsurf;
|
||||
|
||||
int hparams = set_handle_params(false, fill_holes, sel, correct_aspect, false);
|
||||
|
||||
modifier_unwrap_state(obedit, scene, &use_subsurf);
|
||||
|
||||
if (use_subsurf)
|
||||
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
|
||||
else
|
||||
handle = construct_param_handle(scene, obedit, em->bm, false, fill_holes, sel, correct_aspect);
|
||||
handle = construct_param_handle(scene, obedit, em->bm, hparams);
|
||||
|
||||
param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
|
||||
param_lscm_solve(handle);
|
||||
param_lscm_end(handle);
|
||||
|
||||
param_average(handle);
|
||||
param_pack(handle, scene->toolsettings->uvcalc_margin, false);
|
||||
if (pack_islands)
|
||||
param_pack(handle, scene->toolsettings->uvcalc_margin, false);
|
||||
else
|
||||
param_scale_bounds(handle);
|
||||
|
||||
param_flush(handle);
|
||||
|
||||
@@ -1175,6 +1585,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
|
||||
int method = RNA_enum_get(op->ptr, "method");
|
||||
const bool fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
|
||||
const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
|
||||
const bool pack_islands = RNA_boolean_get(op->ptr, "pack_islands");
|
||||
const bool use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data");
|
||||
bool use_subsurf_final;
|
||||
float obsize[3];
|
||||
@@ -1189,6 +1600,9 @@ static int unwrap_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Reveal hidden UVs since they're taken into account*/
|
||||
ED_uvedit_reveal(em);
|
||||
|
||||
mat4_to_size(obsize, obedit->obmat);
|
||||
if (!(fabsf(obsize[0] - obsize[1]) < 1e-4f && fabsf(obsize[1] - obsize[2]) < 1e-4f))
|
||||
BKE_report(op->reports, RPT_INFO,
|
||||
@@ -1215,6 +1629,9 @@ static int unwrap_exec(bContext *C, wmOperator *op)
|
||||
if (correct_aspect) scene->toolsettings->uvcalc_flag &= ~UVCALC_NO_ASPECT_CORRECT;
|
||||
else scene->toolsettings->uvcalc_flag |= UVCALC_NO_ASPECT_CORRECT;
|
||||
|
||||
if (pack_islands) scene->toolsettings->uvcalc_flag |= UVCALC_PACKISLANDS;
|
||||
else scene->toolsettings->uvcalc_flag &= ~UVCALC_PACKISLANDS;
|
||||
|
||||
if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF;
|
||||
else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF;
|
||||
|
||||
@@ -1258,6 +1675,8 @@ void UV_OT_unwrap(wmOperatorType *ot)
|
||||
"Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry");
|
||||
RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect",
|
||||
"Map UVs taking image aspect ratio into account");
|
||||
RNA_def_boolean(ot->srna, "pack_islands", 1, "Pack Islands",
|
||||
"Pack UV islands after unwrapping");
|
||||
RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier",
|
||||
"Map UVs taking vertex position after Subdivision Surface modifier has been applied");
|
||||
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
|
||||
@@ -1303,6 +1722,9 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Reveal hidden UVs since they're taken into account*/
|
||||
ED_uvedit_reveal(em);
|
||||
|
||||
cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "orthographic")) {
|
||||
@@ -1405,6 +1827,9 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Reveal hidden UVs since they're taken into account*/
|
||||
ED_uvedit_reveal(me->edit_btmesh);
|
||||
|
||||
ED_mesh_uv_loop_reset(C, me);
|
||||
|
||||
DAG_id_tag_update(obedit->data, 0);
|
||||
@@ -1491,6 +1916,9 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Reveal hidden UVs since they're taken into account*/
|
||||
ED_uvedit_reveal(em);
|
||||
|
||||
cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
uv_map_transform(C, op, center, rotmat);
|
||||
@@ -1570,6 +1998,9 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Reveal hidden UVs since they're taken into account*/
|
||||
ED_uvedit_reveal(em);
|
||||
|
||||
cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
uv_map_transform(C, op, center, rotmat);
|
||||
@@ -1676,6 +2107,9 @@ static int cube_project_exec(bContext *C, wmOperator *op)
|
||||
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Reveal hidden UVs since they're taken into account*/
|
||||
ED_uvedit_reveal(em);
|
||||
|
||||
ED_uvedit_unwrap_cube_project(obedit, em->bm, cube_size, true);
|
||||
uv_map_clip_correct(scene, obedit, em, op);
|
||||
|
@@ -213,6 +213,7 @@ enum {
|
||||
MLOOPUV_EDGESEL = (1 << 0),
|
||||
MLOOPUV_VERTSEL = (1 << 1),
|
||||
MLOOPUV_PINNED = (1 << 2),
|
||||
MLOOPUV_HIDDEN = (1 << 3)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -2152,6 +2152,7 @@ typedef enum ImagePaintMode {
|
||||
#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
|
||||
#define UVCALC_TRANSFORM_CORRECT 4 /* adjust UV's while transforming to avoid distortion */
|
||||
#define UVCALC_USESUBSURF 8 /* Use mesh data after subsurf to compute UVs*/
|
||||
#define UVCALC_PACKISLANDS 16 /* Pack Islands after unwrapping*/
|
||||
|
||||
/* toolsettings->uv_flag */
|
||||
#define UV_SYNC_SELECTION 1
|
||||
|
Reference in New Issue
Block a user