[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39505] branches/soc-2011-onion/source/ blender: uv paint brushes
Antony Riakiotakis
kalast at gmail.com
Wed Aug 17 21:00:07 CEST 2011
Revision: 39505
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39505
Author: psy-fi
Date: 2011-08-17 19:00:07 +0000 (Wed, 17 Aug 2011)
Log Message:
-----------
uv paint brushes
=================
-Implementation of grab brush.
-Use corrected (root of) distance for brush influence
Modified Paths:
--------------
branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
branches/soc-2011-onion/source/blender/makesdna/DNA_scene_types.h
branches/soc-2011-onion/source/blender/makesrna/intern/rna_scene.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-17 18:42:02 UTC (rev 39504)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c 2011-08-17 19:00:07 UTC (rev 39505)
@@ -85,6 +85,27 @@
}UvAdjacencyEdge;
+typedef struct UVInitialStrokeElement{
+ /* index to unique uv */
+ int uv;
+ /* strength of brush on initial position */
+ float strength;
+ /* initial uv position */
+ float initial_uv[2];
+}UVInitialStrokeElement;
+
+typedef struct UVInitialStroke{
+ /* Initial Selection,for grab brushes for instance */
+ UVInitialStrokeElement *initialSelection;
+
+ /* total initially selected UVs*/
+ int totalInitialSelected;
+
+ /* initial mouse coordinates */
+ float init_coord[2];
+}UVInitialStroke;
+
+
/* custom data for uv smoothing brush */
typedef struct UvBrushData{
/* Contains the first of each set of coincident uvs.
@@ -104,11 +125,14 @@
/* Need I say more? */
int totalUvEdges;
+ UVInitialStroke *initial_stroke;
+
/* Timer to be used for airbrush-type brush */
wmTimer *timer;
/* To determine quickly adjacent uvs */
UvElementMap *elementMap;
+
/* uvsmooth Paint for fast reference */
Paint *uvpaint;
}UvBrushData;
@@ -129,6 +153,7 @@
Temp_UVData *tmp_uvdata;
float diff[2];
int i;
+ float radius_root = sqrt(radius);
Brush *brush = paint_brush(brushdata->uvpaint);
tmp_uvdata = (Temp_UVData *)MEM_callocN(brushdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
@@ -171,7 +196,7 @@
if((dist = dot_v2v2(diff, diff)) <= radius){
UvElement *element;
float strength;
- strength = alpha*brush_curve_strength(brush, dist, radius);
+ strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root);
brushdata->uv[i].uv[0] = (1.0-strength)*brushdata->uv[i].uv[0] + strength*(tmp_uvdata[i].p[0] - 0.5f*(tmp_uvdata[i].b[0] + tmp_uvdata[i].sum_b[0]/tmp_uvdata[i].ncounter));
brushdata->uv[i].uv[1] = (1.0-strength)*brushdata->uv[i].uv[1] + strength*(tmp_uvdata[i].p[1] - 0.5f*(tmp_uvdata[i].b[1] + tmp_uvdata[i].sum_b[1]/tmp_uvdata[i].ncounter));
@@ -193,10 +218,10 @@
static void smooth_laplacian_iteration_uv(EditMesh *em, UvBrushData *brushdata, float mouse_coord[2], float alpha, float radius, float aspectRatio)
{
-
Temp_UVData *tmp_uvdata;
float diff[2];
int i;
+ float radius_root = sqrt(radius);
Brush *brush = paint_brush(brushdata->uvpaint);
tmp_uvdata = (Temp_UVData *)MEM_callocN(brushdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
@@ -231,7 +256,7 @@
if((dist = dot_v2v2(diff, diff)) <= radius){
UvElement *element;
float strength;
- strength = alpha*brush_curve_strength(brush, dist, radius);
+ strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root);
brushdata->uv[i].uv[0] = (1.0-strength)*brushdata->uv[i].uv[0] + strength*tmp_uvdata[i].p[0];
brushdata->uv[i].uv[1] = (1.0-strength)*brushdata->uv[i].uv[1] + strength*tmp_uvdata[i].p[1];
@@ -254,10 +279,9 @@
static void uv_paint_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, Object *obedit)
{
- float co[2], radius;
+ float co[2], radius, radius_root;
ARegion *ar= CTX_wm_region(C);
EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
- EditFace *efa;
unsigned int tool;
UvBrushData *brushdata = (UvBrushData *)op->customdata;
SpaceImage *sima;
@@ -269,7 +293,7 @@
tool = CTX_data_scene(C)->toolsettings->uv_paint_tool;
invert = RNA_boolean_get(op->ptr, "invert")? -1 : 1;
- alpha = brush_alpha(brush);//*invert;
+ alpha = brush_alpha(brush);
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
radius = brush_size(brush);
@@ -279,6 +303,7 @@
radius /= width;
/* We will compare squares to save some computation */
radius = radius*radius;
+ radius_root = sqrt(radius);
if(tool == UV_PAINT_TOOL_PINCH){
int i;
@@ -296,7 +321,7 @@
if((dist = dot_v2v2(diff, diff)) <= radius){
UvElement *element;
float strength;
- strength = alpha*brush_curve_strength(brush, dist, radius);
+ strength = alpha*brush_curve_strength(brush, sqrt(dist), radius_root);
normalize_v2(diff);
brushdata->uv[i].uv[0] -= strength*diff[0]*0.001;
@@ -319,6 +344,26 @@
}else{
smooth_laplacian_iteration_uv(em, brushdata, co, alpha, radius, aspectRatio);
}
+ }else if(tool == UV_PAINT_TOOL_GRAB){
+ int i;
+ float diff[2];
+ sub_v2_v2v2(diff, co, brushdata->initial_stroke->init_coord);
+
+ for(i = 0; i < brushdata->initial_stroke->totalInitialSelected; i++ ){
+ UvElement *element;
+ int uvindex = brushdata->initial_stroke->initialSelection[i].uv;
+ float strength = brushdata->initial_stroke->initialSelection[i].strength;
+ brushdata->uv[uvindex].uv[0] = brushdata->initial_stroke->initialSelection[i].initial_uv[0] + strength*diff[0];
+ brushdata->uv[uvindex].uv[1] = brushdata->initial_stroke->initialSelection[i].initial_uv[1] + strength*diff[1];
+
+ for(element = brushdata->uv[uvindex].element; element; element = element->next){
+ MTFace *mt;
+ if(element->separate && element != brushdata->uv[uvindex].element)
+ break;
+ mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE);
+ copy_v2_v2(mt->uv[element->tfindex], brushdata->uv[uvindex].uv);
+ }
+ }
}
BKE_mesh_end_editmesh(obedit->data, em);
@@ -344,6 +389,12 @@
if(data->uvedges){
MEM_freeN(data->uvedges);
}
+ if(data->initial_stroke){
+ if(data->initial_stroke->initialSelection){
+ MEM_freeN(data->initial_stroke->initialSelection);
+ }
+ MEM_freeN(data->initial_stroke);
+ }
MEM_freeN(data);
op->customdata = NULL;
}
@@ -377,7 +428,7 @@
}
-static UvBrushData *uv_paint_stroke_init(bContext *C, wmOperator *op)
+static UvBrushData *uv_paint_stroke_init(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
@@ -388,10 +439,7 @@
op->customdata = data;
if(data){
- /* This holds a simple information: how many -unique- uvs we have in the uv layer.
- * Unique Uvs are important because they help us make one UVAdjacencyEdge for a group
- * of coincident UVs.*/
- int numOfSeparators = 0, i;
+ int counter = 0, i;
EditFace *efa;
UvAdjacencyEdge *edges;
GHash *edgeHash;
@@ -408,12 +456,12 @@
/* Count 'unique' uvs */
for(i = 0; i < data->elementMap->totalUVs; i++){
if(data->elementMap->buf[i].separate){
- numOfSeparators++;
+ counter++;
}
}
/* Allocate the unique uv buffers */
- data->uv = MEM_mallocN(sizeof(*data->uv)*numOfSeparators, "uv_brush_unique_uvs");
+ data->uv = MEM_mallocN(sizeof(*data->uv)*counter, "uv_brush_unique_uvs");
data->uniqueUv = MEM_mallocN(sizeof(*data->uniqueUv)*data->elementMap->totalUVs, "uv_brush_unique_uv_map");
edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash");
/* we have at most totalUVs edges*/
@@ -423,9 +471,9 @@
return NULL;
}
- data->totalUniqueUvs = numOfSeparators;
+ data->totalUniqueUvs = counter;
/* So that we can use this as index for the UvElements*/
- numOfSeparators = -1;
+ counter = -1;
/* initialize the unique UVs */
for(i = 0; i < em->totvert; i++){
UvElement *element = data->elementMap->vert[i];
@@ -434,42 +482,42 @@
efa = element->face;
mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- numOfSeparators++;
- data->uv[numOfSeparators].element = element;
- data->uv[numOfSeparators].flag = 0;
- data->uv[numOfSeparators].uv = mt->uv[element->tfindex];
+ counter++;
+ data->uv[counter].element = element;
+ data->uv[counter].flag = 0;
+ data->uv[counter].uv = mt->uv[element->tfindex];
}
/* pointer arithmetic to the rescue, as always :)*/
- data->uniqueUv[element - data->elementMap->buf] = numOfSeparators;
+ data->uniqueUv[element - data->elementMap->buf] = counter;
}
}
/* Now, on to generate our uv connectivity data */
- for(efa = em->faces.first, numOfSeparators = 0; efa; efa = efa->next){
+ for(efa = em->faces.first, counter = 0; efa; efa = efa->next){
int nverts = efa->v4 ? 4 : 3;
for(i = 0; i < nverts; i++){
int offset1 = data->uniqueUv[get_uv_element_offset_from_face(data->elementMap, efa, i)];
int offset2 = data->uniqueUv[get_uv_element_offset_from_face(data->elementMap, efa, (i+1)%nverts)];
- edges[numOfSeparators].flag = 0;
+ edges[counter].flag = 0;
if(offset1 < offset2){
- edges[numOfSeparators].uv1 = offset1;
- edges[numOfSeparators].uv2 = offset2;
+ edges[counter].uv1 = offset1;
+ edges[counter].uv2 = offset2;
}
else{
- edges[numOfSeparators].uv1 = offset2;
- edges[numOfSeparators].uv2 = offset1;
+ 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(edgeHash, &edges[numOfSeparators])){
- char *flag = BLI_ghash_lookup(edgeHash, &edges[numOfSeparators]);
+ if(BLI_ghash_haskey(edgeHash, &edges[counter])){
+ char *flag = BLI_ghash_lookup(edgeHash, &edges[counter]);
*flag = 1;
}
else{
/* Hack mentioned */
- BLI_ghash_insert(edgeHash, &edges[numOfSeparators], &edges[numOfSeparators].flag);
+ BLI_ghash_insert(edgeHash, &edges[counter], &edges[counter].flag);
}
- numOfSeparators++;
+ counter++;
}
}
@@ -508,6 +556,66 @@
}
}
}
+
+ /* Allocate initial selection for grab tool */
+ if(ts->uv_paint_tool == UV_PAINT_TOOL_GRAB){
+ float co[2], radius, radius_root;
+ ARegion *ar= CTX_wm_region(C);
+ unsigned int tool;
+ UvBrushData *brushdata = (UvBrushData *)op->customdata;
+ SpaceImage *sima;
+ int width, height;
+ float aspectRatio;
+ float alpha;
+ Brush *brush = paint_brush(brushdata->uvpaint);
+ tool = CTX_data_scene(C)->toolsettings->uv_paint_tool;
+
+ alpha = brush_alpha(brush);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+
+ radius = brush_size(brush);
+ sima = CTX_wm_space_image(C);
+ ED_space_image_size(sima, &width, &height);
+ aspectRatio = width/(float)height;
+ radius /= width;
+ radius = radius*radius;
+ radius_root = sqrt(radius);
+
+ /* Allocate selection stack */
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list