Revision: 29539
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29539
Author: kwk
Date: 2010-06-18 10:04:15 +0200 (Fri, 18 Jun 2010)
Log Message:
-----------
Attempt: Stroke system in texture painting
This is my first step to integrate the new stroke system into the texture
painting. The results are far away from perfect but I'm happy that the code
compiles again and you can at least paint textures in 3D space AND in 2D space
(inside UV/Texture Editor). It appears like there is a zoom dependend offset
between the mouse pointer and the paint stroke. The round brush pointer follows
the mouse pointer correctly in 3D View.
Switching spaces (e.g. from 3D to 2D) somehow breaks the functionality.
Painting sometimes is slower than before my changes, probably because of too
many RNA queries?
The stroke system didn't distinguish between different spaces and only works
with 3D Space. Now I added a stub condition to check if one is painting in 2D
mode. There need to be made some changes to stroke->mats maybe but for now I
couldn't find a place in paint_stroke.c where these matrices are actually used.
This problem requires more research.
Modified Paths:
--------------
branches/soc-2010-kwk/source/blender/editors/sculpt_paint/paint_image.c
branches/soc-2010-kwk/source/blender/editors/sculpt_paint/paint_stroke.c
Modified:
branches/soc-2010-kwk/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- branches/soc-2010-kwk/source/blender/editors/sculpt_paint/paint_image.c
2010-06-18 05:18:46 UTC (rev 29538)
+++ branches/soc-2010-kwk/source/blender/editors/sculpt_paint/paint_image.c
2010-06-18 08:04:15 UTC (rev 29539)
@@ -4514,7 +4514,7 @@
int first;
int prevmouse[2];
- float prev_pressure; /* need this since we dont get tablet events for
pressure change */
+// float prev_pressure; /* need this since we dont get tablet events for
pressure change */
int brush_size_orig;
double starttime;
@@ -4616,7 +4616,7 @@
ps->do_mask_normal = 0; /* no need to do blending */
}
-static int texture_paint_init(bContext *C, wmOperator *op)
+static int texture_paint_init(bContext *C, wmOperator *op, struct PaintStroke
*stroke)
{
Scene *scene= CTX_data_scene(C);
ToolSettings *settings= scene->toolsettings;
@@ -4624,7 +4624,8 @@
PaintOperation *pop= MEM_callocN(sizeof(PaintOperation),
"PaintOperation"); /* caller frees */
pop->first= 1;
- op->customdata= pop;
+ paint_stroke_set_mode_data(stroke, pop);
+// op->customdata= pop;
/* initialize from context */
if(CTX_wm_region_view3d(C)) {
@@ -4700,9 +4701,9 @@
return 1;
}
-static void paint_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
+static void paint_apply(bContext *C, struct PaintStroke *stroke, PointerRNA
*itemptr)
{
- PaintOperation *pop= op->customdata;
+ PaintOperation *pop= paint_stroke_mode_data(stroke);
float time, mousef[2];
float pressure;
int mouse[2], redraw;
@@ -4737,11 +4738,110 @@
pop->first= 0;
}
-static void paint_exit(bContext *C, wmOperator *op)
+//static void paint_exit(bContext *C, wmOperator *op)
+//{
+// Scene *scene= CTX_data_scene(C);
+// ToolSettings *settings= scene->toolsettings;
+// PaintOperation *pop= op->customdata;
+//
+// if(pop->timer)
+// WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C),
pop->timer);
+//
+// settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
+// imapaint_canvas_free(&pop->s);
+// brush_painter_free(pop->painter);
+//
+// if(pop->mode == PAINT_MODE_3D_PROJECT) {
+// pop->ps.brush->size = pop->brush_size_orig;
+// project_paint_end(&pop->ps);
+// }
+//
+// paint_redraw(C, &pop->s, 1);
+// undo_paint_push_end(UNDO_PAINT_IMAGE);
+//
+// if(pop->s.warnmultifile)
+// BKE_reportf(op->reports, RPT_WARNING, "Image requires 4 color
channels to paint: %s", pop->s.warnmultifile);
+// if(pop->s.warnpackedfile)
+// BKE_reportf(op->reports, RPT_WARNING, "Packed MultiLayer files
cannot be painted: %s", pop->s.warnpackedfile);
+//
+// MEM_freeN(pop);
+//}
+
+// XXX: (kwk) comment back in when ready.
+//static int paint_exec(bContext *C, wmOperator *op)
+//{
+// struct PaintStroke *stroke = op->customdata;
+//
+// if(!texture_paint_init(C, op, stroke)) {
+// MEM_freeN(op->customdata);
+// return OPERATOR_CANCELLED;
+// }
+//
+// RNA_BEGIN(op->ptr, itemptr, "stroke") {
+// paint_apply(C, stroke, &itemptr);
+// }
+// RNA_END;
+//
+// paint_exit(C, op);
+//
+// return OPERATOR_FINISHED;
+//}
+
+static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke,
PointerRNA *itemptr)
{
+ ARegion *ar= CTX_wm_region(C);
+ PaintOperation *pop= paint_stroke_mode_data(stroke);
+ float pressure, mousef[2];
+ double time;
+ int mouse[2];
+ int flip; // 1: Eraser, 0: Normal pen
+
+ // XXX +1 matches brush location better but
+ // still not exact, find out why and fix ..
+// mouse[0]= event->x - ar->winrct.xmin + 1;
+// mouse[1]= event->y - ar->winrct.ymin + 1;
+ // XXX: (kwk) for now we use the location from paint stroke but it
probably needs to be fixed.
+ RNA_float_get_array(itemptr, "location", mousef);
+ mouse[0] = (int) mousef[0] - ar->winrct.xmin + 1;
+ mouse[1] = (int) mousef[1] - ar->winrct.ymin + 1;
+
+ time= PIL_check_seconds_timer();
+
+ pop->s.blend= pop->s.brush->blend;
+
+ // XXX: (kwk) cache these values when everything works or get rid of
them.
+ flip = RNA_boolean_get(itemptr, "flip");
+ pressure = RNA_float_get(itemptr, "pressure");
+
+ if (flip) {
+ pop->s.blend = IMB_BLEND_ERASE_ALPHA;
+ }
+
+ if(pop->first) {
+ pop->prevmouse[0]= mouse[0];
+ pop->prevmouse[1]= mouse[1];
+ pop->starttime= time;
+
+ /* special exception here for too high pressure values on first
touch in
+ windows for some tablets, then we just skip first touch ..
*/
+ if ((pop->s.brush->flag &
(BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|BRUSH_SPACING_PRESSURE)) && (pressure
>= 0.99f))
+ return;
+ }
+
+ // XXX: (kwk) ok to add time to existing RNA stroke collection from
paint_stroke.c?
+ RNA_float_set(itemptr, "time", (float)(time - pop->starttime));
+
+ /* apply */
+// paint_apply(C, op, &itemptr);
+ paint_apply(C, stroke, itemptr);
+}
+
+// XXX: (kwk) mainly copied from paint_exit(). Needs to be modified!
+static void paint_stroke_done(bContext *C, struct PaintStroke *stroke)
+{
Scene *scene= CTX_data_scene(C);
ToolSettings *settings= scene->toolsettings;
- PaintOperation *pop= op->customdata;
+ PaintOperation *pop= paint_stroke_mode_data(stroke);
if(pop->timer)
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C),
pop->timer);
@@ -4755,102 +4855,48 @@
project_paint_end(&pop->ps);
}
+ // XXX: (kwk) Think about how to get rid of these to lines. Undo/Redo
is available via new stroke system (RNA) now.
paint_redraw(C, &pop->s, 1);
undo_paint_push_end(UNDO_PAINT_IMAGE);
+ // XXX: (kwk) Since there is no longer a ReportList from op->reports we
solely print the reports but do not store them for now.
if(pop->s.warnmultifile)
- BKE_reportf(op->reports, RPT_WARNING, "Image requires 4 color
channels to paint: %s", pop->s.warnmultifile);
+ BKE_reportf(NULL, RPT_WARNING, "Image requires 4 color channels
to paint: %s", pop->s.warnmultifile);
if(pop->s.warnpackedfile)
- BKE_reportf(op->reports, RPT_WARNING, "Packed MultiLayer files
cannot be painted: %s", pop->s.warnpackedfile);
+ BKE_reportf(NULL, RPT_WARNING, "Packed MultiLayer files cannot
be painted: %s", pop->s.warnpackedfile);
MEM_freeN(pop);
}
-static int paint_exec(bContext *C, wmOperator *op)
+static int paint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent
*event)
{
- if(!texture_paint_init(C, op)) {
- MEM_freeN(op->customdata);
+ struct PaintStroke *stroke = op->customdata;
+
+ if(!texture_paint_init(C, op, stroke)) {
+ MEM_freeN(paint_stroke_mode_data(stroke));
return OPERATOR_CANCELLED;
}
-
- RNA_BEGIN(op->ptr, itemptr, "stroke") {
- paint_apply(C, op, &itemptr);
- }
- RNA_END;
-
- paint_exit(C, op);
-
- return OPERATOR_FINISHED;
+
+ return 1;
}
-static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
-{
- ARegion *ar= CTX_wm_region(C);
- PaintOperation *pop= op->customdata;
- wmTabletData *wmtab;
- PointerRNA itemptr;
- float pressure, mousef[2];
- double time;
- int tablet, mouse[2];
-
- // XXX +1 matches brush location better but
- // still not exact, find out why and fix ..
- mouse[0]= event->x - ar->winrct.xmin + 1;
- mouse[1]= event->y - ar->winrct.ymin + 1;
-
- time= PIL_check_seconds_timer();
-
- tablet= 0;
- pressure= 0;
- pop->s.blend= pop->s.brush->blend;
-
- if(event->custom == EVT_DATA_TABLET) {
- wmtab= event->customdata;
-
- tablet= (wmtab->Active != EVT_TABLET_NONE);
- pressure= wmtab->Pressure;
- if(wmtab->Active == EVT_TABLET_ERASER)
- pop->s.blend= IMB_BLEND_ERASE_ALPHA;
- }
- else /* otherwise airbrush becomes 1.0 pressure instantly */
- pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f;
-
- if(pop->first) {
- pop->prevmouse[0]= mouse[0];
- pop->prevmouse[1]= mouse[1];
- pop->starttime= time;
-
- /* special exception here for too high pressure values on first
touch in
- windows for some tablets, then we just skip first touch ..
*/
- if ((pop->s.brush->flag &
(BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|BRUSH_SPACING_PRESSURE)) && tablet &&
(pressure >= 0.99f))
- return;
- }
-
- /* fill in stroke */
- RNA_collection_add(op->ptr, "stroke", &itemptr);
-
- mousef[0] = mouse[0];
- mousef[1] = mouse[1];
- RNA_float_set_array(&itemptr, "mouse", mousef);
- RNA_float_set(&itemptr, "time", (float)(time - pop->starttime));
- RNA_float_set(&itemptr, "pressure", pressure);
-
- /* apply */
- paint_apply(C, op, &itemptr);
-
- pop->prev_pressure= pressure;
-}
-
static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
PaintOperation *pop;
- if(!texture_paint_init(C, op)) {
- MEM_freeN(op->customdata);
- return OPERATOR_CANCELLED;
- }
+ op->customdata = paint_stroke_new(C,
+ NULL,
+
paint_stroke_test_start,
+
paint_stroke_update_step,
+
paint_stroke_done);
- paint_apply_event(C, op, event);
+// if(!texture_paint_init(C, op)) {
+// MEM_freeN(op->customdata);
+// return OPERATOR_CANCELLED;
+// }
+
+ // XXX: (kwk) This function is now mostly in paint_update_step() which
gets called automatically.
+ //paint_apply_event(C, op, event);
pop= op->customdata;
WM_event_add_modal_handler(C, op);
@@ -4858,38 +4904,21 @@
if(pop->s.brush->flag & BRUSH_AIRBRUSH)
pop->timer= WM_event_add_timer(CTX_wm_manager(C),
CTX_wm_window(C), TIMER, 0.01f);
+ /* XXX (kwk) copied from vpaint_stroke_invoke() and not sure what it
does :( */
+ op->type->modal(C, op, event);
+
return OPERATOR_RUNNING_MODAL;
}
-static int paint_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- PaintOperation *pop= op->customdata;
+// XXX: (kwk) ot->cancel not needed with new stroke system? like in
PAINT_OT_vertex_paint() ?
+//static int paint_cancel(bContext *C, wmOperator *op)
+//{
+// struct PaintStroke *stroke = op->customdata;
+// paint_stroke_done(C, stroke); /* XXX (kwk) OK to call directly? */
+//
+// return OPERATOR_CANCELLED;
+//}
- switch(event->type) {
- case LEFTMOUSE:
- case MIDDLEMOUSE:
- case RIGHTMOUSE: // XXX hardcoded
- paint_exit(C, op);
- return OPERATOR_FINISHED;
- case MOUSEMOVE:
- paint_apply_event(C, op, event);
- break;
- case TIMER:
- if(event->customdata == pop->timer)
- paint_apply_event(C, op, event);
- break;
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int paint_cancel(bContext *C, wmOperator *op)
-{
- paint_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
-
void PAINT_OT_image_paint(wmOperatorType *ot)
{
/* identifiers */
@@ -4897,10 +4926,12 @@
ot->idname= "PAINT_OT_image_paint";
/* api callbacks */
- ot->exec= paint_exec;
ot->invoke= paint_invoke;
- ot->modal= paint_modal;
- ot->cancel= paint_cancel;
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs