Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/gpencil/gpencil_paint.c
| Show First 20 Lines • Show All 1,603 Lines • ▼ Show 20 Lines | static void gp_session_cleanup(tGPsdata *p) | ||||
| /* clear flags */ | /* clear flags */ | ||||
| gpd->sbuffer_size = 0; | gpd->sbuffer_size = 0; | ||||
| gpd->sbuffer_sflag = 0; | gpd->sbuffer_sflag = 0; | ||||
| p->inittime = 0.0; | p->inittime = 0.0; | ||||
| } | } | ||||
| /* init new stroke */ | /* init new stroke */ | ||||
| static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode) | static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, const Depsgraph *depsgraph) | ||||
| { | { | ||||
| Scene *scene = p->scene; | Scene *scene = p->scene; | ||||
| ToolSettings *ts = scene->toolsettings; | ToolSettings *ts = scene->toolsettings; | ||||
| /* get active layer (or add a new one if non-existent) */ | /* get active layer (or add a new one if non-existent) */ | ||||
| p->gpl = BKE_gpencil_layer_getactive(p->gpd); | p->gpl = BKE_gpencil_layer_getactive(p->gpd); | ||||
| if (p->gpl == NULL) { | if (p->gpl == NULL) { | ||||
| p->gpl = BKE_gpencil_layer_addnew(p->gpd, "GP_Layer", true); | p->gpl = BKE_gpencil_layer_addnew(p->gpd, "GP_Layer", true); | ||||
| ▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, const Depsgraph *depsgraph) | ||||
| p->subrect = NULL; | p->subrect = NULL; | ||||
| if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) { | if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) { | ||||
| if (p->sa->spacetype == SPACE_VIEW3D) { | if (p->sa->spacetype == SPACE_VIEW3D) { | ||||
| View3D *v3d = p->sa->spacedata.first; | View3D *v3d = p->sa->spacedata.first; | ||||
| RegionView3D *rv3d = p->ar->regiondata; | RegionView3D *rv3d = p->ar->regiondata; | ||||
| /* for camera view set the subrect */ | /* for camera view set the subrect */ | ||||
| if (rv3d->persp == RV3D_CAMOB) { | if (rv3d->persp == RV3D_CAMOB) { | ||||
| ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */ | ED_view3d_calc_camera_border(p->scene, depsgraph, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */ | ||||
| p->subrect = &p->subrect_data; | p->subrect = &p->subrect_data; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* init stroke point space-conversion settings... */ | /* init stroke point space-conversion settings... */ | ||||
| p->gsc.gpd = p->gpd; | p->gsc.gpd = p->gpd; | ||||
| p->gsc.gpl = p->gpl; | p->gsc.gpl = p->gpl; | ||||
| ▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| p = op->customdata = gp_session_initpaint(C); | p = op->customdata = gp_session_initpaint(C); | ||||
| if ((p == NULL) || (p->status == GP_STATUS_ERROR)) { | if ((p == NULL) || (p->status == GP_STATUS_ERROR)) { | ||||
| /* something wasn't set correctly in context */ | /* something wasn't set correctly in context */ | ||||
| gpencil_draw_exit(C, op); | gpencil_draw_exit(C, op); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* init painting data */ | /* init painting data */ | ||||
| gp_paint_initstroke(p, paintmode); | gp_paint_initstroke(p, paintmode, CTX_data_depsgraph(C)); | ||||
| if (p->status == GP_STATUS_ERROR) { | if (p->status == GP_STATUS_ERROR) { | ||||
| gpencil_draw_exit(C, op); | gpencil_draw_exit(C, op); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| if (event != NULL) { | if (event != NULL) { | ||||
| p->keymodifier = event->keymodifier; | p->keymodifier = event->keymodifier; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | case GP_STATUS_DONE: | ||||
| ED_area_headerprint(p->sa, NULL); | ED_area_headerprint(p->sa, NULL); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* ------------------------------- */ | /* ------------------------------- */ | ||||
| /* create a new stroke point at the point indicated by the painting context */ | /* create a new stroke point at the point indicated by the painting context */ | ||||
| static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) | static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, const Depsgraph *depsgraph) | ||||
| { | { | ||||
| /* handle drawing/erasing -> test for erasing first */ | /* handle drawing/erasing -> test for erasing first */ | ||||
| if (p->paintmode == GP_PAINTMODE_ERASER) { | if (p->paintmode == GP_PAINTMODE_ERASER) { | ||||
| /* do 'live' erasing now */ | /* do 'live' erasing now */ | ||||
| gp_stroke_doeraser(p); | gp_stroke_doeraser(p); | ||||
| /* store used values */ | /* store used values */ | ||||
| p->mvalo[0] = p->mval[0]; | p->mvalo[0] = p->mval[0]; | ||||
| p->mvalo[1] = p->mval[1]; | p->mvalo[1] = p->mval[1]; | ||||
| p->opressure = p->pressure; | p->opressure = p->pressure; | ||||
| } | } | ||||
| /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ | /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ | ||||
| else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { | else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { | ||||
| /* try to add point */ | /* try to add point */ | ||||
| short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); | short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); | ||||
| /* handle errors while adding point */ | /* handle errors while adding point */ | ||||
| if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { | if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { | ||||
| /* finish off old stroke */ | /* finish off old stroke */ | ||||
| gp_paint_strokeend(p); | gp_paint_strokeend(p); | ||||
| /* And start a new one!!! Else, projection errors! */ | /* And start a new one!!! Else, projection errors! */ | ||||
| gp_paint_initstroke(p, p->paintmode); | gp_paint_initstroke(p, p->paintmode, depsgraph); | ||||
| /* start a new stroke, starting from previous point */ | /* start a new stroke, starting from previous point */ | ||||
| /* XXX Must manually reset inittime... */ | /* XXX Must manually reset inittime... */ | ||||
| /* XXX We only need to reuse previous point if overflow! */ | /* XXX We only need to reuse previous point if overflow! */ | ||||
| if (ok == GP_STROKEADD_OVERFLOW) { | if (ok == GP_STROKEADD_OVERFLOW) { | ||||
| p->inittime = p->ocurtime; | p->inittime = p->ocurtime; | ||||
| gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime); | gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime); | ||||
| } | } | ||||
| Show All 16 Lines | else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { | ||||
| p->mvalo[0] = p->mval[0]; | p->mvalo[0] = p->mval[0]; | ||||
| p->mvalo[1] = p->mval[1]; | p->mvalo[1] = p->mval[1]; | ||||
| p->opressure = p->pressure; | p->opressure = p->pressure; | ||||
| p->ocurtime = p->curtime; | p->ocurtime = p->curtime; | ||||
| } | } | ||||
| } | } | ||||
| /* handle draw event */ | /* handle draw event */ | ||||
| static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event) | static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, const Depsgraph *depsgraph) | ||||
| { | { | ||||
| tGPsdata *p = op->customdata; | tGPsdata *p = op->customdata; | ||||
| PointerRNA itemptr; | PointerRNA itemptr; | ||||
| float mousef[2]; | float mousef[2]; | ||||
| int tablet = 0; | int tablet = 0; | ||||
| /* convert from window-space to area-space mouse coordinates | /* convert from window-space to area-space mouse coordinates | ||||
| * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding... | * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding... | ||||
| ▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, const Depsgraph *depsgraph) | ||||
| mousef[1] = p->mval[1]; | mousef[1] = p->mval[1]; | ||||
| RNA_float_set_array(&itemptr, "mouse", mousef); | RNA_float_set_array(&itemptr, "mouse", mousef); | ||||
| RNA_float_set(&itemptr, "pressure", p->pressure); | RNA_float_set(&itemptr, "pressure", p->pressure); | ||||
| RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN) != 0); | RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN) != 0); | ||||
| RNA_float_set(&itemptr, "time", p->curtime - p->inittime); | RNA_float_set(&itemptr, "time", p->curtime - p->inittime); | ||||
| /* apply the current latest drawing point */ | /* apply the current latest drawing point */ | ||||
| gpencil_draw_apply(op, p); | gpencil_draw_apply(op, p, depsgraph); | ||||
| /* force refresh */ | /* force refresh */ | ||||
| ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ | ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ | ||||
| } | } | ||||
| /* ------------------------------- */ | /* ------------------------------- */ | ||||
| /* operator 'redo' (i.e. after changing some properties, but also for repeat last) */ | /* operator 'redo' (i.e. after changing some properties, but also for repeat last) */ | ||||
| static int gpencil_draw_exec(bContext *C, wmOperator *op) | static int gpencil_draw_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| tGPsdata *p = NULL; | tGPsdata *p = NULL; | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | |||||
| /* printf("GPencil - Starting Re-Drawing\n"); */ | /* printf("GPencil - Starting Re-Drawing\n"); */ | ||||
| /* try to initialize context data needed while drawing */ | /* try to initialize context data needed while drawing */ | ||||
| if (!gpencil_draw_init(C, op, NULL)) { | if (!gpencil_draw_init(C, op, NULL)) { | ||||
| if (op->customdata) MEM_freeN(op->customdata); | if (op->customdata) MEM_freeN(op->customdata); | ||||
| /* printf("\tGP - no valid data\n"); */ | /* printf("\tGP - no valid data\n"); */ | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| Show All 21 Lines | RNA_BEGIN (op->ptr, itemptr, "stroke") | ||||
| if (RNA_boolean_get(&itemptr, "is_start")) { | if (RNA_boolean_get(&itemptr, "is_start")) { | ||||
| /* if first-run flag isn't set already (i.e. not true first stroke), | /* if first-run flag isn't set already (i.e. not true first stroke), | ||||
| * then we must terminate the previous one first before continuing | * then we must terminate the previous one first before continuing | ||||
| */ | */ | ||||
| if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) { | if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) { | ||||
| /* TODO: both of these ops can set error-status, but we probably don't need to worry */ | /* TODO: both of these ops can set error-status, but we probably don't need to worry */ | ||||
| gp_paint_strokeend(p); | gp_paint_strokeend(p); | ||||
| gp_paint_initstroke(p, p->paintmode); | gp_paint_initstroke(p, p->paintmode, depsgraph); | ||||
| } | } | ||||
| } | } | ||||
| /* if first run, set previous data too */ | /* if first run, set previous data too */ | ||||
| if (p->flags & GP_PAINTFLAG_FIRSTRUN) { | if (p->flags & GP_PAINTFLAG_FIRSTRUN) { | ||||
| p->flags &= ~GP_PAINTFLAG_FIRSTRUN; | p->flags &= ~GP_PAINTFLAG_FIRSTRUN; | ||||
| p->mvalo[0] = p->mval[0]; | p->mvalo[0] = p->mval[0]; | ||||
| p->mvalo[1] = p->mval[1]; | p->mvalo[1] = p->mval[1]; | ||||
| p->opressure = p->pressure; | p->opressure = p->pressure; | ||||
| p->ocurtime = p->curtime; | p->ocurtime = p->curtime; | ||||
| } | } | ||||
| /* apply this data as necessary now (as per usual) */ | /* apply this data as necessary now (as per usual) */ | ||||
| gpencil_draw_apply(op, p); | gpencil_draw_apply(op, p, depsgraph); | ||||
| } | } | ||||
| RNA_END; | RNA_END; | ||||
| /* printf("\tGP - done\n"); */ | /* printf("\tGP - done\n"); */ | ||||
| /* cleanup */ | /* cleanup */ | ||||
| gpencil_draw_exit(C, op); | gpencil_draw_exit(C, op); | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| /* only start drawing immediately if we're allowed to do so... */ | /* only start drawing immediately if we're allowed to do so... */ | ||||
| if (RNA_boolean_get(op->ptr, "wait_for_input") == false) { | if (RNA_boolean_get(op->ptr, "wait_for_input") == false) { | ||||
| /* hotkey invoked - start drawing */ | /* hotkey invoked - start drawing */ | ||||
| /* printf("\tGP - set first spot\n"); */ | /* printf("\tGP - set first spot\n"); */ | ||||
| p->status = GP_STATUS_PAINTING; | p->status = GP_STATUS_PAINTING; | ||||
| /* handle the initial drawing - i.e. for just doing a simple dot */ | /* handle the initial drawing - i.e. for just doing a simple dot */ | ||||
| gpencil_draw_apply_event(op, event); | gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); | ||||
| op->flag |= OP_IS_MODAL_CURSOR_REGION; | op->flag |= OP_IS_MODAL_CURSOR_REGION; | ||||
| } | } | ||||
| else { | else { | ||||
| /* toolbar invoked - don't start drawing yet... */ | /* toolbar invoked - don't start drawing yet... */ | ||||
| /* printf("\tGP - hotkey invoked... waiting for click-drag\n"); */ | /* printf("\tGP - hotkey invoked... waiting for click-drag\n"); */ | ||||
| op->flag |= OP_IS_MODAL_CURSOR_REGION; | op->flag |= OP_IS_MODAL_CURSOR_REGION; | ||||
| } | } | ||||
| Show All 24 Lines | static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) | ||||
| /* printf("\t\tGP - start stroke\n"); */ | /* printf("\t\tGP - start stroke\n"); */ | ||||
| /* we may need to set up paint env again if we're resuming */ | /* we may need to set up paint env again if we're resuming */ | ||||
| /* XXX: watch it with the paintmode! in future, | /* XXX: watch it with the paintmode! in future, | ||||
| * it'd be nice to allow changing paint-mode when in sketching-sessions */ | * it'd be nice to allow changing paint-mode when in sketching-sessions */ | ||||
| if (gp_session_initdata(C, p)) | if (gp_session_initdata(C, p)) | ||||
| gp_paint_initstroke(p, p->paintmode); | gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph(C)); | ||||
| if (p->status != GP_STATUS_ERROR) { | if (p->status != GP_STATUS_ERROR) { | ||||
| p->status = GP_STATUS_PAINTING; | p->status = GP_STATUS_PAINTING; | ||||
| op->flag &= ~OP_IS_MODAL_CURSOR_REGION; | op->flag &= ~OP_IS_MODAL_CURSOR_REGION; | ||||
| } | } | ||||
| return op->customdata; | return op->customdata; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| } | } | ||||
| /* handle mode-specific events */ | /* handle mode-specific events */ | ||||
| if (p->status == GP_STATUS_PAINTING) { | if (p->status == GP_STATUS_PAINTING) { | ||||
| /* handle painting mouse-movements? */ | /* handle painting mouse-movements? */ | ||||
| if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) { | if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) { | ||||
| /* handle drawing event */ | /* handle drawing event */ | ||||
| /* printf("\t\tGP - add point\n"); */ | /* printf("\t\tGP - add point\n"); */ | ||||
| gpencil_draw_apply_event(op, event); | gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); | ||||
| /* finish painting operation if anything went wrong just now */ | /* finish painting operation if anything went wrong just now */ | ||||
| if (p->status == GP_STATUS_ERROR) { | if (p->status == GP_STATUS_ERROR) { | ||||
| printf("\t\t\t\tGP - add error done!\n"); | printf("\t\t\t\tGP - add error done!\n"); | ||||
| estate = OPERATOR_CANCELLED; | estate = OPERATOR_CANCELLED; | ||||
| } | } | ||||
| else { | else { | ||||
| /* event handled, so just tag as running modal */ | /* event handled, so just tag as running modal */ | ||||
| ▲ Show 20 Lines • Show All 115 Lines • Show Last 20 Lines | |||||