Blender V4.5
object_modifier.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdio>
10#include <cstdlib>
11
12#include "CLG_log.h"
13
14#include "MEM_guardedalloc.h"
15
16#include "DNA_armature_types.h"
17#include "DNA_array_utils.hh"
18#include "DNA_curve_types.h"
19#include "DNA_defaults.h"
20#include "DNA_key_types.h"
21#include "DNA_lattice_types.h"
22#include "DNA_material_types.h"
23#include "DNA_mesh_types.h"
24#include "DNA_meshdata_types.h"
27#include "DNA_scene_types.h"
28
29#include "BLI_array_utils.hh"
30#include "BLI_bitmap.h"
31#include "BLI_listbase.h"
32#include "BLI_string.h"
33#include "BLI_string_utf8.h"
34#include "BLI_string_utils.hh"
35#include "BLI_utildefines.h"
36
37#include "BKE_animsys.h"
39#include "BKE_armature.hh"
40#include "BKE_context.hh"
41#include "BKE_curve.hh"
42#include "BKE_curves.h"
43#include "BKE_curves.hh"
44#include "BKE_displist.h"
45#include "BKE_editmesh.hh"
46#include "BKE_effect.h"
47#include "BKE_geometry_set.hh"
48#include "BKE_global.hh"
49#include "BKE_grease_pencil.hh"
50#include "BKE_idprop.hh"
51#include "BKE_key.hh"
52#include "BKE_lattice.hh"
53#include "BKE_layer.hh"
54#include "BKE_lib_id.hh"
55#include "BKE_library.hh"
56#include "BKE_main.hh"
58#include "BKE_material.hh"
59#include "BKE_mball.hh"
60#include "BKE_mesh.hh"
61#include "BKE_mesh_mapping.hh"
62#include "BKE_mesh_runtime.hh"
63#include "BKE_modifier.hh"
64#include "BKE_multires.hh"
65#include "BKE_object.hh"
66#include "BKE_object_deform.h"
67#include "BKE_object_types.hh"
68#include "BKE_ocean.h"
69#include "BKE_paint.hh"
70#include "BKE_particle.h"
71#include "BKE_pointcloud.hh"
72#include "BKE_report.hh"
73#include "BKE_scene.hh"
74#include "BKE_softbody.h"
75#include "BKE_volume.hh"
76
77#include "BLT_translation.hh"
78
79#include "DEG_depsgraph.hh"
82
83#include "RNA_access.hh"
84#include "RNA_define.hh"
85#include "RNA_enum_types.hh"
86#include "RNA_prototypes.hh"
87
88#include "ED_armature.hh"
89#include "ED_grease_pencil.hh"
90#include "ED_node.hh"
91#include "ED_object.hh"
92#include "ED_object_vgroup.hh"
93#include "ED_screen.hh"
94
96
97#include "GEO_merge_layers.hh"
98
99#include "UI_interface.hh"
100
101#include "WM_api.hh"
102#include "WM_types.hh"
103
104#include "object_intern.hh"
105
106namespace blender::ed::object {
107
108static CLG_LogRef LOG = {"ed.object"};
109
111
112/* ------------------------------------------------------------------- */
115
117{
119 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
120 BKE_object_eval_reset(ob_eval);
121 if (ob->type == OB_MESH) {
123 depsgraph, scene_eval, ob_eval, &CD_MASK_DERIVEDMESH);
124 BKE_id_free(nullptr, mesh_eval);
125 }
126 else if (ob->type == OB_LATTICE) {
127 BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval);
128 }
129 else if (ob->type == OB_MBALL) {
130 BKE_mball_data_update(depsgraph, scene_eval, ob_eval);
131 }
132 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
133 BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false);
134 }
135 else if (ob->type == OB_CURVES) {
136 BKE_curves_data_update(depsgraph, scene_eval, ob);
137 }
138 else if (ob->type == OB_POINTCLOUD) {
139 BKE_pointcloud_data_update(depsgraph, scene_eval, ob);
140 }
141 else if (ob->type == OB_VOLUME) {
142 BKE_volume_data_update(depsgraph, scene_eval, ob);
143 }
144}
145
147 Object *object,
148 ModifierData *md)
149{
150 ModifierData *md_eval = BKE_modifier_get_evaluated(depsgraph, object, md);
151 const int mode = md_eval->mode;
152 md_eval->mode |= eModifierMode_Realtime;
154 md_eval->mode = mode;
155}
156
158 ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
159{
160 ModifierData *new_md = nullptr;
162
163 /* Check compatibility of modifier [#25291, #50373]. */
165 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2);
166 return nullptr;
167 }
168
169 if (mti->flags & eModifierTypeFlag_Single) {
171 BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed");
172 return nullptr;
173 }
174 }
175
176 if (type == eModifierType_ParticleSystem) {
177 /* don't need to worry about the new modifier's name, since that is set to the number
178 * of particle systems which shouldn't have too many duplicates
179 */
180 new_md = object_add_particle_system(bmain, scene, ob, name);
181 }
182 else {
183 /* get new modifier data to add */
184 new_md = BKE_modifier_new(type);
185
186 ModifierData *next_md = nullptr;
188 if (md->flag & eModifierFlag_PinLast) {
189 next_md = md;
190 }
191 else {
192 break;
193 }
194 }
196 next_md = static_cast<ModifierData *>(ob->modifiers.first);
197
198 while (next_md && BKE_modifier_get_info((ModifierType)next_md->type)->type ==
200 {
201 if (next_md->next && (next_md->next->flag & eModifierFlag_PinLast) != 0) {
202 break;
203 }
204 next_md = next_md->next;
205 }
206 }
207 BLI_insertlinkbefore(&ob->modifiers, next_md, new_md);
209
210 if (name) {
211 STRNCPY_UTF8(new_md->name, name);
212 }
213
214 /* make sure modifier data has unique name */
215
217
218 /* special cases */
219 if (type == eModifierType_Softbody) {
220 if (!ob->soft) {
221 ob->soft = sbNew();
223 }
224 }
225 else if (type == eModifierType_Collision) {
226 if (!ob->pd) {
227 ob->pd = BKE_partdeflect_new(0);
228 }
229
230 ob->pd->deflect = 1;
231 }
232 else if (type == eModifierType_Surface) {
233 /* pass */
234 }
235 else if (type == eModifierType_Multires) {
236 /* set totlvl from existing MDISPS layer if object already had it */
238
239 if (ob->mode & OB_MODE_SCULPT) {
240 /* ensure that grid paint mask layer is created */
241 BKE_sculpt_mask_layers_ensure(nullptr, nullptr, ob, (MultiresModifierData *)new_md);
242 }
243 }
244 else if (type == eModifierType_Skin) {
245 /* ensure skin-node customdata exists */
246 BKE_mesh_ensure_skin_customdata(static_cast<Mesh *>(ob->data));
247 }
248 }
249
251
254
255 return new_md;
256}
257
258/* Return true if the object has a modifier of type 'type' other than
259 * the modifier pointed to be 'exclude', otherwise returns false. */
260static bool object_has_modifier(const Object *ob, const ModifierData *exclude, ModifierType type)
261{
263 if ((md != exclude) && (md->type == type)) {
264 return true;
265 }
266 }
267
268 return false;
269}
270
271bool iter_other(Main *bmain,
272 Object *orig_ob,
273 const bool include_orig,
274 bool (*callback)(Object *ob, void *callback_data),
275 void *callback_data)
276{
277 ID *ob_data_id = static_cast<ID *>(orig_ob->data);
278 int users = ob_data_id->us;
279
280 if (ob_data_id->flag & ID_FLAG_FAKEUSER) {
281 users--;
282 }
283
284 /* First check that the object's data has multiple users */
285 if (users > 1) {
286 Object *ob;
287 int totfound = include_orig ? 0 : 1;
288
289 for (ob = static_cast<Object *>(bmain->objects.first); ob && totfound < users;
290 ob = reinterpret_cast<Object *>(ob->id.next))
291 {
292 if (((ob != orig_ob) || include_orig) && (ob->data == orig_ob->data)) {
293 if (callback(ob, callback_data)) {
294 return true;
295 }
296
297 totfound++;
298 }
299 }
300 }
301 else if (include_orig) {
302 return callback(orig_ob, callback_data);
303 }
304
305 return false;
306}
307
308static bool object_has_modifier_cb(Object *ob, void *data)
309{
310 ModifierType type = *((ModifierType *)data);
311
312 return object_has_modifier(ob, nullptr, type);
313}
314
315bool multires_update_totlevels(Object *ob, void *totlevel_v)
316{
317 int totlevel = *((char *)totlevel_v);
318
320 if (md->type == eModifierType_Multires) {
321 multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel);
323 }
324 }
325 return false;
326}
327
328/* Return true if no modifier of type 'type' other than 'exclude' */
330 Object *ob,
331 ModifierData *exclude,
332 ModifierType type)
333{
334 return (!object_has_modifier(ob, exclude, type) &&
335 !iter_other(bmain, ob, false, object_has_modifier_cb, &type));
336}
337
339 Main *bmain, Scene *scene, Object *ob, ModifierData *md, bool *r_sort_depsgraph)
340{
341 /* It seems on rapid delete it is possible to
342 * get called twice on same modifier, so make
343 * sure it is in list. */
344 if (BLI_findindex(&ob->modifiers, md) == -1) {
345 return false;
346 }
347
348 /* special cases */
350 object_remove_particle_system(bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
351 return true;
352 }
353
354 if (md->type == eModifierType_Softbody) {
355 if (ob->soft) {
356 sbFree(ob);
357 ob->softflag = 0; /* TODO(Sybren): this should probably be moved into sbFree() */
358 }
359 }
360 else if (md->type == eModifierType_Collision) {
361 if (ob->pd) {
362 ob->pd->deflect = 0;
363 }
364
365 *r_sort_depsgraph = true;
366 }
367 else if (md->type == eModifierType_Surface) {
368 *r_sort_depsgraph = true;
369 }
370 else if (md->type == eModifierType_Multires) {
371 /* Delete MDisps layer if not used by another multires modifier */
373 multires_customdata_delete(static_cast<Mesh *>(ob->data));
374 }
375 }
376 else if (md->type == eModifierType_Skin) {
377 /* Delete MVertSkin layer if not used by another skin modifier */
380 }
381 }
382
385 {
387 }
388
389 BKE_animdata_drivers_remove_for_rna_struct(ob->id, RNA_Modifier, md);
390
394
395 return true;
396}
397
399{
400 bool sort_depsgraph = false;
401
402 bool ok = object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
403
404 if (!ok) {
405 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
406 return false;
407 }
408
411
412 return true;
413}
414
415void modifiers_clear(Main *bmain, Scene *scene, Object *ob)
416{
417 ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
418 bool sort_depsgraph = false;
419
420 if (!md) {
421 return;
422 }
423
424 while (md) {
425 ModifierData *next_md = md->next;
426
427 object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
428
429 md = next_md;
430 }
431
434}
435
437 eReportType error_type,
438 ModifierData *md,
439 ModifierData *md_prev)
440{
441 if (md_prev) {
442 if (md->flag & eModifierFlag_PinLast && !(md_prev->flag & eModifierFlag_PinLast)) {
443 return false;
444 }
446
449
451 BKE_report(reports, error_type, "Cannot move above a modifier requiring original data");
452 return false;
453 }
454 }
455 }
456 else {
457 BKE_report(reports, error_type, "Cannot move modifier beyond the start of the list");
458 return false;
459 }
460
461 return true;
462}
463
465{
466 if (object_modifier_check_move_before(reports, error_type, md, md->prev)) {
468 return true;
469 }
470
471 return false;
472}
473
475 eReportType error_type,
476 ModifierData *md,
477 ModifierData *md_next)
478{
479 if (md_next) {
480 if (md_next->flag & eModifierFlag_PinLast && !(md->flag & eModifierFlag_PinLast)) {
481 return false;
482 }
484
487
488 if (nmti->type != ModifierTypeType::OnlyDeform) {
489 BKE_report(reports, error_type, "Cannot move beyond a non-deforming modifier");
490 return false;
491 }
492 }
493 }
494 else {
495 BKE_report(reports, error_type, "Cannot move modifier beyond the end of the list");
496 return false;
497 }
498
499 return true;
500}
501
503{
504 if (object_modifier_check_move_after(reports, error_type, md, md->next)) {
506 return true;
507 }
508
509 return false;
510}
511
513 eReportType error_type,
514 Object *ob,
515 ModifierData *md,
516 const int index,
517 bool allow_partial)
518{
519 BLI_assert(md != nullptr);
520
521 if (index < 0 || index >= BLI_listbase_count(&ob->modifiers)) {
522 BKE_report(reports, error_type, "Cannot move modifier beyond the end of the stack");
523 return false;
524 }
525
526 int md_index = BLI_findindex(&ob->modifiers, md);
527 BLI_assert(md_index != -1);
528
529 if (md_index < index) {
530 /* Move modifier down in list. */
531 ModifierData *md_target = md;
532
533 for (; md_index < index; md_index++, md_target = md_target->next) {
534 if (!object_modifier_check_move_after(reports, error_type, md, md_target->next)) {
535 if (!allow_partial || md == md_target) {
536 return false;
537 }
538
539 break;
540 }
541 }
542
543 BLI_assert(md != md_target && md_target);
544
545 BLI_remlink(&ob->modifiers, md);
546 BLI_insertlinkafter(&ob->modifiers, md_target, md);
547 }
548 else if (md_index > index) {
549 /* Move modifier up in list. */
550 ModifierData *md_target = md;
551
552 for (; md_index > index; md_index--, md_target = md_target->prev) {
553 if (!object_modifier_check_move_before(reports, error_type, md, md_target->prev)) {
554 if (!allow_partial || md == md_target) {
555 return false;
556 }
557
558 break;
559 }
560 }
561
562 BLI_assert(md != md_target && md_target);
563
564 BLI_remlink(&ob->modifiers, md);
565 BLI_insertlinkbefore(&ob->modifiers, md_target, md);
566 }
567 else {
568 return true;
569 }
570
571 /* NOTE: Dependency graph only uses modifier nodes for visibility updates, and exact order of
572 * modifier nodes in the graph does not matter. */
573
576
577 return true;
578}
579
589
591 const Scene *scene,
592 const Object *ob_src,
593 const ModifierData *md,
594 Object *ob_dst,
596{
598
599 BLI_assert(ob_src != ob_dst);
600
601 /* Checked in #BKE_object_copy_modifier, but check here too so we can give a better message. */
605 "Object '%s' does not support %s modifiers",
606 ob_dst->id.name + 2,
607 RPT_(mti->name));
608 return false;
609 }
610
611 if (mti->flags & eModifierTypeFlag_Single) {
612 if (BKE_modifiers_findby_type(ob_dst, (ModifierType)md->type)) {
615 "Modifier can only be added once to object '%s'",
616 ob_dst->id.name + 2);
617 return false;
618 }
619 }
620
621 if (!BKE_object_copy_modifier(bmain, scene, ob_dst, ob_src, md)) {
623 RPT_ERROR,
624 "Copying modifier '%s' to object '%s' failed",
625 md->name,
626 ob_dst->id.name + 2);
627 return false;
628 }
629
633 return true;
634}
635
637 Main *bmain,
638 Depsgraph *depsgraph,
639 Scene *scene,
640 ViewLayer *view_layer,
641 Object *ob,
642 ModifierData *md)
643{
644 int cvert = 0;
645
647 return false;
648 }
649 if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
650 return false;
651 }
652
653 ParticleSystem *psys_orig = ((ParticleSystemModifierData *)md)->psys;
654 ParticleSettings *part = psys_orig->part;
655
656 if (part->ren_as != PART_DRAW_PATH) {
657 return false;
658 }
659 ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys_orig);
660 if (psys_eval->pathcache == nullptr) {
661 return false;
662 }
663
664 int part_num = psys_eval->totcached;
665 int child_num = psys_eval->totchildcache;
666
667 if (child_num && (part->draw & PART_DRAW_PARENT) == 0) {
668 part_num = 0;
669 }
670
671 /* count */
672 int verts_num = 0, edges_num = 0;
673 ParticleCacheKey **cache = psys_eval->pathcache;
674 for (int a = 0; a < part_num; a++) {
675 ParticleCacheKey *key = cache[a];
676
677 if (key->segments > 0) {
678 verts_num += key->segments + 1;
679 edges_num += key->segments;
680 }
681 }
682
683 cache = psys_eval->childcache;
684 for (int a = 0; a < child_num; a++) {
685 ParticleCacheKey *key = cache[a];
686
687 if (key->segments > 0) {
688 verts_num += key->segments + 1;
689 edges_num += key->segments;
690 }
691 }
692
693 if (verts_num == 0) {
694 return false;
695 }
696
697 Mesh *mesh = BKE_mesh_new_nomain(verts_num, edges_num, 0, 0);
698 MutableSpan<float3> positions = mesh->vert_positions_for_write();
699 MutableSpan<int2> edges = mesh->edges_for_write();
700
701 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
703 ".select_vert", bke::AttrDomain::Point);
704
705 int edge_index = 0;
706
707 /* copy coordinates */
708 int vert_index = 0;
709 cache = psys_eval->pathcache;
710 for (int a = 0; a < part_num; a++) {
711 ParticleCacheKey *key = cache[a];
712 int kmax = key->segments;
713 for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) {
714 positions[vert_index] = key->co;
715 if (k) {
716 edges[edge_index] = int2(cvert - 1, cvert);
717 edge_index++;
718 }
719 else {
720 /* cheap trick to select the roots */
721 select_vert.span[vert_index] = true;
722 }
723 }
724 }
725
726 cache = psys_eval->childcache;
727 for (int a = 0; a < child_num; a++) {
728 ParticleCacheKey *key = cache[a];
729 int kmax = key->segments;
730 for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) {
731 copy_v3_v3(positions[vert_index], key->co);
732 if (k) {
733 edges[edge_index] = int2(cvert - 1, cvert);
734 edge_index++;
735 }
736 else {
737 /* cheap trick to select the roots */
738 select_vert.span[vert_index] = true;
739 }
740 }
741 }
742
743 select_vert.finish();
744
745 Object *obn = BKE_object_add(bmain, scene, view_layer, OB_MESH, nullptr);
746 BKE_mesh_nomain_to_mesh(mesh, static_cast<Mesh *>(obn->data), obn);
747
749
750 return true;
751}
752
753static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src)
754{
755 if (!mesh_src.key) {
756 return;
757 }
758 int i;
759 LISTBASE_FOREACH_INDEX (const KeyBlock *, kb, &mesh_src.key->block, i) {
760 void *array;
761 if (mesh_src.verts_num != kb->totelem) {
763 "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)",
764 mesh_src.id.name + 2,
765 mesh_src.verts_num,
766 kb->name,
767 kb->totelem);
768 array = MEM_calloc_arrayN<float[3]>(mesh_src.verts_num, __func__);
769 }
770 else {
771 array = MEM_malloc_arrayN<float[3]>(size_t(mesh_src.verts_num), __func__);
772 memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src.verts_num));
773 }
774
776 &mesh_dest.vert_data, CD_SHAPEKEY, array, mesh_dest.verts_num, nullptr);
777 const int ci = CustomData_get_layer_index_n(&mesh_dest.vert_data, CD_SHAPEKEY, i);
778
779 mesh_dest.vert_data.layers[ci].uid = kb->uid;
780 }
781}
782
789 Scene *scene,
790 Object *ob_eval,
791 ModifierData *md_eval,
792 const bool use_virtual_modifiers,
793 const bool build_shapekey_layers,
795{
796 Mesh *mesh = ob_eval->runtime->data_orig ?
797 reinterpret_cast<Mesh *>(ob_eval->runtime->data_orig) :
798 reinterpret_cast<Mesh *>(ob_eval->data);
800 const ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_ORIGINAL};
801
802 if (!(md_eval->mode & eModifierMode_Realtime)) {
803 return nullptr;
804 }
805
806 if (mti->is_disabled && mti->is_disabled(scene, md_eval, false)) {
807 return nullptr;
808 }
809
810 if (build_shapekey_layers && mesh->key) {
811 if (KeyBlock *kb = static_cast<KeyBlock *>(
812 BLI_findlink(&mesh->key->block, ob_eval->shapenr - 1)))
813 {
814 BKE_keyblock_convert_to_mesh(kb, mesh->vert_positions_for_write());
815 }
816 }
817
818 Mesh *mesh_temp = reinterpret_cast<Mesh *>(
819 BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE));
820 MutableSpan<float3> deformedVerts = mesh_temp->vert_positions_for_write();
821
822 if (use_virtual_modifiers) {
823 VirtualModifierData virtual_modifier_data;
824 for (ModifierData *md_eval_virt =
825 BKE_modifiers_get_virtual_modifierlist(ob_eval, &virtual_modifier_data);
826 md_eval_virt && (md_eval_virt != ob_eval->modifiers.first);
827 md_eval_virt = md_eval_virt->next)
828 {
829 if (!BKE_modifier_is_enabled(scene, md_eval_virt, eModifierMode_Realtime)) {
830 continue;
831 }
832 /* All virtual modifiers are deform modifiers. */
833 const ModifierTypeInfo *mti_virt = BKE_modifier_get_info(ModifierType(md_eval_virt->type));
835 if (mti_virt->type != ModifierTypeType::OnlyDeform) {
836 continue;
837 }
838
839 mti_virt->deform_verts(md_eval_virt, &mectx, mesh_temp, deformedVerts);
840 }
841 }
842
843 Mesh *result = nullptr;
845 result = mesh_temp;
846 mti->deform_verts(md_eval, &mectx, result, deformedVerts);
847 result->tag_positions_changed();
848
849 if (build_shapekey_layers) {
851 }
852 }
853 else {
854 if (build_shapekey_layers) {
855 add_shapekey_layers(*mesh_temp, *mesh);
856 }
857
858 if (mti->modify_geometry_set) {
861 mti->modify_geometry_set(md_eval, &mectx, &geometry_set);
862 if (!geometry_set.has_mesh()) {
863 BKE_report(reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a mesh");
864 return nullptr;
865 }
866 result = geometry_set.get_component_for_write<bke::MeshComponent>().release();
867 }
868 else {
869 result = mti->modify_mesh(md_eval, &mectx, mesh_temp);
870 if (mesh_temp != result) {
871 BKE_id_free(nullptr, mesh_temp);
872 }
873 }
874 }
875
876 return result;
877}
878
879static bool modifier_apply_shape(Main *bmain,
881 Depsgraph *depsgraph,
882 Scene *scene,
883 Object *ob,
884 ModifierData *md_eval)
885{
887
888 if (mti->is_disabled && mti->is_disabled(scene, md_eval, false)) {
889 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
890 return false;
891 }
892
893 /* We could investigate using the #CD_ORIGINDEX layer
894 * to support other kinds of modifiers besides deforming modifiers.
895 * as this is done in many other places, see: #BKE_mesh_foreach_mapped_vert_coords_get.
896 *
897 * This isn't high priority in practice since most modifiers users
898 * want to apply as a shape are deforming modifiers.
899 *
900 * If a compelling use-case comes up where we want to support other kinds of modifiers
901 * we can look into supporting them. */
902
903 if (ob->type == OB_MESH) {
904 Mesh *mesh = static_cast<Mesh *>(ob->data);
905 Key *key = mesh->key;
906
908 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
909 return false;
910 }
911
915 md_eval,
916 true,
917 false,
918 reports);
919 if (!mesh_applied) {
920 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
921 return false;
922 }
923
924 if (key == nullptr) {
925 key = mesh->key = BKE_key_add(bmain, (ID *)mesh);
926 key->type = KEY_RELATIVE;
927 /* if that was the first key block added, then it was the basis.
928 * Initialize it with the mesh, and add another for the modifier */
929 KeyBlock *kb = BKE_keyblock_add(key, nullptr);
931 }
932
933 KeyBlock *kb = BKE_keyblock_add(key, md_eval->name);
934 BKE_mesh_nomain_to_meshkey(mesh_applied, mesh, kb);
935
936 BKE_id_free(nullptr, mesh_applied);
937 }
938 else {
939 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
940 return false;
941 }
942 return true;
943}
944
946 Object *ob,
947 GreasePencil &grease_pencil_orig,
948 ModifierData *md_eval)
949{
950 using namespace bke;
951 using namespace bke::greasepencil;
953 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
954 GreasePencil *grease_pencil_for_eval = ob_eval->runtime->data_orig ?
955 reinterpret_cast<GreasePencil *>(
956 ob_eval->runtime->data_orig) :
957 &grease_pencil_orig;
958 const int eval_frame = int(DEG_get_ctime(depsgraph));
959 GreasePencil *grease_pencil_temp = reinterpret_cast<GreasePencil *>(
960 BKE_id_copy_ex(nullptr, &grease_pencil_for_eval->id, nullptr, LIB_ID_COPY_LOCALIZE));
961 grease_pencil_temp->runtime->eval_frame = eval_frame;
962 GeometrySet eval_geometry_set = GeometrySet::from_grease_pencil(grease_pencil_temp,
963 GeometryOwnershipType::Owned);
964
966 mti->modify_geometry_set(md_eval, &mectx, &eval_geometry_set);
967 if (!eval_geometry_set.has_grease_pencil()) {
968
969 return false;
970 }
971 GreasePencil &grease_pencil_result =
972 *eval_geometry_set.get_component_for_write<GreasePencilComponent>().get_for_write();
973
975 eval_frame,
976 grease_pencil_orig.layers().index_range(),
977 grease_pencil_orig);
978
979 Main *bmain = DEG_get_bmain(depsgraph);
980 /* There might be layers with empty names after evaluation. Make sure to rename them. */
981 bke::greasepencil::ensure_non_empty_layer_names(*bmain, grease_pencil_result);
982 BKE_object_material_from_eval_data(bmain, ob, &grease_pencil_result.id);
983 return true;
984}
985
987 Scene *scene,
988 Object *ob,
989 GreasePencil &grease_pencil_orig,
990 ModifierData *md)
991{
992 using namespace bke;
993 using namespace bke::greasepencil;
994 Main *bmain = DEG_get_bmain(depsgraph);
995
997
998 WM_cursor_wait(true);
999
1000 Map<int, Vector<int>> layer_indices_to_apply_per_frame;
1001 {
1002 for (const int layer_i : grease_pencil_orig.layers().index_range()) {
1003 const Layer &layer = grease_pencil_orig.layer(layer_i);
1004 for (const auto &[key, value] : layer.frames().items()) {
1005 if (value.is_end()) {
1006 continue;
1007 }
1008 layer_indices_to_apply_per_frame.lookup_or_add(key, {}).append(layer_i);
1009 }
1010 }
1011 }
1012
1013 Array<int> sorted_frame_times(layer_indices_to_apply_per_frame.size());
1014 int i = 0;
1015 for (const int key : layer_indices_to_apply_per_frame.keys()) {
1016 sorted_frame_times[i++] = key;
1017 }
1018 std::sort(sorted_frame_times.begin(), sorted_frame_times.end());
1019
1020 const int prev_frame = int(DEG_get_ctime(depsgraph));
1021 bool changed = false;
1022 for (const int eval_frame : sorted_frame_times) {
1023 const Span<int> layer_indices = layer_indices_to_apply_per_frame.lookup(eval_frame).as_span();
1024 scene->r.cfra = eval_frame;
1026
1027 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
1028 GreasePencil *grease_pencil_for_eval = ob_eval->runtime->data_orig ?
1029 reinterpret_cast<GreasePencil *>(
1030 ob_eval->runtime->data_orig) :
1031 &grease_pencil_orig;
1032
1033 GreasePencil *grease_pencil_temp = reinterpret_cast<GreasePencil *>(
1034 BKE_id_copy_ex(nullptr, &grease_pencil_for_eval->id, nullptr, LIB_ID_COPY_LOCALIZE));
1035 grease_pencil_temp->runtime->eval_frame = eval_frame;
1036 GeometrySet eval_geometry_set = GeometrySet::from_grease_pencil(grease_pencil_temp,
1037 GeometryOwnershipType::Owned);
1038
1041 mti->modify_geometry_set(md_eval, &mectx, &eval_geometry_set);
1042 if (!eval_geometry_set.has_grease_pencil()) {
1043 continue;
1044 }
1045 GreasePencil &grease_pencil_result =
1046 *eval_geometry_set.get_component_for_write<GreasePencilComponent>().get_for_write();
1047
1048 IndexMaskMemory memory;
1049 const IndexMask orig_layers_to_apply = IndexMask::from_indices(layer_indices, memory);
1051 grease_pencil_result, eval_frame, orig_layers_to_apply, grease_pencil_orig);
1052
1053 BKE_object_material_from_eval_data(bmain, ob, &grease_pencil_result.id);
1054 changed = true;
1055 }
1056
1057 scene->r.cfra = prev_frame;
1059
1060 /* There might be layers with empty names after evaluation. Make sure to rename them. */
1061 bke::greasepencil::ensure_non_empty_layer_names(*bmain, grease_pencil_orig);
1062
1063 WM_cursor_wait(false);
1064 return changed;
1065}
1066
1068 Depsgraph *depsgraph,
1069 Scene *scene,
1070 Object *ob,
1071 ModifierData *md_eval,
1072 const bool do_all_keyframes)
1073{
1075
1076 if (mti->is_disabled && mti->is_disabled(scene, md_eval, false)) {
1077 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
1078 return false;
1079 }
1080
1081 if (ob->type == OB_MESH) {
1082 Mesh *mesh = static_cast<Mesh *>(ob->data);
1084
1085 if (mesh->key && mti->type != ModifierTypeType::NonGeometrical) {
1086 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to a mesh with shape keys");
1087 return false;
1088 }
1089
1090 /* Multires: ensure that recent sculpting is applied */
1091 if (md_eval->type == eModifierType_Multires) {
1093 }
1094
1095 if (mmd && mmd->totlvl &&
1097 {
1098 if (!multiresModifier_reshapeFromDeformModifier(depsgraph, ob, mmd, md_eval)) {
1099 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
1100 return false;
1101 }
1102 }
1103 else {
1104 Mesh *mesh_applied = create_applied_mesh_for_modifier(
1105 depsgraph,
1108 md_eval,
1109 /* It's important not to apply virtual modifiers (e.g. shape-keys) because they're kept,
1110 * causing them to be applied twice, see: #97758. */
1111 false,
1112 true,
1113 reports);
1114 if (!mesh_applied) {
1115 return false;
1116 }
1117
1118 Main *bmain = DEG_get_bmain(depsgraph);
1119 BKE_object_material_from_eval_data(bmain, ob, &mesh_applied->id);
1120 BKE_mesh_nomain_to_mesh(mesh_applied, mesh, ob);
1121
1122 /* Anonymous attributes shouldn't be available on the applied geometry. */
1123 mesh->attributes_for_write().remove_anonymous();
1124
1125 /* Remove strings referring to attributes if they no longer exist. */
1127
1128 if (md_eval->type == eModifierType_Multires) {
1130 }
1131 }
1132 }
1133 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
1134 Object *object_eval = DEG_get_evaluated(depsgraph, ob);
1135 Curve *curve = static_cast<Curve *>(ob->data);
1136 Curve *curve_eval = static_cast<Curve *>(object_eval->data);
1137 ModifierEvalContext mectx = {depsgraph, object_eval, MOD_APPLY_TO_ORIGINAL};
1138
1140 BKE_report(
1141 reports,
1142 RPT_ERROR,
1143 "Cannot apply constructive modifiers on curve. Convert curve to mesh in order to apply");
1144 return false;
1145 }
1146
1148 RPT_INFO,
1149 "Applied modifier only changed CV points, not tessellated/bevel vertices");
1150
1151 Array<float3> vertexCos = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb);
1152 mti->deform_verts(md_eval, &mectx, nullptr, vertexCos);
1153 BKE_curve_nurbs_vert_coords_apply(&curve->nurb, vertexCos, false);
1154
1156 }
1157 else if (ob->type == OB_LATTICE) {
1158 Object *object_eval = DEG_get_evaluated(depsgraph, ob);
1159 Lattice *lattice = static_cast<Lattice *>(ob->data);
1160 ModifierEvalContext mectx = {depsgraph, object_eval, MOD_APPLY_TO_ORIGINAL};
1161
1163 BKE_report(reports, RPT_ERROR, "Constructive modifiers cannot be applied");
1164 return false;
1165 }
1166
1167 Array<float3> positions = BKE_lattice_vert_coords_alloc(lattice);
1168 mti->deform_verts(md_eval, &mectx, nullptr, positions);
1169 BKE_lattice_vert_coords_apply(lattice, positions);
1170
1172 }
1173 else if (ob->type == OB_CURVES) {
1174 Curves &curves = *static_cast<Curves *>(ob->data);
1175 if (mti->modify_geometry_set == nullptr) {
1177 return false;
1178 }
1179
1182
1184 mti->modify_geometry_set(md_eval, &mectx, &geometry_set);
1185 if (!geometry_set.has_curves()) {
1186 BKE_report(reports, RPT_ERROR, "Evaluated geometry from modifier does not contain curves");
1187 return false;
1188 }
1189 Curves &curves_eval = *geometry_set.get_curves_for_write();
1190
1191 /* Anonymous attributes shouldn't be available on original geometry. */
1192 curves_eval.geometry.wrap().attributes_for_write().remove_anonymous();
1193
1194 curves.geometry.wrap() = std::move(curves_eval.geometry.wrap());
1195 Main *bmain = DEG_get_bmain(depsgraph);
1196 BKE_object_material_from_eval_data(bmain, ob, &curves_eval.id);
1197 }
1198 else if (ob->type == OB_POINTCLOUD) {
1199 PointCloud &points = *static_cast<PointCloud *>(ob->data);
1200 if (mti->modify_geometry_set == nullptr) {
1202 return false;
1203 }
1204
1207
1209 mti->modify_geometry_set(md_eval, &mectx, &geometry_set);
1210 if (!geometry_set.has_pointcloud()) {
1211 BKE_report(
1212 reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a point cloud");
1213 return false;
1214 }
1215 PointCloud *pointcloud_eval =
1216 geometry_set.get_component_for_write<bke::PointCloudComponent>().release();
1217
1218 /* Anonymous attributes shouldn't be available on original geometry. */
1219 pointcloud_eval->attributes_for_write().remove_anonymous();
1220
1221 Main *bmain = DEG_get_bmain(depsgraph);
1222 BKE_object_material_from_eval_data(bmain, ob, &pointcloud_eval->id);
1223 BKE_pointcloud_nomain_to_pointcloud(pointcloud_eval, &points);
1224 }
1225 else if (ob->type == OB_GREASE_PENCIL) {
1226 if (mti->modify_geometry_set == nullptr) {
1227 BKE_report(reports, RPT_ERROR, "Cannot apply this modifier to Grease Pencil geometry");
1228 return false;
1229 }
1230 GreasePencil &grease_pencil_orig = *static_cast<GreasePencil *>(ob->data);
1231 bool success = false;
1232 if (do_all_keyframes) {
1233 /* The function #apply_grease_pencil_for_modifier_all_keyframes will retrieve
1234 * the evaluated modifier for each keyframe. The original modifier is passed
1235 * to ensure the evaluated modifier is not used, as it will be invalid when
1236 * the scene graph is updated for the next keyframe. */
1237 ModifierData *md = BKE_modifier_get_original(ob, md_eval);
1239 depsgraph, scene, ob, grease_pencil_orig, md);
1240 }
1241 else {
1242 success = apply_grease_pencil_for_modifier(depsgraph, ob, grease_pencil_orig, md_eval);
1243 }
1244 if (!success) {
1246 RPT_ERROR,
1247 "Evaluated geometry from modifier does not contain Grease Pencil geometry");
1248 return false;
1249 }
1250 }
1251 else {
1252 /* TODO: implement for volumes. */
1253 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
1254 return false;
1255 }
1256
1257 /* lattice modifier can be applied to particle system too */
1258 if (ob->particlesystem.first) {
1260 if (psys->part->type != PART_HAIR) {
1261 continue;
1262 }
1263
1264 psys_apply_hair_lattice(depsgraph, scene, ob, psys);
1265 }
1266 }
1267
1268 return true;
1269}
1270
1273 Depsgraph *depsgraph,
1274 Scene *scene,
1275 Object *ob,
1276 ModifierData *md,
1277 int mode,
1278 bool keep_modifier,
1279 const bool do_all_keyframes)
1280{
1281 if (BKE_object_is_in_editmode(ob)) {
1282 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
1283 return false;
1284 }
1285 if (mode != MODIFIER_APPLY_SHAPE && ID_REAL_USERS(ob->data) > 1) {
1286 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
1287 return false;
1288 }
1289 if ((ob->mode & OB_MODE_SCULPT) && find_multires_modifier_before(scene, md) &&
1290 (BKE_modifier_is_same_topology(md) == false))
1291 {
1293 RPT_ERROR,
1294 "Constructive modifier cannot be applied to multi-res data in sculpt mode");
1295 return false;
1296 }
1297
1298 if (md != ob->modifiers.first) {
1299 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
1300 }
1301
1302 /* Get evaluated modifier, so object links pointer to evaluated data,
1303 * but still use original object it is applied to the original mesh. */
1304 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
1305 ModifierData *md_eval = (ob_eval) ? BKE_modifiers_findby_name(ob_eval, md->name) : md;
1306
1307 Depsgraph *apply_depsgraph = depsgraph;
1308 Depsgraph *local_depsgraph = nullptr;
1309
1310 /* If the object is hidden or the modifier is not enabled for the viewport is disabled a special
1311 * handling is required. This is because the viewport dependency graph optimizes out evaluation
1312 * of objects which are used by hidden objects and disabled modifiers.
1313 *
1314 * The idea is to create a dependency graph which does not perform those optimizations. */
1315 if ((ob_eval->base_flag & BASE_ENABLED_VIEWPORT) == 0 ||
1316 (md_eval->mode & eModifierMode_Realtime) == 0)
1317 {
1319
1320 local_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
1321 DEG_disable_visibility_optimization(local_depsgraph);
1322
1323 DEG_graph_build_from_ids(local_depsgraph, {&ob->id});
1324 DEG_evaluate_on_refresh(local_depsgraph);
1325
1326 apply_depsgraph = local_depsgraph;
1327
1328 /* The evaluated object and modifier are now from the different dependency graph. */
1329 ob_eval = DEG_get_evaluated(local_depsgraph, ob);
1330 md_eval = BKE_modifiers_findby_name(ob_eval, md->name);
1331
1332 /* Force mode on the evaluated modifier, enforcing the modifier evaluation in the apply()
1333 * functions. */
1334 md_eval->mode |= eModifierMode_Realtime;
1335 }
1336
1337 bool did_apply = false;
1338 if (mode == MODIFIER_APPLY_SHAPE) {
1339 did_apply = modifier_apply_shape(bmain, reports, apply_depsgraph, scene, ob, md_eval);
1340 }
1341 else {
1342 did_apply = modifier_apply_obdata(
1343 reports, apply_depsgraph, scene, ob, md_eval, do_all_keyframes);
1344 }
1345
1346 if (did_apply) {
1347 if (!keep_modifier) {
1350 }
1352 }
1353
1354 if (local_depsgraph != nullptr) {
1355 DEG_graph_free(local_depsgraph);
1356 }
1357
1358 return true;
1359}
1360
1362 ReportList * /*reports*/, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
1363{
1366 bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
1367 BLI_remlink(&ob->modifiers, nmd);
1368 BLI_insertlinkafter(&ob->modifiers, md, nmd);
1370 return true;
1371 }
1372
1374 BKE_modifier_copydata(md, nmd);
1375 BLI_insertlinkafter(&ob->modifiers, md, nmd);
1376 STRNCPY(nmd->name, md->name);
1380
1382
1383 return true;
1384}
1385
1387
1389{
1390 Vector<PointerRNA> objects;
1391 if (RNA_boolean_get(op.ptr, "use_selected_objects")) {
1393 }
1394 else {
1395 if (Object *object = context_active_object(&C)) {
1396 objects.append(RNA_id_pointer_create(&object->id));
1397 }
1398 }
1399 return objects;
1400}
1401
1403{
1405 ot->srna,
1406 "use_selected_objects",
1407 false,
1408 "Selected Objects",
1409 "Affect all selected objects instead of just the active object");
1411}
1412
1413/* ------------------------------------------------------------------- */
1416
1418{
1419 Main *bmain = CTX_data_main(C);
1420 Scene *scene = CTX_data_scene(C);
1421 int type = RNA_enum_get(op->ptr, "type");
1422
1423 bool changed = false;
1424 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
1425 Object *ob = static_cast<Object *>(ptr.data);
1426 if (!modifier_add(op->reports, bmain, scene, ob, nullptr, type)) {
1427 continue;
1428 }
1429 changed = true;
1431 }
1432 if (!changed) {
1433 return OPERATOR_CANCELLED;
1434 }
1435
1436 return OPERATOR_FINISHED;
1437}
1438
1440{
1441 if (event->modifier & KM_ALT || CTX_wm_view3d(C)) {
1442 RNA_boolean_set(op->ptr, "use_selected_objects", true);
1443 }
1444 if (!RNA_struct_property_is_set(op->ptr, "type")) {
1445 return WM_menu_invoke(C, op, event);
1446 }
1447 return modifier_add_exec(C, op);
1448}
1449
1451 PointerRNA * /*ptr*/,
1452 PropertyRNA * /*prop*/,
1453 bool *r_free)
1454{
1456
1457 if (!ob) {
1459 }
1460
1461 EnumPropertyItem *items = nullptr;
1462 int totitem = 0;
1463
1464 const EnumPropertyItem *group_item = nullptr;
1465 for (int a = 0; rna_enum_object_modifier_type_items[a].identifier; a++) {
1467
1468 if (md_item->identifier[0]) {
1470
1472 continue;
1473 }
1474
1475 if (!BKE_object_support_modifier_type_check(ob, md_item->value)) {
1476 continue;
1477 }
1478 }
1479 else {
1480 group_item = md_item;
1481 continue;
1482 }
1483
1484 if (group_item) {
1485 RNA_enum_item_add(&items, &totitem, group_item);
1486 group_item = nullptr;
1487 }
1488
1489 RNA_enum_item_add(&items, &totitem, md_item);
1490 }
1491
1492 RNA_enum_item_end(&items, &totitem);
1493 *r_free = true;
1494
1495 return items;
1496}
1497
1499{
1500 PropertyRNA *prop;
1501
1502 /* identifiers */
1503 ot->name = "Add Modifier";
1504 ot->description = "Add a procedural operation/effect to the active object";
1505 ot->idname = "OBJECT_OT_modifier_add";
1506
1507 /* API callbacks. */
1508 ot->invoke = modifier_add_invoke;
1509 ot->exec = modifier_add_exec;
1511
1512 /* flags */
1513 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1514
1515 /* properties */
1516 prop = RNA_def_enum(
1519 ot->prop = prop;
1521}
1522
1524
1525/* ------------------------------------------------------------------- */
1530
1532 StructRNA *rna_type,
1533 int obtype_flag,
1534 const bool is_editmode_allowed,
1535 const bool is_liboverride_allowed)
1536{
1537 Main *bmain = CTX_data_main(C);
1538 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
1539 Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : context_active_object(C);
1540 ModifierData *mod = static_cast<ModifierData *>(ptr.data); /* May be nullptr. */
1541
1542 if (mod == nullptr && ob != nullptr) {
1544 }
1545
1546 if (!ob || !BKE_id_is_editable(bmain, &ob->id)) {
1547 return false;
1548 }
1549 if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) {
1550 return false;
1551 }
1552 if (ptr.owner_id && !BKE_id_is_editable(bmain, ptr.owner_id)) {
1553 return false;
1554 }
1555
1556 if (!is_liboverride_allowed && BKE_modifier_is_nonlocal_in_liboverride(ob, mod)) {
1558 C, "Cannot edit modifiers coming from linked data in a library override");
1559 return false;
1560 }
1561
1562 if (!is_editmode_allowed && CTX_data_edit_object(C) != nullptr) {
1563 CTX_wm_operator_poll_msg_set(C, "This modifier operation is not allowed from Edit mode");
1564 return false;
1565 }
1566
1567 return true;
1568}
1569
1571{
1572 return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true, false);
1573}
1574
1575/* Used by operators performing actions allowed also on modifiers from the overridden linked object
1576 * (not only from added 'local' ones). */
1578{
1579 return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true, true);
1580}
1581
1583{
1585 ot->srna, "modifier", nullptr, MAX_NAME, "Modifier", "Name of the modifier to edit");
1587}
1588
1590{
1592 ot->srna, "report", false, "Report", "Create a notification after the operation");
1594}
1595
1597
1598/* ------------------------------------------------------------------- */
1603
1605{
1606 if (RNA_struct_property_is_set(op->ptr, "modifier")) {
1607 return true;
1608 }
1609
1610 PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1611 if (ctx_ptr.data != nullptr) {
1612 ModifierData *md = static_cast<ModifierData *>(ctx_ptr.data);
1613 RNA_string_set(op->ptr, "modifier", md->name);
1614 return true;
1615 }
1616
1617 return false;
1618}
1619
1626 wmOperator *op,
1627 const wmEvent *event,
1628 wmOperatorStatus *r_retval)
1629{
1630 if (RNA_struct_find_property(op->ptr, "use_selected_objects")) {
1631 if (event->modifier & KM_ALT) {
1632 RNA_boolean_set(op->ptr, "use_selected_objects", true);
1633 }
1634 }
1635
1636 if (RNA_struct_property_is_set(op->ptr, "modifier")) {
1637 return true;
1638 }
1639
1640 /* Note that the context pointer is *not* the active modifier, it is set in UI layouts. */
1641 PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1642 if (ctx_ptr.data != nullptr) {
1643 ModifierData *md = static_cast<ModifierData *>(ctx_ptr.data);
1644 RNA_string_set(op->ptr, "modifier", md->name);
1645 return true;
1646 }
1647
1649 if (panel_ptr == nullptr || RNA_pointer_is_null(panel_ptr)) {
1650 *r_retval = OPERATOR_CANCELLED;
1651 return false;
1652 }
1653
1654 if (!RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) {
1655 /* Work around multiple operators using the same shortcut. The operators for the other
1656 * stacks in the property editor use the same key, and will not run after these return
1657 * OPERATOR_CANCELLED. */
1659 return false;
1660 }
1661
1662 const ModifierData *md = static_cast<const ModifierData *>(panel_ptr->data);
1663 RNA_string_set(op->ptr, "modifier", md->name);
1664 return true;
1665}
1666
1668{
1669 char modifier_name[MAX_NAME];
1670 RNA_string_get(op->ptr, "modifier", modifier_name);
1671
1673
1674 if (md && type != 0 && md->type != type) {
1675 md = nullptr;
1676 }
1677
1678 return md;
1679}
1680
1682
1683/* ------------------------------------------------------------------- */
1686
1688{
1689 Main *bmain = CTX_data_main(C);
1690 Scene *scene = CTX_data_scene(C);
1691 ViewLayer *view_layer = CTX_data_view_layer(C);
1692
1693 char name[MAX_NAME];
1694 RNA_string_get(op->ptr, "modifier", name);
1695
1696 bool changed = false;
1697 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
1698 Object *ob = static_cast<Object *>(ptr.data);
1700 if (md == nullptr) {
1701 continue;
1702 }
1703
1704 int mode_orig = ob->mode;
1705 if (!modifier_remove(op->reports, bmain, scene, ob, md)) {
1706 continue;
1707 }
1708
1709 changed = true;
1710
1712
1713 /* if cloth/softbody was removed, particle mode could be cleared */
1714 if (mode_orig & OB_MODE_PARTICLE_EDIT) {
1715 if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
1716 BKE_view_layer_synced_ensure(scene, view_layer);
1717 if (ob == BKE_view_layer_active_object_get(view_layer)) {
1719 }
1720 }
1721 }
1722 }
1723
1724 if (!changed) {
1725 return OPERATOR_CANCELLED;
1726 }
1727
1728 if (RNA_boolean_get(op->ptr, "report")) {
1729 BKE_reportf(op->reports, RPT_INFO, "Removed modifier: %s", name);
1730 }
1731
1732 return OPERATOR_FINISHED;
1733}
1734
1736{
1737 wmOperatorStatus retval;
1738 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1739 return modifier_remove_exec(C, op);
1740 }
1741 return retval;
1742}
1743
1745{
1746 ot->name = "Remove Modifier";
1747 ot->description = "Remove a modifier from the active object";
1748 ot->idname = "OBJECT_OT_modifier_remove";
1749
1750 ot->invoke = modifier_remove_invoke;
1751 ot->exec = modifier_remove_exec;
1752 ot->poll = edit_modifier_poll;
1753
1754 /* flags */
1759}
1760
1762{
1763 Main *bmain = CTX_data_main(C);
1764 Scene *scene = CTX_data_scene(C);
1765
1766 CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) {
1767 modifiers_clear(bmain, scene, object);
1769 }
1771
1772 return OPERATOR_FINISHED;
1773}
1774
1776{
1778 return false;
1779 }
1780 const Object *object = context_active_object(C);
1781 if (!BKE_object_supports_modifiers(object)) {
1782 return false;
1783 }
1784 return true;
1785}
1786
1788{
1789 ot->name = "Clear Object Modifiers";
1790 ot->description = "Clear all modifiers from the selected objects";
1791 ot->idname = "OBJECT_OT_modifiers_clear";
1792
1793 ot->exec = modifiers_clear_exec;
1794 ot->poll = modifiers_clear_poll;
1795
1796 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1797}
1798
1800
1801/* ------------------------------------------------------------------- */
1804
1806{
1809
1810 if (!md || !modifier_move_up(op->reports, RPT_WARNING, ob, md)) {
1811 return OPERATOR_CANCELLED;
1812 }
1813
1816
1817 return OPERATOR_FINISHED;
1818}
1819
1821{
1822 wmOperatorStatus retval;
1823 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1824 return modifier_move_up_exec(C, op);
1825 }
1826 return retval;
1827}
1828
1830{
1831 ot->name = "Move Up Modifier";
1832 ot->description = "Move modifier up in the stack";
1833 ot->idname = "OBJECT_OT_modifier_move_up";
1834
1835 ot->invoke = modifier_move_up_invoke;
1836 ot->exec = modifier_move_up_exec;
1837 ot->poll = edit_modifier_poll;
1838
1839 /* flags */
1842}
1843
1845
1846/* ------------------------------------------------------------------- */
1849
1851{
1854
1855 if (!md || !modifier_move_down(op->reports, RPT_WARNING, ob, md)) {
1856 return OPERATOR_CANCELLED;
1857 }
1858
1861
1862 return OPERATOR_FINISHED;
1863}
1864
1866 wmOperator *op,
1867 const wmEvent *event)
1868{
1869 wmOperatorStatus retval;
1870 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1871 return modifier_move_down_exec(C, op);
1872 }
1873 return retval;
1874}
1875
1877{
1878 ot->name = "Move Down Modifier";
1879 ot->description = "Move modifier down in the stack";
1880 ot->idname = "OBJECT_OT_modifier_move_down";
1881
1882 ot->invoke = modifier_move_down_invoke;
1884 ot->poll = edit_modifier_poll;
1885
1886 /* flags */
1889}
1890
1892
1893/* ------------------------------------------------------------------- */
1896
1898{
1899 char name[MAX_NAME];
1900 RNA_string_get(op->ptr, "modifier", name);
1901
1902 const int index = RNA_int_get(op->ptr, "index");
1903
1904 bool changed = false;
1905 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
1906 Object *ob = static_cast<Object *>(ptr.data);
1908 if (!md) {
1909 continue;
1910 }
1911
1912 if (!modifier_move_to_index(op->reports, RPT_WARNING, ob, md, index, true)) {
1913 continue;
1914 }
1915 changed = true;
1916 }
1917
1918 if (!changed) {
1919 return OPERATOR_CANCELLED;
1920 }
1921
1922 return OPERATOR_FINISHED;
1923}
1924
1926 wmOperator *op,
1927 const wmEvent *event)
1928{
1929 wmOperatorStatus retval;
1930 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1931 return modifier_move_to_index_exec(C, op);
1932 }
1933 return retval;
1934}
1935
1937{
1938 ot->name = "Move Active Modifier to Index";
1939 ot->description =
1940 "Change the modifier's index in the stack so it evaluates after the set number of others";
1941 ot->idname = "OBJECT_OT_modifier_move_to_index";
1942
1945 ot->poll = edit_modifier_poll;
1946
1947 /* flags */
1951 ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the modifier to", 0, INT_MAX);
1953}
1954
1956
1957/* ------------------------------------------------------------------- */
1960
1962{
1963 if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false, false)) {
1964 return false;
1965 }
1966
1967 Scene *scene = CTX_data_scene(C);
1968 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1969 Object *ob = (ptr.owner_id != nullptr) ? (Object *)ptr.owner_id : context_active_object(C);
1970 ModifierData *md = static_cast<ModifierData *>(ptr.data); /* May be nullptr. */
1971
1972 if (ID_IS_OVERRIDE_LIBRARY(ob) || ((ob->data != nullptr) && ID_IS_OVERRIDE_LIBRARY(ob->data))) {
1973 CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
1974 return false;
1975 }
1976 if (md != nullptr) {
1977 if ((ob->mode & OB_MODE_SCULPT) && find_multires_modifier_before(scene, md) &&
1978 (BKE_modifier_is_same_topology(md) == false))
1979 {
1981 C, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
1982 return false;
1983 }
1984 }
1985 return true;
1986}
1987
1989 wmOperator *op,
1990 int apply_as,
1991 bool keep_modifier)
1992{
1993 Main *bmain = CTX_data_main(C);
1995 Scene *scene = CTX_data_scene(C);
1997
1998 char name[MAX_NAME];
1999 RNA_string_get(op->ptr, "modifier", name);
2000
2001 const bool do_report = RNA_boolean_get(op->ptr, "report");
2002 const int reports_len = do_report ? BLI_listbase_count(&op->reports->list) : 0;
2003
2004 const bool do_single_user = (apply_as == MODIFIER_APPLY_DATA) ?
2005 RNA_boolean_get(op->ptr, "single_user") :
2006 false;
2007 const bool do_merge_customdata = (apply_as == MODIFIER_APPLY_DATA) ?
2008 RNA_boolean_get(op->ptr, "merge_customdata") :
2009 false;
2010 const bool do_all_keyframes = (apply_as == MODIFIER_APPLY_DATA) ?
2011 RNA_boolean_get(op->ptr, "all_keyframes") :
2012 false;
2013
2014 bool changed = false;
2015 for (const PointerRNA &ptr : objects) {
2016 Object *ob = static_cast<Object *>(ptr.data);
2018 if (md == nullptr) {
2019 continue;
2020 }
2021
2023
2024 if (do_single_user && ID_REAL_USERS(ob->data) > 1) {
2025 single_obdata_user_make(bmain, scene, ob);
2029 }
2030
2031 if (!modifier_apply(bmain,
2032 op->reports,
2033 depsgraph,
2034 scene,
2035 ob,
2036 md,
2037 apply_as,
2038 keep_modifier,
2039 do_all_keyframes))
2040 {
2041 continue;
2042 }
2043 changed = true;
2044
2045 if (ob->type == OB_MESH && do_merge_customdata &&
2047 {
2049 }
2050
2054 }
2055
2056 if (!changed) {
2057 return OPERATOR_CANCELLED;
2058 }
2059
2060 if (do_report) {
2061 /* Only add this report if the operator didn't cause another one. The purpose here is
2062 * to alert that something happened, and the previous report will do that anyway. */
2063 if (BLI_listbase_count(&op->reports->list) == reports_len) {
2064 BKE_reportf(op->reports, RPT_INFO, "Applied modifier: %s", name);
2065 }
2066 }
2067
2068 return OPERATOR_FINISHED;
2069}
2070
2075
2077{
2078 wmOperatorStatus retval;
2079 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2080 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
2081 Object *ob = (ptr.owner_id != nullptr) ? (Object *)ptr.owner_id : context_active_object(C);
2082
2083 if ((ob->data != nullptr) && ID_REAL_USERS(ob->data) > 1) {
2084 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "single_user");
2085 if (!RNA_property_is_set(op->ptr, prop)) {
2086 RNA_property_boolean_set(op->ptr, prop, true);
2087 }
2088 if (RNA_property_boolean_get(op->ptr, prop)) {
2090 C,
2091 op,
2092 IFACE_("Apply Modifier"),
2093 IFACE_("Make data single-user, apply modifier, and remove it from the list."),
2094 IFACE_("Apply"),
2096 false);
2097 }
2098 }
2099 return modifier_apply_exec(C, op);
2100 }
2101 return retval;
2102}
2103
2105{
2106 PropertyRNA *prop;
2107
2108 ot->name = "Apply Modifier";
2109 ot->description = "Apply modifier and remove from the stack";
2110 ot->idname = "OBJECT_OT_modifier_apply";
2111
2112 ot->invoke = modifier_apply_invoke;
2113 ot->exec = modifier_apply_exec;
2114 ot->poll = modifier_apply_poll;
2115
2116 /* flags */
2118
2121
2122 RNA_def_boolean(ot->srna,
2123 "merge_customdata",
2124 true,
2125 "Merge UVs",
2126 "For mesh objects, merge UV coordinates that share a vertex to account for "
2127 "imprecision in some modifiers");
2128 prop = RNA_def_boolean(ot->srna,
2129 "single_user",
2130 false,
2131 "Make Data Single User",
2132 "Make the object's data single user if needed");
2134 prop = RNA_def_boolean(ot->srna,
2135 "all_keyframes",
2136 false,
2137 "Apply to all keyframes",
2138 "For Grease Pencil objects, apply the modifier to all the keyframes");
2141}
2142
2144
2145/* ------------------------------------------------------------------- */
2148
2150{
2151 return modifier_apply_poll(C);
2152}
2153
2155{
2156 bool keep = RNA_boolean_get(op->ptr, "keep_modifier");
2157
2159}
2160
2162 wmOperator *op,
2163 const wmEvent *event)
2164{
2165 wmOperatorStatus retval;
2166 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2168 }
2169 return retval;
2170}
2171
2173 wmOperatorType * /*ot*/,
2174 PointerRNA *ptr)
2175{
2176 bool keep = RNA_boolean_get(ptr, "keep_modifier");
2177 if (keep) {
2178 return TIP_("Apply modifier as a new shapekey and keep it in the stack");
2179 }
2180
2181 return "";
2182}
2183
2185{
2186 ot->name = "Apply Modifier as Shape Key";
2187 ot->description = "Apply modifier as a new shape key and remove from the stack";
2188 ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
2189
2194
2195 /* flags */
2197
2199 ot->srna, "keep_modifier", false, "Keep Modifier", "Do not remove the modifier from stack");
2203}
2204
2206
2207/* ------------------------------------------------------------------- */
2210
2212{
2213 Main *bmain = CTX_data_main(C);
2215 Scene *scene = CTX_data_scene(C);
2216 ViewLayer *view_layer = CTX_data_view_layer(C);
2219
2220 if (!md || !convert_psys_to_mesh(op->reports, bmain, depsgraph, scene, view_layer, ob, md)) {
2221 return OPERATOR_CANCELLED;
2222 }
2223
2226
2227 return OPERATOR_FINISHED;
2228}
2229
2231 wmOperator *op,
2232 const wmEvent * /*event*/)
2233{
2235 return modifier_convert_exec(C, op);
2236 }
2237 return OPERATOR_CANCELLED;
2238}
2239
2241{
2242 ot->name = "Convert Particles to Mesh";
2243 ot->description = "Convert particles to a mesh object";
2244 ot->idname = "OBJECT_OT_modifier_convert";
2245
2246 ot->invoke = modifier_convert_invoke;
2247 ot->exec = modifier_convert_exec;
2248 ot->poll = edit_modifier_poll;
2249
2250 /* flags */
2253}
2254
2256
2257/* ------------------------------------------------------------------- */
2260
2262{
2263 Main *bmain = CTX_data_main(C);
2264 Scene *scene = CTX_data_scene(C);
2265 char name[MAX_NAME];
2266 RNA_string_get(op->ptr, "modifier", name);
2267
2268 bool changed = false;
2269 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
2270 Object *ob = static_cast<Object *>(ptr.data);
2272 if (!md) {
2273 continue;
2274 }
2275
2276 if (!modifier_copy(op->reports, bmain, scene, ob, md)) {
2277 continue;
2278 }
2279 changed = true;
2283 }
2284
2285 if (!changed) {
2286 return OPERATOR_CANCELLED;
2287 }
2288
2289 return OPERATOR_FINISHED;
2290}
2291
2293{
2294 wmOperatorStatus retval;
2295 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2296 return modifier_copy_exec(C, op);
2297 }
2298 return retval;
2299}
2300
2302{
2303 ot->name = "Copy Modifier";
2304 ot->description = "Duplicate modifier at the same position in the stack";
2305 ot->idname = "OBJECT_OT_modifier_copy";
2306
2307 ot->invoke = modifier_copy_invoke;
2308 ot->exec = modifier_copy_exec;
2310
2311 /* flags */
2315}
2316
2318
2319/* ------------------------------------------------------------------- */
2322
2324{
2327
2328 /* If there is no modifier set for this operator, clear the active modifier field. */
2330
2332
2333 return OPERATOR_FINISHED;
2334}
2335
2337 wmOperator *op,
2338 const wmEvent *event)
2339{
2340 wmOperatorStatus retval;
2341 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2342 return modifier_set_active_exec(C, op);
2343 }
2344 return retval;
2345}
2346
2348{
2349 ot->name = "Set Active Modifier";
2350 ot->description = "Activate the modifier to use as the context";
2351 ot->idname = "OBJECT_OT_modifier_set_active";
2352
2356
2359}
2360
2362
2363/* ------------------------------------------------------------------- */
2366
2368{
2369 Main *bmain = CTX_data_main(C);
2370 const Scene *scene = CTX_data_scene(C);
2371 Object *obact = context_active_object(C);
2372 ModifierData *md = edit_modifier_property_get(op, obact, 0);
2373 if (!md) {
2374 return OPERATOR_CANCELLED;
2375 }
2376
2377 int num_copied = 0;
2378
2379 Vector<PointerRNA> selected_objects;
2380 CTX_data_selected_objects(C, &selected_objects);
2381 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
2382 if (ob == obact) {
2383 continue;
2384 }
2385 if (!ID_IS_EDITABLE(ob)) {
2386 continue;
2387 }
2388 if (modifier_copy_to_object(bmain, scene, obact, md, ob, op->reports)) {
2390 num_copied++;
2391 }
2392 }
2394
2395 if (num_copied > 0) {
2397 }
2398 else {
2399 BKE_reportf(op->reports, RPT_ERROR, "Modifier '%s' was not copied to any objects", md->name);
2400 return OPERATOR_CANCELLED;
2401 }
2402
2403 return OPERATOR_FINISHED;
2404}
2405
2407 wmOperator *op,
2408 const wmEvent *event)
2409{
2410 wmOperatorStatus retval;
2411 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2413 }
2414 return retval;
2415}
2416
2418{
2419 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
2420 Object *obact = (ptr.owner_id) ? (Object *)ptr.owner_id : context_active_object(C);
2421 ModifierData *md = static_cast<ModifierData *>(ptr.data);
2422
2423 /* This just mirrors the check in #BKE_object_copy_modifier,
2424 * but there is no reasoning for it there. */
2426 CTX_wm_operator_poll_msg_set(C, R"(Not supported for "Collision" or "Hook" modifiers)");
2427 return false;
2428 }
2429
2430 if (!obact) {
2431 CTX_wm_operator_poll_msg_set(C, "No selected object is active");
2432 return false;
2433 }
2434
2435 if (!BKE_object_supports_modifiers(obact)) {
2436 CTX_wm_operator_poll_msg_set(C, "Object type of source object is not supported");
2437 return false;
2438 }
2439
2440 /* This could have a performance impact in the worst case, where there are many objects selected
2441 * and none of them pass either of the checks. But that should be uncommon, and this operator is
2442 * only exposed in a drop-down menu anyway. */
2443 bool found_supported_objects = false;
2444 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
2445 if (ob == obact) {
2446 continue;
2447 }
2448
2449 if (!md) {
2450 /* Skip type check if modifier could not be found ("modifier" context variable not set). */
2452 found_supported_objects = true;
2453 break;
2454 }
2455 }
2456 else if (BKE_object_support_modifier_type_check(ob, md->type)) {
2457 found_supported_objects = true;
2458 break;
2459 }
2460 }
2462
2463 if (!found_supported_objects) {
2464 CTX_wm_operator_poll_msg_set(C, "No supported objects were selected");
2465 return false;
2466 }
2467 return true;
2468}
2469
2471{
2472 ot->name = "Copy Modifier to Selected";
2473 ot->description = "Copy the modifier from the active object to all selected objects";
2474 ot->idname = "OBJECT_OT_modifier_copy_to_selected";
2475
2479
2480 /* flags */
2483}
2484
2486{
2487 Main *bmain = CTX_data_main(C);
2488 const Scene *scene = CTX_data_scene(C);
2489 Object *active_object = context_active_object(C);
2490
2491 Vector<PointerRNA> selected_objects;
2492 CTX_data_selected_objects(C, &selected_objects);
2493 CTX_DATA_BEGIN (C, Object *, object, selected_objects) {
2494 if (object == active_object) {
2495 continue;
2496 }
2497 LISTBASE_FOREACH (const ModifierData *, md, &active_object->modifiers) {
2498 if (modifier_copy_to_object(bmain, scene, active_object, md, object, op->reports)) {
2500 }
2501 }
2502 }
2504
2505 return OPERATOR_FINISHED;
2506
2508
2510
2511 return OPERATOR_FINISHED;
2512}
2513
2515{
2517 return false;
2518 }
2519 const Object *active_object = context_active_object(C);
2520 if (!BKE_object_supports_modifiers(active_object)) {
2521 return false;
2522 }
2523 if (BLI_listbase_is_empty(&active_object->modifiers)) {
2524 CTX_wm_operator_poll_msg_set(C, "Active object has no modifiers");
2525 return false;
2526 }
2527 return true;
2528}
2529
2531{
2532 ot->name = "Copy Modifiers to Selected Objects";
2533 ot->idname = "OBJECT_OT_modifiers_copy_to_selected";
2534 ot->description = "Copy modifiers to other selected objects";
2535
2538
2539 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2540}
2541
2543
2544/* ------------------------------------------------------------------- */
2547
2549{
2550 Mesh *mesh = static_cast<Mesh *>(ob->data);
2551 if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
2552 BM_data_layer_free(em->bm, &em->bm->vdata, CD_MVERT_SKIN);
2553 }
2554 else {
2556 }
2557}
2558
2559static bool skin_poll(bContext *C)
2560{
2561 return edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), false, false);
2562}
2563
2565{
2567 return (ob != nullptr &&
2568 edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true, false) &&
2570}
2571
2572static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
2573{
2574 BMEdge *bm_edge;
2575 BMIter bm_iter;
2576
2577 BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
2578 BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
2579
2580 if (BLI_gset_add(visited, v2)) {
2581 MVertSkin *vs = static_cast<MVertSkin *>(BM_ELEM_CD_GET_VOID_P(v2, cd_vert_skin_offset));
2582
2583 /* clear vertex root flag and add to visited set */
2584 vs->flag &= ~MVERT_SKIN_ROOT;
2585
2586 skin_root_clear(v2, visited, cd_vert_skin_offset);
2587 }
2588 }
2589}
2590
2592{
2595 BMesh *bm = em->bm;
2596
2597 GSet *visited = BLI_gset_ptr_new(__func__);
2598
2599 BKE_mesh_ensure_skin_customdata(static_cast<Mesh *>(ob->data));
2600
2601 const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
2602
2603 BMVert *bm_vert;
2604 BMIter bm_iter;
2605 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2606 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT) && BLI_gset_add(visited, bm_vert)) {
2607 MVertSkin *vs = static_cast<MVertSkin *>(
2608 BM_ELEM_CD_GET_VOID_P(bm_vert, cd_vert_skin_offset));
2609
2610 /* mark vertex as root and add to visited set */
2611 vs->flag |= MVERT_SKIN_ROOT;
2612
2613 /* clear root flag from all connected vertices (recursively) */
2614 skin_root_clear(bm_vert, visited, cd_vert_skin_offset);
2615 }
2616 }
2617
2618 BLI_gset_free(visited, nullptr);
2619
2622
2623 return OPERATOR_FINISHED;
2624}
2625
2627{
2628 ot->name = "Skin Root Mark";
2629 ot->description = "Mark selected vertices as roots";
2630 ot->idname = "OBJECT_OT_skin_root_mark";
2631
2632 ot->poll = skin_edit_poll;
2633 ot->exec = skin_root_mark_exec;
2634
2635 /* flags */
2636 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2637}
2638
2643
2645{
2648 BMesh *bm = em->bm;
2649 SkinLooseAction action = static_cast<SkinLooseAction>(RNA_enum_get(op->ptr, "action"));
2650
2651 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
2652 return OPERATOR_CANCELLED;
2653 }
2654
2655 BMVert *bm_vert;
2656 BMIter bm_iter;
2657 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2658 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
2659 MVertSkin *vs = static_cast<MVertSkin *>(
2660 CustomData_bmesh_get(&bm->vdata, bm_vert->head.data, CD_MVERT_SKIN));
2661
2662 switch (action) {
2663 case SKIN_LOOSE_MARK:
2664 vs->flag |= MVERT_SKIN_LOOSE;
2665 break;
2666 case SKIN_LOOSE_CLEAR:
2667 vs->flag &= ~MVERT_SKIN_LOOSE;
2668 break;
2669 }
2670 }
2671 }
2672
2675
2676 return OPERATOR_FINISHED;
2677}
2678
2680{
2681 static const EnumPropertyItem action_items[] = {
2682 {SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"},
2683 {SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"},
2684 {0, nullptr, 0, nullptr, nullptr},
2685 };
2686
2687 ot->name = "Skin Mark/Clear Loose";
2688 ot->description = "Mark/clear selected vertices as loose";
2689 ot->idname = "OBJECT_OT_skin_loose_mark_clear";
2690
2691 ot->poll = skin_edit_poll;
2693
2694 /* flags */
2695 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2696
2697 RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", nullptr);
2698}
2699
2701{
2704 BMesh *bm = em->bm;
2705
2706 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
2707 return OPERATOR_CANCELLED;
2708 }
2709
2710 BMVert *bm_vert;
2711 BMIter bm_iter;
2712 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2713 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
2714 MVertSkin *vs = static_cast<MVertSkin *>(
2715 CustomData_bmesh_get(&bm->vdata, bm_vert->head.data, CD_MVERT_SKIN));
2716 float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
2717
2718 vs->radius[0] = vs->radius[1] = avg;
2719 }
2720 }
2721
2724
2725 return OPERATOR_FINISHED;
2726}
2727
2729{
2730 ot->name = "Skin Radii Equalize";
2731 ot->description = "Make skin radii of selected vertices equal on each axis";
2732 ot->idname = "OBJECT_OT_skin_radii_equalize";
2733
2734 ot->poll = skin_edit_poll;
2736
2737 /* flags */
2738 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2739}
2740
2742 const Span<float3> positions,
2743 const int2 *edges,
2744 bArmature *arm,
2745 BLI_bitmap *edges_visited,
2746 const GroupedSpan<int> emap,
2747 EditBone *parent_bone,
2748 int parent_v)
2749{
2750 for (int i = 0; i < emap[parent_v].size(); i++) {
2751 int endx = emap[parent_v][i];
2752 const int2 &edge = edges[endx];
2753
2754 /* ignore edge if already visited */
2755 if (BLI_BITMAP_TEST(edges_visited, endx)) {
2756 continue;
2757 }
2758 BLI_BITMAP_ENABLE(edges_visited, endx);
2759
2760 int v = bke::mesh::edge_other_vert(edge, parent_v);
2761
2762 EditBone *bone = ED_armature_ebone_add(arm, "Bone");
2763
2764 bone->parent = parent_bone;
2765 if (parent_bone != nullptr) {
2766 bone->flag |= BONE_CONNECTED;
2767 }
2768
2769 copy_v3_v3(bone->head, positions[parent_v]);
2770 copy_v3_v3(bone->tail, positions[v]);
2771 bone->rad_head = bone->rad_tail = 0.25;
2772 SNPRINTF(bone->name, "Bone.%.2d", endx);
2773
2774 /* add bDeformGroup */
2775 bDeformGroup *dg = BKE_object_defgroup_add_name(skin_ob, bone->name);
2776 if (dg != nullptr) {
2777 blender::ed::object::vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
2779 }
2780
2781 skin_armature_bone_create(skin_ob, positions, edges, arm, edges_visited, emap, bone, v);
2782 }
2783}
2784
2785static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob)
2786{
2787 Mesh *mesh = static_cast<Mesh *>(skin_ob->data);
2788 const Span<float3> me_positions = mesh->vert_positions();
2789 const Span<int2> me_edges = mesh->edges();
2790
2792 Object *ob_eval = DEG_get_evaluated(depsgraph, skin_ob);
2793
2794 const Mesh *me_eval_deform = blender::bke::mesh_get_eval_deform(
2795 depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
2796 const Span<float3> positions_eval = me_eval_deform->vert_positions();
2797
2798 /* add vertex weights to original mesh */
2799 CustomData_add_layer(&mesh->vert_data, CD_MDEFORMVERT, CD_SET_DEFAULT, mesh->verts_num);
2800
2803 Object *arm_ob = BKE_object_add(bmain, scene, view_layer, OB_ARMATURE, nullptr);
2804 BKE_object_transform_copy(arm_ob, skin_ob);
2805 bArmature *arm = static_cast<bArmature *>(arm_ob->data);
2807 arm_ob->dtx |= OB_DRAW_IN_FRONT;
2809 arm->edbo = MEM_callocN<ListBase>("edbo armature");
2810
2811 MVertSkin *mvert_skin = static_cast<MVertSkin *>(
2812 CustomData_get_layer_for_write(&mesh->vert_data, CD_MVERT_SKIN, mesh->verts_num));
2813
2814 Array<int> vert_to_edge_offsets;
2815 Array<int> vert_to_edge_indices;
2817 me_edges, mesh->verts_num, vert_to_edge_offsets, vert_to_edge_indices);
2818
2819 BLI_bitmap *edges_visited = BLI_BITMAP_NEW(mesh->edges_num, "edge_visited");
2820
2821 /* NOTE: we use EditBones here, easier to set them up and use
2822 * edit-armature functions to convert back to regular bones */
2823 for (int v = 0; v < mesh->verts_num; v++) {
2824 if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
2825 EditBone *bone = nullptr;
2826
2827 /* Unless the skin root has just one adjacent edge, create
2828 * a fake root bone (have it going off in the Y direction
2829 * (arbitrary) */
2830 if (emap[v].size() > 1) {
2831 bone = ED_armature_ebone_add(arm, "Bone");
2832
2833 copy_v3_v3(bone->head, me_positions[v]);
2834 copy_v3_v3(bone->tail, me_positions[v]);
2835
2836 bone->head[1] = 1.0f;
2837 bone->rad_head = bone->rad_tail = 0.25;
2838 }
2839
2840 if (emap[v].size() >= 1) {
2842 skin_ob, positions_eval, me_edges.data(), arm, edges_visited, emap, bone, v);
2843 }
2844 }
2845 }
2846
2847 MEM_freeN(edges_visited);
2848
2849 ED_armature_from_edit(bmain, arm);
2851
2852 return arm_ob;
2853}
2854
2856{
2857 Main *bmain = CTX_data_main(C);
2860 Mesh *mesh = static_cast<Mesh *>(ob->data);
2861 ModifierData *skin_md;
2862
2863 if (!CustomData_has_layer(&mesh->vert_data, CD_MVERT_SKIN)) {
2864 BKE_reportf(op->reports, RPT_WARNING, "Mesh '%s' has no skin vertex data", mesh->id.name + 2);
2865 return OPERATOR_CANCELLED;
2866 }
2867
2868 /* create new armature */
2869 Object *arm_ob = modifier_skin_armature_create(depsgraph, bmain, ob);
2870
2871 /* add a modifier to connect the new armature to the mesh */
2873 if (arm_md) {
2875 BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md);
2877
2878 arm_md->object = arm_ob;
2882 }
2883
2885
2886 return OPERATOR_FINISHED;
2887}
2888
2890 wmOperator *op,
2891 const wmEvent * /*event*/)
2892{
2894 return skin_armature_create_exec(C, op);
2895 }
2896 return OPERATOR_CANCELLED;
2897}
2898
2900{
2901 ot->name = "Skin Armature Create";
2902 ot->description = "Create an armature that parallels the skin layout";
2903 ot->idname = "OBJECT_OT_skin_armature_create";
2904
2905 ot->poll = skin_poll;
2908
2909 /* flags */
2912}
2913
2915
2916/* ------------------------------------------------------------------- */
2919
2921{
2922 return edit_modifier_poll_generic(C, &RNA_CorrectiveSmoothModifier, 0, true, false);
2923}
2924
2926{
2928 Scene *scene = CTX_data_scene(C);
2932
2933 if (!csmd) {
2934 return OPERATOR_CANCELLED;
2935 }
2936
2938 BKE_report(op->reports, RPT_ERROR, "Modifier is disabled");
2939 return OPERATOR_CANCELLED;
2940 }
2941
2942 const bool is_bind = (csmd->bind_coords != nullptr);
2943
2946
2947 if (is_bind) {
2948 /* toggle off */
2949 csmd->bind_coords_num = 0;
2950 }
2951 else {
2952 /* Signal to modifier to recalculate. */
2955 csmd_eval->bind_coords_num = uint(-1);
2956
2957 /* Force modifier to run, it will call binding routine
2958 * (this has to happen outside of depsgraph evaluation). */
2960 }
2961
2964
2965 return OPERATOR_FINISHED;
2966}
2967
2969 wmOperator *op,
2970 const wmEvent * /*event*/)
2971{
2973 return correctivesmooth_bind_exec(C, op);
2974 }
2975 return OPERATOR_CANCELLED;
2976}
2977
2979{
2980 /* identifiers */
2981 ot->name = "Corrective Smooth Bind";
2982 ot->description = "Bind base pose in Corrective Smooth modifier";
2983 ot->idname = "OBJECT_OT_correctivesmooth_bind";
2984
2985 /* API callbacks. */
2986 ot->poll = correctivesmooth_poll;
2989
2990 /* flags */
2993}
2994
2996
2997/* ------------------------------------------------------------------- */
3000
3002{
3003 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0, true, false);
3004}
3005
3007{
3011 op, ob, eModifierType_MeshDeform);
3012
3013 if (mmd == nullptr) {
3014 return OPERATOR_CANCELLED;
3015 }
3016
3017 if (mmd->bindcagecos != nullptr) {
3019 MEM_SAFE_FREE(mmd->dyngrid);
3023 MEM_SAFE_FREE(mmd->dynverts);
3024 MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */
3025 MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */
3026 mmd->verts_num = 0;
3027 mmd->cage_verts_num = 0;
3028 mmd->influences_num = 0;
3029 }
3030 else {
3031 /* Force modifier to run, it will call binding routine
3032 * (this has to happen outside of depsgraph evaluation). */
3034 depsgraph, ob, &mmd->modifier);
3037 mmd_eval->bindfunc = nullptr;
3038 }
3039
3042 return OPERATOR_FINISHED;
3043}
3044
3046 wmOperator *op,
3047 const wmEvent * /*event*/)
3048{
3050 return meshdeform_bind_exec(C, op);
3051 }
3052 return OPERATOR_CANCELLED;
3053}
3054
3056{
3057 /* identifiers */
3058 ot->name = "Mesh Deform Bind";
3059 ot->description = "Bind mesh to cage in mesh deform modifier";
3060 ot->idname = "OBJECT_OT_meshdeform_bind";
3061
3062 /* API callbacks. */
3063 ot->poll = meshdeform_poll;
3064 ot->invoke = meshdeform_bind_invoke;
3065 ot->exec = meshdeform_bind_exec;
3066
3067 /* flags */
3070}
3071
3073
3074/* ------------------------------------------------------------------- */
3077
3079{
3080 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0, true, false);
3081}
3082
3100
3102 wmOperator *op,
3103 const wmEvent * /*event*/)
3104{
3106 return explode_refresh_exec(C, op);
3107 }
3108 return OPERATOR_CANCELLED;
3109}
3110
3112{
3113 ot->name = "Explode Refresh";
3114 ot->description = "Refresh data in the Explode modifier";
3115 ot->idname = "OBJECT_OT_explode_refresh";
3116
3117 ot->poll = explode_poll;
3118 ot->invoke = explode_refresh_invoke;
3119 ot->exec = explode_refresh_exec;
3120
3121 /* flags */
3124}
3125
3127
3128/* ------------------------------------------------------------------- */
3131
3133{
3134 return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0, true, false);
3135}
3136
3147
3148static void oceanbake_free(void *customdata)
3149{
3150 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3151 MEM_delete(oj);
3152}
3153
3154/* called by oceanbake, only to check job 'stop' value */
3155static int oceanbake_breakjob(void * /*customdata*/)
3156{
3157 // OceanBakeJob *ob = (OceanBakeJob *)customdata;
3158 // return *(ob->stop);
3159
3160 /* this is not nice yet, need to make the jobs list template better
3161 * for identifying/acting upon various different jobs */
3162 /* but for now we'll reuse the render break... */
3163 return (G.is_break);
3164}
3165
3166/* called by oceanbake, wmJob sends notifier */
3167static void oceanbake_update(void *customdata, float progress, int *cancel)
3168{
3169 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3170
3171 if (oceanbake_breakjob(oj)) {
3172 *cancel = 1;
3173 }
3174
3175 *(oj->do_update) = true;
3176 *(oj->progress) = progress;
3177}
3178
3179static void oceanbake_startjob(void *customdata, wmJobWorkerStatus *worker_status)
3180{
3181 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3182
3183 oj->stop = &worker_status->stop;
3184 oj->do_update = &worker_status->do_update;
3185 oj->progress = &worker_status->progress;
3186
3187 G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
3188
3189 BKE_ocean_bake(oj->ocean, oj->och, oceanbake_update, (void *)oj);
3190
3191 worker_status->do_update = true;
3192 worker_status->stop = false;
3193}
3194
3195static void oceanbake_endjob(void *customdata)
3196{
3197 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3198
3199 if (oj->ocean) {
3200 BKE_ocean_free(oj->ocean);
3201 oj->ocean = nullptr;
3202 }
3203
3204 oj->omd->oceancache = oj->och;
3205 oj->omd->cached = true;
3206
3207 Object *ob = oj->owner;
3209}
3210
3212{
3213 Main *bmain = CTX_data_main(C);
3216 op, ob, eModifierType_Ocean);
3217 Scene *scene = CTX_data_scene(C);
3218 const bool free = RNA_boolean_get(op->ptr, "free");
3219
3220 if (!omd) {
3221 return OPERATOR_CANCELLED;
3222 }
3223
3224 if (free) {
3228 return OPERATOR_FINISHED;
3229 }
3230
3232 BKE_modifier_path_relbase(bmain, ob),
3233 omd->bakestart,
3234 omd->bakeend,
3235 omd->wave_scale,
3236 omd->chop_amount,
3237 omd->foam_coverage,
3238 omd->foam_fade,
3239 omd->resolution);
3240
3241 och->time = MEM_malloc_arrayN<float>(och->duration, "foam bake time");
3242
3243 int cfra = scene->r.cfra;
3244
3245 /* precalculate time variable before baking */
3246 int i = 0;
3248 for (int f = omd->bakestart; f <= omd->bakeend; f++) {
3249 /* For now only simple animation of time value is supported, nothing else.
3250 * No drivers or other modifier parameters. */
3251 /* TODO(sergey): This operates on an original data, so no flush is needed. However, baking
3252 * usually should happen on an evaluated objects, so this seems to be deeper issue here. */
3253
3255 f);
3256 BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
3257
3258 och->time[i] = omd->time;
3259 i++;
3260 }
3261
3262 /* Make a copy of ocean to use for baking - thread-safety. */
3263 Ocean *ocean = BKE_ocean_add();
3264 BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
3265
3266#if 0
3267 BKE_ocean_bake(ocean, och);
3268
3269 omd->oceancache = och;
3270 omd->cached = true;
3271
3272 scene->r.cfra = cfra;
3273
3276#endif
3277
3278 /* job stuff */
3279
3280 scene->r.cfra = cfra;
3281
3282 /* setup job */
3283 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
3285 scene,
3286 "Ocean Simulation",
3289 OceanBakeJob *oj = MEM_callocN<OceanBakeJob>("ocean bake job");
3290 oj->owner = ob;
3291 oj->ocean = ocean;
3292 oj->och = och;
3293 oj->omd = omd;
3294
3297 WM_jobs_callbacks(wm_job, oceanbake_startjob, nullptr, nullptr, oceanbake_endjob);
3298
3299 WM_jobs_start(CTX_wm_manager(C), wm_job);
3300
3301 return OPERATOR_FINISHED;
3302}
3303
3305{
3307 return ocean_bake_exec(C, op);
3308 }
3309 return OPERATOR_CANCELLED;
3310}
3311
3313{
3314 ot->name = "Bake Ocean";
3315 ot->description = "Bake an image sequence of ocean data";
3316 ot->idname = "OBJECT_OT_ocean_bake";
3317
3318 ot->poll = ocean_bake_poll;
3319 ot->invoke = ocean_bake_invoke;
3320 ot->exec = ocean_bake_exec;
3321
3322 /* flags */
3325
3326 RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
3327}
3328
3330
3331/* ------------------------------------------------------------------- */
3334
3336{
3337 return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0, false, false);
3338}
3339
3341{
3346
3347 if (lmd == nullptr) {
3348 return OPERATOR_CANCELLED;
3349 }
3350
3351 if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) {
3353 }
3354 else {
3356 }
3357
3360 lmd_eval->flag = lmd->flag;
3361
3362 /* Force modifier to run, it will call binding routine
3363 * (this has to happen outside of depsgraph evaluation). */
3365
3366 /* This is hard to know from the modifier itself whether the evaluation is
3367 * happening for binding or not. So we copy all the required data here. */
3368 lmd->verts_num = lmd_eval->verts_num;
3369 if (lmd_eval->vertexco == nullptr) {
3370 MEM_SAFE_FREE(lmd->vertexco);
3371 }
3372 else {
3373 lmd->vertexco = static_cast<float *>(MEM_dupallocN(lmd_eval->vertexco));
3374 }
3375
3378 return OPERATOR_FINISHED;
3379}
3380
3382 wmOperator *op,
3383 const wmEvent * /*event*/)
3384{
3386 return laplaciandeform_bind_exec(C, op);
3387 }
3388 return OPERATOR_CANCELLED;
3389}
3390
3392{
3393 /* identifiers */
3394 ot->name = "Laplacian Deform Bind";
3395 ot->description = "Bind mesh to system in laplacian deform modifier";
3396 ot->idname = "OBJECT_OT_laplaciandeform_bind";
3397
3398 /* API callbacks. */
3399 ot->poll = laplaciandeform_poll;
3402
3403 /* flags */
3406}
3407
3409
3410/* ------------------------------------------------------------------- */
3413
3415{
3416 return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0, true, false);
3417}
3418
3420{
3425
3426 if (smd == nullptr) {
3427 return OPERATOR_CANCELLED;
3428 }
3429
3430 if (smd->flags & MOD_SDEF_BIND) {
3431 smd->flags &= ~MOD_SDEF_BIND;
3432 }
3433 else if (smd->target) {
3434 smd->flags |= MOD_SDEF_BIND;
3435 }
3436
3438 depsgraph, ob, &smd->modifier);
3439 smd_eval->flags = smd->flags;
3440
3441 /* Force modifier to run, it will call binding routine
3442 * (this has to happen outside of depsgraph evaluation). */
3444
3447 return OPERATOR_FINISHED;
3448}
3449
3451 wmOperator *op,
3452 const wmEvent * /*event*/)
3453{
3455 return surfacedeform_bind_exec(C, op);
3456 }
3457 return OPERATOR_CANCELLED;
3458}
3459
3461{
3462 /* identifiers */
3463 ot->name = "Surface Deform Bind";
3464 ot->description = "Bind mesh to target in surface deform modifier";
3465 ot->idname = "OBJECT_OT_surfacedeform_bind";
3466
3467 /* API callbacks. */
3469 ot->invoke = surfacedeform_bind_invoke;
3471
3472 /* flags */
3475}
3476
3478
3479/* ------------------------------------------------------------------- */
3486
3488{
3490
3491 char modifier_name[MAX_NAME];
3492 RNA_string_get(op->ptr, "modifier_name", modifier_name);
3494 if (nmd == nullptr) {
3495 return OPERATOR_CANCELLED;
3496 }
3497
3498 char input_name[MAX_NAME];
3499 RNA_string_get(op->ptr, "input_name", input_name);
3500
3501 IDProperty *use_attribute = IDP_GetPropertyFromGroup(
3502 nmd->settings.properties, std::string(input_name + std::string("_use_attribute")).c_str());
3503 if (!use_attribute) {
3504 return OPERATOR_CANCELLED;
3505 }
3506
3507 if (use_attribute->type == IDP_INT) {
3508 IDP_Int(use_attribute) = !IDP_Int(use_attribute);
3509 }
3510 else if (use_attribute->type == IDP_BOOLEAN) {
3511 IDP_Bool(use_attribute) = !IDP_Bool(use_attribute);
3512 }
3513 else {
3514 return OPERATOR_CANCELLED;
3515 }
3516
3519 return OPERATOR_FINISHED;
3520}
3521
3523{
3524 ot->name = "Input Attribute Toggle";
3525 ot->description =
3526 "Switch between an attribute and a single value to define the data for every element";
3527 ot->idname = "OBJECT_OT_geometry_nodes_input_attribute_toggle";
3528
3531
3533
3534 RNA_def_string(ot->srna, "input_name", nullptr, 0, "Input Name", "");
3535 RNA_def_string(ot->srna, "modifier_name", nullptr, MAX_NAME, "Modifier Name", "");
3536}
3537
3539
3540/* ------------------------------------------------------------------- */
3543
3545{
3546 Main *bmain = CTX_data_main(C);
3549 if (!(md && md->type == eModifierType_Nodes)) {
3550 return OPERATOR_CANCELLED;
3551 }
3552
3554 bNodeTree *tree = nmd->node_group;
3555 if (tree == nullptr) {
3556 return OPERATOR_CANCELLED;
3557 }
3558
3559 bNodeTree *new_tree = (bNodeTree *)BKE_id_copy_ex(
3560 bmain, &tree->id, nullptr, LIB_ID_COPY_ACTIONS | LIB_ID_COPY_DEFAULT);
3561
3563
3564 if (new_tree == nullptr) {
3565 return OPERATOR_CANCELLED;
3566 }
3567
3568 nmd->node_group = new_tree;
3569 id_us_min(&tree->id);
3570
3575 return OPERATOR_FINISHED;
3576}
3577
3579{
3580 ot->name = "Copy Geometry Node Group";
3581 ot->description = "Copy the active geometry node group and assign it to the active modifier";
3582 ot->idname = "OBJECT_OT_geometry_node_tree_copy_assign";
3583
3586
3587 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3588}
3589
3591
3592/* ------------------------------------------------------------------- */
3595
3597{
3598 return edit_modifier_poll_generic(C, &RNA_GreasePencilDashModifierData, 0, false, false);
3599}
3600
3602{
3604 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
3606
3607 if (dmd == nullptr) {
3608 return OPERATOR_CANCELLED;
3609 }
3610
3611 GreasePencilDashModifierSegment *new_segments =
3612 MEM_malloc_arrayN<GreasePencilDashModifierSegment>(dmd->segments_num + 1, __func__);
3613
3614 const int new_active_index = std::clamp(dmd->segment_active_index + 1, 0, dmd->segments_num);
3615 if (dmd->segments_num != 0) {
3616 /* Copy the segments before the new segment. */
3617 memcpy(new_segments,
3618 dmd->segments_array,
3619 sizeof(GreasePencilDashModifierSegment) * new_active_index);
3620 /* Copy the segments after the new segment. */
3621 memcpy(new_segments + new_active_index + 1,
3622 dmd->segments_array + new_active_index,
3623 sizeof(GreasePencilDashModifierSegment) * (dmd->segments_num - new_active_index));
3624 }
3625
3626 /* Create the new segment. */
3627 GreasePencilDashModifierSegment *ds = &new_segments[new_active_index];
3628 memcpy(ds,
3632 [&](const StringRef name) {
3633 for (const GreasePencilDashModifierSegment &ds : dmd->segments()) {
3634 if (STREQ(ds.name, name.data())) {
3635 return true;
3636 }
3637 }
3638 return false;
3639 },
3640 '.',
3641 ds->name);
3642
3643 MEM_SAFE_FREE(dmd->segments_array);
3644 dmd->segments_array = new_segments;
3645 dmd->segments_num++;
3646 dmd->segment_active_index = new_active_index;
3647
3650
3651 return OPERATOR_FINISHED;
3652}
3653
3655 wmOperator *op,
3656 const wmEvent * /*event*/)
3657{
3660 }
3661 return OPERATOR_CANCELLED;
3662}
3663
3665{
3666 /* identifiers */
3667 ot->name = "Add Segment";
3668 ot->description = "Add a segment to the dash modifier";
3669 ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_add";
3670
3671 /* API callbacks. */
3675
3676 /* flags */
3679}
3680
3682
3684{
3686 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
3688
3689 if (dmd == nullptr) {
3690 return OPERATOR_CANCELLED;
3691 }
3692
3693 if (!dmd->segments().index_range().contains(dmd->segment_active_index)) {
3694 return OPERATOR_CANCELLED;
3695 }
3696
3697 dna::array::remove_index(&dmd->segments_array,
3698 &dmd->segments_num,
3699 &dmd->segment_active_index,
3700 dmd->segment_active_index,
3702
3705
3706 return OPERATOR_FINISHED;
3707}
3708
3710 wmOperator *op,
3711 const wmEvent * /*event*/)
3712{
3715 }
3716 return OPERATOR_CANCELLED;
3717}
3718
3720{
3721 /* identifiers */
3722 ot->name = "Remove Dash Segment";
3723 ot->description = "Remove the active segment from the dash modifier";
3724 ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_remove";
3725
3726 /* API callbacks. */
3730
3731 /* flags */
3734
3736 ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX);
3737}
3738
3740 Up = -1,
3741 Down = 1,
3742};
3743
3745{
3747 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
3749
3750 if (dmd == nullptr) {
3751 return OPERATOR_CANCELLED;
3752 }
3753
3754 if (dmd->segments_num < 2) {
3755 return OPERATOR_CANCELLED;
3756 }
3757
3759 RNA_enum_get(op->ptr, "type"));
3760 switch (direction) {
3762 if (dmd->segment_active_index == 0) {
3763 return OPERATOR_CANCELLED;
3764 }
3765
3766 std::swap(dmd->segments_array[dmd->segment_active_index],
3767 dmd->segments_array[dmd->segment_active_index - 1]);
3768
3769 dmd->segment_active_index--;
3770 break;
3772 if (dmd->segment_active_index == dmd->segments_num - 1) {
3773 return OPERATOR_CANCELLED;
3774 }
3775
3776 std::swap(dmd->segments_array[dmd->segment_active_index],
3777 dmd->segments_array[dmd->segment_active_index + 1]);
3778
3779 dmd->segment_active_index++;
3780 break;
3781 default:
3782 return OPERATOR_CANCELLED;
3783 }
3784
3787
3788 return OPERATOR_FINISHED;
3789}
3790
3792 wmOperator *op,
3793 const wmEvent * /*event*/)
3794{
3797 }
3798 return OPERATOR_CANCELLED;
3799}
3800
3802{
3803 static const EnumPropertyItem segment_move[] = {
3804 {int(DashSegmentMoveDirection::Up), "UP", 0, "Up", ""},
3805 {int(DashSegmentMoveDirection::Down), "DOWN", 0, "Down", ""},
3806 {0, nullptr, 0, nullptr, nullptr},
3807 };
3808
3809 /* identifiers */
3810 ot->name = "Move Dash Segment";
3811 ot->description = "Move the active dash segment up or down";
3812 ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_move";
3813
3814 /* API callbacks. */
3818
3819 /* flags */
3822
3823 ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", "");
3824}
3825
3827
3828/* ------------------------------------------------------------------- */
3831
3833{
3834 return edit_modifier_poll_generic(C, &RNA_GreasePencilTimeModifier, 0, false, false);
3835}
3836
3838{
3840 auto *tmd = reinterpret_cast<GreasePencilTimeModifierData *>(
3842
3843 if (tmd == nullptr) {
3844 return OPERATOR_CANCELLED;
3845 }
3846
3847 GreasePencilTimeModifierSegment *new_segments =
3848 MEM_malloc_arrayN<GreasePencilTimeModifierSegment>(tmd->segments_num + 1, __func__);
3849
3850 const int new_active_index = std::clamp(tmd->segment_active_index + 1, 0, tmd->segments_num);
3851 if (tmd->segments_num != 0) {
3852 /* Copy the segments before the new segment. */
3853 memcpy(new_segments,
3854 tmd->segments_array,
3855 sizeof(GreasePencilTimeModifierSegment) * new_active_index);
3856 /* Copy the segments after the new segment. */
3857 memcpy(new_segments + new_active_index + 1,
3858 tmd->segments_array + new_active_index,
3859 sizeof(GreasePencilTimeModifierSegment) * (tmd->segments_num - new_active_index));
3860 }
3861
3862 /* Create the new segment. */
3863 GreasePencilTimeModifierSegment *segment = &new_segments[new_active_index];
3864 memcpy(segment,
3868 [&](const StringRef name) {
3869 for (const GreasePencilTimeModifierSegment &segment : tmd->segments()) {
3870 if (STREQ(segment.name, name.data())) {
3871 return true;
3872 }
3873 }
3874 return false;
3875 },
3876 '.',
3877 segment->name);
3878
3879 MEM_SAFE_FREE(tmd->segments_array);
3880 tmd->segments_array = new_segments;
3881 tmd->segments_num++;
3882 tmd->segment_active_index++;
3883
3886
3887 return OPERATOR_FINISHED;
3888}
3889
3891 wmOperator *op,
3892 const wmEvent * /*event*/)
3893{
3896 }
3897 return OPERATOR_CANCELLED;
3898}
3899
3901{
3902 /* identifiers */
3903 ot->name = "Add Segment";
3904 ot->description = "Add a segment to the time modifier";
3905 ot->idname = "OBJECT_OT_grease_pencil_time_modifier_segment_add";
3906
3907 /* API callbacks. */
3911
3912 /* flags */
3915}
3916
3918
3920{
3922 auto *tmd = reinterpret_cast<GreasePencilTimeModifierData *>(
3924
3925 if (tmd == nullptr) {
3926 return OPERATOR_CANCELLED;
3927 }
3928
3929 if (!tmd->segments().index_range().contains(tmd->segment_active_index)) {
3930 return OPERATOR_CANCELLED;
3931 }
3932
3933 dna::array::remove_index(&tmd->segments_array,
3934 &tmd->segments_num,
3935 &tmd->segment_active_index,
3936 tmd->segment_active_index,
3938
3941
3942 return OPERATOR_FINISHED;
3943}
3944
3946 wmOperator *op,
3947 const wmEvent * /*event*/)
3948{
3951 }
3952 return OPERATOR_CANCELLED;
3953}
3954
3956{
3957 /* identifiers */
3958 ot->name = "Remove Segment";
3959 ot->description = "Remove the active segment from the time modifier";
3960 ot->idname = "OBJECT_OT_grease_pencil_time_modifier_segment_remove";
3961
3962 /* API callbacks. */
3966
3967 /* flags */
3970
3972 ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX);
3973}
3974
3976 Up = -1,
3977 Down = 1,
3978};
3979
3981{
3983 auto *tmd = reinterpret_cast<GreasePencilTimeModifierData *>(
3985
3986 if (tmd == nullptr) {
3987 return OPERATOR_CANCELLED;
3988 }
3989
3990 if (tmd->segments_num < 2) {
3991 return OPERATOR_CANCELLED;
3992 }
3993
3995 RNA_enum_get(op->ptr, "type"));
3996 switch (direction) {
3998 if (tmd->segment_active_index == 0) {
3999 return OPERATOR_CANCELLED;
4000 }
4001
4002 std::swap(tmd->segments_array[tmd->segment_active_index],
4003 tmd->segments_array[tmd->segment_active_index - 1]);
4004
4005 tmd->segment_active_index--;
4006 break;
4008 if (tmd->segment_active_index == tmd->segments_num - 1) {
4009 return OPERATOR_CANCELLED;
4010 }
4011
4012 std::swap(tmd->segments_array[tmd->segment_active_index],
4013 tmd->segments_array[tmd->segment_active_index + 1]);
4014
4015 tmd->segment_active_index++;
4016 break;
4017 default:
4018 return OPERATOR_CANCELLED;
4019 }
4020
4023
4024 return OPERATOR_FINISHED;
4025}
4026
4028 wmOperator *op,
4029 const wmEvent * /*event*/)
4030{
4033 }
4034 return OPERATOR_CANCELLED;
4035}
4036
4038{
4039 static const EnumPropertyItem segment_move[] = {
4040 {int(TimeSegmentMoveDirection::Up), "UP", 0, "Up", ""},
4041 {int(TimeSegmentMoveDirection::Down), "DOWN", 0, "Down", ""},
4042 {0, nullptr, 0, nullptr, nullptr},
4043 };
4044
4045 /* identifiers */
4046 ot->name = "Move Segment";
4047 ot->description = "Move the active time segment up or down";
4048 ot->idname = "OBJECT_OT_grease_pencil_time_modifier_segment_move";
4049
4050 /* API callbacks. */
4054
4055 /* flags */
4058
4059 ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", "");
4060}
4061
4063
4064} // namespace blender::ed::object
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_armature_bonecoll_show_all(bArmature *armature)
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time) ATTR_WARN_UNUSED_RESULT
Definition anim_sys.cc:735
@ ADT_RECALC_ANIM
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, bool flush_to_original)
bool BKE_animdata_drivers_remove_for_rna_struct(struct ID &owner_id, struct StructRNA &type, void *data)
#define CTX_DATA_BEGIN(C, Type, instance, member)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
bool CTX_data_selected_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Main * CTX_data_main(const bContext *C)
bool CTX_data_selected_editable_objects(const bContext *C, blender::Vector< PointerRNA > *list)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define CTX_DATA_END
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
blender::Array< blender::float3 > BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb)
Definition curve.cc:4559
void BKE_curve_nurbs_vert_coords_apply(ListBase *lb, const blender::Span< blender::float3 > vert_coords, bool constrain_2d)
Low-level operations for curves that cannot be defined in the C++ header yet.
void BKE_curves_data_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *object)
Low-level operations for curves.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n)
@ CD_SET_DEFAULT
void * CustomData_bmesh_get(const CustomData *data, void *block, eCustomDataType type)
const CustomData_MeshMasks CD_MASK_BAREMESH
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
const void * CustomData_add_layer_with_data(CustomData *data, eCustomDataType type, void *layer_data, int totelem, const blender::ImplicitSharingInfo *sharing_info)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
const CustomData_MeshMasks CD_MASK_DERIVEDMESH
bool CustomData_free_layer_active(CustomData *data, eCustomDataType type)
display list (or rather multi purpose list) stuff.
void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, bool for_render)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:61
struct PartDeflect * BKE_partdeflect_new(int type)
Definition effect.cc:71
Low-level operations for grease pencil.
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:766
#define IDP_Int(prop)
#define IDP_Bool(prop)
Key * BKE_key_add(Main *bmain, ID *id)
Definition key.cc:258
KeyBlock * BKE_keyblock_add(Key *key, const char *name)
Definition key.cc:1835
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, blender::MutableSpan< blender::float3 > vert_positions)
Definition key.cc:2219
void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
Definition key.cc:2203
void BKE_lattice_vert_coords_apply(Lattice *lt, blender::Span< blender::float3 > vert_coordss)
void BKE_lattice_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition lattice.cc:519
blender::Array< blender::float3 > BKE_lattice_vert_coords_alloc(const Lattice *lt)
Definition lattice.cc:493
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
@ LIB_ID_COPY_ACTIONS
@ LIB_ID_COPY_LOCALIZE
@ LIB_ID_COPY_DEFAULT
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2503
void BKE_id_free(Main *bmain, void *idv)
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1981
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
Definition lib_id.cc:767
void id_us_min(ID *id)
Definition lib_id.cc:361
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
General operations, lookup, etc. for materials.
void BKE_object_material_from_eval_data(Main *bmain, Object *ob_orig, const ID *data_eval)
void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition mball.cc:655
void BKE_mesh_ensure_skin_customdata(Mesh *mesh)
void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *mesh)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
void BKE_modifiers_persistent_uid_init(const Object &object, ModifierData &md)
@ eModifierTypeFlag_Single
@ eModifierTypeFlag_NoUserAdd
@ eModifierTypeFlag_RequiresOriginalData
ModifierData * BKE_modifier_get_original(const Object *object, ModifierData *md)
ModifierData * BKE_modifiers_findby_name(const Object *ob, const char *name)
const char * BKE_modifier_path_relbase(Main *bmain, Object *ob)
bool BKE_modifier_is_same_topology(ModifierData *md)
void BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
void BKE_modifier_free(ModifierData *md)
bool BKE_modifier_is_nonlocal_in_liboverride(const Object *ob, const ModifierData *md)
void BKE_modifier_remove_from_list(Object *ob, ModifierData *md)
ModifierData * BKE_modifier_get_evaluated(Depsgraph *depsgraph, Object *object, ModifierData *md)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
ModifierData * BKE_modifier_new(int type)
@ MOD_APPLY_TO_ORIGINAL
void BKE_modifier_copydata(const ModifierData *md, ModifierData *target)
void multires_customdata_delete(Mesh *mesh)
Definition multires.cc:66
bool multiresModifier_reshapeFromDeformModifier(Depsgraph *depsgraph, Object *ob, MultiresModifierData *mmd, ModifierData *deform_md)
MultiresModifierData * find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
Definition multires.cc:282
void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob)
Definition multires.cc:503
void multires_force_sculpt_rebuild(Object *object)
Definition multires.cc:445
void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
Definition multires.cc:343
General operations, lookup, etc. for blender objects.
void BKE_object_eval_reset(Object *ob_eval)
void BKE_object_modifier_set_active(Object *ob, ModifierData *md)
bool BKE_object_is_in_editmode(const Object *ob)
bool BKE_object_supports_modifiers(const Object *ob)
Object * BKE_object_add(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name) ATTR_NONNULL(1
ModifierData * BKE_object_active_modifier(const Object *ob)
void BKE_object_link_modifiers(Object *ob_dst, const Object *ob_src)
bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
bool BKE_object_copy_modifier(Main *bmain, const Scene *scene, Object *ob_dst, const Object *ob_src, const ModifierData *md)
void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
void BKE_object_free_derived_caches(Object *ob)
Functions for dealing with objects and deform verts, used by painting and tools.
struct bDeformGroup * BKE_object_defgroup_add_name(struct Object *ob, const char *name)
struct Ocean * BKE_ocean_add(void)
Definition ocean.cc:1571
void BKE_ocean_bake(struct Ocean *o, struct OceanCache *och, void(*update_cb)(void *, float progress, int *cancel), void *update_cb_data)
Definition ocean.cc:1652
void BKE_ocean_free_modifier_cache(struct OceanModifierData *omd)
Definition ocean.cc:1670
bool BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd, int resolution)
void BKE_ocean_free(struct Ocean *oc)
Definition ocean.cc:1606
struct OceanCache * BKE_ocean_init_cache(const char *bakepath, const char *relbase, int start, int end, float wave_scale, float chop_amount, float foam_coverage, float foam_fade, int resolution)
Definition ocean.cc:1635
void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, Main *bmain, Object *ob, MultiresModifierData *mmd)
Definition paint.cc:2666
struct ModifierData * object_add_particle_system(struct Main *bmain, const struct Scene *scene, struct Object *ob, const char *name)
void object_remove_particle_system(struct Main *bmain, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys)
Definition particle.cc:3982
struct ParticleSystem * psys_eval_get(struct Depsgraph *depsgraph, struct Object *object, struct ParticleSystem *psys)
Definition particle.cc:667
void psys_apply_hair_lattice(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys)
Definition particle.cc:5244
struct ModifierData * object_copy_particle_system(struct Main *bmain, const struct Scene *scene, struct Object *ob, const struct ParticleSystem *psys_orig)
General operations for point clouds.
PointCloud * BKE_pointcloud_copy_for_eval(const PointCloud *pointcloud_src)
void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src, PointCloud *pointcloud_dst)
void BKE_pointcloud_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
Definition scene.cc:2697
struct SoftBody * sbNew(void)
Definition softbody.cc:3110
void sbFree(struct Object *ob)
Definition softbody.cc:3162
Volume data-block.
void BKE_volume_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition BLI_bitmap.h:37
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition BLI_bitmap.h:61
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition BLI_bitmap.h:78
unsigned int BLI_bitmap
Definition BLI_bitmap.h:13
struct GSet GSet
Definition BLI_ghash.h:337
GSet * BLI_gset_ptr_new(const char *info)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.cc:966
void BLI_kdtree_nd_ free(KDTree *tree)
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:332
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:371
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define STRNCPY_UTF8(dst, src)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
unsigned int uint
#define ELEM(...)
#define STREQ(a, b)
#define RPT_(msgid)
#define TIP_(msgid)
#define IFACE_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_disable_visibility_optimization(Depsgraph *depsgraph)
Definition depsgraph.cc:349
@ DAG_EVAL_VIEWPORT
Depsgraph * DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
Definition depsgraph.cc:278
void DEG_evaluate_on_refresh(Depsgraph *graph, DepsgraphEvaluateSyncWriteback sync_writeback=DEG_EVALUATE_SYNC_WRITEBACK_NO)
void DEG_graph_free(Depsgraph *graph)
Definition depsgraph.cc:306
void DEG_relations_tag_update(Main *bmain)
void DEG_graph_build_from_ids(Depsgraph *graph, blender::Span< ID * > ids)
float DEG_get_ctime(const Depsgraph *graph)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
Main * DEG_get_bmain(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:962
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:985
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:682
@ IDP_BOOLEAN
@ IDP_INT
@ ARM_DEF_VGROUP
@ ARM_DEF_QUATERNION
@ BONE_CONNECTED
@ ARM_DRAW_TYPE_STICK
@ CD_MVERT_SKIN
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ KEY_RELATIVE
@ BASE_ENABLED_VIEWPORT
@ MVERT_SKIN_LOOSE
@ MVERT_SKIN_ROOT
@ eModifierFlag_PinLast
@ eModifierFlag_OverrideLibrary_Local
@ eModifierMode_Realtime
@ MOD_SDEF_BIND
@ NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR
@ eModifierType_ParticleSystem
@ eModifierType_MeshDeform
@ eModifierType_Explode
@ eModifierType_Subsurf
@ eModifierType_Surface
@ eModifierType_Skin
@ eModifierType_Cloth
@ eModifierType_Hook
@ eModifierType_GreasePencilTime
@ eModifierType_Ocean
@ eModifierType_LaplacianDeform
@ eModifierType_GreasePencilDash
@ eModifierType_Armature
@ eModifierType_SurfaceDeform
@ eModifierType_CorrectiveSmooth
@ eModifierType_Nodes
@ eModifierType_Collision
@ eModifierType_Softbody
@ eModifierType_Multires
@ eExplodeFlag_CalcFaces
@ MOD_LAPLACIANDEFORM_BIND
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_SCULPT
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ OB_DRAW_IN_FRONT
@ PART_DRAW_PARENT
@ PART_HAIR
@ PART_DRAW_PATH
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
#define WEIGHT_REPLACE
bool ED_operator_object_active_only(bContext *C)
bool ED_operator_object_active_local_editable(bContext *C)
bool ED_operator_object_active(bContext *C)
bool ED_operator_object_active_editable(bContext *C)
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
@ PROP_HIDDEN
Definition RNA_types.hh:324
#define C
Definition RandGen.cpp:29
PointerRNA * UI_region_panel_custom_data_under_cursor(const bContext *C, const wmEvent *event)
@ ALERT_ICON_WARNING
@ WM_JOB_TYPE_OBJECT_SIM_OCEAN
Definition WM_api.hh:1732
@ WM_JOB_PROGRESS
Definition WM_api.hh:1716
#define NC_WINDOW
Definition WM_types.hh:372
@ KM_ALT
Definition WM_types.hh:277
#define ND_MODE
Definition WM_types.hh:442
#define NC_SCENE
Definition WM_types.hh:375
#define NA_ADDED
Definition WM_types.hh:583
#define ND_MODIFIER
Definition WM_types.hh:459
#define NS_MODE_OBJECT
Definition WM_types.hh:557
ReportList * reports
Definition WM_types.hh:1025
#define NA_REMOVED
Definition WM_types.hh:584
float progress
Definition WM_types.hh:1019
#define NC_OBJECT
Definition WM_types.hh:376
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
EditBone * ED_armature_ebone_add(bArmature *arm, const char *name)
void ED_armature_edit_free(bArmature *arm)
void ED_armature_from_edit(Main *bmain, bArmature *arm)
@ BM_ELEM_SELECT
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_flag_test(ele, hflag)
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
@ BM_EDGES_OF_VERT
BMesh const char void * data
BMesh * bm
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
ItemIterator items() const &
Definition BLI_map.hh:902
const T * end() const
Definition BLI_array.hh:314
const T * begin() const
Definition BLI_array.hh:310
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
int64_t size() const
Definition BLI_map.hh:976
KeyIterator keys() const &
Definition BLI_map.hh:875
Value & lookup_or_add(const Key &key, const Value &value)
Definition BLI_map.hh:588
constexpr const T * data() const
Definition BLI_span.hh:215
constexpr const char * data() const
void append(const T &value)
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
int users
KDTree_3d * tree
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
#define MEM_SAFE_FREE(v)
#define ID_IS_EDITABLE(_id)
#define ID_REAL_USERS(id)
#define MAX_NAME
#define ID_IS_OVERRIDE_LIBRARY(_id)
static const char * modifier_name[LS_MODIFIER_NUM]
Definition linestyle.cc:679
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void ED_mesh_deform_bind_callback(Object *object, MeshDeformModifierData *mmd, Mesh *cagemesh, float *vertexcos, int verts_num, float cagemat[4][4])
void ensure_non_empty_layer_names(Main &bmain, GreasePencil &grease_pencil)
int edge_other_vert(const int2 edge, const int vert)
Definition BKE_mesh.hh:354
GroupedSpan< int > build_vert_to_edge_map(Span< int2 > edges, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
void mesh_remove_invalid_attribute_strings(Mesh &mesh)
Mesh * mesh_get_eval_deform(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
Mesh * mesh_create_eval_final(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
void remove_index(T **items, int *items_num, int *active_index, const int index, void(*destruct_item)(T *))
void apply_eval_grease_pencil_data(const GreasePencil &eval_grease_pencil, const int eval_frame, const IndexMask &orig_layers, GreasePencil &orig_grease_pencil)
void modifier_register_use_selected_objects_prop(wmOperatorType *ot)
static void skin_armature_bone_create(Object *skin_ob, const Span< float3 > positions, const int2 *edges, bArmature *arm, BLI_bitmap *edges_visited, const GroupedSpan< int > emap, EditBone *parent_bone, int parent_v)
static wmOperatorStatus modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, bool keep_modifier)
ModifierData * modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
void single_obdata_user_make(Main *bmain, Scene *scene, Object *ob)
static wmOperatorStatus modifier_add_exec(bContext *C, wmOperator *op)
static wmOperatorStatus modifier_copy_to_selected_exec(bContext *C, wmOperator *op)
bool modifier_apply(Main *bmain, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md, int mode, bool keep_modifier, bool do_all_keyframes)
static wmOperatorStatus laplaciandeform_bind_exec(bContext *C, wmOperator *op)
static bool object_modifier_remove(Main *bmain, Scene *scene, Object *ob, ModifierData *md, bool *r_sort_depsgraph)
static int oceanbake_breakjob(void *)
static wmOperatorStatus modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool modifier_apply_shape(Main *bmain, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval)
static wmOperatorStatus time_modifier_segment_add_invoke(bContext *C, wmOperator *op, const wmEvent *)
void OBJECT_OT_geometry_node_tree_copy_assign(wmOperatorType *ot)
bool modifier_copy_to_object(Main *bmain, const Scene *scene, const Object *ob_src, const ModifierData *md, Object *ob_dst, ReportList *reports)
static wmOperatorStatus skin_radii_equalize_exec(bContext *C, wmOperator *)
static bool object_modifier_safe_to_delete(Main *bmain, Object *ob, ModifierData *exclude, ModifierType type)
static wmOperatorStatus meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus modifier_apply_exec(bContext *C, wmOperator *op)
static wmOperatorStatus modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus modifier_move_up_exec(bContext *C, wmOperator *op)
static std::string modifier_apply_as_shapekey_get_description(bContext *, wmOperatorType *, PointerRNA *ptr)
static bool correctivesmooth_poll(bContext *C)
static bool object_modifier_check_move_after(ReportList *reports, eReportType error_type, ModifierData *md, ModifierData *md_next)
static const EnumPropertyItem * modifier_add_itemf(bContext *C, PointerRNA *, PropertyRNA *, bool *r_free)
static bool edit_modifier_poll(bContext *C)
static wmOperatorStatus modifier_set_active_exec(bContext *C, wmOperator *op)
static void oceanbake_startjob(void *customdata, wmJobWorkerStatus *worker_status)
static wmOperatorStatus dash_modifier_segment_add_exec(bContext *C, wmOperator *op)
bool edit_modifier_invoke_properties(bContext *C, wmOperator *op)
static void edit_modifier_report_property(wmOperatorType *ot)
static wmOperatorStatus modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void OBJECT_OT_grease_pencil_dash_modifier_segment_add(wmOperatorType *ot)
static void oceanbake_endjob(void *customdata)
bool iter_other(Main *bmain, Object *orig_ob, bool include_orig, bool(*callback)(Object *ob, void *callback_data), void *callback_data)
static bool ocean_bake_poll(bContext *C)
static wmOperatorStatus modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op)
static wmOperatorStatus geometry_nodes_input_attribute_toggle_exec(bContext *C, wmOperator *op)
static wmOperatorStatus dash_modifier_segment_remove_exec(bContext *C, wmOperator *op)
bool modifier_move_up(ReportList *reports, eReportType error_type, Object *ob, ModifierData *md)
static wmOperatorStatus modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
static wmOperatorStatus meshdeform_bind_exec(bContext *C, wmOperator *op)
static wmOperatorStatus modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus time_modifier_segment_add_exec(bContext *C, wmOperator *op)
void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
static wmOperatorStatus modifiers_clear_exec(bContext *C, wmOperator *)
static void object_force_modifier_bind_simple_options(Depsgraph *depsgraph, Object *object, ModifierData *md)
bool multires_update_totlevels(Object *ob, void *totlevel_v)
void OBJECT_OT_explode_refresh(wmOperatorType *ot)
void OBJECT_OT_ocean_bake(wmOperatorType *ot)
void OBJECT_OT_skin_root_mark(wmOperatorType *ot)
static wmOperatorStatus skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
static bool apply_grease_pencil_for_modifier(Depsgraph *depsgraph, Object *ob, GreasePencil &grease_pencil_orig, ModifierData *md_eval)
static wmOperatorStatus modifier_copy_to_selected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *)
static bool edit_modifier_liboverride_allowed_poll(bContext *C)
static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
static wmOperatorStatus time_modifier_segment_remove_exec(bContext *C, wmOperator *op)
static bool modifier_apply_as_shapekey_poll(bContext *C)
static wmOperatorStatus time_modifier_segment_remove_invoke(bContext *C, wmOperator *op, const wmEvent *)
void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
static bool surfacedeform_bind_poll(bContext *C)
void OBJECT_OT_modifier_remove(wmOperatorType *ot)
static wmOperatorStatus surfacedeform_bind_exec(bContext *C, wmOperator *op)
void OBJECT_OT_grease_pencil_dash_modifier_segment_remove(wmOperatorType *ot)
static wmOperatorStatus dash_modifier_segment_move_invoke(bContext *C, wmOperator *op, const wmEvent *)
void OBJECT_OT_modifier_apply(wmOperatorType *ot)
static void oceanbake_update(void *customdata, float progress, int *cancel)
bool edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag, bool is_editmode_allowed, bool is_liboverride_allowed)
static void dash_modifier_segment_free(GreasePencilDashModifierSegment *)
static Mesh * create_applied_mesh_for_modifier(Depsgraph *depsgraph, Scene *scene, Object *ob_eval, ModifierData *md_eval, const bool use_virtual_modifiers, const bool build_shapekey_layers, ReportList *reports)
void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot)
static bool modifier_apply_obdata(ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval, const bool do_all_keyframes)
static wmOperatorStatus modifier_remove_exec(bContext *C, wmOperator *op)
ModifierData * edit_modifier_property_get(wmOperator *op, Object *ob, int type)
static bool time_modifier_segment_poll(bContext *C)
static bool skin_edit_poll(bContext *C)
void OBJECT_OT_modifier_convert(wmOperatorType *ot)
void OBJECT_OT_grease_pencil_time_modifier_segment_move(wmOperatorType *ot)
bool modifier_copy(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
static bool edit_modifier_invoke_properties_with_hover(bContext *C, wmOperator *op, const wmEvent *event, wmOperatorStatus *r_retval)
static bool meshdeform_poll(bContext *C)
static bool apply_grease_pencil_for_modifier_all_keyframes(Depsgraph *depsgraph, Scene *scene, Object *ob, GreasePencil &grease_pencil_orig, ModifierData *md)
static bool modifiers_copy_to_selected_poll(bContext *C)
Object * context_active_object(const bContext *C)
static wmOperatorStatus object_modifiers_copy_exec(bContext *C, wmOperator *op)
static bool modifiers_clear_poll(bContext *C)
bool modifier_move_down(ReportList *reports, eReportType error_type, Object *ob, ModifierData *md)
static wmOperatorStatus time_modifier_segment_move_exec(bContext *C, wmOperator *op)
static wmOperatorStatus modifier_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src)
static wmOperatorStatus modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static Object * modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob)
static wmOperatorStatus explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *)
void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
static wmOperatorStatus correctivesmooth_bind_exec(bContext *C, wmOperator *op)
void OBJECT_OT_geometry_nodes_input_attribute_toggle(wmOperatorType *ot)
void OBJECT_OT_modifiers_copy_to_selected(wmOperatorType *ot)
static wmOperatorStatus dash_modifier_segment_remove_invoke(bContext *C, wmOperator *op, const wmEvent *)
static bool laplaciandeform_poll(bContext *C)
static wmOperatorStatus skin_root_mark_exec(bContext *C, wmOperator *)
static bool object_modifier_check_move_before(ReportList *reports, eReportType error_type, ModifierData *md, ModifierData *md_prev)
static wmOperatorStatus surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus skin_armature_create_exec(bContext *C, wmOperator *op)
static bool skin_poll(bContext *C)
static void oceanbake_free(void *customdata)
static wmOperatorStatus modifier_convert_exec(bContext *C, wmOperator *op)
void OBJECT_OT_correctivesmooth_bind(wmOperatorType *ot)
static wmOperatorStatus modifier_move_down_exec(bContext *C, wmOperator *op)
void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
static bool modifier_apply_poll(bContext *C)
bool convert_psys_to_mesh(ReportList *reports, Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, Object *ob, ModifierData *md)
bool modifier_move_to_index(ReportList *reports, eReportType error_type, Object *ob, ModifierData *md, int index, bool allow_partial)
void OBJECT_OT_modifier_add(wmOperatorType *ot)
static wmOperatorStatus explode_refresh_exec(bContext *C, wmOperator *op)
static wmOperatorStatus modifier_move_to_index_exec(bContext *C, wmOperator *op)
void OBJECT_OT_modifier_copy(wmOperatorType *ot)
void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
static wmOperatorStatus dash_modifier_segment_add_invoke(bContext *C, wmOperator *op, const wmEvent *)
static bool object_has_modifier(const Object *ob, const ModifierData *exclude, ModifierType type)
void vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight, int assignmode)
static wmOperatorStatus dash_modifier_segment_move_exec(bContext *C, wmOperator *op)
static wmOperatorStatus geometry_node_tree_copy_assign_exec(bContext *C, wmOperator *)
void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
static bool object_has_modifier_cb(Object *ob, void *data)
static bool dash_modifier_segment_poll(bContext *C)
void OBJECT_OT_modifier_copy_to_selected(wmOperatorType *ot)
void OBJECT_OT_modifier_set_active(wmOperatorType *ot)
static void time_modifier_segment_free(GreasePencilTimeModifierSegment *)
static wmOperatorStatus ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus time_modifier_segment_move_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void OBJECT_OT_modifiers_clear(wmOperatorType *ot)
static wmOperatorStatus modifier_copy_exec(bContext *C, wmOperator *op)
static bool modifier_copy_to_selected_poll(bContext *C)
void OBJECT_OT_grease_pencil_time_modifier_segment_remove(wmOperatorType *ot)
Vector< PointerRNA > modifier_get_edit_objects(const bContext &C, const wmOperator &op)
void modifier_link(bContext *C, Object *ob_dst, Object *ob_src)
static CLG_LogRef LOG
void modifiers_clear(Main *bmain, Scene *scene, Object *ob)
void OBJECT_OT_grease_pencil_time_modifier_segment_add(wmOperatorType *ot)
void OBJECT_OT_grease_pencil_dash_modifier_segment_move(wmOperatorType *ot)
static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *ob)
static wmOperatorStatus modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void edit_modifier_properties(wmOperatorType *ot)
static void modifier_skin_customdata_delete(Object *ob)
void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
static bool explode_poll(bContext *C)
static wmOperatorStatus ocean_bake_exec(bContext *C, wmOperator *op)
bool modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
static wmOperatorStatus modifier_set_active_invoke(bContext *C, wmOperator *op, const wmEvent *event)
VecBase< int32_t, 2 > int2
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
bool RNA_pointer_is_null(const PointerRNA *ptr)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
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_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
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)
const EnumPropertyItem rna_enum_object_modifier_type_items[]
void * data
BMHeader head
CorrectiveSmoothDeltaCache delta_cache
ListBase nurb
CurvesGeometry geometry
CustomDataLayer * layers
char name[64]
float tail[3]
EditBone * parent
float rad_tail
float rad_head
float head[3]
const char * identifier
Definition RNA_types.hh:623
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
static GeometrySet from_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
bool has_grease_pencil() const
GreasePencilRuntimeHandle * runtime
char type
Definition DNA_ID.h:146
Definition DNA_ID.h:404
int us
Definition DNA_ID.h:425
short flag
Definition DNA_ID.h:420
void * next
Definition DNA_ID.h:407
char name[66]
Definition DNA_ID.h:415
char type
ListBase block
void * first
ListBase objects
Definition BKE_main.hh:247
void(* bindfunc)(struct Object *object, struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, int verts_num, float cagemat[4][4])
CustomData vert_data
struct Key * key
int verts_num
struct ModifierData * next
struct ModifierData * prev
void(* modify_geometry_set)(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
void(* deform_verts)(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
bool(* is_disabled)(const Scene *scene, ModifierData *md, bool use_render_params)
ModifierTypeFlag flags
ModifierTypeType type
Mesh *(* modify_mesh)(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
struct bNodeTree * node_group
struct NodesModifierSettings settings
struct IDProperty * properties
ListBase particlesystem
short base_flag
ObjectRuntimeHandle * runtime
ListBase modifiers
struct PartDeflect * pd
struct SoftBody * soft
float * time
Definition BKE_ocean.h:40
int duration
Definition BKE_ocean.h:50
struct OceanCache * oceancache
ParticleSettings * part
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
struct RenderData r
ListBase * edbo
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet from_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet from_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
wmEventModifierFlag modifier
Definition WM_types.hh:771
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
void WM_cursor_wait(bool val)
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4227
wmOperatorType * ot
Definition wm_files.cc:4226
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
Definition wm_jobs.cc:353
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:456
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, const eWM_JobFlag flag, const eWM_JobType job_type)
Definition wm_jobs.cc:190
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition wm_jobs.cc:365
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
Definition wm_jobs.cc:337
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
wmOperatorStatus WM_operator_confirm_ex(bContext *C, wmOperator *op, const char *title, const char *message, const char *confirm_text, int icon, bool cancel_default)
uint8_t flag
Definition wm_window.cc:139