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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to