[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41347] branches/soc-2011-onion-uv-tools/ source/blender/editors/uvedit/uvedit_ops.c: smart stitching
Antony Riakiotakis
kalast at gmail.com
Fri Oct 28 20:46:51 CEST 2011
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. @@
More information about the Bf-blender-cvs
mailing list