Blender V4.3
blenkernel/intern/object.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/* Allow using deprecated functionality for .blend file I/O. */
10#define DNA_DEPRECATED_ALLOW
11
12#include <cmath>
13#include <cstdio>
14#include <cstring>
15#include <optional>
16
17#include "CLG_log.h"
18
19#include "MEM_guardedalloc.h"
20
21#include "DNA_anim_types.h"
22#include "DNA_armature_types.h"
23#include "DNA_camera_types.h"
26#include "DNA_defaults.h"
28#include "DNA_effect_types.h"
29#include "DNA_fluid_types.h"
33#include "DNA_key_types.h"
34#include "DNA_lattice_types.h"
35#include "DNA_light_types.h"
37#include "DNA_material_types.h"
38#include "DNA_mesh_types.h"
39#include "DNA_meshdata_types.h"
40#include "DNA_meta_types.h"
41#include "DNA_movieclip_types.h"
42#include "DNA_nla_types.h"
44#include "DNA_object_types.h"
46#include "DNA_rigidbody_types.h"
47#include "DNA_scene_types.h"
48#include "DNA_screen_types.h"
49#include "DNA_sequence_types.h"
50#include "DNA_shader_fx_types.h"
51#include "DNA_space_types.h"
52#include "DNA_view3d_types.h"
53#include "DNA_world_types.h"
54
55#include "BLI_blenlib.h"
56#include "BLI_bounds.hh"
57#include "BLI_kdtree.h"
58#include "BLI_linklist.h"
59#include "BLI_listbase.h"
60#include "BLI_math_matrix.h"
61#include "BLI_math_rotation.h"
63#include "BLI_threads.h"
64#include "BLI_utildefines.h"
65
66#include "BLT_translation.hh"
67
68#include "BKE_action.hh"
69#include "BKE_anim_data.hh"
70#include "BKE_anim_path.h"
72#include "BKE_animsys.h"
73#include "BKE_armature.hh"
74#include "BKE_asset.hh"
75#include "BKE_bpath.hh"
76#include "BKE_camera.h"
77#include "BKE_collection.hh"
78#include "BKE_constraint.h"
79#include "BKE_crazyspace.hh"
80#include "BKE_curve.hh"
81#include "BKE_curves.hh"
82#include "BKE_deform.hh"
83#include "BKE_displist.h"
84#include "BKE_duplilist.hh"
85#include "BKE_editmesh.hh"
86#include "BKE_editmesh_cache.hh"
87#include "BKE_effect.h"
88#include "BKE_fcurve.hh"
89#include "BKE_fcurve_driver.h"
90#include "BKE_geometry_set.hh"
92#include "BKE_global.hh"
94#include "BKE_gpencil_legacy.h"
96#include "BKE_grease_pencil.hh"
97#include "BKE_idprop.hh"
98#include "BKE_idtype.hh"
99#include "BKE_image.hh"
100#include "BKE_key.hh"
101#include "BKE_lattice.hh"
102#include "BKE_layer.hh"
103#include "BKE_lib_id.hh"
104#include "BKE_lib_query.hh"
105#include "BKE_lib_remap.hh"
106#include "BKE_light.h"
107#include "BKE_lightprobe.h"
108#include "BKE_linestyle.h"
109#include "BKE_main.hh"
110#include "BKE_material.h"
111#include "BKE_mball.hh"
112#include "BKE_mesh.hh"
114#include "BKE_mesh_wrapper.hh"
115#include "BKE_modifier.hh"
116#include "BKE_multires.hh"
117#include "BKE_node.hh"
118#include "BKE_object.hh"
119#include "BKE_object_types.hh"
120#include "BKE_paint.hh"
121#include "BKE_particle.h"
122#include "BKE_pointcache.h"
123#include "BKE_pointcloud.hh"
124#include "BKE_pose_backup.h"
125#include "BKE_preview_image.hh"
126#include "BKE_rigidbody.h"
127#include "BKE_scene.hh"
128#include "BKE_shader_fx.h"
129#include "BKE_softbody.h"
130#include "BKE_speaker.h"
131#include "BKE_subdiv_ccg.hh"
132#include "BKE_subsurf.hh"
133#include "BKE_vfont.hh"
134#include "BKE_volume.hh"
135
136#include "DEG_depsgraph.hh"
137#include "DEG_depsgraph_query.hh"
138
139#include "DRW_engine.hh"
140
141#include "BLO_read_write.hh"
142#include "BLO_readfile.hh"
143
144#include "SEQ_sequencer.hh"
145
146#include "ANIM_action_legacy.hh"
147
148#ifdef WITH_PYTHON
149# include "BPY_extern.hh"
150#endif
151
152#include "CCGSubSurf.h"
153#include "atomic_ops.h"
154
155using blender::Bounds;
156using blender::float3;
158using blender::Span;
159using blender::Vector;
160
161static CLG_LogRef LOG = {"bke.object"};
162
169#define VPARENT_THREADING_HACK
170
171#ifdef VPARENT_THREADING_HACK
173#endif
174
175static void copy_object_pose(Object *obn, const Object *ob, const int flag);
176
177static void object_init_data(ID *id)
178{
179 Object *ob = (Object *)id;
181
183
184 ob->type = OB_EMPTY;
185
186 ob->trackflag = OB_POSY;
187 ob->upflag = OB_POSZ;
188 ob->runtime = MEM_new<blender::bke::ObjectRuntime>(__func__);
189
190 /* Animation Visualization defaults */
192}
193
194static void object_copy_data(Main *bmain,
195 std::optional<Library *> /*owner_library*/,
196 ID *id_dst,
197 const ID *id_src,
198 const int flag)
199{
200 Object *ob_dst = (Object *)id_dst;
201 const Object *ob_src = (const Object *)id_src;
202
203 ob_dst->runtime = MEM_new<blender::bke::ObjectRuntime>(__func__, *ob_src->runtime);
205
206 /* We never handle user-count here for own data. */
207 const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
208
209 if (ob_src->totcol) {
210 ob_dst->mat = (Material **)MEM_dupallocN(ob_src->mat);
211 ob_dst->matbits = (char *)MEM_dupallocN(ob_src->matbits);
212 ob_dst->totcol = ob_src->totcol;
213 }
214 else if (ob_dst->mat != nullptr || ob_dst->matbits != nullptr) {
215 /* This shall not be needed, but better be safe than sorry. */
217 0, "Object copy: non-nullptr material pointers with zero counter, should not happen.");
218 ob_dst->mat = nullptr;
219 ob_dst->matbits = nullptr;
220 }
221
222 if (ob_src->iuser) {
223 ob_dst->iuser = (ImageUser *)MEM_dupallocN(ob_src->iuser);
224 }
225
227 LISTBASE_FOREACH (ShaderFxData *, fx, &ob_src->shader_fx) {
228 ShaderFxData *nfx = BKE_shaderfx_new(fx->type);
229 STRNCPY(nfx->name, fx->name);
230 BKE_shaderfx_copydata_ex(fx, nfx, flag_subdata);
231 BLI_addtail(&ob_dst->shader_fx, nfx);
232 }
233
234 if (ob_src->pose) {
235 copy_object_pose(ob_dst, ob_src, flag_subdata);
236 /* backwards compat... non-armatures can get poses in older files? */
237 if (ob_src->type == OB_ARMATURE) {
238 const bool do_pose_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
239 BKE_pose_rebuild(bmain, ob_dst, (bArmature *)ob_dst->data, do_pose_id_user);
240 }
241 }
242
243 BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
244
245 ob_dst->mode = ob_dst->type != OB_GPENCIL_LEGACY ? OB_MODE_OBJECT : ob_dst->mode;
246 ob_dst->sculpt = nullptr;
247
248 if (ob_src->pd) {
249 ob_dst->pd = (PartDeflect *)MEM_dupallocN(ob_src->pd);
250 }
251 BKE_rigidbody_object_copy(bmain, ob_dst, ob_src, flag_subdata);
252
255 /* NOTE: Also takes care of soft-body and particle systems copying. */
256 BKE_object_modifier_stack_copy(ob_dst, ob_src, true, flag_subdata);
258
260 BLI_listbase_clear(&ob_dst->pc_ids);
261
262 ob_dst->avs = ob_src->avs;
263 ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath);
264
265 if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
266 BKE_previewimg_id_copy(&ob_dst->id, &ob_src->id);
267 }
268 else {
269 ob_dst->preview = nullptr;
270 }
271
272 if (ob_src->lightgroup) {
274 }
275 if (ob_src->light_linking) {
277 }
278
280 if (ob_src->lightprobe_cache) {
281 /* Reference the original object data. */
283 ob_dst->lightprobe_cache->shared = true;
284 }
285 }
286 else {
287 if (ob_src->lightprobe_cache) {
288 /* Duplicate the original object data. */
290 ob_dst->lightprobe_cache->shared = false;
291 }
292 }
293}
294
295static void object_free_data(ID *id)
296{
297 Object *ob = (Object *)id;
298
299 DRW_drawdata_free((ID *)ob);
300
301 /* BKE_<id>_free shall never touch to ID->us. Never ever. */
304
305 MEM_SAFE_FREE(ob->mat);
307 MEM_SAFE_FREE(ob->iuser);
308
309 if (ob->pose) {
310 BKE_pose_free_ex(ob->pose, false);
311 ob->pose = nullptr;
312 }
313 if (ob->mpath) {
315 ob->mpath = nullptr;
316 }
317
319
321 BKE_rigidbody_free_object(ob, nullptr);
323
324 sbFree(ob);
325
327
328 BLI_freelistN(&ob->pc_ids);
329
330 /* Free runtime curves data. */
331 if (ob->runtime->curve_cache) {
332 BKE_curve_bevelList_free(&ob->runtime->curve_cache->bev);
333 if (ob->runtime->curve_cache->anim_path_accum_length) {
334 MEM_freeN((void *)ob->runtime->curve_cache->anim_path_accum_length);
335 }
336 MEM_freeN(ob->runtime->curve_cache);
337 ob->runtime->curve_cache = nullptr;
338 }
339
341
344
346
347 MEM_delete(ob->runtime);
348}
349
350static void library_foreach_modifiersForeachIDLink(void *user_data,
351 Object * /*object*/,
352 ID **id_pointer,
353 int cb_flag)
354{
355 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
357 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
358}
359
361 Object * /*object*/,
362 ID **id_pointer,
363 int cb_flag)
364{
365 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
367 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
368}
369
370static void library_foreach_shaderfxForeachIDLink(void *user_data,
371 Object * /*object*/,
372 ID **id_pointer,
373 int cb_flag)
374{
375 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
377 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
378}
379
381 ID **id_pointer,
382 bool is_reference,
383 void *user_data)
384{
385 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
386 const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
388 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
389}
390
392 ID **id_pointer,
393 void *user_data,
394 int cb_flag)
395{
396 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
398 data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
399}
400
402{
403 Object *object = reinterpret_cast<Object *>(id);
405
406 /* object data special case */
407 if (object->type == OB_EMPTY) {
408 /* empty can have nullptr or Image */
409 BKE_LIB_FOREACHID_PROCESS_ID(data, object->data, IDWALK_CB_USER);
410 }
411 else {
412 /* when set, this can't be nullptr */
413 if (object->data) {
415 }
416 }
417
421
422 for (int i = 0; i < object->totcol; i++) {
424 }
425
426 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->instance_collection, IDWALK_CB_USER);
427
428 if (object->pd) {
430 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->pd->f_source, IDWALK_CB_NOP);
431 }
432
433 if (object->pose) {
434 LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
436 data, IDP_foreach_property(pchan->prop, IDP_TYPE_FILTER_ID, [&](IDProperty *prop) {
437 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
438 }));
439
442 data,
444 &pchan->constraints, library_foreach_constraintObjectLooper, flag, data));
445 }
446 }
447
448 if (object->rigidbody_constraint) {
450 data, object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
452 data, object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
453 }
454
458 data,
462 data,
464 &object->constraints, library_foreach_constraintObjectLooper, flag, data));
467
468 LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
471 }
472
473 if (object->soft) {
474 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->soft->collision_group, IDWALK_CB_NOP);
475
476 if (object->soft->effector_weights) {
478 data, object->soft->effector_weights->group, IDWALK_CB_USER);
479 }
480 }
481
482 if (object->light_linking) {
484 data, object->light_linking->receiver_collection, IDWALK_CB_USER);
486 data, object->light_linking->blocker_collection, IDWALK_CB_USER);
487 }
488
492
494
495 LISTBASE_FOREACH (bConstraintChannel *, chan, &object->constraintChannels) {
497 }
498
499 LISTBASE_FOREACH (bActionStrip *, strip, &object->nlastrips) {
503 LISTBASE_FOREACH (bActionModifier *, amod, &strip->modifiers) {
505 }
506 }
507
509
511 BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->proxy_group, IDWALK_CB_NOP);
512 /* Note that `proxy_from` is purposefully skipped here, as this should be considered as pure
513 * runtime data. */
514
516 if (paf && paf->group) {
518 }
519
520 FluidsimModifierData *fluidmd = reinterpret_cast<FluidsimModifierData *>(
522 if (fluidmd && fluidmd->fss) {
524 }
525 }
526}
527
528static void object_foreach_path_pointcache(ListBase *ptcache_list,
529 BPathForeachPathData *bpath_data)
530{
531 for (PointCache *cache = (PointCache *)ptcache_list->first; cache != nullptr;
532 cache = cache->next)
533 {
534 if (cache->flag & PTCACHE_DISK_CACHE) {
535 BKE_bpath_foreach_path_fixed_process(bpath_data, cache->path, sizeof(cache->path));
536 }
537 }
538}
539
540static void object_foreach_path(ID *id, BPathForeachPathData *bpath_data)
541{
542 Object *ob = reinterpret_cast<Object *>(id);
543
545 /* TODO: Move that to #ModifierTypeInfo. */
546 switch (md->type) {
548 FluidsimModifierData *fluidmd = reinterpret_cast<FluidsimModifierData *>(md);
549 if (fluidmd->fss) {
551 bpath_data, fluidmd->fss->surfdataPath, sizeof(fluidmd->fss->surfdataPath));
552 }
553 break;
554 }
555 case eModifierType_Fluid: {
556 FluidModifierData *fmd = reinterpret_cast<FluidModifierData *>(md);
557 if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
559 bpath_data, fmd->domain->cache_directory, sizeof(fmd->domain->cache_directory));
560 }
561 break;
562 }
563 case eModifierType_Cloth: {
564 ClothModifierData *clmd = reinterpret_cast<ClothModifierData *>(md);
565 object_foreach_path_pointcache(&clmd->ptcaches, bpath_data);
566 break;
567 }
568 case eModifierType_Ocean: {
569 OceanModifierData *omd = reinterpret_cast<OceanModifierData *>(md);
570 BKE_bpath_foreach_path_fixed_process(bpath_data, omd->cachepath, sizeof(omd->cachepath));
571 break;
572 }
574 MeshCacheModifierData *mcmd = reinterpret_cast<MeshCacheModifierData *>(md);
575 BKE_bpath_foreach_path_fixed_process(bpath_data, mcmd->filepath, sizeof(mcmd->filepath));
576 break;
577 }
578 default:
579 break;
580 }
581 }
582
583 if (ob->soft != nullptr) {
585 }
586
588 object_foreach_path_pointcache(&psys->ptcaches, bpath_data);
589 }
590}
591
592static void object_foreach_cache(ID *id,
593 IDTypeForeachCacheFunctionCallback function_callback,
594 void *user_data)
595{
596 Object *ob = reinterpret_cast<Object *>(id);
598 if (const ModifierTypeInfo *info = BKE_modifier_get_info(ModifierType(md->type))) {
599 if (info->foreach_cache) {
600 info->foreach_cache(ob, md, [&](const IDCacheKey &cache_key, void **cache_p, uint flags) {
601 function_callback(id, &cache_key, cache_p, flags, user_data);
602 });
603 }
604 }
605 }
606}
607
608static void object_blend_write(BlendWriter *writer, ID *id, const void *id_address)
609{
610 Object *ob = (Object *)id;
611
612 const bool is_undo = BLO_write_is_undo(writer);
613
614 /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
615 ob->runtime = nullptr;
616
617 if (is_undo) {
618 /* For undo we stay in object mode during undo presses, so keep edit-mode disabled on save as
619 * well, can help reducing false detection of changed data-blocks. */
620 ob->mode &= ~OB_MODE_EDIT;
621 }
622
623 /* write LibData */
624 BLO_write_id_struct(writer, Object, id_address, &ob->id);
625 BKE_id_blend_write(writer, &ob->id);
626
627 /* direct data */
628 BLO_write_pointer_array(writer, ob->totcol, ob->mat);
629 BLO_write_char_array(writer, ob->totcol, ob->matbits);
630
631 bArmature *arm = nullptr;
632 if (ob->type == OB_ARMATURE) {
633 arm = (bArmature *)ob->data;
634 }
635
636 if (ob->pose) {
637 BKE_pose_blend_write(writer, ob->pose, arm);
638 }
641
642 BLO_write_struct(writer, PartDeflect, ob->pd);
643 if (ob->soft) {
644 /* Set deprecated pointers to prevent crashes of older Blenders */
645 ob->soft->pointcache = ob->soft->shared->pointcache;
646 ob->soft->ptcaches = ob->soft->shared->ptcaches;
647 BLO_write_struct(writer, SoftBody, ob->soft);
651 }
652
653 if (ob->rigidbody_object) {
654 /* TODO: if any extra data is added to handle duplis, will need separate function then */
656 }
657 if (ob->rigidbody_constraint) {
659 }
660
661 if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) {
662 BLO_write_struct(writer, ImageUser, ob->iuser);
663 }
664
666 BKE_modifier_blend_write(writer, &ob->id, &ob->modifiers);
669
671
673
674 if (ob->lightgroup) {
676 }
677 if (ob->light_linking) {
679 }
680
681 if (ob->lightprobe_cache) {
684 }
685}
686
687/* XXX deprecated - old animation system */
688static void direct_link_nlastrips(BlendDataReader *reader, ListBase *strips)
689{
690 BLO_read_struct_list(reader, bActionStrip, strips);
691
692 LISTBASE_FOREACH (bActionStrip *, strip, strips) {
693 BLO_read_struct_list(reader, bActionModifier, &strip->modifiers);
694 }
695}
696
698{
699 Object *ob = (Object *)id;
700
701 ob->runtime = MEM_new<blender::bke::ObjectRuntime>(__func__);
702
703 PartEff *paf;
704
705 /* XXX This should not be needed - but seems like it can happen in some cases,
706 * so for now play safe. */
707 ob->proxy_from = nullptr;
708
709 const bool is_undo = BLO_read_data_is_undo(reader);
710 if (ob->id.tag & (ID_TAG_EXTERN | ID_TAG_INDIRECT)) {
711 /* Do not allow any non-object mode for linked data.
712 * See #34776, #42780, #81027 for more information. */
713 ob->mode &= ~OB_MODE_ALL_MODE_DATA;
714 }
715 else if (is_undo) {
716 /* For undo we want to stay in object mode during undo presses, so keep some edit modes
717 * disabled.
718 * TODO: Check if we should not disable more edit modes here? */
720 }
721
722 BLO_read_struct(reader, bPose, &ob->pose);
723 BKE_pose_blend_read_data(reader, &ob->id, ob->pose);
724
725 BLO_read_struct(reader, bMotionPath, &ob->mpath);
726 if (ob->mpath) {
728 }
729
730 /* Only for versioning, vertex group names are now stored on object data. */
731 BLO_read_struct_list(reader, bDeformGroup, &ob->defbase);
732 BLO_read_struct_list(reader, bFaceMap, &ob->fmaps);
733
734 /* XXX deprecated - old animation system <<< */
735 direct_link_nlastrips(reader, &ob->nlastrips);
736 BLO_read_struct_list(reader, bConstraintChannel, &ob->constraintChannels);
737 /* >>> XXX deprecated - old animation system */
738
739 BLO_read_pointer_array(reader, ob->totcol, (void **)&ob->mat);
740 BLO_read_char_array(reader, ob->totcol, &ob->matbits);
741
742 /* do it here, below old data gets converted */
743 BKE_modifier_blend_read_data(reader, &ob->modifiers, ob);
745 BKE_shaderfx_blend_read_data(reader, &ob->shader_fx, ob);
746
747 BLO_read_struct_list(reader, PartEff, &ob->effect);
748 paf = (PartEff *)ob->effect.first;
749 while (paf) {
750 if (paf->type == EFF_PARTICLE) {
751 paf->keys = nullptr;
752 }
753 if (paf->type == EFF_WAVE) {
754 WaveEff *wav = (WaveEff *)paf;
755 PartEff *next = paf->next;
757
758 wmd->damp = wav->damp;
759 wmd->flag = wav->flag;
760 wmd->height = wav->height;
761 wmd->lifetime = wav->lifetime;
762 wmd->narrow = wav->narrow;
763 wmd->speed = wav->speed;
764 wmd->startx = wav->startx;
765 wmd->starty = wav->startx;
766 wmd->timeoffs = wav->timeoffs;
767 wmd->width = wav->width;
768
769 BLI_addtail(&ob->modifiers, wmd);
771
772 BLI_remlink(&ob->effect, paf);
773 MEM_freeN(paf);
774
775 paf = next;
776 continue;
777 }
778 if (paf->type == EFF_BUILD) {
779 BuildEff *baf = (BuildEff *)paf;
780 PartEff *next = paf->next;
782
783 bmd->start = baf->sfra;
784 bmd->length = baf->len;
785 bmd->randomize = 0;
786 bmd->seed = 1;
787
788 BLI_addtail(&ob->modifiers, bmd);
790
791 BLI_remlink(&ob->effect, paf);
792 MEM_freeN(paf);
793
794 paf = next;
795 continue;
796 }
797 paf = paf->next;
798 }
799
800 BLO_read_struct(reader, PartDeflect, &ob->pd);
802 BLO_read_struct(reader, SoftBody, &ob->soft);
803 if (ob->soft) {
804 SoftBody *sb = ob->soft;
805
806 sb->bpoint = nullptr; /* init pointers so it gets rebuilt nicely */
807 sb->bspring = nullptr;
808 sb->scratch = nullptr;
809 /* although not used anymore */
810 /* still have to be loaded to be compatible with old files */
811 BLO_read_pointer_array(reader, sb->totkey, (void **)&sb->keys);
812 if (sb->keys) {
813 for (int a = 0; a < sb->totkey; a++) {
814 BLO_read_struct(reader, SBVertex, &sb->keys[a]);
815 }
816 }
817
819 if (!sb->effector_weights) {
821 }
822
824 if (sb->shared == nullptr) {
825 /* Link deprecated caches if they exist, so we can use them for versioning.
826 * We should only do this when `sb->shared == nullptr`, because those pointers
827 * are always set (for compatibility with older Blenders). We mustn't link
828 * the same point-cache twice. */
829 BKE_ptcache_blend_read_data(reader, &sb->ptcaches, &sb->pointcache, false);
830 }
831 else {
832 /* link caches */
833 BKE_ptcache_blend_read_data(reader, &sb->shared->ptcaches, &sb->shared->pointcache, false);
834 }
835 }
836 BLO_read_struct(reader, FluidsimSettings, &ob->fluidsimSettings); /* NT */
837
839 if (ob->rigidbody_object) {
840 RigidBodyOb *rbo = ob->rigidbody_object;
841 /* Allocate runtime-only struct */
842 rbo->shared = (RigidBodyOb_Shared *)MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared");
843 }
845 if (ob->rigidbody_constraint) {
847 }
848
851
853
854 BLO_read_struct_list(reader, ObHook, &ob->hooks);
855 while (ob->hooks.first) {
856 ObHook *hook = (ObHook *)ob->hooks.first;
858
859 BLO_read_int32_array(reader, hook->totindex, &hook->indexar);
860
861 /* Do conversion here because if we have loaded
862 * a hook we need to make sure it gets converted
863 * and freed, regardless of version.
864 */
865 copy_v3_v3(hmd->cent, hook->cent);
866 hmd->falloff = hook->falloff;
867 hmd->force = hook->force;
868 hmd->indexar = hook->indexar;
869 hmd->object = hook->parent;
870 memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
871 hmd->indexar_num = hook->totindex;
872
873 BLI_addhead(&ob->modifiers, hmd);
874 BLI_remlink(&ob->hooks, hook);
875
878
879 MEM_freeN(hook);
880 }
881
882 BLO_read_struct(reader, ImageUser, &ob->iuser);
883 if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE && !ob->iuser) {
885 }
886
887 BLO_read_struct_list(reader, LinkData, &ob->pc_ids);
888
889 /* in case this value changes in future, clamp else we get undefined behavior */
891
892 if (ob->sculpt) {
893 ob->sculpt = nullptr;
894 /* Only create data on undo, otherwise rely on editor mode switching. */
895 if (BLO_read_data_is_undo(reader) && (ob->mode & OB_MODE_ALL_SCULPT)) {
897 }
898 }
899
900 BLO_read_struct(reader, PreviewImage, &ob->preview);
902
905
907 if (ob->lightprobe_cache) {
909 }
910}
911
913{
914 Object *ob = reinterpret_cast<Object *>(id);
915
916 Main *bmain = BLO_read_lib_get_main(reader);
917 BlendFileReadReport *reports = BLO_read_lib_reports(reader);
918
919 if (ob->data == nullptr && ob->type != OB_EMPTY) {
920 /* NOTE: This case is not expected to happen anymore, since in when a linked ID disappears, an
921 * empty placeholder is created for it by readfile code. Only some serious corruption of data
922 * should be able to trigger this code nowadays. */
923
924 ob->type = OB_EMPTY;
925
926 if (ob->pose) {
927 /* This code is now executed after _all_ ID pointers have been lib-linked,so it's safe to do
928 * a proper cleanup. Further more, since user count of IDs is not done in read-code anymore,
929 * `BKE_pose_free_ex(ob->pose, false)` can be called (instead of
930 * `BKE_pose_free_ex(ob->pose)`), avoiding any access to other IDs altogether. */
931 BKE_pose_free_ex(ob->pose, false);
932 ob->pose = nullptr;
933 ob->mode &= ~OB_MODE_POSE;
934 }
935
936 if (ob->id.lib) {
937 BLO_reportf_wrap(reports,
938 RPT_INFO,
939 RPT_("Can't find object data of %s lib %s"),
940 ob->id.name + 2,
941 ob->id.lib->filepath);
942 }
943 else {
944 BLO_reportf_wrap(reports, RPT_INFO, RPT_("Object %s lost data"), ob->id.name + 2);
945 }
946 reports->count.missing_obdata++;
947 }
948
949 /* When the object is local and the data is library its possible
950 * the material list size gets out of sync. #22663. */
951 if (ob->data && ob->id.lib != static_cast<ID *>(ob->data)->lib) {
952 BKE_object_materials_test(bmain, ob, static_cast<ID *>(ob->data));
953 }
954
955 /* Performs quite extensive rebuilding & validation of object-level Pose data from the Armature
956 * obdata. */
958
960}
961
963{
964 PartEff *paf;
965
966 paf = (PartEff *)ob->effect.first;
967 while (paf) {
968 if (paf->type == EFF_PARTICLE) {
969 return paf;
970 }
971 paf = paf->next;
972 }
973 return nullptr;
974}
975
976static void object_lib_override_apply_post(ID *id_dst, ID *id_src)
977{
978 /* id_dst is the new local override copy of the linked reference data. id_src is the old override
979 * data stored on disk, used as source data for override operations. */
980 Object *object_dst = (Object *)id_dst;
981 Object *object_src = (Object *)id_src;
982
983 ListBase pidlist_dst, pidlist_src;
984 BKE_ptcache_ids_from_object(&pidlist_dst, object_dst, nullptr, 0);
985 BKE_ptcache_ids_from_object(&pidlist_src, object_src, nullptr, 0);
986
987 /* Problem with point caches is that several status flags (like OUTDATED or BAKED) are read-only
988 * at RNA level, and therefore not overridable per-se.
989 *
990 * This code is a workaround this to check all point-caches from both source and destination
991 * objects in parallel, and transfer those flags when it makes sense.
992 *
993 * This allows to keep baked caches across lib-overrides applies.
994 *
995 * NOTE: This is fairly hackish and weak, but so is the point-cache system as its whole. A more
996 * robust solution would be e.g. to have a specific RNA entry point to deal with such cases
997 * (maybe a new flag to allow override code to set values of some read-only properties?).
998 */
999 PTCacheID *pid_src, *pid_dst;
1000 for (pid_dst = (PTCacheID *)pidlist_dst.first, pid_src = (PTCacheID *)pidlist_src.first;
1001 pid_dst != nullptr;
1002 pid_dst = pid_dst->next, pid_src = (pid_src != nullptr) ? pid_src->next : nullptr)
1003 {
1004 /* If pid's do not match, just tag info of caches in dst as dirty and continue. */
1005 if (pid_src == nullptr) {
1006 continue;
1007 }
1008 if (pid_dst->type != pid_src->type || pid_dst->file_type != pid_src->file_type ||
1009 pid_dst->default_step != pid_src->default_step || pid_dst->max_step != pid_src->max_step ||
1010 pid_dst->data_types != pid_src->data_types || pid_dst->info_types != pid_src->info_types)
1011 {
1012 LISTBASE_FOREACH (PointCache *, point_cache_src, pid_src->ptcaches) {
1013 point_cache_src->flag |= PTCACHE_FLAG_INFO_DIRTY;
1014 }
1015 continue;
1016 }
1017
1018 PointCache *point_cache_dst, *point_cache_src;
1019 for (point_cache_dst = (PointCache *)pid_dst->ptcaches->first,
1020 point_cache_src = (PointCache *)pid_src->ptcaches->first;
1021 point_cache_dst != nullptr;
1022 point_cache_dst = point_cache_dst->next,
1023 point_cache_src = (point_cache_src != nullptr) ? point_cache_src->next : nullptr)
1024 {
1025 /* Always force updating info about caches of applied lib-overrides. */
1026 point_cache_dst->flag |= PTCACHE_FLAG_INFO_DIRTY;
1027 if (point_cache_src == nullptr || !STREQ(point_cache_dst->name, point_cache_src->name)) {
1028 continue;
1029 }
1030 if ((point_cache_src->flag & PTCACHE_BAKED) != 0) {
1031 point_cache_dst->flag |= PTCACHE_BAKED;
1032 }
1033 if ((point_cache_src->flag & PTCACHE_OUTDATED) == 0) {
1034 point_cache_dst->flag &= ~PTCACHE_OUTDATED;
1035 }
1036 }
1037 }
1038 BLI_freelistN(&pidlist_dst);
1039 BLI_freelistN(&pidlist_src);
1040}
1041
1043{
1044 using namespace blender::bke;
1045 float3 dimensions;
1046 BKE_object_dimensions_get(ob, dimensions);
1047 if (is_zero_v3(dimensions)) {
1048 return nullptr;
1049 }
1050 return idprop::create("dimensions", Span(&dimensions.x, 3)).release();
1051}
1052
1053static void object_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
1054{
1055 Object *ob = (Object *)asset_ptr;
1056 BLI_assert(GS(ob->id.name) == ID_OB);
1057
1058 /* Update dimensions hint for the asset. */
1059 if (IDProperty *dimensions_prop = object_asset_dimensions_property(ob)) {
1060 BKE_asset_metadata_idprop_ensure(asset_data, dimensions_prop);
1061 }
1062}
1063
1065 /*pre_save_fn*/ object_asset_metadata_ensure,
1066 /*on_mark_asset_fn*/ object_asset_metadata_ensure,
1067 /*on_clear_asset_fn*/ nullptr,
1068};
1069
1071 /*id_code*/ ID_OB,
1072 /*id_filter*/ FILTER_ID_OB,
1073 /* Could be more specific, but simpler to just always say 'yes' here. */
1074 /*dependencies_id_types*/ FILTER_ID_ALL,
1075 /*main_listbase_index*/ INDEX_ID_OB,
1076 /*struct_size*/ sizeof(Object),
1077 /*name*/ "Object",
1078 /*name_plural*/ N_("objects"),
1079 /*translation_context*/ BLT_I18NCONTEXT_ID_OBJECT,
1080 /*flags*/ 0,
1081 /*asset_type_info*/ &AssetType_OB,
1082
1083 /*init_data*/ object_init_data,
1084 /*copy_data*/ object_copy_data,
1085 /*free_data*/ object_free_data,
1086 /*make_local*/ nullptr,
1087 /*foreach_id*/ object_foreach_id,
1088 /*foreach_cache*/ object_foreach_cache,
1089 /*foreach_path*/ object_foreach_path,
1090 /*owner_pointer_get*/ nullptr,
1091
1092 /*blend_write*/ object_blend_write,
1093 /*blend_read_data*/ object_blend_read_data,
1094 /*blend_read_after_liblink*/ object_blend_read_after_liblink,
1095
1096 /*blend_read_undo_preserve*/ nullptr,
1097
1098 /*lib_override_apply_post*/ object_lib_override_apply_post,
1099};
1100
1102{
1103 *workob = blender::dna::shallow_zero_initialize();
1104
1105 workob->scale[0] = workob->scale[1] = workob->scale[2] = 1.0f;
1106 workob->dscale[0] = workob->dscale[1] = workob->dscale[2] = 1.0f;
1107 workob->rotmode = ROT_MODE_EUL;
1108}
1109
1111{
1112 while (ParticleSystem *psys = (ParticleSystem *)BLI_pophead(&ob->particlesystem)) {
1113 psys_free(ob, psys);
1114 }
1115}
1116
1118{
1119 sbFree(ob);
1120}
1121
1123{
1124 if (ob->runtime->curve_cache) {
1125 BKE_displist_free(&ob->runtime->curve_cache->disp);
1126 BKE_curve_bevelList_free(&ob->runtime->curve_cache->bev);
1127 if (ob->runtime->curve_cache->anim_path_accum_length) {
1128 MEM_freeN((void *)ob->runtime->curve_cache->anim_path_accum_length);
1129 }
1130 BKE_nurbList_free(&ob->runtime->curve_cache->deformed_nurbs);
1131 MEM_freeN(ob->runtime->curve_cache);
1132 ob->runtime->curve_cache = nullptr;
1133 }
1134}
1135
1137{
1138 while (ModifierData *md = (ModifierData *)BLI_pophead(&ob->modifiers)) {
1140 }
1141
1142 while (
1144 {
1146 }
1147 /* Particle modifiers were freed, so free the particle-systems as well. */
1149
1150 /* Same for soft-body */
1152
1153 /* modifiers may have stored data in the DM cache */
1155}
1156
1158{
1159 while (ShaderFxData *fx = (ShaderFxData *)BLI_pophead(&ob->shader_fx)) {
1161 }
1162}
1163
1165{
1166 /* reset functionality */
1167 if (hmd->object) {
1169
1170 if (hmd->subtarget[0] && pchan) {
1171 float imat[4][4], mat[4][4];
1172
1173 /* Calculate the world-space matrix for the pose-channel target first,
1174 * then carry on as usual. */
1175 mul_m4_m4m4(mat, hmd->object->object_to_world().ptr(), pchan->pose_mat);
1176
1177 invert_m4_m4(imat, mat);
1178 mul_m4_m4m4(hmd->parentinv, imat, ob->object_to_world().ptr());
1179 }
1180 else {
1181 invert_m4_m4(hmd->object->runtime->world_to_object.ptr(),
1182 hmd->object->object_to_world().ptr());
1184 hmd->parentinv, hmd->object->world_to_object().ptr(), ob->object_to_world().ptr());
1185 }
1186 }
1187}
1188
1190{
1191 if (hmd->object == nullptr) {
1192 return;
1193 }
1194 /* reset functionality */
1196
1197 if (hmd->subtarget[0] && pchan) {
1198 float imat[4][4], mat[4][4];
1199
1200 /* Calculate the world-space matrix for the pose-channel target first,
1201 * then carry on as usual. */
1202 mul_m4_m4m4(mat, hmd->object->object_to_world().ptr(), pchan->pose_mat);
1203
1204 invert_m4_m4(imat, mat);
1205 mul_m4_m4m4(hmd->parentinv, imat, ob->object_to_world().ptr());
1206 }
1207 else {
1208 invert_m4_m4(hmd->object->runtime->world_to_object.ptr(),
1209 hmd->object->object_to_world().ptr());
1210 mul_m4_m4m4(hmd->parentinv, hmd->object->world_to_object().ptr(), ob->object_to_world().ptr());
1211 }
1212}
1213
1215{
1216 LISTBASE_FOREACH (ModifierData *, md_iter, &ob->modifiers) {
1217 md_iter->flag &= ~eModifierFlag_Active;
1218 }
1219
1220 if (md != nullptr) {
1221 BLI_assert(BLI_findindex(&ob->modifiers, md) != -1);
1223 }
1224}
1225
1227{
1228 /* In debug mode, check for only one active modifier. */
1229#ifndef NDEBUG
1230 int active_count = 0;
1232 if (md->flag & eModifierFlag_Active) {
1233 active_count++;
1234 }
1235 }
1236 BLI_assert(ELEM(active_count, 0, 1));
1237#endif
1238
1240 if (md->flag & eModifierFlag_Active) {
1241 return md;
1242 }
1243 }
1244
1245 return nullptr;
1246}
1247
1249{
1250 return ELEM(ob->type,
1251 OB_MESH,
1252 OB_CURVES,
1254 OB_SURF,
1255 OB_FONT,
1256 OB_LATTICE,
1258 OB_VOLUME,
1260}
1261
1262bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
1263{
1264 const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)modifier_type);
1265
1266 /* Surface and lattice objects don't output geometry sets. */
1267 if (mti->modify_geometry_set != nullptr && ELEM(ob->type, OB_SURF, OB_LATTICE)) {
1268 return false;
1269 }
1270
1271 if (ELEM(ob->type, OB_POINTCLOUD, OB_CURVES)) {
1273 }
1274 if (ob->type == OB_VOLUME) {
1275 return mti->modify_geometry_set != nullptr;
1276 }
1278 if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) {
1279 return false;
1280 }
1281
1282 if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
1283 (ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
1284 {
1285 return false;
1286 }
1287
1288 return true;
1289 }
1291 return true;
1292 }
1293
1294 return false;
1295}
1296
1298{
1300}
1301
1312 const Scene *scene,
1313 Object *ob_dst,
1314 ParticleSystem *psys_src)
1315{
1316 ParticleSystem *psys_dst = nullptr;
1317
1318 /* Check if a particle system with the same particle settings
1319 * already exists on the destination object. */
1320 LISTBASE_FOREACH (ParticleSystem *, psys, &ob_dst->particlesystem) {
1321 if (psys->part == psys_src->part) {
1322 psys_dst = psys;
1323 break;
1324 }
1325 }
1326
1327 /* If it does not exist, copy the particle system to the destination object. */
1328 if (psys_dst == nullptr) {
1329 ModifierData *md = object_copy_particle_system(bmain, scene, ob_dst, psys_src);
1330 psys_dst = ((ParticleSystemModifierData *)md)->psys;
1331 }
1332
1333 return psys_dst;
1334}
1335
1337 const Scene *scene,
1338 Object *ob_dst,
1339 const Object *ob_src,
1340 const ModifierData *md_src)
1341{
1342 BLI_assert(ob_dst->type != OB_GPENCIL_LEGACY);
1343
1346 /* We never allow copying those modifiers here. */
1347 return false;
1348 }
1349 if (!BKE_object_support_modifier_type_check(ob_dst, md_src->type)) {
1350 return false;
1351 }
1352 if (mti->flags & eModifierTypeFlag_Single) {
1353 if (BKE_modifiers_findby_type(ob_dst, (ModifierType)md_src->type) != nullptr) {
1354 return false;
1355 }
1356 }
1357
1358 ParticleSystem *psys_src = nullptr;
1359 ParticleSystem *psys_dst = nullptr;
1360
1361 switch (md_src->type) {
1363 BKE_object_copy_softbody(ob_dst, ob_src, 0);
1364 break;
1365 case eModifierType_Skin:
1366 /* ensure skin-node customdata exists */
1368 break;
1369 case eModifierType_Fluid: {
1370 const FluidModifierData *fmd = (const FluidModifierData *)md_src;
1371 if (fmd->type == MOD_FLUID_TYPE_FLOW) {
1372 if (fmd->flow != nullptr && fmd->flow->psys != nullptr) {
1373 psys_src = fmd->flow->psys;
1374 psys_dst = object_copy_modifier_particle_system_ensure(bmain, scene, ob_dst, psys_src);
1375 }
1376 }
1377 break;
1378 }
1380 const DynamicPaintModifierData *dpmd = (const DynamicPaintModifierData *)md_src;
1381 if (dpmd->brush != nullptr && dpmd->brush->psys != nullptr) {
1382 psys_src = dpmd->brush->psys;
1383 psys_dst = object_copy_modifier_particle_system_ensure(bmain, scene, ob_dst, psys_src);
1384 }
1385 break;
1386 }
1387 default:
1388 break;
1389 }
1390
1391 ModifierData *md_dst;
1392 if (md_src->type == eModifierType_ParticleSystem) {
1394 bmain, scene, ob_dst, ((const ParticleSystemModifierData *)md_src)->psys);
1395 }
1396 else {
1397 md_dst = BKE_modifier_new(md_src->type);
1398
1399 STRNCPY(md_dst->name, md_src->name);
1400
1401 if (md_src->type == eModifierType_Multires) {
1402 /* Has to be done after mod creation, but *before* we actually copy its settings! */
1404 ob_dst, (const MultiresModifierData *)md_src, (MultiresModifierData *)md_dst);
1405 }
1406
1407 BKE_modifier_copydata(md_src, md_dst);
1408
1409 switch (md_dst->type) {
1411 if (psys_dst != nullptr) {
1412 FluidModifierData *fmd_dst = (FluidModifierData *)md_dst;
1413 BLI_assert(fmd_dst->type == MOD_FLUID_TYPE_FLOW && fmd_dst->flow != nullptr &&
1414 fmd_dst->flow->psys != nullptr);
1415 fmd_dst->flow->psys = psys_dst;
1416 }
1417 break;
1419 if (psys_dst != nullptr) {
1421 BLI_assert(dpmd_dst->brush != nullptr && dpmd_dst->brush->psys != nullptr);
1422 dpmd_dst->brush->psys = psys_dst;
1423 }
1424 break;
1425 default:
1426 break;
1427 }
1428
1429 ModifierData *next_md = nullptr;
1431 if (md->flag & eModifierFlag_PinLast) {
1432 next_md = md;
1433 }
1434 else {
1435 break;
1436 }
1437 }
1438 BLI_insertlinkbefore(&ob_dst->modifiers, next_md, md_dst);
1439 BKE_modifier_unique_name(&ob_dst->modifiers, md_dst);
1440 BKE_modifiers_persistent_uid_init(*ob_dst, *md_dst);
1441 }
1442
1443 BKE_object_modifier_set_active(ob_dst, md_dst);
1444
1445 return true;
1446}
1447
1449 const Object *ob_src,
1450 const bool do_copy_all,
1451 const int flag_subdata)
1452{
1453 if ((ob_dst->type == OB_GPENCIL_LEGACY) != (ob_src->type == OB_GPENCIL_LEGACY)) {
1454 BLI_assert_msg(false,
1455 "Trying to copy a modifier stack between a GPencil object and another type.");
1456 return false;
1457 }
1458
1459 if (!BLI_listbase_is_empty(&ob_dst->modifiers) ||
1461 {
1463 false,
1464 "Trying to copy a modifier stack into an object having a non-empty modifier stack.");
1465 return false;
1466 }
1467
1468 LISTBASE_FOREACH (ModifierData *, md_src, &ob_src->modifiers) {
1469 if (!do_copy_all && !object_modifier_type_copy_check((ModifierType)md_src->type)) {
1470 continue;
1471 }
1472 if (!BKE_object_support_modifier_type_check(ob_dst, md_src->type)) {
1473 continue;
1474 }
1475
1476 ModifierData *md_dst = BKE_modifier_copy_ex(md_src, flag_subdata);
1477 BLI_addtail(&ob_dst->modifiers, md_dst);
1478 }
1479
1480 /* This could be copied from anywhere, since no other modifier actually use this data. But for
1481 * consistency do it together with particle systems. */
1482 BKE_object_copy_softbody(ob_dst, ob_src, flag_subdata);
1483
1484 /* It is mandatory that this happens after copying modifiers, as it will update their `psys`
1485 * pointers accordingly. */
1486 BKE_object_copy_particlesystems(ob_dst, ob_src, flag_subdata);
1487
1488 return true;
1489}
1490
1491void BKE_object_link_modifiers(Object *ob_dst, const Object *ob_src)
1492{
1493 BKE_object_free_modifiers(ob_dst, 0);
1494
1495 BKE_object_modifier_stack_copy(ob_dst, ob_src, false, 0);
1496}
1497
1501static void copy_ccg_data(Mesh *mesh_destination,
1502 Mesh *mesh_source,
1503 const eCustomDataType layer_type)
1504{
1505 BLI_assert(mesh_destination->corners_num == mesh_source->corners_num);
1506 CustomData *data_destination = &mesh_destination->corner_data;
1507 CustomData *data_source = &mesh_source->corner_data;
1508 const int num_elements = mesh_source->corners_num;
1509 if (!CustomData_has_layer(data_source, layer_type)) {
1510 return;
1511 }
1512 const int layer_index = CustomData_get_layer_index(data_destination, layer_type);
1513 CustomData_free_layer(data_destination, layer_type, num_elements, layer_index);
1514 BLI_assert(!CustomData_has_layer(data_destination, layer_type));
1516 data_destination, eCustomDataType(layer_type), CD_SET_DEFAULT, num_elements);
1517 BLI_assert(CustomData_has_layer(data_destination, layer_type));
1518 CustomData_copy_layer_type_data(data_source, data_destination, layer_type, 0, 0, num_elements);
1519}
1520
1522{
1523 /* Currently CCG is only created for Mesh objects. */
1524 if (object->type != OB_MESH) {
1525 return;
1526 }
1527 /* If object does not own evaluated mesh we can not access it since it might be freed already
1528 * (happens on dependency graph free where order of evaluated IDs free is undefined).
1529 *
1530 * Good news is: such mesh does not have modifiers applied, so no need to worry about CCG. */
1531 if (!object->runtime->is_data_eval_owned) {
1532 return;
1533 }
1534 /* Object was never evaluated, so can not have CCG subdivision surface. If it were evaluated, do
1535 * not try to compute OpenSubDiv on the CPU as it is not needed here. */
1537 if (mesh_eval == nullptr) {
1538 return;
1539 }
1540 SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg.get();
1541 if (subdiv_ccg == nullptr) {
1542 return;
1543 }
1544 /* Check whether there is anything to be reshaped. */
1545 if (!subdiv_ccg->dirty.coords && !subdiv_ccg->dirty.hidden) {
1546 return;
1547 }
1548 const int tot_level = mesh_eval->runtime->subdiv_ccg_tot_level;
1549 Object *object_orig = DEG_get_original_object(object);
1550 Mesh *mesh_orig = (Mesh *)object_orig->data;
1551 multiresModifier_reshapeFromCCG(tot_level, mesh_orig, subdiv_ccg);
1552 /* NOTE: we need to reshape into an original mesh from main database,
1553 * allowing:
1554 *
1555 * - Update copies of that mesh at any moment.
1556 * - Save the file without doing extra reshape.
1557 * - All the users of the mesh have updated displacement.
1558 *
1559 * However, the tricky part here is that we only know about sculpted
1560 * state of a mesh on an object level, and object is being updated after
1561 * mesh data-block is updated. This forces us to:
1562 *
1563 * - Update mesh data-block from object evaluation, which is technically
1564 * forbidden, but there is no other place for this yet.
1565 * - Reshape to the original mesh from main database, and then copy updated
1566 * layer to copy of that mesh (since copy of the mesh has decoupled
1567 * custom data layers).
1568 *
1569 * All this is defeating all the designs we need to follow to allow safe
1570 * threaded evaluation, but this is as good as we can make it within the
1571 * current sculpt/evaluated mesh design. This is also how we've survived
1572 * with old #DerivedMesh based solutions. So, while this is all wrong and
1573 * needs reconsideration, doesn't seem to be a big stopper for real
1574 * production artists.
1575 */
1576 /* TODO(sergey): Solve this somehow, to be fully stable for threaded
1577 * evaluation environment.
1578 */
1579 /* NOTE: runtime.data_orig is what was before assigning mesh_eval,
1580 * it is orig as in what was in object_eval->data before evaluating
1581 * modifier stack.
1582 *
1583 * mesh_cow is a copy-on-written version of `object_orig->data`.
1584 */
1585 Mesh *mesh_cow = (Mesh *)object->runtime->data_orig;
1586 copy_ccg_data(mesh_cow, mesh_orig, CD_MDISPS);
1587 copy_ccg_data(mesh_cow, mesh_orig, CD_GRID_PAINT_MASK);
1588 /* Everything is now up-to-date. */
1589 subdiv_ccg->dirty.coords = false;
1590 subdiv_ccg->dirty.hidden = false;
1591}
1592
1593void BKE_object_eval_assign_data(Object *object_eval, ID *data_eval, bool is_owned)
1594{
1595 BLI_assert(object_eval->id.tag & ID_TAG_COPIED_ON_EVAL);
1596 BLI_assert(object_eval->runtime->data_eval == nullptr);
1597 BLI_assert(data_eval->tag & ID_TAG_NO_MAIN);
1598
1599 if (is_owned) {
1600 /* Set flag for debugging. */
1602 }
1603
1604 /* Assigned evaluated data. */
1605 object_eval->runtime->data_eval = data_eval;
1606 object_eval->runtime->is_data_eval_owned = is_owned;
1607
1608 /* Overwrite data of evaluated object, if the data-block types match. */
1609 ID *data = (ID *)object_eval->data;
1610 if (GS(data->name) == GS(data_eval->name)) {
1611 /* NOTE: we are not supposed to invoke evaluation for original objects,
1612 * but some areas are still being ported, so we play safe here. */
1613 if (object_eval->id.tag & ID_TAG_COPIED_ON_EVAL) {
1614 object_eval->data = data_eval;
1615 }
1616 }
1617
1618 /* Is set separately currently. */
1619 object_eval->runtime->geometry_set_eval = nullptr;
1620}
1621
1623{
1624 ob->runtime->bounds_eval.reset();
1625
1627
1628 if (ob->runtime->editmesh_eval_cage &&
1629 ob->runtime->editmesh_eval_cage != reinterpret_cast<Mesh *>(ob->runtime->data_eval))
1630 {
1631 BKE_id_free(nullptr, ob->runtime->editmesh_eval_cage);
1632 }
1633 ob->runtime->editmesh_eval_cage = nullptr;
1634
1635 if (ob->runtime->data_eval != nullptr) {
1636 if (ob->runtime->is_data_eval_owned) {
1637 ID *data_eval = ob->runtime->data_eval;
1638 if (GS(data_eval->name) == ID_ME) {
1639 BKE_id_free(nullptr, (Mesh *)data_eval);
1640 }
1641 else {
1642 BKE_libblock_free_data(data_eval, false);
1643 BKE_libblock_free_datablock(data_eval, 0);
1644 MEM_freeN(data_eval);
1645 }
1646 }
1647 ob->runtime->data_eval = nullptr;
1648 }
1649 if (ob->runtime->mesh_deform_eval != nullptr) {
1650 Mesh *mesh_deform_eval = ob->runtime->mesh_deform_eval;
1651 BKE_id_free(nullptr, mesh_deform_eval);
1652 ob->runtime->mesh_deform_eval = nullptr;
1653 }
1654
1655 /* Restore initial pointer for copy-on-evaluation data-blocks, object->data
1656 * might be pointing to an evaluated data-block data was just freed above. */
1657 if (ob->runtime->data_orig != nullptr) {
1658 ob->data = ob->runtime->data_orig;
1659 }
1660
1665
1667
1668 if (ob->runtime->geometry_set_eval != nullptr) {
1669 delete ob->runtime->geometry_set_eval;
1670 ob->runtime->geometry_set_eval = nullptr;
1671 }
1672}
1673
1675{
1676 short update_flag = 0;
1677
1678 /* Free particle system caches holding paths. */
1679 if (object->particlesystem.first) {
1680 LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
1681 psys_free_path_cache(psys, psys->edit);
1682 update_flag |= ID_RECALC_PSYS_REDO;
1683 }
1684 }
1685
1686 /* Free memory used by cached derived meshes in the particle system modifiers. */
1687 LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1688 if (md->type == eModifierType_ParticleSystem) {
1690 if (psmd->mesh_final) {
1691 BKE_id_free(nullptr, psmd->mesh_final);
1692 psmd->mesh_final = nullptr;
1693 if (psmd->mesh_original) {
1694 BKE_id_free(nullptr, psmd->mesh_original);
1695 psmd->mesh_original = nullptr;
1696 }
1698 update_flag |= ID_RECALC_GEOMETRY;
1699 }
1700 }
1701 }
1702
1703 /* NOTE: If object is coming from a duplicator, it might be a temporary
1704 * object created by dependency graph, which shares pointers with original
1705 * object. In this case we can not free anything.
1706 */
1707 if ((object->base_flag & BASE_FROM_DUPLI) == 0) {
1709 update_flag |= ID_RECALC_GEOMETRY;
1710 }
1711
1712 /* Tag object for update, so once memory critical operation is over and
1713 * scene update routines are back to its business the object will be
1714 * guaranteed to be in a known state.
1715 */
1716 if (update_flag != 0) {
1717 DEG_id_tag_update(&object->id, update_flag);
1718 }
1719}
1720
1722{
1723 if (ob->data == nullptr) {
1724 return false;
1725 }
1726
1727 switch (ob->type) {
1728 case OB_MESH:
1729 return ((Mesh *)ob->data)->runtime->edit_mesh != nullptr;
1730 case OB_ARMATURE:
1731 return ((bArmature *)ob->data)->edbo != nullptr;
1732 case OB_FONT:
1733 return ((Curve *)ob->data)->editfont != nullptr;
1734 case OB_MBALL:
1735 return ((MetaBall *)ob->data)->editelems != nullptr;
1736 case OB_LATTICE:
1737 return ((Lattice *)ob->data)->editlatt != nullptr;
1738 case OB_SURF:
1739 case OB_CURVES_LEGACY:
1740 return ((Curve *)ob->data)->editnurb != nullptr;
1741 case OB_GPENCIL_LEGACY:
1742 /* Grease Pencil object has no edit mode data. */
1743 return GPENCIL_EDIT_MODE((bGPdata *)ob->data);
1744 case OB_CURVES:
1745 case OB_POINTCLOUD:
1746 case OB_GREASE_PENCIL:
1747 return ob->mode == OB_MODE_EDIT;
1748 default:
1749 return false;
1750 }
1751}
1752
1757
1758bool BKE_object_data_is_in_editmode(const Object *ob, const ID *id)
1759{
1760 const short type = GS(id->name);
1762 switch (type) {
1763 case ID_ME:
1764 return ((const Mesh *)id)->runtime->edit_mesh != nullptr;
1765 case ID_CU_LEGACY:
1766 return ((((const Curve *)id)->editnurb != nullptr) ||
1767 (((const Curve *)id)->editfont != nullptr));
1768 case ID_MB:
1769 return ((const MetaBall *)id)->editelems != nullptr;
1770 case ID_LT:
1771 return ((const Lattice *)id)->editlatt != nullptr;
1772 case ID_AR:
1773 return ((const bArmature *)id)->edbo != nullptr;
1774 case ID_CV:
1775 case ID_PT:
1776 case ID_GP:
1777 if (ob) {
1778 return BKE_object_is_in_editmode(ob);
1779 }
1780 return false;
1781 default:
1783 return false;
1784 }
1785}
1786
1788{
1789 const short type = GS(id->name);
1790 switch (type) {
1791 case ID_ME: {
1792 if (BMEditMesh *em = ((Mesh *)id)->runtime->edit_mesh.get()) {
1793 return &em->needs_flush_to_id;
1794 }
1795 break;
1796 }
1797 case ID_CU_LEGACY: {
1798 if (((Curve *)id)->vfont != nullptr) {
1799 EditFont *ef = ((Curve *)id)->editfont;
1800 if (ef != nullptr) {
1801 return &ef->needs_flush_to_id;
1802 }
1803 }
1804 else {
1805 EditNurb *editnurb = ((Curve *)id)->editnurb;
1806 if (editnurb) {
1807 return &editnurb->needs_flush_to_id;
1808 }
1809 }
1810 break;
1811 }
1812 case ID_MB: {
1813 MetaBall *mb = (MetaBall *)id;
1814 return &mb->needs_flush_to_id;
1815 }
1816 case ID_LT: {
1817 EditLatt *editlatt = ((Lattice *)id)->editlatt;
1818 if (editlatt) {
1819 return &editlatt->needs_flush_to_id;
1820 }
1821 break;
1822 }
1823 case ID_AR: {
1824 bArmature *arm = (bArmature *)id;
1825 return &arm->needs_flush_to_id;
1826 }
1827 case ID_GP:
1828 case ID_PT:
1829 case ID_CV:
1830 return nullptr;
1831 default:
1833 return nullptr;
1834 }
1835 return nullptr;
1836}
1837
1839{
1840 if (ob->type == OB_MESH) {
1841 Mesh *mesh = (Mesh *)ob->data;
1842 return ((ob->mode & OB_MODE_WEIGHT_PAINT) && (mesh->runtime->edit_mesh == nullptr) &&
1844 }
1845
1846 return false;
1847}
1848
1849bool BKE_object_has_mode_data(const Object *ob, eObjectMode object_mode)
1850{
1851 if (object_mode & OB_MODE_EDIT) {
1852 if (BKE_object_is_in_editmode(ob)) {
1853 return true;
1854 }
1855 }
1856 else if (object_mode & OB_MODE_VERTEX_PAINT) {
1857 if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) {
1858 return true;
1859 }
1860 }
1861 else if (object_mode & OB_MODE_WEIGHT_PAINT) {
1862 if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) {
1863 return true;
1864 }
1865 }
1866 else if (object_mode & OB_MODE_SCULPT) {
1867 if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) {
1868 return true;
1869 }
1870 }
1871 else if (object_mode & OB_MODE_POSE) {
1872 if (ob->pose != nullptr) {
1873 return true;
1874 }
1875 }
1876 return false;
1877}
1878
1880{
1881 return ((ob->mode == object_mode) || (ob->mode & object_mode) != 0);
1882}
1883
1884int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
1885{
1887 return 0;
1888 }
1889
1890 /* Test which components the object has. */
1891 int visibility = OB_VISIBLE_SELF;
1892 if (ob->particlesystem.first) {
1894 }
1895 else if (ob->transflag & OB_DUPLI) {
1896 visibility |= OB_VISIBLE_INSTANCES;
1897 }
1898
1900 visibility |= OB_VISIBLE_INSTANCES;
1901 }
1902
1903 /* Optional hiding of self if there are particles or instancers. */
1904 if (visibility & (OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES)) {
1905 switch ((eEvaluationMode)dag_eval_mode) {
1906 case DAG_EVAL_VIEWPORT:
1908 visibility &= ~OB_VISIBLE_SELF;
1909 }
1910 break;
1911 case DAG_EVAL_RENDER:
1913 visibility &= ~OB_VISIBLE_SELF;
1914 }
1915 break;
1916 }
1917 }
1918
1919 return visibility;
1920}
1921
1922bool BKE_object_exists_check(Main *bmain, const Object *obtest)
1923{
1924 if (obtest == nullptr) {
1925 return false;
1926 }
1927
1928 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1929 if (ob == obtest) {
1930 return true;
1931 }
1932 }
1933
1934 return false;
1935}
1936
1937/* *************************************************** */
1938
1939static const char *get_obdata_defname(int type)
1940{
1941 switch (type) {
1942 case OB_MESH:
1943 return DATA_("Mesh");
1944 case OB_CURVES_LEGACY:
1945 return DATA_("Curve");
1946 case OB_SURF:
1947 return DATA_("Surf");
1948 case OB_FONT:
1949 return DATA_("Text");
1950 case OB_MBALL:
1951 return DATA_("Mball");
1952 case OB_CAMERA:
1953 return DATA_("Camera");
1954 case OB_LAMP:
1955 return CTX_DATA_(BLT_I18NCONTEXT_ID_LIGHT, "Light");
1956 case OB_LATTICE:
1957 return DATA_("Lattice");
1958 case OB_ARMATURE:
1959 return DATA_("Armature");
1960 case OB_SPEAKER:
1961 return DATA_("Speaker");
1962 case OB_CURVES:
1963 return DATA_("Curves");
1964 case OB_POINTCLOUD:
1965 return DATA_("PointCloud");
1966 case OB_VOLUME:
1967 return CTX_DATA_(BLT_I18NCONTEXT_ID_ID, "Volume");
1968 case OB_EMPTY:
1969 return CTX_DATA_(BLT_I18NCONTEXT_ID_ID, "Empty");
1970 case OB_GPENCIL_LEGACY:
1971 return DATA_("GPencil");
1972 case OB_LIGHTPROBE:
1973 return DATA_("LightProbe");
1974 case OB_GREASE_PENCIL:
1975 return DATA_("GreasePencil");
1976 default:
1977 CLOG_ERROR(&LOG, "Internal error, bad type: %d", type);
1978 return CTX_DATA_(BLT_I18NCONTEXT_ID_ID, "Empty");
1979 }
1980}
1981
1982static void object_init(Object *ob, const short ob_type)
1983{
1984 object_init_data(&ob->id);
1985
1986 ob->type = ob_type;
1987
1988 if (ob->type != OB_EMPTY) {
1989 zero_v2(ob->ima_ofs);
1990 }
1991
1992 if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) {
1993 ob->trackflag = OB_NEGZ;
1994 ob->upflag = OB_POSY;
1995 }
1996
1997 if (ob->type == OB_GREASE_PENCIL) {
1999 }
2000
2001 if (ob->type == OB_LAMP) {
2002 /* Lights are invisible to camera rays and are assumed to be a
2003 * shadow catcher by default. */
2005 }
2006}
2007
2008void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
2009{
2010 if (name == nullptr) {
2011 name = get_obdata_defname(type);
2012 }
2013
2014 switch (type) {
2015 case OB_MESH:
2016 return BKE_mesh_add(bmain, name);
2017 case OB_CURVES_LEGACY:
2018 return BKE_curve_add(bmain, name, OB_CURVES_LEGACY);
2019 case OB_SURF:
2020 return BKE_curve_add(bmain, name, OB_SURF);
2021 case OB_FONT:
2022 return BKE_curve_add(bmain, name, OB_FONT);
2023 case OB_MBALL:
2024 return BKE_mball_add(bmain, name);
2025 case OB_CAMERA:
2026 return BKE_camera_add(bmain, name);
2027 case OB_LAMP:
2028 return BKE_light_add(bmain, name);
2029 case OB_LATTICE:
2030 return BKE_lattice_add(bmain, name);
2031 case OB_ARMATURE:
2032 return BKE_armature_add(bmain, name);
2033 case OB_SPEAKER:
2034 return BKE_speaker_add(bmain, name);
2035 case OB_LIGHTPROBE:
2036 return BKE_lightprobe_add(bmain, name);
2037 case OB_GPENCIL_LEGACY:
2038 return BKE_gpencil_data_addnew(bmain, name);
2039 case OB_CURVES:
2040 return BKE_curves_add(bmain, name);
2041 case OB_POINTCLOUD:
2042 return BKE_pointcloud_add_default(bmain, name);
2043 case OB_VOLUME:
2044 return BKE_volume_add(bmain, name);
2045 case OB_GREASE_PENCIL:
2046 return BKE_grease_pencil_add(bmain, name);
2047 case OB_EMPTY:
2048 return nullptr;
2049 default:
2050 CLOG_ERROR(&LOG, "Internal error, bad type: %d", type);
2051 return nullptr;
2052 }
2053}
2054
2056{
2057 /* Keep in sync with #OB_DATA_SUPPORT_ID macro. */
2058 switch (GS(id->name)) {
2059 case ID_ME:
2060 return OB_MESH;
2061 case ID_CU_LEGACY:
2062 return BKE_curve_type_get((const Curve *)id);
2063 case ID_MB:
2064 return OB_MBALL;
2065 case ID_LA:
2066 return OB_LAMP;
2067 case ID_SPK:
2068 return OB_SPEAKER;
2069 case ID_CA:
2070 return OB_CAMERA;
2071 case ID_LT:
2072 return OB_LATTICE;
2073 case ID_GD_LEGACY:
2074 return OB_GPENCIL_LEGACY;
2075 case ID_AR:
2076 return OB_ARMATURE;
2077 case ID_LP:
2078 return OB_LIGHTPROBE;
2079 case ID_CV:
2080 return OB_CURVES;
2081 case ID_PT:
2082 return OB_POINTCLOUD;
2083 case ID_VO:
2084 return OB_VOLUME;
2085 case ID_GP:
2086 return OB_GREASE_PENCIL;
2087 default:
2088 return -1;
2089 }
2090}
2091
2092Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
2093{
2094 if (!name) {
2095 name = get_obdata_defname(type);
2096 }
2097
2098 /* We cannot use #BKE_id_new here as we need some custom initialization code. */
2099 Object *ob = (Object *)BKE_libblock_alloc(bmain, ID_OB, name, bmain ? 0 : LIB_ID_CREATE_NO_MAIN);
2100
2101 /* We increase object user count when linking to Collections. */
2102 id_us_min(&ob->id);
2103
2104 /* default object vars */
2105 object_init(ob, type);
2106
2107 return ob;
2108}
2109
2111 Main *bmain, const Scene *scene, ViewLayer *view_layer, int type, const char *name)
2112{
2113 Object *ob = BKE_object_add_only_object(bmain, type, name);
2114 ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
2115 BKE_view_layer_base_deselect_all(scene, view_layer);
2116
2119 return ob;
2120}
2121
2123 Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
2124{
2125 Object *ob = object_add_common(bmain, scene, view_layer, type, name);
2126
2127 LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
2128 BKE_collection_viewlayer_object_add(bmain, view_layer, layer_collection->collection, ob);
2129
2130 /* NOTE: There is no way to be sure that #BKE_collection_viewlayer_object_add will actually
2131 * manage to find a valid collection in given `view_layer` to add the new object to. */
2132 BKE_view_layer_synced_ensure(scene, view_layer);
2133 Base *base = BKE_view_layer_base_find(view_layer, ob);
2134 if (base != nullptr) {
2136 }
2137
2138 return ob;
2139}
2140
2142 Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name, Object *ob_src)
2143{
2144 Object *ob = object_add_common(bmain, scene, view_layer, type, name);
2145 BKE_collection_object_add_from(bmain, scene, ob_src, ob);
2146
2147 BKE_view_layer_synced_ensure(scene, view_layer);
2148 Base *base = BKE_view_layer_base_find(view_layer, ob);
2150
2151 return ob;
2152}
2153
2155 const Scene *scene,
2156 ViewLayer *view_layer,
2157 int type,
2158 const char *name,
2159 ID *data,
2160 bool do_id_user)
2161{
2162 /* same as object_add_common, except we don't create new ob->data */
2163 Object *ob = BKE_object_add_only_object(bmain, type, name);
2164 ob->data = (void *)data;
2165 if (do_id_user) {
2166 id_us_plus(data);
2167 }
2168
2169 BKE_view_layer_base_deselect_all(scene, view_layer);
2172
2173 LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
2174 BKE_collection_object_add(bmain, layer_collection->collection, ob);
2175
2176 BKE_view_layer_synced_ensure(scene, view_layer);
2177 Base *base = BKE_view_layer_base_find(view_layer, ob);
2179
2180 return ob;
2181}
2182
2183void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src, const int flag)
2184{
2185 SoftBody *sb = ob_src->soft;
2186 const bool is_orig = (flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) == 0;
2187
2188 ob_dst->softflag = ob_src->softflag;
2189 if (sb == nullptr) {
2190 ob_dst->soft = nullptr;
2191 return;
2192 }
2193
2194 SoftBody *sbn = (SoftBody *)MEM_dupallocN(sb);
2195
2196 if ((flag & LIB_ID_COPY_CACHES) == 0) {
2197 sbn->totspring = sbn->totpoint = 0;
2198 sbn->bpoint = nullptr;
2199 sbn->bspring = nullptr;
2200 }
2201 else {
2202 sbn->totspring = sb->totspring;
2203 sbn->totpoint = sb->totpoint;
2204
2205 if (sbn->bpoint) {
2206 int i;
2207
2208 sbn->bpoint = (BodyPoint *)MEM_dupallocN(sbn->bpoint);
2209
2210 for (i = 0; i < sbn->totpoint; i++) {
2211 if (sbn->bpoint[i].springs) {
2212 sbn->bpoint[i].springs = (int *)MEM_dupallocN(sbn->bpoint[i].springs);
2213 }
2214 }
2215 }
2216
2217 if (sb->bspring) {
2218 sbn->bspring = (BodySpring *)MEM_dupallocN(sb->bspring);
2219 }
2220 }
2221
2222 sbn->keys = nullptr;
2223 sbn->totkey = sbn->totpointkey = 0;
2224
2225 sbn->scratch = nullptr;
2226
2227 if (is_orig) {
2230 &sbn->shared->ptcaches, &sb->shared->ptcaches, flag);
2231 }
2232
2233 if (sb->effector_weights) {
2235 }
2236
2237 ob_dst->soft = sbn;
2238}
2239
2241{
2243
2244 psys_copy_particles(psysn, psys);
2245
2246 if (psys->clmd) {
2249 psys->hair_in_mesh = psys->hair_out_mesh = nullptr;
2250 }
2251
2252 BLI_duplicatelist(&psysn->targets, &psys->targets);
2253
2254 psysn->pathcache = nullptr;
2255 psysn->childcache = nullptr;
2256 psysn->edit = nullptr;
2257 psysn->pdd = nullptr;
2258 psysn->effectors = nullptr;
2259 psysn->tree = nullptr;
2260 psysn->bvhtree = nullptr;
2261 psysn->batch_cache = nullptr;
2262
2265
2267 /* XXX Disabled, fails when evaluating depsgraph after copying ID with no main for preview
2268 * creation. */
2269 // BLI_assert((psys->flag & PSYS_SHARED_CACHES) == 0);
2270 psysn->flag |= PSYS_SHARED_CACHES;
2271 BLI_assert(psysn->pointcache != nullptr);
2272 }
2273 else {
2274 psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag);
2275 }
2276
2277 /* XXX(@ideasman42): from reading existing code this seems correct but intended usage of
2278 * point-cache should with cloth should be added in 'ParticleSystem'. */
2279 if (psysn->clmd) {
2280 psysn->clmd->point_cache = psysn->pointcache;
2281 }
2282
2283 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
2284 id_us_plus((ID *)psysn->part);
2285 }
2286
2287 return psysn;
2288}
2289
2290void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const int flag)
2291{
2292 if (ob_dst->type != OB_MESH) {
2293 /* currently only mesh objects can have soft body */
2294 return;
2295 }
2296
2298 LISTBASE_FOREACH (ParticleSystem *, psys, &ob_src->particlesystem) {
2300
2301 BLI_addtail(&ob_dst->particlesystem, npsys);
2302
2303 /* need to update particle modifiers too */
2304 LISTBASE_FOREACH (ModifierData *, md, &ob_dst->modifiers) {
2305 if (md->type == eModifierType_ParticleSystem) {
2307 if (psmd->psys == psys) {
2308 psmd->psys = npsys;
2309 }
2310 }
2311 else if (md->type == eModifierType_DynamicPaint) {
2313 if (pmd->brush) {
2314 if (pmd->brush->psys == psys) {
2315 pmd->brush->psys = npsys;
2316 }
2317 }
2318 }
2319 else if (md->type == eModifierType_Fluid) {
2321
2322 if (fmd->type == MOD_FLUID_TYPE_FLOW) {
2323 if (fmd->flow) {
2324 if (fmd->flow->psys == psys) {
2325 fmd->flow->psys = npsys;
2326 }
2327 }
2328 }
2329 }
2330 }
2331 }
2332}
2333
2334static void copy_object_pose(Object *obn, const Object *ob, const int flag)
2335{
2336 /* NOTE: need to clear `obn->pose` pointer first,
2337 * so that #BKE_pose_copy_data works (otherwise there's a crash) */
2338 obn->pose = nullptr;
2339 BKE_pose_copy_data_ex(&obn->pose, ob->pose, flag, true); /* true = copy constraints */
2340
2341 LISTBASE_FOREACH (bPoseChannel *, chan, &obn->pose->chanbase) {
2342 chan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE);
2343
2344 /* XXX Remapping object pointing onto itself should be handled by generic
2345 * BKE_library_remap stuff, but...
2346 * the flush_constraint_targets callback am not sure about, so will delay that for now. */
2347 LISTBASE_FOREACH (bConstraint *, con, &chan->constraints) {
2348 ListBase targets = {nullptr, nullptr};
2349
2350 if (BKE_constraint_targets_get(con, &targets)) {
2351 LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
2352 if (ct->tar == ob) {
2353 ct->tar = obn;
2354 }
2355 }
2356
2357 BKE_constraint_targets_flush(con, &targets, false);
2358 }
2359 }
2360 }
2361}
2362
2364{
2365 if ((ob) && (ob->type == OB_ARMATURE) && (ob->pose) && (ob->mode & OB_MODE_POSE)) {
2366 return true;
2367 }
2368
2369 return false;
2370}
2371
2373{
2374 if (ob == nullptr) {
2375 return nullptr;
2376 }
2377
2379 return ob;
2380 }
2381
2383
2384 /* Only use selected check when non-active. */
2386 return ob;
2387 }
2388
2389 return nullptr;
2390}
2391
2393{
2394 /* When not in weight paint mode. */
2395 if (ob) {
2396 switch (ob->type) {
2397 case OB_MESH: {
2398 if ((ob->mode & OB_MODE_WEIGHT_PAINT) == 0) {
2399 return nullptr;
2400 }
2401 break;
2402 }
2403 case OB_GPENCIL_LEGACY: {
2404 if ((ob->mode & OB_MODE_WEIGHT_GREASE_PENCIL) == 0) {
2405 return nullptr;
2406 }
2407 break;
2408 }
2409 }
2410 }
2412}
2413
2415 const Scene *scene,
2416 ViewLayer *view_layer,
2417 View3D *v3d)
2418{
2419 Object *ob_armature = BKE_object_pose_armature_get(ob);
2420 if (ob_armature) {
2421 BKE_view_layer_synced_ensure(scene, view_layer);
2422 Base *base = BKE_view_layer_base_find(view_layer, ob_armature);
2423 if (base) {
2424 if (BASE_VISIBLE(v3d, base)) {
2425 return ob_armature;
2426 }
2427 }
2428 }
2429 return nullptr;
2430}
2431
2433 ViewLayer *view_layer,
2434 View3D *v3d,
2435 bool unique)
2436{
2437 BKE_view_layer_synced_ensure(scene, view_layer);
2438 Object *ob_active = BKE_view_layer_active_object_get(view_layer);
2439 Object *ob_pose = BKE_object_pose_armature_get(ob_active);
2440 if (ob_pose == ob_active) {
2441 ObjectsInModeParams ob_params{};
2442 ob_params.object_mode = OB_MODE_POSE;
2443 ob_params.no_dup_data = unique;
2444
2445 return BKE_view_layer_array_from_objects_in_mode_params(scene, view_layer, v3d, &ob_params);
2446 }
2447 if (ob_pose != nullptr) {
2448 return {ob_pose};
2449 }
2450
2451 return {};
2452}
2454 ViewLayer *view_layer,
2455 View3D *v3d)
2456{
2457 return BKE_object_pose_array_get_ex(scene, view_layer, v3d, true);
2458}
2460{
2461 return BKE_object_pose_array_get_ex(scene, view_layer, v3d, false);
2462}
2463
2465 ViewLayer *view_layer,
2466 View3D *v3d,
2467 bool unique)
2468{
2469 BKE_view_layer_synced_ensure(scene, view_layer);
2470 Base *base_active = BKE_view_layer_active_base_get(view_layer);
2471 Object *ob_pose = base_active ? BKE_object_pose_armature_get(base_active->object) : nullptr;
2472 Base *base_pose = nullptr;
2473
2474 if (base_active) {
2475 if (ob_pose == base_active->object) {
2476 base_pose = base_active;
2477 }
2478 else {
2479 base_pose = BKE_view_layer_base_find(view_layer, ob_pose);
2480 }
2481 }
2482
2483 if (base_active && (base_pose == base_active)) {
2484 ObjectsInModeParams ob_params{};
2485 ob_params.object_mode = OB_MODE_POSE;
2486 ob_params.no_dup_data = unique;
2487
2488 return BKE_view_layer_array_from_bases_in_mode_params(scene, view_layer, v3d, &ob_params);
2489 }
2490 if (base_pose != nullptr) {
2491 return {base_pose};
2492 }
2493
2494 return {};
2495}
2497 ViewLayer *view_layer,
2498 View3D *v3d)
2499{
2500 return BKE_object_pose_base_array_get_ex(scene, view_layer, v3d, true);
2501}
2503 ViewLayer *view_layer,
2504 View3D *v3d)
2505{
2506 return BKE_object_pose_base_array_get_ex(scene, view_layer, v3d, false);
2507}
2508
2509void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
2510{
2511 copy_v3_v3(ob_tar->loc, ob_src->loc);
2512 copy_v3_v3(ob_tar->rot, ob_src->rot);
2513 copy_v4_v4(ob_tar->quat, ob_src->quat);
2514 copy_v3_v3(ob_tar->rotAxis, ob_src->rotAxis);
2515 ob_tar->rotAngle = ob_src->rotAngle;
2516 ob_tar->rotmode = ob_src->rotmode;
2517 copy_v3_v3(ob_tar->scale, ob_src->scale);
2518}
2519
2521 Object *ob,
2522 eDupli_ID_Flags dupflag,
2523 uint duplicate_options)
2524{
2525 const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
2526 const bool is_root_id = (duplicate_options & LIB_ID_DUPLICATE_IS_ROOT_ID) != 0;
2527 int copy_flags = LIB_ID_COPY_DEFAULT;
2528
2529 if (!is_subprocess) {
2531 }
2532 else {
2533 /* In case copying object is a sub-process of collection (or scene) copying, do not try to
2534 * re-assign RB objects to existing RBW collections. */
2536 }
2537 if (is_root_id) {
2538 /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
2539 * all expected linked data. */
2540 if (ID_IS_LINKED(ob)) {
2541 dupflag |= USER_DUP_LINKED_ID;
2542 }
2543 duplicate_options &= ~LIB_ID_DUPLICATE_IS_ROOT_ID;
2544 }
2545
2546 Material ***matarar;
2547
2548 Object *obn = (Object *)BKE_id_copy_for_duplicate(bmain, &ob->id, dupflag, copy_flags);
2549
2550 /* 0 == full linked. */
2551 if (dupflag == 0) {
2552 return obn;
2553 }
2554
2555 if (dupflag & USER_DUP_MAT) {
2556 for (int i = 0; i < obn->totcol; i++) {
2557 BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag, copy_flags);
2558 }
2559 }
2560 if (dupflag & USER_DUP_PSYS) {
2562 BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag, copy_flags);
2563 }
2564 }
2565
2566 ID *id_old = (ID *)obn->data;
2567 ID *id_new = nullptr;
2568 const bool need_to_duplicate_obdata = (id_old != nullptr) && (id_old->newid == nullptr);
2569
2570 switch (obn->type) {
2571 case OB_MESH:
2572 if (dupflag & USER_DUP_MESH) {
2573 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2574 }
2575 break;
2576 case OB_CURVES_LEGACY:
2577 if (dupflag & USER_DUP_CURVE) {
2578 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2579 }
2580 break;
2581 case OB_SURF:
2582 if (dupflag & USER_DUP_SURF) {
2583 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2584 }
2585 break;
2586 case OB_FONT:
2587 if (dupflag & USER_DUP_FONT) {
2588 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2589 }
2590 break;
2591 case OB_MBALL:
2592 if (dupflag & USER_DUP_MBALL) {
2593 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2594 }
2595 break;
2596 case OB_LAMP:
2597 if (dupflag & USER_DUP_LAMP) {
2598 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2599 }
2600 break;
2601 case OB_ARMATURE:
2602 if (dupflag & USER_DUP_ARM) {
2603 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2604 }
2605 break;
2606 case OB_LATTICE:
2607 if (dupflag & USER_DUP_LATTICE) {
2608 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2609 }
2610 break;
2611 case OB_CAMERA:
2612 if (dupflag & USER_DUP_CAMERA) {
2613 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2614 }
2615 break;
2616 case OB_LIGHTPROBE:
2617 if (dupflag & USER_DUP_LIGHTPROBE) {
2618 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2619 }
2620 break;
2621 case OB_SPEAKER:
2622 if (dupflag & USER_DUP_SPEAKER) {
2623 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2624 }
2625 break;
2626 case OB_GPENCIL_LEGACY:
2627 case OB_GREASE_PENCIL:
2628 if (dupflag & USER_DUP_GPENCIL) {
2629 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2630 }
2631 break;
2632 case OB_CURVES:
2633 if (dupflag & USER_DUP_CURVES) {
2634 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2635 }
2636 break;
2637 case OB_POINTCLOUD:
2638 if (dupflag & USER_DUP_POINTCLOUD) {
2639 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2640 }
2641 break;
2642 case OB_VOLUME:
2643 if (dupflag & USER_DUP_VOLUME) {
2644 id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
2645 }
2646 break;
2647 }
2648
2649 /* If obdata has been copied, we may also have to duplicate the materials assigned to it. */
2650 if (need_to_duplicate_obdata && !ELEM(id_new, nullptr, id_old)) {
2651 if (dupflag & USER_DUP_MAT) {
2652 matarar = BKE_object_material_array_p(obn);
2653 if (matarar) {
2654 for (int i = 0; i < obn->totcol; i++) {
2655 BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag, copy_flags);
2656 }
2657 }
2658 }
2659 }
2660
2661 if (!is_subprocess) {
2662 /* This code will follow into all ID links using an ID tagged with ID_TAG_NEW. */
2663 BKE_libblock_relink_to_newid(bmain, &obn->id, 0);
2664
2665#ifndef NDEBUG
2666 /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those flags. */
2667 ID *id_iter;
2668 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
2669 BLI_assert((id_iter->tag & ID_TAG_NEW) == 0);
2670 }
2672#endif
2673
2674 /* Cleanup. */
2676 }
2677
2678 if (obn->type == OB_ARMATURE) {
2680 if (obn->pose) {
2681 BKE_pose_tag_recalc(bmain, obn->pose);
2682 }
2683 // BKE_pose_rebuild(bmain, obn, obn->data, true);
2684 }
2685
2686 if (obn->data != nullptr) {
2688 }
2689
2690 return obn;
2691}
2692
2694{
2695 return (ob && ID_IS_LINKED(ob));
2696}
2697
2699{
2700 /* Linked objects with local obdata are forbidden! */
2701 BLI_assert(!ob || !ob->data || (ID_IS_LINKED(ob) ? ID_IS_LINKED(ob->data) : true));
2702 return (ob && ob->data && ID_IS_LINKED(ob->data));
2703}
2704
2705void BKE_object_obdata_size_init(Object *ob, const float size)
2706{
2707 /* apply radius as a scale to types that support it */
2708 switch (ob->type) {
2709 case OB_EMPTY: {
2710 ob->empty_drawsize *= size;
2711 break;
2712 }
2713 case OB_FONT: {
2714 Curve *cu = (Curve *)ob->data;
2715 cu->fsize *= size;
2716 break;
2717 }
2718 case OB_CAMERA: {
2719 Camera *cam = (Camera *)ob->data;
2720 cam->drawsize *= size;
2721 break;
2722 }
2723 case OB_LAMP: {
2724 Light *lamp = (Light *)ob->data;
2725 lamp->radius *= size;
2726 lamp->area_size *= size;
2727 lamp->area_sizey *= size;
2728 lamp->area_sizez *= size;
2729 break;
2730 }
2731 /* Only lattice (not mesh, curve, mball...),
2732 * because its got data when newly added */
2733 case OB_LATTICE: {
2734 Lattice *lt = (Lattice *)ob->data;
2735 float mat[4][4];
2736
2737 unit_m4(mat);
2738 scale_m4_fl(mat, size);
2739
2740 BKE_lattice_transform(lt, (float(*)[4])mat, false);
2741 break;
2742 }
2743 }
2744}
2745
2746/* -------------------------------------------------------------------- */
2750void BKE_object_scale_to_mat3(const Object *ob, float mat[3][3])
2751{
2752 float3 vec;
2753 mul_v3_v3v3(vec, ob->scale, ob->dscale);
2754 size_to_mat3(mat, vec);
2755}
2756
2757void BKE_object_rot_to_mat3(const Object *ob, float mat[3][3], bool use_drot)
2758{
2759 float rmat[3][3], dmat[3][3];
2760
2761 /* 'dmat' is the delta-rotation matrix, which will get (pre)multiplied
2762 * with the rotation matrix to yield the appropriate rotation
2763 */
2764
2765 /* Rotations may either be quaternions, eulers (with various rotation orders), or axis-angle. */
2766 if (ob->rotmode > 0) {
2767 /* Euler rotations
2768 * (will cause gimbal lock, but this can be alleviated a bit with rotation orders). */
2769 eulO_to_mat3(rmat, ob->rot, ob->rotmode);
2770 eulO_to_mat3(dmat, ob->drot, ob->rotmode);
2771 }
2772 else if (ob->rotmode == ROT_MODE_AXISANGLE) {
2773 /* axis-angle - not really that great for 3D-changing orientations */
2774 axis_angle_to_mat3(rmat, ob->rotAxis, ob->rotAngle);
2775 axis_angle_to_mat3(dmat, ob->drotAxis, ob->drotAngle);
2776 }
2777 else {
2778 /* Quaternions are normalized before use to eliminate scaling issues. */
2779 float tquat[4];
2780
2781 normalize_qt_qt(tquat, ob->quat);
2782 quat_to_mat3(rmat, tquat);
2783
2784 normalize_qt_qt(tquat, ob->dquat);
2785 quat_to_mat3(dmat, tquat);
2786 }
2787
2788 /* combine these rotations */
2789 if (use_drot) {
2790 mul_m3_m3m3(mat, dmat, rmat);
2791 }
2792 else {
2793 copy_m3_m3(mat, rmat);
2794 }
2795}
2796
2797void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)
2798{
2799 BLI_ASSERT_UNIT_M3(mat);
2800
2801 switch (ob->rotmode) {
2802 case ROT_MODE_QUAT: {
2803 float dquat[4];
2804 mat3_normalized_to_quat(ob->quat, mat);
2805 normalize_qt_qt(dquat, ob->dquat);
2806 invert_qt_normalized(dquat);
2807 mul_qt_qtqt(ob->quat, dquat, ob->quat);
2808 break;
2809 }
2810 case ROT_MODE_AXISANGLE: {
2811 float quat[4];
2812 float dquat[4];
2813
2814 /* Without `drot` we could apply 'mat' directly. */
2815 mat3_normalized_to_quat(quat, mat);
2816 axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
2817 invert_qt_normalized(dquat);
2818 mul_qt_qtqt(quat, dquat, quat);
2819 quat_to_axis_angle(ob->rotAxis, &ob->rotAngle, quat);
2820 break;
2821 }
2822 default: /* euler */
2823 {
2824 float quat[4];
2825 float dquat[4];
2826
2827 /* Without `drot` we could apply 'mat' directly. */
2828 mat3_normalized_to_quat(quat, mat);
2829 eulO_to_quat(dquat, ob->drot, ob->rotmode);
2830 invert_qt_normalized(dquat);
2831 mul_qt_qtqt(quat, dquat, quat);
2832 /* End `drot` correction. */
2833
2834 if (use_compat) {
2835 quat_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, quat);
2836 }
2837 else {
2838 quat_to_eulO(ob->rot, ob->rotmode, quat);
2839 }
2840 break;
2841 }
2842 }
2843}
2844
2846{
2847
2848#define TFMCPY(_v) (obtfm->_v = ob->_v)
2849#define TFMCPY3D(_v) copy_v3_v3(obtfm->_v, ob->_v)
2850#define TFMCPY4D(_v) copy_v4_v4(obtfm->_v, ob->_v)
2851
2852 TFMCPY3D(loc);
2853 TFMCPY3D(dloc);
2854 TFMCPY3D(scale);
2855 TFMCPY3D(dscale);
2856 TFMCPY3D(rot);
2857 TFMCPY3D(drot);
2858 TFMCPY4D(quat);
2859 TFMCPY4D(dquat);
2860 TFMCPY3D(rotAxis);
2861 TFMCPY3D(drotAxis);
2862 TFMCPY(rotAngle);
2863 TFMCPY(drotAngle);
2864
2865#undef TFMCPY
2866#undef TFMCPY3D
2867#undef TFMCPY4D
2868}
2869
2871 const ObjectTfmProtectedChannels *obtfm,
2872 const short protectflag)
2873{
2874 uint i;
2875
2876 for (i = 0; i < 3; i++) {
2877 if (protectflag & (OB_LOCK_LOCX << i)) {
2878 ob->loc[i] = obtfm->loc[i];
2879 ob->dloc[i] = obtfm->dloc[i];
2880 }
2881
2882 if (protectflag & (OB_LOCK_SCALEX << i)) {
2883 ob->scale[i] = obtfm->scale[i];
2884 ob->dscale[i] = obtfm->dscale[i];
2885 }
2886
2887 if (protectflag & (OB_LOCK_ROTX << i)) {
2888 ob->rot[i] = obtfm->rot[i];
2889 ob->drot[i] = obtfm->drot[i];
2890
2891 ob->quat[i + 1] = obtfm->quat[i + 1];
2892 ob->dquat[i + 1] = obtfm->dquat[i + 1];
2893
2894 ob->rotAxis[i] = obtfm->rotAxis[i];
2895 ob->drotAxis[i] = obtfm->drotAxis[i];
2896 }
2897 }
2898
2899 if ((protectflag & OB_LOCK_ROT4D) && (protectflag & OB_LOCK_ROTW)) {
2900 ob->quat[0] = obtfm->quat[0];
2901 ob->dquat[0] = obtfm->dquat[0];
2902
2903 ob->rotAngle = obtfm->rotAngle;
2904 ob->drotAngle = obtfm->drotAngle;
2905 }
2906}
2907
2908void BKE_object_tfm_copy(Object *object_dst, const Object *object_src)
2909{
2910#define TFMCPY(_v) (object_dst->_v = object_src->_v)
2911#define TFMCPY3D(_v) copy_v3_v3(object_dst->_v, object_src->_v)
2912#define TFMCPY4D(_v) copy_v4_v4(object_dst->_v, object_src->_v)
2913
2914 TFMCPY3D(loc);
2915 TFMCPY3D(dloc);
2916 TFMCPY3D(scale);
2917 TFMCPY3D(dscale);
2918 TFMCPY3D(rot);
2919 TFMCPY3D(drot);
2920 TFMCPY4D(quat);
2921 TFMCPY4D(dquat);
2922 TFMCPY3D(rotAxis);
2923 TFMCPY3D(drotAxis);
2924 TFMCPY(rotAngle);
2925 TFMCPY(drotAngle);
2926
2927#undef TFMCPY
2928#undef TFMCPY3D
2929#undef TFMCPY4D
2930}
2931
2932void BKE_object_to_mat3(const Object *ob, float r_mat[3][3]) /* no parent */
2933{
2934 float smat[3][3];
2935 float rmat[3][3];
2936
2937 /* Scale. */
2938 BKE_object_scale_to_mat3(ob, smat);
2939
2940 /* Rotation. */
2941 BKE_object_rot_to_mat3(ob, rmat, true);
2942 mul_m3_m3m3(r_mat, rmat, smat);
2943}
2944
2945void BKE_object_to_mat4(const Object *ob, float r_mat[4][4])
2946{
2947 float tmat[3][3];
2948
2949 BKE_object_to_mat3(ob, tmat);
2950
2951 copy_m4_m3(r_mat, tmat);
2952
2953 add_v3_v3v3(r_mat[3], ob->loc, ob->dloc);
2954}
2955
2956void BKE_object_matrix_local_get(Object *ob, float r_mat[4][4])
2957{
2958 if (ob->parent) {
2959 float par_imat[4][4];
2960
2961 BKE_object_get_parent_matrix(ob, ob->parent, par_imat);
2962 invert_m4(par_imat);
2963 mul_m4_m4m4(r_mat, par_imat, ob->object_to_world().ptr());
2964 }
2965 else {
2966 copy_m4_m4(r_mat, ob->object_to_world().ptr());
2967 }
2968}
2969
2973static bool ob_parcurve(const Object *ob, Object *par, float r_mat[4][4])
2974{
2975 Curve *cu = (Curve *)par->data;
2976 float vec[4], quat[4], radius, ctime;
2977
2978 /* NOTE: Curve cache is supposed to be evaluated here already, however there
2979 * are cases where we can not guarantee that. This includes, for example,
2980 * dependency cycles. We can't correct anything from here, since that would
2981 * cause threading conflicts.
2982 *
2983 * TODO(sergey): Some of the legit looking cases like #56619 need to be
2984 * looked into, and maybe curve cache (and other dependencies) are to be
2985 * evaluated prior to conversion. */
2986 if (par->runtime->curve_cache == nullptr) {
2987 return false;
2988 }
2989 if (par->runtime->curve_cache->anim_path_accum_length == nullptr) {
2990 return false;
2991 }
2992
2993 /* `ctime` is now a proper var setting of Curve which gets set by Animato like any other var
2994 * that's animated, but this will only work if it actually is animated.
2995 *
2996 * We divide the curve-time calculated in the previous step by the length of the path,
2997 * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range. */
2998 if (cu->pathlen) {
2999 ctime = cu->ctime / cu->pathlen;
3000 }
3001 else {
3002 ctime = cu->ctime;
3003 }
3004
3005 if (cu->flag & CU_PATH_CLAMP) {
3006 CLAMP(ctime, 0.0f, 1.0f);
3007 }
3008
3009 unit_m4(r_mat);
3010
3011 /* vec: 4 items! */
3013 par, ctime, vec, nullptr, (cu->flag & CU_FOLLOW) ? quat : nullptr, &radius, nullptr))
3014 {
3015 if (cu->flag & CU_FOLLOW) {
3017 quat, std::clamp<short>(ob->trackflag, 0, 5), std::clamp<short>(ob->upflag, 0, 2));
3018 normalize_qt(quat);
3019 quat_to_mat4(r_mat, quat);
3020 }
3021 if (cu->flag & CU_PATH_RADIUS) {
3022 float tmat[4][4], rmat[4][4];
3023 scale_m4_fl(tmat, radius);
3024 mul_m4_m4m4(rmat, tmat, r_mat);
3025 copy_m4_m4(r_mat, rmat);
3026 }
3027 copy_v3_v3(r_mat[3], vec);
3028 }
3029
3030 return true;
3031}
3032
3033static void ob_parbone(const Object *ob, const Object *par, float r_mat[4][4])
3034{
3035 float3 vec;
3036
3037 if (par->type != OB_ARMATURE) {
3038 unit_m4(r_mat);
3039 return;
3040 }
3041
3042 /* Make sure the bone is still valid */
3043 const bPoseChannel *pchan = BKE_pose_channel_find_name(par->pose, ob->parsubstr);
3044 if (!pchan || !pchan->bone) {
3045 CLOG_WARN(
3046 &LOG, "Parent Bone: '%s' for Object: '%s' doesn't exist", ob->parsubstr, ob->id.name + 2);
3047 unit_m4(r_mat);
3048 return;
3049 }
3050
3051 /* get bone transform */
3052 if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
3053 /* the new option uses the root - expected behavior, but differs from old... */
3054 /* XXX check on version patching? */
3055 copy_m4_m4(r_mat, pchan->chan_mat);
3056 }
3057 else {
3058 copy_m4_m4(r_mat, pchan->pose_mat);
3059
3060 /* but for backwards compatibility, the child has to move to the tail */
3061 copy_v3_v3(vec, r_mat[1]);
3062 mul_v3_fl(vec, pchan->bone->length);
3063 add_v3_v3(r_mat[3], vec);
3064 }
3065}
3066
3067static void give_parvert(const Object *par, int nr, float vec[3])
3068{
3069 zero_v3(vec);
3070
3071 if (par->type == OB_MESH) {
3072 const Mesh *mesh = (const Mesh *)par->data;
3073 const BMEditMesh *em = mesh->runtime->edit_mesh.get();
3074 const Mesh *mesh_eval = (em) ? BKE_object_get_editmesh_eval_final(par) :
3076
3077 if (mesh_eval) {
3078 const Span<float3> positions = mesh_eval->vert_positions();
3079 int count = 0;
3080 int numVerts = mesh_eval->verts_num;
3081
3082 if (em && mesh_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
3083 numVerts = em->bm->totvert;
3084 if (em->bm->elem_table_dirty & BM_VERT) {
3085#ifdef VPARENT_THREADING_HACK
3087 if (em->bm->elem_table_dirty & BM_VERT) {
3089 }
3091#else
3092 BLI_assert_msg(0, "Not safe for threading");
3094#endif
3095 }
3096 if (nr < numVerts) {
3097 if (mesh_eval && mesh_eval->runtime->edit_data &&
3098 !mesh_eval->runtime->edit_data->vert_positions.is_empty())
3099 {
3100 add_v3_v3(vec, mesh_eval->runtime->edit_data->vert_positions[nr]);
3101 }
3102 else {
3103 const BMVert *v = BM_vert_at_index(em->bm, nr);
3104 add_v3_v3(vec, v->co);
3105 }
3106 count++;
3107 }
3108 }
3109 else if (CustomData_has_layer(&mesh_eval->vert_data, CD_ORIGINDEX)) {
3110 const int *index = (const int *)CustomData_get_layer(&mesh_eval->vert_data, CD_ORIGINDEX);
3111 /* Get the average of all verts with (original index == nr). */
3112 for (int i = 0; i < numVerts; i++) {
3113 if (index[i] == nr) {
3114 add_v3_v3(vec, positions[i]);
3115 count++;
3116 }
3117 }
3118 }
3119 else {
3120 if (nr < numVerts) {
3121 add_v3_v3(vec, positions[nr]);
3122 count++;
3123 }
3124 }
3125
3126 if (count == 0) {
3127 /* keep as 0, 0, 0 */
3128 }
3129 else if (count > 0) {
3130 mul_v3_fl(vec, 1.0f / count);
3131 }
3132 else {
3133 /* use first index if its out of range */
3134 if (mesh_eval->verts_num) {
3135 copy_v3_v3(vec, positions[0]);
3136 }
3137 }
3138 }
3139 else {
3140 CLOG_ERROR(&LOG,
3141 "Evaluated mesh is needed to solve parenting, "
3142 "object position can be wrong now");
3143 }
3144 }
3145 else if (ELEM(par->type, OB_CURVES_LEGACY, OB_SURF)) {
3146 ListBase *nurb;
3147
3148 /* It is possible that a cycle in the dependency graph was resolved in a way that caused this
3149 * object to be evaluated before its dependencies. In this case the curve cache may be null. */
3150 if (par->runtime->curve_cache && par->runtime->curve_cache->deformed_nurbs.first != nullptr) {
3151 nurb = &par->runtime->curve_cache->deformed_nurbs;
3152 }
3153 else {
3154 Curve *cu = (Curve *)par->data;
3155 nurb = BKE_curve_nurbs_get(cu);
3156 }
3157
3158 BKE_nurbList_index_get_co(nurb, nr, vec);
3159 }
3160 else if (par->type == OB_LATTICE) {
3161 Lattice *latt = (Lattice *)par->data;
3162 DispList *dl = par->runtime->curve_cache ?
3163 BKE_displist_find(&par->runtime->curve_cache->disp, DL_VERTS) :
3164 nullptr;
3165 float(*co)[3] = dl ? (float(*)[3])dl->verts : nullptr;
3166 int tot;
3167
3168 if (latt->editlatt) {
3169 latt = latt->editlatt->latt;
3170 }
3171
3172 tot = latt->pntsu * latt->pntsv * latt->pntsw;
3173
3174 /* ensure dl is correct size */
3175 BLI_assert(dl == nullptr || dl->nr == tot);
3176
3177 if (nr < tot) {
3178 if (co) {
3179 copy_v3_v3(vec, co[nr]);
3180 }
3181 else {
3182 copy_v3_v3(vec, latt->def[nr].vec);
3183 }
3184 }
3185 }
3186}
3187
3188static void ob_parvert3(const Object *ob, const Object *par, float r_mat[4][4])
3189{
3190 /* in local ob space */
3191 if (OB_TYPE_SUPPORT_PARVERT(par->type)) {
3192 float cmat[3][3], v1[3], v2[3], v3[3], q[4];
3193
3194 give_parvert(par, ob->par1, v1);
3195 give_parvert(par, ob->par2, v2);
3196 give_parvert(par, ob->par3, v3);
3197
3198 tri_to_quat(q, v1, v2, v3);
3199 quat_to_mat3(cmat, q);
3200 copy_m4_m3(r_mat, cmat);
3201
3202 mid_v3_v3v3v3(r_mat[3], v1, v2, v3);
3203 }
3204 else {
3205 unit_m4(r_mat);
3206 }
3207}
3208
3209void BKE_object_get_parent_matrix(const Object *ob, Object *par, float r_parentmat[4][4])
3210{
3211 float tmat[4][4];
3212 float vec[3];
3213
3214 switch (ob->partype & PARTYPE) {
3215 case PAROBJECT: {
3216 bool ok = false;
3217 if (par->type == OB_CURVES_LEGACY) {
3218 if ((((Curve *)par->data)->flag & CU_PATH) && ob_parcurve(ob, par, tmat)) {
3219 ok = true;
3220 }
3221 }
3222
3223 if (ok) {
3224 mul_m4_m4m4(r_parentmat, par->object_to_world().ptr(), tmat);
3225 }
3226 else {
3227 copy_m4_m4(r_parentmat, par->object_to_world().ptr());
3228 }
3229
3230 break;
3231 }
3232 case PARBONE:
3233 ob_parbone(ob, par, tmat);
3234 mul_m4_m4m4(r_parentmat, par->object_to_world().ptr(), tmat);
3235 break;
3236
3237 case PARVERT1:
3238 unit_m4(r_parentmat);
3239 give_parvert(par, ob->par1, vec);
3240 mul_v3_m4v3(r_parentmat[3], par->object_to_world().ptr(), vec);
3241 break;
3242 case PARVERT3:
3243 ob_parvert3(ob, par, tmat);
3244
3245 mul_m4_m4m4(r_parentmat, par->object_to_world().ptr(), tmat);
3246 break;
3247
3248 case PARSKEL:
3249 copy_m4_m4(r_parentmat, par->object_to_world().ptr());
3250 break;
3251 }
3252}
3253
3256/* -------------------------------------------------------------------- */
3264static void solve_parenting(const Object *ob,
3265 Object *par,
3266 const bool set_origin,
3267 float r_obmat[4][4],
3268 float r_originmat[3][3])
3269{
3270 float totmat[4][4];
3271 float tmat[4][4];
3272 float locmat[4][4];
3273
3274 BKE_object_to_mat4(ob, locmat);
3275
3276 BKE_object_get_parent_matrix(ob, par, totmat);
3277
3278 /* total */
3279 mul_m4_m4m4(tmat, totmat, ob->parentinv);
3280 mul_m4_m4m4(r_obmat, tmat, locmat);
3281
3282 if (r_originmat) {
3283 /* Usable `r_originmat`. */
3284 copy_m3_m4(r_originmat, tmat);
3285 }
3286
3287 /* origin, for help line */
3288 if (set_origin) {
3289 if ((ob->partype & PARTYPE) == PARSKEL) {
3290 copy_v3_v3(ob->runtime->parent_display_origin, par->object_to_world().location());
3291 }
3292 else {
3293 copy_v3_v3(ob->runtime->parent_display_origin, totmat[3]);
3294 }
3295 }
3296}
3297
3298static void object_where_is_calc_ex(Depsgraph *depsgraph,
3299 Scene *scene,
3300 Object *ob,
3301 float ctime,
3302 RigidBodyWorld *rbw,
3303 float r_originmat[3][3])
3304{
3305 if (ob->parent) {
3306 Object *par = ob->parent;
3307
3308 /* calculate parent matrix */
3309 solve_parenting(ob, par, true, ob->runtime->object_to_world.ptr(), r_originmat);
3310 }
3311 else {
3312 BKE_object_to_mat4(ob, ob->runtime->object_to_world.ptr());
3313 }
3314
3315 /* try to fall back to the scene rigid body world if none given */
3316 rbw = rbw ? rbw : scene->rigidbody_world;
3317 /* read values pushed into RBO from sim/cache... */
3318 BKE_rigidbody_sync_transforms(rbw, ob, ctime);
3319
3320 /* solve constraints */
3321 if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
3322 bConstraintOb *cob;
3324 BKE_constraints_solve(depsgraph, &ob->constraints, cob, ctime);
3326 }
3327
3328 /* set negative scale flag in object */
3329 if (is_negative_m4(ob->object_to_world().ptr())) {
3330 ob->transflag |= OB_NEG_SCALE;
3331 }
3332 else {
3333 ob->transflag &= ~OB_NEG_SCALE;
3334 }
3335}
3336
3337void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
3338{
3339 /* Execute drivers and animation. */
3340 const bool flush_to_original = DEG_is_active(depsgraph);
3342 ctime);
3344 &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ALL, flush_to_original);
3345 object_where_is_calc_ex(depsgraph, scene, ob, ctime, nullptr, nullptr);
3346}
3347
3348void BKE_object_where_is_calc_mat4(const Object *ob, float r_obmat[4][4])
3349{
3350 if (ob->parent) {
3351 Object *par = ob->parent;
3352 solve_parenting(ob, par, false, r_obmat, nullptr);
3353 }
3354 else {
3355 BKE_object_to_mat4(ob, r_obmat);
3356 }
3357}
3358
3360 Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
3361{
3362 float ctime = DEG_get_ctime(depsgraph);
3363 object_where_is_calc_ex(depsgraph, scene, ob, ctime, rbw, r_originmat);
3364}
3365void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
3366{
3367 float ctime = DEG_get_ctime(depsgraph);
3368 object_where_is_calc_ex(depsgraph, scene, ob, ctime, nullptr, nullptr);
3369}
3370
3372{
3373 blender::bke::ObjectRuntime workob_runtime;
3374 Object workob;
3375 BKE_object_workob_clear(&workob);
3376 workob.runtime = &workob_runtime;
3377
3378 unit_m4(workob.runtime->object_to_world.ptr());
3379 unit_m4(workob.parentinv);
3380 unit_m4(workob.constinv);
3381
3382 /* Since this is used while calculating parenting,
3383 * at this moment ob_eval->parent is still nullptr. */
3385
3386 workob.trackflag = ob->trackflag;
3387 workob.upflag = ob->upflag;
3388
3389 workob.partype = ob->partype;
3390 workob.par1 = ob->par1;
3391 workob.par2 = ob->par2;
3392 workob.par3 = ob->par3;
3393
3394 /* The effects of constraints should NOT be included in the parent-inverse matrix. Constraints
3395 * are supposed to be applied after the object's local loc/rot/scale. If the (inverted) effect of
3396 * constraints would be included in the parent inverse matrix, these would be applied before the
3397 * object's local loc/rot/scale instead of after. For example, a "Copy Rotation" constraint would
3398 * rotate the object's local translation as well. See #82156. */
3399
3400 STRNCPY(workob.parsubstr, ob->parsubstr);
3401
3402 BKE_object_where_is_calc(depsgraph, scene, &workob);
3403
3404 return workob.object_to_world();
3405}
3406
3408 const float mat[4][4],
3409 Object *parent,
3410 const float parentinv[4][4],
3411 const bool use_compat)
3412{
3413 /* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
3414
3415 float rot[3][3];
3416
3417 if (parent != nullptr) {
3418 float rmat[4][4], diff_mat[4][4], imat[4][4], parent_mat[4][4];
3419
3420 BKE_object_get_parent_matrix(ob, parent, parent_mat);
3421
3422 mul_m4_m4m4(diff_mat, parent_mat, parentinv);
3423 invert_m4_m4(imat, diff_mat);
3424 mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
3425
3426 /* same as below, use rmat rather than mat */
3427 mat4_to_loc_rot_size(ob->loc, rot, ob->scale, rmat);
3428 }
3429 else {
3430 mat4_to_loc_rot_size(ob->loc, rot, ob->scale, mat);
3431 }
3432
3433 BKE_object_mat3_to_rot(ob, rot, use_compat);
3434
3435 sub_v3_v3(ob->loc, ob->dloc);
3436
3437 if (ob->dscale[0] != 0.0f) {
3438 ob->scale[0] /= ob->dscale[0];
3439 }
3440 if (ob->dscale[1] != 0.0f) {
3441 ob->scale[1] /= ob->dscale[1];
3442 }
3443 if (ob->dscale[2] != 0.0f) {
3444 ob->scale[2] /= ob->dscale[2];
3445 }
3446
3447 /* BKE_object_mat3_to_rot handles delta rotations */
3448}
3449
3451 const float mat[4][4],
3452 const bool use_compat,
3453 const bool use_parent)
3454{
3455 BKE_object_apply_mat4_ex(ob, mat, use_parent ? ob->parent : nullptr, ob->parentinv, use_compat);
3456}
3457
3459{
3460 /*
3461 * Use parent's world transform as the child's origin.
3462 *
3463 * Let:
3464 * `local = identity`
3465 * `world = orthonormalized(parent)`
3466 *
3467 * Then:
3468 * `world = parent @ parentinv @ local`
3469 * `inv(parent) @ world = parentinv`
3470 * `parentinv = inv(parent) @ world`
3471 *
3472 * NOTE: If `ob->object_to_world().ptr()` has shear, then this `parentinv` is insufficient
3473 * because `parent @ parentinv => shearless result`
3474 *
3475 * Thus, local will have shear which cannot be decomposed into TRS:
3476 * `local = inv(parent @ parentinv) @ world`
3477 *
3478 * This is currently not supported for consistency in the handling of shear during the other
3479 * parenting ops: Parent (Keep Transform), Clear [Parent] and Keep Transform.
3480 */
3481 float par_locrot[4][4], par_imat[4][4];
3482 BKE_object_get_parent_matrix(ob, ob->parent, par_locrot);
3483 invert_m4_m4(par_imat, par_locrot);
3484
3485 orthogonalize_m4_stable(par_locrot, 0, true);
3486
3487 mul_m4_m4m4(ob->parentinv, par_imat, par_locrot);
3488
3489 /* Now, preserve `world` given the new `parentinv`.
3490 *
3491 * `world = parent @ parentinv @ local`
3492 * `inv(parent) @ world = parentinv @ local`
3493 * `inv(parentinv) @ inv(parent) @ world = local`
3494 *
3495 * `local = inv(parentinv) @ inv(parent) @ world`
3496 */
3497 float ob_local[4][4];
3498 copy_m4_m4(ob_local, ob->parentinv);
3499 invert_m4(ob_local);
3500 mul_m4_m4_post(ob_local, par_imat);
3501 mul_m4_m4_post(ob_local, ob->object_to_world().ptr());
3502
3503 /* Send use_compat=False so the rotation is predictable. */
3504 BKE_object_apply_mat4(ob, ob_local, false, false);
3505}
3506
3509/* -------------------------------------------------------------------- */
3513void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3])
3514{
3515 bb->vec[0][0] = bb->vec[1][0] = bb->vec[2][0] = bb->vec[3][0] = min[0];
3516 bb->vec[4][0] = bb->vec[5][0] = bb->vec[6][0] = bb->vec[7][0] = max[0];
3517
3518 bb->vec[0][1] = bb->vec[1][1] = bb->vec[4][1] = bb->vec[5][1] = min[1];
3519 bb->vec[2][1] = bb->vec[3][1] = bb->vec[6][1] = bb->vec[7][1] = max[1];
3520
3521 bb->vec[0][2] = bb->vec[3][2] = bb->vec[4][2] = bb->vec[7][2] = min[2];
3522 bb->vec[1][2] = bb->vec[2][2] = bb->vec[5][2] = bb->vec[6][2] = max[2];
3523}
3524
3526 const float obmat[4][4],
3527 float r_min[3],
3528 float r_max[3])
3529{
3530 int i;
3531 for (i = 0; i < 8; i++) {
3532 float vec[3];
3533 mul_v3_m4v3(vec, obmat, bb->vec[i]);
3534 minmax_v3v3_v3(r_min, r_max, vec);
3535 }
3536}
3537
3538std::optional<blender::Bounds<blender::float3>> BKE_object_boundbox_get(const Object *ob)
3539{
3540 switch (ob->type) {
3541 case OB_MESH:
3542 return static_cast<const Mesh *>(ob->data)->bounds_min_max();
3543 case OB_CURVES_LEGACY:
3544 case OB_SURF:
3545 case OB_FONT:
3546 return BKE_curve_minmax(static_cast<const Curve *>(ob->data), true);
3547 case OB_MBALL:
3549 case OB_LATTICE:
3550 return BKE_lattice_minmax(static_cast<const Lattice *>(ob->data));
3551 case OB_ARMATURE:
3552 return BKE_armature_min_max(ob);
3553 case OB_GPENCIL_LEGACY:
3554 return BKE_gpencil_data_minmax(static_cast<const bGPdata *>(ob->data));
3555 case OB_CURVES:
3556 return static_cast<const Curves *>(ob->data)->geometry.wrap().bounds_min_max();
3557 case OB_POINTCLOUD:
3558 return static_cast<const PointCloud *>(ob->data)->bounds_min_max();
3559 case OB_VOLUME:
3560 return BKE_volume_min_max(static_cast<const Volume *>(ob->data));
3561 case OB_GREASE_PENCIL:
3562 return static_cast<const GreasePencil *>(ob->data)->bounds_min_max_eval();
3563 }
3564 return std::nullopt;
3565}
3566
3567std::optional<Bounds<float3>> BKE_object_boundbox_eval_cached_get(const Object *ob)
3568{
3569 if (ob->runtime->bounds_eval) {
3570 return *ob->runtime->bounds_eval;
3571 }
3572 return BKE_object_boundbox_get(ob);
3573}
3574
3575std::optional<Bounds<float3>> BKE_object_evaluated_geometry_bounds(const Object *ob)
3576{
3577 if (const blender::bke::GeometrySet *geometry = ob->runtime->geometry_set_eval) {
3578 return geometry->compute_boundbox_without_instances();
3579 }
3580 if (const CurveCache *curve_cache = ob->runtime->curve_cache) {
3581 float3 min(std::numeric_limits<float>::max());
3582 float3 max(std::numeric_limits<float>::lowest());
3583 BKE_displist_minmax(&curve_cache->disp, min, max);
3584 return Bounds<float3>{min, max};
3585 }
3586 return std::nullopt;
3587}
3588
3591/* -------------------------------------------------------------------- */
3597static float3 boundbox_to_dimensions(const Object *ob, const std::optional<Bounds<float3>> bounds)
3598{
3599 using namespace blender;
3600 if (!bounds) {
3601 return float3(0);
3602 }
3603 const float3 scale = math::to_scale(ob->object_to_world());
3604 return scale * (bounds->max - bounds->min);
3605}
3606
3607void BKE_object_dimensions_get(Object *ob, float r_vec[3])
3608{
3610}
3611
3616
3618 const float value[3],
3619 int axis_mask,
3620 const float ob_scale_orig[3],
3621 const float ob_obmat_orig[4][4])
3622{
3623 if (const std::optional<Bounds<float3>> bounds = BKE_object_boundbox_eval_cached_get(ob)) {
3624 float3 len = bounds->max - bounds->min;
3625
3626 for (int i = 0; i < 3; i++) {
3627 if (((1 << i) & axis_mask) == 0) {
3628
3629 if (ob_scale_orig != nullptr) {
3630 const float scale_delta = len_v3(ob_obmat_orig[i]) / ob_scale_orig[i];
3631 if (isfinite(scale_delta)) {
3632 len[i] *= scale_delta;
3633 }
3634 }
3635
3636 const float scale = copysignf(value[i] / len[i], ob->scale[i]);
3637 if (isfinite(scale)) {
3638 ob->scale[i] = scale;
3639 }
3640 }
3641 }
3642 }
3643}
3644
3645void BKE_object_dimensions_set(Object *ob, const float value[3], int axis_mask)
3646{
3647 BKE_object_dimensions_set_ex(ob, value, axis_mask, nullptr, nullptr);
3648}
3649
3650void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3])
3651{
3652 using namespace blender;
3653 if (const std::optional<Bounds<float3>> bounds = BKE_object_boundbox_get(ob)) {
3654 minmax_v3v3_v3(r_min, r_max, math::transform_point(ob->object_to_world(), bounds->min));
3655 minmax_v3v3_v3(r_min, r_max, math::transform_point(ob->object_to_world(), bounds->max));
3656 return;
3657 }
3658 float3 size = ob->scale;
3659
3660 copy_v3_v3(size, ob->scale);
3661 if (ob->type == OB_EMPTY) {
3662 size *= ob->empty_drawsize;
3663 }
3664
3665 minmax_v3v3_v3(r_min, r_max, ob->object_to_world().location());
3666
3667 float3 vec;
3668 copy_v3_v3(vec, ob->object_to_world().location());
3669 add_v3_v3(vec, size);
3670 minmax_v3v3_v3(r_min, r_max, vec);
3671
3672 copy_v3_v3(vec, ob->object_to_world().location());
3673 sub_v3_v3(vec, size);
3674 minmax_v3v3_v3(r_min, r_max, vec);
3675}
3676
3677void BKE_object_empty_draw_type_set(Object *ob, const int value)
3678{
3679 ob->empty_drawtype = value;
3680
3681 if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) {
3682 if (!ob->iuser) {
3683 ob->iuser = MEM_cnew<ImageUser>("image user");
3684 ob->iuser->flag |= IMA_ANIM_ALWAYS;
3685 ob->iuser->frames = 100;
3686 ob->iuser->sfra = 1;
3687 }
3688 }
3689 else {
3690 MEM_SAFE_FREE(ob->iuser);
3691 }
3692}
3693
3695{
3696 const char visibility_flag = ob->empty_image_visibility_flag;
3697 if (rv3d->is_persp) {
3698 return (visibility_flag & OB_EMPTY_IMAGE_HIDE_PERSPECTIVE) == 0;
3699 }
3700
3701 return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0;
3702}
3703
3705{
3706 /* Caller is expected to check this. */
3708
3709 const char visibility_flag = ob->empty_image_visibility_flag;
3710
3711 if ((visibility_flag & (OB_EMPTY_IMAGE_HIDE_BACK | OB_EMPTY_IMAGE_HIDE_FRONT)) != 0) {
3712 float eps, dot;
3713 if (rv3d->is_persp) {
3714 /* NOTE: we could normalize the 'view_dir' then use 'eps'
3715 * however the issue with empty objects being visible when viewed from the side
3716 * is only noticeable in orthographic views. */
3717 float3 view_dir;
3718 sub_v3_v3v3(view_dir, rv3d->viewinv[3], ob->object_to_world().location());
3719 dot = dot_v3v3(ob->object_to_world().ptr()[2], view_dir);
3720 eps = 0.0f;
3721 }
3722 else {
3723 dot = dot_v3v3(ob->object_to_world().ptr()[2], rv3d->viewinv[2]);
3724 eps = 1e-5f;
3725 }
3726 if (visibility_flag & OB_EMPTY_IMAGE_HIDE_BACK) {
3727 if (dot < eps) {
3728 return false;
3729 }
3730 }
3731 if (visibility_flag & OB_EMPTY_IMAGE_HIDE_FRONT) {
3732 if (dot > -eps) {
3733 return false;
3734 }
3735 }
3736 }
3737
3738 if (visibility_flag & OB_EMPTY_IMAGE_HIDE_NON_AXIS_ALIGNED) {
3739 float3 proj, ob_z_axis;
3740 normalize_v3_v3(ob_z_axis, ob->object_to_world().ptr()[2]);
3741 project_plane_v3_v3v3(proj, ob_z_axis, rv3d->viewinv[2]);
3742 const float proj_length_sq = len_squared_v3(proj);
3743 if (proj_length_sq > 1e-5f) {
3744 return false;
3745 }
3746 }
3747
3748 return true;
3749}
3750
3751bool BKE_object_minmax_empty_drawtype(const Object *ob, float r_min[3], float r_max[3])
3752{
3753 BLI_assert(ob->type == OB_EMPTY);
3754 float3 min(0), max(0);
3755
3756 bool ok = false;
3757 const float radius = ob->empty_drawsize;
3758
3759 switch (ob->empty_drawtype) {
3760 case OB_ARROWS: {
3761 max = float3(radius);
3762 ok = true;
3763 break;
3764 }
3765 case OB_PLAINAXES:
3766 case OB_CUBE:
3767 case OB_EMPTY_SPHERE: {
3768 min = float3(-radius);
3769 max = float3(radius);
3770 ok = true;
3771 break;
3772 }
3773 case OB_CIRCLE: {
3774 max[0] = max[2] = radius;
3775 min[0] = min[2] = -radius;
3776 ok = true;
3777 break;
3778 }
3779 case OB_SINGLE_ARROW: {
3780 max[2] = radius;
3781 ok = true;
3782 break;
3783 }
3784 case OB_EMPTY_CONE: {
3785 min = float3(-radius, 0.0f, -radius);
3786 max = float3(radius, radius * 2.0f, radius);
3787 ok = true;
3788 break;
3789 }
3790 case OB_EMPTY_IMAGE: {
3791 const float *ofs = ob->ima_ofs;
3792 /* NOTE: this is the best approximation that can be calculated without loading the image.
3793 */
3794 min[0] = ofs[0] * radius;
3795 min[1] = ofs[1] * radius;
3796 max[0] = radius + (ofs[0] * radius);
3797 max[1] = radius + (ofs[1] * radius);
3798 /* Since the image aspect can shrink the bounds towards the object origin,
3799 * adjust the min/max to account for that. */
3800 for (int i = 0; i < 2; i++) {
3801 CLAMP_MAX(min[i], 0.0f);
3802 CLAMP_MIN(max[i], 0.0f);
3803 }
3804 ok = true;
3805 break;
3806 }
3807 }
3808
3809 if (ok) {
3810 copy_v3_v3(r_min, min);
3811 copy_v3_v3(r_max, max);
3812 }
3813 return ok;
3814}
3815
3817 Scene *scene,
3818 Object *ob,
3819 float r_min[3],
3820 float r_max[3],
3821 const bool use_hidden)
3822{
3823 using namespace blender;
3824 bool ok = false;
3825 if ((ob->transflag & OB_DUPLI) == 0 && ob->runtime->geometry_set_eval == nullptr) {
3826 return ok;
3827 }
3828
3829 ListBase *lb = object_duplilist(depsgraph, scene, ob);
3830 LISTBASE_FOREACH (DupliObject *, dob, lb) {
3831 if (((use_hidden == false) && (dob->no_draw != 0)) || dob->ob_data == nullptr) {
3832 /* pass */
3833 }
3834 else {
3835 Object temp_ob = blender::dna::shallow_copy(*dob->ob);
3836 blender::bke::ObjectRuntime runtime = *dob->ob->runtime;
3837 temp_ob.runtime = &runtime;
3838
3839 /* Do not modify the original bounding-box. */
3840 temp_ob.runtime->bounds_eval.reset();
3841 BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data);
3842 if (const std::optional<Bounds<float3>> bounds = BKE_object_boundbox_get(&temp_ob)) {
3843 BoundBox bb;
3845 int i;
3846 for (i = 0; i < 8; i++) {
3847 float3 vec;
3848 mul_v3_m4v3(vec, dob->mat, bb.vec[i]);
3849 minmax_v3v3_v3(r_min, r_max, vec);
3850 }
3851
3852 ok = true;
3853 }
3854 }
3855 }
3856 free_object_duplilist(lb); /* does restore */
3857
3858 return ok;
3859}
3860
3862 const float obmat[4][4],
3863 void (*func_cb)(const float[3], void *),
3864 void *user_data)
3865{
3866 /* TODO: point-cloud and curves object support. */
3867 const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
3868 float3 co;
3869
3870 if (mesh_eval != nullptr) {
3871 const Span<float3> positions = BKE_mesh_wrapper_vert_coords(mesh_eval);
3872 for (const int i : positions.index_range()) {
3873 mul_v3_m4v3(co, obmat, positions[i]);
3874 func_cb(co, user_data);
3875 }
3876 }
3877 else if (ob->runtime->curve_cache && ob->runtime->curve_cache->disp.first) {
3878 LISTBASE_FOREACH (DispList *, dl, &ob->runtime->curve_cache->disp) {
3879 const float *v3 = dl->verts;
3880 int totvert = dl->nr;
3881 int i;
3882
3883 for (i = 0; i < totvert; i++, v3 += 3) {
3884 mul_v3_m4v3(co, obmat, v3);
3885 func_cb(co, user_data);
3886 }
3887 }
3888 }
3889}
3890
3892 void (*func_cb)(const float[3], void *),
3893 void *user_data)
3894{
3895 DEGObjectIterSettings deg_iter_settings{};
3896 deg_iter_settings.depsgraph = depsgraph;
3899 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
3900 if ((ob->base_flag & BASE_SELECTED) != 0) {
3901 BKE_object_foreach_display_point(ob, ob->object_to_world().ptr(), func_cb, user_data);
3902 }
3903 }
3905}
3906
3909/* -------------------------------------------------------------------- */
3917 float loc[3], dloc[3];
3918 float scale[3], dscale[3];
3919 float rot[3], drot[3];
3920 float quat[4], dquat[4];
3921 float rotAxis[3], drotAxis[3];
3923 float obmat[4][4];
3924 float parentinv[4][4];
3925 float constinv[4][4];
3926 float imat[4][4];
3927};
3928
3930{
3931 ObTfmBack *obtfm = (ObTfmBack *)MEM_mallocN(sizeof(ObTfmBack), "ObTfmBack");
3932 copy_v3_v3(obtfm->loc, ob->loc);
3933 copy_v3_v3(obtfm->dloc, ob->dloc);
3934 copy_v3_v3(obtfm->scale, ob->scale);
3935 copy_v3_v3(obtfm->dscale, ob->dscale);
3936 copy_v3_v3(obtfm->rot, ob->rot);
3937 copy_v3_v3(obtfm->drot, ob->drot);
3938 copy_qt_qt(obtfm->quat, ob->quat);
3939 copy_qt_qt(obtfm->dquat, ob->dquat);
3940 copy_v3_v3(obtfm->rotAxis, ob->rotAxis);
3941 copy_v3_v3(obtfm->drotAxis, ob->drotAxis);
3942 obtfm->rotAngle = ob->rotAngle;
3943 obtfm->drotAngle = ob->drotAngle;
3944 copy_m4_m4(obtfm->obmat, ob->object_to_world().ptr());
3945 copy_m4_m4(obtfm->parentinv, ob->parentinv);
3946 copy_m4_m4(obtfm->constinv, ob->constinv);
3947 copy_m4_m4(obtfm->imat, ob->world_to_object().ptr());
3948
3949 return (void *)obtfm;
3950}
3951
3952void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
3953{
3954 ObTfmBack *obtfm = (ObTfmBack *)obtfm_pt;
3955 copy_v3_v3(ob->loc, obtfm->loc);
3956 copy_v3_v3(ob->dloc, obtfm->dloc);
3957 copy_v3_v3(ob->scale, obtfm->scale);
3958 copy_v3_v3(ob->dscale, obtfm->dscale);
3959 copy_v3_v3(ob->rot, obtfm->rot);
3960 copy_v3_v3(ob->drot, obtfm->drot);
3961 copy_qt_qt(ob->quat, obtfm->quat);
3962 copy_qt_qt(ob->dquat, obtfm->dquat);
3963 copy_v3_v3(ob->rotAxis, obtfm->rotAxis);
3964 copy_v3_v3(ob->drotAxis, obtfm->drotAxis);
3965 ob->rotAngle = obtfm->rotAngle;
3966 ob->drotAngle = obtfm->drotAngle;
3967 copy_m4_m4(ob->runtime->object_to_world.ptr(), obtfm->obmat);
3968 copy_m4_m4(ob->parentinv, obtfm->parentinv);
3969 copy_m4_m4(ob->constinv, obtfm->constinv);
3970 copy_m4_m4(ob->runtime->world_to_object.ptr(), obtfm->imat);
3971}
3972
3975/* -------------------------------------------------------------------- */
3980 Scene *scene,
3981 Object *ob,
3982 RigidBodyWorld *rbw)
3983{
3984 const ID *object_data = (ID *)ob->data;
3985 const bool recalc_object = (ob->id.recalc & ID_RECALC_ALL) != 0;
3986 const bool recalc_data = (object_data != nullptr) ?
3987 ((object_data->recalc & ID_RECALC_ALL) != 0) :
3988 false;
3989 if (!recalc_object && !recalc_data) {
3990 return;
3991 }
3992 /* Speed optimization for animation lookups. */
3993 if (ob->pose != nullptr) {
3997 }
3998 }
3999 if (recalc_data) {
4000 if (ob->type == OB_ARMATURE) {
4001 /* this happens for reading old files and to match library armatures
4002 * with poses we do it ahead of BKE_object_where_is_calc to ensure animation
4003 * is evaluated on the rebuilt pose, otherwise we get incorrect poses
4004 * on file load */
4005 if (ob->pose == nullptr || (ob->pose->flag & POSE_RECALC)) {
4006 /* No need to pass `bmain` here, we assume we do not need to rebuild DEG from here. */
4007 BKE_pose_rebuild(nullptr, ob, (bArmature *)ob->data, true);
4008 }
4009 }
4010 }
4011 /* XXX new animsys warning: depsgraph tag ID_RECALC_GEOMETRY should not skip drivers,
4012 * which is only in BKE_object_where_is_calc now */
4013 /* XXX: should this case be ID_RECALC_TRANSFORM instead? */
4014 if (recalc_object || recalc_data) {
4015 if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) {
4016 printf("recalcob %s\n", ob->id.name + 2);
4017 }
4018 BKE_object_where_is_calc_ex(depsgraph, scene, rbw, ob, nullptr);
4019 }
4020
4021 if (recalc_data) {
4023 }
4024}
4025
4026void BKE_object_handle_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
4027{
4028 BKE_object_handle_update_ex(depsgraph, scene, ob, nullptr);
4029}
4030
4032{
4033 BLI_assert((ob->sculpt == nullptr) && (ob->mode & OB_MODE_ALL_SCULPT));
4034 ob->sculpt = MEM_new<SculptSession>(__func__);
4035 ob->sculpt->mode_type = (eObjectMode)ob->mode;
4036}
4037
4039 char **r_texspace_flag,
4040 float **r_texspace_location,
4041 float **r_texspace_size)
4042{
4043 if (ob->data == nullptr) {
4044 return false;
4045 }
4046
4047 switch (GS(((ID *)ob->data)->name)) {
4048 case ID_ME: {
4050 (Mesh *)ob->data, r_texspace_flag, r_texspace_location, r_texspace_size);
4051 break;
4052 }
4053 case ID_CU_LEGACY: {
4054 Curve *cu = (Curve *)ob->data;
4056 if (r_texspace_flag) {
4057 *r_texspace_flag = &cu->texspace_flag;
4058 }
4059 if (r_texspace_location) {
4060 *r_texspace_location = cu->texspace_location;
4061 }
4062 if (r_texspace_size) {
4063 *r_texspace_size = cu->texspace_size;
4064 }
4065 break;
4066 }
4067 case ID_MB: {
4068 MetaBall *mb = (MetaBall *)ob->data;
4069 if (r_texspace_flag) {
4070 *r_texspace_flag = &mb->texspace_flag;
4071 }
4072 if (r_texspace_location) {
4073 *r_texspace_location = mb->texspace_location;
4074 }
4075 if (r_texspace_size) {
4076 *r_texspace_size = mb->texspace_size;
4077 }
4078 break;
4079 }
4080 default:
4081 return false;
4082 }
4083 return true;
4084}
4085
4087{
4088 /* First attempt to retrieve the evaluated mesh from the evaluated geometry set. Most
4089 * object types either store it there or add a reference to it if it's owned elsewhere. */
4090 blender::bke::GeometrySet *geometry_set_eval = object->runtime->geometry_set_eval;
4091 if (geometry_set_eval) {
4092 /* Some areas expect to be able to modify the evaluated mesh in limited ways. Theoretically
4093 * this should be avoided, or at least protected with a lock, so a const mesh could be
4094 * returned from this function. We use a const_cast instead of #get_mesh_for_write, because
4095 * that might result in a copy of the mesh when it is shared. */
4096 Mesh *mesh = const_cast<Mesh *>(geometry_set_eval->get_mesh());
4097 if (mesh) {
4098 return mesh;
4099 }
4100 }
4101
4102 /* Some object types do not yet add the evaluated mesh to an evaluated geometry set, if they do
4103 * not support evaluating to multiple data types. Eventually this should be removed, when all
4104 * object types use #geometry_set_eval. */
4105 ID *data_eval = object->runtime->data_eval;
4106 if (data_eval && GS(data_eval->name) == ID_ME) {
4107 return reinterpret_cast<Mesh *>(data_eval);
4108 }
4109
4110 return nullptr;
4111}
4112
4114{
4115 if (!DEG_object_geometry_is_evaluated(*object)) {
4116 return nullptr;
4117 }
4119}
4120
4122{
4124 if (!mesh) {
4125 return nullptr;
4126 }
4127
4128 if (object_eval->data && GS(((const ID *)object_eval->data)->name) == ID_ME) {
4130 }
4131
4132 return mesh;
4133}
4134
4136{
4137 if (!DEG_object_geometry_is_evaluated(*object_eval)) {
4138 return nullptr;
4139 }
4140 return BKE_object_get_evaluated_mesh_unchecked(object_eval);
4141}
4142
4144{
4145 if (object->type == OB_MESH && object->runtime->data_orig != nullptr) {
4146 BLI_assert(object->id.tag & ID_TAG_COPIED_ON_EVAL);
4147 BLI_assert(object->id.orig_id != nullptr);
4148 BLI_assert(object->runtime->data_orig->orig_id == ((Object *)object->id.orig_id)->data);
4149 Mesh *result = (Mesh *)object->runtime->data_orig;
4150 BLI_assert((result->id.tag & ID_TAG_COPIED_ON_EVAL) != 0);
4151 BLI_assert((result->id.tag & ID_TAG_COPIED_ON_EVAL_FINAL_RESULT) == 0);
4152 return result;
4153 }
4154 BLI_assert((object->id.tag & ID_TAG_COPIED_ON_EVAL) == 0);
4155 return (Mesh *)object->data;
4156}
4157
4159{
4160 Mesh *result = nullptr;
4161 if (object->id.orig_id == nullptr) {
4162 BLI_assert((object->id.tag & ID_TAG_COPIED_ON_EVAL) == 0);
4163 result = (Mesh *)object->data;
4164 }
4165 else {
4166 BLI_assert((object->id.tag & ID_TAG_COPIED_ON_EVAL) != 0);
4167 result = (Mesh *)((Object *)object->id.orig_id)->data;
4168 }
4169 BLI_assert(result != nullptr);
4171 return result;
4172}
4173
4175{
4176 BLI_assert(!DEG_is_original_id(&object->id));
4177 BLI_assert(object->type == OB_MESH);
4178
4179 const Mesh *mesh = static_cast<const Mesh *>(object->data);
4180 if (mesh->runtime->edit_mesh == nullptr) {
4181 /* Happens when requesting material of evaluated 3d font object: the evaluated object get
4182 * converted to mesh, and it does not have edit mesh. */
4183 return nullptr;
4184 }
4185
4186 return reinterpret_cast<Mesh *>(object->runtime->data_eval);
4187}
4188
4190{
4191 BLI_assert(!DEG_is_original_id(&object->id));
4192 BLI_assert(object->type == OB_MESH);
4193
4194 const Mesh *mesh = static_cast<const Mesh *>(object->data);
4195 BLI_assert(mesh->runtime->edit_mesh != nullptr);
4196 UNUSED_VARS_NDEBUG(mesh);
4197
4198 return object->runtime->editmesh_eval_cage;
4199}
4200
4202{
4203 BLI_assert(!DEG_is_original_id(&object->id));
4204 BLI_assert(object->type == OB_MESH);
4205 return object->runtime->mesh_deform_eval;
4206}
4207
4209{
4210 ID *data = (ID *)object->data;
4211 if (data == nullptr || GS(data->name) != ID_LT) {
4212 return nullptr;
4213 }
4214
4215 Lattice *lt = (Lattice *)data;
4216 if (lt->editlatt) {
4217 return lt->editlatt->latt;
4218 }
4219
4220 return lt;
4221}
4222
4224{
4225 ID *data_eval = object->runtime->data_eval;
4226
4227 if (data_eval == nullptr || GS(data_eval->name) != ID_LT) {
4228 return nullptr;
4229 }
4230
4231 Lattice *lt_eval = (Lattice *)data_eval;
4232 if (lt_eval->editlatt) {
4233 return lt_eval->editlatt->latt;
4234 }
4235
4236 return lt_eval;
4237}
4238
4241/* -------------------------------------------------------------------- */
4245static int pc_cmp(const void *a, const void *b)
4246{
4247 const LinkData *ad = (const LinkData *)a, *bd = (const LinkData *)b;
4248 if (POINTER_AS_INT(ad->data) > POINTER_AS_INT(bd->data)) {
4249 return 1;
4250 }
4251
4252 return 0;
4253}
4254
4256{
4257 /* TODO: Review the usages of this function, currently with copy-on-eval it will be called for
4258 * orig object and then again for evaluated copies of it, think this is bad since there is no
4259 * guarantee that we get the same stack index in both cases? Order is important since this index
4260 * is used for filenames on disk. */
4261
4262 LinkData *link = nullptr;
4263 int i = 0;
4264
4266
4267 for (link = (LinkData *)ob->pc_ids.first, i = 0; link; link = link->next, i++) {
4268 int index = POINTER_AS_INT(link->data);
4269
4270 if (i < index) {
4271 break;
4272 }
4273 }
4274
4275 link = MEM_cnew<LinkData>("PCLink");
4276 link->data = POINTER_FROM_INT(i);
4277 BLI_addtail(&ob->pc_ids, link);
4278
4279 return i;
4280}
4281
4282static int pc_findindex(ListBase *listbase, int index)
4283{
4284 int number = 0;
4285
4286 if (listbase == nullptr) {
4287 return -1;
4288 }
4289
4290 LinkData *link = (LinkData *)listbase->first;
4291 while (link) {
4292 if (POINTER_AS_INT(link->data) == index) {
4293 return number;
4294 }
4295
4296 number++;
4297 link = link->next;
4298 }
4299
4300 return -1;
4301}
4302
4304{
4305 int list_index = pc_findindex(&ob->pc_ids, index);
4306 LinkData *link = (LinkData *)BLI_findlink(&ob->pc_ids, list_index);
4307 BLI_freelinkN(&ob->pc_ids, link);
4308}
4309
4312/* -------------------------------------------------------------------- */
4317static KeyBlock *insert_meshkey(Main *bmain, Object *ob, const char *name, const bool from_mix)
4318{
4319 Mesh *mesh = (Mesh *)ob->data;
4320 Key *key = mesh->key;
4321 KeyBlock *kb;
4322 int newkey = 0;
4323
4324 if (key == nullptr) {
4325 key = mesh->key = BKE_key_add(bmain, (ID *)mesh);
4326 key->type = KEY_RELATIVE;
4327 newkey = 1;
4328 }
4329
4330 if (newkey || from_mix == false) {
4331 /* create from mesh */
4332 kb = BKE_keyblock_add_ctime(key, name, false);
4333 BKE_keyblock_convert_from_mesh(mesh, key, kb);
4334 }
4335 else {
4336 /* copy from current values */
4337 int totelem;
4338 float *data = BKE_key_evaluate_object(ob, &totelem);
4339
4340 /* create new block with prepared data */
4341 kb = BKE_keyblock_add_ctime(key, name, false);
4342 kb->data = data;
4343 kb->totelem = totelem;
4344 }
4345
4346 return kb;
4347}
4349static KeyBlock *insert_lattkey(Main *bmain, Object *ob, const char *name, const bool from_mix)
4350{
4351 Lattice *lt = (Lattice *)ob->data;
4352 Key *key = lt->key;
4353 KeyBlock *kb;
4354 int newkey = 0;
4355
4356 if (key == nullptr) {
4357 key = lt->key = BKE_key_add(bmain, (ID *)lt);
4358 key->type = KEY_RELATIVE;
4359 newkey = 1;
4360 }
4361
4362 if (newkey || from_mix == false) {
4363 kb = BKE_keyblock_add_ctime(key, name, false);
4364 if (!newkey) {
4365 KeyBlock *basekb = (KeyBlock *)key->block.first;
4366 kb->data = MEM_dupallocN(basekb->data);
4367 kb->totelem = basekb->totelem;
4368 }
4369 else {
4371 }
4372 }
4373 else {
4374 /* copy from current values */
4375 int totelem;
4376 float *data = BKE_key_evaluate_object(ob, &totelem);
4377
4378 /* create new block with prepared data */
4379 kb = BKE_keyblock_add_ctime(key, name, false);
4380 kb->totelem = totelem;
4381 kb->data = data;
4382 }
4383
4384 return kb;
4385}
4387static KeyBlock *insert_curvekey(Main *bmain, Object *ob, const char *name, const bool from_mix)
4388{
4389 Curve *cu = (Curve *)ob->data;
4390 Key *key = cu->key;
4391 KeyBlock *kb;
4392 ListBase *lb = BKE_curve_nurbs_get(cu);
4393 int newkey = 0;
4394
4395 if (key == nullptr) {
4396 key = cu->key = BKE_key_add(bmain, (ID *)cu);
4397 key->type = KEY_RELATIVE;
4398 newkey = 1;
4399 }
4400
4401 if (newkey || from_mix == false) {
4402 /* create from curve */
4403 kb = BKE_keyblock_add_ctime(key, name, false);
4404 if (!newkey) {
4405 KeyBlock *basekb = (KeyBlock *)key->block.first;
4406 kb->data = MEM_dupallocN(basekb->data);
4407 kb->totelem = basekb->totelem;
4408 }
4409 else {
4411 }
4412 }
4413 else {
4414 /* copy from current values */
4415 int totelem;
4416 float *data = BKE_key_evaluate_object(ob, &totelem);
4417
4418 /* create new block with prepared data */
4419 kb = BKE_keyblock_add_ctime(key, name, false);
4420 kb->totelem = totelem;
4421 kb->data = data;
4422 }
4423
4424 return kb;
4425}
4426
4429/* -------------------------------------------------------------------- */
4434 Object *ob,
4435 const char *name,
4436 const bool from_mix)
4437{
4438 KeyBlock *key = nullptr;
4439
4440 switch (ob->type) {
4441 case OB_MESH:
4442 key = insert_meshkey(bmain, ob, name, from_mix);
4443 break;
4444 case OB_CURVES_LEGACY:
4445 case OB_SURF:
4446 key = insert_curvekey(bmain, ob, name, from_mix);
4447 break;
4448 case OB_LATTICE:
4449 key = insert_lattkey(bmain, ob, name, from_mix);
4450 break;
4451 default:
4452 break;
4453 }
4454
4455 /* Set the first active when none is set when called from RNA. */
4456 if (key != nullptr) {
4457 if (ob->shapenr <= 0) {
4458 ob->shapenr = 1;
4459 }
4460 }
4461
4462 return key;
4463}
4464
4466{
4467 Key **key_p, *key;
4468
4469 key_p = BKE_key_from_object_p(ob);
4470 if (ELEM(nullptr, key_p, *key_p)) {
4471 return false;
4472 }
4473
4474 key = *key_p;
4475 *key_p = nullptr;
4476
4477 BKE_id_free_us(bmain, key);
4478
4479 return true;
4480}
4481
4483{
4484 Key *key = BKE_key_from_object(ob);
4485 short kb_index;
4486
4487 if (key == nullptr) {
4488 return false;
4489 }
4490
4491 kb_index = BLI_findindex(&key->block, kb);
4492 BLI_assert(kb_index != -1);
4493
4494 LISTBASE_FOREACH (KeyBlock *, rkb, &key->block) {
4495 if (rkb->relative == kb_index) {
4496 /* remap to the 'Basis' */
4497 rkb->relative = 0;
4498 }
4499 else if (rkb->relative >= kb_index) {
4500 /* Fix positional shift of the keys when kb is deleted from the list */
4501 rkb->relative -= 1;
4502 }
4503 }
4504
4505 BLI_remlink(&key->block, kb);
4506 key->totkey--;
4507 if (key->refkey == kb) {
4508 key->refkey = (KeyBlock *)key->block.first;
4509
4510 if (key->refkey) {
4511 /* apply new basis key on original data */
4512 switch (ob->type) {
4513 case OB_MESH: {
4514 Mesh *mesh = (Mesh *)ob->data;
4515 MutableSpan<float3> positions = mesh->vert_positions_for_write();
4517 key->refkey, reinterpret_cast<float(*)[3]>(positions.data()), mesh->verts_num);
4518 break;
4519 }
4520 case OB_CURVES_LEGACY:
4521 case OB_SURF:
4523 key->refkey, (Curve *)ob->data, BKE_curve_nurbs_get((Curve *)ob->data));
4524 break;
4525 case OB_LATTICE:
4527 break;
4528 }
4529 }
4530 }
4531
4532 if (kb->data) {
4533 MEM_freeN(kb->data);
4534 }
4535 MEM_freeN(kb);
4536
4537 /* Unset active when all are freed. */
4538 if (BLI_listbase_is_empty(&key->block)) {
4539 ob->shapenr = 0;
4540 }
4541 else if (ob->shapenr > 1) {
4542 ob->shapenr--;
4543 }
4544
4545 if (key->totkey == 0) {
4546 BKE_object_shapekey_free(bmain, ob);
4547 }
4548
4549 return true;
4550}
4551
4554/* -------------------------------------------------------------------- */
4558bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
4559{
4560 /* test if 'ob' is a parent somewhere in par's parents */
4561 if (par == nullptr) {
4562 return false;
4563 }
4564 if (ob == par) {
4565 return true;
4566 }
4567 return BKE_object_parent_loop_check(par->parent, ob);
4568}
4569
4571{
4572 if (ob->flag & flag) {
4573 return true;
4574 }
4575 if (ob->parent) {
4577 }
4578
4579 return false;
4580}
4581
4582bool BKE_object_is_child_recursive(const Object *ob_parent, const Object *ob_child)
4583{
4584 for (ob_child = ob_child->parent; ob_child; ob_child = ob_child->parent) {
4585 if (ob_child == ob_parent) {
4586 return true;
4587 }
4588 }
4589 return false;
4590}
4591
4593{
4594 /* Always test on original object since evaluated object may no longer
4595 * have shape keys or modifiers that were used to evaluate it. */
4596 ob = DEG_get_original_object(ob);
4597
4598 int flag = 0;
4599
4600 if (BKE_key_from_object(ob)) {
4602 }
4603 else {
4604 ModifierData *md;
4605 VirtualModifierData virtual_modifier_data;
4606 /* cloth */
4607 for (md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
4609 md = md->next)
4610 {
4611 if ((flag & eModifierMode_Render) == 0 &&
4613 {
4615 }
4616
4617 if ((flag & eModifierMode_Realtime) == 0 &&
4619 {
4621 }
4622 }
4623 }
4624
4625 return flag;
4626}
4627
4628bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
4629{
4630 /* If object has any sort of animation data assume it is moving. */
4631 if (BKE_animdata_id_is_animated(&object->id)) {
4632 return true;
4633 }
4634 if (!BLI_listbase_is_empty(&object->constraints)) {
4635 return true;
4636 }
4637 if (recurse_parent && object->parent != nullptr) {
4638 return BKE_object_moves_in_time(object->parent, true);
4639 }
4640 return false;
4641}
4642
4643static bool object_moves_in_time(const Object *object)
4644{
4645 return BKE_object_moves_in_time(object, true);
4646}
4647
4648static bool object_deforms_in_time(Object *object)
4649{
4650 if (BKE_key_from_object(object) != nullptr) {
4651 return true;
4652 }
4653 if (!BLI_listbase_is_empty(&object->modifiers)) {
4654 return true;
4655 }
4656 return object_moves_in_time(object);
4657}
4658
4660{
4661 /* TODO(sergey): Consider generalizing this a bit so all modifier logic
4662 * is concentrated in MOD_{modifier}.c file,
4663 */
4664 if (md->type == eModifierType_Array) {
4666 /* TODO(sergey): Check if curve is deformed. */
4667 return (amd->start_cap != nullptr && object_moves_in_time(amd->start_cap)) ||
4668 (amd->end_cap != nullptr && object_moves_in_time(amd->end_cap)) ||
4669 (amd->curve_ob != nullptr && object_moves_in_time(amd->curve_ob)) ||
4670 (amd->offset_ob != nullptr && object_moves_in_time(amd->offset_ob));
4671 }
4672 if (md->type == eModifierType_Mirror) {
4674 return mmd->mirror_ob != nullptr &&
4676 }
4677 if (md->type == eModifierType_Screw) {
4679 return smd->ob_axis != nullptr && object_moves_in_time(smd->ob_axis);
4680 }
4682 /* NOTE: Not ideal because it's unknown whether topology changes or not.
4683 * This will be detected later, so by assuming it's only deformation
4684 * going on here we allow baking deform-only mesh to Alembic and have
4685 * proper motion blur after that.
4686 */
4687 return true;
4688 }
4689 if (md->type == eModifierType_Nodes) {
4690 /* Not ideal for performance to always assume this is animated,
4691 * but hard to detect in general. The better long term solution is likely
4692 * to replace BKE_object_is_deform_modified by a test if the object was
4693 * modified by the depsgraph when changing frames. */
4694 return true;
4695 }
4696 return false;
4697}
4698
4700{
4701 /* TODO(sergey): This is a bit code duplication with depsgraph, but
4702 * would be nicer to solve this as a part of new dependency graph
4703 * work, so we avoid conflicts and so.
4704 */
4705 if (ob->adt != nullptr) {
4706 AnimData *adt = ob->adt;
4707 if (adt->action != nullptr) {
4709 if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) {
4710 return true;
4711 }
4712 }
4713 }
4714 LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
4715 if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) {
4716 return true;
4717 }
4718 }
4719 }
4720 return false;
4721}
4722
4724{
4725 /* Always test on original object since evaluated object may no longer
4726 * have shape keys or modifiers that were used to evaluate it. */
4727 ob = DEG_get_original_object(ob);
4728
4729 ModifierData *md;
4730 VirtualModifierData virtual_modifier_data;
4731 int flag = 0;
4732 const bool is_modifier_animated = modifiers_has_animation_check(ob);
4733
4734 if (BKE_key_from_object(ob)) {
4736 }
4737
4738 if (ob->type == OB_CURVES_LEGACY) {
4739 Curve *cu = (Curve *)ob->data;
4740 if (cu->taperobj != nullptr && object_deforms_in_time(cu->taperobj)) {
4742 }
4743 }
4744
4745 /* cloth */
4746 for (md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
4748 md = md->next)
4749 {
4751 bool can_deform = mti->type == ModifierTypeType::OnlyDeform || is_modifier_animated;
4752
4753 if (!can_deform) {
4754 can_deform = constructive_modifier_is_deform_modified(ob, md);
4755 }
4756
4757 if (can_deform) {
4758 if (!(flag & eModifierMode_Render) &&
4760 {
4762 }
4763
4764 if (!(flag & eModifierMode_Realtime) &&
4766 {
4768 }
4769 }
4770 }
4771
4772 return flag;
4773}
4774
4776{
4777 int num_scenes = 0;
4778 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
4779 if (BKE_collection_has_object_recursive(scene->master_collection, ob)) {
4780 num_scenes++;
4781 }
4782 }
4783 return num_scenes;
4784}
4785
4786MovieClip *BKE_object_movieclip_get(Scene *scene, const Object *ob, bool use_default)
4787{
4788 MovieClip *clip = use_default ? scene->clip : nullptr;
4789 bConstraint *con = (bConstraint *)ob->constraints.first, *scon = nullptr;
4790
4791 while (con) {
4792 if (con->type == CONSTRAINT_TYPE_CAMERASOLVER) {
4793 if (scon == nullptr || (scon->flag & CONSTRAINT_OFF)) {
4794 scon = con;
4795 }
4796 }
4797
4798 con = con->next;
4799 }
4800
4801 if (scon) {
4802 bCameraSolverConstraint *solver = (bCameraSolverConstraint *)scon->data;
4803 if ((solver->flag & CAMERASOLVER_ACTIVECLIP) == 0) {
4804 clip = solver->clip;
4805 }
4806 else {
4807 clip = scene->clip;
4808 }
4809 }
4810
4811 return clip;
4812}
4813
4815{
4816 return ELEM(ob->type,
4817 OB_MESH,
4819 OB_SURF,
4820 OB_FONT,
4821 OB_MBALL,
4822 OB_CURVES,
4824 OB_VOLUME,
4827}
4828
4831/* -------------------------------------------------------------------- */
4836{
4837 *object->runtime = {};
4838}
4839
4840void BKE_object_runtime_reset_on_copy(Object *object, const int /*flag*/)
4841{
4842 blender::bke::ObjectRuntime *runtime = object->runtime;
4843 runtime->data_eval = nullptr;
4844 runtime->mesh_deform_eval = nullptr;
4845 runtime->curve_cache = nullptr;
4846 runtime->object_as_temp_mesh = nullptr;
4847 runtime->pose_backup = nullptr;
4848 runtime->object_as_temp_curve = nullptr;
4849 runtime->geometry_set_eval = nullptr;
4850
4851 runtime->crazyspace_deform_imats = {};
4852 runtime->crazyspace_deform_cos = {};
4853}
4854
4856{
4857 /* Currently this is all that's needed. */
4859
4861}
4862
4865/* -------------------------------------------------------------------- */
4873{
4874 Object *ob_arm = nullptr;
4875
4876 if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
4877 ob_arm = ob->parent;
4878 }
4879 else {
4881 if (mod->type == eModifierType_Armature) {
4882 ob_arm = ((ArmatureModifierData *)mod)->object;
4883 }
4884 }
4885 }
4886
4887 return ob_arm;
4888}
4889
4890static bool obrel_list_test(Object *ob)
4891{
4892 return ob && !(ob->id.tag & ID_TAG_DOIT);
4893}
4894
4895static void obrel_list_add(LinkNode **links, Object *ob)
4896{
4897 BLI_linklist_prepend(links, ob);
4898 ob->id.tag |= ID_TAG_DOIT;
4899}
4900
4902 ViewLayer *view_layer,
4903 eObjectSet objectSet,
4904 eObRelationTypes includeFilter)
4905{
4906 LinkNode *links = nullptr;
4907
4908 /* Remove markers from all objects */
4909 BKE_view_layer_synced_ensure(scene, view_layer);
4911 base->object->id.tag &= ~ID_TAG_DOIT;
4912 }
4913
4914 /* iterate over all selected and visible objects */
4916 if (objectSet == OB_SET_ALL) {
4917 /* as we get all anyways just add it */
4918 Object *ob = base->object;
4919 obrel_list_add(&links, ob);
4920 }
4921 else {
4922 if ((objectSet == OB_SET_SELECTED && BASE_SELECTED_EDITABLE(((View3D *)nullptr), base)) ||
4923 (objectSet == OB_SET_VISIBLE && BASE_EDITABLE(((View3D *)nullptr), base)))
4924 {
4925 Object *ob = base->object;
4926
4927 if (obrel_list_test(ob)) {
4928 obrel_list_add(&links, ob);
4929 }
4930
4931 /* parent relationship */
4932 if (includeFilter & (OB_REL_PARENT | OB_REL_PARENT_RECURSIVE)) {
4933 Object *parent = ob->parent;
4934 if (obrel_list_test(parent)) {
4935
4936 obrel_list_add(&links, parent);
4937
4938 /* recursive parent relationship */
4939 if (includeFilter & OB_REL_PARENT_RECURSIVE) {
4940 parent = parent->parent;
4941 while (obrel_list_test(parent)) {
4942
4943 obrel_list_add(&links, parent);
4944 parent = parent->parent;
4945 }
4946 }
4947 }
4948 }
4949
4950 /* child relationship */
4951 if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
4952 LISTBASE_FOREACH (Base *, local_base, BKE_view_layer_object_bases_get(view_layer)) {
4953 if (BASE_EDITABLE(((View3D *)nullptr), local_base)) {
4954
4955 Object *child = local_base->object;
4956 if (obrel_list_test(child)) {
4957 if ((includeFilter & OB_REL_CHILDREN_RECURSIVE &&
4958 BKE_object_is_child_recursive(ob, child)) ||
4959 (includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob))
4960 {
4961 obrel_list_add(&links, child);
4962 }
4963 }
4964 }
4965 }
4966 }
4967
4968 /* include related armatures */
4969 if (includeFilter & OB_REL_MOD_ARMATURE) {
4970 Object *arm = obrel_armature_find(ob);
4971 if (obrel_list_test(arm)) {
4972 obrel_list_add(&links, arm);
4973 }
4974 }
4975 }
4976 }
4977 }
4978
4979 return links;
4980}
4981
4983{
4984 LinkNode *collection_linknode = nullptr;
4985 Collection *collection = nullptr;
4986 while ((collection = BKE_collection_object_find(bmain, scene, collection, ob))) {
4987 BLI_linklist_prepend(&collection_linknode, collection);
4988 }
4989
4990 return collection_linknode;
4991}
4992
4993void BKE_object_groups_clear(Main *bmain, Scene *scene, Object *ob)
4994{
4995 Collection *collection = nullptr;
4996 while ((collection = BKE_collection_object_find(bmain, scene, collection, ob))) {
4997 BKE_collection_object_remove(bmain, collection, ob, false);
4998 DEG_id_tag_update(&collection->id, ID_RECALC_SYNC_TO_EVAL);
4999 }
5000}
5001
5004/* -------------------------------------------------------------------- */
5008KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
5009{
5010 KDTree_3d *tree = nullptr;
5011 uint tot = 0;
5012
5013 switch (ob->type) {
5014 case OB_MESH: {
5015 Mesh *mesh = (Mesh *)ob->data;
5016 uint i;
5017
5018 const Mesh *mesh_eval = BKE_object_get_mesh_deform_eval(ob) ?
5021 const int *index;
5022
5023 if (mesh_eval &&
5024 (index = (const int *)CustomData_get_layer(&mesh_eval->vert_data, CD_ORIGINDEX)))
5025 {
5026 const Span<float3> positions = mesh->vert_positions();
5027
5028 /* Tree over-allocates in case where some verts have #ORIGINDEX_NONE. */
5029 tot = 0;
5030 tree = BLI_kdtree_3d_new(positions.size());
5031
5032 /* We don't how many verts from the DM we can use. */
5033 for (i = 0; i < positions.size(); i++) {
5034 if (index[i] != ORIGINDEX_NONE) {
5035 float co[3];
5036 mul_v3_m4v3(co, ob->object_to_world().ptr(), positions[i]);
5037 BLI_kdtree_3d_insert(tree, index[i], co);
5038 tot++;
5039 }
5040 }
5041 }
5042 else {
5043 const Span<float3> positions = mesh->vert_positions();
5044
5045 tot = positions.size();
5046 tree = BLI_kdtree_3d_new(tot);
5047
5048 for (i = 0; i < tot; i++) {
5049 float co[3];
5050 mul_v3_m4v3(co, ob->object_to_world().ptr(), positions[i]);
5051 BLI_kdtree_3d_insert(tree, i, co);
5052 }
5053 }
5054
5055 BLI_kdtree_3d_balance(tree);
5056 break;
5057 }
5058 case OB_CURVES_LEGACY:
5059 case OB_SURF: {
5060 /* TODO: take deformation into account */
5061 Curve *cu = (Curve *)ob->data;
5062 uint i, a;
5063
5064 Nurb *nu;
5065
5067 tree = BLI_kdtree_3d_new(tot);
5068 i = 0;
5069
5070 nu = (Nurb *)cu->nurb.first;
5071 while (nu) {
5072 if (nu->bezt) {
5073 BezTriple *bezt;
5074
5075 bezt = nu->bezt;
5076 a = nu->pntsu;
5077 while (a--) {
5078 float co[3];
5079 mul_v3_m4v3(co, ob->object_to_world().ptr(), bezt->vec[1]);
5080 BLI_kdtree_3d_insert(tree, i++, co);
5081 bezt++;
5082 }
5083 }
5084 else {
5085 BPoint *bp;
5086
5087 bp = nu->bp;
5088 a = nu->pntsu * nu->pntsv;
5089 while (a--) {
5090 float co[3];
5091 mul_v3_m4v3(co, ob->object_to_world().ptr(), bp->vec);
5092 BLI_kdtree_3d_insert(tree, i++, co);
5093 bp++;
5094 }
5095 }
5096 nu = nu->next;
5097 }
5098
5099 BLI_kdtree_3d_balance(tree);
5100 break;
5101 }
5102 case OB_LATTICE: {
5103 /* TODO: take deformation into account */
5104 Lattice *lt = (Lattice *)ob->data;
5105 BPoint *bp;
5106 uint i;
5107
5108 tot = lt->pntsu * lt->pntsv * lt->pntsw;
5109 tree = BLI_kdtree_3d_new(tot);
5110 i = 0;
5111
5112 for (bp = lt->def; i < tot; bp++) {
5113 float co[3];
5114 mul_v3_m4v3(co, ob->object_to_world().ptr(), bp->vec);
5115 BLI_kdtree_3d_insert(tree, i++, co);
5116 }
5117
5118 BLI_kdtree_3d_balance(tree);
5119 break;
5120 }
5121 }
5122
5123 *r_tot = tot;
5124 return tree;
5125}
5126
5129/* -------------------------------------------------------------------- */
5137{
5138 ListBase pidlist;
5139 BKE_ptcache_ids_from_object(&pidlist, ob, nullptr, 0);
5140
5141 LISTBASE_FOREACH (PTCacheID *, pid, &pidlist) {
5142 if (pid->cache) {
5143 if (state) {
5144 pid->cache->flag |= PTCACHE_IGNORE_CLEAR;
5145 }
5146 else {
5147 pid->cache->flag &= ~PTCACHE_IGNORE_CLEAR;
5148 }
5149 }
5150 }
5151
5152 BLI_freelistN(&pidlist);
5153}
5154
5156 Scene *scene,
5157 Object *ob,
5158 bool update_mesh,
5159 int parent_recursion,
5160 float frame,
5161 int type)
5162{
5163 const bool flush_to_original = DEG_is_active(depsgraph);
5165
5166 if (type == eModifierType_DynamicPaint) {
5168
5169 /* if other is dynamic paint canvas, don't update */
5170 if (pmd && pmd->canvas) {
5171 return true;
5172 }
5173 }
5174 else if (type == eModifierType_Fluid) {
5176
5177 if (fmd && (fmd->type & MOD_FLUID_TYPE_DOMAIN) != 0) {
5178 return true;
5179 }
5180 }
5181
5182 /* if object has parents, update them too */
5183 if (parent_recursion) {
5184 int recursion = parent_recursion - 1;
5185 bool no_update = false;
5186 if (ob->parent) {
5188 depsgraph, scene, ob->parent, false, recursion, frame, type);
5189 }
5190 if (ob->track) {
5192 depsgraph, scene, ob->track, false, recursion, frame, type);
5193 }
5194
5195 /* Skip sub-frame if object is parented to vertex of a dynamic paint canvas. */
5196 if (no_update && ELEM(ob->partype, PARVERT1, PARVERT3)) {
5197 return false;
5198 }
5199
5200 /* also update constraint targets */
5202 ListBase targets = {nullptr, nullptr};
5203
5204 if (BKE_constraint_targets_get(con, &targets)) {
5205 LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
5206 if (ct->tar) {
5208 depsgraph, scene, ct->tar, false, recursion, frame, type);
5209 }
5210 }
5211 /* free temp targets */
5212 BKE_constraint_targets_flush(con, &targets, false);
5213 }
5214 }
5215 }
5216
5217 /* was originally ID_RECALC_ALL - TODO: which flags are really needed??? */
5218 /* TODO(sergey): What about animation? */
5220 frame);
5221
5222 ob->id.recalc |= ID_RECALC_ALL;
5223 if (update_mesh) {
5225 &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
5226 /* Ignore cache clear during sub-frame updates to not mess up cache validity. */
5230 }
5231 else {
5232 BKE_object_where_is_calc_time(depsgraph, scene, ob, frame);
5233 }
5234
5235 /* for curve following objects, parented curve has to be updated too */
5236 if (ob->type == OB_CURVES_LEGACY) {
5237 Curve *cu = (Curve *)ob->data;
5239 &cu->id, cu->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
5240 }
5241 /* and armatures... */
5242 if (ob->type == OB_ARMATURE) {
5243 bArmature *arm = (bArmature *)ob->data;
5245 &arm->id, arm->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
5246 BKE_pose_where_is(depsgraph, scene, ob);
5247 }
5248
5249 return false;
5250}
5251
5253{
5254 Object *ob = (Object *)bmain->objects.first;
5255 int select_id = 1;
5256 while (ob) {
5257 ob->runtime->select_id = select_id++;
5258 ob = (Object *)ob->id.next;
5259 }
5260}
5261
5264/* -------------------------------------------------------------------- */
5268Mesh *BKE_object_to_mesh(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
5269{
5271
5272 Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
5273 object->runtime->object_as_temp_mesh = mesh;
5274 return mesh;
5275}
5276
5278{
5279 if (object->runtime->object_as_temp_mesh == nullptr) {
5280 return;
5281 }
5282 BKE_id_free(nullptr, object->runtime->object_as_temp_mesh);
5283 object->runtime->object_as_temp_mesh = nullptr;
5284}
5285
5286Curve *BKE_object_to_curve(Object *object, Depsgraph *depsgraph, bool apply_modifiers)
5287{
5289
5290 Curve *curve = BKE_curve_new_from_object(object, depsgraph, apply_modifiers);
5291 object->runtime->object_as_temp_curve = curve;
5292 return curve;
5293}
5294
5296{
5297 if (object->runtime->object_as_temp_curve == nullptr) {
5298 return;
5299 }
5300 BKE_id_free(nullptr, object->runtime->object_as_temp_curve);
5301 object->runtime->object_as_temp_curve = nullptr;
5302}
5303
5308
5310{
5311 ModifierData *md = (ModifierData *)(ob->modifiers.last);
5312
5313 while (md) {
5314 if (md->type == eModifierType_Subsurf) {
5315 break;
5316 }
5317
5318 md = md->prev;
5319 }
5320
5321 return (SubsurfModifierData *)(md);
5322}
5323
5325{
5326 ob->type = BKE_object_obdata_to_type(new_data);
5327 ob->data = (void *)new_data;
5328 ob->runtime->geometry_set_eval = nullptr;
5329 ob->runtime->data_eval = new_data;
5330 ob->runtime->bounds_eval.reset();
5331 ob->id.py_instance = nullptr;
5332}
5333
5336const blender::float4x4 &Object::object_to_world() const
5337{
5338 return this->runtime->object_to_world;
5339}
5340const blender::float4x4 &Object::world_to_object() const
5341{
5342 return this->runtime->world_to_object;
5343}
Functions for backward compatibility with the legacy Action API.
Blender kernel action and pose functionality.
void void void void BKE_pose_blend_read_after_liblink(BlendLibReader *reader, Object *ob, bPose *pose) ATTR_NONNULL(1
void BKE_pose_tag_recalc(Main *bmain, bPose *pose) ATTR_NONNULL(1
void void void BKE_pose_blend_read_data(BlendDataReader *reader, ID *id_owner, bPose *pose) ATTR_NONNULL(1
void BKE_pose_free_ex(bPose *pose, bool do_id_user)
void BKE_pose_update_constraint_flags(bPose *pose) ATTR_NONNULL(1)
void BKE_pose_channels_hash_ensure(bPose *pose) ATTR_NONNULL(1)
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_pose_copy_data_ex(bPose **dst, const bPose *src, int flag, bool copy_constraints)
void BKE_pose_check_uids_unique_and_report(const bPose *pose)
void void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm) ATTR_NONNULL(1
bool BKE_animdata_id_is_animated(const ID *id)
Definition anim_data.cc:321
bool BKE_where_on_path(const struct Object *ob, float ctime, float r_vec[4], float r_dir[3], float r_quat[4], float *r_radius, float *r_weight)
void animviz_free_motionpath(struct bMotionPath *mpath)
void animviz_motionpath_blend_write(struct BlendWriter *writer, struct bMotionPath *mpath)
void animviz_motionpath_blend_read_data(struct BlendDataReader *reader, struct bMotionPath *mpath)
void animviz_settings_init(struct bAnimVizSettings *avs)
struct bMotionPath * animviz_copy_motionpath(const struct bMotionPath *mpath_src)
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time) ATTR_WARN_UNUSED_RESULT
Definition anim_sys.cc:734
@ ADT_RECALC_ANIM
@ ADT_RECALC_ALL
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, bool flush_to_original)
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
Definition armature.cc:2767
void BKE_pose_where_is(Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition armature.cc:2941
std::optional< blender::Bounds< blender::float3 > > BKE_armature_min_max(const Object *ob)
Definition armature.cc:3024
bArmature * BKE_armature_add(Main *bmain, const char *name)
Definition armature.cc:514
void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
Definition asset.cc:175
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
Definition bpath.cc:123
Camera data-block and utility functions.
void * BKE_camera_add(struct Main *bmain, const char *name)
bool BKE_collection_object_remove(Main *bmain, Collection *collection, Object *ob, bool free_us)
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
bool BKE_collection_viewlayer_object_add(Main *bmain, const ViewLayer *view_layer, Collection *collection, Object *ob)
Collection * BKE_collection_object_find(Main *bmain, Scene *scene, Collection *collection, Object *ob)
void BKE_collection_object_add_from(Main *bmain, Scene *scene, Object *ob_src, Object *ob_dst)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
void BKE_constraints_free_ex(struct ListBase *list, bool do_id_user)
void BKE_constraints_solve(struct Depsgraph *depsgraph, struct ListBase *conlist, struct bConstraintOb *cob, float ctime)
void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targets, bool no_copy)
void BKE_constraint_blend_write(struct BlendWriter *writer, struct ListBase *conlist)
int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targets)
void BKE_constraint_blend_read_data(struct BlendDataReader *reader, struct ID *id_owner, struct ListBase *lb)
void BKE_constraints_copy_ex(struct ListBase *dst, const struct ListBase *src, int flag, bool do_extern)
void BKE_constraints_clear_evalob(struct bConstraintOb *cob)
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, const int flag, void *userdata)
struct bConstraintOb * BKE_constraints_make_evalob(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, void *subdata, short datatype)
void BKE_crazyspace_api_eval_clear(Object *object)
void BKE_curve_texspace_ensure(Curve *cu)
Definition curve.cc:500
void BKE_curve_bevelList_free(ListBase *bev)
Definition curve.cc:2510
ListBase * BKE_curve_nurbs_get(Curve *cu)
Definition curve.cc:4965
Curve * BKE_curve_new_from_object(Object *object, Depsgraph *depsgraph, bool apply_modifiers)
std::optional< blender::Bounds< blender::float3 > > BKE_curve_minmax(const Curve *cu, bool use_radius)
Definition curve.cc:5104
void BKE_nurbList_free(ListBase *lb)
Definition curve.cc:596
short BKE_curve_type_get(const Curve *cu)
Definition curve.cc:416
Curve * BKE_curve_add(Main *bmain, const char *name, int type)
Definition curve.cc:386
int BKE_nurbList_verts_count_without_handles(const ListBase *nurb)
Definition curve.cc:551
bool BKE_nurbList_index_get_co(ListBase *nurb, int index, float r_co[3])
Definition curve.cc:509
void * BKE_curves_add(struct Main *bmain, const char *name)
Low-level operations for curves.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
@ CD_SET_DEFAULT
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int totelem, int index)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
void CustomData_copy_layer_type_data(const CustomData *source, CustomData *destination, eCustomDataType type, int source_index, int destination_index, int count)
#define ORIGINDEX_NONE
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
support for deformation groups and hooks.
display list (or rather multi purpose list) stuff.
void BKE_displist_free(struct ListBase *lb)
Definition displist.cc:64
DispList * BKE_displist_find(struct ListBase *lb, int type)
Definition displist.cc:71
void BKE_displist_minmax(const struct ListBase *dispbase, float min[3], float max[3])
@ DL_VERTS
ListBase * object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
void free_object_duplilist(ListBase *lb)
void BKE_partdeflect_free(struct PartDeflect *pd)
Definition effect.cc:119
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition effect.cc:57
@ G_DEBUG_DEPSGRAPH_EVAL
std::optional< blender::Bounds< blender::float3 > > BKE_gpencil_data_minmax(const struct bGPdata *gpd)
struct bGPdata * BKE_gpencil_data_addnew(struct Main *bmain, const char name[])
void BKE_gpencil_modifier_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb, struct Object *ob)
void BKE_gpencil_modifiers_foreach_ID_link(struct Object *ob, GreasePencilIDWalkFunc walk, void *user_data)
void BKE_gpencil_modifier_blend_write(struct BlendWriter *writer, struct ListBase *modbase)
void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, int flag)
Low-level operations for grease pencil.
void * BKE_grease_pencil_add(Main *bmain, const char *name)
void IDP_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
void(*)(ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data) IDTypeForeachCacheFunctionCallback
Definition BKE_idtype.hh:98
void BKE_keyblock_convert_to_lattice(const KeyBlock *kb, Lattice *lt)
Definition key.cc:2018
Key * BKE_key_add(Main *bmain, ID *id)
Definition key.cc:256
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, float(*vert_positions)[3], int totvert)
Definition key.cc:2202
void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
Definition key.cc:2186
void BKE_keyblock_convert_from_curve(const Curve *cu, KeyBlock *kb, const ListBase *nurb)
Definition key.cc:2117
KeyBlock * BKE_keyblock_add_ctime(Key *key, const char *name, bool do_force)
Definition key.cc:1878
void BKE_keyblock_convert_from_lattice(const Lattice *lt, KeyBlock *kb)
Definition key.cc:1992
float * BKE_key_evaluate_object(Object *ob, int *r_totelem)
Definition key.cc:1645
void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb)
Definition key.cc:2163
Key ** BKE_key_from_object_p(Object *ob)
Definition key.cc:1811
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1820
void BKE_lattice_transform(Lattice *lt, const float mat[4][4], bool do_keys)
Definition lattice.cc:637
std::optional< blender::Bounds< blender::float3 > > BKE_lattice_minmax(const Lattice *lt)
Definition lattice.cc:617
Lattice * BKE_lattice_add(Main *bmain, const char *name)
Definition lattice.cc:388
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_mode_params(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, const ObjectsInModeParams *params)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void BKE_view_layer_base_select_and_set_active(ViewLayer *view_layer, Base *selbase)
blender::Vector< Base * > BKE_view_layer_array_from_bases_in_mode_params(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, const ObjectsInModeParams *params)
ID * BKE_id_copy_for_duplicate(Main *bmain, ID *id, eDupli_ID_Flags duplicate_flags, int copy_flags)
Definition lib_id.cc:770
void BKE_id_free_us(Main *bmain, void *idv) ATTR_NONNULL()
void BKE_libblock_free_datablock(ID *id, int flag) ATTR_NONNULL()
void * BKE_libblock_alloc(Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
Definition lib_id.cc:1415
@ LIB_ID_COPY_NO_PREVIEW
@ LIB_ID_COPY_CACHES
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
@ LIB_ID_CREATE_NO_USER_REFCOUNT
@ LIB_ID_CREATE_NO_MAIN
@ LIB_ID_COPY_DEFAULT
@ LIB_ID_COPY_RIGID_BODY_NO_COLLECTION_HANDLING
void BKE_id_free(Main *bmain, void *idv)
void id_us_plus(ID *id)
Definition lib_id.cc:351
void BKE_libblock_free_data(ID *id, bool do_id_user) ATTR_NONNULL()
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1947
void id_us_min(ID *id)
Definition lib_id.cc:359
@ LIB_ID_DUPLICATE_IS_ROOT_ID
@ LIB_ID_DUPLICATE_IS_SUBPROCESS
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2560
void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
Definition lib_query.cc:71
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data_, func_call_)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
@ IDWALK_CB_NEVER_SELF
@ IDWALK_CB_USER
@ IDWALK_CB_OVERRIDE_LIBRARY_HIERARCHY_DEFAULT
@ IDWALK_CB_NEVER_NULL
@ IDWALK_CB_NOP
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:120
@ IDWALK_DO_DEPRECATED_POINTERS
#define BKE_LIB_FOREACHID_PROCESS_ID(data_, id_, cb_flag_)
#define BKE_LIB_FOREACHID_PROCESS_ID_NOCHECK(data_, id_, cb_flag_)
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:921
General operations, lookup, etc. for blender lights.
struct Light * BKE_light_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT
General operations for probes.
void BKE_lightprobe_cache_free(struct Object *object)
void BKE_lightprobe_cache_blend_read(struct BlendDataReader *reader, struct LightProbeObjectCache *cache)
void BKE_lightprobe_cache_blend_write(struct BlendWriter *writer, struct LightProbeObjectCache *cache)
void * BKE_lightprobe_add(struct Main *bmain, const char *name)
LightProbeObjectCache * BKE_lightprobe_cache_copy(LightProbeObjectCache *src_cache)
Blender kernel freestyle line style functionality.
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:500
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:494
General operations, lookup, etc. for materials.
void BKE_object_materials_test(struct Main *bmain, struct Object *ob, struct ID *id)
struct Material *** BKE_object_material_array_p(struct Object *ob)
MetaBall * BKE_mball_add(Main *bmain, const char *name)
Definition mball.cc:177
void BKE_mesh_ensure_skin_customdata(Mesh *mesh)
Mesh * BKE_mesh_add(Main *bmain, const char *name)
Mesh * BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers, bool preserve_origindex)
void BKE_mesh_texspace_get_reference(Mesh *mesh, char **r_texspace_flag, float **r_texspace_location, float **r_texspace_size)
@ ME_WRAPPER_TYPE_BMESH
blender::Span< blender::float3 > BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
Mesh * BKE_mesh_wrapper_ensure_subdivision(Mesh *mesh)
void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase *modbase)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, int flag)
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_AcceptsCVs
@ eModifierTypeFlag_AcceptsGreasePencil
@ eModifierTypeFlag_AcceptsVertexCosOnly
@ eModifierTypeFlag_AcceptsMesh
void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob)
void void void BKE_modifiers_foreach_ID_link(Object *ob, IDWalkFunc walk, void *user_data)
ModifierData * BKE_modifier_copy_ex(const ModifierData *md, int flag)
void BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
bool BKE_modifiers_persistent_uids_are_valid(const Object &object)
void BKE_modifier_free_ex(ModifierData *md, int flag)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
ModifierData * BKE_modifier_new(int type)
Object * BKE_modifiers_is_deformed_by_armature(Object *ob)
void BKE_modifier_copydata(const ModifierData *md, ModifierData *target)
void multiresModifier_sync_levels_ex(Object *ob_dst, const MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst)
Definition multires.cc:1343
bool multiresModifier_reshapeFromCCG(int tot_level, Mesh *coarse_mesh, SubdivCCG *subdiv_ccg)
General operations, lookup, etc. for blender objects.
eObRelationTypes
@ OB_REL_MOD_ARMATURE
@ OB_REL_PARENT
@ OB_REL_CHILDREN_RECURSIVE
@ OB_REL_PARENT_RECURSIVE
@ OB_REL_CHILDREN
@ OB_VISIBLE_INSTANCES
@ OB_VISIBLE_SELF
@ OB_VISIBLE_PARTICLES
eObjectSet
@ OB_SET_SELECTED
@ OB_SET_VISIBLE
@ OB_SET_ALL
void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
void BKE_sculptsession_free(Object *ob)
Definition paint.cc:2145
void BKE_particle_system_blend_read_data(struct BlendDataReader *reader, struct ListBase *particles)
Definition particle.cc:5353
void BKE_particle_system_blend_read_after_liblink(struct BlendLibReader *reader, struct Object *ob, struct ID *id, struct ListBase *particles)
Definition particle.cc:5441
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit)
Definition particle.cc:904
void BKE_particle_partdeflect_blend_read_data(struct BlendDataReader *reader, struct PartDeflect *pd)
Definition particle.cc:316
void BKE_particle_system_blend_write(struct BlendWriter *writer, struct ListBase *particles)
Definition particle.cc:5308
void psys_free(struct Object *ob, struct ParticleSystem *psys)
Definition particle.cc:975
struct ModifierData * object_copy_particle_system(struct Main *bmain, const struct Scene *scene, struct Object *ob, const struct ParticleSystem *psys_orig)
void BKE_particlesystem_id_loop(struct ParticleSystem *psys, ParticleSystemIDFunc func, void *userdata)
void psys_copy_particles(struct ParticleSystem *psys_dst, struct ParticleSystem *psys_src)
Definition particle.cc:1053
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis)
struct PointCache * BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, int flag)
void BKE_ptcache_blend_read_data(struct BlendDataReader *reader, struct ListBase *ptcaches, struct PointCache **ocache, int force_disk)
void BKE_ptcache_blend_write(struct BlendWriter *writer, struct ListBase *ptcaches)
General operations for point clouds.
void * BKE_pointcloud_add_default(Main *bmain, const char *name)
void BKE_pose_backup_clear(struct Object *ob)
void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
void BKE_previewimg_free(PreviewImage **prv)
void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
void BKE_previewimg_id_copy(ID *new_id, const ID *old_id)
API for Blender-side Rigid Body stuff.
void BKE_rigidbody_free_constraint(struct Object *ob)
Definition rigidbody.cc:197
void BKE_rigidbody_free_object(struct Object *ob, struct RigidBodyWorld *rbw)
Definition rigidbody.cc:146
void BKE_rigidbody_object_copy(struct Main *bmain, struct Object *ob_dst, const struct Object *ob_src, int flag)
void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime)
void BKE_shaderfx_foreach_ID_link(struct Object *ob, ShaderFxIDWalkFunc walk, void *user_data)
Definition shader_fx.cc:240
void BKE_shaderfx_free_ex(struct ShaderFxData *fx, int flag)
Definition shader_fx.cc:90
void BKE_shaderfx_blend_write(struct BlendWriter *writer, struct ListBase *fxbase)
Definition shader_fx.cc:259
struct ShaderFxData * BKE_shaderfx_new(int type)
Definition shader_fx.cc:54
void BKE_shaderfx_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb, struct Object *ob)
Definition shader_fx.cc:275
void BKE_shaderfx_copydata_ex(struct ShaderFxData *fx, struct ShaderFxData *target, int flag)
Definition shader_fx.cc:186
void sbFree(struct Object *ob)
Definition softbody.cc:3168
General operations for speakers.
void * BKE_speaker_add(struct Main *bmain, const char *name)
Definition speaker.cc:81
Volume data-block.
std::optional< blender::Bounds< blender::float3 > > BKE_volume_min_max(const Volume *volume)
void * BKE_volume_add(Main *bmain, const char *name)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
A KD-tree for nearest neighbor search.
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:90
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:269
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:370
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:251
#define BLI_ASSERT_UNIT_M3(m)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void size_to_mat3(float R[3][3], const float size[3])
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void unit_m4(float m[4][4])
Definition rct.c:1127
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize)
void scale_m4_fl(float R[4][4], float scale)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool is_negative_m4(const float mat[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
bool invert_m4(float mat[4][4])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void mul_m4_m4_post(float R[4][4], const float B[4][4])
void quat_to_compatible_eulO(float eul[3], const float oldrot[3], short order, const float quat[4])
float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3])
void invert_qt_normalized(float q[4])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void quat_to_mat3(float m[3][3], const float q[4])
void quat_to_eulO(float e[3], short order, const float q[4])
float normalize_qt(float q[4])
void quat_to_mat4(float m[4][4], const float q[4])
void eulO_to_quat(float q[4], const float e[3], short order)
float normalize_qt_qt(float r[4], const float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
void quat_apply_track(float quat[4], short axis, short upflag)
void eulO_to_mat3(float M[3][3], const float e[3], short order)
void copy_qt_qt(float q[4], const float a[4])
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle)
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define STRNCPY(dst, src)
Definition BLI_string.h:593
unsigned int uint
#define BLI_MUTEX_INITIALIZER
Definition BLI_threads.h:84
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
pthread_mutex_t ThreadMutex
Definition BLI_threads.h:83
#define CLAMP(a, b, c)
#define CLAMP_MAX(a, c)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define POINTER_AS_INT(i)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define CLAMP_MIN(a, b)
Main * BLO_read_lib_get_main(BlendLibReader *reader)
Definition readfile.cc:5160
bool BLO_read_data_is_undo(BlendDataReader *reader)
Definition readfile.cc:5135
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
Definition readfile.cc:4947
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
BlendFileReadReport * BLO_read_lib_reports(BlendLibReader *reader)
Definition readfile.cc:5165
void BLO_read_char_array(BlendDataReader *reader, int array_size, char **ptr_p)
Definition readfile.cc:4929
void BLO_write_char_array(BlendWriter *writer, uint num, const char *data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
void BLO_read_pointer_array(BlendDataReader *reader, int array_size, void **ptr_p)
Definition readfile.cc:5052
#define BLO_read_struct(reader, struct_name, ptr_p)
bool BLO_write_is_undo(BlendWriter *writer)
void BLO_reportf_wrap(BlendFileReadReport *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
external readfile function prototypes.
#define RPT_(msgid)
#define BLT_I18NCONTEXT_ID_ID
#define BLT_I18NCONTEXT_ID_LIGHT
#define BLT_I18NCONTEXT_ID_OBJECT
#define CTX_DATA_(context, msgid)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
void DEG_id_tag_update(ID *id, unsigned int flags)
eEvaluationMode
@ DAG_EVAL_RENDER
@ DAG_EVAL_VIEWPORT
void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags)
bool DEG_is_active(const Depsgraph *depsgraph)
Definition depsgraph.cc:318
float DEG_get_ctime(const Depsgraph *graph)
#define DEG_OBJECT_ITER_BEGIN(settings_, instance_)
#define DEG_OBJECT_ITER_END
bool DEG_is_original_id(const ID *id)
bool DEG_object_geometry_is_evaluated(const Object &object)
Object * DEG_get_original_object(Object *object)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_VISIBLE
@ DEG_ITER_OBJECT_FLAG_DUPLI
#define FILTER_ID_OB
Definition DNA_ID.h:1181
#define FILTER_ID_ALL
Definition DNA_ID.h:1206
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_PSYS_REDO
Definition DNA_ID.h:1048
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_EDITORS
Definition DNA_ID.h:1078
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_RECALC_ALL
Definition DNA_ID.h:1155
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
@ ID_TAG_NEW
Definition DNA_ID.h:865
@ ID_TAG_COPIED_ON_EVAL
Definition DNA_ID.h:964
@ ID_TAG_INDIRECT
Definition DNA_ID.h:794
@ ID_TAG_EXTERN
Definition DNA_ID.h:788
@ ID_TAG_COPIED_ON_EVAL_FINAL_RESULT
Definition DNA_ID.h:974
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
@ ID_TAG_NO_MAIN
Definition DNA_ID.h:945
@ INDEX_ID_OB
Definition DNA_ID.h:1307
@ ID_CA
@ ID_AR
@ ID_VO
@ ID_LA
@ ID_CV
@ ID_LP
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_ME
@ ID_SPK
@ ID_MB
@ ID_LT
@ ID_OB
@ ID_GP
@ ID_PT
@ IDP_TYPE_FILTER_ID
@ ROT_MODE_QUAT
@ ROT_MODE_MAX
@ ROT_MODE_AXISANGLE
@ ROT_MODE_MIN
@ ROT_MODE_EUL
@ POSE_ROT
@ POSE_LOC
@ POSE_SIZE
@ POSE_CONSTRAINTS_NEED_UPDATE_FLAGS
@ POSE_RECALC
@ BONE_RELATIVE_PARENTING
Object groups, one object can be in many groups at once.
@ CONSTRAINT_OFF
@ CONSTRAINT_TYPE_CAMERASOLVER
@ CONSTRAINT_OBTYPE_OBJECT
@ CAMERASOLVER_ACTIVECLIP
@ CU_FOLLOW
@ CU_PATH
@ CU_PATH_RADIUS
@ CU_PATH_CLAMP
@ CD_GRID_PAINT_MASK
#define DNA_struct_default_get(struct_name)
@ EFF_BUILD
@ EFF_WAVE
@ EFF_PARTICLE
#define GPENCIL_EDIT_MODE(gpd)
@ IMA_ANIM_ALWAYS
@ KEY_RELATIVE
@ BASE_FROM_DUPLI
@ BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT
#define ME_EDIT_PAINT_SEL_MODE(_me)
@ eModifierFlag_PinLast
@ eModifierFlag_Active
@ eModifierMode_Render
@ eModifierMode_Realtime
@ MOD_FLUID_TYPE_DOMAIN
@ MOD_FLUID_TYPE_FLOW
@ eParticleSystemFlag_file_loaded
@ eModifierType_ParticleSystem
@ eModifierType_Fluidsim
@ eModifierType_Subsurf
@ eModifierType_Mirror
@ eModifierType_Skin
@ eModifierType_Wave
@ eModifierType_Cloth
@ eModifierType_Fluid
@ eModifierType_MeshSequenceCache
@ eModifierType_Hook
@ eModifierType_Screw
@ eModifierType_Ocean
@ eModifierType_Armature
@ eModifierType_Nodes
@ eModifierType_Collision
@ eModifierType_DynamicPaint
@ eModifierType_MeshCache
@ eModifierType_Array
@ eModifierType_Softbody
@ eModifierType_Multires
@ eModifierType_Build
eObjectMode
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
@ OB_MODE_OBJECT
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ OB_MODE_VERTEX_PAINT
#define OB_MODE_ALL_SCULPT
Object is a sort of wrapper for general info.
@ OB_HIDE_CAMERA
@ OB_SHADOW_CATCHER
@ PARVERT1
@ PARSKEL
@ PAROBJECT
@ PARTYPE
@ PARVERT3
@ PARBONE
@ OB_LOCK_ROT4D
@ OB_LOCK_ROTX
@ OB_LOCK_SCALEX
@ OB_LOCK_ROTW
@ OB_LOCK_LOCX
#define OB_TYPE_SUPPORT_PARVERT(_type)
@ OB_SPEAKER
@ OB_LATTICE
@ OB_MBALL
@ OB_EMPTY
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_CURVES
@ OB_LIGHTPROBE
@ OB_USE_GPENCIL_LIGHTS
#define OB_DATA_SUPPORT_EDITMODE(_type)
@ OB_DUPLI_FLAG_VIEWPORT
@ OB_DUPLI_FLAG_RENDER
@ OB_DUPLI
@ OB_NO_CONSTRAINTS
@ OB_NEG_SCALE
@ OB_NEGZ
@ OB_POSY
@ OB_POSZ
struct Object Object
@ OB_EMPTY_CONE
@ OB_SINGLE_ARROW
@ OB_PLAINAXES
@ OB_ARROWS
@ OB_CIRCLE
@ OB_CUBE
@ OB_EMPTY_IMAGE
@ OB_EMPTY_SPHERE
#define OB_TYPE_SUPPORT_VGROUP(_type)
@ OB_EMPTY_IMAGE_HIDE_FRONT
@ OB_EMPTY_IMAGE_HIDE_NON_AXIS_ALIGNED
@ OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC
@ OB_EMPTY_IMAGE_HIDE_BACK
@ OB_EMPTY_IMAGE_HIDE_PERSPECTIVE
@ PSYS_SHARED_CACHES
@ PTCACHE_IGNORE_CLEAR
@ PTCACHE_BAKED
@ PTCACHE_FLAG_INFO_DIRTY
@ PTCACHE_OUTDATED
@ PTCACHE_DISK_CACHE
Types and defines for representing Rigid Body entities.
#define BASE_SELECTED(v3d, base)
#define BASE_SELECTED_EDITABLE(v3d, base)
#define BASE_EDITABLE(v3d, base)
@ SCE_SELECT_VERTEX
#define BASE_VISIBLE(v3d, base)
eDupli_ID_Flags
@ USER_DUP_MAT
@ USER_DUP_SURF
@ USER_DUP_LIGHTPROBE
@ USER_DUP_MBALL
@ USER_DUP_LINKED_ID
@ USER_DUP_CURVE
@ USER_DUP_CAMERA
@ USER_DUP_VOLUME
@ USER_DUP_SPEAKER
@ USER_DUP_PSYS
@ USER_DUP_GPENCIL
@ USER_DUP_CURVES
@ USER_DUP_LAMP
@ USER_DUP_ARM
@ USER_DUP_MESH
@ USER_DUP_POINTCLOUD
@ USER_DUP_FONT
@ USER_DUP_LATTICE
void DRW_drawdata_free(ID *id)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
void BKE_object_matrix_local_get(Object *ob, float r_mat[4][4])
static void ob_parvert3(const Object *ob, const Object *par, float r_mat[4][4])
void BKE_object_where_is_calc_mat4(const Object *ob, float r_obmat[4][4])
bool BKE_object_obdata_texspace_get(Object *ob, char **r_texspace_flag, float **r_texspace_location, float **r_texspace_size)
static void object_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
static void object_blend_write(BlendWriter *writer, ID *id, const void *id_address)
void BKE_object_to_mesh_clear(Object *object)
void BKE_object_groups_clear(Main *bmain, Scene *scene, Object *ob)
void BKE_object_empty_draw_type_set(Object *ob, const int value)
bool BKE_object_is_libdata(const Object *ob)
void BKE_object_to_curve_clear(Object *object)
bool BKE_object_has_mode_data(const Object *ob, eObjectMode object_mode)
static void library_foreach_modifiersForeachIDLink(void *user_data, Object *, ID **id_pointer, int cb_flag)
static KeyBlock * insert_curvekey(Main *bmain, Object *ob, const char *name, const bool from_mix)
Vector< Object * > BKE_object_pose_array_get_unique(const Scene *scene, ViewLayer *view_layer, View3D *v3d)
static IDProperty * object_asset_dimensions_property(Object *ob)
const Mesh * BKE_object_get_editmesh_eval_cage(const Object *object)
blender::float4x4 BKE_object_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *ob)
bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update_mesh, int parent_recursion, float frame, int type)
static Object * object_add_common(Main *bmain, const Scene *scene, ViewLayer *view_layer, int type, const char *name)
KDTree_3d * BKE_object_as_kdtree(Object *ob, int *r_tot)
static void object_blend_read_after_liblink(BlendLibReader *reader, ID *id)
bool BKE_object_flag_test_recursive(const Object *ob, short flag)
#define TFMCPY4D(_v)
void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src, const int flag)
LinkNode * BKE_object_relational_superset(const Scene *scene, ViewLayer *view_layer, eObjectSet objectSet, eObRelationTypes includeFilter)
void BKE_object_sculpt_data_create(Object *ob)
void BKE_object_modifier_set_active(Object *ob, ModifierData *md)
PartEff * BKE_object_do_version_give_parteff_245(Object *ob)
MovieClip * BKE_object_movieclip_get(Scene *scene, const Object *ob, bool use_default)
void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
static void object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime, RigidBodyWorld *rbw, float r_originmat[3][3])
Vector< Base * > BKE_object_pose_base_array_get_unique(const Scene *scene, ViewLayer *view_layer, View3D *v3d)
void BKE_object_dimensions_get(Object *ob, float r_vec[3])
bool BKE_object_is_in_editmode(const Object *ob)
bool BKE_object_exists_check(Main *bmain, const Object *obtest)
void BKE_object_handle_update_ex(Depsgraph *depsgraph, Scene *scene, Object *ob, RigidBodyWorld *rbw)
Vector< Base * > BKE_object_pose_base_array_get(const Scene *scene, ViewLayer *view_layer, View3D *v3d)
static KeyBlock * insert_lattkey(Main *bmain, Object *ob, const char *name, const bool from_mix)
static bool ob_parcurve(const Object *ob, Object *par, float r_mat[4][4])
#define TFMCPY3D(_v)
static bool object_modifier_type_copy_check(ModifierType md_type)
static void object_init(Object *ob, const short ob_type)
void BKE_object_scale_to_mat3(const Object *ob, float mat[3][3])
void BKE_object_update_select_id(Main *bmain)
Object * BKE_object_add_from(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name, Object *ob_src)
int BKE_object_obdata_to_type(const ID *id)
void BKE_object_check_uids_unique_and_report(const Object *object)
void BKE_object_dimensions_set(Object *ob, const float value[3], int axis_mask)
void BKE_object_tfm_protected_backup(const Object *ob, ObjectTfmProtectedChannels *obtfm)
static void object_copy_data(Main *bmain, std::optional< Library * >, ID *id_dst, const ID *id_src, const int flag)
void BKE_object_replace_data_on_shallow_copy(Object *ob, ID *new_data)
void BKE_object_workob_clear(Object *workob)
static void object_lib_override_apply_post(ID *id_dst, ID *id_src)
std::optional< Bounds< float3 > > BKE_object_boundbox_eval_cached_get(const Object *ob)
void BKE_object_get_parent_matrix(const Object *ob, Object *par, float r_parentmat[4][4])
static void object_foreach_path(ID *id, BPathForeachPathData *bpath_data)
bool BKE_object_minmax_empty_drawtype(const Object *ob, float r_min[3], float r_max[3])
static AssetTypeInfo AssetType_OB
void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const int flag)
bool BKE_object_supports_modifiers(const Object *ob)
void * BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
char * BKE_object_data_editmode_flush_ptr_get(ID *id)
void BKE_object_runtime_reset(Object *object)
void BKE_object_tfm_copy(Object *object_dst, const Object *object_src)
static void give_parvert(const Object *par, int nr, float vec[3])
static void object_update_from_subsurf_ccg(Object *object)
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name)
Object * BKE_object_add(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
bool BKE_object_pose_context_check(const Object *ob)
static int pc_cmp(const void *a, const void *b)
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
static void library_foreach_constraintObjectLooper(bConstraint *, ID **id_pointer, bool is_reference, void *user_data)
Object * BKE_object_add_for_data(Main *bmain, const Scene *scene, ViewLayer *view_layer, int type, const char *name, ID *data, bool do_id_user)
void BKE_scene_foreach_display_point(Depsgraph *depsgraph, void(*func_cb)(const float[3], void *), void *user_data)
bool BKE_object_shapekey_free(Main *bmain, Object *ob)
static Object * obrel_armature_find(Object *ob)
int BKE_object_is_deform_modified(Scene *scene, Object *ob)
static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data, Object *, ID **id_pointer, int cb_flag)
void BKE_object_apply_mat4(Object *ob, const float mat[4][4], const bool use_compat, const bool use_parent)
int BKE_object_insert_ptcache(Object *ob)
static void ob_parbone(const Object *ob, const Object *par, float r_mat[4][4])
static void object_cacheIgnoreClear(Object *ob, int state)
bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
static ParticleSystem * object_copy_modifier_particle_system_ensure(Main *bmain, const Scene *scene, Object *ob_dst, ParticleSystem *psys_src)
int BKE_object_scenes_users_get(Main *bmain, Object *ob)
bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb)
static KeyBlock * insert_meshkey(Main *bmain, Object *ob, const char *name, const bool from_mix)
Object * BKE_object_pose_armature_get(Object *ob)
void BKE_object_free_modifiers(Object *ob, const int flag)
static bool modifiers_has_animation_check(const Object *ob)
void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd)
void BKE_object_dimensions_set_ex(Object *ob, const float value[3], int axis_mask, const float ob_scale_orig[3], const float ob_obmat_orig[4][4])
const Mesh * BKE_object_get_mesh_deform_eval(const Object *object)
void BKE_object_runtime_free_data(Object *object)
static void solve_parenting(const Object *ob, Object *par, const bool set_origin, float r_obmat[4][4], float r_originmat[3][3])
blender::Vector< Base * > BKE_object_pose_base_array_get_ex(const Scene *scene, ViewLayer *view_layer, View3D *v3d, bool unique)
void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3])
bool BKE_object_supports_material_slots(Object *ob)
bool BKE_object_obdata_is_libdata(const Object *ob)
static void copy_object_pose(Object *obn, const Object *ob, const int flag)
static void object_blend_read_data(BlendDataReader *reader, ID *id)
static bool object_moves_in_time(const Object *object)
ModifierData * BKE_object_active_modifier(const Object *ob)
SubsurfModifierData * BKE_object_get_last_subsurf_modifier(const Object *ob)
void BKE_object_free_particlesystems(Object *ob)
void BKE_object_free_curve_cache(Object *ob)
void BKE_object_obdata_size_init(Object *ob, const float size)
void BKE_object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
bool BKE_object_data_is_in_editmode(const Object *ob, const ID *id)
void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)
static void object_init_data(ID *id)
static void direct_link_nlastrips(BlendDataReader *reader, ListBase *strips)
Object * BKE_object_pose_armature_get_with_wpaint_check(Object *ob)
bool BKE_object_is_mode_compat(const Object *ob, eObjectMode object_mode)
void BKE_object_runtime_reset_on_copy(Object *object, const int)
void BKE_boundbox_minmax(const BoundBox *bb, const float obmat[4][4], float r_min[3], float r_max[3])
void BKE_object_foreach_display_point(Object *ob, const float obmat[4][4], void(*func_cb)(const float[3], void *), void *user_data)
Mesh * BKE_object_to_mesh(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
void BKE_object_apply_mat4_ex(Object *ob, const float mat[4][4], Object *parent, const float parentinv[4][4], const bool use_compat)
void BKE_object_link_modifiers(Object *ob_dst, const Object *ob_src)
Vector< Object * > BKE_object_pose_array_get(const Scene *scene, ViewLayer *view_layer, View3D *v3d)
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
Vector< Object * > BKE_object_pose_array_get_ex(const Scene *scene, ViewLayer *view_layer, View3D *v3d, bool unique)
bool BKE_object_is_child_recursive(const Object *ob_parent, const Object *ob_child)
Object * BKE_object_duplicate(Main *bmain, Object *ob, eDupli_ID_Flags dupflag, uint duplicate_options)
static int pc_findindex(ListBase *listbase, int index)
void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3])
Mesh * BKE_object_get_evaluated_mesh_no_subsurf_unchecked(const Object *object)
Mesh * BKE_object_get_pre_modified_mesh(const Object *object)
bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
bool BKE_object_modifier_stack_copy(Object *ob_dst, const Object *ob_src, const bool do_copy_all, const int flag_subdata)
IDTypeInfo IDType_ID_OB
bool BKE_object_empty_image_frame_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
Mesh * BKE_object_get_evaluated_mesh_no_subsurf(const Object *object)
KeyBlock * BKE_object_shapekey_insert(Main *bmain, Object *ob, const char *name, const bool from_mix)
bool BKE_object_copy_modifier(Main *bmain, const Scene *scene, Object *ob_dst, const Object *ob_src, const ModifierData *md_src)
int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
static CLG_LogRef LOG
Lattice * BKE_object_get_lattice(const Object *object)
void BKE_object_modifier_gpencil_hook_reset(Object *ob, HookGpencilModifierData *hmd)
bool BKE_object_is_in_wpaint_select_vert(const Object *ob)
void BKE_object_apply_parent_inverse(Object *ob)
std::optional< blender::Bounds< blender::float3 > > BKE_object_boundbox_get(const Object *ob)
Mesh * BKE_object_get_evaluated_mesh_unchecked(const Object *object_eval)
Mesh * BKE_object_get_original_mesh(const Object *object)
void BKE_object_to_mat4(const Object *ob, float r_mat[4][4])
Curve * BKE_object_to_curve(Object *object, Depsgraph *depsgraph, bool apply_modifiers)
Lattice * BKE_object_get_evaluated_lattice(const Object *object)
static bool constructive_modifier_is_deform_modified(Object *ob, ModifierData *md)
void BKE_object_eval_assign_data(Object *object_eval, ID *data_eval, bool is_owned)
void * BKE_object_tfm_backup(Object *ob)
void BKE_object_tfm_protected_restore(Object *ob, const ObjectTfmProtectedChannels *obtfm, const short protectflag)
static bool object_deforms_in_time(Object *object)
Object * BKE_object_pose_armature_get_visible(Object *ob, const Scene *scene, ViewLayer *view_layer, View3D *v3d)
static void object_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
void BKE_object_to_mat3(const Object *ob, float r_mat[3][3])
void BKE_object_handle_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
static const char * get_obdata_defname(int type)
void BKE_object_delete_ptcache(Object *ob, int index)
void BKE_object_dimensions_eval_cached_get(Object *ob, float r_vec[3])
void BKE_object_free_caches(Object *object)
bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
static void object_foreach_id(ID *id, LibraryForeachIDData *data)
LinkNode * BKE_object_groups(Main *bmain, Scene *scene, Object *ob)
static void library_foreach_shaderfxForeachIDLink(void *user_data, Object *, ID **id_pointer, int cb_flag)
static float3 boundbox_to_dimensions(const Object *ob, const std::optional< Bounds< float3 > > bounds)
void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
bool BKE_object_is_in_editmode_vgroup(const Object *ob)
#define TFMCPY(_v)
static void copy_ccg_data(Mesh *mesh_destination, Mesh *mesh_source, const eCustomDataType layer_type)
bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
static void object_free_data(ID *id)
void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
void BKE_object_rot_to_mat3(const Object *ob, float mat[3][3], bool use_drot)
int BKE_object_is_modified(Scene *scene, Object *ob)
ParticleSystem * BKE_object_copy_particlesystem(ParticleSystem *psys, const int flag)
static bool obrel_list_test(Object *ob)
static void obrel_list_add(LinkNode **links, Object *ob)
void BKE_object_free_derived_caches(Object *ob)
static void library_foreach_particlesystemsObjectLooper(ParticleSystem *, ID **id_pointer, void *user_data, int cb_flag)
void BKE_object_free_softbody(Object *ob)
std::optional< Bounds< float3 > > BKE_object_evaluated_geometry_bounds(const Object *ob)
static void object_foreach_path_pointcache(ListBase *ptcache_list, BPathForeachPathData *bpath_data)
bool BKE_object_minmax_dupli(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_min[3], float r_max[3], const bool use_hidden)
void BKE_object_free_shaderfx(Object *ob, const int flag)
static ThreadMutex vparent_lock
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
#define BM_VERT
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
constexpr int64_t size() const
Definition BLI_span.hh:253
local_group_size(16, 16) .push_constant(Type b
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define printf
const Depsgraph * depsgraph
#define copysignf(x, y)
int len
KDTree_3d * tree
draw_view in_light_buf[] float
#define rot(x, k)
int count
#define GS(x)
Definition iris.cc:202
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
static ulong * next
static ulong state[N]
#define G(x, y, z)
Vector< FCurve * > fcurves_for_assigned_action(AnimData *adt)
bool object_has_geometry_set_instances(const Object &object)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
const btScalar eps
Definition poly34.cpp:11
#define min(a, b)
Definition sort.c:32
bAction * action
ListBase drivers
struct Object * start_cap
struct Object * offset_ob
struct Object * curve_ob
struct Object * end_cap
The meta-data of an asset. By creating and giving this for a data-block (ID.asset_data),...
float co[3]
int totvert
char elem_table_dirty
float vec[4]
struct Object * object
float vec[3][3]
struct BlendFileReadReport::@128 count
int * springs
float vec[8][3]
float drawsize
struct ListBase ptcaches
struct PointCache * point_cache
struct AnimData * adt
char texspace_flag
struct Key * key
ListBase nurb
float fsize
float ctime
float texspace_size[3]
float texspace_location[3]
struct Object * taperobj
float * verts
struct DynamicPaintCanvasSettings * canvas
struct DynamicPaintBrushSettings * brush
char needs_flush_to_id
Definition BKE_vfont.hh:65
char needs_flush_to_id
struct Lattice * latt
char needs_flush_to_id
struct ParticleSystem * psys
struct FluidDomainSettings * domain
struct FluidFlowSettings * flow
struct FluidsimSettings * fss
struct Object * object
Definition DNA_ID.h:413
unsigned int recalc
Definition DNA_ID.h:437
void * py_instance
Definition DNA_ID.h:482
int tag
Definition DNA_ID.h:434
struct Library * lib
Definition DNA_ID.h:419
struct ID * newid
Definition DNA_ID.h:417
void * next
Definition DNA_ID.h:416
char name[66]
Definition DNA_ID.h:425
struct ID_Runtime runtime
Definition DNA_ID.h:492
void * data
int totkey
char type
ListBase block
KeyBlock * refkey
struct Key * key
struct EditLatt * editlatt
struct BPoint * def
struct Collection * collection
char filepath[1024]
Definition DNA_ID.h:531
float area_sizez
float area_sizey
float radius
float area_size
void * data
struct LinkData * next
void * last
void * first
ListBase scenes
Definition BKE_main.hh:210
ListBase objects
Definition BKE_main.hh:212
int corners_num
MeshRuntimeHandle * runtime
CustomData corner_data
CustomData vert_data
int verts_num
char texspace_flag
float texspace_size[3]
float texspace_location[3]
char needs_flush_to_id
struct Object * mirror_ob
struct ModifierData * next
struct ModifierData * prev
void(* modify_geometry_set)(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
ModifierTypeFlag flags
ModifierTypeType type
struct Nurb * next
BezTriple * bezt
BPoint * bp
struct Object * parent
float cent[3]
float parentinv[4][4]
ListBase particlesystem
struct Object * track
short transflag
ListBase constraints
short base_flag
struct bPose * pose
struct LightProbeObjectCache * lightprobe_cache
ObjectRuntimeHandle * runtime
float drot[3]
ListBase modifiers
float dquat[4]
struct RigidBodyOb * rigidbody_object
float constinv[4][4]
ListBase greasepencil_modifiers
struct PreviewImage * preview
struct Material ** mat
float loc[3]
char * matbits
struct PartDeflect * pd
float dloc[3]
float scale[3]
struct SoftBody * soft
float rot[3]
float parentinv[4][4]
char empty_drawtype
ListBase shader_fx
ImageUser * iuser
short visibility_flag
float drotAxis[3]
float empty_drawsize
bMotionPath * mpath
float quat[4]
LightLinking * light_linking
ListBase pc_ids
float rotAxis[3]
float drotAngle
struct AnimData * adt
float dscale[3]
struct DrawDataList drawdata
struct Object * parent
short trackflag
char duplicator_visibility_flag
struct SculptSession * sculpt
struct RigidBodyCon * rigidbody_constraint
struct LightgroupMembership * lightgroup
char parsubstr[64]
char empty_image_visibility_flag
bAnimVizSettings avs
float ima_ofs[2]
unsigned int data_types
unsigned int info_types
unsigned int type
struct ListBase * ptcaches
unsigned int flag
unsigned int default_step
unsigned int file_type
unsigned int max_step
struct PTCacheID * next
Particle * keys
struct PartEff * next
struct Collection * group
struct ParticleSystem * psys
struct PTCacheEdit * edit
struct ListBase ptcaches
struct ListBase targets
ParticleSettings * part
struct ListBase * effectors
struct PointCache * pointcache
struct BVHTree * bvhtree
struct ClothModifierData * clmd
struct ParticleCacheKey ** childcache
struct Mesh * hair_in_mesh
struct KDTree_3d * tree
struct Mesh * hair_out_mesh
struct ParticleDrawData * pdd
struct ParticleCacheKey ** pathcache
struct PointCache * next
float viewinv[4][4]
struct RigidBodyOb_Shared * shared
struct Object * ob_axis
eObjectMode mode_type
Definition BKE_paint.hh:487
struct PointCache * pointcache
struct SoftBody_Shared * shared
struct EffectorWeights * effector_weights
struct BodySpring * bspring
struct SBScratch * scratch
struct BodyPoint * bpoint
struct SubdivCCG::@64 dirty
struct AnimData * adt
struct bConstraint * next
struct Bone * bone
float chan_mat[4][4]
float pose_mat[4][4]
ListBase chanbase
const Mesh * get_mesh() const
Array< float3x3, 0 > crazyspace_deform_imats
Array< float3, 0 > crazyspace_deform_cos
void recalc_data(TransInfo *t)
float max
ccl_device_inline int mod(int x, int m)
Definition util/math.h:520
#define N_(msgid)
uint8_t flag
Definition wm_window.cc:138