[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41353] branches/soc-2011-onion-uv-tools/ source/blender/editors/uvedit/uvedit_ops.c: smart stitching
Antony Riakiotakis
kalast at gmail.com
Sat Oct 29 00:46:02 CEST 2011
Revision: 41353
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41353
Author: psy-fi
Date: 2011-10-28 22:45:59 +0000 (Fri, 28 Oct 2011)
Log Message:
-----------
smart stitching
===================
*Edge stitch functionality is back
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 20:54:45 UTC (rev 41352)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c 2011-10-28 22:45:59 UTC (rev 41353)
@@ -1491,36 +1491,31 @@
-static void stitch_island_calculate_rotation(UvElement *element, int i, StitchState *state, UVVertAverage *uv_average, IslandStitchData *island_stitch_data)
+static void stitch_island_calculate_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, IslandStitchData *island_stitch_data)
{
+ UvElement *element;
EditFace *efa;
MTFace *mt;
int nverts;
float uv1[2], uv2[2];
- UvElement *element2;
float edgecos, edgesin;
- int i2;
+ int index1, index2;
+ element = edge->element;
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->elementMap->vert[(*(&efa->v1 + (element->tfindex + 1)%nverts))->tmp.l];
- for(; element2; element2 = element2->next){
- if(element2->face == efa){
- break;
- }
- }
- i2 = element2 - state->elementMap->buf;
+ index1 = (*(&element->face->v1 + element->tfindex))->tmp.l;
+ index2 = (*(&element->face->v1 + (element->tfindex + 1)%nverts))->tmp.l;
/* 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;
+ uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
+ uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
normalize_v2(uv1);
normalize_v2(uv2);
@@ -1532,7 +1527,6 @@
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;
-
}
@@ -1888,6 +1882,11 @@
edge->flag |= STITCH_STITCHABLE;
edge_iter->flag |= STITCH_STITCHABLE;
+
+ element1->flag |= STITCH_STITCHABLE;
+ element2->flag |= STITCH_STITCHABLE;
+ element_prev1->flag |= STITCH_STITCHABLE;
+ element_prev2->flag |= STITCH_STITCHABLE;
preview->numOfStitchable++;
}
}
@@ -1903,6 +1902,11 @@
edge->flag |= STITCH_STITCHABLE;
edge_iter->flag |= STITCH_STITCHABLE;
+
+ element1->flag |= STITCH_STITCHABLE;
+ element2->flag |= STITCH_STITCHABLE;
+ element_prev1->flag |= STITCH_STITCHABLE;
+ element_prev2->flag |= STITCH_STITCHABLE;
preview->numOfStitchable++;
}
}
@@ -2084,66 +2088,201 @@
/* Second pass, propagate changes to stitchable uvs */
for(i = 0; i < state->selection_size; i++){
- char stitchable = 0;
UvElement *element = (UvElement *)state->selection_stack[i];
if(element->flag & STITCH_STITCHABLE){
UvElement *element_iter = state->elementMap->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
- for(;element_iter; element_iter = element_iter->next){
- MTFace *mt;
- efa = element_iter->face;
- mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+ for(;element_iter;){
+ /* determine if uv stitchable */
+ if(element_iter->separate && element_iter->flag & STITCH_STITCHABLE){
+ MTFace *mt;
+ efa = element_iter->face;
+ mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
- /* determine if uv stitchable */
- if(element_iter->separate){
- if(element_iter->flag & STITCH_STITCHABLE){
- stitchable = 1;
- if(state->snapIslands){
- /* Accumulate each islands' translation from stitchable elements. It is important to do here
- * because in final pass MTFaces get modified and result is zero. */
- island_stitch_data[element_iter->island].translation[0] += averageUvPosition[i].uv[0] - mt->uv[element_iter->tfindex][0];
- island_stitch_data[element_iter->island].translation[1] += averageUvPosition[i].uv[1] - mt->uv[element_iter->tfindex][1];
- island_stitch_data[element_iter->island].numOfElements++;
+ if(state->snapIslands){
+ /* Accumulate each islands' translation from stitchable elements. It is important to do here
+ * because in final pass MTFaces get modified and result is zero. */
+ island_stitch_data[element_iter->island].translation[0] += averageUvPosition[i].uv[0] - mt->uv[element_iter->tfindex][0];
+ island_stitch_data[element_iter->island].translation[1] += averageUvPosition[i].uv[1] - mt->uv[element_iter->tfindex][1];
+ island_stitch_data[element_iter->island].numOfElements++;
+ }
+ /* propagate to coincident uvs */
+ do{
+ efa = element_iter->face;
+ mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+
+ element_iter->flag |= STITCH_PROCESSED;
+ /* Either flush to preview or to the MTFace, if final */
+ if(final){
+ mt->uv[element_iter->tfindex][0] = averageUvPosition[i].uv[0];
+ mt->uv[element_iter->tfindex][1] = averageUvPosition[i].uv[1];
+
+ uvedit_uv_select(scene, efa, mt, element_iter->tfindex);
+ }else if(efa->tmp.l != STITCH_NO_PREVIEW){
+ if(efa->v4){
+ *(preview->previewQuads+efa->tmp.l + element_iter->tfindex*2) = averageUvPosition[i].uv[0];
+ *(preview->previewQuads+efa->tmp.l + element_iter->tfindex*2 + 1) = averageUvPosition[i].uv[1];
+ }else{
+ *(preview->previewTris+efa->tmp.l + element_iter->tfindex*2) = averageUvPosition[i].uv[0];
+ *(preview->previewTris+efa->tmp.l + element_iter->tfindex*2 + 1) = averageUvPosition[i].uv[1];
+ }
}
- } else {
- stitchable = 0;
- }
+
+ /* end of calculations, keep only the selection flag */
+ if( (!state->snapIslands) || ((!stitchAtMidpoints) && (element_iter->island == state->static_island))) {
+ element_iter->flag &= STITCH_SELECTED;
+ }
+
+ element_iter = element_iter->next;
+ }while(element_iter && !element_iter->separate);
+
+ continue;
}
- /* propagate to coincident uvs */
- if(stitchable){
- element_iter->flag |= STITCH_PROCESSED;
- /* Either flush to preview or to the MTFace, if final */
- if(final){
- mt->uv[element_iter->tfindex][0] = averageUvPosition[i].uv[0];
- mt->uv[element_iter->tfindex][1] = averageUvPosition[i].uv[1];
+ element_iter = element_iter->next;
+ }
+ }
+ }
+ MEM_freeN(averageUvPosition);
+ }else{
+ /***************** Edge Case ******************************/
+ UVVertAverage *averageUvPosition = MEM_callocN(state->em->totvert*sizeof(*averageUvPosition), "stitch_uv_average");
- uvedit_uv_select(scene, efa, mt, element_iter->tfindex);
- }else if(efa->tmp.l != STITCH_NO_PREVIEW){
- if(efa->v4){
- *(preview->previewQuads+efa->tmp.l + element_iter->tfindex*2) = averageUvPosition[i].uv[0];
- *(preview->previewQuads+efa->tmp.l + element_iter->tfindex*2 + 1) = averageUvPosition[i].uv[1];
- }else{
- *(preview->previewTris+efa->tmp.l + element_iter->tfindex*2) = averageUvPosition[i].uv[0];
- *(preview->previewTris+efa->tmp.l + element_iter->tfindex*2 + 1) = averageUvPosition[i].uv[1];
+ /* First pass, accumulate final position for stitchable edges */
+ for(i = 0; i < state->selection_size; i++){
+ UvEdge *edge = (UvEdge *)state->selection_stack[i];
+ if(edge->flag & STITCH_STITCHABLE){
+ 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_STITCHABLE){
+ int index1, index2;
+ EditFace *efa2;
+ MTFace *mt1, *mt2;
+ efa = element_iter1->face;
+ efa2 = element_iter2->face;
+ mt1 = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
+ mt2 = CustomData_em_get(&state->em->fdata, efa2->data, CD_MTFACE);
+
+ index1 = (*(&element_iter1->face->v1 + element_iter1->tfindex))->tmp.l;
+ index2 = (*(&element_iter2->face->v1 + element_iter2->tfindex))->tmp.l;
+
+ if(stitchAtMidpoints){
+ averageUvPosition[index1].uv[0] += mt1->uv[element_iter1->tfindex][0];
+ averageUvPosition[index1].uv[1] += mt1->uv[element_iter1->tfindex][1];
+ averageUvPosition[index2].uv[0] += mt2->uv[element_iter2->tfindex][0];
+ averageUvPosition[index2].uv[1] += mt2->uv[element_iter2->tfindex][1];
+ averageUvPosition[index1].count++;
+ averageUvPosition[index2].count++;
+ }else if(element_iter1->island == state->static_island){
+ averageUvPosition[index1].uv[0] = mt1->uv[element_iter1->tfindex][0];
+ averageUvPosition[index1].uv[1] = mt1->uv[element_iter1->tfindex][1];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list