Revision: 41347
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41347
Author:   psy-fi
Date:     2011-10-28 18:46:50 +0000 (Fri, 28 Oct 2011)
Log Message:
-----------
smart stitching
================
*fix incorrect proximity calculation for edge limit stitch
*enable switching selection from edge to uv after operator redo. Previous 
selection gets converted if mode is different than the stored format of 
selection.
This is not 100% tested yet because edge stitch is not working currently but 
should be correct.

--Edge stitch implementation and we're set for review :)

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

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-28 17:00:53 UTC (rev 41346)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c 
2011-10-28 18:46:50 UTC (rev 41347)
@@ -2358,8 +2358,8 @@
                                                                MTFace 
*mtface_orig1 = CustomData_em_get(&state->em->fdata, element1->face->data, 
CD_MTFACE);
                                                                MTFace 
*mtface_iter1 = CustomData_em_get(&state->em->fdata, element_iter1->face->data, 
CD_MTFACE);
 
-                                                               MTFace 
*mtface_orig2 = CustomData_em_get(&state->em->fdata, element1->face->data, 
CD_MTFACE);
-                                                               MTFace 
*mtface_iter2 = CustomData_em_get(&state->em->fdata, element_iter1->face->data, 
CD_MTFACE);
+                                                               MTFace 
*mtface_orig2 = CustomData_em_get(&state->em->fdata, element2->face->data, 
CD_MTFACE);
+                                                               MTFace 
*mtface_iter2 = CustomData_em_get(&state->em->fdata, element_iter2->face->data, 
CD_MTFACE);
 
                                                                
if(fabs(mtface_orig1->uv[element1->tfindex][0] - 
mtface_iter1->uv[element_iter1->tfindex][0]) < state->limitDist
                                                                                
&& fabs(mtface_orig1->uv[element1->tfindex][1] - 
mtface_iter1->uv[element_iter1->tfindex][1]) < state->limitDist
@@ -2638,7 +2638,7 @@
        return 1;
 }
 
-/* Stitch initialization functions */
+/* Stitch hash initialization functions */
 static unsigned int    uv_edge_hash(const void *key){
        UvEdge *edge = (UvEdge *)key;
        return
@@ -2656,6 +2656,165 @@
        return 1;
 }
 
+
+/* Make sure we are selecting only one of a vertex's common uv */
+static void stitch_select_uv(UvElement *element, StitchState *stitch_state, 
void **selection_stack, int *total_selected, int select)
+{
+       int uniqueIndex;
+       /* This works due to setting of tmp in find nearest uv vert */
+       UvElement *element_iter, *unique_element;
+       uniqueIndex = stitch_state->map[element - 
stitch_state->elementMap->buf];
+       unique_element = stitch_state->uvs[uniqueIndex];
+       element_iter = stitch_state->elementMap->vert[(*(&element->face->v1 + 
element->tfindex))->tmp.l];
+       /* first deselect all common uvs */
+       for(; element_iter; element_iter = element_iter->next){
+               if(element_iter->separate){
+                       /* only separators go to selection */
+                       if(element_iter->flag & STITCH_SELECTED){
+                               int i;
+                               element_iter->flag &= ~STITCH_SELECTED;
+                               for(i = 0; i < *total_selected; i++){
+                                       if(((UvElement *)selection_stack[i]) == 
element_iter){
+                                               (*total_selected)--;
+                                               selection_stack[i] = 
selection_stack[*total_selected];
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if(select && !(unique_element->flag & STITCH_SELECTED)){
+               unique_element->flag |= STITCH_SELECTED;
+               selection_stack[(*total_selected)++] = unique_element;
+       }
+}
+
+/* Make sure we are selecting only one of edges with common vertices */
+static void stitch_select_edge(UvEdge *edge, StitchState *state, void 
**selection_stack, int *total_selected, int select)
+{
+       UvElement *element1 = state->uvs[edge->uv1];
+       UvElement *element2 = state->uvs[edge->uv2];
+
+       UvElement *element_iter1 = 
state->elementMap->vert[(*(&element1->face->v1 + element1->tfindex))->tmp.l];
+
+       for(;element_iter1; element_iter1 = element_iter1->next){
+
+               UvElement *element_iter2 = 
state->elementMap->vert[(*(&element2->face->v1 + element2->tfindex))->tmp.l];
+
+               for(;element_iter2; element_iter2 = element_iter2->next){
+                       int uniqueIndex1;
+                       int uniqueIndex2;
+                       UvEdge tmp_edge, *edge_iter;
+
+                       uniqueIndex1 = state->map[element_iter1 - 
state->elementMap->buf];
+                       uniqueIndex2 = state->map[element_iter2 - 
state->elementMap->buf];
+
+                       if(uniqueIndex2 > uniqueIndex1){
+                               tmp_edge.uv1 = uniqueIndex1;
+                               tmp_edge.uv2 = uniqueIndex2;
+                       }else{
+                               tmp_edge.uv1 = uniqueIndex2;
+                               tmp_edge.uv2 = uniqueIndex1;
+                       }
+
+                       edge_iter = (UvEdge *)BLI_ghash_lookup(state->edgeHash, 
&tmp_edge);
+
+                       if(edge_iter && edge_iter->flag & STITCH_SELECTED){
+                               int i;
+                               edge_iter->flag &= ~STITCH_SELECTED;
+                               for(i = 0; i < *total_selected; i++){
+                                       if(((UvEdge *)selection_stack[i]) == 
edge_iter){
+                                               (*total_selected)--;
+                                               selection_stack[i] = 
selection_stack[*total_selected];
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if(select){
+               edge->flag |= STITCH_SELECTED;
+               selection_stack[(*total_selected)++] = edge;
+       }
+}
+
+/* Switch between edge/uv selection mode*/
+static void stitch_switch_mode(StitchState *stitch_state){
+       EditVert *ev;
+       int i;
+
+       void **new_selection = 
MEM_mallocN(sizeof(*new_selection)*stitch_state->elementMap->totalUVs, 
"uv_stitch_selection_stack");
+
+       /* Store Indices to editVerts. */
+       for(ev = stitch_state->em->verts.first, i = 0; ev; ev = ev->next, i++){
+               ev->tmp.l = i;
+       }
+
+       if(stitch_state->mode == EDGE_STITCH){
+               int i;
+               int total_uvs_selected = 0;
+
+               for(i = 0; i < stitch_state->selection_size; i++){
+                       UvEdge *edge = stitch_state->selection_stack[i];
+
+                       stitch_select_uv(stitch_state->uvs[edge->uv1], 
stitch_state, new_selection, &total_uvs_selected, 1);
+                       stitch_select_uv(stitch_state->uvs[edge->uv2], 
stitch_state, new_selection, &total_uvs_selected, 1);
+
+                       edge->flag &= ~STITCH_SELECTED;
+               }
+
+               stitch_state->mode = VERT_STITCH;
+               MEM_freeN(stitch_state->selection_stack);
+               stitch_state->selection_size = total_uvs_selected;
+       }
+       else{
+               int i;
+               int total_edges_selected = 0;
+
+               /* first do a quick evaluation of stitchability of uvs */
+               for(i = 0; i < stitch_state->selection_size; i++){
+                       UvElement *element = (UvElement 
*)stitch_state->selection_stack[i];
+                       UvElement *element_iter = 
stitch_state->elementMap->vert[(*(&element->face->v1 + 
element->tfindex))->tmp.l];
+                       for(; element_iter; element_iter = element_iter->next){
+                               if(element_iter->separate){
+                                       if(stitch_state->use_limit){
+                                               MTFace *mtface_orig = 
CustomData_em_get(&stitch_state->em->fdata, element->face->data, CD_MTFACE);
+                                               MTFace *mtface_iter = 
CustomData_em_get(&stitch_state->em->fdata, element_iter->face->data, 
CD_MTFACE);
+
+                                               
if(fabs(mtface_orig->uv[element->tfindex][0] - 
mtface_iter->uv[element_iter->tfindex][0]) < stitch_state->limitDist
+                                                       && 
fabs(mtface_orig->uv[element->tfindex][1] - 
mtface_iter->uv[element_iter->tfindex][1]) < stitch_state->limitDist){
+                                                       element_iter->flag |= 
STITCH_STITCHABLE;
+                                               }
+                                       }else{
+                                               element_iter->flag |= 
STITCH_STITCHABLE;
+                                       }
+                               }
+                       }
+               }
+               /* Then select one of the edges */
+               for(i = 0; i < stitch_state->total_edges; i++){
+                       UvEdge *edge = stitch_state->edges + i;
+
+                       if(stitch_state->uvs[edge->uv1]->flag & 
STITCH_STITCHABLE && stitch_state->uvs[edge->uv2]->flag & STITCH_STITCHABLE){
+                               stitch_select_edge(edge, stitch_state, 
new_selection, &total_edges_selected, 1);
+                       }
+               }
+
+               /* Cleanup old uv element selection */
+               for(i = 0; i < stitch_state->total_separate_uvs; i++){
+                       ((UvElement *)stitch_state->uvs[i])->flag &= 
~(STITCH_SELECTED | STITCH_STITCHABLE);
+               }
+               stitch_state->mode = EDGE_STITCH;
+               MEM_freeN(stitch_state->selection_stack);
+               stitch_state->selection_size = total_edges_selected;
+       }
+
+       stitch_state->selection_stack = new_selection;
+}
+
+
 static int stitch_init(bContext *C, wmOperator *op)
 {
        int counter = 0, i;
@@ -2810,24 +2969,64 @@
        stitch_state->selection_size = 0;
 
        /* Fill selection stack */
+
+       /* Load old selection if redoing operator with different settings */
        if(RNA_property_is_set(op->ptr, "selection")){
+               unsigned int oldMode =  RNA_enum_get(op->ptr, "mode_old");
                int faceIndex, elementIndex, uniqueIndex;
                UvElement *element;
 
                EM_init_index_arrays(em, 0, 0, 1);
 
-               RNA_BEGIN(op->ptr, itemptr, "selection") {
-                       faceIndex = RNA_int_get(&itemptr, "face_index");
-                       elementIndex = RNA_int_get(&itemptr, "element_index");
-                       element = get_uv_element(stitch_state->elementMap, 
EM_get_face_for_index(faceIndex), elementIndex);
-                       uniqueIndex = stitch_state->map[element - 
stitch_state->elementMap->buf];
-                       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;
+
+                       RNA_BEGIN(op->ptr, itemptr, "selection") {
+                               faceIndex = RNA_int_get(&itemptr, "face_index");
+                               elementIndex = RNA_int_get(&itemptr, 
"element_index");
+                               efa = EM_get_face_for_index(faceIndex);
+                               element = 
get_uv_element(stitch_state->elementMap, efa, elementIndex);
+                               uniqueIndex = stitch_state->map[element - 
stitch_state->elementMap->buf];
+
+                               if(oldMode == VERT_STITCH){
+                                       
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;
+                                       }
+                               }else{
+                                       UvEdge *edge, tmp_edge;
+                                       int uniqueIndex2, nverts;
+                                       UvElement *element2;
+
+                                       nverts = efa->v4? 4 : 3;
+
+                                       element2 = 
get_uv_element(stitch_state->elementMap, efa, (elementIndex+1)%nverts);
+                                       uniqueIndex2 = 
stitch_state->map[element2 - stitch_state->elementMap->buf];
+
+                                       if(uniqueIndex2 > uniqueIndex){
+                                               tmp_edge.uv1 = uniqueIndex;
+                                               tmp_edge.uv2 = uniqueIndex2;
+                                       }else{
+                                               tmp_edge.uv1 = uniqueIndex2;
+                                               tmp_edge.uv2 = uniqueIndex;
+                                       }
+
+                                       edge = (UvEdge 
*)BLI_ghash_lookup(stitch_state->edgeHash, &tmp_edge);
+
+                                       if(!(edge->flag & STITCH_SELECTED)){
+                                               
stitch_state->selection_stack[stitch_state->selection_size++] = edge;
+                                               edge->flag |= STITCH_SELECTED;
+                                       }
+                               }
                        }
+                       RNA_END;
+
+               EM_free_index_arrays();
+               /* Clear the selection */
+               RNA_collection_clear(op->ptr, "selection");
+
+               if(stitch_state->mode != oldMode){
+                       stitch_state->mode = oldMode;
+                       stitch_switch_mode(stitch_state);
                }
-               RNA_END;
-               EM_free_index_arrays();
        } else {
                for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
                        int numOfVerts;
@@ -2893,11 +3092,13 @@
                RNA_boolean_set(op->ptr, "snap_islands", 
stitch_state->snapIslands);
                RNA_int_set(op->ptr, "static_island", 
stitch_state->static_island);
                RNA_enum_set(op->ptr, "mode", stitch_state->mode);
+               RNA_enum_set(op->ptr, "mode_old", stitch_state->mode);
                RNA_boolean_set(op->ptr, "midpoint_snap", 
stitch_state->midpoints);
 
                for(i = 0, efa = stitch_state->em->faces.first; efa; efa = 
efa->next, i++){
                        efa->tmp.l = i;
                }
+

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