Blender  V2.93
gpencil_edit_curve.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008, Blender Foundation
17  * This is a new part of Blender
18  * Operators for editing Grease Pencil strokes
19  */
20 
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "DNA_gpencil_types.h"
32 #include "DNA_view3d_types.h"
33 
34 #include "BKE_context.h"
35 #include "BKE_gpencil.h"
36 #include "BKE_gpencil_curve.h"
37 #include "BKE_gpencil_geom.h"
38 
39 #include "BLI_listbase.h"
40 #include "BLI_math.h"
41 
42 #include "RNA_access.h"
43 #include "RNA_define.h"
44 
45 #include "WM_api.h"
46 #include "WM_types.h"
47 
48 #include "ED_gpencil.h"
49 
50 #include "DEG_depsgraph.h"
51 
52 #include "gpencil_intern.h"
53 
54 /* Poll callback for checking if there is an active layer and we are in curve edit mode. */
56 {
58  if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
59  return false;
60  }
61  bGPdata *gpd = (bGPdata *)ob->data;
63  return false;
64  }
65 
67  return (gpl != NULL);
68 }
69 
71 {
73  bGPdata *gpd = ob->data;
74 
75  float error_threshold = RNA_float_get(op->ptr, "error_threshold");
76  gpd->curve_edit_threshold = error_threshold;
77 
78  if (ELEM(NULL, gpd)) {
79  return OPERATOR_CANCELLED;
80  }
81 
82  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
83  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
84  if (gpf == gpl->actframe) {
85  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
86  /* only allow selected and non-converted strokes to be transformed */
87  if ((gps->flag & GP_STROKE_SELECT && gps->editcurve == NULL) ||
88  (gps->editcurve != NULL && gps->editcurve->flag & GP_CURVE_NEEDS_STROKE_UPDATE)) {
90  /* Update the selection from the stroke to the curve. */
91  BKE_gpencil_editcurve_stroke_sync_selection(gpd, gps, gps->editcurve);
92  gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
94  }
95  }
96  }
97  }
98  }
99 
101 
102  /* notifiers */
105 
106  return OPERATOR_FINISHED;
107 }
108 
110 {
111  PropertyRNA *prop;
112 
113  /* identifiers */
114  ot->name = "Enter curve edit mode";
115  ot->idname = "GPENCIL_OT_stroke_enter_editcurve_mode";
116  ot->description = "Called to transform a stroke into a curve";
117 
118  /* api callbacks */
121 
122  /* flags */
124 
125  /* properties */
126  prop = RNA_def_float(ot->srna,
127  "error_threshold",
128  0.1f,
129  FLT_MIN,
130  100.0f,
131  "Error Threshold",
132  "Threshold on the maximum deviation from the actual stroke",
133  FLT_MIN,
134  10.0f);
135  RNA_def_property_ui_range(prop, FLT_MIN, 10.0f, 0.1f, 5);
136 }
137 
139 {
141  bGPdata *gpd = ob->data;
142  const int handle_type = RNA_enum_get(op->ptr, "type");
143 
144  if (ELEM(NULL, gpd)) {
145  return OPERATOR_CANCELLED;
146  }
147 
148  GP_EDITABLE_CURVES_BEGIN(gps_iter, C, gpl, gps, gpc)
149  {
150  for (int i = 0; i < gpc->tot_curve_points; i++) {
151  bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
152 
153  if (gpc_pt->flag & GP_CURVE_POINT_SELECT) {
154  BezTriple *bezt = &gpc_pt->bezt;
155 
156  if (bezt->f2 & SELECT) {
157  bezt->h1 = handle_type;
158  bezt->h2 = handle_type;
159  }
160  else {
161  if (bezt->f1 & SELECT) {
162  bezt->h1 = handle_type;
163  }
164  if (bezt->f3 & SELECT) {
165  bezt->h2 = handle_type;
166  }
167  }
168  }
169  }
170 
172  gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
174  }
175  GP_EDITABLE_CURVES_END(gps_iter);
176 
177  /* notifiers */
180 
181  return OPERATOR_FINISHED;
182 }
183 
185 {
186  static const EnumPropertyItem editcurve_handle_type_items[] = {
187  {HD_FREE, "FREE", 0, "Free", ""},
188  {HD_AUTO, "AUTOMATIC", 0, "Automatic", ""},
189  {HD_VECT, "VECTOR", 0, "Vector", ""},
190  {HD_ALIGN, "ALIGNED", 0, "Aligned", ""},
191  {0, NULL, 0, NULL, NULL},
192  };
193 
194  /* identifiers */
195  ot->name = "Set handle type";
196  ot->idname = "GPENCIL_OT_stroke_editcurve_set_handle_type";
197  ot->description = "Set the type of a edit curve handle";
198 
199  /* api callbacks */
203 
204  /* flags */
206 
207  /* properties */
208  ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type");
209 }
210 
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct bGPDlayer * BKE_gpencil_layer_active_get(struct bGPdata *gpd)
Definition: gpencil.c:1650
void BKE_gpencil_stroke_editcurve_update(struct bGPdata *gpd, struct bGPDlayer *gpl, struct bGPDstroke *gps)
void BKE_gpencil_editcurve_stroke_sync_selection(struct bGPdata *gpd, struct bGPDstroke *gps, struct bGPDcurve *gpc)
void BKE_gpencil_editcurve_recalculate_handles(struct bGPDstroke *gps)
void BKE_gpencil_stroke_geometry_update(struct bGPdata *gpd, struct bGPDstroke *gps)
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ HD_VECT
@ HD_FREE
@ HD_AUTO
@ HD_ALIGN
@ GP_CURVE_NEEDS_STROKE_UPDATE
@ GP_STROKE_NEEDS_CURVE_UPDATE
@ GP_STROKE_SELECT
@ GP_DATA_CURVE_EDIT_MODE
#define GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd)
@ GP_CURVE_POINT_SELECT
@ OB_GPENCIL
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
#define C
Definition: RandGen.cpp:39
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_DATA
Definition: WM_types.h:408
#define NA_EDITED
Definition: WM_types.h:462
#define NC_GPENCIL
Definition: WM_types.h:300
#define SELECT
void GPENCIL_OT_stroke_enter_editcurve_mode(wmOperatorType *ot)
static bool gpencil_curve_edit_mode_poll(bContext *C)
void GPENCIL_OT_stroke_editcurve_set_handle_type(wmOperatorType *ot)
static int gpencil_stroke_enter_editcurve_mode_exec(bContext *C, wmOperator *op)
static int gpencil_editcurve_set_handle_type_exec(bContext *C, wmOperator *op)
#define GP_EDITABLE_CURVES_END(gpstroke_iter)
#define GP_EDITABLE_CURVES_BEGIN(gpstroke_iter, C, gpl, gps, gpc)
bool gpencil_active_layer_poll(struct bContext *C)
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
Definition: rna_define.c:1706
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
void * data
ListBase layers
float curve_edit_threshold
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982