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:
2012-01-17 16:31:13 +00:00
parent fcc54520d1
commit a8081c1d2b
42 changed files with 3727 additions and 320 deletions

View File

@@ -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)
{