[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29539] branches/soc-2010-kwk/source/ blender/editors/sculpt_paint: Attempt: Stroke system in texture painting

Nicholas Bishop nicholasbishop at gmail.com
Fri Jun 18 17:45:24 CEST 2010


> Painting sometimes is slower than before my changes, probably because of too many RNA queries?
I'd suggest to profile that and see if RNA is indeed the problem; if
so you could do something similar to what sculpt mode does and create
a cache for values. (Of course, if multiple modes have such caches you
might be able to come up with a generic solution between them, or at
least a partially-shared cache.)

> 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.
Hmm, mats indeed is not used. Probably this was either used
originally, and when something changed that field was forgotten about,
or I added the mats field, and never used it at all :) Either way, you
can remove it if you don't end up needing it for your other changes.

-Nicholas

>
> 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
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>


More information about the Bf-committers mailing list