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_update.c')
-rw-r--r--source/blender/blenkernel/intern/object_update.c220
1 files changed, 156 insertions, 64 deletions
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 84d2f624577..52c85011b6a 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -32,18 +32,18 @@
#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_threads.h"
#include "BKE_global.h"
#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_constraint.h"
-#include "BKE_depsgraph.h"
+#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
#include "BKE_animsys.h"
#include "BKE_displist.h"
@@ -51,28 +51,26 @@
#include "BKE_key.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
+#include "BKE_library.h"
#include "BKE_editmesh.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_material.h"
+#include "BKE_mball.h"
+#include "BKE_mesh.h"
#include "BKE_image.h"
+#include "MEM_guardedalloc.h"
#include "DEG_depsgraph.h"
-#ifdef WITH_LEGACY_DEPSGRAPH
-# define DEBUG_PRINT if (!DEG_depsgraph_use_legacy() && G.debug & G_DEBUG_DEPSGRAPH) printf
-#else
-# define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
-#endif
-
-static ThreadMutex material_lock = BLI_MUTEX_INITIALIZER;
+#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
-void BKE_object_eval_local_transform(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_local_transform(const EvaluationContext *UNUSED(eval_ctx),
Object *ob)
{
- DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, ob->id.name, ob);
/* calculate local matrix */
BKE_object_to_mat4(ob, ob->obmat);
@@ -80,7 +78,7 @@ void BKE_object_eval_local_transform(EvaluationContext *UNUSED(eval_ctx),
/* Evaluate parent */
/* NOTE: based on solve_parenting(), but with the cruft stripped out */
-void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_parent(const EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
@@ -90,7 +88,7 @@ void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
float tmat[4][4];
float locmat[4][4];
- DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, ob->id.name, ob);
/* get local matrix (but don't calculate it, as that was done already!) */
// XXX: redundant?
@@ -112,14 +110,14 @@ void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_object_eval_constraints(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_constraints(const EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
{
bConstraintOb *cob;
float ctime = BKE_scene_frame_get(scene);
- DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, ob->id.name, ob);
/* evaluate constraints stack */
/* TODO: split this into:
@@ -131,22 +129,23 @@ void BKE_object_eval_constraints(EvaluationContext *UNUSED(eval_ctx),
*
*/
cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- BKE_constraints_solve(&ob->constraints, cob, ctime);
+ BKE_constraints_solve(eval_ctx, &ob->constraints, cob, ctime);
BKE_constraints_clear_evalob(cob);
}
-void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob)
+void BKE_object_eval_done(const EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
- DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, ob->id.name, ob);
/* Set negative scale flag in object. */
if (is_negative_m4(ob->obmat)) ob->transflag |= OB_NEG_SCALE;
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
- Scene *scene,
- Object *ob)
+void BKE_object_handle_data_update(
+ const EvaluationContext *eval_ctx,
+ Scene *scene,
+ Object *ob)
{
ID *data_id = (ID *)ob->data;
AnimData *adt = BKE_animdata_from_id(data_id);
@@ -174,7 +173,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
switch (ob->type) {
case OB_MESH:
{
- BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
+ BMEditMesh *em = (eval_ctx->object_mode & OB_MODE_EDIT) ? BKE_editmesh_from_object(ob) : NULL;
uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
#ifdef WITH_FREESTYLE
/* make sure Freestyle edge/face marks appear in DM for render (see T40315) */
@@ -183,10 +182,10 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
}
#endif
if (em) {
- makeDerivedMesh(scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */
+ makeDerivedMesh(eval_ctx, scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */
}
else {
- makeDerivedMesh(scene, ob, NULL, data_mask, false);
+ makeDerivedMesh(eval_ctx, scene, ob, NULL, data_mask, false);
}
break;
}
@@ -198,7 +197,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
}
}
else {
- BKE_pose_where_is(scene, ob);
+ BKE_pose_where_is(eval_ctx, scene, ob);
}
break;
@@ -209,11 +208,11 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
case OB_CURVE:
case OB_SURF:
case OB_FONT:
- BKE_displist_make_curveTypes(scene, ob, 0);
+ BKE_displist_make_curveTypes(eval_ctx, scene, ob, 0);
break;
case OB_LATTICE:
- BKE_lattice_modifiers_calc(scene, ob);
+ BKE_lattice_modifiers_calc(eval_ctx, scene, ob);
break;
case OB_EMPTY:
@@ -223,30 +222,8 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
break;
}
- /* related materials */
- /* XXX: without depsgraph tagging, this will always need to be run, which will be slow!
- * However, not doing anything (or trying to hack around this lack) is not an option
- * anymore, especially due to Cycles [#31834]
- */
- if (ob->totcol) {
- int a;
- if (ob->totcol != 0) {
- BLI_mutex_lock(&material_lock);
- for (a = 1; a <= ob->totcol; a++) {
- Material *ma = give_current_material(ob, a);
- if (ma) {
- /* recursively update drivers for this material */
- material_drivers_update(scene, ma, ctime);
- }
- }
- BLI_mutex_unlock(&material_lock);
- }
- }
- else if (ob->type == OB_LAMP)
- lamp_drivers_update(scene, ob->data, ctime);
-
/* particles */
- if (ob != scene->obedit && ob->particlesystem.first) {
+ if ((ob != OBEDIT_FROM_EVAL_CTX(eval_ctx)) && ob->particlesystem.first) {
ParticleSystem *tpsys, *psys;
DerivedMesh *dm;
ob->transflag &= ~OB_DUPLIPARTS;
@@ -266,7 +243,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
ob->transflag |= OB_DUPLIPARTS;
}
- particle_system_update(scene, ob, psys, (eval_ctx->mode == DAG_EVAL_RENDER));
+ particle_system_update(eval_ctx, scene, ob, psys, (eval_ctx->mode == DAG_EVAL_RENDER));
psys = psys->next;
}
else if (psys->flag & PSYS_DELETE) {
@@ -284,7 +261,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
* the derivedmesh must be created before init_render_mesh,
* since object_duplilist does dupliparticles before that */
CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL;
- dm = mesh_create_derived_render(scene, ob, data_mask);
+ dm = mesh_create_derived_render(eval_ctx, scene, ob, data_mask);
dm->release(dm);
for (psys = ob->particlesystem.first; psys; psys = psys->next)
@@ -295,7 +272,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
/* quick cache removed */
}
-bool BKE_object_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx),
+bool BKE_object_eval_proxy_copy(const EvaluationContext *UNUSED(eval_ctx),
Object *object)
{
/* Handle proxy copy for target, */
@@ -319,35 +296,98 @@ bool BKE_object_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx),
return false;
}
-void BKE_object_eval_uber_transform(EvaluationContext *eval_ctx, Object *object)
+void BKE_object_eval_uber_transform(const EvaluationContext *eval_ctx, Object *object)
{
BKE_object_eval_proxy_copy(eval_ctx, object);
- object->recalc &= ~(OB_RECALC_OB | OB_RECALC_TIME);
- if (object->data == NULL) {
- object->recalc &= ~OB_RECALC_DATA;
- }
}
-void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
+void BKE_object_eval_uber_data(const EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
{
- DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, ob->id.name, ob);
BLI_assert(ob->type != OB_ARMATURE);
BKE_object_handle_data_update(eval_ctx, scene, ob);
- ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
+ switch (ob->type) {
+ case OB_MESH:
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+ break;
+ case OB_LATTICE:
+ BKE_lattice_batch_cache_dirty(ob->data, BKE_LATTICE_BATCH_DIRTY_ALL);
+ break;
+ case OB_CURVE:
+ case OB_FONT:
+ case OB_SURF:
+ BKE_curve_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_ALL);
+ break;
+ case OB_MBALL:
+ BKE_mball_batch_cache_dirty(ob->data, BKE_MBALL_BATCH_DIRTY_ALL);
+ break;
+ }
+
+ if (DEG_depsgraph_use_copy_on_write()) {
+ if (ob->type == OB_MESH) {
+ /* Quick hack to convert evaluated derivedMesh to Mesh. */
+ DerivedMesh *dm = ob->derivedFinal;
+ if (dm != NULL) {
+ Mesh *mesh = (Mesh *)ob->data;
+ Mesh *new_mesh = BKE_libblock_alloc_notest(ID_ME);
+ BKE_mesh_init(new_mesh);
+ /* Copy ID name so GS(new_mesh->id) works correct later on. */
+ BLI_strncpy(new_mesh->id.name, mesh->id.name, sizeof(new_mesh->id.name));
+ /* Copy materials so render engines can access them. */
+ new_mesh->mat = MEM_dupallocN(mesh->mat);
+ new_mesh->totcol = mesh->totcol;
+ DM_to_mesh(dm, new_mesh, ob, CD_MASK_MESH, true);
+ new_mesh->edit_btmesh = mesh->edit_btmesh;
+ /* Store result mesh as derived_mesh of object. This way we have
+ * explicit way to query final object evaluated data and know for sure
+ * who owns the newly created mesh datablock.
+ */
+ ob->mesh_evaluated = new_mesh;
+ /* TODO(sergey): This is kind of compatibility thing, so all render
+ * engines can use object->data for mesh data for display. This is
+ * something what we might want to change in the future.
+ */
+ ob->data = new_mesh;
+ /* Special flags to help debugging. */
+ new_mesh->id.tag |= LIB_TAG_COPY_ON_WRITE_EVAL;
+ /* Save some memory by throwing DerivedMesh away. */
+ /* NOTE: Watch out, some tools might need it!
+ * So keep around for now..
+ */
+ /* Store original ID as a pointer in evaluated ID.
+ * This way we can restore original object data when we are freeing
+ * evaluated mesh.
+ */
+ new_mesh->id.orig_id = &mesh->id;
+ }
+#if 0
+ if (ob->derivedFinal != NULL) {
+ ob->derivedFinal->needsFree = 1;
+ ob->derivedFinal->release(ob->derivedFinal);
+ ob->derivedFinal = NULL;
+ }
+ if (ob->derivedDeform != NULL) {
+ ob->derivedDeform->needsFree = 1;
+ ob->derivedDeform->release(ob->derivedDeform);
+ ob->derivedDeform = NULL;
+ }
+#endif
+ }
+ }
}
-void BKE_object_eval_cloth(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_cloth(const EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *object)
{
- DEBUG_PRINT("%s on %s\n", __func__, object->id.name);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object);
BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH);
}
-void BKE_object_eval_transform_all(EvaluationContext *eval_ctx,
+void BKE_object_eval_transform_all(const EvaluationContext *eval_ctx,
Scene *scene,
Object *object)
{
@@ -362,3 +402,55 @@ void BKE_object_eval_transform_all(EvaluationContext *eval_ctx,
BKE_object_eval_uber_transform(eval_ctx, object);
BKE_object_eval_done(eval_ctx, object);
}
+
+void BKE_object_eval_update_shading(const EvaluationContext *UNUSED(eval_ctx),
+ Object *object)
+{
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object);
+ if (object->type == OB_MESH) {
+ BKE_mesh_batch_cache_dirty(object->data, BKE_MESH_BATCH_DIRTY_SHADING);
+ }
+}
+
+void BKE_object_data_select_update(const EvaluationContext *UNUSED(eval_ctx),
+ struct ID *object_data)
+{
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, object_data->name, object_data);
+ switch (GS(object_data->name)) {
+ case ID_ME:
+ BKE_mesh_batch_cache_dirty((Mesh *)object_data,
+ BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ case ID_CU:
+ BKE_curve_batch_cache_dirty((Curve *)object_data,
+ BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ case ID_LT:
+ BKE_lattice_batch_cache_dirty((struct Lattice *)object_data,
+ BKE_CURVE_BATCH_DIRTY_SELECT);
+ break;
+ default:
+ break;
+ }
+}
+
+void BKE_object_eval_flush_base_flags(const EvaluationContext *UNUSED(eval_ctx),
+ Object *object, Base *base, bool is_from_set)
+{
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object);
+
+ /* Make sure we have the base collection settings is already populated.
+ * This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet.
+ *
+ * Which usually means a missing call to DEG_id_tag_update(id, DEG_TAG_BASE_FLAGS_UPDATE).
+ * Either of the entire scene, or of the newly added objects.*/
+ BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group));
+
+ /* Copy flags and settings from base. */
+ object->base_flag = base->flag;
+ if (is_from_set) {
+ object->base_flag |= BASE_FROM_SET;
+ object->base_flag &= ~(BASE_SELECTED | BASE_SELECTABLED);
+ }
+ object->base_collection_properties = base->collection_properties;
+}