diff options
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_edit.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 279 |
1 files changed, 222 insertions, 57 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index e2bd1c4a4a9..8771fcb0c8d 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -90,8 +90,9 @@ #include "gpencil_intern.h" -/* ************************************************ */ -/* Stroke Edit Mode Management */ +/* -------------------------------------------------------------------- */ +/** \name Stroke Edit Mode Management + * \{ */ /* poll callback for all stroke editing operators */ static bool gp_stroke_edit_poll(bContext *C) @@ -138,6 +139,12 @@ static bool gpencil_editmode_toggle_poll(bContext *C) return ED_gpencil_data_get_active(C) != NULL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Toggle Edit Mode Operator + * \{ */ + static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *op) { const int back = RNA_boolean_get(op->ptr, "back"); @@ -223,6 +230,12 @@ void GPENCIL_OT_editmode_toggle(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Toggle Select Mode Operator + * \{ */ + /* set select mode */ static bool gpencil_selectmode_toggle_poll(bContext *C) { @@ -298,7 +311,11 @@ void GPENCIL_OT_selectmode_toggle(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -/* Stroke Paint Mode Management */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Toggle Stroke Paint Mode Operator + * \{ */ static bool gpencil_paintmode_toggle_poll(bContext *C) { @@ -410,7 +427,11 @@ void GPENCIL_OT_paintmode_toggle(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -/* Stroke Sculpt Mode Management */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Toggle Stroke Sculpt Mode Operator + * \{ */ static bool gpencil_sculptmode_toggle_poll(bContext *C) { @@ -491,6 +512,12 @@ static int gpencil_sculptmode_toggle_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Toggle Weight Paint Mode Operator + * \{ */ + void GPENCIL_OT_sculptmode_toggle(wmOperatorType *ot) { PropertyRNA *prop; @@ -616,7 +643,11 @@ void GPENCIL_OT_weightmode_toggle(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -/* Vertex Paint Mode Management */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Toggle Vertex Paint Mode Operator + * \{ */ static bool gpencil_vertexmode_toggle_poll(bContext *C) { @@ -721,10 +752,11 @@ void GPENCIL_OT_vertexmode_toggle(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -/* ************************************************ */ -/* Stroke Editing Operators */ +/** \} */ -/* ************ Stroke Hide selection Toggle ************** */ +/* -------------------------------------------------------------------- */ +/** \name Stroke Hide Selection Toggle Operator + * \{ */ static int gpencil_hideselect_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -763,7 +795,11 @@ void GPENCIL_OT_selection_opacity_toggle(wmOperatorType *ot) ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; } -/* ************** Duplicate Selected Strokes **************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Duplicate Selected Strokes Operator + * \{ */ /* Make copies of selected point segments in a selected stroke */ static void gp_duplicate_points(const bGPDstroke *gps, @@ -940,7 +976,11 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ************** Extrude Selected Strokes **************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Extrude Selected Strokes Operator + * \{ */ /* helper to copy a point to temp area */ static void copy_move_point(bGPDstroke *gps, @@ -1161,14 +1201,18 @@ void GPENCIL_OT_extrude(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************* Copy/Paste Strokes ************************* */ -/* Grease Pencil stroke data copy/paste buffer: +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Copy/Paste Strokes Utilities + * + * Grease Pencil stroke data copy/paste buffer: * - The copy operation collects all segments of selected strokes, * dumping "ready to be copied" copies of the strokes into the buffer. * - The paste operation makes a copy of those elements, and adds them * to the active layer. This effectively flattens down the strokes * from several different layers into a single layer. - */ + * \{ */ /* list of bGPDstroke instances */ /* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */ @@ -1280,8 +1324,11 @@ GHash *gp_copybuf_validate_colormap(bContext *C) return new_colors; } -/* --------------------- */ -/* Copy selected strokes */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Copy Selected Strokes Operator + * \{ */ static int gp_strokes_copy_exec(bContext *C, wmOperator *op) { @@ -1398,8 +1445,11 @@ void GPENCIL_OT_copy(wmOperatorType *ot) // ot->flag = OPTYPE_REGISTER; } -/* --------------------- */ -/* Paste selected strokes */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paste Selected Strokes Operator + * \{ */ static bool gp_strokes_paste_poll(bContext *C) { @@ -1570,7 +1620,11 @@ void GPENCIL_OT_paste(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -/* ******************* Move To Layer ****************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Move To Layer Operator + * \{ */ static int gp_move_to_layer_exec(bContext *C, wmOperator *op) { @@ -1690,7 +1744,11 @@ void GPENCIL_OT_move_to_layer(wmOperatorType *ot) RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -/* ********************* Add Blank Frame *************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Add Blank Frame Operator + * \{ */ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op) { @@ -1764,7 +1822,11 @@ void GPENCIL_OT_blank_frame_add(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -/* ******************* Delete Active Frame ************************ */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete Active Frame Operator + * \{ */ static bool gp_actframe_delete_poll(bContext *C) { @@ -1845,7 +1907,12 @@ void GPENCIL_OT_annotation_active_frame_delete(wmOperatorType *ot) ot->exec = gp_actframe_delete_exec; ot->poll = gp_annotation_actframe_delete_poll; } -/* **************** Delete All Active Frames ****************** */ + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete All Active Frames + * \{ */ static bool gp_actframe_delete_all_poll(bContext *C) { @@ -1906,7 +1973,11 @@ void GPENCIL_OT_active_frames_delete_all(wmOperatorType *ot) ot->poll = gp_actframe_delete_all_poll; } -/* ******************* Delete Operator ************************ */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete/Dissolve Utilities + * \{ */ typedef enum eGP_DeleteMode { /* delete selected stroke points */ @@ -1926,8 +1997,6 @@ typedef enum eGP_DissolveMode { GP_DISSOLVE_UNSELECT = 2, } eGP_DissolveMode; -/* ----------------------------------- */ - /* Delete selected strokes */ static int gp_delete_selected_strokes(bContext *C) { @@ -2521,7 +2590,11 @@ int gp_delete_selected_point_wrap(bContext *C) return gp_delete_selected_points(C); } -/* ----------------------------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete Operator + * \{ */ static int gp_delete_exec(bContext *C, wmOperator *op) { @@ -2580,6 +2653,12 @@ void GPENCIL_OT_delete(wmOperatorType *ot) "Method used for deleting Grease Pencil data"); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Dissolve Operator + * \{ */ + static int gp_dissolve_exec(bContext *C, wmOperator *op) { eGP_DissolveMode mode = RNA_enum_get(op->ptr, "type"); @@ -2622,7 +2701,11 @@ void GPENCIL_OT_dissolve(wmOperatorType *ot) "Method used for dissolving Stroke points"); } -/* ****************** Snapping - Strokes <-> Cursor ************************ */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snapping Selection to Grid Operator + * \{ */ /* Poll callback for snap operators */ /* NOTE: For now, we only allow these in the 3D view, as other editors do not @@ -2637,8 +2720,6 @@ static bool gp_snap_poll(bContext *C) ((area != NULL) && (area->spacetype == SPACE_VIEW3D)); } -/* --------------------------------- */ - static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); @@ -2713,7 +2794,11 @@ void GPENCIL_OT_snap_to_grid(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ------------------------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snapping Selection to Cursor Operator + * \{ */ static int gp_snap_to_cursor(bContext *C, wmOperator *op) { @@ -2805,7 +2890,11 @@ void GPENCIL_OT_snap_to_cursor(wmOperatorType *ot) "Offset the entire stroke instead of selected points only"); } -/* ------------------------------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snapping Cursor to Selection Operator + * \{ */ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) { @@ -2896,7 +2985,11 @@ void GPENCIL_OT_snap_cursor_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************* Apply layer thickness change to strokes ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Apply Layer Thickness Change to Strokes Operator + * \{ */ static int gp_stroke_apply_thickness_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -2943,7 +3036,11 @@ void GPENCIL_OT_stroke_apply_thickness(wmOperatorType *ot) ot->poll = gp_active_layer_poll; } -/* ******************* Close Strokes ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Toggle Cyclic Operator + * \{ */ enum { GP_STROKE_CYCLIC_CLOSE = 1, @@ -3063,7 +3160,11 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -/* ******************* Flat Stroke Caps ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Toggle Flat Caps Operator + * \{ */ enum { GP_STROKE_CAPS_TOGGLE_BOTH = 0, @@ -3159,7 +3260,11 @@ void GPENCIL_OT_stroke_caps_set(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", toggle_type, GP_STROKE_CAPS_TOGGLE_BOTH, "Type", ""); } -/* ******************* Stroke join ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Join Operator + * \{ */ /* Helper: flip stroke */ static void gpencil_flip_stroke(bGPDstroke *gps) @@ -3209,8 +3314,8 @@ static void gpencil_flip_stroke(bGPDstroke *gps) /* Helper: copy point between strokes */ static void gpencil_stroke_copy_point(bGPDstroke *gps, + MDeformVert *dvert, bGPDspoint *point, - int idx, const float delta[3], float pressure, float strength, @@ -3222,6 +3327,13 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, if (gps->dvert != NULL) { gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1)); } + else { + /* If destination has weight add weight to origin. */ + if (dvert != NULL) { + gps->dvert = MEM_callocN(sizeof(MDeformVert) * (gps->totpoints + 1), __func__); + } + } + gps->totpoints++; newpoint = &gps->points[gps->totpoints - 1]; @@ -3235,11 +3347,16 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, copy_v4_v4(newpoint->vert_color, point->vert_color); if (gps->dvert != NULL) { - MDeformVert *dvert = &gps->dvert[idx]; MDeformVert *newdvert = &gps->dvert[gps->totpoints - 1]; - newdvert->totweight = dvert->totweight; - newdvert->dw = MEM_dupallocN(dvert->dw); + if (dvert != NULL) { + newdvert->totweight = dvert->totweight; + newdvert->dw = MEM_dupallocN(dvert->dw); + } + else { + newdvert->totweight = 0; + newdvert->dw = NULL; + } } } @@ -3290,16 +3407,18 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, /* 1st: add one tail point to start invisible area */ point = gps_a->points[gps_a->totpoints - 1]; deltatime = point.time; - gpencil_stroke_copy_point(gps_a, &point, gps_a->totpoints - 1, delta, 0.0f, 0.0f, 0.0f); + + gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, 0.0f); /* 2nd: add one head point to finish invisible area */ point = gps_b->points[0]; - gpencil_stroke_copy_point(gps_a, &point, 0, delta, 0.0f, 0.0f, deltatime); + gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, deltatime); } /* 3rd: add all points */ for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) { - gpencil_stroke_copy_point(gps_a, pt, i, delta, pt->pressure, pt->strength, deltatime); + MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : NULL; + gpencil_stroke_copy_point(gps_a, dvert, pt, delta, pt->pressure, pt->strength, deltatime); } } @@ -3445,7 +3564,11 @@ void GPENCIL_OT_stroke_join(wmOperatorType *ot) "Leave gaps between joined strokes instead of linking them"); } -/* ******************* Stroke flip ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Flip Operator + * \{ */ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -3504,7 +3627,11 @@ void GPENCIL_OT_stroke_flip(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ***************** Reproject Strokes ********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Re-project Operator + * \{ */ typedef enum eGP_ReprojectModes { /* Axis */ @@ -3542,7 +3669,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) int cfra_prv = INT_MIN; /* init snap context for geometry projection */ - sctx = ED_transform_snap_object_context_create_view3d(bmain, scene, 0, region, CTX_wm_view3d(C)); + sctx = ED_transform_snap_object_context_create_view3d(scene, 0, region, CTX_wm_view3d(C)); /* Go through each editable + selected stroke, adjusting each of its points one by one... */ GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { @@ -3742,7 +3869,6 @@ static int gp_recalc_geometry_exec(bContext *C, wmOperator *UNUSED(op)) void GPENCIL_OT_recalc_geometry(wmOperatorType *ot) { - /* identifiers */ ot->name = "Recalculate internal geometry"; ot->idname = "GPENCIL_OT_recalc_geometry"; @@ -3756,7 +3882,12 @@ void GPENCIL_OT_recalc_geometry(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************* Stroke subdivide ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Subdivide Operator + * \{ */ + /* helper to smooth */ static void gp_smooth_stroke(bContext *C, wmOperator *op) { @@ -4137,7 +4268,12 @@ void GPENCIL_OT_stroke_sample(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -/* ******************* Stroke trim ************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Trim Operator + * \{ */ + static int gp_stroke_trim_exec(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); @@ -4202,7 +4338,12 @@ void GPENCIL_OT_stroke_trim(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ***************** Separate Strokes ********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Separate Operator + * \{ */ + typedef enum eGP_SeparateModes { /* Points */ GP_SEPARATE_POINT = 0, @@ -4420,7 +4561,12 @@ void GPENCIL_OT_stroke_separate(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "mode", separate_type, GP_SEPARATE_POINT, "Mode", ""); } -/* ***************** Split Strokes ********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Split Operator + * \{ */ + static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_active_object(C); @@ -4517,6 +4663,12 @@ void GPENCIL_OT_stroke_split(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Smooth Operator + * \{ */ + static int gp_stroke_smooth_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); @@ -4567,11 +4719,17 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot) RNA_def_boolean(ot->srna, "smooth_uv", false, "UV", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stroke Cutter Operator + * \{ */ + /* smart stroke cutter for trimming stroke ends */ struct GP_SelectLassoUserData { rcti rect; - const int (*mcords)[2]; - int mcords_len; + const int (*mcoords)[2]; + int mcoords_len; }; static bool gpencil_test_lasso(bGPDstroke *gps, @@ -4587,7 +4745,7 @@ static bool gpencil_test_lasso(bGPDstroke *gps, gp_point_to_xy(gsc, gps, &pt2, &x0, &y0); /* test if in lasso */ return ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&data->rect, x0, y0) && - BLI_lasso_is_point_inside(data->mcords, data->mcords_len, x0, y0, INT_MAX)); + BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, x0, y0, INT_MAX)); } typedef bool (*GPencilTestFn)(bGPDstroke *gps, @@ -4765,19 +4923,19 @@ static int gpencil_cutter_exec(bContext *C, wmOperator *op) } struct GP_SelectLassoUserData data = {0}; - data.mcords = WM_gesture_lasso_path_to_array(C, op, &data.mcords_len); + data.mcoords = WM_gesture_lasso_path_to_array(C, op, &data.mcoords_len); /* Sanity check. */ - if (data.mcords == NULL) { + if (data.mcoords == NULL) { return OPERATOR_PASS_THROUGH; } /* Compute boundbox of lasso (for faster testing later). */ - BLI_lasso_boundbox(&data.rect, data.mcords, data.mcords_len); + BLI_lasso_boundbox(&data.rect, data.mcoords, data.mcoords_len); gpencil_cutter_lasso_select(C, op, gpencil_test_lasso, &data); - MEM_freeN((void *)data.mcords); + MEM_freeN((void *)data.mcoords); return OPERATOR_FINISHED; } @@ -4823,7 +4981,12 @@ bool ED_object_gpencil_exit(struct Main *bmain, Object *ob) return ok; } -/* ** merge by distance *** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Merge By Distance Operator + * \{ */ + static bool gp_merge_by_distance_poll(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -4892,3 +5055,5 @@ void GPENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot) ot->srna, "use_unselected", 0, "Unselected", "Use whole stroke, not only selected points"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } + +/** \} */ |