Revision: 40859
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40859
Author:   psy-fi
Date:     2011-10-08 20:38:41 +0000 (Sat, 08 Oct 2011)
Log Message:
-----------
Smart Stitch
============
*create edge data structures on initialization
*remove old stitch vertex selection code path

Modified Paths:
--------------
    
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
    branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c

Modified: 
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
===================================================================
--- 
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
    2011-10-08 17:28:37 UTC (rev 40858)
+++ 
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
    2011-10-08 20:38:41 UTC (rev 40859)
@@ -609,8 +609,8 @@
                        return NULL;
                }
                /* fill the edges with data */
-               for(i = 0; !BLI_ghashIterator_isDone(ghi); 
BLI_ghashIterator_step(ghi), i++){
-                       data->uvedges[i] = *((UvEdge 
*)BLI_ghashIterator_getKey(ghi));
+               for(i = 0; !BLI_ghashIterator_isDone(ghi); 
BLI_ghashIterator_step(ghi)){
+                       data->uvedges[i++] = *((UvEdge 
*)BLI_ghashIterator_getKey(ghi));
                }
                data->totalUvEdges = BLI_ghash_size(edgeHash);
 

Modified: 
branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c
===================================================================
--- branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c 
2011-10-08 17:28:37 UTC (rev 40858)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c 
2011-10-08 20:38:41 UTC (rev 40859)
@@ -1297,13 +1297,11 @@
        EditMesh *em;
        /* element map for getting info about uv connectivity */
        UvElementMap *elementMap;
-
-#ifdef STITCHNEW
        /* Edge container */
        UvEdge *uvedges;
        /* container of first of a group of coincident uvs, these will be 
operated upon */
        UvElement **uvs;
-       int numOfSeparateUvs;
+       int total_separate_uvs;
        /* maps uvelements to their first coincident uv */
        int *map;
        /* hold selection related information */
@@ -1311,7 +1309,11 @@
        int selection_size;
        /* island that stays in place */
        int static_island;
-#endif
+       /* For fast edge lookup... */
+       GHash *edgeHash;
+       /* ...And actual edge storage */
+       UvEdge *edges;
+       int total_edges;
 } StitchState;
 
 
@@ -1329,6 +1331,7 @@
 #define STITCH_SELECTED 1
 #define STITCH_STITCHABLE 2
 #define STITCH_PROCESSED 4
+#define STITCH_BOUNDARY 8
 #endif
 /* Previewer stuff (see uvedit_intern.h for more info) */
 static StitchPreviewer *_stitch_preview;
@@ -1389,6 +1392,7 @@
        return _stitch_preview;
 }
 
+
 /* This function updates the header of the UV editor when the stitch tool 
updates its settings */
 static void stitch_update_header(StitchState *stitch_state, bContext *C)
 {
@@ -2176,7 +2180,12 @@
                if(stitch_state->map){
                        MEM_freeN(stitch_state->map);
                }
-
+               if(stitch_state->edgeHash){
+                       BLI_ghash_free(stitch_state->edgeHash, NULL, NULL);
+               }
+               if(stitch_state->edges){
+                       MEM_freeN(stitch_state->edges);
+               }
                MEM_freeN(stitch_state);
        }
 }
@@ -2359,7 +2368,7 @@
                }
                if(state->mode == VERT_STITCH){
                        /* Fill the preview buffers with stitchable only uvs */
-                       for(i = 0; i < state->numOfSeparateUvs; i++){
+                       for(i = 0; i < state->total_separate_uvs; i++){
                                UvElement *element = (UvElement *)state->uvs[i];
                                if(element->flag & STITCH_STITCHABLE){
                                        MTFace *mt;
@@ -2493,11 +2502,30 @@
        return 1;
 }
 
+/* Stitch initialization functions */
+static unsigned int    uv_edge_hash(const void *key){
+       UvEdge *edge = (UvEdge *)key;
+       return
+               BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
+               BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
+}
 
+static int uv_edge_compare(const void *a, const void *b){
+       UvEdge *edge1 = (UvEdge *)a;
+       UvEdge *edge2 = (UvEdge *)b;
+
+       if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){
+               return 0;
+       }
+       return 1;
+}
+
 static int stitch_init(bContext *C, wmOperator *op)
 {
        int counter = 0, i;
        EditFace *efa;
+       GHashIterator* ghi;
+       UvEdge *edges;
        StitchState *stitch_state = MEM_mallocN(sizeof(StitchState), 
"stitch_state");
        StitchPreviewer *preview = stitch_preview_init();
        Scene *scene = CTX_data_scene(C);
@@ -2536,13 +2564,18 @@
                }
        }
 
+       /* Allocate the unique uv buffers */
        stitch_state->uvs = MEM_mallocN(sizeof(*stitch_state->uvs)*counter, 
"uv_stitch_unique_uvs");
-       stitch_state->numOfSeparateUvs = counter;
+       stitch_state->total_separate_uvs = counter;
        /* we can at most have totalUVs edges or uvs selected. Actually they 
are less, considering we store only
         * unique uvs for processing but I am accounting for all bizarre cases, 
especially for edges, this way */
        stitch_state->selection_stack = 
MEM_mallocN(sizeof(*stitch_state->selection_stack)*stitch_state->elementMap->totalUVs,
 "uv_stitch_selection_stack");
        stitch_state->map = 
MEM_mallocN(sizeof(*stitch_state->map)*stitch_state->elementMap->totalUVs, 
"uv_stitch_unique_map");
-       if(!stitch_state->selection_stack || !stitch_state->uvs || 
!stitch_state->map){
+       /* Allcate the edge stack */
+       stitch_state->edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, 
"stitch_edge_hash");
+       edges = MEM_mallocN(sizeof(*edges)*stitch_state->elementMap->totalUVs, 
"stitch_all_edges");
+
+       if(!stitch_state->selection_stack || !stitch_state->uvs || 
!stitch_state->map || !stitch_state->edgeHash || !edges){
                stitch_state_delete(stitch_state);
                return 0;
        }
@@ -2566,6 +2599,72 @@
                }
        }
 
+       /* Now, on to generate our uv connectivity data */
+       for(efa = stitch_state->em->faces.first, counter = 0; efa; efa = 
efa->next){
+               int nverts = efa->v4 ? 4 : 3;
+               for(i = 0; i < nverts; i++){
+                       int offset1, itmp1 = 
get_uv_element(stitch_state->elementMap, efa, i) - 
stitch_state->elementMap->buf;
+                       int offset2, itmp2 = 
get_uv_element(stitch_state->elementMap, efa, (i+1)%nverts) - 
stitch_state->elementMap->buf;
+
+                       offset1 = stitch_state->map[itmp1];
+                       offset2 = stitch_state->map[itmp2];
+
+                       edges[counter].flag = 0;
+                       /* using an order policy, sort uvs according to address 
space. This avoids
+                        * Having two different UvEdges with the same uvs on 
different positions  */
+                       if(offset1 < offset2){
+                               edges[counter].uv1 = offset1;
+                               edges[counter].uv2 = offset2;
+                       }
+                       else{
+                               edges[counter].uv1 = offset2;
+                               edges[counter].uv2 = offset1;
+                       }
+                       /* Hack! Set the value of the key to its flag. Now we 
can set the flag when an edge exists twice :) */
+                       if(BLI_ghash_haskey(stitch_state->edgeHash, 
&edges[counter])){
+                               char *flag = 
BLI_ghash_lookup(stitch_state->edgeHash, &edges[counter]);
+                               *flag = 0;
+                       }
+                       else{
+                               /* Hack mentioned */
+                               BLI_ghash_insert(stitch_state->edgeHash, 
&edges[counter], &edges[counter].flag);
+                               edges[counter].flag = STITCH_BOUNDARY;
+                       }
+                       counter++;
+               }
+       }
+
+       ghi = BLI_ghashIterator_new(stitch_state->edgeHash);
+       stitch_state->edges = 
MEM_mallocN(sizeof(*stitch_state->edges)*BLI_ghash_size(stitch_state->edgeHash),
 "stitch_edges");
+       if(!ghi || !stitch_state->edges){
+               MEM_freeN(edges);
+               stitch_state_delete(stitch_state);
+               return 0;
+       }
+       /* fill the edges with data */
+       for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
+               stitch_state->edges[i++] = *((UvEdge 
*)BLI_ghashIterator_getKey(ghi));
+       }
+       stitch_state->total_edges = BLI_ghash_size(stitch_state->edgeHash);
+
+       /* cleanup temporary stuff */
+       BLI_ghashIterator_free(ghi);
+       MEM_freeN(edges);
+
+       /* refill hash with new pointers */
+       BLI_ghash_free(stitch_state->edgeHash, NULL, NULL);
+       stitch_state->edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, 
"stitch_edge_hash");
+       for(i = 0; i < stitch_state->total_edges; i++){
+               BLI_ghash_insert(stitch_state->edgeHash, &stitch_state->edges + 
i, NULL);
+       }
+
+       for(i = 0; i < stitch_state->total_edges; i++){
+               if(stitch_state->edges[i].flag & STITCH_BOUNDARY){
+                       stitch_state->uvs[stitch_state->edges[i].uv1]->flag |= 
STITCH_BOUNDARY;
+                       stitch_state->uvs[stitch_state->edges[i].uv2]->flag |= 
STITCH_BOUNDARY;
+               }
+       }
+
        stitch_state->selection_size = 0;
 
        /* Fill selection stack */
@@ -2581,26 +2680,26 @@
                }
                RNA_END;
        } else {
-       for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
-               int numOfVerts;
-               MTFace *mt;
-               mt = CustomData_em_get(&stitch_state->em->fdata, efa->data, 
CD_MTFACE);
-               numOfVerts = efa->v4 ? 4 : 3;
+               for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
+                       int numOfVerts;
+                       MTFace *mt;
+                       mt = CustomData_em_get(&stitch_state->em->fdata, 
efa->data, CD_MTFACE);
+                       numOfVerts = efa->v4 ? 4 : 3;
 
-               for(i = 0; i < numOfVerts; i++){
-                       if(uvedit_uv_selected(scene, efa, mt, i)){
-                               int uniqueIndex;
-                               UvElement *element = 
get_uv_element(stitch_state->elementMap, efa, i);
-                               uniqueIndex = stitch_state->map[element - 
stitch_state->elementMap->buf];
-                               /* count a uv only once, or duplicates will 
happen */
-                               if(!(stitch_state->uvs[uniqueIndex]->flag & 
STITCH_SELECTED)){
-                                       
stitch_state->selection_stack[stitch_state->selection_size++] = 
stitch_state->uvs[uniqueIndex];
-                                       stitch_state->uvs[uniqueIndex]->flag |= 
STITCH_SELECTED;
+                       for(i = 0; i < numOfVerts; i++){
+                               if(uvedit_uv_selected(scene, efa, mt, i)){
+                                       int uniqueIndex;
+                                       UvElement *element = 
get_uv_element(stitch_state->elementMap, efa, i);
+                                       uniqueIndex = stitch_state->map[element 
- stitch_state->elementMap->buf];
+                                       /* count a uv only once, or duplicates 
will happen */
+                                       
if(!(stitch_state->uvs[uniqueIndex]->flag & STITCH_SELECTED)){
+                                               
stitch_state->selection_stack[stitch_state->selection_size++] = 
stitch_state->uvs[uniqueIndex];
+                                               
stitch_state->uvs[uniqueIndex]->flag |= STITCH_SELECTED;
+                                       }
                                }
                        }
                }
        }
-       }
 
        if(!stitch_process_data(stitch_state, scene, 0, 1)){
                stitch_state_delete(stitch_state);
@@ -2812,7 +2911,6 @@
                                         * becomes dependent on the order of 
stitching different uv's corresponding to the same vertex */
                                        if(stitch_state->mode == VERT_STITCH)
                                        {
-                                               #ifdef STITCHNEW
                                                int uniqueIndex;
                                                /* This works due to setting of 
tmp in find nearest uv vert */
                                                UvElement *element_iter, 
*unique_element, *element = get_uv_element(stitch_state->elementMap, hit.efa, 
hit.uv);
@@ -2841,39 +2939,6 @@
                                                        unique_element->flag |= 
STITCH_SELECTED;
                                                        
stitch_state->selection_stack[stitch_state->selection_size++] = unique_element;
                                                }
-                                               #else
-                                               UvElement *element = 
stitch_state->elementMap->vert[(*(&hit.efa->v1 + hit.uv))->tmp.l];
-                                               UvElement *firstCoincident;
-                                               for(; element; element = 
element->next)
-                                               {
-                                                       MTFace *tface;
-                                                       tface =  
CustomData_em_get(&stitch_state->em->fdata, element->face->data, CD_MTFACE);
-                                                       if(element->separate)
-                                                               firstCoincident 
= element;
-                                                       if(element->face == 
hit.efa){

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