Blender V5.0
rna_grease_pencil_api.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "DNA_curves_types.h"
10#include "DNA_meshdata_types.h"
11#include "DNA_scene_types.h"
12
13#include "ED_object_vgroup.hh"
14#include "RNA_define.hh"
15#include "RNA_enum_types.hh"
16
17#include "WM_api.hh"
18
19#include "rna_internal.hh" /* own include */
20
22 {-1, "DOWN", 0, "Down", ""},
23 {1, "UP", 0, "Up", ""},
24 {0, nullptr, 0, nullptr, nullptr},
25};
26
27#ifdef RNA_RUNTIME
28
29# include "BKE_attribute.hh"
30# include "BKE_context.hh"
31# include "BKE_curves.hh"
32# include "BKE_deform.hh"
33# include "BKE_grease_pencil.hh"
35# include "BKE_report.hh"
36# include "DNA_meshdata_types.h"
37
38# include "DEG_depsgraph.hh"
39
40# include "rna_curves_utils.hh"
41
42static void rna_GreasePencilDrawing_add_curves(ID *grease_pencil_id,
43 GreasePencilDrawing *drawing_ptr,
44 ReportList *reports,
45 const int *sizes,
46 const int sizes_num)
47{
48 using namespace blender;
49 bke::greasepencil::Drawing &drawing = drawing_ptr->wrap();
50 bke::CurvesGeometry &curves = drawing.strokes_for_write();
51 if (!rna_CurvesGeometry_add_curves(curves, reports, sizes, sizes_num)) {
52 return;
53 }
54
55 /* Default to `POLY` curves for the newly added ones. */
56 drawing.strokes_for_write().curve_types_for_write().take_back(sizes_num).fill(CURVE_TYPE_POLY);
58
59 drawing.tag_topology_changed();
60
61 /* Avoid updates for importers. */
62 if (grease_pencil_id->us > 0) {
63 DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
64 WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
65 }
66}
67
68static void rna_GreasePencilDrawing_remove_curves(ID *grease_pencil_id,
69 GreasePencilDrawing *drawing_ptr,
70 ReportList *reports,
71 const int *indices_ptr,
72 const int indices_num)
73{
74 using namespace blender;
75 bke::greasepencil::Drawing &drawing = drawing_ptr->wrap();
76 bke::CurvesGeometry &curves = drawing.strokes_for_write();
77 if (!rna_CurvesGeometry_remove_curves(curves, reports, indices_ptr, indices_num)) {
78 return;
79 }
80
81 drawing.tag_topology_changed();
82
83 /* Avoid updates for importers. */
84 if (grease_pencil_id->us > 0) {
85 DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
86 WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
87 }
88}
89
90static void rna_GreasePencilDrawing_resize_curves(ID *grease_pencil_id,
91 GreasePencilDrawing *drawing_ptr,
92 ReportList *reports,
93 const int *sizes_ptr,
94 const int sizes_num,
95 const int *indices_ptr,
96 const int indices_num)
97{
98 using namespace blender;
99 bke::greasepencil::Drawing &drawing = drawing_ptr->wrap();
100 bke::CurvesGeometry &curves = drawing.strokes_for_write();
101 if (!rna_CurvesGeometry_resize_curves(
102 curves, reports, sizes_ptr, sizes_num, indices_ptr, indices_num))
103 {
104 return;
105 }
106
107 drawing.tag_topology_changed();
108
109 /* Avoid updates for importers. */
110 if (grease_pencil_id->us > 0) {
111 DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
112 WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
113 }
114}
115
116static void rna_GreasePencilDrawing_reorder_curves(ID *grease_pencil_id,
117 GreasePencilDrawing *drawing_ptr,
118 ReportList *reports,
119 const int *reorder_indices_ptr,
120 const int reorder_indices_num)
121{
122 using namespace blender;
123 bke::greasepencil::Drawing &drawing = drawing_ptr->wrap();
124 bke::CurvesGeometry &curves = drawing.strokes_for_write();
125 if (!rna_CurvesGeometry_reorder_curves(
126 curves, reports, reorder_indices_ptr, reorder_indices_num))
127 {
128 return;
129 }
130
131 drawing.tag_topology_changed();
132
133 /* Avoid updates for importers. */
134 if (grease_pencil_id->us > 0) {
135 DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
136 WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
137 }
138}
139
140static void rna_GreasePencilDrawing_set_types(ID *grease_pencil_id,
141 GreasePencilDrawing *drawing_ptr,
142 ReportList *reports,
143 const int type,
144 const int *indices_ptr,
145 const int indices_num)
146{
147 using namespace blender;
148 bke::greasepencil::Drawing &drawing = drawing_ptr->wrap();
149 bke::CurvesGeometry &curves = drawing.strokes_for_write();
150 if (!rna_CurvesGeometry_set_types(curves, reports, type, indices_ptr, indices_num)) {
151 return;
152 }
153 /* Avoid updates for importers. */
154 if (grease_pencil_id->us > 0) {
155 DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
156 WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id);
157 }
158}
159
160static void rna_GreasePencilDrawing_tag_positions_changed(GreasePencilDrawing *drawing_ptr)
161{
162 drawing_ptr->wrap().tag_positions_changed();
163}
164
165static void rna_GreasePencilDrawing_vertex_group_assign(ID *id,
166 GreasePencilDrawing *drawing_ptr,
167 ReportList *reports,
168 const char *vgroup_name,
169 const int *indices_ptr,
170 int indices_num,
171 float weight)
172{
173 using namespace blender;
174 GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
175 const int vgroup_index = BKE_defgroup_name_index(&grease_pencil.vertex_group_names, vgroup_name);
176 if (vgroup_index == -1) {
177 return;
178 }
179
180 const bDeformGroup *dg = static_cast<const bDeformGroup *>(
181 BLI_findlink(&grease_pencil.vertex_group_names, vgroup_index));
182 if (dg->flag & DG_LOCK_WEIGHT) {
183 BKE_report(reports, RPT_ERROR, "Vertex Group is locked");
184 return;
185 }
186
187 bke::CurvesGeometry &curves = drawing_ptr->wrap().strokes_for_write();
188 const int def_nr = bke::greasepencil::ensure_vertex_group(vgroup_name,
189 curves.vertex_group_names);
190 const MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
191 const int dverts_size = dverts.size();
192 const Span<int> indices(indices_ptr, indices_num);
193
194 for (const int i : indices) {
195 if (i < dverts_size) {
196 if (MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[i], def_nr)) {
197 dw->weight = weight;
198 }
199 }
200 }
201 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
202 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
203}
204
205static void rna_GreasePencilDrawing_vertex_group_remove(ID *id,
206 GreasePencilDrawing *drawing_ptr,
207 ReportList *reports,
208 const char *vgroup_name,
209 const int *indices_ptr,
210 int indices_num)
211{
212 using namespace blender;
213 GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
214 const int vgroup_index = BKE_defgroup_name_index(&grease_pencil.vertex_group_names, vgroup_name);
215 if (vgroup_index == -1) {
216 return;
217 }
218
219 const bDeformGroup *dg = static_cast<const bDeformGroup *>(
220 BLI_findlink(&grease_pencil.vertex_group_names, vgroup_index));
221 if (dg->flag & DG_LOCK_WEIGHT) {
222 BKE_report(reports, RPT_ERROR, "Vertex Group is locked");
223 return;
224 }
225
226 bke::CurvesGeometry &curves = drawing_ptr->wrap().strokes_for_write();
227 const int def_nr = BKE_defgroup_name_index(&curves.vertex_group_names, vgroup_name);
228 if (def_nr == -1) {
229 return;
230 }
231
232 const MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
233 const int dverts_size = dverts.size();
234 const Span<int> indices(indices_ptr, indices_num);
235 for (const int i : indices) {
236 if (i < dverts_size) {
237 MDeformVert *dv = &dverts[i];
238 if (MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr)) {
240 }
241 }
242 }
243
244 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
245 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
246}
247
248static void rna_GreasePencilDrawing_set_vertex_weights(ID *grease_pencil_id,
249 GreasePencilDrawing *drawing_ptr,
250 ReportList *reports,
251 const char *vertex_group_name,
252 const int *indices_ptr,
253 const int indices_num,
254 const float *weights_ptr,
255 const int weights_num,
256 const int assignmode)
257{
258 using namespace blender;
259 const Span<int> indices(indices_ptr, indices_num);
260 const Span<float> weights(weights_ptr, weights_num);
261 if (indices.size() != weights.size()) {
262 BKE_report(reports, RPT_ERROR, "Indices and weights must have the same lengths");
263 return;
264 }
265 if (!std::is_sorted(indices.begin(), indices.end())) {
266 BKE_report(reports, RPT_ERROR, "Indices must be sorted in ascending order");
267 return;
268 }
269 if (std::adjacent_find(indices.begin(), indices.end(), std::greater_equal<>()) != indices.end())
270 {
271 BKE_report(reports, RPT_ERROR, "Indices cannot have duplicates");
272 return;
273 }
274
275 const GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(grease_pencil_id);
276 const int vgroup_index = BKE_defgroup_name_index(&grease_pencil.vertex_group_names,
277 vertex_group_name);
278 if (vgroup_index == -1) {
279 BKE_reportf(reports, RPT_ERROR, "Vertex Group \"%s\" does not exist", vertex_group_name);
280 return;
281 }
282
283 const bDeformGroup *dg = static_cast<const bDeformGroup *>(
284 BLI_findlink(&grease_pencil.vertex_group_names, vgroup_index));
285 if (dg->flag & DG_LOCK_WEIGHT) {
286 BKE_reportf(reports, RPT_ERROR, "Vertex Group \"%s\" is locked", vertex_group_name);
287 return;
288 }
289
290 bke::CurvesGeometry &curves = drawing_ptr->wrap().strokes_for_write();
291 const int def_nr = bke::greasepencil::ensure_vertex_group(vertex_group_name,
292 curves.vertex_group_names);
293 const MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
294 if (std::any_of(indices.begin(), indices.end(), [&](const int index) {
295 return !dverts.index_range().contains(index);
296 }))
297 {
298 BKE_reportf(reports, RPT_ERROR, "Indices must be in range");
299 return;
300 }
301
302 threading::parallel_for(indices.index_range(), 2048, [&](const IndexRange range) {
303 for (const int i : range) {
304 const int dvert_index = indices[i];
305 const float weight = weights[i];
306 MDeformVert *dv = &dverts[dvert_index];
307 /* Lets first check to see if this vert is already in the weight group and update it. */
308 if (MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr)) {
309 switch (assignmode) {
310 case WEIGHT_REPLACE:
311 dw->weight = weight;
312 break;
313 case WEIGHT_ADD:
314 dw->weight += weight;
315 break;
316 case WEIGHT_SUBTRACT:
317 dw->weight -= weight;
318 break;
319 }
320 dw->weight = std::clamp(dw->weight, 0.0f, 1.0f);
321 }
322 else {
323 /* If the vert wasn't in the deform group then we must take a different form of action. */
324 switch (assignmode) {
325 case WEIGHT_SUBTRACT:
326 /* If we are subtracting then we don't need to do anything. */
327 return;
328
329 case WEIGHT_REPLACE:
330 case WEIGHT_ADD:
331 /* If we are doing an additive assignment, then we need to create the deform weight. */
332 /* We checked if the vertex was added before so no need to test again, simply add. */
333 BKE_defvert_add_index_notest(dv, def_nr, std::clamp(weight, 0.0f, 1.0f));
334 break;
335 }
336 }
337 }
338 });
339
341 DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY);
342}
343
344static GreasePencilFrame *rna_Frames_frame_new(ID *id,
345 GreasePencilLayer *layer_in,
346 ReportList *reports,
347 int frame_number)
348{
349 using namespace blender::bke::greasepencil;
350 GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
351 Layer &layer = layer_in->wrap();
352
353 if (layer.frames().contains(frame_number)) {
354 BKE_reportf(reports, RPT_ERROR, "Frame already exists on frame number %d", frame_number);
355 return nullptr;
356 }
357
358 grease_pencil.insert_frame(layer, frame_number, 0, BEZT_KEYTYPE_KEYFRAME);
359 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
360 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
361
362 return layer.frame_at(frame_number);
363}
364
365static void rna_Frames_frame_remove(ID *id,
366 GreasePencilLayer *layer_in,
367 ReportList *reports,
368 int frame_number)
369{
370 using namespace blender::bke::greasepencil;
371 GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
372 Layer &layer = layer_in->wrap();
373
374 if (!layer.frames().contains(frame_number)) {
375 BKE_reportf(reports, RPT_ERROR, "Frame does not exist on frame number %d", frame_number);
376 return;
377 }
378
379 if (grease_pencil.remove_frames(layer, {frame_number})) {
380 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
381 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
382 }
383
384 /* TODO: Use #PointerRNA::invalidate() to invalidate python objects pointing to the frame_number?
385 */
386}
387
388static GreasePencilFrame *rna_Frames_frame_copy(ID *id,
389 GreasePencilLayer *layer_in,
390 ReportList *reports,
391 int from_frame_number,
392 int to_frame_number,
393 bool instance_drawing)
394{
395 using namespace blender::bke::greasepencil;
396 GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
397 Layer &layer = layer_in->wrap();
398
399 if (!layer.frames().contains(from_frame_number)) {
400 BKE_reportf(reports, RPT_ERROR, "Frame does not exist on frame number %d", from_frame_number);
401 return nullptr;
402 }
403 if (layer.frames().contains(to_frame_number)) {
404 BKE_reportf(reports, RPT_ERROR, "Frame already exists on frame number %d", to_frame_number);
405 return nullptr;
406 }
407
408 grease_pencil.insert_duplicate_frame(
409 layer, from_frame_number, to_frame_number, instance_drawing);
410 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
411
412 return layer.frame_at(to_frame_number);
413}
414
415static GreasePencilFrame *rna_Frames_frame_move(ID *id,
416 GreasePencilLayer *layer_in,
417 ReportList *reports,
418 int from_frame_number,
419 int to_frame_number)
420{
421 using namespace blender::bke::greasepencil;
422 GreasePencil &grease_pencil = *reinterpret_cast<GreasePencil *>(id);
423 Layer &layer = layer_in->wrap();
424
425 if (!layer.frames().contains(from_frame_number)) {
426 BKE_reportf(reports, RPT_ERROR, "Frame does not exist on frame number %d", from_frame_number);
427 return nullptr;
428 }
429 if (layer.frames().contains(to_frame_number)) {
430 BKE_reportf(reports, RPT_ERROR, "Frame already exists on frame number %d", to_frame_number);
431 return nullptr;
432 }
433
434 grease_pencil.insert_duplicate_frame(layer, from_frame_number, to_frame_number, true);
435 grease_pencil.remove_frames(layer, {from_frame_number});
436 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, &grease_pencil);
437
438 /* TODO: Use #PointerRNA::invalidate() to invalidate python objects pointing to the
439 * from_frame_number? */
440
441 return layer.frame_at(to_frame_number);
442}
443
444static GreasePencilFrame *rna_GreasePencilLayer_get_frame_at(GreasePencilLayer *layer,
445 int frame_number)
446{
447 using namespace blender::bke::greasepencil;
448 return static_cast<Layer *>(layer)->frame_at(frame_number);
449}
450
451static GreasePencilFrame *rna_GreasePencilLayer_current_frame(GreasePencilLayer *layer,
452 bContext *C)
453{
454 using namespace blender::bke::greasepencil;
455 Scene *scene = CTX_data_scene(C);
456 return static_cast<Layer *>(layer)->frame_at(scene->r.cfra);
457}
458
459static GreasePencilLayer *rna_GreasePencil_layer_new(GreasePencil *grease_pencil,
460 const char *name,
461 const bool set_active,
462 PointerRNA *layer_group_ptr)
463{
464 using namespace blender::bke::greasepencil;
465 LayerGroup *layer_group = nullptr;
466 if (layer_group_ptr && layer_group_ptr->data) {
467 layer_group = static_cast<LayerGroup *>(layer_group_ptr->data);
468 }
469 Layer *layer;
470 if (layer_group) {
471 layer = &grease_pencil->add_layer(*layer_group, name);
472 }
473 else {
474 layer = &grease_pencil->add_layer(name);
475 }
476 if (set_active) {
477 grease_pencil->set_active_layer(layer);
478 }
479
480 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
481
482 return layer;
483}
484
485static void rna_GreasePencil_layer_remove(GreasePencil *grease_pencil, PointerRNA *layer_ptr)
486{
488 layer_ptr->data);
489 grease_pencil->remove_layer(layer);
490
491 layer_ptr->invalidate();
492 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
494}
495
496static void rna_GreasePencil_layer_move(GreasePencil *grease_pencil,
497 PointerRNA *layer_ptr,
498 const int direction)
499{
500 if (direction == 0) {
501 return;
502 }
503
505 static_cast<blender::bke::greasepencil::Layer *>(layer_ptr->data)->as_node();
506 switch (direction) {
507 case -1:
508 grease_pencil->move_node_down(layer_node, 1);
509 break;
510 case 1:
511 grease_pencil->move_node_up(layer_node, 1);
512 break;
513 }
514
515 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
516 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
517}
518
519static void rna_GreasePencil_layer_move_top(GreasePencil *grease_pencil, PointerRNA *layer_ptr)
520{
522 static_cast<blender::bke::greasepencil::Layer *>(layer_ptr->data)->as_node();
523 grease_pencil->move_node_top(layer_node);
524
525 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
526 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
527}
528
529static void rna_GreasePencil_layer_move_bottom(GreasePencil *grease_pencil, PointerRNA *layer_ptr)
530{
532 static_cast<blender::bke::greasepencil::Layer *>(layer_ptr->data)->as_node();
533 grease_pencil->move_node_bottom(layer_node);
534
535 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
536 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
537}
538
539static void rna_GreasePencil_layer_move_to_layer_group(GreasePencil *grease_pencil,
540 PointerRNA *layer_ptr,
541 PointerRNA *layer_group_ptr)
542{
543 using namespace blender::bke::greasepencil;
544 TreeNode &layer_node = static_cast<Layer *>(layer_ptr->data)->as_node();
545 LayerGroup *layer_group;
546 if (layer_group_ptr && layer_group_ptr->data) {
547 layer_group = static_cast<LayerGroup *>(layer_group_ptr->data);
548 }
549 else {
550 layer_group = &grease_pencil->root_group();
551 }
552 if (layer_group == nullptr) {
553 return;
554 }
555 grease_pencil->move_node_into(layer_node, *layer_group);
556
557 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
558 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
559}
560
561static PointerRNA rna_GreasePencil_layer_group_new(GreasePencil *grease_pencil,
562 const char *name,
563 PointerRNA *parent_group_ptr)
564{
565 using namespace blender::bke::greasepencil;
566 LayerGroup *parent_group;
567 if (parent_group_ptr && parent_group_ptr->data) {
568 parent_group = static_cast<LayerGroup *>(parent_group_ptr->data);
569 }
570 else {
571 parent_group = &grease_pencil->root_group();
572 }
573 LayerGroup *new_layer_group = &grease_pencil->add_layer_group(*parent_group, name);
574
575 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
576
578 &grease_pencil->id, &RNA_GreasePencilLayerGroup, new_layer_group);
579 return ptr;
580}
581
582static void rna_GreasePencil_layer_group_remove(GreasePencil *grease_pencil,
583 PointerRNA *layer_group_ptr,
584 bool keep_children)
585{
586 using namespace blender::bke::greasepencil;
587 LayerGroup &layer_group = *static_cast<LayerGroup *>(layer_group_ptr->data);
588 grease_pencil->remove_group(layer_group, keep_children);
589
590 layer_group_ptr->invalidate();
591 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
593}
594
595static void rna_GreasePencil_layer_group_move(GreasePencil *grease_pencil,
596 PointerRNA *layer_group_ptr,
597 int direction)
598{
599 if (direction == 0) {
600 return;
601 }
602
603 blender::bke::greasepencil::TreeNode &layer_group_node =
604 static_cast<blender::bke::greasepencil::LayerGroup *>(layer_group_ptr->data)->as_node();
605 switch (direction) {
606 case -1:
607 grease_pencil->move_node_down(layer_group_node, 1);
608 break;
609 case 1:
610 grease_pencil->move_node_up(layer_group_node, 1);
611 break;
612 }
613
614 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
615 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
616}
617
618static void rna_GreasePencil_layer_group_move_top(GreasePencil *grease_pencil,
619 PointerRNA *layer_group_ptr)
620{
621 blender::bke::greasepencil::TreeNode &layer_group_node =
622 static_cast<blender::bke::greasepencil::LayerGroup *>(layer_group_ptr->data)->as_node();
623 grease_pencil->move_node_top(layer_group_node);
624
625 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
626 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
627}
628
629static void rna_GreasePencil_layer_group_move_bottom(GreasePencil *grease_pencil,
630 PointerRNA *layer_group_ptr)
631{
632 blender::bke::greasepencil::TreeNode &layer_group_node =
633 static_cast<blender::bke::greasepencil::LayerGroup *>(layer_group_ptr->data)->as_node();
634 grease_pencil->move_node_bottom(layer_group_node);
635
636 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
637 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
638}
639
640static void rna_GreasePencil_layer_group_move_to_layer_group(GreasePencil *grease_pencil,
641 PointerRNA *layer_group_ptr,
642 PointerRNA *parent_group_ptr)
643{
644 using namespace blender::bke::greasepencil;
645 TreeNode &layer_group_node = static_cast<LayerGroup *>(layer_group_ptr->data)->as_node();
646 LayerGroup *parent_group;
647 if (parent_group_ptr && parent_group_ptr->data) {
648 parent_group = static_cast<LayerGroup *>(parent_group_ptr->data);
649 }
650 else {
651 parent_group = &grease_pencil->root_group();
652 }
653 grease_pencil->move_node_into(layer_group_node, *parent_group);
654
655 DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
656 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, grease_pencil);
657}
658
659#else
660
662{
663 FunctionRNA *func;
664 PropertyRNA *parm;
665
666 func = RNA_def_function(srna, "add_strokes", "rna_GreasePencilDrawing_add_curves");
667 RNA_def_function_ui_description(func, "Add new strokes with provided sizes at the end");
669 parm = RNA_def_int_array(func,
670 "sizes",
671 1,
672 nullptr,
673 1,
674 INT_MAX,
675 "Sizes",
676 "The number of points in each stroke",
677 1,
678 10000);
680
681 func = RNA_def_function(srna, "remove_strokes", "rna_GreasePencilDrawing_remove_curves");
683 "Remove all strokes. If indices are provided, remove only the "
684 "strokes with the given indices.");
686 parm = RNA_def_int_array(func,
687 "indices",
688 1,
689 nullptr,
690 0,
691 INT_MAX,
692 "Indices",
693 "The indices of the strokes to remove",
694 0,
695 10000);
697
698 func = RNA_def_function(srna, "resize_strokes", "rna_GreasePencilDrawing_resize_curves");
700 func,
701 "Resize all existing strokes. If indices are provided, resize only the strokes with the "
702 "given indices. If the new size for a stroke is smaller, the stroke is trimmed. If "
703 "the new size for a stroke is larger, the new end values are default initialized.");
705 parm = RNA_def_int_array(func,
706 "sizes",
707 1,
708 nullptr,
709 1,
710 INT_MAX,
711 "Sizes",
712 "The number of points in each stroke",
713 1,
714 10000);
716 parm = RNA_def_int_array(func,
717 "indices",
718 1,
719 nullptr,
720 0,
721 INT_MAX,
722 "Indices",
723 "The indices of the stroke to resize",
724 0,
725 10000);
727
728 func = RNA_def_function(srna, "reorder_strokes", "rna_GreasePencilDrawing_reorder_curves");
729 RNA_def_function_ui_description(func, "Reorder the strokes by the new indices.");
731 parm = RNA_def_int_array(func,
732 "new_indices",
733 1,
734 nullptr,
735 0,
736 INT_MAX,
737 "New indices",
738 "The new index for each of the strokes",
739 0,
740 10000);
742
743 func = RNA_def_function(srna, "set_types", "rna_GreasePencilDrawing_set_types");
745 "Set the curve type. If indices are provided, set only the "
746 "types with the given curve indices.");
749 parm = RNA_def_int_array(func,
750 "indices",
751 1,
752 nullptr,
753 0,
754 INT_MAX,
755 "Indices",
756 "The indices of the curves to resize",
757 0,
758 INT_MAX);
760
761 func = RNA_def_function(
762 srna, "tag_positions_changed", "rna_GreasePencilDrawing_tag_positions_changed");
764 func, "Indicate that the positions of points in the drawing have changed");
765
766 func = RNA_def_function(
767 srna, "vertex_group_assign", "rna_GreasePencilDrawing_vertex_group_assign");
768 RNA_def_function_ui_description(func, "Assign points to vertex group");
770 parm = RNA_def_string(
771 func, "vgroup_name", "Group", MAX_NAME, "Vertex Group Name", "Name of the vertex group");
773 parm = RNA_def_int_array(func,
774 "indices_ptr",
775 1,
776 nullptr,
777 0,
778 0,
779 "Indices",
780 "The point indices to assign the weight to",
781 0,
782 0);
784 parm = RNA_def_float(func, "weight", 0, 0.0f, 1.0f, "", "Vertex weight", 0.0f, 1.0f);
786
787 func = RNA_def_function(
788 srna, "vertex_group_remove", "rna_GreasePencilDrawing_vertex_group_remove");
789 RNA_def_function_ui_description(func, "Remove points from vertex group");
791 parm = RNA_def_string(
792 func, "vgroup_name", "Group", MAX_NAME, "Vertex Group Name", "Name of the vertex group");
794 parm = RNA_def_int_array(func,
795 "indices_ptr",
796 1,
797 nullptr,
798 0,
799 0,
800 "Indices",
801 "The point indices to remove from the vertex group",
802 0,
803 0);
805
806 static const EnumPropertyItem assign_mode_items[] = {
807 {WEIGHT_REPLACE, "REPLACE", 0, "Replace", "Replace"},
808 {WEIGHT_ADD, "ADD", 0, "Add", "Add"},
809 {WEIGHT_SUBTRACT, "SUBTRACT", 0, "Subtract", "Subtract"},
810 {0, nullptr, 0, nullptr, nullptr},
811 };
812 func = RNA_def_function(
813 srna, "set_vertex_weights", "rna_GreasePencilDrawing_set_vertex_weights");
814 RNA_def_function_ui_description(func, "Set the weights of vertices in a grease pencil drawing");
816 parm = RNA_def_string(func,
817 "vertex_group_name",
818 "Group",
819 MAX_NAME,
820 "Vertex Group Name",
821 "Name of the vertex group");
823 parm = RNA_def_int_array(func,
824 "indices",
825 1,
826 nullptr,
827 0,
828 0,
829 "Indices",
830 "The point indices in the vertex group to modify",
831 0,
832 0);
834 parm = RNA_def_float_array(func,
835 "weights",
836 1,
837 nullptr,
838 0.0f,
839 1.0f,
840 "Weights",
841 "The weight for each corresponding index in the indices array",
842 0,
843 0);
845 parm = RNA_def_enum(func, "assign_mode", assign_mode_items, 0, "", "");
846}
847
849{
850 FunctionRNA *func;
851 PropertyRNA *parm;
852
853 func = RNA_def_function(srna, "new", "rna_Frames_frame_new");
854 RNA_def_function_ui_description(func, "Add a new Grease Pencil frame");
856 parm = RNA_def_int(func,
857 "frame_number",
858 1,
859 MINAFRAME,
860 MAXFRAME,
861 "Frame Number",
862 "The frame on which the drawing appears",
863 MINAFRAME,
864 MAXFRAME);
866 parm = RNA_def_pointer(func, "frame", "GreasePencilFrame", "", "The newly created frame");
867 RNA_def_function_return(func, parm);
868
869 func = RNA_def_function(srna, "remove", "rna_Frames_frame_remove");
870 RNA_def_function_ui_description(func, "Remove a Grease Pencil frame");
872 parm = RNA_def_int(func,
873 "frame_number",
874 1,
875 MINAFRAME,
876 MAXFRAME,
877 "Frame Number",
878 "The frame number of the frame to remove",
879 MINAFRAME,
880 MAXFRAME);
882
883 func = RNA_def_function(srna, "copy", "rna_Frames_frame_copy");
884 RNA_def_function_ui_description(func, "Copy a Grease Pencil frame");
886 parm = RNA_def_int(func,
887 "from_frame_number",
888 1,
889 MINAFRAME,
890 MAXFRAME,
891 "Source Frame Number",
892 "The frame number of the source frame",
893 MINAFRAME,
894 MAXFRAME);
896 parm = RNA_def_int(func,
897 "to_frame_number",
898 2,
899 MINAFRAME,
900 MAXFRAME,
901 "Frame Number of Copy",
902 "The frame number to copy the frame to",
903 MINAFRAME,
904 MAXFRAME);
906 parm = RNA_def_boolean(func,
907 "instance_drawing",
908 false,
909 "Instance Drawing",
910 "Let the copied frame use the same drawing as the source");
911 parm = RNA_def_pointer(func, "copy", "GreasePencilFrame", "", "The newly copied frame");
912 RNA_def_function_return(func, parm);
913
914 func = RNA_def_function(srna, "move", "rna_Frames_frame_move");
915 RNA_def_function_ui_description(func, "Move a Grease Pencil frame");
917 parm = RNA_def_int(func,
918 "from_frame_number",
919 1,
920 MINAFRAME,
921 MAXFRAME,
922 "Source Frame Number",
923 "The frame number of the source frame",
924 MINAFRAME,
925 MAXFRAME);
927 parm = RNA_def_int(func,
928 "to_frame_number",
929 2,
930 MINAFRAME,
931 MAXFRAME,
932 "Target Frame Number",
933 "The frame number to move the frame to",
934 MINAFRAME,
935 MAXFRAME);
937 parm = RNA_def_pointer(func, "moved", "GreasePencilFrame", "", "The moved frame");
938 RNA_def_function_return(func, parm);
939}
940
942{
943 FunctionRNA *func;
944 PropertyRNA *parm;
945
946 func = RNA_def_function(srna, "get_frame_at", "rna_GreasePencilLayer_get_frame_at");
947 RNA_def_function_ui_description(func, "Get the frame at given frame number");
948 parm = RNA_def_int(
949 func, "frame_number", 1, MINAFRAME, MAXFRAME, "Frame Number", "", MINAFRAME, MAXFRAME);
951 parm = RNA_def_pointer(func, "frame", "GreasePencilFrame", "Frame", "");
952 RNA_def_function_return(func, parm);
953
954 func = RNA_def_function(srna, "current_frame", "rna_GreasePencilLayer_current_frame");
956 func, "The Grease Pencil frame at the current scene time on this layer");
958 parm = RNA_def_pointer(func, "frame", "GreasePencilFrame", "", "");
959 RNA_def_function_return(func, parm);
960}
961
963{
964 FunctionRNA *func;
965 PropertyRNA *parm;
966
967 func = RNA_def_function(srna, "new", "rna_GreasePencil_layer_new");
968 RNA_def_function_ui_description(func, "Add a new Grease Pencil layer");
969 parm = RNA_def_string(func, "name", "GreasePencilLayer", MAX_NAME, "Name", "Name of the layer");
972 func, "set_active", true, "Set Active", "Set the newly created layer as the active layer");
973 parm = RNA_def_pointer(
974 func,
975 "layer_group",
976 "GreasePencilLayerGroup",
977 "",
978 "The layer group the new layer will be created in (use None for the main stack)");
980 parm = RNA_def_pointer(func, "layer", "GreasePencilLayer", "", "The newly created layer");
981 RNA_def_function_return(func, parm);
982
983 func = RNA_def_function(srna, "remove", "rna_GreasePencil_layer_remove");
984 RNA_def_function_ui_description(func, "Remove a Grease Pencil layer");
985 parm = RNA_def_pointer(func, "layer", "GreasePencilLayer", "", "The layer to remove");
988
989 func = RNA_def_function(srna, "move", "rna_GreasePencil_layer_move");
991 "Move a Grease Pencil layer in the layer group or main stack");
992 parm = RNA_def_pointer(func, "layer", "GreasePencilLayer", "", "The layer to move");
995 parm = RNA_def_enum(
996 func, "type", rna_enum_tree_node_move_type_items, 1, "", "Direction of movement");
998
999 func = RNA_def_function(srna, "move_top", "rna_GreasePencil_layer_move_top");
1001 func, "Move a Grease Pencil layer to the top of the layer group or main stack");
1002 parm = RNA_def_pointer(func, "layer", "GreasePencilLayer", "", "The layer to move");
1005
1006 func = RNA_def_function(srna, "move_bottom", "rna_GreasePencil_layer_move_bottom");
1008 func, "Move a Grease Pencil layer to the bottom of the layer group or main stack");
1009 parm = RNA_def_pointer(func, "layer", "GreasePencilLayer", "", "The layer to move");
1012
1013 func = RNA_def_function(
1014 srna, "move_to_layer_group", "rna_GreasePencil_layer_move_to_layer_group");
1015 RNA_def_function_ui_description(func, "Move a Grease Pencil layer into a layer group");
1016 parm = RNA_def_pointer(func, "layer", "GreasePencilLayer", "", "The layer to move");
1019 parm = RNA_def_pointer(
1020 func,
1021 "layer_group",
1022 "GreasePencilLayerGroup",
1023 "",
1024 "The layer group the layer will be moved into (use None for the main stack)");
1027}
1028
1030{
1031 FunctionRNA *func;
1032 PropertyRNA *parm;
1033
1034 func = RNA_def_function(srna, "new", "rna_GreasePencil_layer_group_new");
1035 RNA_def_function_ui_description(func, "Add a new Grease Pencil layer group");
1036 parm = RNA_def_string(
1037 func, "name", "GreasePencilLayerGroup", MAX_NAME, "Name", "Name of the layer group");
1039 parm = RNA_def_pointer(func,
1040 "parent_group",
1041 "GreasePencilLayerGroup",
1042 "",
1043 "The parent layer group the new group will be created in (use None "
1044 "for the main stack)");
1046 parm = RNA_def_pointer(
1047 func, "layer_group", "GreasePencilLayerGroup", "", "The newly created layer group");
1049 RNA_def_function_return(func, parm);
1050
1051 func = RNA_def_function(srna, "remove", "rna_GreasePencil_layer_group_remove");
1052 RNA_def_function_ui_description(func, "Remove a new Grease Pencil layer group");
1053 parm = RNA_def_pointer(
1054 func, "layer_group", "GreasePencilLayerGroup", "", "The layer group to remove");
1057 parm = RNA_def_boolean(func,
1058 "keep_children",
1059 false,
1060 "",
1061 "Keep the children nodes of the group and only delete the group itself");
1062
1063 func = RNA_def_function(srna, "move", "rna_GreasePencil_layer_group_move");
1065 "Move a layer group in the parent layer group or main stack");
1066 parm = RNA_def_pointer(
1067 func, "layer_group", "GreasePencilLayerGroup", "", "The layer group to move");
1070 parm = RNA_def_enum(
1071 func, "type", rna_enum_tree_node_move_type_items, 1, "", "Direction of movement");
1073
1074 func = RNA_def_function(srna, "move_top", "rna_GreasePencil_layer_group_move_top");
1076 func, "Move a layer group to the top of the parent layer group or main stack");
1077 parm = RNA_def_pointer(
1078 func, "layer_group", "GreasePencilLayerGroup", "", "The layer group to move");
1081
1082 func = RNA_def_function(srna, "move_bottom", "rna_GreasePencil_layer_group_move_bottom");
1084 func, "Move a layer group to the bottom of the parent layer group or main stack");
1085 parm = RNA_def_pointer(
1086 func, "layer_group", "GreasePencilLayerGroup", "", "The layer group to move");
1089
1090 func = RNA_def_function(
1091 srna, "move_to_layer_group", "rna_GreasePencil_layer_group_move_to_layer_group");
1092 RNA_def_function_ui_description(func, "Move a layer group into a parent layer group");
1093 parm = RNA_def_pointer(
1094 func, "layer_group", "GreasePencilLayerGroup", "", "The layer group to move");
1097 parm = RNA_def_pointer(func,
1098 "parent_group",
1099 "GreasePencilLayerGroup",
1100 "",
1101 "The parent layer group the layer group will be moved into (use "
1102 "None for the main stack)");
1105}
1106
1107#endif
Scene * CTX_data_scene(const bContext *C)
Low-level operations for curves.
support for deformation groups and hooks.
int BKE_defgroup_name_index(const ListBase *defbase, blender::StringRef name)
Definition deform.cc:540
MDeformWeight * BKE_defvert_ensure_index(MDeformVert *dv, int defgroup)
Definition deform.cc:825
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:806
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
Definition deform.cc:880
Low-level operations for grease pencil.
Utility functions for vertex groups in grease pencil objects.
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ BEZT_KEYTYPE_KEYFRAME
#define MAX_NAME
Definition DNA_defs.h:50
@ DG_LOCK_WEIGHT
#define MINAFRAME
#define MAXFRAME
#define WEIGHT_REPLACE
#define WEIGHT_ADD
#define WEIGHT_SUBTRACT
ParameterFlag
Definition RNA_types.hh:544
@ PARM_RNAPTR
Definition RNA_types.hh:547
@ PARM_REQUIRED
Definition RNA_types.hh:545
@ FUNC_USE_REPORTS
Definition RNA_types.hh:914
@ FUNC_USE_CONTEXT
Definition RNA_types.hh:913
@ FUNC_USE_SELF_ID
Definition RNA_types.hh:889
PropertyFlag
Definition RNA_types.hh:300
@ PROP_THICK_WRAP
Definition RNA_types.hh:423
@ PROP_DYNAMIC
Definition RNA_types.hh:428
@ PROP_NEVER_NULL
Definition RNA_types.hh:377
#define C
Definition RandGen.cpp:29
#define NC_GEOM
Definition WM_types.hh:393
#define ND_DATA
Definition WM_types.hh:509
#define ND_VERTEX_GROUP
Definition WM_types.hh:510
#define NA_EDITED
Definition WM_types.hh:584
#define NC_GPENCIL
Definition WM_types.hh:399
#define NA_SELECTED
Definition WM_types.hh:589
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
const GreasePencilFrame * frame_at(const int frame_number) const
constexpr int64_t size() const
Definition BLI_span.hh:493
MutableSpan< MDeformVert > deform_verts_for_write()
MutableSpan< int8_t > curve_types_for_write()
bke::CurvesGeometry & strokes_for_write()
static ushort indices[]
int ensure_vertex_group(StringRef name, ListBase &vertex_group_names)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
const char * name
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const EnumPropertyItem rna_enum_curves_type_items[]
Definition rna_curves.cc:24
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const int *default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_parameter_clear_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
void RNA_def_function_flag(FunctionRNA *func, int flag)
PropertyRNA * RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void RNA_api_grease_pencil_drawing(StructRNA *srna)
void RNA_api_grease_pencil_frames(StructRNA *srna)
const EnumPropertyItem rna_enum_tree_node_move_type_items[]
void RNA_api_grease_pencil_layer(StructRNA *srna)
void RNA_api_grease_pencil_layers(StructRNA *srna)
void RNA_api_grease_pencil_layer_groups(StructRNA *srna)
ListBase vertex_group_names
Definition DNA_ID.h:414
int us
Definition DNA_ID.h:443
void invalidate()
Definition RNA_types.hh:110
void * data
Definition RNA_types.hh:53
struct RenderData r
i
Definition text_draw.cc:230
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4238