[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39315] branches/soc-2011-onion/source/ blender/editors/sculpt_paint/paint_uv.c: Smooth Brushes
Antony Riakiotakis
kalast at gmail.com
Fri Aug 12 02:06:04 CEST 2011
Revision: 39315
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39315
Author: psy-fi
Date: 2011-08-12 00:06:03 +0000 (Fri, 12 Aug 2011)
Log Message:
-----------
Smooth Brushes
=====================
-implemented connectivity data (Not as expensive as I thought though I do have a relatively fast PC)
Now keep on to use it into the brush!
Modified Paths:
--------------
branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c 2011-08-11 22:14:07 UTC (rev 39314)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c 2011-08-12 00:06:03 UTC (rev 39315)
@@ -78,9 +78,9 @@
} UvAdjacencyElement;
typedef struct UvAdjacencyEdge {
- UvAdjacencyElement *uv1;
- UvAdjacencyElement *uv2;
- /* flag whether edge is boundary */
+ unsigned int uv1;
+ unsigned int uv2;
+ /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
char flag;
}UvAdjacencyEdge;
@@ -329,7 +329,7 @@
int *uniqueUv;
/* Edges used for adjacency info, used with laplacian smoothing */
- GHash *uvedges;
+ UvAdjacencyEdge *uvedges;
/* Timer to be used for airbrush-type brush */
wmTimer *timer;
@@ -404,6 +404,9 @@
if(data->uniqueUv){
MEM_freeN(data->uniqueUv);
}
+ if(data->uvedges){
+ MEM_freeN(data->uvedges);
+ }
MEM_freeN(data);
op->customdata = NULL;
}
@@ -418,6 +421,23 @@
return -1;
}
+
+static unsigned int uv_edge_hash(const void *key){
+ UvAdjacencyEdge *edge = (UvAdjacencyEdge *)key;
+ return BLI_ghashutil_inthash(edge->uv2) + BLI_ghashutil_inthash(edge->uv1);
+}
+
+static int uv_edge_compare(const void *a, const void *b){
+ UvAdjacencyEdge *edge1 = (UvAdjacencyEdge *)a;
+ UvAdjacencyEdge *edge2 = (UvAdjacencyEdge *)b;
+
+ if((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)){
+ return 0;
+ }
+ return -1;
+}
+
+
static SmoothBrushData *uv_smooth_stroke_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@@ -434,6 +454,9 @@
* of coincident UVs.*/
int numOfSeparators = 0, i;
EditFace *efa;
+ UvAdjacencyEdge *edges;
+ GHash *edgeHash;
+ GHashIterator* ghi;
data->uvpaint = &ts->uvsmooth->paint;
data->elementMap = EM_make_uv_element_map(em, 0, 0);
@@ -452,7 +475,9 @@
/* Allocate the unique uv buffers */
data->uv = MEM_mallocN(sizeof(*data->uv)*numOfSeparators, "uv_brush_unique_uvs");
data->uniqueUv = MEM_mallocN(sizeof(*data->uniqueUv)*data->elementMap->totalUVs, "uv_brush_unique_uv_map");
- if(!data->uv || !data->uniqueUv){
+ edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash");
+ edges = MEM_mallocN(sizeof(*edges)*data->elementMap->totalUVs, "uv_brush_all_edges");
+ if(!data->uv || !data->uniqueUv || !edgeHash || !edges){
uv_smooth_stroke_exit(C, op);
return NULL;
}
@@ -475,13 +500,52 @@
}
/* Now, to generate our uv connectivity data...Man, this is gonna be -slow-! */
- for(efa = em->faces.first; efa; efa = efa->next){
+ for(efa = em->faces.first, numOfSeparators = 0; efa; efa = efa->next){
int nverts = efa->v4 ? 4 : 3;
for(i = 0; i < nverts; i++){
int offset1 = get_uv_element_offset_from_face(data->elementMap, efa, i);
int offset2 = get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts);
+ if(offset1 < offset2){
+ edges[numOfSeparators].uv1 = data->uniqueUv[offset1];
+ edges[numOfSeparators].uv2 = data->uniqueUv[offset2];
+ edges[numOfSeparators].flag = 0;
+ }
+ else{
+ edges[numOfSeparators].uv1 = data->uniqueUv[offset2];
+ edges[numOfSeparators].uv2 = data->uniqueUv[offset1];
+ edges[numOfSeparators].flag = 0;
+ }
+ /* 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(edgeHash, &edges[numOfSeparators])){
+ char *flag = BLI_ghash_lookup(edgeHash, &edges[numOfSeparators]);
+ *flag = 1;
+ }
+ else{
+ /* Hack mentioned */
+ BLI_ghash_insert(edgeHash, &edges[numOfSeparators], &edges[numOfSeparators].flag);
+ }
+ numOfSeparators++;
}
}
+
+// printf("total Uvs %d, total edgeKeys %d\n", data->elementMap->totalUVs, BLI_ghash_size(edgeHash));
+ /* Allocate connectivity data, we allocate edges once */
+ data->uvedges = MEM_mallocN(sizeof(*data->uvedges)*BLI_ghash_size(edgeHash), "uv_brush_edge_connectivity_data");
+
+ ghi = BLI_ghashIterator_new(edgeHash);
+ if(!ghi){
+ BLI_ghash_free(edgeHash, NULL, NULL);
+ MEM_freeN(edges);
+ uv_smooth_stroke_exit(C, op);
+ return NULL;
+ }
+ /* fill the edges with data */
+ for(i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi), i++){
+ data->uvedges[i] = *((UvAdjacencyEdge *)BLI_ghashIterator_getKey(ghi));
+ }
+ BLI_ghashIterator_free(ghi);
+ BLI_ghash_free(edgeHash, NULL, NULL);
+ MEM_freeN(edges);
}
return op->customdata;
More information about the Bf-blender-cvs
mailing list