Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/object.c')
-rw-r--r--source/blender/blenkernel/intern/object.c932
1 files changed, 519 insertions, 413 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index eeb0ab22bd6..af963d784ec 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -58,7 +58,7 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
-#include "DNA_property_types.h"
+#include "DNA_lightprobe_types.h"
#include "DNA_rigidbody_types.h"
#include "BLI_blenlib.h"
@@ -76,21 +76,20 @@
#include "BKE_idprop.h"
#include "BKE_armature.h"
#include "BKE_action.h"
-#include "BKE_bullet.h"
#include "BKE_deform.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_animsys.h"
#include "BKE_anim.h"
+#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
-#include "BKE_group.h"
#include "BKE_icons.h"
#include "BKE_key.h"
#include "BKE_lamp.h"
+#include "BKE_layer.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -103,12 +102,12 @@
#include "BKE_multires.h"
#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_object_facemap.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
-#include "BKE_property.h"
+#include "BKE_lightprobe.h"
#include "BKE_rigidbody.h"
-#include "BKE_sca.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_speaker.h"
@@ -118,6 +117,11 @@
#include "BKE_camera.h"
#include "BKE_image.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "DRW_engine.h"
+
#ifdef WITH_MOD_FLUID
#include "LBM_fluidsim.h"
#endif
@@ -129,8 +133,6 @@
#include "CCGSubSurf.h"
#include "atomic_ops.h"
-#include "GPU_material.h"
-
/* Vertex parent modifies original BMesh which is not safe for threading.
* Ideally such a modification should be handled as a separate DAG update
* callback for mesh datablock, but for until it is actually supported use
@@ -152,16 +154,6 @@ void BKE_object_workob_clear(Object *workob)
workob->rotmode = ROT_MODE_EUL;
}
-void BKE_object_update_base_layer(struct Scene *scene, Object *ob)
-{
- Base *base = scene->base.first;
-
- while (base) {
- if (base->object == ob) base->lay = ob->lay;
- base = base->next;
- }
-}
-
void BKE_object_free_particlesystems(Object *ob)
{
ParticleSystem *psys;
@@ -179,14 +171,6 @@ void BKE_object_free_softbody(Object *ob)
}
}
-void BKE_object_free_bulletsoftbody(Object *ob)
-{
- if (ob->bsoft) {
- bsbFree(ob->bsoft);
- ob->bsoft = NULL;
- }
-}
-
void BKE_object_free_curve_cache(Object *ob)
{
if (ob->curve_cache) {
@@ -265,7 +249,7 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
return true;
}
-void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src)
+void BKE_object_link_modifiers(Scene *scene, struct Object *ob_dst, const struct Object *ob_src)
{
ModifierData *md;
BKE_object_free_modifiers(ob_dst, 0);
@@ -304,7 +288,7 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
if (md->type == eModifierType_Multires) {
/* Has to be done after mod creation, but *before* we actually copy its settings! */
- multiresModifier_sync_levels_ex(ob_dst, (MultiresModifierData *)md, (MultiresModifierData *)nmd);
+ multiresModifier_sync_levels_ex(scene, ob_dst, (MultiresModifierData *)md, (MultiresModifierData *)nmd);
}
modifier_copyData(md, nmd);
@@ -346,6 +330,34 @@ void BKE_object_free_derived_caches(Object *ob)
ob->bb = NULL;
}
+ BKE_object_free_derived_mesh_caches(ob);
+
+ if (ob->runtime.mesh_eval != NULL) {
+ Mesh *mesh_eval = ob->runtime.mesh_eval;
+ /* Restore initial pointer. */
+ if (ob->data == mesh_eval) {
+ ob->data = ob->runtime.mesh_orig;
+ }
+ /* Evaluated mesh points to edit mesh, but does not own it. */
+ mesh_eval->edit_btmesh = NULL;
+ BKE_mesh_free(mesh_eval);
+ BKE_libblock_free_data(&mesh_eval->id, false);
+ MEM_freeN(mesh_eval);
+ ob->runtime.mesh_eval = NULL;
+ }
+ if (ob->runtime.mesh_deform_eval != NULL) {
+ Mesh *mesh_deform_eval = ob->runtime.mesh_deform_eval;
+ BKE_mesh_free(mesh_deform_eval);
+ BKE_libblock_free_data(&mesh_deform_eval->id, false);
+ MEM_freeN(mesh_deform_eval);
+ ob->runtime.mesh_deform_eval = NULL;
+ }
+
+ BKE_object_free_curve_cache(ob);
+}
+
+void BKE_object_free_derived_mesh_caches(struct Object *ob)
+{
if (ob->derivedFinal) {
ob->derivedFinal->needsFree = 1;
ob->derivedFinal->release(ob->derivedFinal);
@@ -356,8 +368,6 @@ void BKE_object_free_derived_caches(Object *ob)
ob->derivedDeform->release(ob->derivedDeform);
ob->derivedDeform = NULL;
}
-
- BKE_object_free_curve_cache(ob);
}
void BKE_object_free_caches(Object *object)
@@ -381,14 +391,12 @@ void BKE_object_free_caches(Object *object)
for (md = object->modifiers.first; md != NULL; md = md->next) {
if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- if (psmd->dm_final != NULL) {
- psmd->dm_final->needsFree = 1;
- psmd->dm_final->release(psmd->dm_final);
- psmd->dm_final = NULL;
- if (psmd->dm_deformed != NULL) {
- psmd->dm_deformed->needsFree = 1;
- psmd->dm_deformed->release(psmd->dm_deformed);
- psmd->dm_deformed = NULL;
+ if (psmd->mesh_final) {
+ BKE_id_free(NULL, psmd->mesh_final);
+ psmd->mesh_final = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
psmd->flag |= eParticleSystemFlag_file_loaded;
update_flag |= OB_RECALC_DATA;
@@ -401,7 +409,7 @@ void BKE_object_free_caches(Object *object)
* guaranteed to be in a known state.
*/
if (update_flag != 0) {
- DAG_id_tag_update(&object->id, update_flag);
+ DEG_id_tag_update(&object->id, update_flag);
}
}
@@ -419,6 +427,7 @@ void BKE_object_free(Object *ob)
MEM_SAFE_FREE(ob->bb);
BLI_freelistN(&ob->defbase);
+ BLI_freelistN(&ob->fmaps);
if (ob->pose) {
BKE_pose_free_ex(ob->pose, false);
ob->pose = NULL;
@@ -427,11 +436,6 @@ void BKE_object_free(Object *ob)
animviz_free_motionpath(ob->mpath);
ob->mpath = NULL;
}
- BKE_bproperty_free_list(&ob->prop);
-
- free_sensors(&ob->sensors);
- free_controllers(&ob->controllers);
- free_actuators(&ob->actuators);
BKE_constraints_free_ex(&ob->constraints, false);
@@ -443,11 +447,13 @@ void BKE_object_free(Object *ob)
sbFree(ob->soft);
ob->soft = NULL;
}
- if (ob->bsoft) {
- bsbFree(ob->bsoft);
- ob->bsoft = NULL;
+
+ for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
+ if (oed->free != NULL) {
+ oed->free(oed);
+ }
}
- GPU_lamp_free(ob);
+ BLI_freelistN(&ob->drawdata);
BKE_sculptsession_free(ob);
@@ -517,6 +523,30 @@ bool BKE_object_is_in_editmode_vgroup(const Object *ob)
BKE_object_is_in_editmode(ob));
}
+bool BKE_object_data_is_in_editmode(const ID *id)
+{
+ const short type = GS(id->name);
+ BLI_assert(OB_DATA_SUPPORT_EDITMODE(type));
+ switch (type) {
+ case ID_ME:
+ return ((const Mesh *)id)->edit_btmesh != NULL;
+ case ID_CU:
+ return (
+ (((const Curve *)id)->editnurb != NULL) ||
+ (((const Curve *)id)->editfont != NULL)
+ );
+ case ID_MB:
+ return ((const MetaBall *)id)->editelems != NULL;
+ case ID_LT:
+ return ((const Lattice *)id)->editlatt != NULL;
+ case ID_AR:
+ return ((const bArmature *)id)->edbo != NULL;
+ default:
+ BLI_assert(0);
+ return false;
+ }
+}
+
bool BKE_object_is_in_wpaint_select_vert(const Object *ob)
{
if (ob->type == OB_MESH) {
@@ -529,6 +559,72 @@ bool BKE_object_is_in_wpaint_select_vert(const Object *ob)
return false;
}
+bool BKE_object_has_mode_data(const struct Object *ob, eObjectMode object_mode)
+{
+ if (object_mode & OB_MODE_EDIT) {
+ if (BKE_object_is_in_editmode(ob)) {
+ return true;
+ }
+ }
+ else if (object_mode & OB_MODE_VERTEX_PAINT) {
+ if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) {
+ return true;
+ }
+ }
+ else if (object_mode & OB_MODE_WEIGHT_PAINT) {
+ if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) {
+ return true;
+ }
+ }
+ else if (object_mode & OB_MODE_SCULPT) {
+ if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) {
+ return true;
+ }
+ }
+ else if (object_mode & OB_MODE_POSE) {
+ if (ob->pose != NULL) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
+{
+ return ((ob->mode == object_mode) ||
+ (ob->mode & object_mode) != 0);
+}
+
+/**
+ * Return if the object is visible, as evaluated by depsgraph
+ */
+bool BKE_object_is_visible(Object *ob, const eObjectVisibilityCheck mode)
+{
+ if ((ob->base_flag & BASE_VISIBLED) == 0) {
+ return false;
+ }
+
+ if (mode == OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) {
+ return true;
+ }
+
+ if (((ob->transflag & OB_DUPLI) == 0) &&
+ (ob->particlesystem.first == NULL))
+ {
+ return true;
+ }
+
+ switch (mode) {
+ case OB_VISIBILITY_CHECK_FOR_VIEWPORT:
+ return ((ob->duplicator_visibility_flag & OB_DUPLI_FLAG_VIEWPORT) != 0);
+ case OB_VISIBILITY_CHECK_FOR_RENDER:
+ return ((ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER) != 0);
+ default:
+ BLI_assert(!"Object visible test mode not supported.");
+ return false;
+ }
+}
+
bool BKE_object_exists_check(Main *bmain, const Object *obtest)
{
Object *ob;
@@ -582,6 +678,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
case OB_LATTICE: return BKE_lattice_add(bmain, name);
case OB_ARMATURE: return BKE_armature_add(bmain, name);
case OB_SPEAKER: return BKE_speaker_add(bmain, name);
+ case OB_LIGHTPROBE:return BKE_lightprobe_add(bmain, name);
case OB_EMPTY: return NULL;
default:
printf("%s: Internal error, bad type: %d\n", __func__, type);
@@ -633,26 +730,10 @@ void BKE_object_init(Object *ob)
ob->dupsta = 1; ob->dupend = 100;
ob->dupfacesca = 1.0;
- /* Game engine defaults*/
- ob->mass = ob->inertia = 1.0f;
- ob->formfactor = 0.4f;
- ob->damping = 0.04f;
- ob->rdamping = 0.1f;
- ob->anisotropicFriction[0] = 1.0f;
- ob->anisotropicFriction[1] = 1.0f;
- ob->anisotropicFriction[2] = 1.0f;
- ob->gameflag = OB_PROP | OB_COLLISION;
- ob->margin = 0.04f;
- ob->init_state = 1;
- ob->state = 1;
- ob->obstacleRad = 1.0f;
- ob->step_height = 0.15f;
- ob->jump_speed = 10.0f;
- ob->fall_speed = 55.0f;
- ob->max_jumps = 1;
ob->col_group = 0x01;
ob->col_mask = 0xffff;
ob->preview = NULL;
+ ob->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT | OB_DUPLI_FLAG_RENDER;
/* NT fluid sim defaults */
ob->fluidsimSettings = NULL;
@@ -661,6 +742,8 @@ void BKE_object_init(Object *ob)
/* Animation Visualization defaults */
animviz_settings_init(&ob->avs);
+
+ ob->display.flag = OB_SHOW_SHADOW;
}
/* more general add: creates minimum required data, but without vertices etc. */
@@ -673,6 +756,9 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
ob = BKE_libblock_alloc(bmain, ID_OB, name, 0);
+ /* We increase object user count when linking to Collections. */
+ id_us_min(&ob->id);
+
/* default object vars */
ob->type = type;
@@ -681,163 +767,66 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
return ob;
}
-/* general add: to scene, with layer from area and default name */
-/* creates minimum required data, but without vertices etc. */
-Object *BKE_object_add(
- Main *bmain, Scene *scene,
- int type, const char *name)
+
+static Object *object_add_common(Main *bmain, ViewLayer *view_layer, int type, const char *name)
{
Object *ob;
- Base *base;
ob = BKE_object_add_only_object(bmain, type, name);
-
ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
+ BKE_view_layer_base_deselect_all(view_layer);
- ob->lay = scene->lay;
-
- base = BKE_scene_base_add(scene, ob);
- BKE_scene_base_deselect_all(scene);
- BKE_scene_base_select(scene, base);
- DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
-
+ DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
-
-#ifdef WITH_GAMEENGINE
-
-void BKE_object_lod_add(Object *ob)
-{
- LodLevel *lod = MEM_callocN(sizeof(LodLevel), "LoD Level");
- LodLevel *last = ob->lodlevels.last;
-
- /* If the lod list is empty, initialize it with the base lod level */
- if (!last) {
- LodLevel *base = MEM_callocN(sizeof(LodLevel), "Base LoD Level");
- BLI_addtail(&ob->lodlevels, base);
- base->flags = OB_LOD_USE_MESH | OB_LOD_USE_MAT;
- base->source = ob;
- base->obhysteresis = 10;
- last = ob->currentlod = base;
- }
-
- lod->distance = last->distance + 25.0f;
- lod->obhysteresis = 10;
- lod->flags = OB_LOD_USE_MESH | OB_LOD_USE_MAT;
-
- BLI_addtail(&ob->lodlevels, lod);
-}
-
-static int lod_cmp(const void *a, const void *b)
-{
- const LodLevel *loda = a;
- const LodLevel *lodb = b;
-
- if (loda->distance < lodb->distance) return -1;
- return loda->distance > lodb->distance;
-}
-
-void BKE_object_lod_sort(Object *ob)
-{
- BLI_listbase_sort(&ob->lodlevels, lod_cmp);
-}
-
-bool BKE_object_lod_remove(Object *ob, int level)
-{
- LodLevel *rem;
-
- if (level < 1 || level > BLI_listbase_count(&ob->lodlevels) - 1)
- return false;
-
- rem = BLI_findlink(&ob->lodlevels, level);
-
- if (rem == ob->currentlod) {
- ob->currentlod = rem->prev;
- }
-
- BLI_remlink(&ob->lodlevels, rem);
- MEM_freeN(rem);
-
- /* If there are no user defined lods, remove the base lod as well */
- if (BLI_listbase_is_single(&ob->lodlevels)) {
- LodLevel *base = ob->lodlevels.first;
- BLI_remlink(&ob->lodlevels, base);
- MEM_freeN(base);
- ob->currentlod = NULL;
- }
-
- return true;
-}
-
-static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
+/**
+ * General add: to scene, with layer from area and default name
+ *
+ * Object is added to the active Collection.
+ * If there is no linked collection to the active ViewLayer we create a new one.
+ */
+/* creates minimum required data, but without vertices etc. */
+Object *BKE_object_add(
+ Main *bmain, Scene *UNUSED(scene), ViewLayer *view_layer,
+ int type, const char *name)
{
- LodLevel *current = ob->currentlod;
- float dist_sq;
-
- if (!current) return NULL;
+ Object *ob;
+ Base *base;
+ LayerCollection *layer_collection;
- dist_sq = len_squared_v3v3(ob->obmat[3], camera_position);
+ ob = object_add_common(bmain, view_layer, type, name);
- if (dist_sq < SQUARE(current->distance)) {
- /* check for higher LoD */
- while (current->prev && dist_sq < SQUARE(current->distance)) {
- current = current->prev;
- }
- }
- else {
- /* check for lower LoD */
- while (current->next && dist_sq > SQUARE(current->next->distance)) {
- current = current->next;
- }
- }
+ layer_collection = BKE_layer_collection_get_active(view_layer);
+ BKE_collection_object_add(bmain, layer_collection->collection, ob);
- return current;
-}
+ base = BKE_view_layer_base_find(view_layer, ob);
+ BKE_view_layer_base_select(view_layer, base);
-bool BKE_object_lod_is_usable(Object *ob, Scene *scene)
-{
- bool active = (scene) ? ob == OBACT : false;
- return (ob->mode == OB_MODE_OBJECT || !active);
-}
-
-void BKE_object_lod_update(Object *ob, const float camera_position[3])
-{
- LodLevel *cur_level = ob->currentlod;
- LodLevel *new_level = lod_level_select(ob, camera_position);
-
- if (new_level != cur_level) {
- ob->currentlod = new_level;
- }
+ return ob;
}
-static Object *lod_ob_get(Object *ob, Scene *scene, int flag)
+/**
+ * Add a new object, using another one as a reference
+ *
+ * /param ob_src object to use to determine the collections of the new object.
+ */
+Object *BKE_object_add_from(
+ Main *bmain, Scene *scene, ViewLayer *view_layer,
+ int type, const char *name, Object *ob_src)
{
- LodLevel *current = ob->currentlod;
-
- if (!current || !BKE_object_lod_is_usable(ob, scene))
- return ob;
-
- while (current->prev && (!(current->flags & flag) || !current->source || current->source->type != OB_MESH)) {
- current = current->prev;
- }
+ Object *ob;
+ Base *base;
- return current->source;
-}
+ ob = object_add_common(bmain, view_layer, type, name);
+ BKE_collection_object_add_from(bmain, scene, ob_src, ob);
-struct Object *BKE_object_lod_meshob_get(Object *ob, Scene *scene)
-{
- return lod_ob_get(ob, scene, OB_LOD_USE_MESH);
-}
+ base = BKE_view_layer_base_find(view_layer, ob);
+ BKE_view_layer_base_select(view_layer, base);
-struct Object *BKE_object_lod_matob_get(Object *ob, Scene *scene)
-{
- return lod_ob_get(ob, scene, OB_LOD_USE_MAT);
+ return ob;
}
-#endif /* WITH_GAMEENGINE */
-
-
SoftBody *copy_softbody(const SoftBody *sb, const int flag)
{
SoftBody *sbn;
@@ -883,56 +872,16 @@ SoftBody *copy_softbody(const SoftBody *sb, const int flag)
return sbn;
}
-BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb, const int UNUSED(flag))
-{
- BulletSoftBody *bsbn;
-
- if (bsb == NULL)
- return NULL;
- bsbn = MEM_dupallocN(bsb);
- /* no pointer in this structure yet */
- return bsbn;
-}
-
ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int flag)
{
- ParticleSystem *psysn;
- ParticleData *pa;
- int p;
-
- psysn = MEM_dupallocN(psys);
- psysn->particles = MEM_dupallocN(psys->particles);
- psysn->child = MEM_dupallocN(psys->child);
-
- if (psys->part->type == PART_HAIR) {
- for (p = 0, pa = psysn->particles; p < psysn->totpart; p++, pa++)
- pa->hair = MEM_dupallocN(pa->hair);
- }
+ ParticleSystem *psysn = MEM_dupallocN(psys);
- if (psysn->particles && (psysn->particles->keys || psysn->particles->boid)) {
- ParticleKey *key = psysn->particles->keys;
- BoidParticle *boid = psysn->particles->boid;
-
- if (key)
- key = MEM_dupallocN(key);
-
- if (boid)
- boid = MEM_dupallocN(boid);
-
- for (p = 0, pa = psysn->particles; p < psysn->totpart; p++, pa++) {
- if (boid)
- pa->boid = boid++;
- if (key) {
- pa->keys = key;
- key += pa->totkey;
- }
- }
- }
+ psys_copy_particles(psysn, psys);
if (psys->clmd) {
psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
modifier_copyData_ex((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd, flag);
- psys->hair_in_dm = psys->hair_out_dm = NULL;
+ psys->hair_in_mesh = psys->hair_out_mesh = NULL;
}
BLI_duplicatelist(&psysn->targets, &psys->targets);
@@ -944,13 +893,12 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f
psysn->effectors = NULL;
psysn->tree = NULL;
psysn->bvhtree = NULL;
+ psysn->batch_cache = NULL;
BLI_listbase_clear(&psysn->pathcachebufs);
BLI_listbase_clear(&psysn->childcachebufs);
- psysn->renderdata = NULL;
- /* XXX Never copy caches here? */
- psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag & ~LIB_ID_COPY_CACHES);
+ psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag);
/* XXX - from reading existing code this seems correct but intended usage of
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -1084,12 +1032,103 @@ Object *BKE_object_pose_armature_get(Object *ob)
ob = modifiers_isDeformedByArmature(ob);
+ /* Only use selected check when non-active. */
if (BKE_object_pose_context_check(ob))
return ob;
return NULL;
}
+Object *BKE_object_pose_armature_get_visible(Object *ob, ViewLayer *view_layer)
+{
+ Object *ob_armature = BKE_object_pose_armature_get(ob);
+ if (ob_armature) {
+ Base *base = BKE_view_layer_base_find(view_layer, ob_armature);
+ if (base) {
+ if (BASE_VISIBLE(base)) {
+ return ob_armature;
+ }
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Access pose array with special check to get pose object when in weight paint mode.
+ */
+Object **BKE_object_pose_array_get_ex(ViewLayer *view_layer, uint *r_objects_len, bool unique)
+{
+ Object *ob_active = OBACT(view_layer);
+ Object *ob_pose = BKE_object_pose_armature_get(ob_active);
+ Object **objects = NULL;
+ if (ob_pose == ob_active) {
+ objects = BKE_view_layer_array_from_objects_in_mode(
+ view_layer, r_objects_len, {
+ .object_mode = OB_MODE_POSE,
+ .no_dup_data = unique});
+ }
+ else if (ob_pose != NULL) {
+ *r_objects_len = 1;
+ objects = MEM_mallocN(sizeof(*objects), __func__);
+ objects[0] = ob_pose;
+ }
+ else {
+ *r_objects_len = 0;
+ objects = MEM_mallocN(0, __func__);
+ }
+ return objects;
+}
+Object **BKE_object_pose_array_get_unique(ViewLayer *view_layer, uint *r_objects_len)
+{
+ return BKE_object_pose_array_get_ex(view_layer, r_objects_len, true);
+}
+Object **BKE_object_pose_array_get(ViewLayer *view_layer, uint *r_objects_len)
+{
+ return BKE_object_pose_array_get_ex(view_layer, r_objects_len, false);
+}
+
+Base **BKE_object_pose_base_array_get_ex(ViewLayer *view_layer, uint *r_bases_len, bool unique)
+{
+ Base *base_active = BASACT(view_layer);
+ Object *ob_pose = base_active ? BKE_object_pose_armature_get(base_active->object) : NULL;
+ Base *base_pose = NULL;
+ Base **bases = NULL;
+
+ if (base_active) {
+ if (ob_pose == base_active->object) {
+ base_pose = base_active;
+ }
+ else {
+ base_pose = BKE_view_layer_base_find(view_layer, ob_pose);
+ }
+ }
+
+ if (base_active && (base_pose == base_active)) {
+ bases = BKE_view_layer_array_from_bases_in_mode(
+ view_layer, r_bases_len, {
+ .object_mode = OB_MODE_POSE,
+ .no_dup_data = unique});
+ }
+ else if (base_pose != NULL) {
+ *r_bases_len = 1;
+ bases = MEM_mallocN(sizeof(*bases), __func__);
+ bases[0] = base_pose;
+ }
+ else {
+ *r_bases_len = 0;
+ bases = MEM_mallocN(0, __func__);
+ }
+ return bases;
+}
+Base **BKE_object_pose_base_array_get_unique(ViewLayer *view_layer, uint *r_bases_len)
+{
+ return BKE_object_pose_base_array_get_ex(view_layer, r_bases_len, true);
+}
+Base **BKE_object_pose_base_array_get(ViewLayer *view_layer, uint *r_bases_len)
+{
+ return BKE_object_pose_base_array_get_ex(view_layer, r_bases_len, false);
+}
+
void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
{
copy_v3_v3(ob_tar->loc, ob_src->loc);
@@ -1125,7 +1164,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
if (ob_src->iuser) ob_dst->iuser = MEM_dupallocN(ob_src->iuser);
if (ob_src->bb) ob_dst->bb = MEM_dupallocN(ob_src->bb);
- ob_dst->flag &= ~OB_FROMGROUP;
BLI_listbase_clear(&ob_dst->modifiers);
@@ -1136,11 +1174,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
BLI_addtail(&ob_dst->modifiers, nmd);
}
- BLI_listbase_clear(&ob_dst->prop);
- BKE_bproperty_copy_list(&ob_dst->prop, &ob_src->prop);
-
- BKE_sca_logic_copy(ob_dst, ob_src, flag_subdata);
-
if (ob_src->pose) {
copy_object_pose(ob_dst, ob_src, flag_subdata);
/* backwards compat... non-armatures can get poses in older files? */
@@ -1148,6 +1181,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
BKE_pose_rebuild(ob_dst, ob_dst->data);
}
defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
+ BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
ob_dst->mode = OB_MODE_OBJECT;
@@ -1160,7 +1194,6 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
}
}
ob_dst->soft = copy_softbody(ob_src->soft, flag_subdata);
- ob_dst->bsoft = copy_bulletsoftbody(ob_src->bsoft, flag_subdata);
ob_dst->rigidbody_object = BKE_rigidbody_copy_object(ob_src, flag_subdata);
ob_dst->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob_src, flag_subdata);
@@ -1170,9 +1203,11 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
ob_dst->derivedFinal = NULL;
BLI_listbase_clear(&ob_dst->gpulamp);
+ BLI_listbase_clear(&ob_dst->drawdata);
BLI_listbase_clear(&ob_dst->pc_ids);
- ob_dst->mpath = NULL;
+ ob_dst->avs = ob_src->avs;
+ ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath);
copy_object_lod(ob_dst, ob_src, flag_subdata);
@@ -1193,6 +1228,10 @@ Object *BKE_object_copy(Main *bmain, const Object *ob)
{
Object *ob_copy;
BKE_id_copy_ex(bmain, &ob->id, (ID **)&ob_copy, 0, false);
+
+ /* We increase object user count when linking to Collections. */
+ id_us_min(&ob_copy->id);
+
return ob_copy;
}
@@ -1316,9 +1355,9 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
/* proxy rule: lib_object->proxy_from == the one we borrow from, set temporally while object_update */
/* local_object->proxy == pointer to library object, saved in files and read */
-/* local_object->proxy_group == pointer to group dupli-object, saved in files and read */
+/* local_object->proxy_group == pointer to collection dupli-object, saved in files and read */
-void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
+void BKE_object_make_proxy(Object *ob, Object *target, Object *cob)
{
/* paranoia checks */
if (ID_IS_LINKED(ob) || !ID_IS_LINKED(target)) {
@@ -1327,24 +1366,24 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
}
ob->proxy = target;
- ob->proxy_group = gob;
+ ob->proxy_group = cob;
id_lib_extern(&target->id);
- DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
- DAG_id_tag_update(&target->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&target->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* copy transform
- * - gob means this proxy comes from a group, just apply the matrix
+ * - cob means this proxy comes from a collection, just apply the matrix
* so the object wont move from its dupli-transform.
*
- * - no gob means this is being made from a linked object,
+ * - no cob means this is being made from a linked object,
* this is closer to making a copy of the object - in-place. */
- if (gob) {
+ if (cob) {
ob->rotmode = target->rotmode;
- mul_m4_m4m4(ob->obmat, gob->obmat, target->obmat);
- if (gob->dup_group) { /* should always be true */
+ mul_m4_m4m4(ob->obmat, cob->obmat, target->obmat);
+ if (cob->dup_group) { /* should always be true */
float tvec[3];
- mul_v3_mat3_m4v3(tvec, ob->obmat, gob->dup_group->dupli_ofs);
+ mul_v3_mat3_m4v3(tvec, ob->obmat, cob->dup_group->dupli_ofs);
sub_v3_v3(ob->obmat[3], tvec);
}
BKE_object_apply_mat4(ob, ob->obmat, false, true);
@@ -1653,7 +1692,7 @@ void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
if (ob->parent) {
float par_imat[4][4];
- BKE_object_get_parent_matrix(NULL, ob, ob->parent, par_imat);
+ BKE_object_get_parent_matrix(NULL, NULL, ob, ob->parent, par_imat);
invert_m4(par_imat);
mul_m4_m4m4(mat, par_imat, ob->obmat);
}
@@ -1666,21 +1705,24 @@ void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
int enable_cu_speed = 1;
/**
- * \param scene: Used when curve cache needs to be calculated, or for dupli-frame time.
+ * \param depsgraph: Used for dupli-frame time.
* \return success if \a mat is set.
*/
-static bool ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4])
+static bool ob_parcurve(Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob, Object *par, float mat[4][4])
{
Curve *cu = par->data;
float vec[4], dir[3], quat[4], radius, ctime;
+ /* TODO: Make sure this doesn't crash. */
+#if 0
/* only happens on reload file, but violates depsgraph still... fix! */
if (par->curve_cache == NULL) {
if (scene == NULL) {
return false;
}
- BKE_displist_make_curveTypes(scene, par, 0);
+ BKE_displist_make_curveTypes(depsgraph, scene, par, 0);
}
+#endif
if (par->curve_cache->path == NULL) {
return false;
@@ -1705,11 +1747,11 @@ static bool ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4])
}
else {
/* For dupli-frames only */
- if (scene == NULL) {
+ if (depsgraph == NULL) {
return false;
}
- ctime = BKE_scene_frame_get(scene);
+ ctime = DEG_get_ctime(depsgraph);
if (cu->pathlen) {
ctime /= cu->pathlen;
}
@@ -1960,7 +2002,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
}
-void BKE_object_get_parent_matrix(Scene *scene, Object *ob, Object *par, float parentmat[4][4])
+void BKE_object_get_parent_matrix(Depsgraph *depsgraph, Scene *scene, Object *ob, Object *par, float parentmat[4][4])
{
float tmat[4][4];
float vec[3];
@@ -1971,7 +2013,7 @@ void BKE_object_get_parent_matrix(Scene *scene, Object *ob, Object *par, float p
ok = 0;
if (par->type == OB_CURVE) {
if ((((Curve *)par->data)->flag & CU_PATH) &&
- (ob_parcurve(scene, ob, par, tmat)))
+ (ob_parcurve(depsgraph, scene, ob, par, tmat)))
{
ok = 1;
}
@@ -2007,7 +2049,8 @@ void BKE_object_get_parent_matrix(Scene *scene, Object *ob, Object *par, float p
/**
* \param r_originmat Optional matrix that stores the space the object is in (without its own matrix applied)
*/
-static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
+static void solve_parenting(Depsgraph *depsgraph,
+ Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
float r_originmat[3][3], const bool set_origin)
{
float totmat[4][4];
@@ -2018,7 +2061,7 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4
if (ob->partype & PARSLOW) copy_m4_m4(slowmat, obmat);
- BKE_object_get_parent_matrix(scene, ob, par, totmat);
+ BKE_object_get_parent_matrix(depsgraph, scene, ob, par, totmat);
/* total */
mul_m4_m4m4(tmat, totmat, ob->parentinv);
@@ -2061,20 +2104,21 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
-void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
- RigidBodyWorld *rbw, float r_originmat[3][3])
+void BKE_object_where_is_calc_time_ex(
+ Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime,
+ RigidBodyWorld *rbw, float r_originmat[3][3])
{
if (ob == NULL) return;
/* execute drivers only, as animation has already been done */
- BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
if (ob->parent) {
Object *par = ob->parent;
float slowmat[4][4];
/* calculate parent matrix */
- solve_parenting(scene, ob, par, ob->obmat, slowmat, r_originmat, true);
+ solve_parenting(depsgraph, scene, ob, par, ob->obmat, slowmat, r_originmat, true);
/* "slow parent" is definitely not threadsafe, and may also give bad results jumping around
* An old-fashioned hack which probably doesn't really cut it anymore
@@ -2096,8 +2140,8 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
/* solve constraints */
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
- cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- BKE_constraints_solve(&ob->constraints, cob, ctime);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_constraints_solve(depsgraph, &ob->constraints, cob, ctime);
BKE_constraints_clear_evalob(cob);
}
@@ -2106,16 +2150,16 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
+void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
{
- BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL, NULL);
+ BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, NULL, NULL);
}
/* get object transformation matrix without recalculating dependencies and
* constraints -- assume dependencies are already solved by depsgraph.
* no changes to object and it's parent would be done.
* used for bundles orientation in 3d space relative to parented blender camera */
-void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
+void BKE_object_where_is_calc_mat4(Depsgraph *depsgraph, Scene *scene, Object *ob, float obmat[4][4])
{
if (ob->parent) {
@@ -2123,7 +2167,7 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
Object *par = ob->parent;
- solve_parenting(scene, ob, par, obmat, slowmat, NULL, false);
+ solve_parenting(depsgraph, scene, ob, par, obmat, slowmat, NULL, false);
if (ob->partype & PARSLOW)
where_is_object_parslow(ob, obmat, slowmat);
@@ -2133,52 +2177,69 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
}
}
-void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
+void BKE_object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
{
- BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat);
+ BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), rbw, r_originmat);
}
-void BKE_object_where_is_calc(Scene *scene, Object *ob)
+void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
- BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL, NULL);
+ BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), NULL, NULL);
}
-/* for calculation of the inverse parent transform, only used for editor */
-void BKE_object_workob_calc_parent(Scene *scene, Object *ob, Object *workob)
+/**
+ * For calculation of the inverse parent transform, only used for editor.
+ *
+ * It assumes the object parent is already in the depsgraph.
+ * Otherwise, after changing ob->parent you need to call:
+ * DEG_relations_tag_update(bmain);
+ * BKE_scene_graph_update_tagged(depsgraph, bmain);
+ */
+void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *ob, Object *workob)
{
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_workob_clear(workob);
unit_m4(workob->obmat);
unit_m4(workob->parentinv);
unit_m4(workob->constinv);
- workob->parent = ob->parent;
- workob->trackflag = ob->trackflag;
- workob->upflag = ob->upflag;
+ /* Since this is used while calculating parenting, at this moment ob_eval->parent is still NULL. */
+ workob->parent = DEG_get_evaluated_object(depsgraph, ob->parent);
+
+ workob->trackflag = ob_eval->trackflag;
+ workob->upflag = ob_eval->upflag;
- workob->partype = ob->partype;
- workob->par1 = ob->par1;
- workob->par2 = ob->par2;
- workob->par3 = ob->par3;
+ workob->partype = ob_eval->partype;
+ workob->par1 = ob_eval->par1;
+ workob->par2 = ob_eval->par2;
+ workob->par3 = ob_eval->par3;
- workob->constraints.first = ob->constraints.first;
- workob->constraints.last = ob->constraints.last;
+ workob->constraints = ob_eval->constraints;
- BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr));
+ BLI_strncpy(workob->parsubstr, ob_eval->parsubstr, sizeof(workob->parsubstr));
- BKE_object_where_is_calc(scene, workob);
+ BKE_object_where_is_calc(depsgraph, scene, workob);
}
-/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
-void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, const bool use_parent)
+/**
+ * Applies the global transformation \a mat to the \a ob using a relative parent space if supplied.
+ *
+ * \param mat the global transformation mat that the object should be set object to.
+ * \param parent the parent space in which this object will be set relative to (should probably always be parent_eval).
+ * \param use_compat true to ensure that rotations are set using the min difference between the old and new orientation.
+ */
+void BKE_object_apply_mat4_ex(Object *ob, float mat[4][4], Object *parent, float parentinv[4][4], const bool use_compat)
{
+ /* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
+
float rot[3][3];
- if (use_parent && ob->parent) {
+ if (parent != NULL) {
float rmat[4][4], diff_mat[4][4], imat[4][4], parent_mat[4][4];
- BKE_object_get_parent_matrix(NULL, ob, ob->parent, parent_mat);
+ BKE_object_get_parent_matrix(NULL, NULL, ob, parent, parent_mat);
- mul_m4_m4m4(diff_mat, parent_mat, ob->parentinv);
+ mul_m4_m4m4(diff_mat, parent_mat, parentinv);
invert_m4_m4(imat, diff_mat);
mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
@@ -2200,10 +2261,16 @@ void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, c
/* BKE_object_mat3_to_rot handles delta rotations */
}
+/* XXX: should be removed after COW operators port to use BKE_object_apply_mat4_ex directly */
+void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, const bool use_parent)
+{
+ BKE_object_apply_mat4_ex(ob, mat, use_parent ? ob->parent : NULL, ob->parentinv, use_compat);
+}
+
BoundBox *BKE_boundbox_alloc_unit(void)
{
BoundBox *bb;
- const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {-1.0f, -1.0f, -1.0f};
+ const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f};
bb = MEM_callocN(sizeof(BoundBox), "OB-BoundBox");
BKE_boundbox_init_from_minmax(bb, min, max);
@@ -2408,6 +2475,7 @@ void BKE_object_empty_draw_type_set(Object *ob, const int value)
if (!ob->iuser) {
ob->iuser = MEM_callocN(sizeof(ImageUser), "image user");
ob->iuser->ok = 1;
+ ob->iuser->flag |= IMA_ANIM_ALWAYS;
ob->iuser->frames = 100;
ob->iuser->sfra = 1;
ob->iuser->fie_ima = 2;
@@ -2421,9 +2489,7 @@ void BKE_object_empty_draw_type_set(Object *ob, const int value)
}
}
-bool BKE_object_minmax_dupli(
- Main *bmain, Scene *scene,
- Object *ob, float r_min[3], float r_max[3], const bool use_hidden)
+bool BKE_object_minmax_dupli(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_min[3], float r_max[3], const bool use_hidden)
{
bool ok = false;
if ((ob->transflag & OB_DUPLI) == 0) {
@@ -2432,7 +2498,7 @@ bool BKE_object_minmax_dupli(
else {
ListBase *lb;
DupliObject *dob;
- lb = object_duplilist(bmain, bmain->eval_ctx, scene, ob);
+ lb = object_duplilist(depsgraph, scene, ob);
for (dob = lb->first; dob; dob = dob->next) {
if ((use_hidden == false) && (dob->no_draw != 0)) {
/* pass */
@@ -2464,13 +2530,11 @@ void BKE_object_foreach_display_point(
{
float co[3];
- if (ob->derivedFinal) {
- DerivedMesh *dm = ob->derivedFinal;
- MVert *mv = dm->getVertArray(dm);
- int totvert = dm->getNumVerts(dm);
- int i;
-
- for (i = 0; i < totvert; i++, mv++) {
+ if (ob->runtime.mesh_eval) {
+ const Mesh *me = ob->runtime.mesh_eval;
+ const MVert *mv = me->mvert;
+ const int totvert = me->totvert;
+ for (int i = 0; i < totvert; i++, mv++) {
mul_v3_m4v3(co, obmat, mv->co);
func_cb(co, user_data);
}
@@ -2492,33 +2556,20 @@ void BKE_object_foreach_display_point(
}
void BKE_scene_foreach_display_point(
- Main *bmain, Scene *scene, View3D *v3d, const short flag,
+ Depsgraph *depsgraph,
void (*func_cb)(const float[3], void *), void *user_data)
{
- Base *base;
- Object *ob;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag & flag) == flag) {
- ob = base->object;
-
- if ((ob->transflag & OB_DUPLI) == 0) {
- BKE_object_foreach_display_point(ob, ob->obmat, func_cb, user_data);
- }
- else {
- ListBase *lb;
- DupliObject *dob;
-
- lb = object_duplilist(bmain, bmain->eval_ctx, scene, ob);
- for (dob = lb->first; dob; dob = dob->next) {
- if (dob->no_draw == 0) {
- BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data);
- }
- }
- free_object_duplilist(lb); /* does restore */
- }
+ DEG_OBJECT_ITER_BEGIN(
+ depsgraph, ob,
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI)
+ {
+ if ((ob->base_flag & BASE_SELECTED) != 0) {
+ BKE_object_foreach_display_point(ob, ob->obmat, func_cb, user_data);
}
}
+ DEG_OBJECT_ITER_END;
}
/* copied from DNA_object_types.h */
@@ -2532,7 +2583,7 @@ typedef struct ObTfmBack {
float obmat[4][4]; /* final worldspace matrix with constraints & animsys applied */
float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */
float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */
- float imat[4][4]; /* inverse matrix of 'obmat' for during render, old game engine, temporally: ipokeys of transform */
+ float imat[4][4]; /* inverse matrix of 'obmat' for during render, temporally: ipokeys of transform */
} ObTfmBack;
void *BKE_object_tfm_backup(Object *ob)
@@ -2589,25 +2640,24 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
return BKE_object_parent_loop_check(par->parent, ob);
}
-static void object_handle_update_proxy(Main *bmain,
- EvaluationContext *eval_ctx,
+static void object_handle_update_proxy(Depsgraph *depsgraph,
Scene *scene,
Object *object,
const bool do_proxy_update)
{
- /* The case when this is a group proxy, object_update is called in group.c */
+ /* The case when this is a collection proxy, object_update is called in collection.c */
if (object->proxy == NULL) {
return;
}
/* set pointer in library proxy target, for copying, but restore it */
object->proxy->proxy_from = object;
- // printf("set proxy pointer for later group stuff %s\n", ob->id.name);
+ // printf("set proxy pointer for later collection stuff %s\n", ob->id.name);
/* the no-group proxy case, we call update */
if (object->proxy_group == NULL) {
if (do_proxy_update) {
// printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
- BKE_object_handle_update(bmain, eval_ctx, scene, object->proxy);
+ BKE_object_handle_update(depsgraph, scene, object->proxy);
}
}
}
@@ -2620,14 +2670,18 @@ static void object_handle_update_proxy(Main *bmain,
/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
/* requires flags to be set! */
/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
-void BKE_object_handle_update_ex(Main *bmain,
- EvaluationContext *eval_ctx,
+void BKE_object_handle_update_ex(Depsgraph *depsgraph,
Scene *scene, Object *ob,
RigidBodyWorld *rbw,
const bool do_proxy_update)
{
- if ((ob->recalc & OB_RECALC_ALL) == 0) {
- object_handle_update_proxy(bmain, eval_ctx, scene, ob, do_proxy_update);
+ const ID *object_data = ob->data;
+ const bool recalc_object = (ob->id.recalc & ID_RECALC) != 0;
+ const bool recalc_data =
+ (object_data != NULL) ? ((object_data->recalc & ID_RECALC_ALL) != 0)
+ : 0;
+ if (!recalc_object && ! recalc_data) {
+ object_handle_update_proxy(depsgraph, scene, ob, do_proxy_update);
return;
}
/* Speed optimization for animation lookups. */
@@ -2637,7 +2691,7 @@ void BKE_object_handle_update_ex(Main *bmain,
BKE_pose_update_constraint_flags(ob->pose);
}
}
- if (ob->recalc & OB_RECALC_DATA) {
+ if (recalc_data) {
if (ob->type == OB_ARMATURE) {
/* this happens for reading old files and to match library armatures
* with poses we do it ahead of BKE_object_where_is_calc to ensure animation
@@ -2650,23 +2704,23 @@ void BKE_object_handle_update_ex(Main *bmain,
/* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers,
* which is only in BKE_object_where_is_calc now */
/* XXX: should this case be OB_RECALC_OB instead? */
- if (ob->recalc & OB_RECALC_ALL) {
+ if (recalc_object || recalc_data) {
if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) {
printf("recalcob %s\n", ob->id.name + 2);
}
/* Handle proxy copy for target. */
- if (!BKE_object_eval_proxy_copy(eval_ctx, ob)) {
- BKE_object_where_is_calc_ex(scene, rbw, ob, NULL);
+ if (!BKE_object_eval_proxy_copy(depsgraph, ob)) {
+ BKE_object_where_is_calc_ex(depsgraph, scene, rbw, ob, NULL);
}
}
- if (ob->recalc & OB_RECALC_DATA) {
- BKE_object_handle_data_update(bmain, eval_ctx, scene, ob);
+ if (recalc_data) {
+ BKE_object_handle_data_update(depsgraph, scene, ob);
}
- ob->recalc &= ~OB_RECALC_ALL;
+ ob->id.recalc &= ID_RECALC_ALL;
- object_handle_update_proxy(bmain, eval_ctx, scene, ob, do_proxy_update);
+ object_handle_update_proxy(depsgraph, scene, ob, do_proxy_update);
}
/* WARNING: "scene" here may not be the scene object actually resides in.
@@ -2674,9 +2728,9 @@ void BKE_object_handle_update_ex(Main *bmain,
* e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
* rigid bodies depend on their world so use BKE_object_handle_update_ex() to also pass along the corrent rigid body world
*/
-void BKE_object_handle_update(Main *bmain, EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_object_handle_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
- BKE_object_handle_update_ex(bmain, eval_ctx, scene, ob, NULL, true);
+ BKE_object_handle_update_ex(depsgraph, scene, ob, NULL, true);
}
void BKE_object_sculpt_modifiers_changed(Object *ob)
@@ -2721,14 +2775,7 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
switch (GS(((ID *)ob->data)->name)) {
case ID_ME:
{
- Mesh *me = ob->data;
- if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
- BKE_mesh_texspace_calc(me);
- }
- if (r_texflag) *r_texflag = &me->texflag;
- if (r_loc) *r_loc = me->loc;
- if (r_size) *r_size = me->size;
- if (r_rot) *r_rot = me->rot;
+ BKE_mesh_texspace_get_reference((Mesh *)ob->data, r_texflag, r_loc, r_rot, r_size);
break;
}
case ID_CU:
@@ -2758,6 +2805,68 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
return 1;
}
+/** Get evaluated mesh for given (main, original) object and depsgraph. */
+Mesh *BKE_object_get_evaluated_mesh(const Depsgraph *depsgraph, Object *ob)
+{
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ return ob_eval->runtime.mesh_eval;
+}
+
+/* Get object's mesh with all modifiers applied. */
+Mesh *BKE_object_get_final_mesh(Object *object)
+{
+ if (object->runtime.mesh_eval != NULL) {
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
+ BLI_assert(object->runtime.mesh_eval == object->data);
+ BLI_assert((object->runtime.mesh_eval->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) != 0);
+ return object->runtime.mesh_eval;
+ }
+ /* Wasn't evaluated yet. */
+ return object->data;
+}
+
+/* Get mesh which is not affected by modifiers:
+ * - For original objects it will be same as object->data, and it is a mesh
+ * which is in the corresponding bmain.
+ * - For copied-on-write objects it will give pointer to a copied-on-write
+ * mesh which corresponds to original object's mesh.
+ */
+Mesh *BKE_object_get_pre_modified_mesh(Object *object)
+{
+ if (object->runtime.mesh_orig != NULL) {
+ BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
+ BLI_assert(object->id.orig_id != NULL);
+ BLI_assert(object->runtime.mesh_orig->id.orig_id == ((Object *)object->id.orig_id)->data);
+ Mesh *result = object->runtime.mesh_orig;
+ BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
+ BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
+ return result;
+ }
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
+ return object->data;
+}
+
+/* Get a mesh which corresponds to very very original mesh from bmain.
+ * - For original objects it will be object->data.
+ * - For evaluated objects it will be same mesh as corresponding original
+ * object uses as data.
+ */
+Mesh *BKE_object_get_original_mesh(Object *object)
+{
+ Mesh *result = NULL;
+ if (object->id.orig_id == NULL) {
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
+ result = object->data;
+ }
+ else {
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
+ result = ((Object *)object->id.orig_id)->data;
+ }
+ BLI_assert(result != NULL);
+ BLI_assert((result->id.tag & (LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT)) == 0);
+ return result;
+}
+
static int pc_cmp(const void *a, const void *b)
{
const LinkData *ad = a, *bd = b;
@@ -2832,7 +2941,7 @@ static KeyBlock *insert_meshkey(Main *bmain, Object *ob, const char *name, const
if (newkey || from_mix == false) {
/* create from mesh */
kb = BKE_keyblock_add_ctime(key, name, false);
- BKE_keyblock_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, key, kb);
}
else {
/* copy from current values */
@@ -3260,6 +3369,10 @@ MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, bool use_default)
return clip;
}
+void BKE_object_runtime_reset(Object *object)
+{
+ memset(&object->runtime, 0, sizeof(object->runtime));
+}
/*
* Find an associated Armature object
@@ -3295,33 +3408,33 @@ static void obrel_list_add(LinkNode **links, Object *ob)
}
/*
- * Iterates over all objects of the given scene.
+ * Iterates over all objects of the given scene layer.
* Depending on the eObjectSet flag:
* collect either OB_SET_ALL, OB_SET_VISIBLE or OB_SET_SELECTED objects.
* If OB_SET_VISIBLE or OB_SET_SELECTED are collected,
* then also add related objects according to the given includeFilters.
*/
-LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
+LinkNode *BKE_object_relational_superset(struct ViewLayer *view_layer, eObjectSet objectSet, eObRelationTypes includeFilter)
{
LinkNode *links = NULL;
Base *base;
/* Remove markers from all objects */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = view_layer->object_bases.first; base; base = base->next) {
base->object->id.tag &= ~LIB_TAG_DOIT;
}
/* iterate over all selected and visible objects */
- for (base = scene->base.first; base; base = base->next) {
+ for (base = view_layer->object_bases.first; base; base = base->next) {
if (objectSet == OB_SET_ALL) {
/* as we get all anyways just add it */
Object *ob = base->object;
obrel_list_add(&links, ob);
}
else {
- if ((objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base)) ||
- (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base)))
+ if ((objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(base)) ||
+ (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(base)))
{
Object *ob = base->object;
@@ -3350,8 +3463,8 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
/* child relationship */
if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
Base *local_base;
- for (local_base = scene->base.first; local_base; local_base = local_base->next) {
- if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) {
+ for (local_base = view_layer->object_bases.first; local_base; local_base = local_base->next) {
+ if (BASE_EDITABLE_BGMODE(local_base)) {
Object *child = local_base->object;
if (obrel_list_test(child)) {
@@ -3386,27 +3499,21 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
*/
struct LinkNode *BKE_object_groups(Main *bmain, Object *ob)
{
- LinkNode *group_linknode = NULL;
- Group *group = NULL;
- while ((group = BKE_group_object_find(bmain, group, ob))) {
- BLI_linklist_prepend(&group_linknode, group);
+ LinkNode *collection_linknode = NULL;
+ Collection *collection = NULL;
+ while ((collection = BKE_collection_object_find(bmain, collection, ob))) {
+ BLI_linklist_prepend(&collection_linknode, collection);
}
- return group_linknode;
+ return collection_linknode;
}
-void BKE_object_groups_clear(Main *bmain, Scene *scene, Base *base, Object *object)
+void BKE_object_groups_clear(Main *bmain, Object *ob)
{
- Group *group = NULL;
-
- BLI_assert((base == NULL) || (base->object == object));
-
- if (scene && base == NULL) {
- base = BKE_scene_base_find(scene, object);
- }
-
- while ((group = BKE_group_object_find(bmain, group, base->object))) {
- BKE_group_object_unlink(bmain, group, object, scene, base);
+ Collection *collection = NULL;
+ while ((collection = BKE_collection_object_find(bmain, collection, ob))) {
+ BKE_collection_object_remove(bmain, collection, ob, false);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
}
}
@@ -3586,11 +3693,11 @@ bool BKE_object_modifier_use_time(Object *ob, ModifierData *md)
}
/* set "ignore cache" flag for all caches on this object */
-static void object_cacheIgnoreClear(Main *bmain, Object *ob, int state)
+static void object_cacheIgnoreClear(Object *ob, int state)
{
ListBase pidlist;
PTCacheID *pid;
- BKE_ptcache_ids_from_object(bmain, &pidlist, ob, NULL, 0);
+ BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
for (pid = pidlist.first; pid; pid = pid->next) {
if (pid->cache) {
@@ -3608,10 +3715,8 @@ static void object_cacheIgnoreClear(Main *bmain, Object *ob, int state)
* Avoid calling this in new code unless there is a very good reason for it!
*/
bool BKE_object_modifier_update_subframe(
- Main *bmain, EvaluationContext *eval_ctx,
- Scene *scene, Object *ob, bool update_mesh,
- int parent_recursion, float frame,
- int type)
+ Depsgraph *depsgraph, Scene *scene, Object *ob, bool update_mesh,
+ int parent_recursion, float frame, int type)
{
ModifierData *md = modifiers_findByType(ob, (ModifierType)type);
bConstraint *con;
@@ -3634,8 +3739,8 @@ bool BKE_object_modifier_update_subframe(
if (parent_recursion) {
int recursion = parent_recursion - 1;
bool no_update = false;
- if (ob->parent) no_update |= BKE_object_modifier_update_subframe(bmain, eval_ctx, scene, ob->parent, 0, recursion, frame, type);
- if (ob->track) no_update |= BKE_object_modifier_update_subframe(bmain, eval_ctx, scene, ob->track, 0, recursion, frame, type);
+ if (ob->parent) no_update |= BKE_object_modifier_update_subframe(depsgraph, scene, ob->parent, 0, recursion, frame, type);
+ if (ob->track) no_update |= BKE_object_modifier_update_subframe(depsgraph, scene, ob->track, 0, recursion, frame, type);
/* skip subframe if object is parented
* to vertex of a dynamic paint canvas */
@@ -3652,7 +3757,7 @@ bool BKE_object_modifier_update_subframe(
cti->get_constraint_targets(con, &targets);
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar)
- BKE_object_modifier_update_subframe(bmain, eval_ctx, scene, ct->tar, 0, recursion, frame, type);
+ BKE_object_modifier_update_subframe(depsgraph, scene, ct->tar, 0, recursion, frame, type);
}
/* free temp targets */
if (cti->flush_constraint_targets)
@@ -3662,28 +3767,29 @@ bool BKE_object_modifier_update_subframe(
}
/* was originally OB_RECALC_ALL - TODO - which flags are really needed??? */
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
- BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, frame, ADT_RECALC_ANIM);
+ /* TODO(sergey): What about animation? */
+ ob->id.recalc |= ID_RECALC_ALL;
+ BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, frame, ADT_RECALC_ANIM);
if (update_mesh) {
/* ignore cache clear during subframe updates
* to not mess up cache validity */
- object_cacheIgnoreClear(bmain, ob, 1);
- BKE_object_handle_update(bmain, eval_ctx, scene, ob);
- object_cacheIgnoreClear(bmain, ob, 0);
+ object_cacheIgnoreClear(ob, 1);
+ BKE_object_handle_update(depsgraph, scene, ob);
+ object_cacheIgnoreClear(ob, 0);
}
else
- BKE_object_where_is_calc_time(scene, ob, frame);
+ BKE_object_where_is_calc_time(depsgraph, scene, ob, frame);
/* for curve following objects, parented curve has to be updated too */
if (ob->type == OB_CURVE) {
Curve *cu = ob->data;
- BKE_animsys_evaluate_animdata(scene, &cu->id, cu->adt, frame, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(depsgraph, scene, &cu->id, cu->adt, frame, ADT_RECALC_ANIM);
}
/* and armatures... */
if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
- BKE_animsys_evaluate_animdata(scene, &arm->id, arm->adt, frame, ADT_RECALC_ANIM);
- BKE_pose_where_is(scene, ob);
+ BKE_animsys_evaluate_animdata(depsgraph, scene, &arm->id, arm->adt, frame, ADT_RECALC_ANIM);
+ BKE_pose_where_is(depsgraph, scene, ob);
}
return false;