[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38567] branches/soc-2011-onion/source/ blender/editors/uvedit/uvedit_ops.c: smart stitch
Antony Riakiotakis
kalast at gmail.com
Thu Jul 21 18:15:33 CEST 2011
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)
More information about the Bf-blender-cvs
mailing list