Revision: 38567
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38567
Author:   psy-fi
Date:     2011-07-21 16:15:31 +0000 (Thu, 21 Jul 2011)
Log Message:
-----------
smart stitch
============================
-Island rotation works in preview, spoiled in final. Fix coming soon

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

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-21 16:05:21 UTC (rev 38566)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c  
2011-07-21 16:15:31 UTC (rev 38567)
@@ -1116,7 +1116,7 @@
        ot->poll= ED_operator_uvedit;
 }
 
-/* ******************** stitch operator **************** */
+/* ********************** smart stitch operator *********************** */
 
 
 struct IslandStitchData;
@@ -1130,6 +1130,7 @@
        /* Used for rotation, the island will rotate around this point */
        float medianPoint[2];
        int numOfElements;
+       int numOfEdges;
        /* Flag to remember if island has been aded for preview */
        char addedForPreview;
 }IslandStitchData;
@@ -1260,7 +1261,20 @@
        }
 }
 
+static void stitch_island_rotate(float rotation, float medianPoint[2], float 
uv[2]){
+       float uv_rotation_result[2];
 
+       uv[0] -= medianPoint[0];
+       uv[1] -= medianPoint[1];
+
+       uv_rotation_result[0] = cos(rotation)*uv[0] - sin(rotation)*uv[1];
+       uv_rotation_result[1] = sin(rotation)*uv[0] + cos(rotation)*uv[1];
+
+       uv[0] = uv_rotation_result[0] + medianPoint[0];
+       uv[1] = uv_rotation_result[1] + medianPoint[1];
+}
+
+
 /* Calculate snapping for islands */
 static void stitch_calculate_island_snapping(StitchState *state, 
StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){
        int i;
@@ -1268,41 +1282,51 @@
        MTFace *mt;
        UvElement *element;
 
-       if(state->snapIslands){
-               for(i = 0; i <  state->vmap->numOfIslands; i++){
-                       if(island_stitch_data[i].addedForPreview){
-                               int previewIslandUVs = 0, j;
-
-                               island_stitch_data[i].translation[0] /= 
island_stitch_data[i].numOfElements;
-                               island_stitch_data[i].translation[1] /= 
island_stitch_data[i].numOfElements;
-
-                               if(i == state->vmap->numOfIslands-1){
-                                       previewIslandUVs = 
state->vmap->numOfUVs - state->vmap->islandIndices[i];
-                               }else{
-                                       previewIslandUVs = 
state->vmap->islandIndices[i+1] - state->vmap->islandIndices[i];
-                               }
-
-                               element = 
&state->vmap->buf[state->vmap->islandIndices[i]];
-                               for(j = 0; j < previewIslandUVs; j++, 
element++){
-                                       /* stitchable uvs have already been 
processed, don't process */
-                                       if(!(element->flag & 
STITCH_STITCHABLE)){
-                                               efa = element->face;
-                                               mt = 
CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
-                                               if(final){
-                                                       
mt->uv[element->tfindex][0] += island_stitch_data[i].translation[0];
-                                                       
mt->uv[element->tfindex][1] += island_stitch_data[i].translation[1];
+       for(i = 0; i <  state->vmap->numOfIslands; i++){
+               if(island_stitch_data[i].addedForPreview){
+                       int previewIslandUVs = 0, j;
+                       /* check to avoid divide by 0 */
+                       if(state->mode == EDGE_STITCH){
+                               island_stitch_data[i].rotation /= 
island_stitch_data[i].numOfEdges;
+                               island_stitch_data[i].medianPoint[0] /= 
island_stitch_data[i].numOfEdges;
+                               island_stitch_data[i].medianPoint[1] /= 
island_stitch_data[i].numOfEdges;
+                       }
+                       island_stitch_data[i].translation[0] /= 
island_stitch_data[i].numOfElements;
+                       island_stitch_data[i].translation[1] /= 
island_stitch_data[i].numOfElements;
+                       if(i == state->vmap->numOfIslands-1){
+                               previewIslandUVs = state->vmap->numOfUVs - 
state->vmap->islandIndices[i];
+                       }else{
+                               previewIslandUVs = 
state->vmap->islandIndices[i+1] - state->vmap->islandIndices[i];
+                       }
+                       element = 
&state->vmap->buf[state->vmap->islandIndices[i]];
+                       for(j = 0; j < previewIslandUVs; j++, element++){
+                               /* stitchable uvs have already been processed, 
don't process */
+                               if(!(element->flag & STITCH_STITCHABLE)){
+                                       efa = element->face;
+                                       mt = 
CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+                                       if(final){
+                                               if(state->mode == EDGE_STITCH){
+                                                       
stitch_island_rotate(island_stitch_data[i].rotation, 
island_stitch_data[i].medianPoint, mt->uv[element->tfindex]);
                                                }
-                                               else{
-                                                       if(efa->v4){
-                                                               
preview->previewQuads[efa->tmp.l + 2*element->tfindex] += 
island_stitch_data[i].translation[0];
-                                                               
preview->previewQuads[efa->tmp.l + 2*element->tfindex + 1] += 
island_stitch_data[i].translation[1];
+                                               mt->uv[element->tfindex][0] += 
island_stitch_data[i].translation[0];
+                                               mt->uv[element->tfindex][1] += 
island_stitch_data[i].translation[1];
+                                       }
+                                       else{
+                                               if(efa->v4){
+                                                       if(state->mode == 
EDGE_STITCH){
+                                                               
stitch_island_rotate(island_stitch_data[i].rotation, 
island_stitch_data[i].medianPoint, &preview->previewQuads[efa->tmp.l + 
2*element->tfindex]);
                                                        }
-                                                       else {
-                                                               
preview->previewTris[efa->tmp.l + 2*element->tfindex]  += 
island_stitch_data[i].translation[0];
-                                                               
preview->previewTris[efa->tmp.l + 2*element->tfindex + 1] += 
island_stitch_data[i].translation[1];
+                                                       
preview->previewQuads[efa->tmp.l + 2*element->tfindex] += 
island_stitch_data[i].translation[0];
+                                                       
preview->previewQuads[efa->tmp.l + 2*element->tfindex + 1] += 
island_stitch_data[i].translation[1];
+                                               }
+                                               else {
+                                                       if(state->mode == 
EDGE_STITCH){
+                                                               
stitch_island_rotate(island_stitch_data[i].rotation, 
island_stitch_data[i].medianPoint, &preview->previewTris[efa->tmp.l + 
2*element->tfindex]);
                                                        }
-                                                       element->flag = 0;
+                                                       
preview->previewTris[efa->tmp.l + 2*element->tfindex]  += 
island_stitch_data[i].translation[0];
+                                                       
preview->previewTris[efa->tmp.l + 2*element->tfindex + 1] += 
island_stitch_data[i].translation[1];
                                                }
+                                               element->flag = 0;
                                        }
                                }
                        }
@@ -1310,6 +1334,50 @@
        }
 }
 
+static void stitch_island_calculate_rotation(UvElement *element, int i, 
StitchState *state, UVVertAverage *uv_average, IslandStitchData 
*island_stitch_data)
+{
+       EditFace *efa;
+       MTFace *mt;
+       int nverts;
+       float uv1[2], uv2[2];
+       UvElement *element2;
+       float edgecos, edgesin;
+       int i2;
+
+       efa = element->face;
+       nverts = (efa->v4)? 4 : 3;
+       mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+
+       /* find second UV element */
+       element2 = state->vmap->vert[(*(&efa->v1 + (element->tfindex + 
1)%nverts))->tmp.l];
+       for(; element2; element2 = element2->next){
+               if(element2->face == efa){
+                       break;
+               }
+       }
+       i2 = element2 - state->vmap->buf;
+
+       /* The idea here is to take the directions of the edges and find the 
rotation between final and initial
+       * direction. This, using inner and outer vector products, gives the 
angle. Directions are differences so... */
+       uv1[0] = mt->uv[(element->tfindex + 1)%nverts][0] - 
mt->uv[element->tfindex][0];
+       uv1[1] = mt->uv[(element->tfindex + 1)%nverts][1] - 
mt->uv[element->tfindex][1];
+
+       uv2[0] = uv_average[i2].uv[0]/uv_average[i2].count - 
uv_average[i].uv[0]/uv_average[i].count;
+       uv2[1] = uv_average[i2].uv[1]/uv_average[i2].count - 
uv_average[i].uv[1]/uv_average[i].count;
+
+       normalize_v2(uv1);
+       normalize_v2(uv2);
+
+       edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1];
+       edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1];
+
+       island_stitch_data[element->island].numOfEdges++;
+       island_stitch_data[element->island].rotation += (edgesin > 0)? 
acos(edgecos): -acos(edgecos);
+       island_stitch_data[element->island].medianPoint[0] += 
(mt->uv[(element->tfindex + 1)%nverts][0] + mt->uv[element->tfindex][0]) / 2.0;
+       island_stitch_data[element->island].medianPoint[1] += 
(mt->uv[(element->tfindex + 1)%nverts][1] + mt->uv[element->tfindex][1]) / 2.0;
+
+}
+
 /* This function prepares the data of the previewer for display */
 static int stitch_process_data(StitchState *state, int final, Scene *scene, 
int doIndexInit)
 {
@@ -1792,26 +1860,8 @@
 
                                        /* we will have to calculate the 
rotation of the edges here */
                                        if(state->snapIslands && element->flag 
& STITCH_EDGE_STITCHABLE){
-                                               float uv1[2], uv2[2];
-
-                                               efa = element->face;
-                                               nverts = (efa->v4)? 4 : 3;
-                                               mt = 
CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
-
-                                               /* grab original uv's*/
-                                               uv1[0] = 
mt->uv[(element->tfindex + 1)%nverts][0] - mt->uv[element->tfindex][0];
-                                               uv1[1] = 
mt->uv[(element->tfindex + 1)%nverts][1] - mt->uv[element->tfindex][1];
-
-                                               //uv2[0] = ;
-                                               //uv2[1] = ;
-
-                                               /* The idea here is to take the 
directions of the edges and find the rotation between final and initial
-                                                * edge */
-                                               normalize_v2(uv1);
-                                               //normalize_v2(uv2);
-
+                                               
stitch_island_calculate_rotation(element, i, state, uv_average, 
island_stitch_data);
                                        }
-
                                        if(element->flag & 
STITCH_EDGE_STITCHABLE){
                                                
preview->previewOrigColors[bufferIterator*2] = 0x0000FF00;
                                                
preview->previewOrigColors[bufferIterator*2 + 1] = 0x0000FF00;
@@ -1827,8 +1877,9 @@
                                element->flag = 0;
                        }
                }
-
-               stitch_calculate_island_snapping(state, preview, 
island_stitch_data, 0);
+               if(state->snapIslands){
+                       stitch_calculate_island_snapping(state, preview, 
island_stitch_data, 0);
+               }
        }
 
 
@@ -1849,6 +1900,10 @@
                                        
island_stitch_data[element->island].translation[0] += uv[0] - 
mt->uv[element->tfindex][0];
                                        
island_stitch_data[element->island].translation[1] += uv[1] - 
mt->uv[element->tfindex][1];
                                        
island_stitch_data[element->island].numOfElements++;
+
+                                       if(element->flag & 
STITCH_EDGE_STITCHABLE){
+                                               
stitch_island_calculate_rotation(element, i, state, uv_average, 
island_stitch_data);
+                                       }
                                }
 
                                mt->uv[element->tfindex][0] = uv[0];
@@ -1857,7 +1912,9 @@
                                uvedit_uv_select(scene, efa, mt, 
element->tfindex);
                        }
                }
-               stitch_calculate_island_snapping(state, preview, 
island_stitch_data, 1);
+               if(state->snapIslands){
+                       stitch_calculate_island_snapping(state, preview, 
island_stitch_data, 1);
+               }
        }
 
        if(island_stitch_data)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to