forked from bartvdbraak/blender
Add access to UVs from python, patch python unwrap scripts to work wtih ngons
This commit is contained in:
parent
3ed866d2fc
commit
1038c76c55
@ -140,8 +140,7 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
|
||||
edges = {}
|
||||
|
||||
for f in faces:
|
||||
# if len(f) == 4:
|
||||
if f.vertices_raw[3] != 0:
|
||||
if len(f.vertices) == 4:
|
||||
edge_keys = f.edge_keys
|
||||
for i, edkey in enumerate(f.edge_keys):
|
||||
edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]])
|
||||
|
@ -442,6 +442,20 @@ class MeshFace(StructRNA):
|
||||
ord_ind(verts[3], verts[0]),
|
||||
)
|
||||
|
||||
class MeshPolygon(StructRNA):
|
||||
__slots__ = ()
|
||||
|
||||
@property
|
||||
def edge_keys(self):
|
||||
verts = self.vertices[:]
|
||||
vlen = len(self.vertices)
|
||||
return [ord_ind(verts[i], verts[(i+1) % vlen]) for i in range(vlen)]
|
||||
|
||||
@property
|
||||
def loops(self):
|
||||
start = self.loop_start
|
||||
end = start + self.loop_total
|
||||
return range(start, end)
|
||||
|
||||
class Text(bpy_types.ID):
|
||||
__slots__ = ()
|
||||
|
@ -30,6 +30,7 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
|
||||
me = obj.data
|
||||
me_verts = me.vertices
|
||||
|
||||
# script will fail without UVs
|
||||
if not me.uv_textures:
|
||||
me.uv_textures.new()
|
||||
@ -52,17 +53,15 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
'''
|
||||
|
||||
def face_edge_vs(vi):
|
||||
# assume a quad
|
||||
return [(vi[0], vi[1]), (vi[1], vi[2]), (vi[2], vi[3]), (vi[3], vi[0])]
|
||||
vlen = len(vi)
|
||||
return [(vi[i], vi[(i+1) % vlen]) for i in range(vlen)]
|
||||
|
||||
vidx_source = face_source.vertices
|
||||
vidx_target = face_target.vertices
|
||||
|
||||
faceUVsource = me.uv_textures.active.data[face_source.index]
|
||||
uvs_source = [faceUVsource.uv1, faceUVsource.uv2, faceUVsource.uv3, faceUVsource.uv4]
|
||||
|
||||
faceUVtarget = me.uv_textures.active.data[face_target.index]
|
||||
uvs_target = [faceUVtarget.uv1, faceUVtarget.uv2, faceUVtarget.uv3, faceUVtarget.uv4]
|
||||
uv_layer = me.uv_loop_layers.active.data
|
||||
uvs_source = [uv_layer[i].uv for i in face_source.loops]
|
||||
uvs_target = [uv_layer[i].uv for i in face_target.loops]
|
||||
|
||||
# vertex index is the key, uv is the value
|
||||
|
||||
@ -135,15 +134,12 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
|
||||
uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
|
||||
|
||||
if not me.uv_textures:
|
||||
me.uv_textures.new()
|
||||
|
||||
face_act = me.faces.active
|
||||
face_act = me.polygons.active
|
||||
if face_act == -1:
|
||||
operator.report({'ERROR'}, "No active face")
|
||||
return
|
||||
|
||||
face_sel = [f for f in me.faces if len(f.vertices) == 4 and f.select]
|
||||
face_sel = [f for f in me.polygons if len(f.vertices) == 4 and f.select]
|
||||
|
||||
face_act_local_index = -1
|
||||
for i, f in enumerate(face_sel):
|
||||
|
@ -88,8 +88,8 @@ class prettyface(object):
|
||||
self.children = []
|
||||
|
||||
else: # blender face
|
||||
# self.uv = data.uv
|
||||
self.uv = data.id_data.uv_textures.active.data[data.index].uv # XXX25
|
||||
uv_layer = data.id_data.uv_loop_layers.active.data
|
||||
self.uv = [uv_layer[i].uv for i in data.loops]
|
||||
|
||||
# cos = [v.co for v in data]
|
||||
cos = [data.id_data.vertices[v].co for v in data.vertices] # XXX25
|
||||
@ -158,7 +158,8 @@ class prettyface(object):
|
||||
I = [i for a, i in angles_co]
|
||||
|
||||
#~ fuv = f.uv
|
||||
fuv = f.id_data.uv_textures.active.data[f.index].uv # XXX25
|
||||
uv_layer = f.id_data.uv_loop_layers.active.data
|
||||
fuv = [uv_layer[i].uv for i in f.loops] # XXX25
|
||||
|
||||
if self.rot:
|
||||
fuv[I[2]] = p1
|
||||
@ -219,15 +220,10 @@ def lightmap_uvpack(meshes,
|
||||
face_groups = []
|
||||
|
||||
for me in meshes:
|
||||
# Add face UV if it does not exist.
|
||||
# All new faces are selected.
|
||||
if not me.uv_textures:
|
||||
me.uv_textures.new()
|
||||
|
||||
if PREF_SEL_ONLY:
|
||||
faces = [f for f in me.faces if f.select]
|
||||
faces = [f for f in me.polygons if f.select]
|
||||
else:
|
||||
faces = me.faces[:]
|
||||
faces = me.polygons[:]
|
||||
|
||||
if PREF_PACK_IN_ONE:
|
||||
face_groups[0].extend(faces)
|
||||
@ -237,6 +233,11 @@ def lightmap_uvpack(meshes,
|
||||
if PREF_NEW_UVLAYER:
|
||||
me.uv_textures.new()
|
||||
|
||||
# Add face UV if it does not exist.
|
||||
# All new faces are selected.
|
||||
if not me.uv_textures:
|
||||
me.uv_textures.new()
|
||||
|
||||
for face_sel in face_groups:
|
||||
print("\nStarting unwrap")
|
||||
|
||||
@ -504,7 +505,7 @@ def lightmap_uvpack(meshes,
|
||||
|
||||
for f in face_sel:
|
||||
# f.image = image
|
||||
f.id_data.uv_textures.active.data[f.index].image = image # XXX25
|
||||
f.id_data.uv_loop_layers.active.data[f.index].image = image # XXX25
|
||||
|
||||
for me in meshes:
|
||||
me.update()
|
||||
@ -528,7 +529,7 @@ def unwrap(operator, context, **kwargs):
|
||||
if obj and obj.type == 'MESH':
|
||||
meshes = [obj.data]
|
||||
else:
|
||||
meshes = list({me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if me.faces and me.library is None})
|
||||
meshes = list({me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if me.polygons and me.library is None})
|
||||
|
||||
if not meshes:
|
||||
operator.report({'ERROR'}, "No mesh object")
|
||||
|
@ -756,13 +756,10 @@ def VectoQuat(vec):
|
||||
|
||||
|
||||
class thickface(object):
|
||||
__slost__= 'v', 'uv', 'no', 'area', 'edge_keys'
|
||||
def __init__(self, face, uvface, mesh_verts):
|
||||
__slots__= ('v', 'uv', 'no', 'area', 'edge_keys')
|
||||
def __init__(self, face, uv_layer, mesh_verts):
|
||||
self.v = [mesh_verts[i] for i in face.vertices]
|
||||
if len(self.v)==4:
|
||||
self.uv = uvface.uv1, uvface.uv2, uvface.uv3, uvface.uv4
|
||||
else:
|
||||
self.uv = uvface.uv1, uvface.uv2, uvface.uv3
|
||||
self.uv = [uv_layer[i].uv for i in face.loops]
|
||||
|
||||
self.no = face.normal
|
||||
self.area = face.area
|
||||
@ -892,13 +889,13 @@ def main(context,
|
||||
if not me.uv_textures: # Mesh has no UV Coords, don't bother.
|
||||
me.uv_textures.new()
|
||||
|
||||
uv_layer = me.uv_textures.active.data
|
||||
uv_layer = me.uv_loop_layers.active.data
|
||||
me_verts = list(me.vertices)
|
||||
|
||||
if USER_ONLY_SELECTED_FACES:
|
||||
meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces) if f.select]
|
||||
meshFaces = [thickface(f, uv_layer, me_verts) for i, f in enumerate(me.polygons) if f.select]
|
||||
else:
|
||||
meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces)]
|
||||
meshFaces = [thickface(f, uv_layer, me_verts) for i, f in enumerate(me.polygons)]
|
||||
|
||||
if not meshFaces:
|
||||
continue
|
||||
|
@ -292,6 +292,7 @@ void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges);
|
||||
|
||||
int ED_mesh_uv_texture_add(struct bContext *C, struct Mesh *me, const char *name, int active_set);
|
||||
int ED_mesh_uv_texture_remove(struct bContext *C, struct Object *ob, struct Mesh *me);
|
||||
int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me);
|
||||
int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me, const char *name, int active_set);
|
||||
int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me);
|
||||
int ED_mesh_color_remove_named(struct bContext *C, struct Object *ob, struct Mesh *me, const char *name);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_array.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_edgehash.h"
|
||||
@ -200,6 +201,112 @@ static void copy_editface_active_customdata(BMEditMesh *em, int type, int index)
|
||||
#endif
|
||||
}
|
||||
|
||||
int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
|
||||
{
|
||||
BMEditMesh *em= me->edit_btmesh;
|
||||
MLoopUV *luv;
|
||||
BLI_array_declare(polylengths);
|
||||
int *polylengths = NULL;
|
||||
BLI_array_declare(uvs);
|
||||
float **uvs = NULL;
|
||||
float **fuvs = NULL;
|
||||
int i, j;
|
||||
|
||||
if (em) {
|
||||
/* Collect BMesh UVs */
|
||||
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
|
||||
BLI_assert(CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV));
|
||||
|
||||
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
|
||||
if (!BM_TestHFlag(efa, BM_SELECT))
|
||||
continue;
|
||||
|
||||
i = 0;
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
BLI_array_append(uvs, luv->uv);
|
||||
i++;
|
||||
}
|
||||
|
||||
BLI_array_append(polylengths, efa->len);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Collect Mesh UVs */
|
||||
|
||||
MPoly *mp;
|
||||
|
||||
BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
|
||||
|
||||
for (j = 0; j < me->totpoly; j++) {
|
||||
mp = &me->mpoly[j];
|
||||
|
||||
for (i = 0; i < mp->totloop; i++) {
|
||||
luv = &me->mloopuv[mp->loopstart + i];
|
||||
BLI_array_append(uvs, luv->uv);
|
||||
}
|
||||
|
||||
BLI_array_append(polylengths, mp->totloop);
|
||||
}
|
||||
}
|
||||
|
||||
fuvs = uvs;
|
||||
for (j = 0; j < BLI_array_count(polylengths); j++) {
|
||||
int len = polylengths[j];
|
||||
|
||||
if (len == 3) {
|
||||
fuvs[0][0] = 0.0;
|
||||
fuvs[0][1] = 0.0;
|
||||
|
||||
fuvs[1][0] = 1.0;
|
||||
fuvs[1][1] = 0.0;
|
||||
|
||||
fuvs[2][0] = 1.0;
|
||||
fuvs[2][1] = 1.0;
|
||||
} else if (len == 4) {
|
||||
fuvs[0][0] = 0.0;
|
||||
fuvs[0][1] = 0.0;
|
||||
|
||||
fuvs[1][0] = 1.0;
|
||||
fuvs[1][1] = 0.0;
|
||||
|
||||
fuvs[2][0] = 1.0;
|
||||
fuvs[2][1] = 1.0;
|
||||
|
||||
fuvs[3][0] = 0.0;
|
||||
fuvs[3][1] = 1.0;
|
||||
/*make sure we ignore 2-sided faces*/
|
||||
} else if (len > 2) {
|
||||
float fac = 0.0f, dfac = 1.0f / (float)len;
|
||||
|
||||
dfac *= M_PI*2;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
fuvs[i][0] = 0.5f * sin(fac) + 0.5f;
|
||||
fuvs[i][1] = 0.5f * cos(fac) + 0.5f;
|
||||
|
||||
fac += dfac;
|
||||
}
|
||||
}
|
||||
|
||||
fuvs += len;
|
||||
}
|
||||
|
||||
/* BMESH_TODO: Copy poly UVs onto CD_MTFACE layer for tesselated faces */
|
||||
|
||||
BLI_array_free(uvs);
|
||||
BLI_array_free(polylengths);
|
||||
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_set)
|
||||
{
|
||||
BMEditMesh *em;
|
||||
@ -237,20 +344,25 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
|
||||
if(me->mtpoly) {
|
||||
CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DUPLICATE, me->mtpoly, me->totpoly, name);
|
||||
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name);
|
||||
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
|
||||
} else {
|
||||
CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, name);
|
||||
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, name);
|
||||
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
|
||||
}
|
||||
|
||||
if(active_set || layernum==0) {
|
||||
CustomData_set_layer_active(&me->pdata, CD_MTEXPOLY, layernum);
|
||||
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum);
|
||||
|
||||
CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
|
||||
}
|
||||
|
||||
|
||||
mesh_update_customdata_pointers(me);
|
||||
}
|
||||
|
||||
ED_mesh_uv_loop_reset(C, me);
|
||||
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
|
||||
|
||||
@ -307,13 +419,19 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
|
||||
if(layernum >= CD_MLOOPCOL)
|
||||
return 0;
|
||||
|
||||
if(me->mloopcol)
|
||||
if(me->mloopcol) {
|
||||
CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DUPLICATE, me->mloopcol, me->totloop, name);
|
||||
else
|
||||
CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mloopcol, me->totface, name);
|
||||
}
|
||||
else {
|
||||
CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name);
|
||||
CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface, name);
|
||||
}
|
||||
|
||||
if(active_set || layernum==0)
|
||||
if(active_set || layernum==0) {
|
||||
CustomData_set_layer_active(&me->ldata, CD_MLOOPCOL, layernum);
|
||||
CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
|
||||
}
|
||||
|
||||
mesh_update_customdata_pointers(me);
|
||||
}
|
||||
|
@ -1124,7 +1124,8 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
|
||||
Mesh *me = (Mesh*)obedit->data;
|
||||
BMEditMesh *em= me->edit_btmesh;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
@ -1134,57 +1135,12 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
int i;
|
||||
|
||||
/* add uvs if they don't exist yet */
|
||||
if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
|
||||
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
|
||||
if (!BM_TestHFlag(efa, BM_SELECT))
|
||||
continue;
|
||||
|
||||
BLI_array_empty(uvs);
|
||||
i = 0;
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
BLI_array_growone(uvs);
|
||||
|
||||
uvs[i++] = luv->uv;
|
||||
}
|
||||
|
||||
if (i == 3) {
|
||||
uvs[0][0] = 0.0;
|
||||
uvs[0][1] = 0.0;
|
||||
|
||||
uvs[1][0] = 1.0;
|
||||
uvs[1][1] = 0.0;
|
||||
|
||||
uvs[2][0] = 1.0;
|
||||
uvs[2][1] = 1.0;
|
||||
} else if (i == 4) {
|
||||
uvs[0][0] = 0.0;
|
||||
uvs[0][1] = 0.0;
|
||||
|
||||
uvs[1][0] = 1.0;
|
||||
uvs[1][1] = 0.0;
|
||||
|
||||
uvs[2][0] = 1.0;
|
||||
uvs[2][1] = 1.0;
|
||||
|
||||
uvs[3][0] = 0.0;
|
||||
uvs[3][1] = 1.0;
|
||||
/*make sure we ignore 2-sided faces*/
|
||||
} else if (i > 2) {
|
||||
float fac = 0.0f, dfac = 1.0f / (float)efa->len;
|
||||
|
||||
dfac *= M_PI*2;
|
||||
|
||||
for (i=0; i<efa->len; i++) {
|
||||
uvs[i][0] = sin(fac);
|
||||
uvs[i][1] = cos(fac);
|
||||
|
||||
fac += dfac;
|
||||
}
|
||||
}
|
||||
if (!ED_mesh_uv_loop_reset(C, me)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
DAG_id_tag_update(obedit->data, 0);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user