diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
22 files changed, 404 insertions, 504 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index c04079bed22..148c7a6b6c0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -43,7 +43,7 @@ #include "BLI_linklist.h" #include "BLI_task.h" -#include "BKE_cdderivedmesh.h" +#include "BKE_DerivedMesh.h" #include "BKE_colorband.h" #include "BKE_editmesh.h" #include "BKE_key.h" @@ -317,8 +317,6 @@ void DM_init_funcs(DerivedMesh *dm) dm->getTessFaceDataArray = DM_get_tessface_data_layer; dm->getPolyDataArray = DM_get_poly_data_layer; dm->getLoopDataArray = DM_get_loop_data_layer; - - dm->bvhCache = NULL; } /** @@ -411,19 +409,12 @@ void DM_from_template(DerivedMesh *dm, int DM_release(DerivedMesh *dm) { if (dm->needsFree) { - bvhcache_free(&dm->bvhCache); CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); CustomData_free(&dm->faceData, dm->numTessFaceData); CustomData_free(&dm->loopData, dm->numLoopData); CustomData_free(&dm->polyData, dm->numPolyData); - if (dm->mat) { - MEM_freeN(dm->mat); - dm->mat = NULL; - dm->totmat = 0; - } - MEM_SAFE_FREE(dm->looptris.array); dm->looptris.num = 0; dm->looptris.num_alloc = 0; @@ -1728,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); } } @@ -1802,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, @@ -1811,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, @@ -1951,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/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index a55b5dc7817..8d79d106145 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -29,6 +29,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BKE_DerivedMesh.h" #include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" @@ -150,22 +151,6 @@ static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly) memcpy(r_poly, cddm->mpoly, sizeof(*r_poly) * dm->numPolyData); } -static void cdDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - int i; - - if (dm->numVertData) { - for (i = 0; i < dm->numVertData; i++) { - minmax_v3v3_v3(r_min, r_max, cddm->mvert[i].co); - } - } - else { - zero_v3(r_min); - zero_v3(r_max); - } -} - static void cdDM_getVertCo(DerivedMesh *dm, int index, float r_co[3]) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; @@ -193,7 +178,7 @@ static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm) return cddm->pmap; } -void CDDM_recalc_looptri(DerivedMesh *dm) +static void cdDM_recalc_looptri(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; const unsigned int totpoly = dm->numPolyData; @@ -240,8 +225,6 @@ static CDDerivedMesh *cdDM_create(const char *desc) cddm = MEM_callocN(sizeof(*cddm), desc); dm = &cddm->dm; - dm->getMinMax = cdDM_getMinMax; - dm->getNumVerts = cdDM_getNumVerts; dm->getNumEdges = cdDM_getNumEdges; dm->getNumTessFaces = cdDM_getNumTessFaces; @@ -265,7 +248,7 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->getEdgeDataArray = DM_get_edge_data_layer; dm->getTessFaceDataArray = DM_get_tessface_data_layer; - dm->recalcLoopTri = CDDM_recalc_looptri; + dm->recalcLoopTri = cdDM_recalc_looptri; dm->getVertCo = cdDM_getVertCo; dm->getVertNo = cdDM_getVertNo; @@ -277,41 +260,9 @@ static CDDerivedMesh *cdDM_create(const char *desc) return cddm; } -DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys) -{ - CDDerivedMesh *cddm = cdDM_create("CDDM_new dm"); - DerivedMesh *dm = &cddm->dm; - - DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); - - CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); - CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces); - CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys); - - CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); - CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); - CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces); - CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops); - CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys); - - cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); - cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); - cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); - cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP); - cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); - - return dm; -} - -DerivedMesh *CDDM_from_mesh(Mesh *mesh) -{ - return CDDM_from_mesh_ex(mesh, CD_REFERENCE, &CD_MASK_MESH); -} - -DerivedMesh *CDDM_from_mesh_ex(Mesh *mesh, - eCDAllocType alloctype, - const CustomData_MeshMasks *mask) +static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, + eCDAllocType alloctype, + const CustomData_MeshMasks *mask) { CDDerivedMesh *cddm = cdDM_create(__func__); DerivedMesh *dm = &cddm->dm; @@ -370,148 +321,9 @@ DerivedMesh *CDDM_from_mesh_ex(Mesh *mesh, return dm; } -/* TODO(campbell): remove, use BKE_mesh_from_bmesh_for_eval_nomain instead. */ - -/* used for both editbmesh and bmesh */ -static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps) -{ - DerivedMesh *dm = CDDM_new(bm->totvert, bm->totedge, 0, bm->totloop, bm->totface); - - CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - BMIter iter; - BMVert *eve; - BMEdge *eed; - BMFace *efa; - MVert *mvert = cddm->mvert; - MEdge *medge = cddm->medge; - MLoop *mloop = cddm->mloop; - MPoly *mpoly = cddm->mpoly; - int *index, add_orig; - CustomData_MeshMasks mask = {0}; - unsigned int i, j; - - const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); - const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); - const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); - - dm->deformedOnly = 1; - - /* don't add origindex layer if one already exists */ - add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX); - - mask = CD_MASK_DERIVEDMESH; - if (use_mdisps) { - mask.lmask |= CD_MASK_MDISPS; - } - - /* don't process shapekeys, we only feed them through the modifier stack as needed, - * e.g. for applying modifiers or the like*/ - mask.vmask &= ~CD_MASK_SHAPEKEY; - CustomData_merge(&bm->vdata, &dm->vertData, mask.vmask, CD_CALLOC, dm->numVertData); - CustomData_merge(&bm->edata, &dm->edgeData, mask.emask, CD_CALLOC, dm->numEdgeData); - CustomData_merge(&bm->ldata, &dm->loopData, mask.lmask, CD_CALLOC, dm->numLoopData); - CustomData_merge(&bm->pdata, &dm->polyData, mask.pmask, CD_CALLOC, dm->numPolyData); - - index = dm->getVertDataArray(dm, CD_ORIGINDEX); - - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - MVert *mv = &mvert[i]; - - copy_v3_v3(mv->co, eve->co); - - BM_elem_index_set(eve, i); /* set_inline */ - - normal_float_to_short_v3(mv->no, eve->no); - - mv->flag = BM_vert_flag_to_mflag(eve); - - if (cd_vert_bweight_offset != -1) { - mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); - } - - if (add_orig) { - *index++ = i; - } - - CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i); - } - bm->elem_index_dirty &= ~BM_VERT; - - index = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { - MEdge *med = &medge[i]; - - BM_elem_index_set(eed, i); /* set_inline */ - - med->v1 = BM_elem_index_get(eed->v1); - med->v2 = BM_elem_index_get(eed->v2); - - med->flag = BM_edge_flag_to_mflag(eed); - - /* handle this differently to editmode switching, - * only enable draw for single user edges rather then calculating angle */ - if ((med->flag & ME_EDGEDRAW) == 0) { - if (eed->l && eed->l == eed->l->radial_next) { - med->flag |= ME_EDGEDRAW; - } - } - - if (cd_edge_crease_offset != -1) { - med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); - } - if (cd_edge_bweight_offset != -1) { - med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); - } - - CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i); - if (add_orig) { - *index++ = i; - } - } - bm->elem_index_dirty &= ~BM_EDGE; - - index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); - j = 0; - BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - BMLoop *l_iter; - BMLoop *l_first; - MPoly *mp = &mpoly[i]; - - BM_elem_index_set(efa, i); /* set_inline */ - - mp->totloop = efa->len; - mp->flag = BM_face_flag_to_mflag(efa); - mp->loopstart = j; - mp->mat_nr = efa->mat_nr; - - l_iter = l_first = BM_FACE_FIRST_LOOP(efa); - do { - mloop->v = BM_elem_index_get(l_iter->v); - mloop->e = BM_elem_index_get(l_iter->e); - CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j); - - BM_elem_index_set(l_iter, j); /* set_inline */ - - j++; - mloop++; - } while ((l_iter = l_iter->next) != l_first); - - CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i); - - if (add_orig) { - *index++ = i; - } - } - bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); - - dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); - - return dm; -} - -DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, const bool use_mdisps) +DerivedMesh *CDDM_from_mesh(Mesh *mesh) { - return cddm_from_bmesh_ex(em->bm, use_mdisps); + return cdDM_from_mesh_ex(mesh, CD_REFERENCE, &CD_MASK_MESH); } DerivedMesh *CDDM_copy(DerivedMesh *source) @@ -559,62 +371,3 @@ DerivedMesh *CDDM_copy(DerivedMesh *source) return dm; } - -/* #define DEBUG_CLNORS */ -#ifdef DEBUG_CLNORS -# include "BLI_linklist.h" -#endif - -/* mesh element access functions */ - -MVert *CDDM_get_vert(DerivedMesh *dm, int index) -{ - return &((CDDerivedMesh *)dm)->mvert[index]; -} - -MEdge *CDDM_get_edge(DerivedMesh *dm, int index) -{ - return &((CDDerivedMesh *)dm)->medge[index]; -} - -MFace *CDDM_get_tessface(DerivedMesh *dm, int index) -{ - return &((CDDerivedMesh *)dm)->mface[index]; -} - -MLoop *CDDM_get_loop(DerivedMesh *dm, int index) -{ - return &((CDDerivedMesh *)dm)->mloop[index]; -} - -MPoly *CDDM_get_poly(DerivedMesh *dm, int index) -{ - return &((CDDerivedMesh *)dm)->mpoly[index]; -} - -/* array access functions */ - -MVert *CDDM_get_verts(DerivedMesh *dm) -{ - return ((CDDerivedMesh *)dm)->mvert; -} - -MEdge *CDDM_get_edges(DerivedMesh *dm) -{ - return ((CDDerivedMesh *)dm)->medge; -} - -MFace *CDDM_get_tessfaces(DerivedMesh *dm) -{ - return ((CDDerivedMesh *)dm)->mface; -} - -MLoop *CDDM_get_loops(DerivedMesh *dm) -{ - return ((CDDerivedMesh *)dm)->mloop; -} - -MPoly *CDDM_get_polys(DerivedMesh *dm) -{ - return ((CDDerivedMesh *)dm)->mpoly; -} diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 42efd9a7057..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]; @@ -855,97 +855,93 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar bConstraintTarget *ct = targets->first; /* only evaluate if there is a target */ - if (VALID_CONS_TARGET(ct)) { - float parmat[4][4]; + if (!VALID_CONS_TARGET(ct)) { + return; + } - /* simple matrix parenting */ - if (data->flag == CHILDOF_ALL) { + float parmat[4][4]; + /* Simple matrix parenting. */ + if ((data->flag & CHILDOF_ALL) == CHILDOF_ALL) { + copy_m4_m4(parmat, ct->matrix); + } + /* Filter the parent matrix by channel. */ + else { + float loc[3], eul[3], size[3]; - /* 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); + /* 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); - /* 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); + /* disable channels not enabled */ + if (!(data->flag & CHILDOF_LOCX)) { + loc[0] = 0.0f; + } + if (!(data->flag & CHILDOF_LOCY)) { + loc[1] = 0.0f; + } + if (!(data->flag & CHILDOF_LOCZ)) { + loc[2] = 0.0f; + } + if (!(data->flag & CHILDOF_ROTX)) { + eul[0] = 0.0f; + } + if (!(data->flag & CHILDOF_ROTY)) { + eul[1] = 0.0f; + } + if (!(data->flag & CHILDOF_ROTZ)) { + eul[2] = 0.0f; + } + if (!(data->flag & CHILDOF_SIZEX)) { + size[0] = 1.0f; + } + if (!(data->flag & CHILDOF_SIZEY)) { + size[1] = 1.0f; + } + if (!(data->flag & CHILDOF_SIZEZ)) { + size[2] = 1.0f; } - 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); + /* make new target mat and offset mat */ + loc_eulO_size_to_mat4(parmat, loc, eul, size, ct->rotOrder); + } - copy_v3_v3(loco, invmat[3]); - mat4_to_eulO(eulo, cob->rotOrder, invmat); - mat4_to_size(sizo, invmat); + /* Compute the inverse matrix if requested. */ + if (data->flag & CHILDOF_SET_INVERSE) { + invert_m4_m4(data->invmat, parmat); - /* disable channels not enabled */ - if (!(data->flag & CHILDOF_LOCX)) { - loc[0] = loco[0] = 0.0f; - } - if (!(data->flag & CHILDOF_LOCY)) { - loc[1] = loco[1] = 0.0f; - } - if (!(data->flag & CHILDOF_LOCZ)) { - loc[2] = loco[2] = 0.0f; - } - if (!(data->flag & CHILDOF_ROTX)) { - eul[0] = eulo[0] = 0.0f; - } - if (!(data->flag & CHILDOF_ROTY)) { - eul[1] = eulo[1] = 0.0f; - } - if (!(data->flag & CHILDOF_ROTZ)) { - eul[2] = eulo[2] = 0.0f; - } - if (!(data->flag & CHILDOF_SIZEX)) { - size[0] = sizo[0] = 1.0f; - } - if (!(data->flag & CHILDOF_SIZEY)) { - size[1] = sizo[1] = 1.0f; - } - if (!(data->flag & CHILDOF_SIZEZ)) { - size[2] = sizo[2] = 1.0f; - } + data->flag &= ~CHILDOF_SET_INVERSE; - /* 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); + /* Write the computed matrix back to the master copy if in COW evaluation. */ + bConstraint *orig_con = constraint_find_original_for_update(cob, con); - /* 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); + if (orig_con != NULL) { + bChildOfConstraint *orig_data = orig_con->data; - /* 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); - - /* 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]; - } + 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 */ @@ -3972,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); @@ -4740,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; @@ -4877,37 +4873,47 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase if (data->flag & OBJECTSOLVER_ACTIVECLIP) { clip = scene->clip; } - if (!camob || !clip) { return; } - if (clip) { - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object; + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *object; + + object = BKE_tracking_object_get_named(tracking, data->object); + if (!object) { + return; + } + + 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); - object = BKE_tracking_object_get_named(tracking, data->object); + BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat); - if (object) { - float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; - float ctime = DEG_get_ctime(depsgraph); - float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime); + invert_m4_m4(imat, mat); + mul_m4_m4m4(parmat, camob->obmat, imat); - BKE_object_where_is_calc_mat4(camob, cammat); + copy_m4_m4(obmat, cob->matrix); - BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat); + /* Recalculate the inverse matrix if requested. */ + if (data->flag & OBJECTSOLVER_SET_INVERSE) { + invert_m4_m4(data->invmat, parmat); - invert_m4_m4(camimat, cammat); - mul_m4_m4m4(parmat, cammat, data->invmat); + data->flag &= ~OBJECTSOLVER_SET_INVERSE; - copy_m4_m4(cammat, camob->obmat); - copy_m4_m4(obmat, cob->matrix); + /* Write the computed matrix back to the master copy if in COW evaluation. */ + bConstraint *orig_con = constraint_find_original_for_update(cob, con); - invert_m4_m4(imat, mat); + if (orig_con != NULL) { + bObjectSolverConstraint *orig_data = orig_con->data; - mul_m4_series(cob->matrix, cammat, imat, camimat, parmat, obmat); + copy_m4_m4(orig_data->invmat, data->invmat); + orig_data->flag &= ~OBJECTSOLVER_SET_INVERSE; } } + + 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 fc310ee720a..6963f629798 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -33,15 +33,16 @@ #include "DNA_object_types.h" #include "DNA_vfont_types.h" -#include "BLI_blenlib.h" -#include "BLI_memarena.h" +#include "BLI_bitmap.h" +#include "BLI_linklist.h" +#include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_memarena.h" #include "BLI_scanfill.h" +#include "BLI_string.h" #include "BLI_utildefines.h" -#include "BLI_linklist.h" #include "BKE_displist.h" -#include "BKE_cdderivedmesh.h" #include "BKE_object.h" #include "BKE_lib_id.h" #include "BKE_mball.h" @@ -1771,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); } @@ -1799,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); @@ -1860,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/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 4c076256d9f..5f727c2d01e 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -27,10 +27,11 @@ #include "DNA_object_types.h" #include "DNA_mesh_types.h" +#include "BLI_bitmap.h" #include "BLI_math.h" +#include "BKE_DerivedMesh.h" #include "BKE_editmesh.h" -#include "BKE_cdderivedmesh.h" #include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_mesh_iterators.h" 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/lattice.c b/source/blender/blenkernel/intern/lattice.c index 02cf7f1cd45..5446640b2dd 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -45,7 +45,6 @@ #include "BKE_animsys.h" #include "BKE_anim.h" -#include "BKE_cdderivedmesh.h" #include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_key.h" 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 2591edb502e..381e43241ea 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -48,7 +48,6 @@ #include "BLT_translation.h" #include "BKE_appdir.h" -#include "BKE_cdderivedmesh.h" #include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_idcode.h" @@ -1020,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/ocean.c b/source/blender/blenkernel/intern/ocean.c index 9faa61f986d..c27fb59835f 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -49,6 +49,8 @@ #include "RE_render_ext.h" +#include "BLI_hash.h" + #ifdef WITH_OCEANSIM /* Ocean code */ @@ -985,11 +987,15 @@ void BKE_ocean_init(struct Ocean *o, } } - /*srand(seed);*/ rng = BLI_rng_new(seed); for (i = 0; i < o->_M; i++) { for (j = 0; j < o->_N; j++) { + /* This ensures we get a value tied to the surface location, avoiding dramatic surface + * change with changing resolution. */ + int new_seed = seed + BLI_hash_int_2d(o->_kx[i] * 360.0f, o->_kz[j] * 360.0f); + + BLI_rng_seed(rng, new_seed); float r1 = gaussRand(rng); float r2 = gaussRand(rng); 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/particle.c b/source/blender/blenkernel/intern/particle.c index 68df93d742a..0a5637c103b 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -68,7 +68,6 @@ #include "BKE_lib_id.h" #include "BKE_modifier.h" #include "BKE_mesh.h" -#include "BKE_cdderivedmesh.h" /* for weight_to_rgb() */ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_deform.h" diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 141e93183fb..efe13fc8817 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1378,6 +1378,138 @@ void BKE_pbvh_update_vertex_data(PBVH *bvh, int flag) } } +static void pbvh_faces_node_visibility_update(PBVH *bvh, PBVHNode *node) +{ + MVert *mvert; + const int *vert_indices; + int totvert, i; + BKE_pbvh_node_num_verts(bvh, node, NULL, &totvert); + BKE_pbvh_node_get_verts(bvh, node, &vert_indices, &mvert); + + for (i = 0; i < totvert; i++) { + MVert *v = &mvert[vert_indices[i]]; + if (!(v->flag & ME_HIDE)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } + + BKE_pbvh_node_fully_hidden_set(node, true); +} + +static void pbvh_grids_node_visibility_update(PBVH *bvh, PBVHNode *node) +{ + CCGElem **grids; + BLI_bitmap **grid_hidden; + int *grid_indices, totgrid, i; + + BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, NULL, &grids); + grid_hidden = BKE_pbvh_grid_hidden(bvh); + CCGKey key = *BKE_pbvh_get_grid_key(bvh); + + for (i = 0; i < totgrid; i++) { + int g = grid_indices[i], x, y; + BLI_bitmap *gh = grid_hidden[g]; + + if (!gh) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + + for (y = 0; y < key.grid_size; y++) { + for (x = 0; x < key.grid_size; x++) { + if (!BLI_BITMAP_TEST(gh, y * key.grid_size + x)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } + } + } + BKE_pbvh_node_fully_hidden_set(node, true); +} + +static void pbvh_bmesh_node_visibility_update(PBVHNode *node) +{ + GSet *unique, *other; + + unique = BKE_pbvh_bmesh_node_unique_verts(node); + other = BKE_pbvh_bmesh_node_other_verts(node); + + GSetIterator gs_iter; + + GSET_ITER (gs_iter, unique) { + BMVert *v = BLI_gsetIterator_getKey(&gs_iter); + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } + + GSET_ITER (gs_iter, other) { + BMVert *v = BLI_gsetIterator_getKey(&gs_iter); + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } + + BKE_pbvh_node_fully_hidden_set(node, true); +} + +static void pbvh_update_visibility_task_cb(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + + PBVHUpdateData *data = userdata; + PBVH *bvh = data->bvh; + PBVHNode *node = data->nodes[n]; + if (node->flag & PBVH_UpdateMask) { + switch (BKE_pbvh_type(bvh)) { + case PBVH_FACES: + pbvh_faces_node_visibility_update(bvh, node); + break; + case PBVH_GRIDS: + pbvh_grids_node_visibility_update(bvh, node); + break; + case PBVH_BMESH: + pbvh_bmesh_node_visibility_update(node); + break; + } + node->flag &= ~PBVH_UpdateMask; + } +} + +static void pbvh_update_visibility(PBVH *bvh, PBVHNode **nodes, int totnode) +{ + PBVHUpdateData data = { + .bvh = bvh, + .nodes = nodes, + }; + + PBVHParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range(0, totnode, &data, pbvh_update_visibility_task_cb, &settings); +} + +void BKE_pbvh_update_visibility(PBVH *bvh) +{ + if (!bvh->nodes) { + return; + } + + PBVHNode **nodes; + int totnode; + + BKE_pbvh_search_gather( + bvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateVisibility), &nodes, &totnode); + pbvh_update_visibility(bvh, nodes, totnode); + + if (nodes) { + MEM_freeN(nodes); + } +} + void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]) { PBVHIter iter; @@ -1533,6 +1665,11 @@ void BKE_pbvh_node_mark_normals_update(PBVHNode *node) node->flag |= PBVH_UpdateNormals; } +void BKE_pbvh_node_mark_visibility_update(PBVHNode *node) +{ + node->flag |= PBVH_UpdateVisibility; +} + void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden) { BLI_assert(node->flag & PBVH_Leaf); 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 */ diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c index 8654c50a783..3c1a9c4d3d6 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.c +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -623,9 +623,9 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg) MEM_SAFE_FREE(subdiv_ccg->grid_flag_mats); if (subdiv_ccg->grid_hidden != NULL) { for (int grid_index = 0; grid_index < num_grids; grid_index++) { - MEM_freeN(subdiv_ccg->grid_hidden[grid_index]); + MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]); } - MEM_freeN(subdiv_ccg->grid_hidden); + MEM_SAFE_FREE(subdiv_ccg->grid_hidden); } if (subdiv_ccg->subdiv != NULL) { BKE_subdiv_free(subdiv_ccg->subdiv); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 33a9875151a..da3c03cf705 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -838,7 +838,8 @@ static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3]) } } -static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) +/* UNUSED, keep since this functionality may be useful in the future. */ +static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], float r_max[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGSubSurf *ss = ccgdm->ss; @@ -2042,7 +2043,6 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm) static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) { - ccgdm->dm.getMinMax = ccgDM_getMinMax; ccgdm->dm.getNumVerts = ccgDM_getNumVerts; ccgdm->dm.getNumEdges = ccgDM_getNumEdges; ccgdm->dm.getNumLoops = ccgDM_getNumLoops; |