[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17759] branches/projection-paint/source/ blender: * tablet pressure changing opacity while painting didnt work
Campbell Barton
ideasman42 at gmail.com
Tue Dec 9 09:21:56 CET 2008
Revision: 17759
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17759
Author: campbellbarton
Date: 2008-12-09 09:21:53 +0100 (Tue, 09 Dec 2008)
Log Message:
-----------
* tablet pressure changing opacity while painting didnt work
* pixels with <= the current opacity are not painted onto, speeds up painting especially with low spacing. (only when airbrush is disabled)
* use qsort rather then own crufty sorting function
* grouped projection painting functions together.
Modified Paths:
--------------
branches/projection-paint/source/blender/blenkernel/intern/customdata.c
branches/projection-paint/source/blender/src/buttons_editing.c
branches/projection-paint/source/blender/src/imagepaint.c
Modified: branches/projection-paint/source/blender/blenkernel/intern/customdata.c
===================================================================
--- branches/projection-paint/source/blender/blenkernel/intern/customdata.c 2008-12-09 07:26:23 UTC (rev 17758)
+++ branches/projection-paint/source/blender/blenkernel/intern/customdata.c 2008-12-09 08:21:53 UTC (rev 17759)
@@ -964,9 +964,13 @@
if(index > 0 && data->layers[index-1].type == type) {
data->layers[index].active = data->layers[index-1].active;
data->layers[index].active_rnd = data->layers[index-1].active_rnd;
+ data->layers[index].active_clone = data->layers[index-1].active_clone;
+ data->layers[index].active_mask = data->layers[index-1].active_mask;
} else {
data->layers[index].active = 0;
data->layers[index].active_rnd = 0;
+ data->layers[index].active_clone = 0;
+ data->layers[index].active_mask = 0;
}
customData_update_offsets(data);
@@ -1026,6 +1030,8 @@
for (; i < data->totlayer && data->layers[i].type == type; i++) {
data->layers[i].active--;
data->layers[i].active_rnd--;
+ data->layers[i].active_clone--;
+ data->layers[i].active_mask--;
}
}
Modified: branches/projection-paint/source/blender/src/buttons_editing.c
===================================================================
--- branches/projection-paint/source/blender/src/buttons_editing.c 2008-12-09 07:26:23 UTC (rev 17758)
+++ branches/projection-paint/source/blender/src/buttons_editing.c 2008-12-09 08:21:53 UTC (rev 17759)
@@ -722,10 +722,10 @@
Mesh *me= (Mesh*)data1;
CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata;
CustomDataLayer *layer= (CustomDataLayer*)data2;
- void *actlayerdata, *rndlayerdata, *layerdata=layer->data;
+ void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
int type= layer->type;
int index= CustomData_get_layer_index(data, type);
- int i, actindex, rndindex;
+ int i, actindex, rndindex, cloneindex, maskindex;
/*ok, deleting a non-active layer needs to preserve the active layer indices.
to do this, we store a pointer to the .data member of both layer and the active layer,
@@ -736,6 +736,8 @@
layer. */
actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
+ clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
+ masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
CustomData_set_layer_active(data, type, layer - &data->layers[index]);
/* Multires is handled seperately because the display data is separate
@@ -787,7 +789,34 @@
CustomData_set_layer_render(data, type, rndindex);
}
+ if (clonelayerdata != layerdata) {
+ /*find index. . .*/
+ cloneindex = CustomData_get_layer_index(data, type);
+ for (i=cloneindex; i<data->totlayer; i++) {
+ if (data->layers[i].data == clonelayerdata) {
+ cloneindex = i - cloneindex;
+ break;
+ }
+ }
+
+ /*set index. . .*/
+ CustomData_set_layer_clone(data, type, cloneindex);
+ }
+ if (masklayerdata != layerdata) {
+ /*find index. . .*/
+ maskindex = CustomData_get_layer_index(data, type);
+ for (i=maskindex; i<data->totlayer; i++) {
+ if (data->layers[i].data == masklayerdata) {
+ maskindex = i - maskindex;
+ break;
+ }
+ }
+
+ /*set index. . .*/
+ CustomData_set_layer_mask(data, type, maskindex);
+ }
+
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
if(type == CD_MTFACE)
Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c 2008-12-09 07:26:23 UTC (rev 17758)
+++ branches/projection-paint/source/blender/src/imagepaint.c 2008-12-09 08:21:53 UTC (rev 17759)
@@ -118,6 +118,9 @@
#define MAXUNDONAME 64
+static void imapaint_image_update(Image *image, ImBuf *ibuf, short texpaint);
+
+
typedef struct ImagePaintState {
Brush *brush;
short tool, blend;
@@ -293,8 +296,16 @@
typedef struct ProjPixel {
float projCoSS[2]; /* the floating point screen projection of this pixel */
- float mask; /* for various reasons we may want to mask out painting onto this pixel */
+ /* Only used when the airbrush is disabled.
+ * Store the max mask value to avoid painting over an area with a lower opacity
+ * with an advantage that we can avoid touching the pixel at all, if the
+ * new mask value is lower then mask_max */
+ unsigned short mask_max;
+
+ /* for various reasons we may want to mask out painting onto this pixel */
+ unsigned short mask;
+
short x_px, y_px;
PixelStore origColor;
@@ -943,10 +954,26 @@
}
}
-/* simple func use for comparing UV locations to check if there are seams */
+/* simple func use for comparing UV locations to check if there are seams.
+ * Its possible this gives incorrect results, when the UVs for 1 face go into the next
+ * tile, but do not do this for the adjacent face, it could return a false positive.
+ * This is so unlikely that Id not worry about it. */
static int cmp_uv(const float vec2a[2], const float vec2b[2])
{
- return ((fabs(vec2a[0]-vec2b[0]) < 0.0001f) && (fabs(vec2a[1]-vec2b[1]) < 0.0001f)) ? 1:0;
+ /* if the UV's are not between 0.0 and 1.0 */
+ float xa = (float)fmod(vec2a[0], 1.0f);
+ float ya = (float)fmod(vec2a[1], 1.0f);
+
+ float xb = (float)fmod(vec2b[0], 1.0f);
+ float yb = (float)fmod(vec2b[1], 1.0f);
+
+ if (xa < 0.0f) xa += 1.0f;
+ if (ya < 0.0f) ya += 1.0f;
+
+ if (xb < 0.0f) xb += 1.0f;
+ if (yb < 0.0f) yb += 1.0f;
+
+ return ((fabs(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabs(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0;
}
@@ -1440,9 +1467,9 @@
}
}
- if (ps->is_airbrush==0) {
- mask *= ps->brush->alpha;
- }
+ // This only works when the opacity dosnt change while paintnig, stylus pressure messes with this
+ // so dont use it.
+ // if (ps->is_airbrush==0) mask *= ps->brush->alpha;
return mask;
}
@@ -1501,7 +1528,8 @@
projPixel->x_px = x_px;
projPixel->y_px = y_px;
- projPixel->mask = mask;
+ projPixel->mask = (unsigned short)(mask * 65535);
+ projPixel->mask_max = 0;
/* which bounding box cell are we in?, needed for undo */
projPixel->bb_cell_index = ((int)(((float)x_px/(float)ibuf->x) * PROJ_BOUNDBOX_DIV)) + ((int)(((float)y_px/(float)ibuf->y) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV ;
@@ -1934,9 +1962,22 @@
static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
{
- return (AreaF2Dfl(v1,v2,v3) + limit) > (AreaF2Dfl(pt,v1,v2) + AreaF2Dfl(pt,v2,v3) + AreaF2Dfl(pt,v3,v1)) ? 1 : 0;
+ return (AreaF2Dfl(v1,v2,v3) + limit) > (AreaF2Dfl(pt,v1,v2) + AreaF2Dfl(pt,v2,v3) + AreaF2Dfl(pt,v3,v1));
}
+/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
+ * so we have the clipped UV's to do pixel intersection tests with
+ * */
+
+
+static int float_z_sort_flip(const void *p1, const void *p2) {
+ return (((float *)p1)[2] < ((float *)p2)[2] ? 1:-1);
+}
+
+static int float_z_sort(const void *p1, const void *p2) {
+ return (((float *)p1)[2] < ((float *)p2)[2] ?-1:1);
+}
+
static void project_bucket_clip_face(
const int is_ortho,
rctf *bucket_bounds,
@@ -1949,7 +1990,6 @@
int inside_face_flag = 0;
const int flip = ((SIDE_OF_LINE(v1coSS, v2coSS, v3coSS) > 0.0f) != (SIDE_OF_LINE(uv1co, uv2co, uv3co) > 0.0f));
- float uv[2];
float bucket_bounds_ss[4][2];
float w[3];
@@ -2019,17 +2059,14 @@
/* Maximum possible 6 intersections when using a rectangle and triangle */
- float isectVCosSS[8][2];
- float isectVAngles[8];
+ float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
+ float v1_clipSS[2], v2_clipSS[2];
- float vClipSS_A[2], vClipSS_B[2];
-
/* calc center*/
float cent[2] = {0.0f, 0.0f};
/*float up[2] = {0.0f, 1.0f};*/
- float tmp_f;
int i;
- short unsorted, doubles;
+ short doubles;
(*tot) = 0;
@@ -2043,23 +2080,23 @@
if (inside_bucket_flag & ISECT_3) { VECCOPY2D(isectVCosSS[*tot], v3coSS); (*tot)++; }
if ((inside_bucket_flag & (ISECT_1|ISECT_2)) != (ISECT_1|ISECT_2)) {
- if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, vClipSS_A, vClipSS_B)) {
- if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], vClipSS_A); (*tot)++; }
- if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], vClipSS_B); (*tot)++; }
+ if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
}
}
if ((inside_bucket_flag & (ISECT_2|ISECT_3)) != (ISECT_2|ISECT_3)) {
- if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, vClipSS_A, vClipSS_B)) {
- if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], vClipSS_A); (*tot)++; }
- if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], vClipSS_B); (*tot)++; }
+ if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
}
}
if ((inside_bucket_flag & (ISECT_3|ISECT_1)) != (ISECT_3|ISECT_1)) {
- if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, vClipSS_A, vClipSS_B)) {
- if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], vClipSS_A); (*tot)++; }
- if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], vClipSS_B); (*tot)++; }
+ if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
}
}
@@ -2081,49 +2118,26 @@
/* Collect angles for every point around the center point */
-#if 1 /* starting not so pretty, slightly faster loop */
- vClipSS_A[0] = cent[0]; /* Abuse this var for the loop below */
- vClipSS_A[1] = cent[1] + 1.0f;
-
- for(i=0; i<(*tot); i++) {
- vClipSS_B[0] = isectVCosSS[i][0] - cent[0];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list