/** * \note Only use in object mode. */ static void validate_object_select_id( struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, Object *obact) { RegionView3D *rv3d = ar->regiondata; Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id); Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact); BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) || BKE_paint_select_face_test(obact_eval))) { /* do nothing */ } /* texture paint mode sampling */ else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) && (v3d->shading.type > OB_WIRE)) { /* do nothing */ } else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) { /* do nothing */ } else { v3d->flag &= ~V3D_INVALID_BACKBUF; return; } if (!(v3d->flag & V3D_INVALID_BACKBUF)) { return; } if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) { uint dummy_vert_ofs, dummy_edge_ofs, dummy_face_ofs; DRW_framebuffer_select_id_setup(ar, true); DRW_draw_select_id_object(scene_eval, rv3d, obact_eval, scene->toolsettings->selectmode, false, 1, &dummy_vert_ofs, &dummy_edge_ofs, &dummy_face_ofs); DRW_framebuffer_select_id_release(ar); } /* TODO: Create a flag in `DRW_manager` because the drawing is no longer * made on the backbuffer in this case. */ v3d->flag &= ~V3D_INVALID_BACKBUF; }
void ED_view3d_backbuf_depth_validate(ViewContext *vc) { if (vc->v3d->flag & V3D_INVALID_BACKBUF) { ARegion *ar = vc->ar; Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact); if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) { GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); DRW_draw_depth_object(vc->ar, viewport, obact_eval); } vc->v3d->flag &= ~V3D_INVALID_BACKBUF; } }
static void vpaint_proj_dm_map_cosnos_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob, struct VertProjHandle *vp_handle) { Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *me = ob->data; CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX; Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert); BKE_mesh_foreach_mapped_vert( me_eval, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, MESH_FOREACH_USE_NORMAL); }
static Subdiv *multires_create_subdiv_for_reshape(struct Depsgraph *depsgraph, /*const*/ Object *object, const MultiresModifierData *mmd) { Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *object_eval = DEG_get_evaluated_object(depsgraph, object); Mesh *deformed_mesh = mesh_get_eval_deform( depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); SubdivSettings subdiv_settings; BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, deformed_mesh); if (!BKE_subdiv_eval_update_from_mesh(subdiv, deformed_mesh)) { BKE_subdiv_free(subdiv); return NULL; } return subdiv; }
static void rna_Object_calc_matrix_camera(Object *ob, Depsgraph *depsgraph, float mat_ret[16], int width, int height, float scalex, float scaley) { const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); CameraParams params; /* setup parameters */ BKE_camera_params_init(¶ms); BKE_camera_params_from_object(¶ms, ob_eval); /* compute matrix, viewplane, .. */ BKE_camera_params_compute_viewplane(¶ms, width, height, scalex, scaley); BKE_camera_params_compute_matrix(¶ms); copy_m4_m4((float(*)[4])mat_ret, params.winmat); }
static Object *eval_object_ensure(Object *ob, bContext *C, ReportList *reports, PointerRNA *rnaptr_depsgraph) { if (ob->runtime.mesh_eval == NULL) { Object *ob_orig = ob; Depsgraph *depsgraph = rnaptr_depsgraph != NULL ? rnaptr_depsgraph->data : NULL; if (depsgraph == NULL) { depsgraph = CTX_data_depsgraph(C); } if (depsgraph != NULL) { ob = DEG_get_evaluated_object(depsgraph, ob); } if (ob == NULL || ob->runtime.mesh_eval == NULL) { BKE_reportf( reports, RPT_ERROR, "Object '%s' has no evaluated mesh data", ob_orig->id.name + 2); return NULL; } } return ob; }
static void vpaint_proj_dm_map_cosnos_update(struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl}; Object *ob = vp_handle->ob; Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *me = ob->data; CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX; Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); /* quick sanity check - we shouldn't have to run this if there are no modifiers */ BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false); copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX); BKE_mesh_foreach_mapped_vert( me_eval, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, MESH_FOREACH_USE_NORMAL); }
void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob) { /* make new mesh data from the original copy */ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH); ListBase nurblist = {NULL, NULL}; BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0); BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1); if (nurblist.first) { Curve *cu = BKE_curve_add(bmain, ob->id.name + 2, OB_CURVE); cu->flag |= CU_3D; cu->nurb = nurblist; id_us_min(&((Mesh *)ob->data)->id); ob->data = cu; ob->type = OB_CURVE; BKE_object_free_derived_caches(ob); } }
/* copy the face flags, most importantly selection from the mesh to the final derived mesh, * use in object mode when selecting faces (while painting) */ void paintface_flush_flags(struct bContext *C, Object *ob, short flag) { Mesh *me = BKE_mesh_from_object(ob); MPoly *polys, *mp_orig; const int *index_array = NULL; int totpoly; int i; BLI_assert((flag & ~(SELECT | ME_HIDE)) == 0); if (me == NULL) { return; } /* note, call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags */ /* we could call this directly in all areas that change selection, * since this could become slow for realtime updates (circle-select for eg) */ if (flag & SELECT) { BKE_mesh_flush_select_from_polys(me); } Depsgraph *depsgraph = CTX_data_depsgraph(C); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); if (ob_eval == NULL) { return; } Mesh *me_orig = ob_eval->runtime.mesh_orig; Mesh *me_eval = ob_eval->runtime.mesh_eval; bool updated = false; if (me_orig != NULL && me_eval != NULL && me_orig->totpoly == me->totpoly) { /* Update the COW copy of the mesh. */ for (i = 0; i < me->totpoly; i++) { me_orig->mpoly[i].flag = me->mpoly[i].flag; } /* If the mesh has only deform modifiers, the evaluated mesh shares arrays. */ if (me_eval->mpoly == me_orig->mpoly) { updated = true; } /* Mesh polys => Final derived polys */ else if ((index_array = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) { polys = me_eval->mpoly; totpoly = me_eval->totpoly; /* loop over final derived polys */ for (i = 0; i < totpoly; i++) { if (index_array[i] != ORIGINDEX_NONE) { /* Copy flags onto the final derived poly from the original mesh poly */ mp_orig = me->mpoly + index_array[i]; polys[i].flag = mp_orig->flag; } } updated = true; } } if (updated) { if (flag & ME_HIDE) { BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_ALL); } else { BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_SELECT_PAINT); } DEG_id_tag_update(ob->data, ID_RECALC_SELECT); } else { DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT); } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); }
/* settings: 1 - preview, 2 - render * * The convention goes as following: * * - Passing original object with apply_modifiers=false will give a * non-modified non-deformed mesh. * The result mesh will point to datablocks from the original "domain". For * example, materials will be original. * * - Passing original object with apply_modifiers=true will give a mesh which * has all modifiers applied. * The result mesh will point to datablocks from the original "domain". For * example, materials will be original. * * - Passing evaluated object will ignore apply_modifiers argument, and the * result always contains all modifiers applied. * The result mesh will point to an evaluated datablocks. For example, * materials will be an evaluated IDs from the dependency graph. */ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph, Main *bmain, Scene *sce, Object *ob, const bool apply_modifiers, const bool calc_undeformed) { Mesh *tmpmesh; Curve *tmpcu = NULL, *copycu; int i; const bool render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); bool effective_apply_modifiers = apply_modifiers; bool do_mat_id_data_us = true; Object *object_input = ob; Object *object_eval = DEG_get_evaluated_object(depsgraph, object_input); Object object_for_eval; if (object_eval == object_input) { /* Evaluated mesh contains all modifiers applied already. * The other types of object has them applied, but are stored in other * data structures than a mesh. So need to apply modifiers again on a * temporary copy before converting result to mesh. */ if (object_input->type == OB_MESH) { effective_apply_modifiers = false; } else { effective_apply_modifiers = true; } object_for_eval = *object_eval; } else { if (apply_modifiers) { object_for_eval = *object_eval; if (object_for_eval.runtime.mesh_orig != NULL) { object_for_eval.data = object_for_eval.runtime.mesh_orig; } } else { object_for_eval = *object_input; } } const bool cage = !effective_apply_modifiers; /* perform the mesh extraction based on type */ switch (object_for_eval.type) { case OB_FONT: case OB_CURVE: case OB_SURF: { ListBase dispbase = {NULL, NULL}; Mesh *me_eval_final = NULL; int uv_from_orco; /* copies object and modifiers (but not the data) */ Object *tmpobj; BKE_id_copy_ex(NULL, &object_for_eval.id, (ID **)&tmpobj, LIB_ID_COPY_LOCALIZE); tmpcu = (Curve *)tmpobj->data; /* Copy cached display list, it might be needed by the stack evaluation. * Ideally stack should be able to use render-time display list, but doing * so is quite tricky and not safe so close to the release. * * TODO(sergey): Look into more proper solution. */ if (object_for_eval.runtime.curve_cache != NULL) { if (tmpobj->runtime.curve_cache == NULL) { tmpobj->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); } BKE_displist_copy(&tmpobj->runtime.curve_cache->disp, &object_for_eval.runtime.curve_cache->disp); } /* if getting the original caged mesh, delete object modifiers */ if (cage) { BKE_object_free_modifiers(tmpobj, LIB_ID_CREATE_NO_USER_REFCOUNT); } /* copies the data, but *not* the shapekeys. */ BKE_id_copy_ex(NULL, object_for_eval.data, (ID **)©cu, LIB_ID_COPY_LOCALIZE); tmpobj->data = copycu; /* make sure texture space is calculated for a copy of curve, * it will be used for the final result. */ BKE_curve_texspace_calc(copycu); /* temporarily set edit so we get updates from edit mode, but * also because for text datablocks copying it while in edit * mode gives invalid data structures */ copycu->editfont = tmpcu->editfont; copycu->editnurb = tmpcu->editnurb; /* get updated display list, and convert to a mesh */ BKE_displist_make_curveTypes_forRender( depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, NULL); copycu->editfont = NULL; copycu->editnurb = NULL; tmpobj->runtime.mesh_eval = me_eval_final; /* convert object type to mesh */ uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; BKE_mesh_from_nurbs_displist( bmain, tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2, true); /* Function above also frees copycu (aka tmpobj->data), make this obvious here. */ copycu = NULL; tmpmesh = tmpobj->data; id_us_min( &tmpmesh->id); /* Gets one user from its creation in BKE_mesh_from_nurbs_displist(). */ BKE_displist_free(&dispbase); /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked. * if it didn't the curve did not have any segments or otherwise * would have generated an empty mesh */ if (tmpobj->type != OB_MESH) { BKE_id_free(NULL, tmpobj); return NULL; } BKE_id_free(NULL, tmpobj); /* XXX The curve to mesh conversion is convoluted... * But essentially, BKE_mesh_from_nurbs_displist() * already transfers the ownership of materials from the temp copy of the Curve ID to the * new Mesh ID, so we do not want to increase materials' usercount later. */ do_mat_id_data_us = false; break; } case OB_MBALL: { /* metaballs don't have modifiers, so just convert to mesh */ Object *basis_ob = BKE_mball_basis_find(sce, object_input); /* todo, re-generatre for render-res */ /* metaball_polygonize(scene, ob) */ if (basis_ob != object_input) { /* Only do basis metaball. */ return NULL; } tmpmesh = BKE_mesh_add(bmain, ((ID *)object_for_eval.data)->name + 2); /* BKE_mesh_add gives us a user count we don't need */ id_us_min(&tmpmesh->id); if (render) { ListBase disp = {NULL, NULL}; BKE_displist_make_mball_forRender(depsgraph, sce, &object_for_eval, &disp); BKE_mesh_from_metaball(&disp, tmpmesh); BKE_displist_free(&disp); } else { ListBase disp = {NULL, NULL}; if (object_for_eval.runtime.curve_cache) { disp = object_for_eval.runtime.curve_cache->disp; } BKE_mesh_from_metaball(&disp, tmpmesh); } BKE_mesh_texspace_copy_from_object(tmpmesh, &object_for_eval); break; } case OB_MESH: /* copies object and modifiers (but not the data) */ if (cage) { /* copies the data (but *not* the shapekeys). */ Mesh *mesh = object_for_eval.data; BKE_id_copy_ex(bmain, &mesh->id, (ID **)&tmpmesh, 0); /* XXX BKE_mesh_copy() already handles materials usercount. */ do_mat_id_data_us = false; } /* if not getting the original caged mesh, get final derived mesh */ else { /* Make a dummy mesh, saves copying */ Mesh *me_eval; CustomData_MeshMasks mask = CD_MASK_MESH; /* this seems more suitable, exporter, * for example, needs CD_MASK_MDEFORMVERT */ if (calc_undeformed) { mask.vmask |= CD_MASK_ORCO; } if (render) { me_eval = mesh_create_eval_final_render(depsgraph, sce, &object_for_eval, &mask); } else { me_eval = mesh_create_eval_final_view(depsgraph, sce, &object_for_eval, &mask); } tmpmesh = BKE_mesh_add(bmain, ((ID *)object_for_eval.data)->name + 2); BKE_mesh_nomain_to_mesh(me_eval, tmpmesh, &object_for_eval, &mask, true); /* Copy autosmooth settings from original mesh. */ Mesh *me = (Mesh *)object_for_eval.data; tmpmesh->flag |= (me->flag & ME_AUTOSMOOTH); tmpmesh->smoothresh = me->smoothresh; } /* BKE_mesh_add/copy gives us a user count we don't need */ id_us_min(&tmpmesh->id); break; default: /* "Object does not have geometry data") */ return NULL; } /* Copy materials to new mesh */ switch (object_for_eval.type) { case OB_SURF: case OB_FONT: case OB_CURVE: tmpmesh->totcol = tmpcu->totcol; /* free old material list (if it exists) and adjust user counts */ if (tmpcu->mat) { for (i = tmpcu->totcol; i-- > 0;) { /* are we an object material or data based? */ tmpmesh->mat[i] = give_current_material(object_input, i + 1); if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) && tmpmesh->mat[i]) { id_us_plus(&tmpmesh->mat[i]->id); } } } break; case OB_MBALL: { MetaBall *tmpmb = (MetaBall *)object_for_eval.data; tmpmesh->mat = MEM_dupallocN(tmpmb->mat); tmpmesh->totcol = tmpmb->totcol; /* free old material list (if it exists) and adjust user counts */ if (tmpmb->mat) { for (i = tmpmb->totcol; i-- > 0;) { /* are we an object material or data based? */ tmpmesh->mat[i] = give_current_material(object_input, i + 1); if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) && tmpmesh->mat[i]) { id_us_plus(&tmpmesh->mat[i]->id); } } } break; } case OB_MESH: if (!cage) { Mesh *origmesh = object_for_eval.data; tmpmesh->flag = origmesh->flag; tmpmesh->mat = MEM_dupallocN(origmesh->mat); tmpmesh->totcol = origmesh->totcol; tmpmesh->smoothresh = origmesh->smoothresh; if (origmesh->mat) { for (i = origmesh->totcol; i-- > 0;) { /* are we an object material or data based? */ tmpmesh->mat[i] = give_current_material(object_input, i + 1); if (((object_for_eval.matbits && object_for_eval.matbits[i]) || do_mat_id_data_us) && tmpmesh->mat[i]) { id_us_plus(&tmpmesh->mat[i]->id); } } } } break; } /* end copy materials */ return tmpmesh; }