Blender V4.3
object_edit.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
9#include <cctype>
10#include <cfloat>
11#include <cmath>
12#include <cstddef> /* For `offsetof`. */
13#include <cstdlib>
14#include <cstring>
15#include <ctime>
16
17#include "MEM_guardedalloc.h"
18
19#include "BLI_blenlib.h"
20#include "BLI_ghash.h"
21#include "BLI_math_rotation.h"
22#include "BLI_utildefines.h"
23
24#include "BLT_translation.hh"
25
26#include "DNA_armature_types.h"
27#include "DNA_asset_types.h"
29#include "DNA_curve_types.h"
31#include "DNA_lattice_types.h"
32#include "DNA_material_types.h"
33#include "DNA_mesh_types.h"
34#include "DNA_meta_types.h"
36#include "DNA_object_types.h"
37#include "DNA_scene_types.h"
38#include "DNA_vfont_types.h"
39#include "DNA_workspace_types.h"
40
41#include "IMB_imbuf_types.hh"
42
44#include "BKE_armature.hh"
45#include "BKE_collection.hh"
46#include "BKE_constraint.h"
47#include "BKE_context.hh"
48#include "BKE_curve.hh"
49#include "BKE_editlattice.h"
50#include "BKE_editmesh.hh"
51#include "BKE_effect.h"
52#include "BKE_global.hh"
53#include "BKE_idprop.hh"
54#include "BKE_image.hh"
55#include "BKE_lattice.hh"
56#include "BKE_layer.hh"
57#include "BKE_lib_id.hh"
58#include "BKE_main.hh"
59#include "BKE_material.h"
60#include "BKE_mball.hh"
61#include "BKE_mesh.hh"
62#include "BKE_modifier.hh"
63#include "BKE_node_runtime.hh"
64#include "BKE_object.hh"
65#include "BKE_paint.hh"
66#include "BKE_particle.h"
67#include "BKE_pointcache.h"
68#include "BKE_report.hh"
69#include "BKE_scene.hh"
70#include "BKE_softbody.h"
71#include "BKE_workspace.hh"
72
73#include "DEG_depsgraph.hh"
75
76#include "ED_anim_api.hh"
77#include "ED_armature.hh"
78#include "ED_asset.hh"
80#include "ED_curve.hh"
81#include "ED_gpencil_legacy.hh"
82#include "ED_image.hh"
84#include "ED_lattice.hh"
85#include "ED_mball.hh"
86#include "ED_mesh.hh"
87#include "ED_object.hh"
88#include "ED_outliner.hh"
89#include "ED_screen.hh"
90#include "ED_undo.hh"
91
92#include "RNA_access.hh"
93#include "RNA_define.hh"
94#include "RNA_enum_types.hh"
95#include "RNA_types.hh"
96
97#include "UI_interface_icons.hh"
98
99#include "CLG_log.h"
100
101/* For menu/popup icons etc. */
102
103#include "UI_interface.hh"
104#include "UI_resources.hh"
105
106#include "WM_api.hh"
107#include "WM_message.hh"
108#include "WM_toolsystem.hh"
109#include "WM_types.hh"
110
111#include "MOD_nodes.hh"
112
113#include "object_intern.hh" /* own include */
114
115namespace blender::ed::object {
116
117static CLG_LogRef LOG = {"ed.object.edit"};
118
119/* prototypes */
120struct MoveToCollectionData;
121static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionData *menu);
123
124/* -------------------------------------------------------------------- */
129{
130 return static_cast<Object *>(CTX_data_pointer_get_type(C, "object", &RNA_Object).data);
131}
132
134{
135 Object *ob = nullptr;
136 if (C) {
137 ob = context_object(C);
138 if (!ob) {
140 }
141 }
142 return ob;
143}
144
146 bool (*filter_fn)(const Object *ob, void *user_data),
147 void *filter_user_data)
148{
149 ScrArea *area = CTX_wm_area(C);
150 const Scene *scene = CTX_data_scene(C);
151 ViewLayer *view_layer = CTX_data_view_layer(C);
152 BKE_view_layer_synced_ensure(scene, view_layer);
153 Object *ob_active = BKE_view_layer_active_object_get(view_layer);
154 ID *id_pin = nullptr;
155 const bool use_objects_in_mode = (ob_active != nullptr) &&
156 (ob_active->mode & (OB_MODE_EDIT | OB_MODE_POSE));
157 const eSpace_Type space_type = area ? eSpace_Type(area->spacetype) : SPACE_EMPTY;
158
159 Object *ob = nullptr;
160 bool use_ob = true;
161
162 if (space_type == SPACE_PROPERTIES) {
163 SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first);
164 id_pin = sbuts->pinid;
165 }
166
167 if (id_pin && (GS(id_pin->name) == ID_OB)) {
168 /* Pinned data takes priority, in this case ignore selection & other objects in the mode. */
169 ob = (Object *)id_pin;
170 }
171 else if ((space_type == SPACE_PROPERTIES) && (use_objects_in_mode == false)) {
172 /* When using the space-properties, we don't want to use the entire selection
173 * as the current active object may not be selected.
174 *
175 * This is not the case when we're in a mode that supports multi-mode editing,
176 * since the active object and all other objects in the mode will be included
177 * irrespective of selection. */
178 ob = ob_active;
179 }
180 else if (ob_active && (ob_active->mode &
182 {
183 /* When painting, limit to active. */
184 ob = ob_active;
185 }
186 else {
187 /* Otherwise use full selection. */
188 use_ob = false;
189 }
190
191 if (use_ob) {
192 if ((ob != nullptr) && !filter_fn(ob, filter_user_data)) {
193 ob = nullptr;
194 }
195 return ob ? Vector<Object *>({ob}) : Vector<Object *>();
196 }
197 const View3D *v3d = (space_type == SPACE_VIEW3D) ?
198 static_cast<const View3D *>(area->spacedata.first) :
199 nullptr;
200
201 /* When in a mode that supports multiple active objects, use "objects in mode"
202 * instead of the object's selection. */
203 if (use_objects_in_mode) {
205 params.object_mode = ob_active->mode;
206 params.no_dup_data = true;
207 params.filter_fn = filter_fn;
208 params.filter_userdata = filter_user_data;
209 return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, &params);
210 }
211
213 params.no_dup_data = true;
214 params.filter_fn = filter_fn;
215 params.filter_userdata = filter_user_data;
217}
218
221/* -------------------------------------------------------------------- */
226 ViewLayer *view_layer,
227 const eObjectMode mode,
228 const Object *ob)
229{
230 BLI_assert(ob != nullptr);
231 /* NOTE: the `v3d` is always nullptr because the purpose of this function is to return
232 * a reusable index, using the `v3d` only increases the chance the index may become
233 * invalid-parameters. */
234 int index = -1;
235 int i = 0;
236 FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, nullptr, -1, mode, base_iter) {
237 if (base_iter->object == ob) {
238 index = i;
239 break;
240 }
241 i++;
242 }
244 return index;
245}
246
248 ViewLayer *view_layer,
249 const eObjectMode mode,
250 int index)
251{
252 BLI_assert(index >= 0);
253 Object *ob = nullptr;
254 int i = 0;
255 FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, nullptr, -1, mode, base_iter) {
256 if (index == i) {
257 ob = base_iter->object;
258 break;
259 }
260 i++;
261 }
263 return ob;
264}
265
268/* -------------------------------------------------------------------- */
273{
274 if (CTX_wm_space_outliner(C) != nullptr) {
276 }
278}
279
281{
282 Scene *scene = CTX_data_scene(C);
283 ViewLayer *view_layer = CTX_data_view_layer(C);
284 const bool select = RNA_boolean_get(op->ptr, "select");
285 bool changed = false;
286
287 BKE_view_layer_synced_ensure(scene, view_layer);
289 if (base->flag & BASE_HIDDEN) {
290 base->flag &= ~BASE_HIDDEN;
291 changed = true;
292
293 if (select) {
294 /* We cannot call `base_select` because
295 * base is not selectable while it is hidden. */
296 base->flag |= BASE_SELECTED;
298 }
299 }
300 }
301
302 if (!changed) {
303 return OPERATOR_CANCELLED;
304 }
305
310
311 return OPERATOR_FINISHED;
312}
313
315{
316 /* identifiers */
317 ot->name = "Show Hidden Objects";
318 ot->description = "Reveal temporarily hidden objects";
319 ot->idname = "OBJECT_OT_hide_view_clear";
320
321 /* api callbacks */
324
325 /* flags */
327
328 RNA_def_boolean(ot->srna, "select", true, "Select", "Select revealed objects");
329}
330
332{
333 Scene *scene = CTX_data_scene(C);
334 ViewLayer *view_layer = CTX_data_view_layer(C);
335 const bool unselected = RNA_boolean_get(op->ptr, "unselected");
336 bool changed = false;
337
338 /* Hide selected or unselected objects. */
339 BKE_view_layer_synced_ensure(scene, view_layer);
342 continue;
343 }
344
345 if (!unselected) {
346 if (base->flag & BASE_SELECTED) {
348 base->flag |= BASE_HIDDEN;
349 changed = true;
350 }
351 }
352 else {
353 if (!(base->flag & BASE_SELECTED)) {
355 base->flag |= BASE_HIDDEN;
356 changed = true;
357 }
358 }
359 }
360 if (!changed) {
361 return OPERATOR_CANCELLED;
362 }
363
368
369 return OPERATOR_FINISHED;
370}
371
373{
374 /* identifiers */
375 ot->name = "Hide Objects";
376 ot->description = "Temporarily hide objects from the viewport";
377 ot->idname = "OBJECT_OT_hide_view_set";
378
379 /* api callbacks */
382
383 /* flags */
385
386 PropertyRNA *prop;
387 prop = RNA_def_boolean(
388 ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected objects");
390}
391
393{
394 View3D *v3d = CTX_wm_view3d(C);
395
396 int index = RNA_int_get(op->ptr, "collection_index");
397 const bool extend = RNA_boolean_get(op->ptr, "extend");
398 const bool toggle = RNA_boolean_get(op->ptr, "toggle");
399
400 Scene *scene = CTX_data_scene(C);
401 ViewLayer *view_layer = CTX_data_view_layer(C);
402 LayerCollection *lc = BKE_layer_collection_from_index(view_layer, index);
403
404 if (!lc) {
405 return OPERATOR_CANCELLED;
406 }
407
409
410 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
412 return OPERATOR_CANCELLED;
413 }
414 if (toggle) {
416 BKE_layer_collection_local_sync(scene, view_layer, v3d);
417 }
418 else {
419 BKE_layer_collection_isolate_local(scene, view_layer, v3d, lc, extend);
420 }
421 }
422 else {
423 BKE_layer_collection_isolate_global(scene, view_layer, lc, extend);
424 }
425
427
428 return OPERATOR_FINISHED;
429}
430
431#define COLLECTION_INVALID_INDEX -1
432
434{
435 const Scene *scene = CTX_data_scene(C);
436 ViewLayer *view_layer = CTX_data_view_layer(C);
437 LayerCollection *lc_scene = static_cast<LayerCollection *>(view_layer->layer_collections.first);
438
440
442 int index = BKE_layer_collection_findindex(view_layer, lc);
443 uiLayout *row = uiLayoutRow(layout, false);
444
445 if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
446 continue;
447 }
448
449 if (lc->collection->flag & COLLECTION_HIDE_VIEWPORT) {
450 continue;
451 }
452
453 int icon = ICON_NONE;
454 if (BKE_layer_collection_has_selected_objects(scene, view_layer, lc)) {
455 icon = ICON_LAYER_ACTIVE;
456 }
457 else if (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) {
458 icon = ICON_LAYER_USED;
459 }
460
461 uiItemIntO(row,
462 lc->collection->id.name + 2,
463 icon,
464 "OBJECT_OT_hide_collection",
465 "collection_index",
466 index);
467 }
468}
469
471{
472 /* Immediately execute if collection index was specified. */
473 int index = RNA_int_get(op->ptr, "collection_index");
474 if (index != COLLECTION_INVALID_INDEX) {
475 /* Only initialize extend from the shift key if the property isn't set
476 * (typically initialized from the key-map). */
477 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
478 if (!RNA_property_is_set(op->ptr, prop)) {
479 RNA_property_boolean_set(op->ptr, prop, (event->modifier & KM_SHIFT) != 0);
480 }
481 return object_hide_collection_exec(C, op);
482 }
483
484 /* Open popup menu. */
485 const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
486 uiPopupMenu *pup = UI_popup_menu_begin(C, title, ICON_OUTLINER_COLLECTION);
487 uiLayout *layout = UI_popup_menu_layout(pup);
488
489 collection_hide_menu_draw(C, layout);
490
491 UI_popup_menu_end(C, pup);
492
493 return OPERATOR_INTERFACE;
494}
495
497{
498 /* identifiers */
499 ot->name = "Hide Collection";
500 ot->description = "Show only objects in collection (Shift to extend)";
501 ot->idname = "OBJECT_OT_hide_collection";
502
503 /* api callbacks */
507
508 /* flags */
510
511 /* Properties. */
512 PropertyRNA *prop;
513 prop = RNA_def_int(ot->srna,
514 "collection_index",
517 INT_MAX,
518 "Collection Index",
519 "Index of the collection to change visibility",
520 0,
521 INT_MAX);
523 prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle", "Toggle visibility");
525 prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend visibility");
527}
528
531/* -------------------------------------------------------------------- */
535static bool mesh_needs_keyindex(Main *bmain, const Mesh *mesh)
536{
537 if (mesh->key) {
538 return false; /* will be added */
539 }
540
541 LISTBASE_FOREACH (const Object *, ob, &bmain->objects) {
542 if ((ob->parent) && (ob->parent->data == mesh) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
543 return true;
544 }
545 if (ob->data == mesh) {
546 LISTBASE_FOREACH (const ModifierData *, md, &ob->modifiers) {
547 if (md->type == eModifierType_Hook) {
548 return true;
549 }
550 }
551 }
552 }
553 return false;
554}
555
562static bool editmode_load_free_ex(Main *bmain,
563 Object *obedit,
564 const bool load_data,
565 const bool free_data)
566{
567 BLI_assert(load_data || free_data);
568
569 if (obedit == nullptr) {
570 return false;
571 }
572
573 if (obedit->type == OB_MESH) {
574 Mesh *mesh = static_cast<Mesh *>(obedit->data);
575 if (mesh->runtime->edit_mesh == nullptr) {
576 return false;
577 }
578
579 if (mesh->runtime->edit_mesh->bm->totvert > MESH_MAX_VERTS) {
580 /* This used to be warned int the UI, we could warn again although it's quite rare. */
581 CLOG_WARN(&LOG,
582 "Too many vertices for mesh '%s' (%d)",
583 mesh->id.name + 2,
584 mesh->runtime->edit_mesh->bm->totvert);
585 return false;
586 }
587
588 if (load_data) {
589 EDBM_mesh_load_ex(bmain, obedit, free_data);
590 }
591
592 if (free_data) {
593 EDBM_mesh_free_data(mesh->runtime->edit_mesh.get());
594 mesh->runtime->edit_mesh.reset();
595 }
596 /* will be recalculated as needed. */
597 {
600 }
601 }
602 else if (obedit->type == OB_ARMATURE) {
603 const bArmature *arm = static_cast<const bArmature *>(obedit->data);
604 if (arm->edbo == nullptr) {
605 return false;
606 }
607
608 if (load_data) {
609 ED_armature_from_edit(bmain, static_cast<bArmature *>(obedit->data));
610 }
611
612 if (free_data) {
613 ED_armature_edit_free(static_cast<bArmature *>(obedit->data));
614
615 if (load_data == false) {
616 /* Don't keep unused pose channels created by duplicating bones
617 * which may have been deleted/undone, see: #87631. */
618 if (obedit->pose != nullptr) {
620 }
621 }
622 }
623 /* TODO(sergey): Pose channels might have been changed, so need
624 * to inform dependency graph about this. But is it really the
625 * best place to do this?
626 */
628 }
629 else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
630 const Curve *cu = static_cast<const Curve *>(obedit->data);
631 if (cu->editnurb == nullptr) {
632 return false;
633 }
634
635 if (load_data) {
636 ED_curve_editnurb_load(bmain, obedit);
637 }
638
639 if (free_data) {
641 }
642 }
643 else if (obedit->type == OB_FONT) {
644 const Curve *cu = static_cast<const Curve *>(obedit->data);
645 if (cu->editfont == nullptr) {
646 return false;
647 }
648
649 if (load_data) {
651 }
652
653 if (free_data) {
655 }
656 }
657 else if (obedit->type == OB_LATTICE) {
658 const Lattice *lt = static_cast<const Lattice *>(obedit->data);
659 if (lt->editlatt == nullptr) {
660 return false;
661 }
662
663 if (load_data) {
664 BKE_editlattice_load(obedit);
665 }
666
667 if (free_data) {
668 BKE_editlattice_free(obedit);
669 }
670 }
671 else if (obedit->type == OB_MBALL) {
672 const MetaBall *mb = static_cast<const MetaBall *>(obedit->data);
673 if (mb->editelems == nullptr) {
674 return false;
675 }
676
677 if (load_data) {
679 }
680
681 if (free_data) {
683 }
684 }
685 else if (ELEM(obedit->type, OB_CURVES, OB_GREASE_PENCIL, OB_POINTCLOUD)) {
686 /* Object doesn't have specific edit mode data, so pass. */
687 }
688 else {
689 return false;
690 }
691
692 if (load_data) {
693 char *needs_flush_ptr = BKE_object_data_editmode_flush_ptr_get(
694 static_cast<ID *>(obedit->data));
695 if (needs_flush_ptr) {
696 *needs_flush_ptr = false;
697 }
698 }
699
700 return true;
701}
702
703bool editmode_load(Main *bmain, Object *obedit)
704{
705 return editmode_load_free_ex(bmain, obedit, true, false);
706}
707
708bool editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int flag)
709{
710 const bool free_data = (flag & EM_FREEDATA) != 0;
711
712 if (editmode_load_free_ex(bmain, obedit, true, free_data) == false) {
713 /* in rare cases (background mode) its possible active object
714 * is flagged for editmode, without 'obedit' being set #35489. */
715 if (UNLIKELY(obedit && obedit->mode & OB_MODE_EDIT)) {
716 obedit->mode &= ~OB_MODE_EDIT;
717 /* Also happens when mesh is shared across multiple objects. #69834. */
719 /* Leaving edit mode may modify the original object data; tag that as well. */
720 DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY);
721 }
722 return true;
723 }
724
725 /* `free_data` only false now on file saves and render. */
726 if (free_data) {
727 /* flag object caches as outdated */
728 ListBase pidlist;
729 BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
730 LISTBASE_FOREACH (PTCacheID *, pid, &pidlist) {
731 /* particles don't need reset on geometry change */
732 if (pid->type != PTCACHE_TYPE_PARTICLES) {
733 pid->cache->flag |= PTCACHE_OUTDATED;
734 }
735 }
736 BLI_freelistN(&pidlist);
737
740
741 /* also flush ob recalc, doesn't take much overhead, but used for particles */
743 /* Leaving edit mode may modify the original object data; tag that as well. */
744 DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY);
745
747
748 obedit->mode &= ~OB_MODE_EDIT;
749 }
750
751 return (obedit->mode & OB_MODE_EDIT) == 0;
752}
753
755{
756 Main *bmain = CTX_data_main(C);
757 Scene *scene = CTX_data_scene(C);
758 Object *obedit = CTX_data_edit_object(C);
759 return editmode_exit_ex(bmain, scene, obedit, flag);
760}
761
762bool editmode_free_ex(Main *bmain, Object *obedit)
763{
764 return editmode_load_free_ex(bmain, obedit, false, true);
765}
766
767bool editmode_exit_multi_ex(Main *bmain, Scene *scene, ViewLayer *view_layer, int flag)
768{
769 BKE_view_layer_synced_ensure(scene, view_layer);
770 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
771 if (obedit == nullptr) {
772 return false;
773 }
774 bool changed = false;
775 const short obedit_type = obedit->type;
776
777 BKE_view_layer_synced_ensure(scene, view_layer);
779 Object *ob = base->object;
780 if ((ob->type == obedit_type) && (ob->mode & OB_MODE_EDIT)) {
781 changed |= editmode_exit_ex(bmain, scene, base->object, flag);
782 }
783 }
784 return changed;
785}
786
788{
789 Main *bmain = CTX_data_main(C);
790 Scene *scene = CTX_data_scene(C);
791 ViewLayer *view_layer = CTX_data_view_layer(C);
792 return editmode_exit_multi_ex(bmain, scene, view_layer, flag);
793}
794
795bool editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
796{
797 bool ok = false;
798
799 if (ELEM(nullptr, ob, ob->data) || !ID_IS_EDITABLE(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
801 {
802 return false;
803 }
804
805 /* This checks actual `ob->data`, for cases when other scenes have it in edit-mode context.
806 * Currently multiple objects sharing a mesh being in edit-mode at once isn't supported,
807 * see: #86767. */
809 return true;
810 }
811
813 /* Ideally the caller should check this. */
814 CLOG_WARN(&LOG, "Unable to enter edit-mode on library data for object '%s'", ob->id.name + 2);
815 return false;
816 }
817
818 ob->restore_mode = ob->mode;
819
820 ob->mode = OB_MODE_EDIT;
821
822 if (ob->type == OB_MESH) {
823 ok = true;
824
825 const bool use_key_index = mesh_needs_keyindex(bmain, static_cast<const Mesh *>(ob->data));
826
827 EDBM_mesh_make(ob, scene->toolsettings->selectmode, use_key_index);
828
830 if (LIKELY(em)) {
832 }
833
835 }
836 else if (ob->type == OB_ARMATURE) {
837 bArmature *arm = static_cast<bArmature *>(ob->data);
838 ok = true;
840 /* To ensure all goes in rest-position and without striding. */
841
842 arm->needs_flush_to_id = 0;
843
844 /* WORKAROUND / FIXME: this is a temporary workaround to ensure that
845 * full bone collection data gets restored when exiting edit mode
846 * via an undo step. The correct fix is to have a full edit-mode
847 * copy of bone collections so that edit-mode changes don't modify
848 * object-mode armature data until exiting edit mode. But that
849 * change is a bit of a project, and will be done later. This line
850 * should be removed when that is done. */
851 bmain->is_memfile_undo_written = false;
852
853 /* XXX: should this be ID_RECALC_GEOMETRY? */
855
857 }
858 else if (ob->type == OB_FONT) {
859 ok = true;
861
863 }
864 else if (ob->type == OB_MBALL) {
865 MetaBall *mb = static_cast<MetaBall *>(ob->data);
866
867 ok = true;
869
870 mb->needs_flush_to_id = 0;
871
873 }
874 else if (ob->type == OB_LATTICE) {
875 ok = true;
877
879 }
880 else if (ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY)) {
881 ok = true;
883
885 }
886 else if (ob->type == OB_CURVES) {
887 ok = true;
889 }
890 else if (ob->type == OB_GREASE_PENCIL) {
891 ok = true;
893 }
894 else if (ob->type == OB_POINTCLOUD) {
895 ok = true;
897 }
898
899 if (ok) {
901 }
902 else {
903 if ((flag & EM_NO_CONTEXT) == 0) {
904 ob->mode &= ~OB_MODE_EDIT;
905 }
907 }
908
909 return (ob->mode & OB_MODE_EDIT) != 0;
910}
911
913{
914 Main *bmain = CTX_data_main(C);
915 Scene *scene = CTX_data_scene(C);
916
917 /* Active layer checked here for view3d,
918 * callers that don't want view context can call the extended version. */
920 return editmode_enter_ex(bmain, scene, ob, flag);
921}
922
924{
925 Main *bmain = CTX_data_main(C);
926 Scene *scene = CTX_data_scene(C);
927 View3D *v3d = CTX_wm_view3d(C);
928 ViewLayer *view_layer = CTX_data_view_layer(C);
929 BKE_view_layer_synced_ensure(scene, view_layer);
930 Object *obact = BKE_view_layer_active_object_get(view_layer);
931 const int mode_flag = OB_MODE_EDIT;
932 const bool is_mode_set = (obact->mode & mode_flag) != 0;
933 wmMsgBus *mbus = CTX_wm_message_bus(C);
934
935 if (!is_mode_set) {
936 if (!mode_compat_set(C, obact, eObjectMode(mode_flag), op->reports)) {
937 return OPERATOR_CANCELLED;
938 }
939 }
940
941 if (!is_mode_set) {
942 editmode_enter_ex(bmain, scene, obact, 0);
943 /* Grease Pencil does not support multi-object editing. */
944 if ((obact->type != OB_GREASE_PENCIL) && ((obact->mode & mode_flag) != 0)) {
945 FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
946 if ((ob != obact) && (ob->type == obact->type)) {
947 editmode_enter_ex(bmain, scene, ob, EM_NO_CONTEXT);
948 }
949 }
951 }
952 }
953 else {
954 editmode_exit_ex(bmain, scene, obact, EM_FREEDATA);
955
956 if ((obact->mode & mode_flag) == 0) {
957 FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
958 if ((ob != obact) && (ob->type == obact->type)) {
959 editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
960 }
961 }
963 }
964 }
965
966 WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
967
968 if (G.background == false) {
970 }
971
972 return OPERATOR_FINISHED;
973}
974
976{
978
979 /* Covers liboverrides too. */
980 if (ELEM(nullptr, ob, ob->data) || !ID_IS_EDITABLE(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob) ||
982 {
983 return false;
984 }
985
986 /* If hidden but in edit mode, we still display. */
987 if ((ob->visibility_flag & OB_HIDE_VIEWPORT) && !(ob->mode & OB_MODE_EDIT)) {
988 return false;
989 }
990
991 return OB_TYPE_SUPPORT_EDITMODE(ob->type);
992}
993
995{
996
997 /* identifiers */
998 ot->name = "Toggle Edit Mode";
999 ot->description = "Toggle object's edit mode";
1000 ot->idname = "OBJECT_OT_editmode_toggle";
1001
1002 /* api callbacks */
1005
1006 /* flags */
1008}
1009
1012/* -------------------------------------------------------------------- */
1017{
1018 wmMsgBus *mbus = CTX_wm_message_bus(C);
1019 Main *bmain = CTX_data_main(C);
1020 Scene *scene = CTX_data_scene(C);
1021 ViewLayer *view_layer = CTX_data_view_layer(C);
1022 Base *base = CTX_data_active_base(C);
1023
1024 /* If the base is nullptr it means we have an active object, but the object itself is hidden. */
1025 if (base == nullptr) {
1026 return OPERATOR_CANCELLED;
1027 }
1028
1029 Object *obact = base->object;
1030 const int mode_flag = OB_MODE_POSE;
1031 bool is_mode_set = (obact->mode & mode_flag) != 0;
1032
1033 if (!is_mode_set) {
1034 if (!mode_compat_set(C, obact, eObjectMode(mode_flag), op->reports)) {
1035 return OPERATOR_CANCELLED;
1036 }
1037 }
1038
1039 if (obact->type != OB_ARMATURE) {
1040 return OPERATOR_PASS_THROUGH;
1041 }
1042
1043 {
1044 BKE_view_layer_synced_ensure(scene, view_layer);
1045 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
1046 if (obact == obedit) {
1047 editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
1048 is_mode_set = false;
1049 }
1050 }
1051
1052 if (is_mode_set) {
1053 bool ok = ED_object_posemode_exit(C, obact);
1054 if (ok) {
1055 FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
1056 if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode & mode_flag)) {
1057 ED_object_posemode_exit_ex(bmain, ob);
1058 }
1059 }
1061 }
1062 }
1063 else {
1064 bool ok = ED_object_posemode_enter(C, obact);
1065 if (ok) {
1066 const View3D *v3d = CTX_wm_view3d(C);
1067 FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
1068 if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode == OB_MODE_OBJECT) &&
1069 BKE_id_is_editable(bmain, &ob->id))
1070 {
1071 ED_object_posemode_enter_ex(bmain, ob);
1072 }
1073 }
1075 }
1076 }
1077
1078 WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
1079
1080 if (G.background == false) {
1082 }
1083
1084 return OPERATOR_FINISHED;
1085}
1086
1088{
1089 /* identifiers */
1090 ot->name = "Toggle Pose Mode";
1091 ot->idname = "OBJECT_OT_posemode_toggle";
1092 ot->description = "Enable or disable posing/selecting bones";
1093
1094 /* api callbacks */
1097
1098 /* flag */
1100}
1101
1104/* -------------------------------------------------------------------- */
1108void check_force_modifiers(Main *bmain, Scene *scene, Object *object)
1109{
1110 PartDeflect *pd = object->pd;
1112
1113 /* add/remove modifier as needed */
1114 if (!md) {
1115 if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) &&
1117 {
1118 if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVES_LEGACY)) {
1119 modifier_add(nullptr, bmain, scene, object, nullptr, eModifierType_Surface);
1120 }
1121 }
1122 }
1123 else {
1124 if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) ||
1126 {
1127 modifier_remove(nullptr, bmain, scene, object, md);
1128 }
1129 }
1130}
1131
1133{
1135
1136 if (ob->pd == nullptr) {
1139 }
1140 else if (ob->pd->forcefield == 0) {
1141 ob->pd->forcefield = PFIELD_FORCE;
1143 }
1144 else {
1145 ob->pd->forcefield = 0;
1146 }
1147
1151
1153
1154 return OPERATOR_FINISHED;
1155}
1156
1158{
1159
1160 /* identifiers */
1161 ot->name = "Toggle Force Field";
1162 ot->description = "Toggle object's force field";
1163 ot->idname = "OBJECT_OT_forcefield_toggle";
1164
1165 /* api callbacks */
1168
1169 /* flags */
1171}
1172
1175/* -------------------------------------------------------------------- */
1191
1193{
1194 ListBase selected_objects = {nullptr, nullptr};
1195 CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1196 BLI_addtail(&selected_objects, BLI_genericNodeN(ob));
1197 }
1199
1200 motion_paths_recalc(C, scene, range, &selected_objects);
1201
1202 BLI_freelistN(&selected_objects);
1203}
1204
1206{
1207 ListBase visible_objects = {nullptr, nullptr};
1208 CTX_DATA_BEGIN (C, Object *, ob, visible_objects) {
1209 BLI_addtail(&visible_objects, BLI_genericNodeN(ob));
1210 }
1212
1213 motion_paths_recalc(C, scene, range, &visible_objects);
1214
1215 BLI_freelistN(&visible_objects);
1216}
1217
1219{
1220 return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
1221}
1222
1224{
1225 return ob->pose && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
1226}
1227
1229 Scene *scene,
1231 ListBase *ld_objects)
1232{
1233 /* Transform doesn't always have context available to do update. */
1234 if (C == nullptr) {
1235 return;
1236 }
1237
1238 Main *bmain = CTX_data_main(C);
1239 ViewLayer *view_layer = CTX_data_view_layer(C);
1240
1241 ListBase targets = {nullptr, nullptr};
1242 LISTBASE_FOREACH (LinkData *, link, ld_objects) {
1243 Object *ob = static_cast<Object *>(link->data);
1244
1245 /* set flag to force recalc, then grab path(s) from object */
1246 if (has_object_motion_paths(ob)) {
1248 }
1249
1250 if (has_pose_motion_paths(ob)) {
1252 }
1253
1254 animviz_get_object_motionpaths(ob, &targets);
1255 }
1256
1257 Depsgraph *depsgraph;
1258 bool free_depsgraph = false;
1259 /* For a single frame update it's faster to re-use existing dependency graph and avoid overhead
1260 * of building all the relations and so on for a temporary one. */
1262 /* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
1263 * nested pointers, like animation data. */
1265 free_depsgraph = false;
1266 }
1267 else {
1268 depsgraph = animviz_depsgraph_build(bmain, scene, view_layer, &targets);
1269 free_depsgraph = true;
1270 }
1271
1272 /* recalculate paths, then free */
1274 depsgraph, bmain, scene, &targets, object_path_convert_range(range), true);
1275 BLI_freelistN(&targets);
1276
1278 /* Tag objects for copy-on-eval - so paths will draw/redraw
1279 * For currently frame only we update evaluated object directly. */
1280 LISTBASE_FOREACH (LinkData *, link, ld_objects) {
1281 Object *ob = static_cast<Object *>(link->data);
1282
1285 }
1286 }
1287 }
1288
1289 /* Free temporary depsgraph. */
1290 if (free_depsgraph) {
1292 }
1293}
1294
1295/* show popup to determine settings */
1296static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
1297{
1299
1300 if (ob == nullptr) {
1301 return OPERATOR_CANCELLED;
1302 }
1303
1304 /* set default settings from existing/stored settings */
1305 {
1306 bAnimVizSettings *avs = &ob->avs;
1307 RNA_enum_set(op->ptr, "display_type", avs->path_type);
1308 RNA_enum_set(op->ptr, "range", avs->path_range);
1309 }
1310
1311 /* show popup dialog to allow editing of range... */
1312 /* FIXME: hard-coded dimensions here are just arbitrary. */
1314 C, op, 270, IFACE_("Calculate Object Motion Paths"), IFACE_("Calculate"));
1315}
1316
1317/* Calculate/recalculate whole paths (avs.path_sf to avs.path_ef) */
1319{
1320 Scene *scene = CTX_data_scene(C);
1321 short path_type = RNA_enum_get(op->ptr, "display_type");
1322 short path_range = RNA_enum_get(op->ptr, "range");
1323
1324 /* set up path data for objects being calculated */
1325 CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1326 bAnimVizSettings *avs = &ob->avs;
1327 /* grab baking settings from operator settings */
1328 avs->path_type = path_type;
1329 avs->path_range = path_range;
1331
1332 /* verify that the selected object has the appropriate settings */
1333 animviz_verify_motionpaths(op->reports, scene, ob, nullptr);
1334 }
1336
1337 /* calculate the paths for objects that have them (and are tagged to get refreshed) */
1339
1340 /* notifiers for updates */
1342 /* NOTE: the notifier below isn't actually correct, but kept around just to be on the safe side.
1343 * If further testing shows it's not necessary (for both bones and objects) removal is fine. */
1345
1346 return OPERATOR_FINISHED;
1347}
1348
1350{
1351 /* identifiers */
1352 ot->name = "Calculate Object Motion Paths";
1353 ot->idname = "OBJECT_OT_paths_calculate";
1354 ot->description = "Generate motion paths for the selected objects";
1355
1356 /* api callbacks */
1360
1361 /* flags */
1363
1364 /* properties */
1366 "display_type",
1369 "Display type",
1370 "");
1372 "range",
1375 "Computation Range",
1376 "");
1377}
1378
1381/* -------------------------------------------------------------------- */
1386{
1389 return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
1390 }
1391
1392 return false;
1393}
1394
1396{
1397 Scene *scene = CTX_data_scene(C);
1398
1399 if (scene == nullptr) {
1400 return OPERATOR_CANCELLED;
1401 }
1402 CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1404 /* verify that the selected object has the appropriate settings */
1405 animviz_verify_motionpaths(op->reports, scene, ob, nullptr);
1406 }
1408
1409 /* calculate the paths for objects that have them (and are tagged to get refreshed) */
1411
1412 /* notifiers for updates */
1414 /* NOTE: the notifier below isn't actually correct, but kept around just to be on the safe side.
1415 * If further testing shows it's not necessary (for both bones and objects) removal is fine. */
1417
1418 return OPERATOR_FINISHED;
1419}
1420
1422{
1423 /* identifiers */
1424 ot->name = "Update Object Paths";
1425 ot->idname = "OBJECT_OT_paths_update";
1426 ot->description = "Recalculate motion paths for selected objects";
1427
1428 /* api callbacks */
1431
1432 /* flags */
1434}
1435
1438/* -------------------------------------------------------------------- */
1443{
1444 return true;
1445}
1446
1448{
1449 Scene *scene = CTX_data_scene(C);
1450
1451 if (scene == nullptr) {
1452 return OPERATOR_CANCELLED;
1453 }
1454
1456
1458
1459 return OPERATOR_FINISHED;
1460}
1461
1463{
1464 /* identifiers */
1465 ot->name = "Update All Object Paths";
1466 ot->idname = "OBJECT_OT_paths_update_visible";
1467 ot->description = "Recalculate all visible motion paths for objects and poses";
1468
1469 /* api callbacks */
1472
1473 /* flags */
1475}
1476
1479/* -------------------------------------------------------------------- */
1483/* Helper for motion_paths_clear() */
1485{
1486 if (ob->mpath) {
1488 ob->mpath = nullptr;
1489 ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
1490
1491 /* tag object for copy-on-eval - so removed paths don't still show */
1493 }
1494}
1495
1496void motion_paths_clear(bContext *C, bool only_selected)
1497{
1498 if (only_selected) {
1499 /* Loop over all selected + editable objects in scene. */
1500 CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1502 }
1504 }
1505 else {
1506 /* Loop over all editable objects in scene. */
1507 CTX_DATA_BEGIN (C, Object *, ob, editable_objects) {
1509 }
1511 }
1512}
1513
1514/* operator callback for this */
1516{
1517 bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
1518
1519 /* use the backend function for this */
1520 motion_paths_clear(C, only_selected);
1521
1522 /* notifiers for updates */
1524
1525 return OPERATOR_FINISHED;
1526}
1527
1529 wmOperatorType * /*ot*/,
1530 PointerRNA *ptr)
1531{
1532 const bool only_selected = RNA_boolean_get(ptr, "only_selected");
1533 if (only_selected) {
1534 return TIP_("Clear motion paths of selected objects");
1535 }
1536 return TIP_("Clear motion paths of all objects");
1537}
1538
1540{
1541 /* identifiers */
1542 ot->name = "Clear Object Paths";
1543 ot->idname = "OBJECT_OT_paths_clear";
1544
1545 /* api callbacks */
1549
1550 /* flags */
1552
1553 /* properties */
1555 "only_selected",
1556 false,
1557 "Only Selected",
1558 "Only clear motion paths of selected objects");
1560}
1561
1564/* -------------------------------------------------------------------- */
1569{
1570 if (md.type != eModifierType_Nodes) {
1571 return false;
1572 }
1573 const NodesModifierData &nmd = reinterpret_cast<const NodesModifierData &>(md);
1574 if (!nmd.node_group) {
1575 return false;
1576 }
1577 const LibraryWeakReference *library_ref = nmd.node_group->id.library_weak_reference;
1578 if (!library_ref) {
1579 return false;
1580 }
1581 if (!STREQ(library_ref->library_id_name + 2, "Smooth by Angle")) {
1582 return false;
1583 }
1584 return true;
1585}
1586
1588{
1589 const bool use_flat = STREQ(op->idname, "OBJECT_OT_shade_flat");
1590 const bool use_smooth = STREQ(op->idname, "OBJECT_OT_shade_smooth");
1591 const bool use_smooth_by_angle = STREQ(op->idname, "OBJECT_OT_shade_smooth_by_angle");
1592 Main *bmain = CTX_data_main(C);
1593 Scene *scene = CTX_data_scene(C);
1594
1595 Vector<PointerRNA> ctx_objects;
1596
1597 /* For modes that only use an active object, don't handle the whole selection. */
1598 {
1599 Scene *scene = CTX_data_scene(C);
1600 ViewLayer *view_layer = CTX_data_view_layer(C);
1601 BKE_view_layer_synced_ensure(scene, view_layer);
1602 Object *obact = BKE_view_layer_active_object_get(view_layer);
1603 if (obact && (obact->mode & OB_MODE_ALL_PAINT)) {
1604 ctx_objects.append(RNA_id_pointer_create(&obact->id));
1605 }
1606 }
1607
1608 if (ctx_objects.is_empty()) {
1609 CTX_data_selected_editable_objects(C, &ctx_objects);
1610 }
1611
1612 bool modifier_removed = false;
1613
1614 Set<ID *> object_data;
1615 for (const PointerRNA &ptr : ctx_objects) {
1616 Object *ob = static_cast<Object *>(ptr.data);
1617 if (ID *data = static_cast<ID *>(ob->data)) {
1618 object_data.add(data);
1619
1620 if (ob->type == OB_MESH) {
1621 if (use_flat || use_smooth) {
1623 if (is_smooth_by_angle_modifier(*md)) {
1624 modifier_remove(op->reports, bmain, scene, ob, md);
1626 modifier_removed = true;
1627 break;
1628 }
1629 }
1630 }
1631 }
1632 }
1633 }
1634
1635 bool changed_multi = false;
1636 bool has_linked_data = false;
1637 for (ID *data : object_data) {
1638 if (!BKE_id_is_editable(bmain, data)) {
1639 has_linked_data = true;
1640 continue;
1641 }
1642
1643 bool changed = false;
1644 if (GS(data->name) == ID_ME) {
1645 Mesh &mesh = *reinterpret_cast<Mesh *>(data);
1646 const bool keep_sharp_edges = RNA_boolean_get(op->ptr, "keep_sharp_edges");
1647 bke::mesh_smooth_set(mesh, use_smooth || use_smooth_by_angle, keep_sharp_edges);
1648 if (use_smooth_by_angle) {
1649 const float angle = RNA_float_get(op->ptr, "angle");
1650 bke::mesh_sharp_edges_set_from_angle(mesh, angle, keep_sharp_edges);
1651 }
1653 changed = true;
1654 }
1655 else if (GS(data->name) == ID_CU_LEGACY) {
1656 BKE_curve_smooth_flag_set(reinterpret_cast<Curve *>(data), use_smooth);
1657 changed = true;
1658 }
1659
1660 if (changed) {
1661 changed_multi = true;
1664 }
1665 }
1666
1667 if (modifier_removed) {
1668 /* Outliner needs to know. #124302. */
1670 }
1671
1672 if (has_linked_data) {
1673 BKE_report(op->reports, RPT_WARNING, "Can't edit linked mesh or curve data");
1674 }
1675
1676 return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1677}
1678
1679static bool shade_poll(bContext *C)
1680{
1681 const Scene *scene = CTX_data_scene(C);
1682 ViewLayer *view_layer = CTX_data_view_layer(C);
1683 BKE_view_layer_synced_ensure(scene, view_layer);
1684 Object *obact = BKE_view_layer_active_object_get(view_layer);
1685 if (obact != nullptr) {
1686 /* Doesn't handle edit-data, sculpt dynamic-topology, or their undo systems. */
1687 if (obact->mode & (OB_MODE_EDIT | OB_MODE_SCULPT) || obact->data == nullptr ||
1688 !ID_IS_EDITABLE(obact) || !ID_IS_EDITABLE(obact->data) || ID_IS_OVERRIDE_LIBRARY(obact) ||
1690 {
1691 return false;
1692 }
1693 }
1694 return true;
1695}
1696
1698{
1699 /* identifiers */
1700 ot->name = "Shade Flat";
1701 ot->description = "Render and display faces uniform, using face normals";
1702 ot->idname = "OBJECT_OT_shade_flat";
1703
1704 /* api callbacks */
1705 ot->poll = shade_poll;
1707
1708 /* flags */
1710
1712 "keep_sharp_edges",
1713 true,
1714 "Keep Sharp Edges",
1715 "Don't remove sharp edges, which are redundant with faces shaded smooth");
1716}
1717
1719{
1720 /* identifiers */
1721 ot->name = "Shade Smooth";
1722 ot->description = "Render and display faces smooth, using interpolated vertex normals";
1723 ot->idname = "OBJECT_OT_shade_smooth";
1724
1725 /* api callbacks */
1726 ot->poll = shade_poll;
1728
1729 /* flags */
1731
1733 "keep_sharp_edges",
1734 true,
1735 "Keep Sharp Edges",
1736 "Don't remove sharp edges. Tagged edges will remain sharp");
1737}
1738
1740{
1741 ot->name = "Shade Smooth by Angle";
1742 ot->description =
1743 "Set the sharpness of mesh edges based on the angle between the neighboring faces";
1744 ot->idname = "OBJECT_OT_shade_smooth_by_angle";
1745
1746 ot->poll = shade_poll;
1748
1750
1752 RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
1755 prop, "Angle", "Maximum angle between face normals that will be considered as smooth");
1756
1758 "keep_sharp_edges",
1759 true,
1760 "Keep Sharp Edges",
1761 "Only add sharp edges instead of clearing existing tags first");
1762}
1763
1766/* -------------------------------------------------------------------- */
1771{
1772 Main &bmain = *CTX_data_main(C);
1773 Scene &scene = *CTX_data_scene(C);
1774
1775 const bool use_auto_smooth = RNA_boolean_get(op->ptr, "use_auto_smooth");
1776 const float angle = RNA_float_get(op->ptr, "angle");
1777
1778 Vector<PointerRNA> ctx_objects;
1779 CTX_data_selected_editable_objects(C, &ctx_objects);
1780
1781 if (use_auto_smooth) {
1782 AssetWeakReference asset_weak_ref{};
1784 asset_weak_ref.relative_asset_identifier = BLI_strdup(
1785 "geometry_nodes/smooth_by_angle.blend/NodeTree/Smooth by Angle");
1786
1787 const asset_system::AssetRepresentation *asset_representation =
1788 asset::find_asset_from_weak_ref(*C, asset_weak_ref, op->reports);
1789 if (!asset_representation) {
1790 return OPERATOR_CANCELLED;
1791 }
1792
1793 ID *node_group_id = asset::asset_local_id_ensure_imported(bmain, *asset_representation);
1794 if (!node_group_id) {
1795 return OPERATOR_CANCELLED;
1796 }
1797 if (GS(node_group_id->name) != ID_NT) {
1798 return OPERATOR_CANCELLED;
1799 }
1800 bNodeTree *node_group = reinterpret_cast<bNodeTree *>(node_group_id);
1801 node_group->ensure_topology_cache();
1802
1803 const StringRefNull angle_identifier = node_group->interface_inputs()[1]->identifier;
1804
1805 for (const PointerRNA &ob_ptr : ctx_objects) {
1806 Object *object = static_cast<Object *>(ob_ptr.data);
1807 if (object->type == OB_MESH) {
1808 Mesh *mesh = static_cast<Mesh *>(object->data);
1809 bke::mesh_smooth_set(*mesh, true, true);
1811 }
1812 NodesModifierData *smooth_by_angle_nmd = nullptr;
1813 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1814 if (is_smooth_by_angle_modifier(*md)) {
1815 smooth_by_angle_nmd = reinterpret_cast<NodesModifierData *>(md);
1816 break;
1817 }
1818 }
1819 if (!smooth_by_angle_nmd) {
1820 smooth_by_angle_nmd = reinterpret_cast<NodesModifierData *>(
1821 modifier_add(op->reports, &bmain, &scene, object, nullptr, eModifierType_Nodes));
1822 if (!smooth_by_angle_nmd) {
1823 continue;
1824 }
1825 smooth_by_angle_nmd->modifier.flag |= eModifierFlag_PinLast;
1826 smooth_by_angle_nmd->node_group = node_group;
1827 id_us_plus(&node_group->id);
1828 MOD_nodes_update_interface(object, smooth_by_angle_nmd);
1829 smooth_by_angle_nmd->flag |= NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR;
1830 STRNCPY(smooth_by_angle_nmd->modifier.name, DATA_(node_group->id.name + 2));
1831 BKE_modifier_unique_name(&object->modifiers, &smooth_by_angle_nmd->modifier);
1832 }
1833
1834 IDProperty *angle_prop = IDP_GetPropertyFromGroup(smooth_by_angle_nmd->settings.properties,
1835 angle_identifier.c_str());
1836 if (angle_prop->type == IDP_FLOAT) {
1837 IDP_Float(angle_prop) = angle;
1838 }
1839 else if (angle_prop->type == IDP_DOUBLE) {
1840 IDP_Double(angle_prop) = angle;
1841 }
1842
1845 }
1846 }
1847 else {
1848 for (const PointerRNA &ob_ptr : ctx_objects) {
1849 Object *object = static_cast<Object *>(ob_ptr.data);
1850 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1851 if (is_smooth_by_angle_modifier(*md)) {
1852 modifier_remove(op->reports, &bmain, &scene, object, md);
1853 break;
1854 }
1855 }
1856 }
1857 }
1858
1859 return OPERATOR_FINISHED;
1860}
1861
1863{
1864 uiLayout *layout = op->layout;
1865
1866 uiLayoutSetPropSep(layout, true);
1867 uiLayoutSetPropDecorate(layout, false);
1868
1869 uiItemR(layout, op->ptr, "use_auto_smooth", UI_ITEM_NONE, nullptr, ICON_NONE);
1870
1871 uiLayout *col = uiLayoutColumn(layout, false);
1872 uiLayoutSetActive(col, RNA_boolean_get(op->ptr, "use_auto_smooth"));
1873 uiItemR(layout, op->ptr, "angle", UI_ITEM_NONE, nullptr, ICON_NONE);
1874}
1875
1877{
1878 ot->name = "Shade Auto Smooth";
1879 ot->description =
1880 "Add modifier to automatically set the sharpness of mesh edges based on the angle between "
1881 "the neighboring faces";
1882 ot->idname = "OBJECT_OT_shade_auto_smooth";
1883
1884 ot->poll = shade_poll;
1887
1889
1890 PropertyRNA *prop;
1891
1892 prop = RNA_def_boolean(ot->srna,
1893 "use_auto_smooth",
1894 true,
1895 "Auto Smooth",
1896 "Add modifier to set edge sharpness automatically");
1898
1899 prop = RNA_def_property(ot->srna, "angle", PROP_FLOAT, PROP_ANGLE);
1900 RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
1903 prop, "Angle", "Maximum angle between face normals that will be considered as smooth");
1904}
1905
1908/* -------------------------------------------------------------------- */
1913 PointerRNA * /*ptr*/,
1914 PropertyRNA * /*prop*/,
1915 bool *r_free)
1916{
1918 EnumPropertyItem *item = nullptr;
1919 int totitem = 0;
1920
1921 if (!C) { /* needed for docs */
1923 }
1924
1925 const Object *ob = CTX_data_active_object(C);
1926 if (ob) {
1927 while (input->identifier) {
1928 if (mode_compat_test(ob, eObjectMode(input->value))) {
1929 RNA_enum_item_add(&item, &totitem, input);
1930 }
1931 input++;
1932 }
1933 }
1934 else {
1935 /* We need at least this one! */
1936 RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT);
1937 }
1938
1939 RNA_enum_item_end(&item, &totitem);
1940
1941 *r_free = true;
1942
1943 return item;
1944}
1945
1947{
1948 /* Needed as #ED_operator_object_active_editable doesn't call use 'active_object'. */
1951}
1952
1954{
1955 const bool use_submode = STREQ(op->idname, "OBJECT_OT_mode_set_with_submode");
1957 eObjectMode mode = eObjectMode(RNA_enum_get(op->ptr, "mode"));
1958 const bool toggle = RNA_boolean_get(op->ptr, "toggle");
1959
1960 /* by default the operator assume is a mesh, but if gp object change mode */
1961 if ((ob->type == OB_GPENCIL_LEGACY) && (mode == OB_MODE_EDIT)) {
1963 }
1964
1965 if (!mode_compat_test(ob, mode)) {
1966 return OPERATOR_PASS_THROUGH;
1967 }
1968
1987 if (toggle == false) {
1988 if (ob->mode != mode) {
1989 mode_set_ex(C, mode, true, op->reports);
1990 }
1991 }
1992 else {
1993 const eObjectMode mode_prev = eObjectMode(ob->mode);
1994 /* When toggling object mode, we always use the restore mode,
1995 * otherwise there is nothing to do. */
1996 if (mode == OB_MODE_OBJECT) {
1997 if (ob->mode != OB_MODE_OBJECT) {
1998 if (mode_set_ex(C, OB_MODE_OBJECT, true, op->reports)) {
1999 /* Store old mode so we know what to go back to. */
2000 ob->restore_mode = mode_prev;
2001 }
2002 }
2003 else {
2004 if (ob->restore_mode != OB_MODE_OBJECT) {
2005 mode_set_ex(C, eObjectMode(ob->restore_mode), true, op->reports);
2006 }
2007 }
2008 }
2009 else {
2010 /* Non-object modes, enter the 'mode' unless it's already set,
2011 * in that case use restore mode. */
2012 if (ob->mode != mode) {
2013 if (mode_set_ex(C, mode, true, op->reports)) {
2014 /* Store old mode so we know what to go back to. */
2015 ob->restore_mode = mode_prev;
2016 }
2017 }
2018 else {
2019 if (ob->restore_mode != OB_MODE_OBJECT) {
2020 mode_set_ex(C, eObjectMode(ob->restore_mode), true, op->reports);
2021 }
2022 else {
2023 mode_set_ex(C, OB_MODE_OBJECT, true, op->reports);
2024 }
2025 }
2026 }
2027 }
2028
2029 if (use_submode) {
2030 if (ob->type == OB_MESH) {
2031 if (ob->mode & OB_MODE_EDIT) {
2032 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "mesh_select_mode");
2033 if (RNA_property_is_set(op->ptr, prop)) {
2034 int mesh_select_mode = RNA_property_enum_get(op->ptr, prop);
2035 if (mesh_select_mode != 0) {
2036 EDBM_selectmode_set_multi(C, mesh_select_mode);
2037 }
2038 }
2039 }
2040 }
2041 }
2042
2044 if (wm) {
2045 if (WM_autosave_is_scheduled(wm)) {
2047 }
2048 }
2049
2050 return OPERATOR_FINISHED;
2051}
2052
2054{
2055 PropertyRNA *prop;
2056
2057 /* identifiers */
2058 ot->name = "Set Object Mode";
2059 ot->description = "Sets the object interaction mode";
2060 ot->idname = "OBJECT_OT_mode_set";
2061
2062 /* api callbacks */
2065
2066 /* flags */
2067 ot->flag = 0; /* no register/undo here, leave it to operators being called */
2068
2069 ot->prop = RNA_def_enum(
2070 ot->srna, "mode", rna_enum_object_mode_items, OB_MODE_OBJECT, "Mode", "");
2073
2074 prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle", "");
2076}
2077
2079{
2081
2082 /* identifiers */
2083 ot->name = "Set Object Mode with Sub-mode";
2084 ot->idname = "OBJECT_OT_mode_set_with_submode";
2085
2086 /* properties */
2087 /* we could add other types - particle for eg. */
2088 PropertyRNA *prop;
2089 prop = RNA_def_enum_flag(
2090 ot->srna, "mesh_select_mode", rna_enum_mesh_select_mode_items, 0, "Mesh Mode", "");
2092}
2093
2096/* -------------------------------------------------------------------- */
2101{
2102 ListBase objects = {nullptr};
2103
2104 if (CTX_wm_space_outliner(C) != nullptr) {
2106 }
2107 else {
2108 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
2109 BLI_addtail(&objects, BLI_genericNodeN(ob));
2110 }
2112 }
2113
2114 return objects;
2115}
2116
2118{
2119 if (CTX_wm_space_outliner(C) != nullptr) {
2121 }
2122 return ED_operator_objectmode(C);
2123}
2124
2126{
2127 Main *bmain = CTX_data_main(C);
2128 Scene *scene = CTX_data_scene(C);
2129 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "collection_index");
2130 const bool is_link = STREQ(op->idname, "OBJECT_OT_link_to_collection");
2131 const bool is_new = RNA_boolean_get(op->ptr, "is_new");
2132
2133 if (!RNA_property_is_set(op->ptr, prop)) {
2134 BKE_report(op->reports, RPT_ERROR, "No collection selected");
2135 return OPERATOR_CANCELLED;
2136 }
2137
2138 int collection_index = RNA_property_int_get(op->ptr, prop);
2139 Collection *collection = BKE_collection_from_index(scene, collection_index);
2140 if (collection == nullptr) {
2141 BKE_report(op->reports, RPT_ERROR, "Unexpected error, collection not found");
2142 return OPERATOR_CANCELLED;
2143 }
2144
2145 if (!ID_IS_EDITABLE(collection) || ID_IS_OVERRIDE_LIBRARY(collection)) {
2146 BKE_report(
2147 op->reports, RPT_ERROR, "Cannot add objects to a library override or linked collection");
2148 return OPERATOR_CANCELLED;
2149 }
2150
2151 ListBase objects = selected_objects_get(C);
2152
2153 if (is_new) {
2154 char new_collection_name[MAX_NAME];
2155 RNA_string_get(op->ptr, "new_collection_name", new_collection_name);
2156 collection = BKE_collection_add(bmain, collection, new_collection_name);
2157 }
2158
2159 Object *single_object = BLI_listbase_is_single(&objects) ?
2160 static_cast<Object *>(((LinkData *)objects.first)->data) :
2161 nullptr;
2162
2163 if ((single_object != nullptr) && is_link &&
2164 BKE_collection_has_object(collection, single_object))
2165 {
2166 BKE_reportf(op->reports,
2167 RPT_ERROR,
2168 "%s already in %s",
2169 single_object->id.name + 2,
2170 BKE_collection_ui_name_get(collection));
2171 BLI_freelistN(&objects);
2172 return OPERATOR_CANCELLED;
2173 }
2174
2175 LISTBASE_FOREACH (LinkData *, link, &objects) {
2176 Object *ob = static_cast<Object *>(link->data);
2177
2178 if (!is_link) {
2179 BKE_collection_object_move(bmain, scene, collection, nullptr, ob);
2180 }
2181 else {
2182 BKE_collection_object_add(bmain, collection, ob);
2183 }
2184 }
2185 BLI_freelistN(&objects);
2186
2187 if (is_link) {
2188 if (single_object != nullptr) {
2189 BKE_reportf(op->reports,
2190 RPT_INFO,
2191 "%s linked to %s",
2192 single_object->id.name + 2,
2193 BKE_collection_ui_name_get(collection));
2194 }
2195 else {
2197 op->reports, RPT_INFO, "Objects linked to %s", BKE_collection_ui_name_get(collection));
2198 }
2199 }
2200 else {
2201 if (single_object != nullptr) {
2202 BKE_reportf(op->reports,
2203 RPT_INFO,
2204 "%s moved to %s",
2205 single_object->id.name + 2,
2206 BKE_collection_ui_name_get(collection));
2207 }
2208 else {
2210 op->reports, RPT_INFO, "Objects moved to %s", BKE_collection_ui_name_get(collection));
2211 }
2212 }
2213
2216
2220
2221 return OPERATOR_FINISHED;
2222}
2223
2232
2234{
2235 int index = menu->index;
2237 Collection *collection = child->collection;
2238 MoveToCollectionData *submenu = MEM_new<MoveToCollectionData>(__func__);
2239 BLI_addtail(&menu->submenus, submenu);
2240 submenu->collection = collection;
2241 submenu->index = ++index;
2242 index = move_to_collection_menus_create(op, submenu);
2243 submenu->ot = op->type;
2244 }
2245 return index;
2246}
2247
2249{
2252 MEM_delete(submenu);
2253 }
2255}
2256
2258{
2259 if (*menu == nullptr) {
2260 return;
2261 }
2262
2264 MEM_delete(*menu);
2265 *menu = nullptr;
2266}
2267
2268static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *menu_v)
2269{
2270 MoveToCollectionData *menu = static_cast<MoveToCollectionData *>(menu_v);
2271 const char *name = BKE_collection_ui_name_get(menu->collection);
2272
2274 RNA_int_set(&menu->ptr, "collection_index", menu->index);
2275 RNA_boolean_set(&menu->ptr, "is_new", true);
2276
2277 uiItemFullO_ptr(layout,
2278 menu->ot,
2280 ICON_ADD,
2281 static_cast<IDProperty *>(menu->ptr.data),
2284 nullptr);
2285
2286 uiItemS(layout);
2287
2288 Scene *scene = CTX_data_scene(C);
2289 const int icon = (menu->collection == scene->master_collection) ?
2290 ICON_SCENE_DATA :
2292 uiItemIntO(layout, name, icon, menu->ot->idname, "collection_index", menu->index);
2293
2294 LISTBASE_FOREACH (MoveToCollectionData *, submenu, &menu->submenus) {
2295 move_to_collection_menus_items(layout, submenu);
2296 }
2297}
2298
2300{
2301 const int icon = UI_icon_color_from_collection(menu->collection);
2302
2303 if (BLI_listbase_is_empty(&menu->submenus)) {
2304 uiItemIntO(layout,
2305 menu->collection->id.name + 2,
2306 icon,
2307 menu->ot->idname,
2308 "collection_index",
2309 menu->index);
2310 }
2311 else {
2312 uiItemMenuF(layout, menu->collection->id.name + 2, icon, move_to_collection_menu_create, menu);
2313 }
2314}
2315
2316/* This is allocated statically because we need this available for the menus creation callback. */
2318
2319static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
2320{
2321 Scene *scene = CTX_data_scene(C);
2322
2323 ListBase objects = selected_objects_get(C);
2324 if (BLI_listbase_is_empty(&objects)) {
2325 BKE_report(op->reports, RPT_ERROR, "No objects selected");
2326 return OPERATOR_CANCELLED;
2327 }
2328 BLI_freelistN(&objects);
2329
2330 /* Reset the menus data for the current master collection, and free previously allocated data. */
2332
2333 PropertyRNA *prop;
2334 prop = RNA_struct_find_property(op->ptr, "collection_index");
2335 if (RNA_property_is_set(op->ptr, prop)) {
2336 int collection_index = RNA_property_int_get(op->ptr, prop);
2337
2338 if (RNA_boolean_get(op->ptr, "is_new")) {
2339 prop = RNA_struct_find_property(op->ptr, "new_collection_name");
2340 if (!RNA_property_is_set(op->ptr, prop)) {
2341 char name[MAX_NAME];
2342 Collection *collection;
2343
2344 collection = BKE_collection_from_index(scene, collection_index);
2345 BKE_collection_new_name_get(collection, name);
2346
2347 RNA_property_string_set(op->ptr, prop, name);
2349 C, op, 200, IFACE_("Move to New Collection"), IFACE_("Create"));
2350 }
2351 }
2352 return move_to_collection_exec(C, op);
2353 }
2354
2355 Collection *master_collection = scene->master_collection;
2356
2357 /* We need the data to be allocated so it's available during menu drawing.
2358 * Technically we could use #wmOperator.customdata. However there is no free callback
2359 * called to an operator that exit with OPERATOR_INTERFACE to launch a menu.
2360 *
2361 * So we are left with a memory that will necessarily leak. It's a small leak though. */
2362 if (master_collection_menu == nullptr) {
2363 master_collection_menu = MEM_new<MoveToCollectionData>(
2364 "MoveToCollectionData menu - expected eventual memleak");
2365 }
2366
2367 master_collection_menu->collection = master_collection;
2370
2371 uiPopupMenu *pup;
2372 uiLayout *layout;
2373
2374 /* Build the menus. */
2375 const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
2376 pup = UI_popup_menu_begin(C, title, ICON_NONE);
2377 layout = UI_popup_menu_layout(pup);
2378
2380
2382
2383 UI_popup_menu_end(C, pup);
2384
2385 return OPERATOR_INTERFACE;
2386}
2387
2389{
2390 PropertyRNA *prop;
2391
2392 /* identifiers */
2393 ot->name = "Move to Collection";
2394 ot->description = "Move objects to a collection";
2395 ot->idname = "OBJECT_OT_move_to_collection";
2396
2397 /* api callbacks */
2401
2402 /* flags */
2404
2405 prop = RNA_def_int(ot->srna,
2406 "collection_index",
2409 INT_MAX,
2410 "Collection Index",
2411 "Index of the collection to move to",
2412 0,
2413 INT_MAX);
2415 prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection");
2417 prop = RNA_def_string(ot->srna,
2418 "new_collection_name",
2419 nullptr,
2420 MAX_NAME,
2421 "Name",
2422 "Name of the newly added collection");
2424 ot->prop = prop;
2425}
2426
2428{
2429 PropertyRNA *prop;
2430
2431 /* identifiers */
2432 ot->name = "Link to Collection";
2433 ot->description = "Link objects to a collection";
2434 ot->idname = "OBJECT_OT_link_to_collection";
2435
2436 /* api callbacks */
2440
2441 /* flags */
2443
2444 prop = RNA_def_int(ot->srna,
2445 "collection_index",
2448 INT_MAX,
2449 "Collection Index",
2450 "Index of the collection to move to",
2451 0,
2452 INT_MAX);
2454 prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection");
2456 prop = RNA_def_string(ot->srna,
2457 "new_collection_name",
2458 nullptr,
2459 MAX_NAME,
2460 "Name",
2461 "Name of the newly added collection");
2463 ot->prop = prop;
2464}
2465
2468} // namespace blender::ed::object
struct bMotionPath * animviz_verify_motionpaths(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan)
void animviz_free_motionpath(struct bMotionPath *mpath)
void BKE_pose_channels_clear_with_null_bone(bPose *pose, bool do_id_user)
Definition armature.cc:2756
Collection * BKE_collection_from_index(Scene *scene, int index)
const char * BKE_collection_ui_name_get(Collection *collection)
Collection * BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
bool BKE_collection_has_object(Collection *collection, const Object *ob)
void BKE_collection_object_move(Main *bmain, Scene *scene, Collection *collection_dst, Collection *collection_src, Object *ob)
void BKE_collection_new_name_get(Collection *collection_parent, char *rname)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
#define CTX_DATA_BEGIN(C, Type, instance, member)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(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)
Base * CTX_data_active_base(const bContext *C)
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
wmMsgBus * CTX_wm_message_bus(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_curve_smooth_flag_set(Curve *cu, bool use_smooth)
Definition curve.cc:5428
void BKE_editlattice_load(struct Object *obedit)
void BKE_editlattice_make(struct Object *obedit)
void BKE_editlattice_free(struct Object *ob)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:63
void BKE_editmesh_looptris_and_normals_calc(BMEditMesh *em)
Definition editmesh.cc:83
struct PartDeflect * BKE_partdeflect_new(int type)
Definition effect.cc:71
#define IDP_Float(prop)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:763
#define IDP_Double(prop)
#define FOREACH_BASE_IN_MODE_END
Definition BKE_layer.hh:367
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
#define FOREACH_SELECTED_OBJECT_BEGIN(_view_layer, _v3d, _instance)
Definition BKE_layer.hh:298
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_mode_params(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, const ObjectsInModeParams *params)
void BKE_layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
LayerCollection * BKE_layer_collection_from_index(ViewLayer *view_layer, int index)
#define FOREACH_OBJECT_END
Definition BKE_layer.hh:432
#define FOREACH_BASE_IN_MODE_BEGIN(_scene, _view_layer, _v3d, _object_type, _object_mode, _instance)
Definition BKE_layer.hh:349
void BKE_layer_collection_isolate_local(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, LayerCollection *lc, bool extend)
#define FOREACH_OBJECT_BEGIN(scene, view_layer, _instance)
Definition BKE_layer.hh:422
bool BKE_layer_collection_has_selected_objects(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc)
blender::Vector< Object * > BKE_view_layer_array_selected_objects_params(ViewLayer *view_layer, const View3D *v3d, const ObjectsInViewLayerParams *params)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
void BKE_layer_collection_isolate_global(Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool extend)
void BKE_view_layer_need_resync_tag(ViewLayer *view_layer)
#define FOREACH_SELECTED_OBJECT_END
Definition BKE_layer.hh:310
int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection *lc)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
Object * BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2456
void id_us_plus(ID *id)
Definition lib_id.cc:351
General operations, lookup, etc. for materials.
void BKE_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
@ BKE_MESH_BATCH_DIRTY_ALL
Definition BKE_mesh.h:38
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
void BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
char * BKE_object_data_editmode_flush_ptr_get(ID *id)
bool BKE_object_obdata_is_libdata(const Object *ob)
void BKE_particlesystem_reset_all(struct Object *object)
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis)
#define PTCACHE_TYPE_PARTICLES
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_object_reset(struct Scene *scene, struct Object *ob, int mode)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
void BKE_scene_object_base_flag_sync_from_base(Base *base)
Definition scene.cc:2820
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
struct LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:909
#define DEG2RADF(_deg)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define LIKELY(x)
#define TIP_(msgid)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define IFACE_(msgid)
#define DATA_(msgid)
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_graph_free(Depsgraph *graph)
Definition depsgraph.cc:301
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_SELECT
Definition DNA_ID.h:1068
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1071
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
@ ID_NT
@ ID_CU_LEGACY
@ ID_ME
@ ID_OB
@ IDP_DOUBLE
@ IDP_FLOAT
@ MOTIONPATH_BAKE_HAS_PATHS
@ MOTIONPATH_TYPE_RANGE
@ MOTIONPATH_RANGE_SCENE
@ ANIMVIZ_RECALC_PATHS
@ ASSET_LIBRARY_ESSENTIALS
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_VIEWPORT
#define MAX_NAME
Definition DNA_defs.h:50
@ LAYER_COLLECTION_HIDE_VIEWPORT
@ LAYER_COLLECTION_HAS_OBJECTS
@ LAYER_COLLECTION_EXCLUDE
@ BASE_HIDDEN
@ BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT
#define MESH_MAX_VERTS
@ eModifierFlag_PinLast
@ NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR
@ eModifierType_Surface
@ eModifierType_Hook
@ eModifierType_Nodes
#define OB_MODE_ALL_PAINT
#define OB_MODE_ALL_PAINT_GPENCIL
eObjectMode
@ OB_MODE_EDIT_GPENCIL_LEGACY
@ OB_MODE_EDIT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
@ OB_MODE_OBJECT
#define OB_MODE_ALL_SCULPT
@ PFIELD_SHAPE_SURFACE
Object is a sort of wrapper for general info.
@ OB_HIDE_VIEWPORT
@ PARVERT1
@ PARVERT3
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_CURVES
@ OB_PLAINAXES
#define OB_TYPE_SUPPORT_EDITMODE(_type)
@ PTCACHE_OUTDATED
#define BASE_SELECTED(v3d, base)
eSpace_Type
@ SPACE_PROPERTIES
@ SPACE_EMPTY
@ SPACE_VIEW3D
@ V3D_LOCAL_COLLECTIONS
@ OPERATOR_PASS_THROUGH
eAnimvizCalcRange
@ ANIMVIZ_CALC_RANGE_FULL
@ ANIMVIZ_CALC_RANGE_CURRENT_FRAME
@ ANIMVIZ_CALC_RANGE_CHANGED
void ED_mball_editmball_free(Object *obedit)
Definition mball_edit.cc:62
void ED_mball_editmball_load(Object *obedit)
Definition mball_edit.cc:87
void ED_mball_editmball_make(Object *obedit)
Definition mball_edit.cc:70
void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
void EDBM_mesh_make(Object *ob, int select_mode, bool add_key_index)
void ED_mesh_mirror_topo_table_end(Object *ob)
Definition meshtools.cc:857
void EDBM_mesh_free_data(BMEditMesh *em)
bool EDBM_selectmode_set_multi(bContext *C, short selectmode)
void ED_mesh_mirror_spatial_table_end(Object *ob)
void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
bool ED_outliner_collections_editor_poll(bContext *C)
bool ED_operator_objectmode(bContext *C)
bool ED_operator_view3d_active(bContext *C)
bool ED_operator_object_active_editable(bContext *C)
bool ED_operator_object_active_editable_ex(bContext *C, const Object *ob)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
Definition MOD_nodes.cc:453
@ PROP_FLOAT
Definition RNA_types.hh:67
PropertyFlag
Definition RNA_types.hh:201
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
@ PROP_HIDDEN
Definition RNA_types.hh:239
@ PROP_ANGLE
Definition RNA_types.hh:155
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
void uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, IDProperty *properties, wmOperatorCallContext context, eUI_Item_Flag flag, PointerRNA *r_opptr)
#define UI_ITEM_NONE
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg)
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
int UI_icon_color_from_collection(const Collection *collection)
#define NS_EDITMODE_MESH
Definition WM_types.hh:528
#define NS_EDITMODE_POINT_CLOUD
Definition WM_types.hh:539
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NS_EDITMODE_TEXT
Definition WM_types.hh:531
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DRAW
Definition WM_types.hh:428
#define ND_OB_ACTIVE
Definition WM_types.hh:407
#define ND_DATA
Definition WM_types.hh:475
#define NS_EDITMODE_CURVES
Definition WM_types.hh:537
#define ND_MODE
Definition WM_types.hh:412
#define ND_OB_SELECT
Definition WM_types.hh:409
#define NC_SCENE
Definition WM_types.hh:345
#define NS_EDITMODE_ARMATURE
Definition WM_types.hh:534
#define ND_OB_VISIBLE
Definition WM_types.hh:410
#define ND_LAYER_CONTENT
Definition WM_types.hh:420
#define ND_MODIFIER
Definition WM_types.hh:429
#define ND_POSE
Definition WM_types.hh:425
#define NS_MODE_OBJECT
Definition WM_types.hh:526
#define NS_EDITMODE_MBALL
Definition WM_types.hh:532
#define NS_EDITMODE_GREASE_PENCIL
Definition WM_types.hh:538
#define ND_TRANSFORM
Definition WM_types.hh:423
#define NS_EDITMODE_LATTICE
Definition WM_types.hh:533
#define ND_LAYER
Definition WM_types.hh:417
@ WM_OP_EXEC_REGION_WIN
Definition WM_types.hh:226
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:218
@ KM_SHIFT
Definition WM_types.hh:255
#define ND_DRAW_ANIMVIZ
Definition WM_types.hh:440
#define NC_OBJECT
Definition WM_types.hh:346
#define NS_EDITMODE_CURVE
Definition WM_types.hh:529
void animviz_calc_motionpaths(Depsgraph *depsgraph, Main *bmain, Scene *scene, ListBase *targets, eAnimvizCalcRange range, bool restore)
void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
void animviz_motionpath_compute_range(Object *ob, Scene *scene)
Depsgraph * animviz_depsgraph_build(Main *bmain, Scene *scene, ViewLayer *view_layer, ListBase *targets)
void ED_armature_edit_free(bArmature *arm)
void ED_armature_from_edit(Main *bmain, bArmature *arm)
void ED_armature_to_edit(bArmature *arm)
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr const char * c_str() const
void append(const T &value)
bool is_empty() const
const Depsgraph * depsgraph
void ED_curve_editnurb_make(Object *obedit)
void ED_curve_editnurb_free(Object *obedit)
void ED_curve_editnurb_load(Main *bmain, Object *obedit)
void ED_curve_editfont_make(Object *obedit)
Definition editfont.cc:2190
void ED_curve_editfont_load(Object *obedit)
Definition editfont.cc:2231
void ED_curve_editfont_free(Object *obedit)
Definition editfont.cc:2262
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define GS(x)
Definition iris.cc:202
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
#define G(x, y, z)
void mesh_sharp_edges_set_from_angle(Mesh &mesh, float angle, bool keep_sharp_edges=false)
void mesh_smooth_set(Mesh &mesh, bool use_smooth, bool keep_sharp_edges=false)
const asset_system::AssetRepresentation * find_asset_from_weak_ref(const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports)
ID * asset_local_id_ensure_imported(Main &bmain, const asset_system::AssetRepresentation &asset)
void OBJECT_OT_paths_update_visible(wmOperatorType *ot)
static void move_to_collection_menus_free(MoveToCollectionData **menu)
void OBJECT_OT_shade_smooth(wmOperatorType *ot)
void motion_paths_recalc(bContext *C, Scene *scene, eObjectPathCalcRange range, ListBase *ld_objects)
ModifierData * modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
@ OBJECT_PATH_CALC_RANGE_CURRENT_FRAME
Definition ED_object.hh:350
static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionData *menu)
static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *)
void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
bool editmode_exit_multi(bContext *C, int flag)
void OBJECT_OT_mode_set(wmOperatorType *ot)
static bool editmode_load_free_ex(Main *bmain, Object *obedit, const bool load_data, const bool free_data)
bool editmode_enter(bContext *C, int flag)
void motion_paths_recalc_selected(bContext *C, Scene *scene, eObjectPathCalcRange range)
void OBJECT_OT_posemode_toggle(wmOperatorType *ot)
static bool object_mode_set_poll(bContext *C)
int object_in_mode_to_index(const Scene *scene, ViewLayer *view_layer, eObjectMode mode, const Object *ob)
void OBJECT_OT_shade_flat(wmOperatorType *ot)
void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
void OBJECT_OT_shade_auto_smooth(wmOperatorType *ot)
void motion_paths_recalc_visible(bContext *C, Scene *scene, eObjectPathCalcRange range)
static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
static void object_clear_mpath(Object *ob)
void motion_paths_clear(bContext *C, bool only_selected)
void OBJECT_OT_shade_smooth_by_angle(wmOperatorType *ot)
void OBJECT_OT_move_to_collection(wmOperatorType *ot)
bool editmode_free_ex(Main *bmain, Object *obedit)
bool mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportList *reports)
void OBJECT_OT_hide_view_set(wmOperatorType *ot)
static int move_to_collection_menus_create(wmOperator *op, MoveToCollectionData *menu)
static int shade_auto_smooth_exec(bContext *C, wmOperator *op)
void base_select(Base *base, eObjectSelect_Mode mode)
Object * context_object(const bContext *C)
void OBJECT_OT_mode_set_with_submode(wmOperatorType *ot)
void OBJECT_OT_hide_collection(wmOperatorType *ot)
static int object_update_paths_exec(bContext *C, wmOperator *op)
static int object_hide_view_set_exec(bContext *C, wmOperator *op)
static int object_clear_paths_exec(bContext *C, wmOperator *op)
static bool shade_poll(bContext *C)
void OBJECT_OT_paths_update(wmOperatorType *ot)
void OBJECT_OT_paths_calculate(wmOperatorType *ot)
void collection_hide_menu_draw(const bContext *C, uiLayout *layout)
static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *menu_v)
static int forcefield_toggle_exec(bContext *C, wmOperator *)
static eAnimvizCalcRange object_path_convert_range(eObjectPathCalcRange range)
bool mode_compat_test(const Object *ob, eObjectMode mode)
bool editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
static ListBase selected_objects_get(bContext *C)
static void move_to_collection_menus_free_recursive(MoveToCollectionData *menu)
static int posemode_exec(bContext *C, wmOperator *op)
Object * context_active_object(const bContext *C)
void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
static const EnumPropertyItem * object_mode_set_itemf(bContext *C, PointerRNA *, PropertyRNA *, bool *r_free)
static int move_to_collection_exec(bContext *C, wmOperator *op)
bool editmode_exit(bContext *C, int flag)
static int editmode_toggle_exec(bContext *C, wmOperator *op)
Object * object_in_mode_from_index(const Scene *scene, ViewLayer *view_layer, eObjectMode mode, int index)
static bool has_object_motion_paths(Object *ob)
void OBJECT_OT_link_to_collection(wmOperatorType *ot)
static bool move_to_collection_poll(bContext *C)
static int object_calculate_paths_exec(bContext *C, wmOperator *op)
static int object_update_all_paths_exec(bContext *C, wmOperator *)
bool mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
bool editmode_exit_multi_ex(Main *bmain, Scene *scene, ViewLayer *view_layer, int flag)
static int object_mode_set_exec(bContext *C, wmOperator *op)
static bool object_update_all_paths_poll(bContext *)
void check_force_modifiers(Main *bmain, Scene *scene, Object *object)
static bool object_update_paths_poll(bContext *C)
static bool editmode_toggle_poll(bContext *C)
static void shade_auto_smooth_ui(bContext *, wmOperator *op)
static bool mesh_needs_keyindex(Main *bmain, const Mesh *mesh)
static bool has_pose_motion_paths(Object *ob)
static int object_hide_collection_exec(bContext *C, wmOperator *op)
static bool is_smooth_by_angle_modifier(const ModifierData &md)
bool editmode_load(Main *bmain, Object *obedit)
static std::string object_clear_paths_get_description(bContext *, wmOperatorType *, PointerRNA *ptr)
blender::Vector< Object * > objects_in_mode_or_selected(bContext *C, bool(*filter_fn)(const Object *ob, void *user_data), void *filter_user_data)
static int shade_smooth_exec(bContext *C, wmOperator *op)
bool editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int flag)
static CLG_LogRef LOG
static MoveToCollectionData * master_collection_menu
void OBJECT_OT_paths_clear(wmOperatorType *ot)
static bool object_hide_poll(bContext *C)
static int object_hide_collection_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *)
bool modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
static void free_data(ModifierData *md)
#define COLLECTION_INVALID_INDEX
bool ED_object_posemode_enter_ex(Main *bmain, Object *ob)
Definition pose_edit.cc:78
bool ED_object_posemode_enter(bContext *C, Object *ob)
Definition pose_edit.cc:98
bool ED_object_posemode_exit_ex(Main *bmain, Object *ob)
Definition pose_edit.cc:113
bool ED_object_posemode_exit(bContext *C, Object *ob)
Definition pose_edit.cc:126
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)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
const EnumPropertyItem rna_enum_motionpath_display_type_items[]
const EnumPropertyItem rna_enum_motionpath_range_items[]
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *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_def_property_range(PropertyRNA *prop, double min, double max)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
PropertyRNA * RNA_def_enum_flag(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)
void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item, int value)
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_mode_items[]
Definition rna_object.cc:57
const EnumPropertyItem rna_enum_mesh_select_mode_items[]
Definition rna_scene.cc:126
struct Object * object
struct EditFont * editfont
EditNurb * editnurb
char type
Definition DNA_ID.h:154
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
struct LibraryWeakReference * library_weak_reference
Definition DNA_ID.h:490
struct EditLatt * editlatt
ListBase layer_collections
unsigned short local_collections_bits
char library_id_name[66]
Definition DNA_ID.h:574
void * first
bool is_memfile_undo_written
Definition BKE_main.hh:160
ListBase objects
Definition BKE_main.hh:212
ListBase * editelems
char needs_flush_to_id
struct bNodeTree * node_group
struct NodesModifierSettings settings
struct IDProperty * properties
struct bPose * pose
ListBase modifiers
struct PartDeflect * pd
char empty_drawtype
short visibility_flag
bMotionPath * mpath
bAnimVizSettings avs
void * data
Definition RNA_types.hh:42
unsigned short local_collections_uid
ListBase layer_collections
ListBase * edbo
bAnimVizSettings avs
uint8_t modifier
Definition WM_types.hh:739
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
std::string(* get_description)(bContext *C, wmOperatorType *ot, PointerRNA *ptr)
Definition WM_types.hh:1074
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * translation_context
Definition WM_types.hh:994
const char * description
Definition WM_types.hh:996
void(* ui)(bContext *C, wmOperator *op)
Definition WM_types.hh:1053
PropertyRNA * prop
Definition WM_types.hh:1092
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_autosave_write(wmWindowManager *wm, Main *bmain)
Definition wm_files.cc:2311
bool WM_autosave_is_scheduled(wmWindowManager *wm)
Definition wm_files.cc:2306
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_toolsystem_update_from_context_view3d(bContext *C)
uint8_t flag
Definition wm_window.cc:138