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')
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c73
-rw-r--r--source/blender/blenkernel/intern/constraint.c134
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c4
-rw-r--r--source/blender/blenkernel/intern/displist.c16
-rw-r--r--source/blender/blenkernel/intern/effect.c6
-rw-r--r--source/blender/blenkernel/intern/image.c8
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c32
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/object.c101
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c4
-rw-r--r--source/blender/blenkernel/intern/object_update.c4
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c8
15 files changed, 207 insertions, 193 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9f436db97ee..8963f241ca8 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -287,6 +287,7 @@ void BKE_object_eval_uber_transform(struct Depsgraph *depsgraph, struct Object *
void BKE_object_eval_uber_data(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
+void BKE_object_eval_assign_data(struct Object *object, struct ID *data, bool is_owned);
void BKE_object_eval_boundbox(struct Depsgraph *depsgraph, struct Object *object);
void BKE_object_synchronize_to_original(struct Depsgraph *depsgraph, struct Object *object);
@@ -326,8 +327,7 @@ int BKE_object_obdata_texspace_get(struct Object *ob,
float **r_loc,
float **r_size);
-struct Mesh *BKE_object_get_evaluated_mesh(const struct Depsgraph *depsgraph, struct Object *ob);
-struct Mesh *BKE_object_get_final_mesh(struct Object *object);
+struct Mesh *BKE_object_get_evaluated_mesh(struct Object *object);
struct Mesh *BKE_object_get_pre_modified_mesh(struct Object *object);
struct Mesh *BKE_object_get_original_mesh(struct Object *object);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 3006ab76032..148c7a6b6c0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1719,43 +1719,12 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
}
}
-static void assign_object_mesh_eval(Object *object)
-{
- BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
-
- Mesh *mesh = (Mesh *)object->data;
- Mesh *mesh_eval = object->runtime.mesh_eval;
-
- /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
- * is not guaranteed to be owned by object.
- *
- * Check ownership now, since later on we can not go to a mesh owned by someone else via object's
- * runtime: this could cause access freed data on depsgraph destruction (mesh who owns the final
- * result might be freed prior to object). */
- if (mesh_eval == mesh->runtime.mesh_eval) {
- object->runtime.is_mesh_eval_owned = false;
- }
- else {
- mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- object->runtime.is_mesh_eval_owned = true;
- }
-
- /* NOTE: We are not supposed to invoke evaluation for original object, but some areas are still
- * under process of being ported, so we play safe here. */
- if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
- object->data = mesh_eval;
- }
- else {
- /* evaluated will be available via: 'object->runtime.mesh_eval' */
- }
-}
-
-static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob)
+static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob, Mesh *mesh_eval)
{
uint32_t eval_flags = DEG_get_eval_flags_for_id(depsgraph, &ob->id);
if (eval_flags & DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY) {
- BKE_shrinkwrap_compute_boundary_data(ob->runtime.mesh_eval);
+ BKE_shrinkwrap_compute_boundary_data(mesh_eval);
}
}
@@ -1793,6 +1762,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
}
#endif
+ Mesh *mesh_eval = NULL, *mesh_deform_eval = NULL;
mesh_calc_modifiers(depsgraph,
scene,
ob,
@@ -1802,26 +1772,35 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
-1,
true,
true,
- &ob->runtime.mesh_deform_eval,
- &ob->runtime.mesh_eval);
-
- BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
-
- assign_object_mesh_eval(ob);
+ &mesh_deform_eval,
+ &mesh_eval);
+ /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
+ * is not guaranteed to be owned by object.
+ *
+ * Check ownership now, since later on we can not go to a mesh owned by someone else via
+ * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
+ * the final result might be freed prior to object). */
+ Mesh *mesh = ob->data;
+ const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
+ BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
+
+ ob->runtime.mesh_deform_eval = mesh_deform_eval;
ob->runtime.last_data_mask = *dataMask;
ob->runtime.last_need_mapping = need_mapping;
+ BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
+
if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
if (DEG_is_active(depsgraph)) {
BKE_sculpt_update_object_after_eval(depsgraph, ob);
}
}
- if (ob->runtime.mesh_eval != NULL) {
- mesh_runtime_check_normals_valid(ob->runtime.mesh_eval);
+ if (mesh_eval != NULL) {
+ mesh_runtime_check_normals_valid(mesh_eval);
}
- mesh_build_extra_data(depsgraph, ob);
+ mesh_build_extra_data(depsgraph, ob, mesh_eval);
}
static void editbmesh_build_data(struct Depsgraph *depsgraph,
@@ -1942,18 +1921,20 @@ Mesh *mesh_get_eval_final(struct Depsgraph *depsgraph,
CustomData_MeshMasks cddata_masks = *dataMask;
object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping);
- if (!ob->runtime.mesh_eval ||
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if ((mesh_eval == NULL) ||
!CustomData_MeshMasks_are_matching(&(ob->runtime.last_data_mask), &cddata_masks) ||
(need_mapping && !ob->runtime.last_need_mapping)) {
CustomData_MeshMasks_update(&cddata_masks, &ob->runtime.last_data_mask);
mesh_build_data(
depsgraph, scene, ob, &cddata_masks, need_mapping || ob->runtime.last_need_mapping);
+ mesh_eval = BKE_object_get_evaluated_mesh(ob);
}
- if (ob->runtime.mesh_eval) {
- BLI_assert(!(ob->runtime.mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL));
+ if (mesh_eval != NULL) {
+ BLI_assert(!(mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL));
}
- return ob->runtime.mesh_eval;
+ return mesh_eval;
}
Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 8ba746e3493..3df1a84a0c9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -368,7 +368,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* when not in EditMode, use the 'final' evaluated mesh, depsgraph
* ensures we build with CD_MDEFORMVERT layer
*/
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
BMEditMesh *em = BKE_editmesh_from_object(ob);
float plane[3];
float imat[3][3], tmat[3][3];
@@ -860,94 +860,88 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
}
float parmat[4][4];
-
- /* simple matrix parenting */
- if (data->flag == CHILDOF_ALL) {
-
- /* multiply target (parent matrix) by offset (parent inverse) to get
- * the effect of the parent that will be exerted on the owner
- */
- mul_m4_m4m4(parmat, ct->matrix, data->invmat);
-
- /* now multiply the parent matrix by the owner matrix to get the
- * the effect of this constraint (i.e. owner is 'parented' to parent)
- */
- mul_m4_m4m4(cob->matrix, parmat, cob->matrix);
+ /* Simple matrix parenting. */
+ if ((data->flag & CHILDOF_ALL) == CHILDOF_ALL) {
+ copy_m4_m4(parmat, ct->matrix);
}
+ /* Filter the parent matrix by channel. */
else {
- float invmat[4][4], tempmat[4][4];
float loc[3], eul[3], size[3];
- float loco[3], eulo[3], sizo[3];
-
- /* get offset (parent-inverse) matrix */
- copy_m4_m4(invmat, data->invmat);
/* extract components of both matrices */
copy_v3_v3(loc, ct->matrix[3]);
mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
mat4_to_size(size, ct->matrix);
- copy_v3_v3(loco, invmat[3]);
- mat4_to_eulO(eulo, cob->rotOrder, invmat);
- mat4_to_size(sizo, invmat);
-
/* disable channels not enabled */
if (!(data->flag & CHILDOF_LOCX)) {
- loc[0] = loco[0] = 0.0f;
+ loc[0] = 0.0f;
}
if (!(data->flag & CHILDOF_LOCY)) {
- loc[1] = loco[1] = 0.0f;
+ loc[1] = 0.0f;
}
if (!(data->flag & CHILDOF_LOCZ)) {
- loc[2] = loco[2] = 0.0f;
+ loc[2] = 0.0f;
}
if (!(data->flag & CHILDOF_ROTX)) {
- eul[0] = eulo[0] = 0.0f;
+ eul[0] = 0.0f;
}
if (!(data->flag & CHILDOF_ROTY)) {
- eul[1] = eulo[1] = 0.0f;
+ eul[1] = 0.0f;
}
if (!(data->flag & CHILDOF_ROTZ)) {
- eul[2] = eulo[2] = 0.0f;
+ eul[2] = 0.0f;
}
if (!(data->flag & CHILDOF_SIZEX)) {
- size[0] = sizo[0] = 1.0f;
+ size[0] = 1.0f;
}
if (!(data->flag & CHILDOF_SIZEY)) {
- size[1] = sizo[1] = 1.0f;
+ size[1] = 1.0f;
}
if (!(data->flag & CHILDOF_SIZEZ)) {
- size[2] = sizo[2] = 1.0f;
+ size[2] = 1.0f;
}
/* make new target mat and offset mat */
- loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder);
- loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
+ loc_eulO_size_to_mat4(parmat, loc, eul, size, ct->rotOrder);
+ }
- /* multiply target (parent matrix) by offset (parent inverse) to get
- * the effect of the parent that will be exerted on the owner
- */
- mul_m4_m4m4(parmat, ct->matrix, invmat);
+ /* Compute the inverse matrix if requested. */
+ if (data->flag & CHILDOF_SET_INVERSE) {
+ invert_m4_m4(data->invmat, parmat);
- /* now multiply the parent matrix by the owner matrix to get the
- * the effect of this constraint (i.e. owner is 'parented' to parent)
- */
- copy_m4_m4(tempmat, cob->matrix);
- mul_m4_m4m4(cob->matrix, parmat, tempmat);
+ data->flag &= ~CHILDOF_SET_INVERSE;
- /* without this, changes to scale and rotation can change location
- * of a parentless bone or a disconnected bone. Even though its set
- * to zero above. */
- if (!(data->flag & CHILDOF_LOCX)) {
- cob->matrix[3][0] = tempmat[3][0];
- }
- if (!(data->flag & CHILDOF_LOCY)) {
- cob->matrix[3][1] = tempmat[3][1];
- }
- if (!(data->flag & CHILDOF_LOCZ)) {
- cob->matrix[3][2] = tempmat[3][2];
+ /* Write the computed matrix back to the master copy if in COW evaluation. */
+ bConstraint *orig_con = constraint_find_original_for_update(cob, con);
+
+ if (orig_con != NULL) {
+ bChildOfConstraint *orig_data = orig_con->data;
+
+ copy_m4_m4(orig_data->invmat, data->invmat);
+ orig_data->flag &= ~CHILDOF_SET_INVERSE;
}
}
+
+ /* Multiply together the target (parent) matrix, parent inverse,
+ * and the owner transform matrixto get the effect of this constraint
+ * (i.e. owner is 'parented' to parent). */
+ float orig_cob_matrix[4][4];
+ copy_m4_m4(orig_cob_matrix, cob->matrix);
+ mul_m4_series(cob->matrix, parmat, data->invmat, orig_cob_matrix);
+
+ /* Without this, changes to scale and rotation can change location
+ * of a parentless bone or a disconnected bone. Even though its set
+ * to zero above. */
+ if (!(data->flag & CHILDOF_LOCX)) {
+ cob->matrix[3][0] = orig_cob_matrix[3][0];
+ }
+ if (!(data->flag & CHILDOF_LOCY)) {
+ cob->matrix[3][1] = orig_cob_matrix[3][1];
+ }
+ if (!(data->flag & CHILDOF_LOCZ)) {
+ cob->matrix[3][2] = orig_cob_matrix[3][2];
+ }
}
/* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */
@@ -3974,7 +3968,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
float track_no[3] = {0.0f, 0.0f, 0.0f};
SpaceTransform transform;
- Mesh *target_eval = ct->tar->runtime.mesh_eval;
+ Mesh *target_eval = BKE_object_get_evaluated_mesh(ct->tar);
copy_m4_m4(ct->matrix, cob->matrix);
@@ -4742,7 +4736,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
if (data->depth_ob) {
Object *depth_ob = data->depth_ob;
- Mesh *target_eval = depth_ob->runtime.mesh_eval;
+ Mesh *target_eval = BKE_object_get_evaluated_mesh(depth_ob);
if (target_eval) {
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
BVHTreeRayHit hit;
@@ -4891,23 +4885,35 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
return;
}
- float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
+ float mat[4][4], obmat[4][4], imat[4][4], parmat[4][4];
float ctime = DEG_get_ctime(depsgraph);
float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
- BKE_object_where_is_calc_mat4(camob, cammat);
-
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
- invert_m4_m4(camimat, cammat);
- mul_m4_m4m4(parmat, cammat, data->invmat);
+ invert_m4_m4(imat, mat);
+ mul_m4_m4m4(parmat, camob->obmat, imat);
- copy_m4_m4(cammat, camob->obmat);
copy_m4_m4(obmat, cob->matrix);
- invert_m4_m4(imat, mat);
+ /* Recalculate the inverse matrix if requested. */
+ if (data->flag & OBJECTSOLVER_SET_INVERSE) {
+ invert_m4_m4(data->invmat, parmat);
+
+ data->flag &= ~OBJECTSOLVER_SET_INVERSE;
+
+ /* Write the computed matrix back to the master copy if in COW evaluation. */
+ bConstraint *orig_con = constraint_find_original_for_update(cob, con);
+
+ if (orig_con != NULL) {
+ bObjectSolverConstraint *orig_data = orig_con->data;
+
+ copy_m4_m4(orig_data->invmat, data->invmat);
+ orig_data->flag &= ~OBJECTSOLVER_SET_INVERSE;
+ }
+ }
- mul_m4_series(cob->matrix, cammat, imat, camimat, parmat, obmat);
+ mul_m4_series(cob->matrix, parmat, data->invmat, obmat);
}
static bConstraintTypeInfo CTI_OBJECTSOLVER = {
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index e0abe836bf8..bdca888efcc 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -338,8 +338,8 @@ static void crazyspace_init_object_for_eval(struct Depsgraph *depsgraph,
{
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
*object_crazy = *object_eval;
- if (object_crazy->runtime.mesh_orig != NULL) {
- object_crazy->data = object_crazy->runtime.mesh_orig;
+ if (object_crazy->runtime.data_orig != NULL) {
+ object_crazy->data = object_crazy->runtime.data_orig;
}
}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 6d7d42b2293..6963f629798 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1772,7 +1772,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render);
}
- if (cu->flag & CU_DEFORM_FILL && !ob->runtime.mesh_eval) {
+ if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
curve_to_filledpoly(cu, &nubase, dispbase);
}
@@ -1800,12 +1800,11 @@ void BKE_displist_make_curveTypes(
dispbase = &(ob->runtime.curve_cache->disp);
- do_makeDispListCurveTypes(
- depsgraph, scene, ob, dispbase, for_render, for_orco, &ob->runtime.mesh_eval);
+ Mesh *mesh_eval = NULL;
+ do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, for_render, for_orco, &mesh_eval);
- if (ob->runtime.mesh_eval != NULL) {
- ob->runtime.mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- ob->runtime.is_mesh_eval_owned = true;
+ if (mesh_eval != NULL) {
+ BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
}
boundbox_displist_object(ob);
@@ -1861,8 +1860,9 @@ static void boundbox_displist_object(Object *ob)
ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "boundbox");
}
- if (ob->runtime.mesh_eval) {
- BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if (mesh_eval) {
+ BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
}
else {
float min[3], max[3];
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 8971021329a..4a9efc7cac4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -315,7 +315,7 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph,
else if (weights->weight[ob->pd->forcefield] == 0.0f) {
continue;
}
- else if (ob->pd->shape == PFIELD_SHAPE_POINTS && ob->runtime.mesh_eval == NULL) {
+ else if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) {
continue;
}
@@ -656,7 +656,7 @@ int get_effector_data(EffectorCache *eff,
efd->size = 0.0f;
}
else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
- Mesh *me_eval = eff->ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
if (me_eval != NULL) {
copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
normal_short_to_float_v3(efd->nor, me_eval->mvert[*efd->index].no);
@@ -769,7 +769,7 @@ static void get_effector_tot(
efd->index = p;
if (eff->pd->shape == PFIELD_SHAPE_POINTS) {
- Mesh *me_eval = eff->ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
*tot = me_eval != NULL ? me_eval->totvert : 1;
if (*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 7868b72e9cf..5761bec98b2 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -5180,6 +5180,14 @@ void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
iuser->ok = 1;
}
+ if (ima) {
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ if (tile->ok == 0) {
+ tile->ok = IMA_OK;
+ }
+ }
+ }
+
iuser->flag &= ~IMA_NEED_FRAME_RECALC;
}
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index af5e867ac38..d8d5653730b 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1608,6 +1608,7 @@ static void material_default_surface_init(Material *ma)
{
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
+ ma->use_nodes = true;
bNode *principled = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_PRINCIPLED);
bNodeSocket *base_color = nodeFindSocket(principled, SOCK_IN, "Base Color");
@@ -1633,6 +1634,7 @@ static void material_default_volume_init(Material *ma)
{
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
+ ma->use_nodes = true;
bNode *principled = nodeAddStaticNode(NULL, ntree, SH_NODE_VOLUME_PRINCIPLED);
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 014ccdb913e..f0bab4c0aa2 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -582,7 +582,7 @@ void BKE_mesh_from_nurbs_displist(
Main *bmain, Object *ob, ListBase *dispbase, const char *obdata_name, bool temporary)
{
Object *ob1;
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
Mesh *me;
Curve *cu;
MVert *allvert = NULL;
@@ -644,7 +644,7 @@ void BKE_mesh_from_nurbs_displist(
me = BKE_id_new_nomain(ID_ME, obdata_name);
}
- ob->runtime.mesh_eval = NULL;
+ ob->runtime.data_eval = NULL;
BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
}
@@ -929,11 +929,9 @@ static Object *object_for_curve_to_mesh_create(Object *object)
BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp);
}
/* Constructive modifiers will use mesh to store result. */
- if (object->runtime.mesh_eval != NULL) {
- BKE_id_copy_ex(NULL,
- &object->runtime.mesh_eval->id,
- (ID **)&temp_object->runtime.mesh_eval,
- LIB_ID_COPY_LOCALIZE);
+ if (object->runtime.data_eval != NULL) {
+ BKE_id_copy_ex(
+ NULL, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
}
/* Need to create copy of curve itself as well, it will be freed by underlying conversion
@@ -994,19 +992,15 @@ static void curve_to_mesh_eval_ensure(Object *object)
* bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also
* Mesh From Curve operator.
* Brecht says hold off with that. */
- BKE_displist_make_curveTypes_forRender(NULL,
- NULL,
- &remapped_object,
- &remapped_object.runtime.curve_cache->disp,
- &remapped_object.runtime.mesh_eval,
- false);
+ Mesh *mesh_eval = NULL;
+ BKE_displist_make_curveTypes_forRender(
+ NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval, false);
/* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a
* real issue currently, code here is broken in more than one way, fix(es) will be done
* separately. */
- if (remapped_object.runtime.mesh_eval != NULL) {
- remapped_object.runtime.mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- remapped_object.runtime.is_mesh_eval_owned = true;
+ if (mesh_eval != NULL) {
+ BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true);
}
BKE_object_free_curve_cache(&bevel_object);
@@ -1104,8 +1098,8 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object
}
Object object_for_eval = *object;
- if (object_for_eval.runtime.mesh_orig != NULL) {
- object_for_eval.data = object_for_eval.runtime.mesh_orig;
+ if (object_for_eval.runtime.data_orig != NULL) {
+ object_for_eval.data = object_for_eval.runtime.data_orig;
}
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -1306,7 +1300,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
ModifierData *md_eval,
int build_shapekey_layers)
{
- Mesh *me = ob_eval->runtime.mesh_orig ? ob_eval->runtime.mesh_orig : ob_eval->data;
+ Mesh *me = ob_eval->runtime.data_orig ? ob_eval->runtime.data_orig : ob_eval->data;
const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type);
Mesh *result;
KeyBlock *kb;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 51c70406692..381e43241ea 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -1019,7 +1019,7 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval,
if (me == NULL) {
me = (get_cage_mesh && ob_eval->runtime.mesh_deform_eval != NULL) ?
ob_eval->runtime.mesh_deform_eval :
- ob_eval->runtime.mesh_eval;
+ BKE_object_get_evaluated_mesh(ob_eval);
}
return me;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 51d397a44bc..4d7d5861a09 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -363,11 +363,11 @@ static void object_update_from_subsurf_ccg(Object *object)
* (happens on dependency graph free where order of CoW-ed IDs free is undefined).
*
* Good news is: such mesh does not have modifiers applied, so no need to worry about CCG. */
- if (!object->runtime.is_mesh_eval_owned) {
+ if (!object->runtime.is_data_eval_owned) {
return;
}
/* Object was never evaluated, so can not have CCG subdivision surface. */
- Mesh *mesh_eval = object->runtime.mesh_eval;
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object);
if (mesh_eval == NULL) {
return;
}
@@ -410,13 +410,13 @@ static void object_update_from_subsurf_ccg(Object *object)
/* TODO(sergey): Solve this somehow, to be fully stable for threaded
* evaluation environment.
*/
- /* NOTE: runtime.mesh_orig is what was before assigning mesh_eval,
+ /* NOTE: runtime.data_orig is what was before assigning mesh_eval,
* it is orig as in what was in object_eval->data before evaluating
* modifier stack.
*
* mesh_cow is a copy-on-written version od object_orig->data.
*/
- Mesh *mesh_cow = object->runtime.mesh_orig;
+ Mesh *mesh_cow = (Mesh *)object->runtime.data_orig;
copy_ccg_data(mesh_cow, mesh_orig, CD_MDISPS);
copy_ccg_data(mesh_cow, mesh_orig, CD_GRID_PAINT_MASK);
/* Everything is now up-to-date. */
@@ -424,6 +424,33 @@ static void object_update_from_subsurf_ccg(Object *object)
subdiv_ccg->dirty.hidden = false;
}
+/* Assign data after modifier stack evaluation. */
+void BKE_object_eval_assign_data(Object *object_eval, ID *data_eval, bool is_owned)
+{
+ BLI_assert(object_eval->id.tag & LIB_TAG_COPIED_ON_WRITE);
+ BLI_assert(object_eval->runtime.data_eval == NULL);
+ BLI_assert(data_eval->tag & LIB_TAG_NO_MAIN);
+
+ if (is_owned) {
+ /* Set flag for debugging. */
+ data_eval->tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
+ }
+
+ /* Assigned evaluated data. */
+ object_eval->runtime.data_eval = data_eval;
+ object_eval->runtime.is_data_eval_owned = is_owned;
+
+ /* Overwrite data of evaluated object, if the datablock types match. */
+ ID *data = object_eval->data;
+ if (GS(data->name) == GS(data_eval->name)) {
+ /* NOTE: we are not supposed to invoke evaluation for original objects,
+ * but some areas are still being ported, so we play safe here. */
+ if (object_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) {
+ object_eval->data = data_eval;
+ }
+ }
+}
+
/* free data derived from mesh, called when mesh changes or is freed */
void BKE_object_free_derived_caches(Object *ob)
{
@@ -431,17 +458,18 @@ void BKE_object_free_derived_caches(Object *ob)
object_update_from_subsurf_ccg(ob);
- /* Restore initial pointer. */
- if (ob->runtime.mesh_orig != NULL) {
- ob->data = ob->runtime.mesh_orig;
- }
-
- if (ob->runtime.mesh_eval != NULL) {
- if (ob->runtime.is_mesh_eval_owned) {
- Mesh *mesh_eval = ob->runtime.mesh_eval;
- BKE_mesh_eval_delete(mesh_eval);
+ if (ob->runtime.data_eval != NULL) {
+ if (ob->runtime.is_data_eval_owned) {
+ ID *data_eval = ob->runtime.data_eval;
+ if (GS(data_eval->name) == ID_ME) {
+ BKE_mesh_eval_delete((Mesh *)data_eval);
+ }
+ else {
+ BKE_libblock_free_datablock(data_eval, 0);
+ MEM_freeN(data_eval);
+ }
}
- ob->runtime.mesh_eval = NULL;
+ ob->runtime.data_eval = NULL;
}
if (ob->runtime.mesh_deform_eval != NULL) {
Mesh *mesh_deform_eval = ob->runtime.mesh_deform_eval;
@@ -449,6 +477,12 @@ void BKE_object_free_derived_caches(Object *ob)
ob->runtime.mesh_deform_eval = NULL;
}
+ /* Restore initial pointer for copy-on-write datablocks, object->data
+ * might be pointing to an evaluated datablock data was just freed above. */
+ if (ob->runtime.data_orig != NULL) {
+ ob->data = ob->runtime.data_orig;
+ }
+
BKE_object_to_mesh_clear(ob);
BKE_object_free_curve_cache(ob);
@@ -2308,7 +2342,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
if (par->type == OB_MESH) {
Mesh *me = par->data;
BMEditMesh *em = me->edit_mesh;
- Mesh *me_eval = (em) ? em->mesh_eval_final : par->runtime.mesh_eval;
+ Mesh *me_eval = (em) ? em->mesh_eval_final : BKE_object_get_evaluated_mesh(par);
if (me_eval) {
int count = 0;
@@ -3067,12 +3101,12 @@ void BKE_object_foreach_display_point(Object *ob,
void (*func_cb)(const float[3], void *),
void *user_data)
{
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
float co[3];
- if (ob->runtime.mesh_eval) {
- const Mesh *me = ob->runtime.mesh_eval;
- const MVert *mv = me->mvert;
- const int totvert = me->totvert;
+ if (mesh_eval != NULL) {
+ const MVert *mv = mesh_eval->mvert;
+ const int totvert = mesh_eval->totvert;
for (int i = 0; i < totvert; i++, mv++) {
mul_v3_m4v3(co, obmat, mv->co);
func_cb(co, user_data);
@@ -3342,24 +3376,11 @@ 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)
+/** Get evaluated mesh for given object. */
+Mesh *BKE_object_get_evaluated_mesh(Object *object)
{
- 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;
+ ID *data_eval = object->runtime.data_eval;
+ return (data_eval && GS(data_eval->name) == ID_ME) ? (Mesh *)data_eval : NULL;
}
/* Get mesh which is not affected by modifiers:
@@ -3370,11 +3391,11 @@ Mesh *BKE_object_get_final_mesh(Object *object)
*/
Mesh *BKE_object_get_pre_modified_mesh(Object *object)
{
- if (object->runtime.mesh_orig != NULL) {
+ if (object->type == OB_MESH && object->runtime.data_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(object->runtime.data_orig->orig_id == ((Object *)object->id.orig_id)->data);
+ Mesh *result = (Mesh *)object->runtime.data_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;
@@ -3925,7 +3946,7 @@ void BKE_object_runtime_reset(Object *object)
void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
{
Object_Runtime *runtime = &object->runtime;
- runtime->mesh_eval = NULL;
+ runtime->data_eval = NULL;
runtime->mesh_deform_eval = NULL;
runtime->curve_cache = NULL;
runtime->gpencil_cache = NULL;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index c10ab3cddab..28b6e0d4e02 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -426,7 +426,7 @@ static void make_duplis_verts(const DupliContext *ctx)
vdd.me_eval = vdd.edit_mesh->mesh_eval_cage;
}
else {
- vdd.me_eval = parent->runtime.mesh_eval;
+ vdd.me_eval = BKE_object_get_evaluated_mesh(parent);
}
if (vdd.me_eval == NULL) {
@@ -702,7 +702,7 @@ static void make_duplis_faces(const DupliContext *ctx)
fdd.me_eval = em->mesh_eval_cage;
}
else {
- fdd.me_eval = parent->runtime.mesh_eval;
+ fdd.me_eval = BKE_object_get_evaluated_mesh(parent);
}
if (fdd.me_eval == NULL) {
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 366fd0950fa..c647afdd00a 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -398,8 +398,8 @@ void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data)
void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
{
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
- if (object->type == OB_MESH && !object->runtime.is_mesh_eval_owned) {
- Mesh *mesh_input = object->runtime.mesh_orig;
+ if (object->type == OB_MESH && !object->runtime.is_data_eval_owned) {
+ Mesh *mesh_input = (Mesh *)object->runtime.data_orig;
Mesh_Runtime *mesh_runtime = &mesh_input->runtime;
BLI_mutex_lock(mesh_runtime->eval_mutex);
BKE_object_data_select_update(depsgraph, object->data);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 2cc1681d436..4da7d8d007a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1351,7 +1351,7 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
/* Update after mesh evaluation in the dependency graph, to rebuild PBVH or
* other data when modifiers change the mesh. */
Object *ob_orig = DEG_get_original_object(ob_eval);
- Mesh *me_eval = ob_eval->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
BLI_assert(me_eval != NULL);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index c2180e50b74..494c5e21613 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -332,22 +332,24 @@ void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src
/* get the appropriate evaluated mesh based on rigid body mesh source */
static Mesh *rigidbody_get_mesh(Object *ob)
{
+ BLI_assert(ob->type == OB_MESH);
+
switch (ob->rigidbody_object->mesh_source) {
case RBO_MESH_DEFORM:
return ob->runtime.mesh_deform_eval;
case RBO_MESH_FINAL:
- return ob->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(ob);
case RBO_MESH_BASE:
/* This mesh may be used for computing looptris, which should be done
* on the original; otherwise every time the CoW is recreated it will
* have to be recomputed. */
BLI_assert(ob->rigidbody_object->mesh_source == RBO_MESH_BASE);
- return ob->runtime.mesh_orig;
+ return (Mesh *)ob->runtime.data_orig;
}
/* Just return something sensible so that at least Blender won't crash. */
BLI_assert(!"Unknown mesh source");
- return ob->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(ob);
}
/* create collision shape of mesh - convex hull */