Revision: 40859
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40859
Author: psy-fi
Date: 2011-10-08 20:38:41 +0000 (Sat, 08 Oct 2011)
Log Message:
-----------
Smart Stitch
============
*create edge data structures on initialization
*remove old stitch vertex selection code path
Modified Paths:
--------------
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c
Modified:
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
===================================================================
---
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
2011-10-08 17:28:37 UTC (rev 40858)
+++
branches/soc-2011-onion-uv-tools/source/blender/editors/sculpt_paint/sculpt_uv.c
2011-10-08 20:38:41 UTC (rev 40859)
@@ -609,8 +609,8 @@
return NULL;
}
/* fill the edges with data */
- for(i = 0; !BLI_ghashIterator_isDone(ghi);
BLI_ghashIterator_step(ghi), i++){
- data->uvedges[i] = *((UvEdge
*)BLI_ghashIterator_getKey(ghi));
+ for(i = 0; !BLI_ghashIterator_isDone(ghi);
BLI_ghashIterator_step(ghi)){
+ data->uvedges[i++] = *((UvEdge
*)BLI_ghashIterator_getKey(ghi));
}
data->totalUvEdges = BLI_ghash_size(edgeHash);
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-08 17:28:37 UTC (rev 40858)
+++ branches/soc-2011-onion-uv-tools/source/blender/editors/uvedit/uvedit_ops.c
2011-10-08 20:38:41 UTC (rev 40859)
@@ -1297,13 +1297,11 @@
EditMesh *em;
/* element map for getting info about uv connectivity */
UvElementMap *elementMap;
-
-#ifdef STITCHNEW
/* Edge container */
UvEdge *uvedges;
/* container of first of a group of coincident uvs, these will be
operated upon */
UvElement **uvs;
- int numOfSeparateUvs;
+ int total_separate_uvs;
/* maps uvelements to their first coincident uv */
int *map;
/* hold selection related information */
@@ -1311,7 +1309,11 @@
int selection_size;
/* island that stays in place */
int static_island;
-#endif
+ /* For fast edge lookup... */
+ GHash *edgeHash;
+ /* ...And actual edge storage */
+ UvEdge *edges;
+ int total_edges;
} StitchState;
@@ -1329,6 +1331,7 @@
#define STITCH_SELECTED 1
#define STITCH_STITCHABLE 2
#define STITCH_PROCESSED 4
+#define STITCH_BOUNDARY 8
#endif
/* Previewer stuff (see uvedit_intern.h for more info) */
static StitchPreviewer *_stitch_preview;
@@ -1389,6 +1392,7 @@
return _stitch_preview;
}
+
/* This function updates the header of the UV editor when the stitch tool
updates its settings */
static void stitch_update_header(StitchState *stitch_state, bContext *C)
{
@@ -2176,7 +2180,12 @@
if(stitch_state->map){
MEM_freeN(stitch_state->map);
}
-
+ if(stitch_state->edgeHash){
+ BLI_ghash_free(stitch_state->edgeHash, NULL, NULL);
+ }
+ if(stitch_state->edges){
+ MEM_freeN(stitch_state->edges);
+ }
MEM_freeN(stitch_state);
}
}
@@ -2359,7 +2368,7 @@
}
if(state->mode == VERT_STITCH){
/* Fill the preview buffers with stitchable only uvs */
- for(i = 0; i < state->numOfSeparateUvs; i++){
+ for(i = 0; i < state->total_separate_uvs; i++){
UvElement *element = (UvElement *)state->uvs[i];
if(element->flag & STITCH_STITCHABLE){
MTFace *mt;
@@ -2493,11 +2502,30 @@
return 1;
}
+/* Stitch initialization functions */
+static unsigned int uv_edge_hash(const void *key){
+ UvEdge *edge = (UvEdge *)key;
+ return
+ BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
+ BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
+}
+static int uv_edge_compare(const void *a, const void *b){
+ UvEdge *edge1 = (UvEdge *)a;
+ UvEdge *edge2 = (UvEdge *)b;
+
+ if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){
+ return 0;
+ }
+ return 1;
+}
+
static int stitch_init(bContext *C, wmOperator *op)
{
int counter = 0, i;
EditFace *efa;
+ GHashIterator* ghi;
+ UvEdge *edges;
StitchState *stitch_state = MEM_mallocN(sizeof(StitchState),
"stitch_state");
StitchPreviewer *preview = stitch_preview_init();
Scene *scene = CTX_data_scene(C);
@@ -2536,13 +2564,18 @@
}
}
+ /* Allocate the unique uv buffers */
stitch_state->uvs = MEM_mallocN(sizeof(*stitch_state->uvs)*counter,
"uv_stitch_unique_uvs");
- stitch_state->numOfSeparateUvs = counter;
+ stitch_state->total_separate_uvs = counter;
/* we can at most have totalUVs edges or uvs selected. Actually they
are less, considering we store only
* unique uvs for processing but I am accounting for all bizarre cases,
especially for edges, this way */
stitch_state->selection_stack =
MEM_mallocN(sizeof(*stitch_state->selection_stack)*stitch_state->elementMap->totalUVs,
"uv_stitch_selection_stack");
stitch_state->map =
MEM_mallocN(sizeof(*stitch_state->map)*stitch_state->elementMap->totalUVs,
"uv_stitch_unique_map");
- if(!stitch_state->selection_stack || !stitch_state->uvs ||
!stitch_state->map){
+ /* Allcate the edge stack */
+ stitch_state->edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare,
"stitch_edge_hash");
+ edges = MEM_mallocN(sizeof(*edges)*stitch_state->elementMap->totalUVs,
"stitch_all_edges");
+
+ if(!stitch_state->selection_stack || !stitch_state->uvs ||
!stitch_state->map || !stitch_state->edgeHash || !edges){
stitch_state_delete(stitch_state);
return 0;
}
@@ -2566,6 +2599,72 @@
}
}
+ /* Now, on to generate our uv connectivity data */
+ for(efa = stitch_state->em->faces.first, counter = 0; efa; efa =
efa->next){
+ int nverts = efa->v4 ? 4 : 3;
+ for(i = 0; i < nverts; i++){
+ int offset1, itmp1 =
get_uv_element(stitch_state->elementMap, efa, i) -
stitch_state->elementMap->buf;
+ int offset2, itmp2 =
get_uv_element(stitch_state->elementMap, efa, (i+1)%nverts) -
stitch_state->elementMap->buf;
+
+ offset1 = stitch_state->map[itmp1];
+ offset2 = stitch_state->map[itmp2];
+
+ edges[counter].flag = 0;
+ /* using an order policy, sort uvs according to address
space. This avoids
+ * Having two different UvEdges with the same uvs on
different positions */
+ if(offset1 < offset2){
+ edges[counter].uv1 = offset1;
+ edges[counter].uv2 = offset2;
+ }
+ else{
+ edges[counter].uv1 = offset2;
+ edges[counter].uv2 = offset1;
+ }
+ /* Hack! Set the value of the key to its flag. Now we
can set the flag when an edge exists twice :) */
+ if(BLI_ghash_haskey(stitch_state->edgeHash,
&edges[counter])){
+ char *flag =
BLI_ghash_lookup(stitch_state->edgeHash, &edges[counter]);
+ *flag = 0;
+ }
+ else{
+ /* Hack mentioned */
+ BLI_ghash_insert(stitch_state->edgeHash,
&edges[counter], &edges[counter].flag);
+ edges[counter].flag = STITCH_BOUNDARY;
+ }
+ counter++;
+ }
+ }
+
+ ghi = BLI_ghashIterator_new(stitch_state->edgeHash);
+ stitch_state->edges =
MEM_mallocN(sizeof(*stitch_state->edges)*BLI_ghash_size(stitch_state->edgeHash),
"stitch_edges");
+ if(!ghi || !stitch_state->edges){
+ MEM_freeN(edges);
+ stitch_state_delete(stitch_state);
+ return 0;
+ }
+ /* fill the edges with data */
+ for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
+ stitch_state->edges[i++] = *((UvEdge
*)BLI_ghashIterator_getKey(ghi));
+ }
+ stitch_state->total_edges = BLI_ghash_size(stitch_state->edgeHash);
+
+ /* cleanup temporary stuff */
+ BLI_ghashIterator_free(ghi);
+ MEM_freeN(edges);
+
+ /* refill hash with new pointers */
+ BLI_ghash_free(stitch_state->edgeHash, NULL, NULL);
+ stitch_state->edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare,
"stitch_edge_hash");
+ for(i = 0; i < stitch_state->total_edges; i++){
+ BLI_ghash_insert(stitch_state->edgeHash, &stitch_state->edges +
i, NULL);
+ }
+
+ for(i = 0; i < stitch_state->total_edges; i++){
+ if(stitch_state->edges[i].flag & STITCH_BOUNDARY){
+ stitch_state->uvs[stitch_state->edges[i].uv1]->flag |=
STITCH_BOUNDARY;
+ stitch_state->uvs[stitch_state->edges[i].uv2]->flag |=
STITCH_BOUNDARY;
+ }
+ }
+
stitch_state->selection_size = 0;
/* Fill selection stack */
@@ -2581,26 +2680,26 @@
}
RNA_END;
} else {
- for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
- int numOfVerts;
- MTFace *mt;
- mt = CustomData_em_get(&stitch_state->em->fdata, efa->data,
CD_MTFACE);
- numOfVerts = efa->v4 ? 4 : 3;
+ for(efa = stitch_state->em->faces.first ; efa; efa = efa->next){
+ int numOfVerts;
+ MTFace *mt;
+ mt = CustomData_em_get(&stitch_state->em->fdata,
efa->data, CD_MTFACE);
+ numOfVerts = efa->v4 ? 4 : 3;
- for(i = 0; i < numOfVerts; i++){
- if(uvedit_uv_selected(scene, efa, mt, i)){
- int uniqueIndex;
- UvElement *element =
get_uv_element(stitch_state->elementMap, efa, i);
- uniqueIndex = stitch_state->map[element -
stitch_state->elementMap->buf];
- /* count a uv only once, or duplicates will
happen */
- 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;
+ for(i = 0; i < numOfVerts; i++){
+ if(uvedit_uv_selected(scene, efa, mt, i)){
+ int uniqueIndex;
+ UvElement *element =
get_uv_element(stitch_state->elementMap, efa, i);
+ uniqueIndex = stitch_state->map[element
- stitch_state->elementMap->buf];
+ /* count a uv only once, or duplicates
will happen */
+
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;
+ }
}
}
}
}
- }
if(!stitch_process_data(stitch_state, scene, 0, 1)){
stitch_state_delete(stitch_state);
@@ -2812,7 +2911,6 @@
* becomes dependent on the order of
stitching different uv's corresponding to the same vertex */
if(stitch_state->mode == VERT_STITCH)
{
- #ifdef STITCHNEW
int uniqueIndex;
/* This works due to setting of
tmp in find nearest uv vert */
UvElement *element_iter,
*unique_element, *element = get_uv_element(stitch_state->elementMap, hit.efa,
hit.uv);
@@ -2841,39 +2939,6 @@
unique_element->flag |=
STITCH_SELECTED;
stitch_state->selection_stack[stitch_state->selection_size++] = unique_element;
}
- #else
- UvElement *element =
stitch_state->elementMap->vert[(*(&hit.efa->v1 + hit.uv))->tmp.l];
- UvElement *firstCoincident;
- for(; element; element =
element->next)
- {
- MTFace *tface;
- tface =
CustomData_em_get(&stitch_state->em->fdata, element->face->data, CD_MTFACE);
- if(element->separate)
- firstCoincident
= element;
- if(element->face ==
hit.efa){
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs