Blender V5.0
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"
32#include "BLI_listbase.h"
33#include "BLI_string.h"
34#include "BLI_string_utf8.h"
35#include "BLI_string_utils.hh"
36#include "BLI_utildefines.h"
37
38#include "BKE_animsys.h"
40#include "BKE_armature.hh"
41#include "BKE_context.hh"
42#include "BKE_curve.hh"
43#include "BKE_curves.h"
44#include "BKE_curves.hh"
45#include "BKE_displist.h"
46#include "BKE_editmesh.hh"
47#include "BKE_effect.h"
48#include "BKE_geometry_set.hh"
49#include "BKE_global.hh"
50#include "BKE_grease_pencil.hh"
51#include "BKE_idprop.hh"
52#include "BKE_key.hh"
53#include "BKE_lattice.hh"
54#include "BKE_layer.hh"
55#include "BKE_lib_id.hh"
56#include "BKE_library.hh"
57#include "BKE_main.hh"
59#include "BKE_material.hh"
60#include "BKE_mball.hh"
61#include "BKE_mesh.hh"
62#include "BKE_mesh_mapping.hh"
63#include "BKE_mesh_runtime.hh"
64#include "BKE_modifier.hh"
65#include "BKE_multires.hh"
66#include "BKE_object.hh"
67#include "BKE_object_deform.h"
68#include "BKE_object_types.hh"
69#include "BKE_ocean.h"
70#include "BKE_paint.hh"
71#include "BKE_particle.h"
72#include "BKE_pointcloud.hh"
73#include "BKE_report.hh"
74#include "BKE_scene.hh"
75#include "BKE_softbody.h"
76#include "BKE_volume.hh"
77
78#include "BLT_translation.hh"
79
80#include "DEG_depsgraph.hh"
83
84#include "RNA_access.hh"
85#include "RNA_define.hh"
86#include "RNA_enum_types.hh"
87#include "RNA_prototypes.hh"
88
89#include "ED_armature.hh"
90#include "ED_grease_pencil.hh"
91#include "ED_node.hh"
92#include "ED_object.hh"
93#include "ED_object_vgroup.hh"
94#include "ED_screen.hh"
95
97
98#include "GEO_merge_layers.hh"
99
100#include "UI_interface.hh"
101
102#include "WM_api.hh"
103#include "WM_types.hh"
104
105#include "object_intern.hh"
106
107namespace blender::ed::object {
108
109static CLG_LogRef LOG = {"object"};
110
112
113/* ------------------------------------------------------------------- */
116
118{
120 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
121 BKE_object_eval_reset(ob_eval);
122 if (ob->type == OB_MESH) {
124 depsgraph, scene_eval, ob_eval, &CD_MASK_DERIVEDMESH);
125 BKE_id_free(nullptr, mesh_eval);
126 }
127 else if (ob->type == OB_LATTICE) {
128 BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval);
129 }
130 else if (ob->type == OB_MBALL) {
131 BKE_mball_data_update(depsgraph, scene_eval, ob_eval);
132 }
133 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
134 BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false);
135 }
136 else if (ob->type == OB_CURVES) {
137 BKE_curves_data_update(depsgraph, scene_eval, ob);
138 }
139 else if (ob->type == OB_POINTCLOUD) {
140 BKE_pointcloud_data_update(depsgraph, scene_eval, ob);
141 }
142 else if (ob->type == OB_VOLUME) {
143 BKE_volume_data_update(depsgraph, scene_eval, ob);
144 }
145}
146
148 Object *object,
149 ModifierData *md)
150{
151 ModifierData *md_eval = BKE_modifier_get_evaluated(depsgraph, object, md);
152 const int mode = md_eval->mode;
153 md_eval->mode |= eModifierMode_Realtime;
155 md_eval->mode = mode;
156}
157
159 ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
160{
161 ModifierData *new_md = nullptr;
163
164 /* Check compatibility of modifier [#25291, #50373]. */
166 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2);
167 return nullptr;
168 }
169
170 if (mti->flags & eModifierTypeFlag_Single) {
172 BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed");
173 return nullptr;
174 }
175 }
176
177 if (type == eModifierType_ParticleSystem) {
178 /* don't need to worry about the new modifier's name, since that is set to the number
179 * of particle systems which shouldn't have too many duplicates
180 */
181 new_md = object_add_particle_system(bmain, scene, ob, name);
182 }
183 else {
184 /* get new modifier data to add */
185 new_md = BKE_modifier_new(type);
186
187 ModifierData *next_md = nullptr;
189 if (md->flag & eModifierFlag_PinLast) {
190 next_md = md;
191 }
192 else {
193 break;
194 }
195 }
197 next_md = static_cast<ModifierData *>(ob->modifiers.first);
198
199 while (next_md && BKE_modifier_get_info((ModifierType)next_md->type)->type ==
201 {
202 if (next_md->next && (next_md->next->flag & eModifierFlag_PinLast) != 0) {
203 break;
204 }
205 next_md = next_md->next;
206 }
207 }
208 BLI_insertlinkbefore(&ob->modifiers, next_md, new_md);
210
211 if (name) {
212 STRNCPY_UTF8(new_md->name, name);
213 }
214
215 /* make sure modifier data has unique name */
216
218
219 /* special cases */
220 if (type == eModifierType_Softbody) {
221 if (!ob->soft) {
222 ob->soft = sbNew();
224 }
225 }
226 else if (type == eModifierType_Collision) {
227 if (!ob->pd) {
228 ob->pd = BKE_partdeflect_new(0);
229 }
230
231 ob->pd->deflect = 1;
232 }
233 else if (type == eModifierType_Surface) {
234 /* pass */
235 }
236 else if (type == eModifierType_Multires) {
237 /* set totlvl from existing MDISPS layer if object already had it */
239
240 if (ob->mode & OB_MODE_SCULPT) {
241 /* ensure that grid paint mask layer is created */
242 BKE_sculpt_mask_layers_ensure(nullptr, nullptr, ob, (MultiresModifierData *)new_md);
243 }
244 }
245 else if (type == eModifierType_Skin) {
246 /* ensure skin-node customdata exists */
247 BKE_mesh_ensure_skin_customdata(static_cast<Mesh *>(ob->data));
248 }
249 }
250
252
255
256 return new_md;
257}
258
259/* Return true if the object has a modifier of type 'type' other than
260 * the modifier pointed to be 'exclude', otherwise returns false. */
261static bool object_has_modifier(const Object *ob, const ModifierData *exclude, ModifierType type)
262{
264 if ((md != exclude) && (md->type == type)) {
265 return true;
266 }
267 }
268
269 return false;
270}
271
272bool iter_other(Main *bmain,
273 Object *orig_ob,
274 const bool include_orig,
275 bool (*callback)(Object *ob, void *callback_data),
276 void *callback_data)
277{
278 ID *ob_data_id = static_cast<ID *>(orig_ob->data);
279 int users = ob_data_id->us;
280
281 if (ob_data_id->flag & ID_FLAG_FAKEUSER) {
282 users--;
283 }
284
285 /* First check that the object's data has multiple users */
286 if (users > 1) {
287 Object *ob;
288 int totfound = include_orig ? 0 : 1;
289
290 for (ob = static_cast<Object *>(bmain->objects.first); ob && totfound < users;
291 ob = reinterpret_cast<Object *>(ob->id.next))
292 {
293 if (((ob != orig_ob) || include_orig) && (ob->data == orig_ob->data)) {
294 if (callback(ob, callback_data)) {
295 return true;
296 }
297
298 totfound++;
299 }
300 }
301 }
302 else if (include_orig) {
303 return callback(orig_ob, callback_data);
304 }
305
306 return false;
307}
308
309static bool object_has_modifier_cb(Object *ob, void *data)
310{
311 ModifierType type = *((ModifierType *)data);
312
313 return object_has_modifier(ob, nullptr, type);
314}
315
316bool multires_update_totlevels(Object *ob, void *totlevel_v)
317{
318 int totlevel = *((char *)totlevel_v);
319
321 if (md->type == eModifierType_Multires) {
322 multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel);
324 }
325 }
326 return false;
327}
328
329/* Return true if no modifier of type 'type' other than 'exclude' */
331 Object *ob,
332 ModifierData *exclude,
333 ModifierType type)
334{
335 return (!object_has_modifier(ob, exclude, type) &&
336 !iter_other(bmain, ob, false, object_has_modifier_cb, &type));
337}
338
340 Main *bmain, Scene *scene, Object *ob, ModifierData *md, bool *r_sort_depsgraph)
341{
342 /* It seems on rapid delete it is possible to
343 * get called twice on same modifier, so make
344 * sure it is in list. */
345 if (BLI_findindex(&ob->modifiers, md) == -1) {
346 return false;
347 }
348
349 /* special cases */
351 object_remove_particle_system(bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
352 return true;
353 }
354
355 if (md->type == eModifierType_Softbody) {
356 if (ob->soft) {
357 sbFree(ob);
358 ob->softflag = 0; /* TODO(Sybren): this should probably be moved into sbFree() */
359 }
360 }
361 else if (md->type == eModifierType_Collision) {
362 if (ob->pd) {
363 ob->pd->deflect = 0;
364 }
365
366 *r_sort_depsgraph = true;
367 }
368 else if (md->type == eModifierType_Surface) {
369 *r_sort_depsgraph = true;
370 }
371 else if (md->type == eModifierType_Multires) {
372 /* Delete MDisps layer if not used by another multires modifier */
374 multires_customdata_delete(static_cast<Mesh *>(ob->data));
375 }
376 }
377 else if (md->type == eModifierType_Skin) {
378 /* Delete MVertSkin layer if not used by another skin modifier */
381 }
382 }
383
386 {
388 }
389
390 BKE_animdata_drivers_remove_for_rna_struct(ob->id, RNA_Modifier, md);
391
395
396 return true;
397}
398
399bool modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
400{
401 bool sort_depsgraph = false;
402
403 bool ok = object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
404
405 if (!ok) {
406 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
407 return false;
408 }
409
412
413 return true;
414}
415
416void modifiers_clear(Main *bmain, Scene *scene, Object *ob)
417{
418 ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
419 bool sort_depsgraph = false;
420
421 if (!md) {
422 return;
423 }
424
425 while (md) {
426 ModifierData *next_md = md->next;
427
428 object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
429
430 md = next_md;
431 }
432
435}
436
438 eReportType error_type,
439 ModifierData *md,
440 ModifierData *md_prev)
441{
442 if (md_prev) {
443 if (md->flag & eModifierFlag_PinLast && !(md_prev->flag & eModifierFlag_PinLast)) {
444 return false;
445 }
447
450
452 BKE_report(reports, error_type, "Cannot move above a modifier requiring original data");
453 return false;
454 }
455 }
456 }
457 else {
458 BKE_report(reports, error_type, "Cannot move modifier beyond the start of the list");
459 return false;
460 }
461
462 return true;
463}
464
465bool modifier_move_up(ReportList *reports, eReportType error_type, Object *ob, ModifierData *md)
466{
467 if (object_modifier_check_move_before(reports, error_type, md, md->prev)) {
469 return true;
470 }
471
472 return false;
473}
474
476 eReportType error_type,
477 ModifierData *md,
478 ModifierData *md_next)
479{
480 if (md_next) {
481 if (md_next->flag & eModifierFlag_PinLast && !(md->flag & eModifierFlag_PinLast)) {
482 return false;
483 }
485
488
489 if (nmti->type != ModifierTypeType::OnlyDeform) {
490 BKE_report(reports, error_type, "Cannot move beyond a non-deforming modifier");
491 return false;
492 }
493 }
494 }
495 else {
496 BKE_report(reports, error_type, "Cannot move modifier beyond the end of the list");
497 return false;
498 }
499
500 return true;
501}
502
503bool modifier_move_down(ReportList *reports, eReportType error_type, Object *ob, ModifierData *md)
504{
505 if (object_modifier_check_move_after(reports, error_type, md, md->next)) {
507 return true;
508 }
509
510 return false;
511}
512
514 eReportType error_type,
515 Object *ob,
516 ModifierData *md,
517 const int index,
518 bool allow_partial)
519{
520 BLI_assert(md != nullptr);
521
522 if (index < 0 || index >= BLI_listbase_count(&ob->modifiers)) {
523 BKE_report(reports, error_type, "Cannot move modifier beyond the end of the stack");
524 return false;
525 }
526
527 int md_index = BLI_findindex(&ob->modifiers, md);
528 BLI_assert(md_index != -1);
529
530 if (md_index < index) {
531 /* Move modifier down in list. */
532 ModifierData *md_target = md;
533
534 for (; md_index < index; md_index++, md_target = md_target->next) {
535 if (!object_modifier_check_move_after(reports, error_type, md, md_target->next)) {
536 if (!allow_partial || md == md_target) {
537 return false;
538 }
539
540 break;
541 }
542 }
543
544 BLI_assert(md != md_target && md_target);
545
546 BLI_remlink(&ob->modifiers, md);
547 BLI_insertlinkafter(&ob->modifiers, md_target, md);
548 }
549 else if (md_index > index) {
550 /* Move modifier up in list. */
551 ModifierData *md_target = md;
552
553 for (; md_index > index; md_index--, md_target = md_target->prev) {
554 if (!object_modifier_check_move_before(reports, error_type, md, md_target->prev)) {
555 if (!allow_partial || md == md_target) {
556 return false;
557 }
558
559 break;
560 }
561 }
562
563 BLI_assert(md != md_target && md_target);
564
565 BLI_remlink(&ob->modifiers, md);
566 BLI_insertlinkbefore(&ob->modifiers, md_target, md);
567 }
568 else {
569 return true;
570 }
571
572 /* NOTE: Dependency graph only uses modifier nodes for visibility updates, and exact order of
573 * modifier nodes in the graph does not matter. */
574
577
578 return true;
579}
580
590
592 const Scene *scene,
593 const Object *ob_src,
594 const ModifierData *md,
595 Object *ob_dst,
596 ReportList *reports)
597{
599
600 BLI_assert(ob_src != ob_dst);
601
602 /* Checked in #BKE_object_copy_modifier, but check here too so we can give a better message. */
604 BKE_reportf(reports,
606 "Object '%s' does not support %s modifiers",
607 ob_dst->id.name + 2,
608 RPT_(mti->name));
609 return false;
610 }
611
612 if (mti->flags & eModifierTypeFlag_Single) {
613 if (BKE_modifiers_findby_type(ob_dst, (ModifierType)md->type)) {
614 BKE_reportf(reports,
616 "Modifier can only be added once to object '%s'",
617 ob_dst->id.name + 2);
618 return false;
619 }
620 }
621
622 if (!BKE_object_copy_modifier(bmain, scene, ob_dst, ob_src, md)) {
623 BKE_reportf(reports,
624 RPT_ERROR,
625 "Copying modifier '%s' to object '%s' failed",
626 md->name,
627 ob_dst->id.name + 2);
628 return false;
629 }
630
634 return true;
635}
636
638 Main *bmain,
639 Depsgraph *depsgraph,
640 Scene *scene,
641 ViewLayer *view_layer,
642 Object *ob,
643 ModifierData *md)
644{
645 int cvert = 0;
646
648 return false;
649 }
650 if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) {
651 return false;
652 }
653
654 ParticleSystem *psys_orig = ((ParticleSystemModifierData *)md)->psys;
655 ParticleSettings *part = psys_orig->part;
656
657 if (part->ren_as != PART_DRAW_PATH) {
658 return false;
659 }
660 ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys_orig);
661 if (psys_eval->pathcache == nullptr) {
662 return false;
663 }
664
665 int part_num = psys_eval->totcached;
666 int child_num = psys_eval->totchildcache;
667
668 if (child_num && (part->draw & PART_DRAW_PARENT) == 0) {
669 part_num = 0;
670 }
671
672 /* count */
673 int verts_num = 0, edges_num = 0;
674 ParticleCacheKey **cache = psys_eval->pathcache;
675 for (int a = 0; a < part_num; a++) {
676 ParticleCacheKey *key = cache[a];
677
678 if (key->segments > 0) {
679 verts_num += key->segments + 1;
680 edges_num += key->segments;
681 }
682 }
683
684 cache = psys_eval->childcache;
685 for (int a = 0; a < child_num; a++) {
686 ParticleCacheKey *key = cache[a];
687
688 if (key->segments > 0) {
689 verts_num += key->segments + 1;
690 edges_num += key->segments;
691 }
692 }
693
694 if (verts_num == 0) {
695 return false;
696 }
697
698 Mesh *mesh = BKE_mesh_new_nomain(verts_num, edges_num, 0, 0);
699 MutableSpan<float3> positions = mesh->vert_positions_for_write();
700 MutableSpan<int2> edges = mesh->edges_for_write();
701
702 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
704 ".select_vert", bke::AttrDomain::Point);
705
706 int edge_index = 0;
707
708 /* copy coordinates */
709 int vert_index = 0;
710 cache = psys_eval->pathcache;
711 for (int a = 0; a < part_num; a++) {
712 ParticleCacheKey *key = cache[a];
713 int kmax = key->segments;
714 for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) {
715 positions[vert_index] = key->co;
716 if (k) {
717 edges[edge_index] = int2(cvert - 1, cvert);
718 edge_index++;
719 }
720 else {
721 /* cheap trick to select the roots */
722 select_vert.span[vert_index] = true;
723 }
724 }
725 }
726
727 cache = psys_eval->childcache;
728 for (int a = 0; a < child_num; a++) {
729 ParticleCacheKey *key = cache[a];
730 int kmax = key->segments;
731 for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) {
732 copy_v3_v3(positions[vert_index], key->co);
733 if (k) {
734 edges[edge_index] = int2(cvert - 1, cvert);
735 edge_index++;
736 }
737 else {
738 /* cheap trick to select the roots */
739 select_vert.span[vert_index] = true;
740 }
741 }
742 }
743
744 select_vert.finish();
745
746 Object *obn = BKE_object_add(bmain, scene, view_layer, OB_MESH, nullptr);
747 BKE_mesh_nomain_to_mesh(mesh, static_cast<Mesh *>(obn->data), obn);
748
750
751 return true;
752}
753
754static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src)
755{
756 if (!mesh_src.key) {
757 return;
758 }
759 int i;
760 LISTBASE_FOREACH_INDEX (const KeyBlock *, kb, &mesh_src.key->block, i) {
761 void *array;
762 if (mesh_src.verts_num != kb->totelem) {
764 "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)",
765 mesh_src.id.name + 2,
766 mesh_src.verts_num,
767 kb->name,
768 kb->totelem);
769 array = MEM_calloc_arrayN<float[3]>(mesh_src.verts_num, __func__);
770 }
771 else {
772 array = MEM_malloc_arrayN<float[3]>(size_t(mesh_src.verts_num), __func__);
773 memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src.verts_num));
774 }
775
777 &mesh_dest.vert_data, CD_SHAPEKEY, array, mesh_dest.verts_num, nullptr);
778 const int ci = CustomData_get_layer_index_n(&mesh_dest.vert_data, CD_SHAPEKEY, i);
779
780 mesh_dest.vert_data.layers[ci].uid = kb->uid;
781 }
782}
783
790 Scene *scene,
791 Object *ob_eval,
792 ModifierData *md_eval,
793 const bool use_virtual_modifiers,
794 const bool build_shapekey_layers,
795 ReportList *reports)
796{
797 Mesh *mesh = ob_eval->runtime->data_orig ?
798 reinterpret_cast<Mesh *>(ob_eval->runtime->data_orig) :
799 reinterpret_cast<Mesh *>(ob_eval->data);
801 const ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_ORIGINAL};
802
803 if (!(md_eval->mode & eModifierMode_Realtime)) {
804 return nullptr;
805 }
806
807 if (mti->is_disabled && mti->is_disabled(scene, md_eval, false)) {
808 return nullptr;
809 }
810
811 if (build_shapekey_layers && mesh->key) {
812 if (KeyBlock *kb = static_cast<KeyBlock *>(
813 BLI_findlink(&mesh->key->block, ob_eval->shapenr - 1)))
814 {
815 BKE_keyblock_convert_to_mesh(kb, mesh->vert_positions_for_write());
816 }
817 }
818
819 Mesh *mesh_temp = reinterpret_cast<Mesh *>(
820 BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE));
821 MutableSpan<float3> deformedVerts = mesh_temp->vert_positions_for_write();
822
823 if (use_virtual_modifiers) {
824 VirtualModifierData virtual_modifier_data;
825 for (ModifierData *md_eval_virt =
826 BKE_modifiers_get_virtual_modifierlist(ob_eval, &virtual_modifier_data);
827 md_eval_virt && (md_eval_virt != ob_eval->modifiers.first);
828 md_eval_virt = md_eval_virt->next)
829 {
830 if (!BKE_modifier_is_enabled(scene, md_eval_virt, eModifierMode_Realtime)) {
831 continue;
832 }
833 /* All virtual modifiers are deform modifiers. */
834 const ModifierTypeInfo *mti_virt = BKE_modifier_get_info(ModifierType(md_eval_virt->type));
836 if (mti_virt->type != ModifierTypeType::OnlyDeform) {
837 continue;
838 }
839
840 mti_virt->deform_verts(md_eval_virt, &mectx, mesh_temp, deformedVerts);
841 }
842 }
843
844 Mesh *result = nullptr;
846 result = mesh_temp;
847 mti->deform_verts(md_eval, &mectx, result, deformedVerts);
848 result->tag_positions_changed();
849
850 if (build_shapekey_layers) {
852 }
853 }
854 else {
855 if (build_shapekey_layers) {
856 add_shapekey_layers(*mesh_temp, *mesh);
857 }
858
859 if (mti->modify_geometry_set) {
862 mti->modify_geometry_set(md_eval, &mectx, &geometry_set);
863 if (!geometry_set.has_mesh()) {
864 BKE_report(reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a mesh");
865 return nullptr;
866 }
867 result = geometry_set.get_component_for_write<bke::MeshComponent>().release();
868 }
869 else {
870 result = mti->modify_mesh(md_eval, &mectx, mesh_temp);
871 if (mesh_temp != result) {
872 BKE_id_free(nullptr, mesh_temp);
873 }
874 }
875 }
876
877 return result;
878}
879
880static bool modifier_apply_shape(Main *bmain,
881 ReportList *reports,
882 Depsgraph *depsgraph,
883 Scene *scene,
884 Object *ob,
885 ModifierData *md_eval)
886{
888
889 if (mti->is_disabled && mti->is_disabled(scene, md_eval, false)) {
890 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
891 return false;
892 }
893
894 /* We could investigate using the #CD_ORIGINDEX layer
895 * to support other kinds of modifiers besides deforming modifiers.
896 * as this is done in many other places, see: #BKE_mesh_foreach_mapped_vert_coords_get.
897 *
898 * This isn't high priority in practice since most modifiers users
899 * want to apply as a shape are deforming modifiers.
900 *
901 * If a compelling use-case comes up where we want to support other kinds of modifiers
902 * we can look into supporting them. */
903
904 if (ob->type == OB_MESH) {
905 Mesh *mesh = static_cast<Mesh *>(ob->data);
906 Key *key = mesh->key;
907
909 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
910 return false;
911 }
912
916 md_eval,
917 true,
918 false,
919 reports);
920 if (!mesh_applied) {
921 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
922 return false;
923 }
924
925 if (key == nullptr) {
926 key = mesh->key = BKE_key_add(bmain, (ID *)mesh);
927 key->type = KEY_RELATIVE;
928 /* if that was the first key block added, then it was the basis.
929 * Initialize it with the mesh, and add another for the modifier */
930 KeyBlock *kb = BKE_keyblock_add(key, nullptr);
932 }
933
934 KeyBlock *kb = BKE_keyblock_add(key, md_eval->name);
935 BKE_mesh_nomain_to_meshkey(mesh_applied, mesh, kb);
936
937 BKE_id_free(nullptr, mesh_applied);
938 }
939 else {
940 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
941 return false;
942 }
943 return true;
944}
945
947 Object *ob,
948 GreasePencil &grease_pencil_orig,
949 ModifierData *md_eval)
950{
951 using namespace bke;
952 using namespace bke::greasepencil;
954 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
955 GreasePencil *grease_pencil_for_eval = ob_eval->runtime->data_orig ?
956 reinterpret_cast<GreasePencil *>(
957 ob_eval->runtime->data_orig) :
958 &grease_pencil_orig;
959 const int eval_frame = int(DEG_get_ctime(depsgraph));
960 GreasePencil *grease_pencil_temp = reinterpret_cast<GreasePencil *>(
961 BKE_id_copy_ex(nullptr, &grease_pencil_for_eval->id, nullptr, LIB_ID_COPY_LOCALIZE));
962 grease_pencil_temp->runtime->eval_frame = eval_frame;
963 GeometrySet eval_geometry_set = GeometrySet::from_grease_pencil(grease_pencil_temp,
964 GeometryOwnershipType::Owned);
965
967 mti->modify_geometry_set(md_eval, &mectx, &eval_geometry_set);
968 if (!eval_geometry_set.has_grease_pencil()) {
969
970 return false;
971 }
972 GreasePencil &grease_pencil_result =
973 *eval_geometry_set.get_component_for_write<GreasePencilComponent>().get_for_write();
974
976 eval_frame,
977 grease_pencil_orig.layers().index_range(),
978 grease_pencil_orig);
979
980 Main *bmain = DEG_get_bmain(depsgraph);
981 /* There might be layers with empty names after evaluation. Make sure to rename them. */
982 bke::greasepencil::ensure_non_empty_layer_names(*bmain, grease_pencil_result);
983 BKE_object_material_from_eval_data(bmain, ob, &grease_pencil_result.id);
984 return true;
985}
986
988 Scene *scene,
989 Object *ob,
990 GreasePencil &grease_pencil_orig,
991 ModifierData *md)
992{
993 using namespace bke;
994 using namespace bke::greasepencil;
995 Main *bmain = DEG_get_bmain(depsgraph);
996
998
999 WM_cursor_wait(true);
1000
1001 Map<int, Vector<int>> layer_indices_to_apply_per_frame;
1002 {
1003 for (const int layer_i : grease_pencil_orig.layers().index_range()) {
1004 const Layer &layer = grease_pencil_orig.layer(layer_i);
1005 for (const auto &[key, value] : layer.frames().items()) {
1006 if (value.is_end()) {
1007 continue;
1008 }
1009 layer_indices_to_apply_per_frame.lookup_or_add(key, {}).append(layer_i);
1010 }
1011 }
1012 }
1013
1014 Array<int> sorted_frame_times(layer_indices_to_apply_per_frame.size());
1015 int i = 0;
1016 for (const int key : layer_indices_to_apply_per_frame.keys()) {
1017 sorted_frame_times[i++] = key;
1018 }
1019 std::sort(sorted_frame_times.begin(), sorted_frame_times.end());
1020
1021 const int prev_frame = int(DEG_get_ctime(depsgraph));
1022 bool changed = false;
1023 for (const int eval_frame : sorted_frame_times) {
1024 const Span<int> layer_indices = layer_indices_to_apply_per_frame.lookup(eval_frame).as_span();
1025 scene->r.cfra = eval_frame;
1027
1028 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
1029 GreasePencil *grease_pencil_for_eval = ob_eval->runtime->data_orig ?
1030 reinterpret_cast<GreasePencil *>(
1031 ob_eval->runtime->data_orig) :
1032 &grease_pencil_orig;
1033
1034 GreasePencil *grease_pencil_temp = reinterpret_cast<GreasePencil *>(
1035 BKE_id_copy_ex(nullptr, &grease_pencil_for_eval->id, nullptr, LIB_ID_COPY_LOCALIZE));
1036 grease_pencil_temp->runtime->eval_frame = eval_frame;
1037 GeometrySet eval_geometry_set = GeometrySet::from_grease_pencil(grease_pencil_temp,
1038 GeometryOwnershipType::Owned);
1039
1042 mti->modify_geometry_set(md_eval, &mectx, &eval_geometry_set);
1043 if (!eval_geometry_set.has_grease_pencil()) {
1044 continue;
1045 }
1046 GreasePencil &grease_pencil_result =
1047 *eval_geometry_set.get_component_for_write<GreasePencilComponent>().get_for_write();
1048
1049 IndexMaskMemory memory;
1050 const IndexMask orig_layers_to_apply = IndexMask::from_indices(layer_indices, memory);
1052 grease_pencil_result, eval_frame, orig_layers_to_apply, grease_pencil_orig);
1053
1054 BKE_object_material_from_eval_data(bmain, ob, &grease_pencil_result.id);
1055 changed = true;
1056 }
1057
1058 scene->r.cfra = prev_frame;
1060
1061 /* There might be layers with empty names after evaluation. Make sure to rename them. */
1062 bke::greasepencil::ensure_non_empty_layer_names(*bmain, grease_pencil_orig);
1063
1064 WM_cursor_wait(false);
1065 return changed;
1066}
1067
1069 Depsgraph *depsgraph,
1070 Scene *scene,
1071 Object *ob,
1072 ModifierData *md_eval,
1073 const bool do_all_keyframes)
1074{
1076
1077 if (mti->is_disabled && mti->is_disabled(scene, md_eval, false)) {
1078 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
1079 return false;
1080 }
1081
1082 if (ob->type == OB_MESH) {
1083 Mesh *mesh = static_cast<Mesh *>(ob->data);
1085
1086 if (mesh->key && mti->type != ModifierTypeType::NonGeometrical) {
1087 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to a mesh with shape keys");
1088 return false;
1089 }
1090
1091 /* Multires: ensure that recent sculpting is applied */
1092 if (md_eval->type == eModifierType_Multires) {
1094 }
1095
1096 if (mmd && mmd->totlvl &&
1098 {
1099 if (!multiresModifier_reshapeFromDeformModifier(depsgraph, ob, mmd, md_eval)) {
1100 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
1101 return false;
1102 }
1103 }
1104 else {
1105 Mesh *mesh_applied = create_applied_mesh_for_modifier(
1106 depsgraph,
1109 md_eval,
1110 /* It's important not to apply virtual modifiers (e.g. shape-keys) because they're kept,
1111 * causing them to be applied twice, see: #97758. */
1112 false,
1113 true,
1114 reports);
1115 if (!mesh_applied) {
1116 return false;
1117 }
1118
1119 Main *bmain = DEG_get_bmain(depsgraph);
1120 BKE_object_material_from_eval_data(bmain, ob, &mesh_applied->id);
1121 BKE_mesh_nomain_to_mesh(mesh_applied, mesh, ob);
1122
1123 /* Anonymous attributes shouldn't be available on the applied geometry. */
1124 mesh->attributes_for_write().remove_anonymous();
1125
1126 /* Remove strings referring to attributes if they no longer exist. */
1128
1129 if (md_eval->type == eModifierType_Multires) {
1131 }
1132 }
1133 }
1134 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
1135 Object *object_eval = DEG_get_evaluated(depsgraph, ob);
1136 Curve *curve = static_cast<Curve *>(ob->data);
1137 Curve *curve_eval = static_cast<Curve *>(object_eval->data);
1138 ModifierEvalContext mectx = {depsgraph, object_eval, MOD_APPLY_TO_ORIGINAL};
1139
1141 BKE_report(
1142 reports,
1143 RPT_ERROR,
1144 "Cannot apply constructive modifiers on curve. Convert curve to mesh in order to apply");
1145 return false;
1146 }
1147
1148 BKE_report(reports,
1149 RPT_INFO,
1150 "Applied modifier only changed CV points, not tessellated/bevel vertices");
1151
1152 Array<float3> vertexCos = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb);
1153 mti->deform_verts(md_eval, &mectx, nullptr, vertexCos);
1154 BKE_curve_nurbs_vert_coords_apply(&curve->nurb, vertexCos, false);
1155
1157 }
1158 else if (ob->type == OB_LATTICE) {
1159 Object *object_eval = DEG_get_evaluated(depsgraph, ob);
1160 Lattice *lattice = static_cast<Lattice *>(ob->data);
1161 ModifierEvalContext mectx = {depsgraph, object_eval, MOD_APPLY_TO_ORIGINAL};
1162
1164 BKE_report(reports, RPT_ERROR, "Constructive modifiers cannot be applied");
1165 return false;
1166 }
1167
1168 Array<float3> positions = BKE_lattice_vert_coords_alloc(lattice);
1169 mti->deform_verts(md_eval, &mectx, nullptr, positions);
1170 BKE_lattice_vert_coords_apply(lattice, positions);
1171
1173 }
1174 else if (ob->type == OB_CURVES) {
1175 Curves &curves = *static_cast<Curves *>(ob->data);
1176 if (mti->modify_geometry_set == nullptr) {
1178 return false;
1179 }
1180
1183
1185 mti->modify_geometry_set(md_eval, &mectx, &geometry_set);
1186 if (!geometry_set.has_curves()) {
1187 BKE_report(reports, RPT_ERROR, "Evaluated geometry from modifier does not contain curves");
1188 return false;
1189 }
1190 Curves &curves_eval = *geometry_set.get_curves_for_write();
1191
1192 /* Anonymous attributes shouldn't be available on original geometry. */
1193 curves_eval.geometry.wrap().attributes_for_write().remove_anonymous();
1194
1195 curves.geometry.wrap() = std::move(curves_eval.geometry.wrap());
1196 Main *bmain = DEG_get_bmain(depsgraph);
1197 BKE_object_material_from_eval_data(bmain, ob, &curves_eval.id);
1198 }
1199 else if (ob->type == OB_POINTCLOUD) {
1200 PointCloud &points = *static_cast<PointCloud *>(ob->data);
1201 if (mti->modify_geometry_set == nullptr) {
1203 return false;
1204 }
1205
1208
1210 mti->modify_geometry_set(md_eval, &mectx, &geometry_set);
1211 if (!geometry_set.has_pointcloud()) {
1212 BKE_report(
1213 reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a point cloud");
1214 return false;
1215 }
1216 PointCloud *pointcloud_eval =
1217 geometry_set.get_component_for_write<bke::PointCloudComponent>().release();
1218
1219 /* Anonymous attributes shouldn't be available on original geometry. */
1220 pointcloud_eval->attributes_for_write().remove_anonymous();
1221
1222 Main *bmain = DEG_get_bmain(depsgraph);
1223 BKE_object_material_from_eval_data(bmain, ob, &pointcloud_eval->id);
1224 BKE_pointcloud_nomain_to_pointcloud(pointcloud_eval, &points);
1225 }
1226 else if (ob->type == OB_GREASE_PENCIL) {
1227 if (mti->modify_geometry_set == nullptr) {
1228 BKE_report(reports, RPT_ERROR, "Cannot apply this modifier to Grease Pencil geometry");
1229 return false;
1230 }
1231 GreasePencil &grease_pencil_orig = *static_cast<GreasePencil *>(ob->data);
1232 bool success = false;
1233 if (do_all_keyframes) {
1234 /* The function #apply_grease_pencil_for_modifier_all_keyframes will retrieve
1235 * the evaluated modifier for each keyframe. The original modifier is passed
1236 * to ensure the evaluated modifier is not used, as it will be invalid when
1237 * the scene graph is updated for the next keyframe. */
1238 ModifierData *md = BKE_modifier_get_original(ob, md_eval);
1240 depsgraph, scene, ob, grease_pencil_orig, md);
1241 }
1242 else {
1243 success = apply_grease_pencil_for_modifier(depsgraph, ob, grease_pencil_orig, md_eval);
1244 }
1245 if (!success) {
1246 BKE_report(reports,
1247 RPT_ERROR,
1248 "Evaluated geometry from modifier does not contain Grease Pencil geometry");
1249 return false;
1250 }
1251 }
1252 else {
1253 /* TODO: implement for volumes. */
1254 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
1255 return false;
1256 }
1257
1258 /* lattice modifier can be applied to particle system too */
1259 if (ob->particlesystem.first) {
1261 if (psys->part->type != PART_HAIR) {
1262 continue;
1263 }
1264
1265 psys_apply_hair_lattice(depsgraph, scene, ob, psys);
1266 }
1267 }
1268
1269 return true;
1270}
1271
1273 ReportList *reports,
1274 Depsgraph *depsgraph,
1275 Scene *scene,
1276 Object *ob,
1277 ModifierData *md,
1278 int mode,
1279 bool keep_modifier,
1280 const bool do_all_keyframes)
1281{
1282 if (BKE_object_is_in_editmode(ob)) {
1283 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
1284 return false;
1285 }
1286 if (mode != MODIFIER_APPLY_SHAPE && ID_REAL_USERS(ob->data) > 1) {
1287 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
1288 return false;
1289 }
1290 if ((ob->mode & OB_MODE_SCULPT) && find_multires_modifier_before(scene, md) &&
1291 (BKE_modifier_is_same_topology(md) == false))
1292 {
1293 BKE_report(reports,
1294 RPT_ERROR,
1295 "Constructive modifier cannot be applied to multi-res data in sculpt mode");
1296 return false;
1297 }
1298
1299 if (md != ob->modifiers.first) {
1300 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
1301 }
1302
1303 /* Get evaluated modifier, so object links pointer to evaluated data,
1304 * but still use original object it is applied to the original mesh. */
1305 Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
1306 ModifierData *md_eval = (ob_eval) ? BKE_modifiers_findby_name(ob_eval, md->name) : md;
1307
1308 Depsgraph *apply_depsgraph = depsgraph;
1309 Depsgraph *local_depsgraph = nullptr;
1310
1311 /* If the object is hidden or the modifier is not enabled for the viewport is disabled a special
1312 * handling is required. This is because the viewport dependency graph optimizes out evaluation
1313 * of objects which are used by hidden objects and disabled modifiers.
1314 *
1315 * The idea is to create a dependency graph which does not perform those optimizations. */
1316 if ((ob_eval->base_flag & BASE_ENABLED_VIEWPORT) == 0 ||
1317 (md_eval->mode & eModifierMode_Realtime) == 0)
1318 {
1320
1321 local_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
1322 DEG_disable_visibility_optimization(local_depsgraph);
1323
1324 DEG_graph_build_from_ids(local_depsgraph, {&ob->id});
1325 DEG_evaluate_on_refresh(local_depsgraph);
1326
1327 apply_depsgraph = local_depsgraph;
1328
1329 /* The evaluated object and modifier are now from the different dependency graph. */
1330 ob_eval = DEG_get_evaluated(local_depsgraph, ob);
1331 md_eval = BKE_modifiers_findby_name(ob_eval, md->name);
1332
1333 /* Force mode on the evaluated modifier, enforcing the modifier evaluation in the apply()
1334 * functions. */
1335 md_eval->mode |= eModifierMode_Realtime;
1336 }
1337
1338 bool did_apply = false;
1339 if (mode == MODIFIER_APPLY_SHAPE) {
1340 did_apply = modifier_apply_shape(bmain, reports, apply_depsgraph, scene, ob, md_eval);
1341 }
1342 else {
1343 did_apply = modifier_apply_obdata(
1344 reports, apply_depsgraph, scene, ob, md_eval, do_all_keyframes);
1345 }
1346
1347 if (did_apply) {
1348 if (!keep_modifier) {
1351 }
1353 }
1354
1355 if (local_depsgraph != nullptr) {
1356 DEG_graph_free(local_depsgraph);
1357 }
1358
1359 return true;
1360}
1361
1363 ReportList * /*reports*/, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
1364{
1367 bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
1368 BLI_remlink(&ob->modifiers, nmd);
1369 BLI_insertlinkafter(&ob->modifiers, md, nmd);
1371 return true;
1372 }
1373
1375 BKE_modifier_copydata(md, nmd);
1376 BLI_insertlinkafter(&ob->modifiers, md, nmd);
1377 STRNCPY_UTF8(nmd->name, md->name);
1381
1383
1384 return true;
1385}
1386
1388
1390{
1391 Vector<PointerRNA> objects;
1392 if (RNA_boolean_get(op.ptr, "use_selected_objects")) {
1394 }
1395 else {
1396 if (Object *object = context_active_object(&C)) {
1397 objects.append(RNA_id_pointer_create(&object->id));
1398 }
1399 }
1400 return objects;
1401}
1402
1404{
1406 ot->srna,
1407 "use_selected_objects",
1408 false,
1409 "Selected Objects",
1410 "Affect all selected objects instead of just the active object");
1412}
1413
1414/* ------------------------------------------------------------------- */
1417
1419{
1420 Main *bmain = CTX_data_main(C);
1421 Scene *scene = CTX_data_scene(C);
1422 int type = RNA_enum_get(op->ptr, "type");
1423
1424 bool changed = false;
1425 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
1426 Object *ob = static_cast<Object *>(ptr.data);
1427 if (!modifier_add(op->reports, bmain, scene, ob, nullptr, type)) {
1428 continue;
1429 }
1430 changed = true;
1432 }
1433 if (!changed) {
1434 return OPERATOR_CANCELLED;
1435 }
1436
1437 return OPERATOR_FINISHED;
1438}
1439
1441{
1442 if (event->modifier & KM_ALT || CTX_wm_view3d(C)) {
1443 RNA_boolean_set(op->ptr, "use_selected_objects", true);
1444 }
1445 if (!RNA_struct_property_is_set(op->ptr, "type")) {
1446 return WM_menu_invoke(C, op, event);
1447 }
1448 return modifier_add_exec(C, op);
1449}
1450
1452 PointerRNA * /*ptr*/,
1453 PropertyRNA * /*prop*/,
1454 bool *r_free)
1455{
1457
1458 if (!ob) {
1460 }
1461
1462 EnumPropertyItem *items = nullptr;
1463 int totitem = 0;
1464
1465 const EnumPropertyItem *group_item = nullptr;
1466 for (int a = 0; rna_enum_object_modifier_type_items[a].identifier; a++) {
1468
1469 if (md_item->identifier[0]) {
1471
1473 continue;
1474 }
1475
1476 if (!BKE_object_support_modifier_type_check(ob, md_item->value)) {
1477 continue;
1478 }
1479 }
1480 else {
1481 group_item = md_item;
1482 continue;
1483 }
1484
1485 if (group_item) {
1486 RNA_enum_item_add(&items, &totitem, group_item);
1487 group_item = nullptr;
1488 }
1489
1490 RNA_enum_item_add(&items, &totitem, md_item);
1491 }
1492
1493 RNA_enum_item_end(&items, &totitem);
1494 *r_free = true;
1495
1496 return items;
1497}
1498
1500{
1501 PropertyRNA *prop;
1502
1503 /* identifiers */
1504 ot->name = "Add Modifier";
1505 ot->description = "Add a procedural operation/effect to the active object";
1506 ot->idname = "OBJECT_OT_modifier_add";
1507
1508 /* API callbacks. */
1509 ot->invoke = modifier_add_invoke;
1510 ot->exec = modifier_add_exec;
1512
1513 /* flags */
1514 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1515
1516 /* properties */
1517 prop = RNA_def_enum(
1520 ot->prop = prop;
1522}
1523
1525
1526/* ------------------------------------------------------------------- */
1531
1533 StructRNA *rna_type,
1534 int obtype_flag,
1535 const bool is_editmode_allowed,
1536 const bool is_liboverride_allowed)
1537{
1538 Main *bmain = CTX_data_main(C);
1539 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
1540 Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : context_active_object(C);
1541 ModifierData *mod = static_cast<ModifierData *>(ptr.data); /* May be nullptr. */
1542
1543 if (mod == nullptr && ob != nullptr) {
1545 }
1546
1547 if (!ob || !BKE_id_is_editable(bmain, &ob->id)) {
1548 return false;
1549 }
1550 if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) {
1551 return false;
1552 }
1553 if (ptr.owner_id && !BKE_id_is_editable(bmain, ptr.owner_id)) {
1554 return false;
1555 }
1556
1557 if (!is_liboverride_allowed && BKE_modifier_is_nonlocal_in_liboverride(ob, mod)) {
1559 C, "Cannot edit modifiers coming from linked data in a library override");
1560 return false;
1561 }
1562
1563 if (!is_editmode_allowed && CTX_data_edit_object(C) != nullptr) {
1564 CTX_wm_operator_poll_msg_set(C, "This modifier operation is not allowed from Edit mode");
1565 return false;
1566 }
1567
1568 return true;
1569}
1570
1572{
1573 return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true, false);
1574}
1575
1576/* Used by operators performing actions allowed also on modifiers from the overridden linked object
1577 * (not only from added 'local' ones). */
1579{
1580 return edit_modifier_poll_generic(C, &RNA_Modifier, 0, true, true);
1581}
1582
1584{
1586 ot->srna, "modifier", nullptr, MAX_NAME, "Modifier", "Name of the modifier to edit");
1588}
1589
1591{
1593 ot->srna, "report", false, "Report", "Create a notification after the operation");
1595}
1596
1598
1599/* ------------------------------------------------------------------- */
1604
1606{
1607 if (RNA_struct_property_is_set(op->ptr, "modifier")) {
1608 return true;
1609 }
1610
1611 PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1612 if (ctx_ptr.data != nullptr) {
1613 ModifierData *md = static_cast<ModifierData *>(ctx_ptr.data);
1614 RNA_string_set(op->ptr, "modifier", md->name);
1615 return true;
1616 }
1617
1618 return false;
1619}
1620
1627 wmOperator *op,
1628 const wmEvent *event,
1629 wmOperatorStatus *r_retval)
1630{
1631 if (RNA_struct_find_property(op->ptr, "use_selected_objects")) {
1632 if (event->modifier & KM_ALT) {
1633 RNA_boolean_set(op->ptr, "use_selected_objects", true);
1634 }
1635 }
1636
1637 if (RNA_struct_property_is_set(op->ptr, "modifier")) {
1638 return true;
1639 }
1640
1641 /* Note that the context pointer is *not* the active modifier, it is set in UI layouts. */
1642 PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1643 if (ctx_ptr.data != nullptr) {
1644 ModifierData *md = static_cast<ModifierData *>(ctx_ptr.data);
1645 RNA_string_set(op->ptr, "modifier", md->name);
1646 return true;
1647 }
1648
1650 if (panel_ptr == nullptr || RNA_pointer_is_null(panel_ptr)) {
1651 *r_retval = OPERATOR_CANCELLED;
1652 return false;
1653 }
1654
1655 if (!RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) {
1656 /* Work around multiple operators using the same shortcut. The operators for the other
1657 * stacks in the property editor use the same key, and will not run after these return
1658 * OPERATOR_CANCELLED. */
1660 return false;
1661 }
1662
1663 const ModifierData *md = static_cast<const ModifierData *>(panel_ptr->data);
1664 RNA_string_set(op->ptr, "modifier", md->name);
1665 return true;
1666}
1667
1669{
1670 char modifier_name[MAX_NAME];
1671 RNA_string_get(op->ptr, "modifier", modifier_name);
1672
1674
1675 if (md && type != 0 && md->type != type) {
1676 md = nullptr;
1677 }
1678
1679 return md;
1680}
1681
1683
1684/* ------------------------------------------------------------------- */
1687
1689{
1690 Main *bmain = CTX_data_main(C);
1691 Scene *scene = CTX_data_scene(C);
1692 ViewLayer *view_layer = CTX_data_view_layer(C);
1693
1694 char name[MAX_NAME];
1695 RNA_string_get(op->ptr, "modifier", name);
1696
1697 bool changed = false;
1698 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
1699 Object *ob = static_cast<Object *>(ptr.data);
1701 if (md == nullptr) {
1702 continue;
1703 }
1704
1705 int mode_orig = ob->mode;
1706 if (!modifier_remove(op->reports, bmain, scene, ob, md)) {
1707 continue;
1708 }
1709
1710 changed = true;
1711
1713
1714 /* if cloth/softbody was removed, particle mode could be cleared */
1715 if (mode_orig & OB_MODE_PARTICLE_EDIT) {
1716 if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
1717 BKE_view_layer_synced_ensure(scene, view_layer);
1718 if (ob == BKE_view_layer_active_object_get(view_layer)) {
1720 }
1721 }
1722 }
1723 }
1724
1725 if (!changed) {
1726 return OPERATOR_CANCELLED;
1727 }
1728
1729 if (RNA_boolean_get(op->ptr, "report")) {
1730 BKE_reportf(op->reports, RPT_INFO, "Removed modifier: %s", name);
1731 }
1732
1733 return OPERATOR_FINISHED;
1734}
1735
1737{
1738 wmOperatorStatus retval;
1739 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1740 return modifier_remove_exec(C, op);
1741 }
1742 return retval;
1743}
1744
1746{
1747 ot->name = "Remove Modifier";
1748 ot->description = "Remove a modifier from the active object";
1749 ot->idname = "OBJECT_OT_modifier_remove";
1750
1751 ot->invoke = modifier_remove_invoke;
1752 ot->exec = modifier_remove_exec;
1753 ot->poll = edit_modifier_poll;
1754
1755 /* flags */
1760}
1761
1763{
1764 Main *bmain = CTX_data_main(C);
1765 Scene *scene = CTX_data_scene(C);
1766
1767 CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) {
1768 modifiers_clear(bmain, scene, object);
1770 }
1772
1773 return OPERATOR_FINISHED;
1774}
1775
1777{
1779 return false;
1780 }
1781 const Object *object = context_active_object(C);
1782 if (!BKE_object_supports_modifiers(object)) {
1783 return false;
1784 }
1785 return true;
1786}
1787
1789{
1790 ot->name = "Clear Object Modifiers";
1791 ot->description = "Clear all modifiers from the selected objects";
1792 ot->idname = "OBJECT_OT_modifiers_clear";
1793
1794 ot->exec = modifiers_clear_exec;
1795 ot->poll = modifiers_clear_poll;
1796
1797 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1798}
1799
1801
1802/* ------------------------------------------------------------------- */
1805
1807{
1810
1811 if (!md || !modifier_move_up(op->reports, RPT_WARNING, ob, md)) {
1812 return OPERATOR_CANCELLED;
1813 }
1814
1817
1818 return OPERATOR_FINISHED;
1819}
1820
1822{
1823 wmOperatorStatus retval;
1824 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1825 return modifier_move_up_exec(C, op);
1826 }
1827 return retval;
1828}
1829
1831{
1832 ot->name = "Move Up Modifier";
1833 ot->description = "Move modifier up in the stack";
1834 ot->idname = "OBJECT_OT_modifier_move_up";
1835
1836 ot->invoke = modifier_move_up_invoke;
1837 ot->exec = modifier_move_up_exec;
1838 ot->poll = edit_modifier_poll;
1839
1840 /* flags */
1843}
1844
1846
1847/* ------------------------------------------------------------------- */
1850
1852{
1855
1856 if (!md || !modifier_move_down(op->reports, RPT_WARNING, ob, md)) {
1857 return OPERATOR_CANCELLED;
1858 }
1859
1862
1863 return OPERATOR_FINISHED;
1864}
1865
1867 wmOperator *op,
1868 const wmEvent *event)
1869{
1870 wmOperatorStatus retval;
1871 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1872 return modifier_move_down_exec(C, op);
1873 }
1874 return retval;
1875}
1876
1878{
1879 ot->name = "Move Down Modifier";
1880 ot->description = "Move modifier down in the stack";
1881 ot->idname = "OBJECT_OT_modifier_move_down";
1882
1883 ot->invoke = modifier_move_down_invoke;
1885 ot->poll = edit_modifier_poll;
1886
1887 /* flags */
1890}
1891
1893
1894/* ------------------------------------------------------------------- */
1897
1899{
1900 char name[MAX_NAME];
1901 RNA_string_get(op->ptr, "modifier", name);
1902
1903 const int index = RNA_int_get(op->ptr, "index");
1904
1905 bool changed = false;
1906 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
1907 Object *ob = static_cast<Object *>(ptr.data);
1909 if (!md) {
1910 continue;
1911 }
1912
1913 if (!modifier_move_to_index(op->reports, RPT_WARNING, ob, md, index, true)) {
1914 continue;
1915 }
1916 changed = true;
1917 }
1918
1919 if (!changed) {
1920 return OPERATOR_CANCELLED;
1921 }
1922
1923 return OPERATOR_FINISHED;
1924}
1925
1927 wmOperator *op,
1928 const wmEvent *event)
1929{
1930 wmOperatorStatus retval;
1931 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
1932 return modifier_move_to_index_exec(C, op);
1933 }
1934 return retval;
1935}
1936
1938{
1939 ot->name = "Move Active Modifier to Index";
1940 ot->description =
1941 "Change the modifier's index in the stack so it evaluates after the set number of others";
1942 ot->idname = "OBJECT_OT_modifier_move_to_index";
1943
1946 ot->poll = edit_modifier_poll;
1947
1948 /* flags */
1952 ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the modifier to", 0, INT_MAX);
1954}
1955
1957
1958/* ------------------------------------------------------------------- */
1961
1963{
1964 if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false, false)) {
1965 return false;
1966 }
1967
1968 Scene *scene = CTX_data_scene(C);
1969 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
1970 Object *ob = (ptr.owner_id != nullptr) ? (Object *)ptr.owner_id : context_active_object(C);
1971 ModifierData *md = static_cast<ModifierData *>(ptr.data); /* May be nullptr. */
1972
1973 if (ID_IS_OVERRIDE_LIBRARY(ob) || ((ob->data != nullptr) && ID_IS_OVERRIDE_LIBRARY(ob->data))) {
1974 CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
1975 return false;
1976 }
1977 if (md != nullptr) {
1978 if ((ob->mode & OB_MODE_SCULPT) && find_multires_modifier_before(scene, md) &&
1979 (BKE_modifier_is_same_topology(md) == false))
1980 {
1982 C, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
1983 return false;
1984 }
1985 }
1986 return true;
1987}
1988
1990 wmOperator *op,
1991 int apply_as,
1992 bool keep_modifier)
1993{
1994 Main *bmain = CTX_data_main(C);
1996 Scene *scene = CTX_data_scene(C);
1998
1999 char name[MAX_NAME];
2000 RNA_string_get(op->ptr, "modifier", name);
2001
2002 const bool do_report = RNA_boolean_get(op->ptr, "report");
2003 const int reports_len = do_report ? BLI_listbase_count(&op->reports->list) : 0;
2004
2005 const bool do_single_user = (apply_as == MODIFIER_APPLY_DATA) ?
2006 RNA_boolean_get(op->ptr, "single_user") :
2007 false;
2008 const bool do_merge_customdata = (apply_as == MODIFIER_APPLY_DATA) ?
2009 RNA_boolean_get(op->ptr, "merge_customdata") :
2010 false;
2011 const bool do_all_keyframes = (apply_as == MODIFIER_APPLY_DATA) ?
2012 RNA_boolean_get(op->ptr, "all_keyframes") :
2013 false;
2014
2015 bool changed = false;
2016 for (const PointerRNA &ptr : objects) {
2017 Object *ob = static_cast<Object *>(ptr.data);
2019 if (md == nullptr) {
2020 continue;
2021 }
2022
2024
2025 if (do_single_user && ID_REAL_USERS(ob->data) > 1) {
2026 single_obdata_user_make(bmain, scene, ob);
2030 }
2031
2032 if (!modifier_apply(bmain,
2033 op->reports,
2034 depsgraph,
2035 scene,
2036 ob,
2037 md,
2038 apply_as,
2039 keep_modifier,
2040 do_all_keyframes))
2041 {
2042 continue;
2043 }
2044 changed = true;
2045
2046 if (ob->type == OB_MESH && do_merge_customdata &&
2048 {
2050 }
2051
2055 }
2056
2057 if (!changed) {
2058 return OPERATOR_CANCELLED;
2059 }
2060
2061 if (do_report) {
2062 /* Only add this report if the operator didn't cause another one. The purpose here is
2063 * to alert that something happened, and the previous report will do that anyway. */
2064 if (BLI_listbase_count(&op->reports->list) == reports_len) {
2065 BKE_reportf(op->reports, RPT_INFO, "Applied modifier: %s", name);
2066 }
2067 }
2068
2069 return OPERATOR_FINISHED;
2070}
2071
2076
2078{
2079 wmOperatorStatus retval;
2080 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2081 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
2082 Object *ob = (ptr.owner_id != nullptr) ? (Object *)ptr.owner_id : context_active_object(C);
2083
2084 if ((ob->data != nullptr) && ID_REAL_USERS(ob->data) > 1) {
2085 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "single_user");
2086 if (!RNA_property_is_set(op->ptr, prop)) {
2087 RNA_property_boolean_set(op->ptr, prop, true);
2088 }
2089 if (RNA_property_boolean_get(op->ptr, prop)) {
2091 C,
2092 op,
2093 IFACE_("Apply Modifier"),
2094 IFACE_("Make data single-user, apply modifier, and remove it from the list."),
2095 IFACE_("Apply"),
2097 false);
2098 }
2099 }
2100 return modifier_apply_exec(C, op);
2101 }
2102 return retval;
2103}
2104
2106{
2107 PropertyRNA *prop;
2108
2109 ot->name = "Apply Modifier";
2110 ot->description = "Apply modifier and remove from the stack";
2111 ot->idname = "OBJECT_OT_modifier_apply";
2112
2113 ot->invoke = modifier_apply_invoke;
2114 ot->exec = modifier_apply_exec;
2115 ot->poll = modifier_apply_poll;
2116
2117 /* flags */
2119
2122
2123 RNA_def_boolean(ot->srna,
2124 "merge_customdata",
2125 true,
2126 "Merge UVs",
2127 "For mesh objects, merge UV coordinates that share a vertex to account for "
2128 "imprecision in some modifiers");
2129 prop = RNA_def_boolean(ot->srna,
2130 "single_user",
2131 false,
2132 "Make Data Single User",
2133 "Make the object's data single user if needed");
2135 prop = RNA_def_boolean(ot->srna,
2136 "all_keyframes",
2137 false,
2138 "Apply to all keyframes",
2139 "For Grease Pencil objects, apply the modifier to all the keyframes");
2142}
2143
2145
2146/* ------------------------------------------------------------------- */
2149
2151{
2152 return modifier_apply_poll(C);
2153}
2154
2156{
2157 bool keep = RNA_boolean_get(op->ptr, "keep_modifier");
2158
2160}
2161
2163 wmOperator *op,
2164 const wmEvent *event)
2165{
2166 wmOperatorStatus retval;
2167 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2169 }
2170 return retval;
2171}
2172
2174 wmOperatorType * /*ot*/,
2175 PointerRNA *ptr)
2176{
2177 bool keep = RNA_boolean_get(ptr, "keep_modifier");
2178 if (keep) {
2179 return TIP_("Apply modifier as a new shapekey and keep it in the stack");
2180 }
2181
2182 return "";
2183}
2184
2186{
2187 ot->name = "Apply Modifier as Shape Key";
2188 ot->description = "Apply modifier as a new shape key and remove from the stack";
2189 ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
2190
2195
2196 /* flags */
2198
2200 ot->srna, "keep_modifier", false, "Keep Modifier", "Do not remove the modifier from stack");
2204}
2205
2207
2208/* ------------------------------------------------------------------- */
2211
2213{
2214 Main *bmain = CTX_data_main(C);
2216 Scene *scene = CTX_data_scene(C);
2217 ViewLayer *view_layer = CTX_data_view_layer(C);
2220
2221 if (!md || !convert_psys_to_mesh(op->reports, bmain, depsgraph, scene, view_layer, ob, md)) {
2222 return OPERATOR_CANCELLED;
2223 }
2224
2227
2228 return OPERATOR_FINISHED;
2229}
2230
2232 wmOperator *op,
2233 const wmEvent * /*event*/)
2234{
2236 return modifier_convert_exec(C, op);
2237 }
2238 return OPERATOR_CANCELLED;
2239}
2240
2242{
2243 ot->name = "Convert Particles to Mesh";
2244 ot->description = "Convert particles to a mesh object";
2245 ot->idname = "OBJECT_OT_modifier_convert";
2246
2247 ot->invoke = modifier_convert_invoke;
2248 ot->exec = modifier_convert_exec;
2249 ot->poll = edit_modifier_poll;
2250
2251 /* flags */
2254}
2255
2257
2258/* ------------------------------------------------------------------- */
2261
2263{
2264 Main *bmain = CTX_data_main(C);
2265 Scene *scene = CTX_data_scene(C);
2266 char name[MAX_NAME];
2267 RNA_string_get(op->ptr, "modifier", name);
2268
2269 bool changed = false;
2270 for (const PointerRNA &ptr : modifier_get_edit_objects(*C, *op)) {
2271 Object *ob = static_cast<Object *>(ptr.data);
2273 if (!md) {
2274 continue;
2275 }
2276
2277 if (!modifier_copy(op->reports, bmain, scene, ob, md)) {
2278 continue;
2279 }
2280 changed = true;
2284 }
2285
2286 if (!changed) {
2287 return OPERATOR_CANCELLED;
2288 }
2289
2290 return OPERATOR_FINISHED;
2291}
2292
2294{
2295 wmOperatorStatus retval;
2296 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2297 return modifier_copy_exec(C, op);
2298 }
2299 return retval;
2300}
2301
2303{
2304 ot->name = "Copy Modifier";
2305 ot->description = "Duplicate modifier at the same position in the stack";
2306 ot->idname = "OBJECT_OT_modifier_copy";
2307
2308 ot->invoke = modifier_copy_invoke;
2309 ot->exec = modifier_copy_exec;
2311
2312 /* flags */
2316}
2317
2319
2320/* ------------------------------------------------------------------- */
2323
2325{
2328
2329 /* If there is no modifier set for this operator, clear the active modifier field. */
2331
2333
2334 return OPERATOR_FINISHED;
2335}
2336
2338 wmOperator *op,
2339 const wmEvent *event)
2340{
2341 wmOperatorStatus retval;
2342 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2343 return modifier_set_active_exec(C, op);
2344 }
2345 return retval;
2346}
2347
2349{
2350 ot->name = "Set Active Modifier";
2351 ot->description = "Activate the modifier to use as the context";
2352 ot->idname = "OBJECT_OT_modifier_set_active";
2353
2357
2360}
2361
2363
2364/* ------------------------------------------------------------------- */
2367
2369{
2370 Main *bmain = CTX_data_main(C);
2371 const Scene *scene = CTX_data_scene(C);
2372 Object *obact = context_active_object(C);
2373 ModifierData *md = edit_modifier_property_get(op, obact, 0);
2374 if (!md) {
2375 return OPERATOR_CANCELLED;
2376 }
2377
2378 int num_copied = 0;
2379
2380 Vector<PointerRNA> selected_objects;
2381 CTX_data_selected_objects(C, &selected_objects);
2382 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
2383 if (ob == obact) {
2384 continue;
2385 }
2386 if (!ID_IS_EDITABLE(ob)) {
2387 continue;
2388 }
2389 if (modifier_copy_to_object(bmain, scene, obact, md, ob, op->reports)) {
2391 num_copied++;
2392 }
2393 }
2395
2396 if (num_copied > 0) {
2398 }
2399 else {
2400 BKE_reportf(op->reports, RPT_ERROR, "Modifier '%s' was not copied to any objects", md->name);
2401 return OPERATOR_CANCELLED;
2402 }
2403
2404 return OPERATOR_FINISHED;
2405}
2406
2408 wmOperator *op,
2409 const wmEvent *event)
2410{
2411 wmOperatorStatus retval;
2412 if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
2414 }
2415 return retval;
2416}
2417
2419{
2420 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
2421 Object *obact = (ptr.owner_id) ? (Object *)ptr.owner_id : context_active_object(C);
2422 ModifierData *md = static_cast<ModifierData *>(ptr.data);
2423
2424 /* This just mirrors the check in #BKE_object_copy_modifier,
2425 * but there is no reasoning for it there. */
2427 CTX_wm_operator_poll_msg_set(C, R"(Not supported for "Collision" or "Hook" modifiers)");
2428 return false;
2429 }
2430
2431 if (!obact) {
2432 CTX_wm_operator_poll_msg_set(C, "No selected object is active");
2433 return false;
2434 }
2435
2436 if (!BKE_object_supports_modifiers(obact)) {
2437 CTX_wm_operator_poll_msg_set(C, "Object type of source object is not supported");
2438 return false;
2439 }
2440
2441 /* This could have a performance impact in the worst case, where there are many objects selected
2442 * and none of them pass either of the checks. But that should be uncommon, and this operator is
2443 * only exposed in a drop-down menu anyway. */
2444 bool found_supported_objects = false;
2445 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
2446 if (ob == obact) {
2447 continue;
2448 }
2449
2450 if (!md) {
2451 /* Skip type check if modifier could not be found ("modifier" context variable not set). */
2453 found_supported_objects = true;
2454 break;
2455 }
2456 }
2457 else if (BKE_object_support_modifier_type_check(ob, md->type)) {
2458 found_supported_objects = true;
2459 break;
2460 }
2461 }
2463
2464 if (!found_supported_objects) {
2465 CTX_wm_operator_poll_msg_set(C, "No supported objects were selected");
2466 return false;
2467 }
2468 return true;
2469}
2470
2472{
2473 ot->name = "Copy Modifier to Selected";
2474 ot->description = "Copy the modifier from the active object to all selected objects";
2475 ot->idname = "OBJECT_OT_modifier_copy_to_selected";
2476
2480
2481 /* flags */
2484}
2485
2487{
2488 Main *bmain = CTX_data_main(C);
2489 const Scene *scene = CTX_data_scene(C);
2490 Object *active_object = context_active_object(C);
2491
2492 Vector<PointerRNA> selected_objects;
2493 CTX_data_selected_objects(C, &selected_objects);
2494 CTX_DATA_BEGIN (C, Object *, object, selected_objects) {
2495 if (object == active_object) {
2496 continue;
2497 }
2498 LISTBASE_FOREACH (const ModifierData *, md, &active_object->modifiers) {
2499 if (modifier_copy_to_object(bmain, scene, active_object, md, object, op->reports)) {
2501 }
2502 }
2503 }
2505
2506 return OPERATOR_FINISHED;
2507
2509
2511
2512 return OPERATOR_FINISHED;
2513}
2514
2516{
2518 return false;
2519 }
2520 const Object *active_object = context_active_object(C);
2521 if (!BKE_object_supports_modifiers(active_object)) {
2522 return false;
2523 }
2524 if (BLI_listbase_is_empty(&active_object->modifiers)) {
2525 CTX_wm_operator_poll_msg_set(C, "Active object has no modifiers");
2526 return false;
2527 }
2528 return true;
2529}
2530
2532{
2533 ot->name = "Copy Modifiers to Selected Objects";
2534 ot->idname = "OBJECT_OT_modifiers_copy_to_selected";
2535 ot->description = "Copy modifiers to other selected objects";
2536
2539
2540 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2541}
2542
2544
2545/* ------------------------------------------------------------------- */
2548
2550{
2551 Mesh *mesh = static_cast<Mesh *>(ob->data);
2552 if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
2553 BM_data_layer_free(em->bm, &em->bm->vdata, CD_MVERT_SKIN);
2554 }
2555 else {
2557 }
2558}
2559
2560static bool skin_poll(bContext *C)
2561{
2562 return edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), false, false);
2563}
2564
2566{
2568 return (ob != nullptr &&
2569 edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true, false) &&
2571}
2572
2573static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
2574{
2575 BMEdge *bm_edge;
2576 BMIter bm_iter;
2577
2578 BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
2579 BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
2580
2581 if (BLI_gset_add(visited, v2)) {
2582 MVertSkin *vs = static_cast<MVertSkin *>(BM_ELEM_CD_GET_VOID_P(v2, cd_vert_skin_offset));
2583
2584 /* clear vertex root flag and add to visited set */
2585 vs->flag &= ~MVERT_SKIN_ROOT;
2586
2587 skin_root_clear(v2, visited, cd_vert_skin_offset);
2588 }
2589 }
2590}
2591
2593{
2596 BMesh *bm = em->bm;
2597
2598 GSet *visited = BLI_gset_ptr_new(__func__);
2599
2600 BKE_mesh_ensure_skin_customdata(static_cast<Mesh *>(ob->data));
2601
2602 const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
2603
2604 BMVert *bm_vert;
2605 BMIter bm_iter;
2606 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2607 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT) && BLI_gset_add(visited, bm_vert)) {
2608 MVertSkin *vs = static_cast<MVertSkin *>(
2609 BM_ELEM_CD_GET_VOID_P(bm_vert, cd_vert_skin_offset));
2610
2611 /* mark vertex as root and add to visited set */
2612 vs->flag |= MVERT_SKIN_ROOT;
2613
2614 /* clear root flag from all connected vertices (recursively) */
2615 skin_root_clear(bm_vert, visited, cd_vert_skin_offset);
2616 }
2617 }
2618
2619 BLI_gset_free(visited, nullptr);
2620
2623
2624 return OPERATOR_FINISHED;
2625}
2626
2628{
2629 ot->name = "Skin Root Mark";
2630 ot->description = "Mark selected vertices as roots";
2631 ot->idname = "OBJECT_OT_skin_root_mark";
2632
2633 ot->poll = skin_edit_poll;
2634 ot->exec = skin_root_mark_exec;
2635
2636 /* flags */
2637 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2638}
2639
2644
2646{
2649 BMesh *bm = em->bm;
2650 SkinLooseAction action = static_cast<SkinLooseAction>(RNA_enum_get(op->ptr, "action"));
2651
2652 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
2653 return OPERATOR_CANCELLED;
2654 }
2655
2656 BMVert *bm_vert;
2657 BMIter bm_iter;
2658 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2659 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
2660 MVertSkin *vs = static_cast<MVertSkin *>(
2661 CustomData_bmesh_get(&bm->vdata, bm_vert->head.data, CD_MVERT_SKIN));
2662
2663 switch (action) {
2664 case SKIN_LOOSE_MARK:
2665 vs->flag |= MVERT_SKIN_LOOSE;
2666 break;
2667 case SKIN_LOOSE_CLEAR:
2668 vs->flag &= ~MVERT_SKIN_LOOSE;
2669 break;
2670 }
2671 }
2672 }
2673
2676
2677 return OPERATOR_FINISHED;
2678}
2679
2681{
2682 static const EnumPropertyItem action_items[] = {
2683 {SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"},
2684 {SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"},
2685 {0, nullptr, 0, nullptr, nullptr},
2686 };
2687
2688 ot->name = "Skin Mark/Clear Loose";
2689 ot->description = "Mark/clear selected vertices as loose";
2690 ot->idname = "OBJECT_OT_skin_loose_mark_clear";
2691
2692 ot->poll = skin_edit_poll;
2694
2695 /* flags */
2696 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2697
2698 RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", nullptr);
2699}
2700
2702{
2705 BMesh *bm = em->bm;
2706
2707 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
2708 return OPERATOR_CANCELLED;
2709 }
2710
2711 BMVert *bm_vert;
2712 BMIter bm_iter;
2713 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
2714 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
2715 MVertSkin *vs = static_cast<MVertSkin *>(
2716 CustomData_bmesh_get(&bm->vdata, bm_vert->head.data, CD_MVERT_SKIN));
2717 float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
2718
2719 vs->radius[0] = vs->radius[1] = avg;
2720 }
2721 }
2722
2725
2726 return OPERATOR_FINISHED;
2727}
2728
2730{
2731 ot->name = "Skin Radii Equalize";
2732 ot->description = "Make skin radii of selected vertices equal on each axis";
2733 ot->idname = "OBJECT_OT_skin_radii_equalize";
2734
2735 ot->poll = skin_edit_poll;
2737
2738 /* flags */
2739 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2740}
2741
2743 const Span<float3> positions,
2744 const int2 *edges,
2745 bArmature *arm,
2746 BLI_bitmap *edges_visited,
2747 const GroupedSpan<int> emap,
2748 EditBone *parent_bone,
2749 int parent_v)
2750{
2751 for (int i = 0; i < emap[parent_v].size(); i++) {
2752 int endx = emap[parent_v][i];
2753 const int2 &edge = edges[endx];
2754
2755 /* ignore edge if already visited */
2756 if (BLI_BITMAP_TEST(edges_visited, endx)) {
2757 continue;
2758 }
2759 BLI_BITMAP_ENABLE(edges_visited, endx);
2760
2761 int v = bke::mesh::edge_other_vert(edge, parent_v);
2762
2763 EditBone *bone = ED_armature_ebone_add(arm, "Bone");
2764
2765 bone->parent = parent_bone;
2766 if (parent_bone != nullptr) {
2767 bone->flag |= BONE_CONNECTED;
2768 }
2769
2770 copy_v3_v3(bone->head, positions[parent_v]);
2771 copy_v3_v3(bone->tail, positions[v]);
2772 bone->rad_head = bone->rad_tail = 0.25;
2773 SNPRINTF_UTF8(bone->name, "Bone.%.2d", endx);
2774
2775 /* add bDeformGroup */
2776 bDeformGroup *dg = BKE_object_defgroup_add_name(skin_ob, bone->name);
2777 if (dg != nullptr) {
2778 blender::ed::object::vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
2780 }
2781
2782 skin_armature_bone_create(skin_ob, positions, edges, arm, edges_visited, emap, bone, v);
2783 }
2784}
2785
2786static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob)
2787{
2788 Mesh *mesh = static_cast<Mesh *>(skin_ob->data);
2789 const Span<float3> me_positions = mesh->vert_positions();
2790 const Span<int2> me_edges = mesh->edges();
2791
2793 Object *ob_eval = DEG_get_evaluated(depsgraph, skin_ob);
2794
2795 const Mesh *me_eval_deform = blender::bke::mesh_get_eval_deform(
2796 depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
2797 const Span<float3> positions_eval = me_eval_deform->vert_positions();
2798
2799 /* add vertex weights to original mesh */
2800 mesh->deform_verts_for_write();
2801
2804 Object *arm_ob = BKE_object_add(bmain, scene, view_layer, OB_ARMATURE, nullptr);
2805 BKE_object_transform_copy(arm_ob, skin_ob);
2806 bArmature *arm = static_cast<bArmature *>(arm_ob->data);
2808 arm_ob->dtx |= OB_DRAW_IN_FRONT;
2810 arm->edbo = MEM_callocN<ListBase>("edbo armature");
2811
2812 MVertSkin *mvert_skin = static_cast<MVertSkin *>(
2813 CustomData_get_layer_for_write(&mesh->vert_data, CD_MVERT_SKIN, mesh->verts_num));
2814
2815 Array<int> vert_to_edge_offsets;
2816 Array<int> vert_to_edge_indices;
2818 me_edges, mesh->verts_num, vert_to_edge_offsets, vert_to_edge_indices);
2819
2820 BLI_bitmap *edges_visited = BLI_BITMAP_NEW(mesh->edges_num, "edge_visited");
2821
2822 /* NOTE: we use EditBones here, easier to set them up and use
2823 * edit-armature functions to convert back to regular bones */
2824 for (int v = 0; v < mesh->verts_num; v++) {
2825 if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
2826 EditBone *bone = nullptr;
2827
2828 /* Unless the skin root has just one adjacent edge, create
2829 * a fake root bone (have it going off in the Y direction
2830 * (arbitrary) */
2831 if (emap[v].size() > 1) {
2832 bone = ED_armature_ebone_add(arm, "Bone");
2833
2834 copy_v3_v3(bone->head, me_positions[v]);
2835 copy_v3_v3(bone->tail, me_positions[v]);
2836
2837 bone->head[1] = 1.0f;
2838 bone->rad_head = bone->rad_tail = 0.25;
2839 }
2840
2841 if (emap[v].size() >= 1) {
2843 skin_ob, positions_eval, me_edges.data(), arm, edges_visited, emap, bone, v);
2844 }
2845 }
2846 }
2847
2848 MEM_freeN(edges_visited);
2849
2850 ED_armature_from_edit(bmain, arm);
2852
2853 return arm_ob;
2854}
2855
2857{
2858 Main *bmain = CTX_data_main(C);
2861 Mesh *mesh = static_cast<Mesh *>(ob->data);
2862 ModifierData *skin_md;
2863
2864 if (!CustomData_has_layer(&mesh->vert_data, CD_MVERT_SKIN)) {
2865 BKE_reportf(op->reports, RPT_WARNING, "Mesh '%s' has no skin vertex data", mesh->id.name + 2);
2866 return OPERATOR_CANCELLED;
2867 }
2868
2869 /* create new armature */
2870 Object *arm_ob = modifier_skin_armature_create(depsgraph, bmain, ob);
2871
2872 /* add a modifier to connect the new armature to the mesh */
2874 if (arm_md) {
2876 BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md);
2878
2879 arm_md->object = arm_ob;
2883 }
2884
2886
2887 return OPERATOR_FINISHED;
2888}
2889
2891 wmOperator *op,
2892 const wmEvent * /*event*/)
2893{
2895 return skin_armature_create_exec(C, op);
2896 }
2897 return OPERATOR_CANCELLED;
2898}
2899
2901{
2902 ot->name = "Skin Armature Create";
2903 ot->description = "Create an armature that parallels the skin layout";
2904 ot->idname = "OBJECT_OT_skin_armature_create";
2905
2906 ot->poll = skin_poll;
2909
2910 /* flags */
2913}
2914
2916
2917/* ------------------------------------------------------------------- */
2920
2922{
2923 return edit_modifier_poll_generic(C, &RNA_CorrectiveSmoothModifier, 0, true, false);
2924}
2925
2927{
2929 Scene *scene = CTX_data_scene(C);
2933
2934 if (!csmd) {
2935 return OPERATOR_CANCELLED;
2936 }
2937
2939 BKE_report(op->reports, RPT_ERROR, "Modifier is disabled");
2940 return OPERATOR_CANCELLED;
2941 }
2942
2943 const bool is_bind = (csmd->bind_coords != nullptr);
2944
2947
2948 if (is_bind) {
2949 /* toggle off */
2950 csmd->bind_coords_num = 0;
2951 }
2952 else {
2953 /* Signal to modifier to recalculate. */
2956 csmd_eval->bind_coords_num = uint(-1);
2957
2958 /* Force modifier to run, it will call binding routine
2959 * (this has to happen outside of depsgraph evaluation). */
2961 }
2962
2965
2966 return OPERATOR_FINISHED;
2967}
2968
2970 wmOperator *op,
2971 const wmEvent * /*event*/)
2972{
2974 return correctivesmooth_bind_exec(C, op);
2975 }
2976 return OPERATOR_CANCELLED;
2977}
2978
2980{
2981 /* identifiers */
2982 ot->name = "Corrective Smooth Bind";
2983 ot->description = "Bind base pose in Corrective Smooth modifier";
2984 ot->idname = "OBJECT_OT_correctivesmooth_bind";
2985
2986 /* API callbacks. */
2987 ot->poll = correctivesmooth_poll;
2990
2991 /* flags */
2994}
2995
2997
2998/* ------------------------------------------------------------------- */
3001
3003{
3004 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0, true, false);
3005}
3006
3008{
3009 using namespace blender;
3013 op, ob, eModifierType_MeshDeform);
3014
3015 if (mmd == nullptr) {
3016 return OPERATOR_CANCELLED;
3017 }
3018
3019 if (mmd->bindcagecos != nullptr) {
3026 MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */
3027 MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */
3028 mmd->verts_num = 0;
3029 mmd->cage_verts_num = 0;
3030 mmd->influences_num = 0;
3031 }
3032 else {
3033 /* Force modifier to run, it will call binding routine
3034 * (this has to happen outside of depsgraph evaluation). */
3036 depsgraph, ob, &mmd->modifier);
3039 mmd_eval->bindfunc = nullptr;
3040 }
3041
3044 return OPERATOR_FINISHED;
3045}
3046
3048 wmOperator *op,
3049 const wmEvent * /*event*/)
3050{
3052 return meshdeform_bind_exec(C, op);
3053 }
3054 return OPERATOR_CANCELLED;
3055}
3056
3058{
3059 /* identifiers */
3060 ot->name = "Mesh Deform Bind";
3061 ot->description = "Bind mesh to cage in mesh deform modifier";
3062 ot->idname = "OBJECT_OT_meshdeform_bind";
3063
3064 /* API callbacks. */
3065 ot->poll = meshdeform_poll;
3066 ot->invoke = meshdeform_bind_invoke;
3067 ot->exec = meshdeform_bind_exec;
3068
3069 /* flags */
3072}
3073
3075
3076/* ------------------------------------------------------------------- */
3079
3081{
3082 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0, true, false);
3083}
3084
3102
3104 wmOperator *op,
3105 const wmEvent * /*event*/)
3106{
3108 return explode_refresh_exec(C, op);
3109 }
3110 return OPERATOR_CANCELLED;
3111}
3112
3114{
3115 ot->name = "Explode Refresh";
3116 ot->description = "Refresh data in the Explode modifier";
3117 ot->idname = "OBJECT_OT_explode_refresh";
3118
3119 ot->poll = explode_poll;
3120 ot->invoke = explode_refresh_invoke;
3121 ot->exec = explode_refresh_exec;
3122
3123 /* flags */
3126}
3127
3129
3130/* ------------------------------------------------------------------- */
3133
3135{
3136 return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0, true, false);
3137}
3138
3149
3150static void oceanbake_free(void *customdata)
3151{
3152 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3153 MEM_delete(oj);
3154}
3155
3156/* called by oceanbake, only to check job 'stop' value */
3157static int oceanbake_breakjob(void * /*customdata*/)
3158{
3159 // OceanBakeJob *ob = (OceanBakeJob *)customdata;
3160 // return *(ob->stop);
3161
3162 /* this is not nice yet, need to make the jobs list template better
3163 * for identifying/acting upon various different jobs */
3164 /* but for now we'll reuse the render break... */
3165 return (G.is_break);
3166}
3167
3168/* called by oceanbake, wmJob sends notifier */
3169static void oceanbake_update(void *customdata, float progress, int *cancel)
3170{
3171 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3172
3173 if (oceanbake_breakjob(oj)) {
3174 *cancel = 1;
3175 }
3176
3177 *(oj->do_update) = true;
3178 *(oj->progress) = progress;
3179}
3180
3181static void oceanbake_startjob(void *customdata, wmJobWorkerStatus *worker_status)
3182{
3183 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3184
3185 oj->stop = &worker_status->stop;
3186 oj->do_update = &worker_status->do_update;
3187 oj->progress = &worker_status->progress;
3188
3189 G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
3190
3191 BKE_ocean_bake(oj->ocean, oj->och, oceanbake_update, (void *)oj);
3192
3193 worker_status->do_update = true;
3194 worker_status->stop = false;
3195}
3196
3197static void oceanbake_endjob(void *customdata)
3198{
3199 OceanBakeJob *oj = static_cast<OceanBakeJob *>(customdata);
3200
3201 if (oj->ocean) {
3202 BKE_ocean_free(oj->ocean);
3203 oj->ocean = nullptr;
3204 }
3205
3206 oj->omd->oceancache = oj->och;
3207 oj->omd->cached = true;
3208
3209 Object *ob = oj->owner;
3211}
3212
3214{
3215 Main *bmain = CTX_data_main(C);
3218 op, ob, eModifierType_Ocean);
3219 Scene *scene = CTX_data_scene(C);
3220 const bool free = RNA_boolean_get(op->ptr, "free");
3221
3222 if (!omd) {
3223 return OPERATOR_CANCELLED;
3224 }
3225
3226 if (free) {
3230 return OPERATOR_FINISHED;
3231 }
3232
3234 BKE_modifier_path_relbase(bmain, ob),
3235 omd->bakestart,
3236 omd->bakeend,
3237 omd->wave_scale,
3238 omd->chop_amount,
3239 omd->foam_coverage,
3240 omd->foam_fade,
3241 omd->resolution);
3242
3243 och->time = MEM_malloc_arrayN<float>(och->duration, "foam bake time");
3244
3245 int cfra = scene->r.cfra;
3246
3247 /* precalculate time variable before baking */
3248 int i = 0;
3250 for (int f = omd->bakestart; f <= omd->bakeend; f++) {
3251 /* For now only simple animation of time value is supported, nothing else.
3252 * No drivers or other modifier parameters. */
3253 /* TODO(sergey): This operates on an original data, so no flush is needed. However, baking
3254 * usually should happen on an evaluated objects, so this seems to be deeper issue here. */
3255
3257 f);
3258 BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
3259
3260 och->time[i] = omd->time;
3261 i++;
3262 }
3263
3264 /* Make a copy of ocean to use for baking - thread-safety. */
3265 Ocean *ocean = BKE_ocean_add();
3266 BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
3267
3268#if 0
3269 BKE_ocean_bake(ocean, och);
3270
3271 omd->oceancache = och;
3272 omd->cached = true;
3273
3274 scene->r.cfra = cfra;
3275
3278#endif
3279
3280 /* job stuff */
3281
3282 scene->r.cfra = cfra;
3283
3284 /* setup job */
3285 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
3287 scene,
3288 "Simulating ocean...",
3291 OceanBakeJob *oj = MEM_callocN<OceanBakeJob>("ocean bake job");
3292 oj->owner = ob;
3293 oj->ocean = ocean;
3294 oj->och = och;
3295 oj->omd = omd;
3296
3299 WM_jobs_callbacks(wm_job, oceanbake_startjob, nullptr, nullptr, oceanbake_endjob);
3300
3301 WM_jobs_start(CTX_wm_manager(C), wm_job);
3302
3303 return OPERATOR_FINISHED;
3304}
3305
3307{
3309 return ocean_bake_exec(C, op);
3310 }
3311 return OPERATOR_CANCELLED;
3312}
3313
3315{
3316 ot->name = "Bake Ocean";
3317 ot->description = "Bake an image sequence of ocean data";
3318 ot->idname = "OBJECT_OT_ocean_bake";
3319
3320 ot->poll = ocean_bake_poll;
3321 ot->invoke = ocean_bake_invoke;
3322 ot->exec = ocean_bake_exec;
3323
3324 /* flags */
3327
3328 RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
3329}
3330
3332
3333/* ------------------------------------------------------------------- */
3336
3338{
3339 return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0, false, false);
3340}
3341
3343{
3348
3349 if (lmd == nullptr) {
3350 return OPERATOR_CANCELLED;
3351 }
3352
3353 if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) {
3355 }
3356 else {
3358 }
3359
3362 lmd_eval->flag = lmd->flag;
3363
3364 /* Force modifier to run, it will call binding routine
3365 * (this has to happen outside of depsgraph evaluation). */
3367
3368 /* This is hard to know from the modifier itself whether the evaluation is
3369 * happening for binding or not. So we copy all the required data here. */
3370 lmd->verts_num = lmd_eval->verts_num;
3371 if (lmd_eval->vertexco == nullptr) {
3373 }
3374 else {
3376 lmd_eval->vertexco_sharing_info,
3377 &lmd->vertexco,
3378 &lmd->vertexco_sharing_info);
3379 }
3380
3383 return OPERATOR_FINISHED;
3384}
3385
3387 wmOperator *op,
3388 const wmEvent * /*event*/)
3389{
3391 return laplaciandeform_bind_exec(C, op);
3392 }
3393 return OPERATOR_CANCELLED;
3394}
3395
3397{
3398 /* identifiers */
3399 ot->name = "Laplacian Deform Bind";
3400 ot->description = "Bind mesh to system in laplacian deform modifier";
3401 ot->idname = "OBJECT_OT_laplaciandeform_bind";
3402
3403 /* API callbacks. */
3404 ot->poll = laplaciandeform_poll;
3407
3408 /* flags */
3411}
3412
3414
3415/* ------------------------------------------------------------------- */
3418
3420{
3421 return edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0, true, false);
3422}
3423
3425{
3430
3431 if (smd == nullptr) {
3432 return OPERATOR_CANCELLED;
3433 }
3434
3435 if (smd->flags & MOD_SDEF_BIND) {
3436 smd->flags &= ~MOD_SDEF_BIND;
3437 }
3438 else if (smd->target) {
3439 smd->flags |= MOD_SDEF_BIND;
3440 }
3441
3443 depsgraph, ob, &smd->modifier);
3444 smd_eval->flags = smd->flags;
3445
3446 /* Force modifier to run, it will call binding routine
3447 * (this has to happen outside of depsgraph evaluation). */
3449
3452 return OPERATOR_FINISHED;
3453}
3454
3456 wmOperator *op,
3457 const wmEvent * /*event*/)
3458{
3460 return surfacedeform_bind_exec(C, op);
3461 }
3462 return OPERATOR_CANCELLED;
3463}
3464
3466{
3467 /* identifiers */
3468 ot->name = "Surface Deform Bind";
3469 ot->description = "Bind mesh to target in surface deform modifier";
3470 ot->idname = "OBJECT_OT_surfacedeform_bind";
3471
3472 /* API callbacks. */
3474 ot->invoke = surfacedeform_bind_invoke;
3476
3477 /* flags */
3480}
3481
3483
3484/* ------------------------------------------------------------------- */
3491
3493{
3495
3496 char modifier_name[MAX_NAME];
3497 RNA_string_get(op->ptr, "modifier_name", modifier_name);
3499 if (nmd == nullptr) {
3500 return OPERATOR_CANCELLED;
3501 }
3502
3503 char input_name[MAX_NAME];
3504 RNA_string_get(op->ptr, "input_name", input_name);
3505
3506 IDProperty *use_attribute = IDP_GetPropertyFromGroup(
3507 nmd->settings.properties, std::string(input_name + std::string("_use_attribute")).c_str());
3508 if (!use_attribute) {
3509 return OPERATOR_CANCELLED;
3510 }
3511
3512 if (use_attribute->type == IDP_INT) {
3513 IDP_int_set(use_attribute, !IDP_int_get(use_attribute));
3514 }
3515 else if (use_attribute->type == IDP_BOOLEAN) {
3516 IDP_bool_set(use_attribute, !IDP_bool_get(use_attribute));
3517 }
3518 else {
3519 return OPERATOR_CANCELLED;
3520 }
3521
3524 return OPERATOR_FINISHED;
3525}
3526
3528{
3529 ot->name = "Input Attribute Toggle";
3530 ot->description =
3531 "Switch between an attribute and a single value to define the data for every element";
3532 ot->idname = "OBJECT_OT_geometry_nodes_input_attribute_toggle";
3533
3536
3538
3539 RNA_def_string(ot->srna, "input_name", nullptr, 0, "Input Name", "");
3540 RNA_def_string(ot->srna, "modifier_name", nullptr, MAX_NAME, "Modifier Name", "");
3541}
3542
3544
3545/* ------------------------------------------------------------------- */
3548
3550{
3551 Main *bmain = CTX_data_main(C);
3554 if (!(md && md->type == eModifierType_Nodes)) {
3555 return OPERATOR_CANCELLED;
3556 }
3557
3559 bNodeTree *tree = nmd->node_group;
3560 if (tree == nullptr) {
3561 return OPERATOR_CANCELLED;
3562 }
3563
3564 bNodeTree *new_tree = (bNodeTree *)BKE_id_copy_ex(
3565 bmain, &tree->id, nullptr, LIB_ID_COPY_ACTIONS | LIB_ID_COPY_DEFAULT);
3566
3568
3569 if (new_tree == nullptr) {
3570 return OPERATOR_CANCELLED;
3571 }
3572
3573 nmd->node_group = new_tree;
3574 id_us_min(&tree->id);
3575
3580 return OPERATOR_FINISHED;
3581}
3582
3584{
3585 ot->name = "New Geometry Node Group";
3586 ot->description =
3587 "Duplicate the active geometry node group and assign it to the active modifier";
3588 ot->idname = "OBJECT_OT_geometry_node_tree_copy_assign";
3589
3592
3593 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3594}
3595
3597
3598/* ------------------------------------------------------------------- */
3601
3603{
3604 return edit_modifier_poll_generic(C, &RNA_GreasePencilDashModifierData, 0, false, false);
3605}
3606
3608{
3610 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
3612
3613 if (dmd == nullptr) {
3614 return OPERATOR_CANCELLED;
3615 }
3616
3617 GreasePencilDashModifierSegment *new_segments =
3618 MEM_malloc_arrayN<GreasePencilDashModifierSegment>(dmd->segments_num + 1, __func__);
3619
3620 const int new_active_index = std::clamp(dmd->segment_active_index + 1, 0, dmd->segments_num);
3621 if (dmd->segments_num != 0) {
3622 /* Copy the segments before the new segment. */
3623 memcpy(new_segments,
3624 dmd->segments_array,
3625 sizeof(GreasePencilDashModifierSegment) * new_active_index);
3626 /* Copy the segments after the new segment. */
3627 memcpy(new_segments + new_active_index + 1,
3628 dmd->segments_array + new_active_index,
3629 sizeof(GreasePencilDashModifierSegment) * (dmd->segments_num - new_active_index));
3630 }
3631
3632 /* Create the new segment. */
3633 GreasePencilDashModifierSegment *ds = &new_segments[new_active_index];
3634 memcpy(ds,
3638 [&](const StringRef name) {
3639 for (const GreasePencilDashModifierSegment &ds : dmd->segments()) {
3640 if (STREQ(ds.name, name.data())) {
3641 return true;
3642 }
3643 }
3644 return false;
3645 },
3646 '.',
3647 ds->name);
3648
3649 MEM_SAFE_FREE(dmd->segments_array);
3650 dmd->segments_array = new_segments;
3651 dmd->segments_num++;
3652 dmd->segment_active_index = new_active_index;
3653
3656
3657 return OPERATOR_FINISHED;
3658}
3659
3661 wmOperator *op,
3662 const wmEvent * /*event*/)
3663{
3666 }
3667 return OPERATOR_CANCELLED;
3668}
3669
3671{
3672 /* identifiers */
3673 ot->name = "Add Segment";
3674 ot->description = "Add a segment to the dash modifier";
3675 ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_add";
3676
3677 /* API callbacks. */
3681
3682 /* flags */
3685}
3686
3688
3690{
3692 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
3694
3695 if (dmd == nullptr) {
3696 return OPERATOR_CANCELLED;
3697 }
3698
3699 if (!dmd->segments().index_range().contains(dmd->segment_active_index)) {
3700 return OPERATOR_CANCELLED;
3701 }
3702
3703 dna::array::remove_index(&dmd->segments_array,
3704 &dmd->segments_num,
3705 &dmd->segment_active_index,
3706 dmd->segment_active_index,
3708
3711
3712 return OPERATOR_FINISHED;
3713}
3714
3716 wmOperator *op,
3717 const wmEvent * /*event*/)
3718{
3721 }
3722 return OPERATOR_CANCELLED;
3723}
3724
3726{
3727 /* identifiers */
3728 ot->name = "Remove Dash Segment";
3729 ot->description = "Remove the active segment from the dash modifier";
3730 ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_remove";
3731
3732 /* API callbacks. */
3736
3737 /* flags */
3740
3742 ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX);
3743}
3744
3746 Up = -1,
3747 Down = 1,
3748};
3749
3751{
3753 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
3755
3756 if (dmd == nullptr) {
3757 return OPERATOR_CANCELLED;
3758 }
3759
3760 if (dmd->segments_num < 2) {
3761 return OPERATOR_CANCELLED;
3762 }
3763
3765 RNA_enum_get(op->ptr, "type"));
3766 switch (direction) {
3768 if (dmd->segment_active_index == 0) {
3769 return OPERATOR_CANCELLED;
3770 }
3771
3772 std::swap(dmd->segments_array[dmd->segment_active_index],
3773 dmd->segments_array[dmd->segment_active_index - 1]);
3774
3775 dmd->segment_active_index--;
3776 break;
3778 if (dmd->segment_active_index == dmd->segments_num - 1) {
3779 return OPERATOR_CANCELLED;
3780 }
3781
3782 std::swap(dmd->segments_array[dmd->segment_active_index],
3783 dmd->segments_array[dmd->segment_active_index + 1]);
3784
3785 dmd->segment_active_index++;
3786 break;
3787 default:
3788 return OPERATOR_CANCELLED;
3789 }
3790
3793
3794 return OPERATOR_FINISHED;
3795}
3796
3798 wmOperator *op,
3799 const wmEvent * /*event*/)
3800{
3803 }
3804 return OPERATOR_CANCELLED;
3805}
3806
3808{
3809 static const EnumPropertyItem segment_move[] = {
3810 {int(DashSegmentMoveDirection::Up), "UP", 0, "Up", ""},
3811 {int(DashSegmentMoveDirection::Down), "DOWN", 0, "Down", ""},
3812 {0, nullptr, 0, nullptr, nullptr},
3813 };
3814
3815 /* identifiers */
3816 ot->name = "Move Dash Segment";
3817 ot->description = "Move the active dash segment up or down";
3818 ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_move";
3819
3820 /* API callbacks. */
3824
3825 /* flags */
3828
3829 ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", "");
3830}
3831
3833
3834/* ------------------------------------------------------------------- */
3837
3839{
3840 return edit_modifier_poll_generic(C, &RNA_GreasePencilTimeModifier, 0, false, false);
3841}
3842
3844{
3846 auto *tmd = reinterpret_cast<GreasePencilTimeModifierData *>(
3848
3849 if (tmd == nullptr) {
3850 return OPERATOR_CANCELLED;
3851 }
3852
3853 GreasePencilTimeModifierSegment *new_segments =
3854 MEM_malloc_arrayN<GreasePencilTimeModifierSegment>(tmd->segments_num + 1, __func__);
3855
3856 const int new_active_index = std::clamp(tmd->segment_active_index + 1, 0, tmd->segments_num);
3857 if (tmd->segments_num != 0) {
3858 /* Copy the segments before the new segment. */
3859 memcpy(new_segments,
3860 tmd->segments_array,
3861 sizeof(GreasePencilTimeModifierSegment) * new_active_index);
3862 /* Copy the segments after the new segment. */
3863 memcpy(new_segments + new_active_index + 1,
3864 tmd->segments_array + new_active_index,
3865 sizeof(GreasePencilTimeModifierSegment) * (tmd->segments_num - new_active_index));
3866 }
3867
3868 /* Create the new segment. */
3869 GreasePencilTimeModifierSegment *segment = &new_segments[new_active_index];
3870 memcpy(segment,
3874 [&](const StringRef name) {
3875 for (const GreasePencilTimeModifierSegment &segment : tmd->segments()) {
3876 if (STREQ(segment.name, name.data())) {
3877 return true;
3878 }
3879 }
3880 return false;
3881 },
3882 '.',
3883 segment->name);
3884
3885 MEM_SAFE_FREE(tmd->segments_array);
3886 tmd->segments_array = new_segments;
3887 tmd->segments_num++;
3888 tmd->segment_active_index++;
3889
3892
3893 return OPERATOR_FINISHED;
3894}
3895
3897 wmOperator *op,
3898 const wmEvent * /*event*/)
3899{
3902 }
3903 return OPERATOR_CANCELLED;
3904}
3905
3907{
3908 /* identifiers */
3909 ot->name = "Add Segment";
3910 ot->description = "Add a segment to the time modifier";
3911 ot->idname = "OBJECT_OT_grease_pencil_time_modifier_segment_add";
3912
3913 /* API callbacks. */
3917
3918 /* flags */
3921}
3922
3924
3926{
3928 auto *tmd = reinterpret_cast<GreasePencilTimeModifierData *>(
3930
3931 if (tmd == nullptr) {
3932 return OPERATOR_CANCELLED;
3933 }
3934
3935 if (!tmd->segments().index_range().contains(tmd->segment_active_index)) {
3936 return OPERATOR_CANCELLED;
3937 }
3938
3939 dna::array::remove_index(&tmd->segments_array,
3940 &tmd->segments_num,
3941 &tmd->segment_active_index,
3942 tmd->segment_active_index,
3944
3947
3948 return OPERATOR_FINISHED;
3949}
3950
3952 wmOperator *op,
3953 const wmEvent * /*event*/)
3954{
3957 }
3958 return OPERATOR_CANCELLED;
3959}
3960
3962{
3963 /* identifiers */
3964 ot->name = "Remove Segment";
3965 ot->description = "Remove the active segment from the time modifier";
3966 ot->idname = "OBJECT_OT_grease_pencil_time_modifier_segment_remove";
3967
3968 /* API callbacks. */
3972
3973 /* flags */
3976
3978 ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX);
3979}
3980
3982 Up = -1,
3983 Down = 1,
3984};
3985
3987{
3989 auto *tmd = reinterpret_cast<GreasePencilTimeModifierData *>(
3991
3992 if (tmd == nullptr) {
3993 return OPERATOR_CANCELLED;
3994 }
3995
3996 if (tmd->segments_num < 2) {
3997 return OPERATOR_CANCELLED;
3998 }
3999
4001 RNA_enum_get(op->ptr, "type"));
4002 switch (direction) {
4004 if (tmd->segment_active_index == 0) {
4005 return OPERATOR_CANCELLED;
4006 }
4007
4008 std::swap(tmd->segments_array[tmd->segment_active_index],
4009 tmd->segments_array[tmd->segment_active_index - 1]);
4010
4011 tmd->segment_active_index--;
4012 break;
4014 if (tmd->segment_active_index == tmd->segments_num - 1) {
4015 return OPERATOR_CANCELLED;
4016 }
4017
4018 std::swap(tmd->segments_array[tmd->segment_active_index],
4019 tmd->segments_array[tmd->segment_active_index + 1]);
4020
4021 tmd->segment_active_index++;
4022 break;
4023 default:
4024 return OPERATOR_CANCELLED;
4025 }
4026
4029
4030 return OPERATOR_FINISHED;
4031}
4032
4034 wmOperator *op,
4035 const wmEvent * /*event*/)
4036{
4039 }
4040 return OPERATOR_CANCELLED;
4041}
4042
4044{
4045 static const EnumPropertyItem segment_move[] = {
4046 {int(TimeSegmentMoveDirection::Up), "UP", 0, "Up", ""},
4047 {int(TimeSegmentMoveDirection::Down), "DOWN", 0, "Down", ""},
4048 {0, nullptr, 0, nullptr, nullptr},
4049 };
4050
4051 /* identifiers */
4052 ot->name = "Move Segment";
4053 ot->description = "Move the active time segment up or down";
4054 ot->idname = "OBJECT_OT_grease_pencil_time_modifier_segment_move";
4055
4056 /* API callbacks. */
4060
4061 /* flags */
4064
4065 ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", "");
4066}
4067
4069
4070} // 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:738
@ 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:4555
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)
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)
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:747
#define IDP_bool_set(prop, value)
#define IDP_int_get(prop)
#define IDP_int_set(prop, value)
#define IDP_bool_get(prop)
Key * BKE_key_add(Main *bmain, ID *id)
Definition key.cc:225
KeyBlock * BKE_keyblock_add(Key *key, const char *name)
Definition key.cc:1802
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, blender::MutableSpan< blender::float3 > vert_positions)
Definition key.cc:2186
void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
Definition key.cc:2170
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:514
blender::Array< blender::float3 > BKE_lattice_vert_coords_alloc(const Lattice *lt)
Definition lattice.cc:488
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2523
void BKE_id_free(Main *bmain, void *idv)
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:2001
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
Definition lib_id.cc:777
@ LIB_ID_COPY_ACTIONS
@ LIB_ID_COPY_LOCALIZE
@ LIB_ID_COPY_DEFAULT
void id_us_min(ID *id)
Definition lib_id.cc:366
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:650
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, bool process_shape_keys=true)
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:53
bool multiresModifier_reshapeFromDeformModifier(Depsgraph *depsgraph, Object *ob, MultiresModifierData *mmd, ModifierData *deform_md)
MultiresModifierData * find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
Definition multires.cc:164
void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob)
Definition multires.cc:385
void multires_force_sculpt_rebuild(Object *object)
Definition multires.cc:327
void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
Definition multires.cc:225
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:2806
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:3984
struct ParticleSystem * psys_eval_get(struct Depsgraph *depsgraph, struct Object *object, struct ParticleSystem *psys)
Definition particle.cc:668
void psys_apply_hair_lattice(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys)
Definition particle.cc:5246
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
eReportType
Definition BKE_report.hh:33
@ RPT_INFO
Definition BKE_report.hh:35
@ RPT_ERROR
Definition BKE_report.hh:39
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
Definition scene.cc:2700
struct SoftBody * sbNew(void)
Definition softbody.cc:3107
void sbFree(struct Object *ob)
Definition softbody.cc:3159
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_UTF8(dst, format,...)
#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:188
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:1054
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1077
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
#define ID_REAL_USERS(id)
Definition DNA_ID.h:676
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:769
@ IDP_BOOLEAN
@ IDP_INT
@ ARM_DEF_VGROUP
@ ARM_DEF_QUATERNION
@ BONE_CONNECTED
@ ARM_DRAW_TYPE_STICK
@ CD_MVERT_SKIN
#define DNA_struct_default_get(struct_name)
#define MAX_NAME
Definition DNA_defs.h:50
@ 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_DRAW_IN_FRONT
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ 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.
#define MEM_SAFE_FREE(v)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
@ PROP_HIDDEN
Definition RNA_types.hh:338
#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:1782
@ WM_JOB_PROGRESS
Definition WM_api.hh:1766
#define NC_WINDOW
Definition WM_types.hh:375
@ KM_ALT
Definition WM_types.hh:280
#define ND_MODE
Definition WM_types.hh:445
#define NC_SCENE
Definition WM_types.hh:378
#define NA_ADDED
Definition WM_types.hh:586
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define ND_MODIFIER
Definition WM_types.hh:462
#define NS_MODE_OBJECT
Definition WM_types.hh:560
#define NA_REMOVED
Definition WM_types.hh:587
#define NC_OBJECT
Definition WM_types.hh:379
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:325
const T * begin() const
Definition BLI_array.hh:321
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
void append(const T &value)
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType 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
static const char * modifier_name[LS_MODIFIER_NUM]
Definition linestyle.cc:689
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_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:370
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)
void copy_shared_pointer(T *src_ptr, const ImplicitSharingInfo *src_sharing_info, T **r_dst_ptr, const ImplicitSharingInfo **r_dst_sharing_info)
void free_shared_data(T **data, const ImplicitSharingInfo **sharing_info)
VecBase< int32_t, 2 > int2
const char * name
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)
int RNA_int_get(PointerRNA *ptr, const char *name)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
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
const ImplicitSharingInfoHandle * bind_coords_sharing_info
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:657
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:156
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
int us
Definition DNA_ID.h:443
short flag
Definition DNA_ID.h:438
void * next
Definition DNA_ID.h:417
char type
ListBase block
const ImplicitSharingInfoHandle * vertexco_sharing_info
void * first
ListBase objects
Definition BKE_main.hh:280
void(* bindfunc)(struct Object *object, struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, int verts_num, float cagemat[4][4])
const ImplicitSharingInfoHandle * dyninfluences_sharing_info
const ImplicitSharingInfoHandle * bindinfluences_sharing_info
const ImplicitSharingInfoHandle * dynverts_sharing_info
const ImplicitSharingInfoHandle * dyngrid_sharing_info
const ImplicitSharingInfoHandle * bindcagecos_sharing_info
const ImplicitSharingInfoHandle * bindoffsets_sharing_info
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
ListBase list
Definition BKE_report.hh:75
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:774
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:4238
wmOperatorType * ot
Definition wm_files.cc:4237
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
Definition wm_jobs.cc:376
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:479
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:211
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:388
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
Definition wm_jobs.cc:360
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:145