Revision: 38360
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38360
Author:   psy-fi
Date:     2011-07-13 12:44:00 +0000 (Wed, 13 Jul 2011)
Log Message:
-----------
smart stitch
====================
When this operator is over I swear I am going to have a party.

-group UvElements according to islands and store island information on them. 
This is crucial information for snapping islands together after stitching.
(Next commit will be first attempt with vertices.)
-do some minor corrections to functions.

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h
    branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h
    branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c
    
branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c
    branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c

Modified: branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h        
2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h        
2011-07-13 12:44:00 UTC (rev 38360)
@@ -53,6 +53,10 @@
 struct CustomData;
 struct DerivedMesh;
 struct Scene;
+struct UvVertMap;
+struct UvMapVert;
+struct UvVertMap2;
+struct UvElement;
 
 #ifdef __cplusplus
 extern "C" {
@@ -126,14 +130,22 @@
        struct UvElement **vert;
        struct UvElement *buf;
        int numOfUVs;
+       int numOfIslands;
+       int *islandIndices;
 } UvVertMap2;
 
 typedef struct UvElement {
        struct UvElement *next;
        struct EditFace *face;
        unsigned char tfindex, separate, flag;
+       unsigned short island;
 } UvElement;
 
+/* invalid island index is max short. If any one has the patience
+ * to make that many islands, he can bite me :p */
+#define INVALID_ISLAND 0xFFFF
+
+
 UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, 
unsigned int totface, unsigned int totvert, int selected, float *limit);
 UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v);
 void free_uv_vert_map(UvVertMap *vmap);

Modified: branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h
===================================================================
--- branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h    
2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h    
2011-07-13 12:44:00 UTC (rev 38360)
@@ -156,7 +156,7 @@
 struct UvMapVert *EM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
 void           EM_free_uv_vert_map(struct UvVertMap *vmap);
 
-struct UvVertMap2 *EM_make_uv_vert_map2(struct EditMesh *em, int selected, 
float *limit);
+struct UvVertMap2 *EM_make_uv_vert_map2(struct EditMesh *em, int selected);
 struct UvElement *EM_get_uv_map_vert_for_edge(struct UvVertMap2 *vmap, struct 
EditMesh *em, struct EditEdge *edge, int initVertexArray);
 void           EM_free_uv_vert_map2(struct UvVertMap2 *vmap);
 

Modified: branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c  
2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c  
2011-07-13 12:44:00 UTC (rev 38360)
@@ -2357,7 +2357,8 @@
        return vmap;
 }
 
-UvVertMap2 *EM_make_uv_vert_map2(EditMesh *em, int selected, float *limit)
+/* A specialized vert map used by stitch operator */
+UvVertMap2 *EM_make_uv_vert_map2(EditMesh *em, int selected)
 {
        EditVert *ev;
        EditFace *efa;
@@ -2366,13 +2367,18 @@
        /* vars from original func */
        UvVertMap2 *vmap;
        UvElement *buf;
+       UvElement *islandbuf;
        MTFace *tf;
        unsigned int a;
-       int     i, totuv, nverts;
+       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, totverts=0; ev; ev= ev->next, totverts++) {
-               ev->tmp.l = totverts;
+       for (ev= em->verts.first, i=0; ev; ev= ev->next, i++) {
+               ev->tmp.l = i;
        }
 
        totuv = 0;
@@ -2390,7 +2396,7 @@
                return NULL;
        }
 
-       vmap->vert= (UvElement**)MEM_callocN(sizeof(*vmap->vert)*totverts, 
"UvElement*");
+       vmap->vert= (UvElement**)MEM_callocN(sizeof(*vmap->vert)*em->totvert, 
"UvElement*");
        buf= vmap->buf= (UvElement*)MEM_callocN(sizeof(*vmap->buf)*totuv, 
"UvElement");
 
        if (!vmap->vert || !vmap->buf) {
@@ -2408,6 +2414,7 @@
                                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;
@@ -2415,58 +2422,145 @@
                                buf++;
                        }
                }
+               efa->tmp.l = INVALID_ISLAND;
        }
 
-       if(limit)
-       {
-               /* 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;
+       /* 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;
 
-                               efa = v->face;
+               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);
-                               uv = tf->uv[v->tfindex];
+                               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;
+       }
 
-                               lastv= NULL;
-                               iterv= vlist;
+       /* At this point, every UvElement in vert points to a UvElement sharing 
the same vertex. Now we should sort uv's in islands. */
 
-                               while(iterv) {
-                                       next= iterv->next;
-                                       efa = iterv->face;
-                                       tf = CustomData_em_get(&em->fdata, 
efa->data, CD_MTFACE);
-                                       uv2 = tf->uv[iterv->tfindex];
+       /* 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");
+       if(!map || !stack || !islandbuf){
+               if(stack)
+                       MEM_freeN(stack);
+               if(map)
+                       MEM_freeN(map);
+               if(islandbuf)
+                       MEM_freeN(islandbuf);
+               EM_free_uv_vert_map2(vmap);
+               return NULL;
+       }
+       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 = 0;
+                       stacksize=1;
 
-                                       if(fabsf(uv[0]-uv2[0]) < limit[0] && 
fabsf(uv[1]-uv2[1]) < limit[1]) {
-                                               if(lastv) lastv->next= next;
-                                               else vlist= next;
-                                               iterv->next= newvlist;
-                                               newvlist= iterv;
+                       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;
+                                                       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;
+                                               }
                                        }
-                                       else
-                                               lastv=iterv;
-
-                                       iterv= next;
                                }
-
-                               newvlist->separate = 1;
                        }
 
-                       vmap->vert[a]= newvlist;
+                       nislands++;
                }
        }
+       /* Remap */
+       for(i = 0; i < em->totvert; 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_vert_map2(vmap);
+       }
 
+
+       j = 0;
+       for(i = 0; i < totuv; i++){
+               UvElement *element = vmap->buf[i].next;
+               if(element == NULL){
+                       islandbuf[map[i]].next = NULL;
+                       continue;
+               }
+               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->numOfIslands = nislands;
+       MEM_freeN(stack);
+       MEM_freeN(map);
        return vmap;
 }
-
-/* Will return the UV for which uvi and uvi+1 belong to given edge */
+/* The function below is buggy, should check face first. correct before use */
+/* Will return the UV for which uvi and uvi+1 belong to given edge
 UvElement *EM_get_uv_map_vert_for_edge(UvVertMap2 *vmap, EditMesh *em, 
EditEdge *edge, int initVertexArray)
 {
        int i;
@@ -2497,6 +2591,7 @@
        }
        return NULL;
 }
+*/
 
 UvMapVert *EM_get_uv_map_vert(UvVertMap *vmap, unsigned int v)
 {
@@ -2517,6 +2612,7 @@
        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);
        }
 }

Modified: 
branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c
===================================================================
--- 
branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c   
    2011-07-13 12:16:45 UTC (rev 38359)
+++ 
branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c   
    2011-07-13 12:44:00 UTC (rev 38360)
@@ -1,5 +1,5 @@
 /*
- * $Id: uvedit_island_manager.cpp 38000 2011-07-01 12:06:32Z psy-fi $
+ * $Id: uvedit_island_manager.c 38360 2011-07-01 12:06:32Z psy-fi $
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c  
2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c  
2011-07-13 12:44:00 UTC (rev 38360)
@@ -22,7 +22,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Antony Riakiotakis.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -1735,12 +1735,10 @@
        StitchState *stitch_state = MEM_mallocN(sizeof(StitchState), 
"stitch_state");
        StitchPreviewer *preview = stitch_preview_init();
        EditMesh *em;
-       float limit[2];

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to