Uv Tools branch GSOC 2011
========================= Documentation: http://wiki.blender.org/index.php/User:Psy-Fi/UV_Tools Major features include: *16 bit image support in viewport *Subsurf aware unwrapping *Smart Stitch(snap/rotate islands, preview, middlepoint/endpoint stitching) *Seams from islands tool (marks seams and sharp, depending on settings) *Uv Sculpting(Grab/Pinch/Rotate) All tools are complete apart from stitching that is considered stable but with an extra edge mode under development(will be in soc-2011-onion-uv-tools).
This commit is contained in:
@@ -2322,7 +2322,7 @@ UvVertMap *EM_make_uv_vert_map(EditMesh *em, int selected, int do_face_idx_array
|
||||
for(a=0, ev=em->verts.first; ev; a++, ev= ev->next) {
|
||||
UvMapVert *newvlist= NULL, *vlist=vmap->vert[a];
|
||||
UvMapVert *iterv, *v, *lastv, *next;
|
||||
float *uv, *uv2, uvdiff[2];
|
||||
float *uv, *uv2;
|
||||
|
||||
while(vlist) {
|
||||
v= vlist;
|
||||
@@ -2332,8 +2332,8 @@ UvVertMap *EM_make_uv_vert_map(EditMesh *em, int selected, int do_face_idx_array
|
||||
|
||||
efa = EM_get_face_for_index(v->f);
|
||||
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
uv = tf->uv[v->tfindex];
|
||||
|
||||
uv = tf->uv[v->tfindex];
|
||||
|
||||
lastv= NULL;
|
||||
iterv= vlist;
|
||||
|
||||
@@ -2342,8 +2342,6 @@ UvVertMap *EM_make_uv_vert_map(EditMesh *em, int selected, int do_face_idx_array
|
||||
efa = EM_get_face_for_index(iterv->f);
|
||||
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
uv2 = tf->uv[iterv->tfindex];
|
||||
|
||||
sub_v2_v2v2(uvdiff, uv2, uv);
|
||||
|
||||
if(fabsf(uv[0]-uv2[0]) < limit[0] && fabsf(uv[1]-uv2[1]) < limit[1]) {
|
||||
if(lastv) lastv->next= next;
|
||||
@@ -2353,22 +2351,224 @@ UvVertMap *EM_make_uv_vert_map(EditMesh *em, int selected, int do_face_idx_array
|
||||
}
|
||||
else
|
||||
lastv=iterv;
|
||||
|
||||
iterv= next;
|
||||
}
|
||||
newvlist->separate = 1;
|
||||
}
|
||||
vmap->vert[a]= newvlist;
|
||||
}
|
||||
|
||||
|
||||
if (do_face_idx_array)
|
||||
EM_free_index_arrays();
|
||||
|
||||
return vmap;
|
||||
}
|
||||
|
||||
/* A specialized vert map used by stitch operator */
|
||||
UvElementMap *EM_make_uv_element_map(EditMesh *em, int selected, int do_islands)
|
||||
{
|
||||
EditVert *ev;
|
||||
EditFace *efa;
|
||||
|
||||
/* vars from original func */
|
||||
UvElementMap *vmap;
|
||||
UvElement *buf;
|
||||
UvElement *islandbuf;
|
||||
MTFace *tf;
|
||||
unsigned int a;
|
||||
int i,j, totuv, nverts, nislands = 0, islandbufsize = 0;
|
||||
unsigned int *map;
|
||||
/* for uv island creation */
|
||||
EditFace **stack;
|
||||
int stacksize = 0;
|
||||
|
||||
/* we need the vert */
|
||||
for(ev = em->verts.first, i = 0; ev; ev = ev->next, i++)
|
||||
ev->tmp.l = i;
|
||||
|
||||
totuv = 0;
|
||||
|
||||
for(efa = em->faces.first; efa; efa = efa->next)
|
||||
if(!selected || ((!efa->h) && (efa->f & SELECT)))
|
||||
totuv += (efa->v4)? 4: 3;
|
||||
|
||||
if(totuv == 0)
|
||||
return NULL;
|
||||
|
||||
vmap = (UvElementMap *)MEM_callocN(sizeof(*vmap), "UvVertElementMap");
|
||||
if(!vmap)
|
||||
return NULL;
|
||||
|
||||
vmap->vert = (UvElement**)MEM_callocN(sizeof(*vmap->vert)*em->totvert, "UvElementVerts");
|
||||
buf = vmap->buf = (UvElement*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvElement");
|
||||
|
||||
if(!vmap->vert || !vmap->buf) {
|
||||
EM_free_uv_element_map(vmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vmap->totalUVs = totuv;
|
||||
|
||||
for(efa = em->faces.first; efa; a++, efa = efa->next) {
|
||||
if(!selected || ((!efa->h) && (efa->f & SELECT))) {
|
||||
nverts = (efa->v4)? 4: 3;
|
||||
|
||||
for(i = 0; i<nverts; i++) {
|
||||
buf->tfindex = i;
|
||||
buf->face = efa;
|
||||
buf->separate = 0;
|
||||
buf->island = INVALID_ISLAND;
|
||||
|
||||
buf->next = vmap->vert[(*(&efa->v1 + i))->tmp.l];
|
||||
vmap->vert[(*(&efa->v1 + i))->tmp.l] = buf;
|
||||
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
efa->tmp.l = INVALID_ISLAND;
|
||||
}
|
||||
|
||||
/* sort individual uvs for each vert */
|
||||
for(a = 0, ev = em->verts.first; ev; a++, ev = ev->next) {
|
||||
UvElement *newvlist = NULL, *vlist = vmap->vert[a];
|
||||
UvElement *iterv, *v, *lastv, *next;
|
||||
float *uv, *uv2;
|
||||
|
||||
while(vlist) {
|
||||
v= vlist;
|
||||
vlist= vlist->next;
|
||||
v->next= newvlist;
|
||||
newvlist= v;
|
||||
|
||||
efa = v->face;
|
||||
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
uv = tf->uv[v->tfindex];
|
||||
|
||||
lastv= NULL;
|
||||
iterv= vlist;
|
||||
|
||||
while(iterv) {
|
||||
next= iterv->next;
|
||||
efa = iterv->face;
|
||||
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
uv2 = tf->uv[iterv->tfindex];
|
||||
|
||||
if(fabsf(uv[0]-uv2[0]) < STD_UV_CONNECT_LIMIT && fabsf(uv[1]-uv2[1]) < STD_UV_CONNECT_LIMIT) {
|
||||
if(lastv) lastv->next = next;
|
||||
else vlist = next;
|
||||
iterv->next = newvlist;
|
||||
newvlist = iterv;
|
||||
}
|
||||
else
|
||||
lastv = iterv;
|
||||
|
||||
iterv = next;
|
||||
}
|
||||
|
||||
newvlist->separate = 1;
|
||||
}
|
||||
|
||||
vmap->vert[a]= newvlist;
|
||||
vmap->vert[a] = newvlist;
|
||||
}
|
||||
|
||||
if (do_face_idx_array)
|
||||
EM_free_index_arrays();
|
||||
|
||||
|
||||
if(do_islands) {
|
||||
/* at this point, every UvElement in vert points to a UvElement sharing the same vertex. Now we should sort uv's in islands. */
|
||||
|
||||
/* map holds the map from current vmap->buf to the new, sorted map*/
|
||||
map = MEM_mallocN(sizeof(*map)*totuv, "uvelement_remap");
|
||||
stack = MEM_mallocN(sizeof(*stack)*em->totface, "uv_island_face_stack");
|
||||
islandbuf = MEM_callocN(sizeof(*islandbuf)*totuv, "uvelement_island_buffer");
|
||||
|
||||
for(i = 0; i < totuv; i++) {
|
||||
if(vmap->buf[i].island == INVALID_ISLAND) {
|
||||
vmap->buf[i].island = nislands;
|
||||
stack[0] = vmap->buf[i].face;
|
||||
stack[0]->tmp.l = nislands;
|
||||
stacksize=1;
|
||||
|
||||
while(stacksize > 0) {
|
||||
efa = stack[--stacksize];
|
||||
nverts = efa->v4? 4 : 3;
|
||||
|
||||
for(j = 0; j < nverts; j++) {
|
||||
UvElement *element, *initelement = vmap->vert[(*(&efa->v1 + j))->tmp.l];
|
||||
|
||||
for(element = initelement; element; element = element->next) {
|
||||
if(element->separate)
|
||||
initelement = element;
|
||||
|
||||
if(element->face == efa) {
|
||||
/* found the uv corresponding to our face and vertex. Now fill it to the buffer */
|
||||
element->island = nislands;
|
||||
map[element - vmap->buf] = islandbufsize;
|
||||
islandbuf[islandbufsize].tfindex = element->tfindex;
|
||||
islandbuf[islandbufsize].face = element->face;
|
||||
islandbuf[islandbufsize].separate = element->separate;
|
||||
islandbuf[islandbufsize].island = nislands;
|
||||
islandbufsize++;
|
||||
|
||||
for(element = initelement; element; element = element->next) {
|
||||
if(element->separate && element != initelement)
|
||||
break;
|
||||
|
||||
if(element->face->tmp.l == INVALID_ISLAND) {
|
||||
stack[stacksize++] = element->face;
|
||||
element->face->tmp.l = nislands;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nislands++;
|
||||
}
|
||||
}
|
||||
|
||||
/* remap */
|
||||
for(i = 0; i < em->totvert; i++) {
|
||||
/* important since we may do selection only. Some of these may be NULL */
|
||||
if(vmap->vert[i])
|
||||
vmap->vert[i] = &islandbuf[map[vmap->vert[i] - vmap->buf]];
|
||||
}
|
||||
|
||||
vmap->islandIndices = MEM_callocN(sizeof(*vmap->islandIndices)*nislands,"UvVertMap2_island_indices");
|
||||
if(!vmap->islandIndices) {
|
||||
MEM_freeN(islandbuf);
|
||||
MEM_freeN(stack);
|
||||
MEM_freeN(map);
|
||||
EM_free_uv_element_map(vmap);
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < totuv; i++) {
|
||||
UvElement *element = vmap->buf[i].next;
|
||||
if(element == NULL)
|
||||
islandbuf[map[i]].next = NULL;
|
||||
else
|
||||
islandbuf[map[i]].next = &islandbuf[map[element - vmap->buf]];
|
||||
|
||||
if(islandbuf[i].island != j) {
|
||||
j++;
|
||||
vmap->islandIndices[j] = i;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(vmap->buf);
|
||||
|
||||
vmap->buf = islandbuf;
|
||||
vmap->totalIslands = nislands;
|
||||
MEM_freeN(stack);
|
||||
MEM_freeN(map);
|
||||
}
|
||||
|
||||
return vmap;
|
||||
}
|
||||
|
||||
|
||||
UvMapVert *EM_get_uv_map_vert(UvVertMap *vmap, unsigned int v)
|
||||
{
|
||||
return vmap->vert[v];
|
||||
@@ -2383,6 +2583,16 @@ void EM_free_uv_vert_map(UvVertMap *vmap)
|
||||
}
|
||||
}
|
||||
|
||||
void EM_free_uv_element_map(UvElementMap *vmap)
|
||||
{
|
||||
if (vmap) {
|
||||
if (vmap->vert) MEM_freeN(vmap->vert);
|
||||
if (vmap->buf) MEM_freeN(vmap->buf);
|
||||
if (vmap->islandIndices) MEM_freeN(vmap->islandIndices);
|
||||
MEM_freeN(vmap);
|
||||
}
|
||||
}
|
||||
|
||||
/* poll call for mesh operators requiring a view3d context */
|
||||
int EM_view3d_poll(bContext *C)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user