diff options
35 files changed, 201 insertions, 1184 deletions
diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp index ca1aa6329d9..109408c354d 100644 --- a/intern/cycles/blender/object.cpp +++ b/intern/cycles/blender/object.cpp @@ -66,12 +66,6 @@ bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info) return true; } - /* Other object types that are not meshes but evaluate to meshes are presented to render engines - * as separate instance objects. Metaballs have not been affected by that change yet. */ - if (type == BL::Object::type_META) { - return true; - } - return b_ob_data.is_a(&RNA_Mesh); } diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index cdca740555a..6551e732300 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -24,8 +24,6 @@ enum { DL_SURF = 2, /** Triangles. */ DL_INDEX3 = 4, - /** Quads, with support for triangles (when values of the 3rd and 4th indices match). */ - DL_INDEX4 = 5, // DL_VERTCOL = 6, /* UNUSED */ /** Isolated points. */ DL_VERTS = 7, @@ -62,15 +60,12 @@ typedef struct DispList { } DispList; DispList *BKE_displist_find(struct ListBase *lb, int type); -void BKE_displist_normals_add(struct ListBase *lb); -void BKE_displist_count(const struct ListBase *lb, int *totvert, int *totface, int *tottri); void BKE_displist_free(struct ListBase *lb); void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, bool for_render); -void BKE_displist_make_mball(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph, const struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 9fa59c9e81b..aa4b1c69d24 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -27,7 +27,6 @@ void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object * struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name); void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du); -bool object_deform_mball(struct Object *ob, struct ListBase *dispbase); void outside_lattice(struct Lattice *lt); float (*BKE_lattice_vert_coords_alloc(const struct Lattice *lt, int *r_vert_len))[3]; diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index a23d010b51f..667a1044e7b 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -55,14 +55,6 @@ bool BKE_mball_is_basis(const struct Object *ob); struct Object *BKE_mball_basis_find(struct Scene *scene, struct Object *ob); /** - * Compute bounding box of all meta-elements / meta-ball. - * - * Bounding box is computed from polygonized surface. \a ob is - * basic meta-balls (with name `Meta` for example). All other meta-ball objects - * (with names `Meta.001`, `Meta.002`, etc) are included in this bounding-box. - */ -void BKE_mball_texspace_calc(struct Object *ob); -/** * Return or compute bounding-box for given meta-ball object. */ struct BoundBox *BKE_mball_boundbox_get(struct Object *ob); @@ -110,18 +102,7 @@ bool BKE_mball_select_swap_multi_ex(struct Base **bases, int bases_len); /* **** Depsgraph evaluation **** */ -struct Depsgraph; - -/* Draw Cache */ - -enum { - BKE_MBALL_BATCH_DIRTY_ALL = 0, -}; -void BKE_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode); -void BKE_mball_batch_cache_free(struct MetaBall *mb); - -extern void (*BKE_mball_batch_cache_dirty_tag_cb)(struct MetaBall *mb, int mode); -extern void (*BKE_mball_batch_cache_free_cb)(struct MetaBall *mb); +void BKE_mball_data_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_mball_tessellate.h b/source/blender/blenkernel/BKE_mball_tessellate.h index 2dc16dc64d6..0840c51bb4d 100644 --- a/source/blender/blenkernel/BKE_mball_tessellate.h +++ b/source/blender/blenkernel/BKE_mball_tessellate.h @@ -12,11 +12,11 @@ extern "C" { struct Depsgraph; struct Object; struct Scene; +struct Mesh; -void BKE_mball_polygonize(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob, - struct ListBase *dispbase); +struct Mesh *BKE_mball_polygonize(struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *ob); void BKE_mball_cubeTable_free(void); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index b9f6b4b73f3..8cf973b785c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -193,7 +193,6 @@ void BKE_mesh_orco_ensure(struct Object *ob, struct Mesh *mesh); struct Mesh *BKE_mesh_from_object(struct Object *ob); void BKE_mesh_assign_object(struct Main *bmain, struct Object *ob, struct Mesh *me); -void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me); void BKE_mesh_to_curve_nurblist(const struct Mesh *me, struct ListBase *nurblist, int edge_users_test); diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index 0b3ed584246..65f6dc174f7 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -34,10 +34,8 @@ #include "BKE_displist.h" #include "BKE_geometry_set.hh" #include "BKE_key.h" -#include "BKE_lattice.h" #include "BKE_lib_id.h" #include "BKE_mball.h" -#include "BKE_mball_tessellate.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -86,120 +84,6 @@ DispList *BKE_displist_find(ListBase *lb, int type) return nullptr; } -void BKE_displist_normals_add(ListBase *lb) -{ - float *vdata, *ndata, nor[3]; - float *v1, *v2, *v3, *v4; - float *n1, *n2, *n3, *n4; - int a, b, p1, p2, p3, p4; - - LISTBASE_FOREACH (DispList *, dl, lb) { - if (dl->type == DL_INDEX3) { - if (dl->nors == nullptr) { - dl->nors = (float *)MEM_callocN(sizeof(float[3]), __func__); - - if (dl->flag & DL_BACK_CURVE) { - dl->nors[2] = -1.0f; - } - else { - dl->nors[2] = 1.0f; - } - } - } - else if (dl->type == DL_SURF) { - if (dl->nors == nullptr) { - dl->nors = (float *)MEM_callocN(sizeof(float[3]) * dl->nr * dl->parts, __func__); - - vdata = dl->verts; - ndata = dl->nors; - - for (a = 0; a < dl->parts; a++) { - - if (BKE_displist_surfindex_get(dl, a, &b, &p1, &p2, &p3, &p4) == 0) { - break; - } - - v1 = vdata + 3 * p1; - n1 = ndata + 3 * p1; - v2 = vdata + 3 * p2; - n2 = ndata + 3 * p2; - v3 = vdata + 3 * p3; - n3 = ndata + 3 * p3; - v4 = vdata + 3 * p4; - n4 = ndata + 3 * p4; - - for (; b < dl->nr; b++) { - normal_quad_v3(nor, v1, v3, v4, v2); - - add_v3_v3(n1, nor); - add_v3_v3(n2, nor); - add_v3_v3(n3, nor); - add_v3_v3(n4, nor); - - v2 = v1; - v1 += 3; - v4 = v3; - v3 += 3; - n2 = n1; - n1 += 3; - n4 = n3; - n3 += 3; - } - } - a = dl->parts * dl->nr; - v1 = ndata; - while (a--) { - normalize_v3(v1); - v1 += 3; - } - } - } - } -} - -void BKE_displist_count(const ListBase *lb, int *totvert, int *totface, int *tottri) -{ - LISTBASE_FOREACH (const DispList *, dl, lb) { - int vert_tot = 0; - int face_tot = 0; - int tri_tot = 0; - bool cyclic_u = dl->flag & DL_CYCL_U; - bool cyclic_v = dl->flag & DL_CYCL_V; - - switch (dl->type) { - case DL_SURF: { - int segments_u = dl->nr - (cyclic_u == false); - int segments_v = dl->parts - (cyclic_v == false); - vert_tot = dl->nr * dl->parts; - face_tot = segments_u * segments_v; - tri_tot = face_tot * 2; - break; - } - case DL_INDEX3: { - vert_tot = dl->nr; - face_tot = dl->parts; - tri_tot = face_tot; - break; - } - case DL_INDEX4: { - vert_tot = dl->nr; - face_tot = dl->parts; - tri_tot = face_tot * 2; - break; - } - case DL_POLY: - case DL_SEGM: { - vert_tot = dl->nr * dl->parts; - break; - } - } - - *totvert += vert_tot; - *totface += face_tot; - *tottri += tri_tot; - } -} - bool BKE_displist_surfindex_get( const DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4) { @@ -625,27 +509,6 @@ float BKE_displist_calc_taper( return displist_calc_taper(depsgraph, scene, taperobj, fac); } -void BKE_displist_make_mball(Depsgraph *depsgraph, Scene *scene, Object *ob) -{ - if (!ob || ob->type != OB_MBALL) { - return; - } - - if (ob == BKE_mball_basis_find(scene, ob)) { - if (ob->runtime.curve_cache) { - BKE_displist_free(&(ob->runtime.curve_cache->disp)); - } - else { - ob->runtime.curve_cache = MEM_cnew<CurveCache>(__func__); - } - - BKE_mball_polygonize(depsgraph, scene, ob, &ob->runtime.curve_cache->disp); - BKE_mball_texspace_calc(ob); - - object_deform_mball(ob, &ob->runtime.curve_cache->disp); - } -} - static ModifierData *curve_get_tessellate_point(const Scene *scene, const Object *ob, const bool for_render, @@ -1504,7 +1367,7 @@ void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3]) bool doit = false; LISTBASE_FOREACH (const DispList *, dl, dispbase) { - const int tot = (ELEM(dl->type, DL_INDEX3, DL_INDEX4)) ? dl->nr : dl->nr * dl->parts; + const int tot = dl->type == DL_INDEX3 ? dl->nr : dl->nr * dl->parts; for (const int i : IndexRange(tot)) { minmax_v3v3_v3(min, max, &dl->verts[i * 3]); } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index b5c025a40b6..6fb67711ae9 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -398,21 +398,6 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name) return lt; } -bool object_deform_mball(Object *ob, ListBase *dispbase) -{ - if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) { - DispList *dl; - - for (dl = dispbase->first; dl; dl = dl->next) { - BKE_lattice_deform_coords(ob->parent, ob, (float(*)[3])dl->verts, dl->nr, 0, NULL, 1.0f); - } - - return true; - } - - return false; -} - static BPoint *latt_bp(Lattice *lt, int u, int v, int w) { return <->def[BKE_lattice_index_from_uvw(lt, u, v, w)]; diff --git a/source/blender/blenkernel/intern/mball.cc b/source/blender/blenkernel/intern/mball.cc index 084fea6abbd..beed21dc3b7 100644 --- a/source/blender/blenkernel/intern/mball.cc +++ b/source/blender/blenkernel/intern/mball.cc @@ -25,6 +25,7 @@ #include "DNA_defaults.h" #include "DNA_material_types.h" +#include "DNA_mesh_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -41,11 +42,15 @@ #include "BKE_anim_data.h" #include "BKE_curve.h" #include "BKE_displist.h" +#include "BKE_geometry_set.hh" #include "BKE_idtype.h" +#include "BKE_lattice.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" #include "BKE_material.h" #include "BKE_mball.h" +#include "BKE_mball_tessellate.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_scene.h" @@ -76,15 +81,12 @@ static void metaball_copy_data(Main *UNUSED(bmain), metaball_dst->editelems = nullptr; metaball_dst->lastelem = nullptr; - metaball_dst->batch_cache = nullptr; } static void metaball_free_data(ID *id) { MetaBall *metaball = (MetaBall *)id; - BKE_mball_batch_cache_free(metaball); - MEM_SAFE_FREE(metaball->mat); BLI_freelistN(&metaball->elems); @@ -111,7 +113,6 @@ static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_add /* Must always be cleared (meta's don't have their own edit-data). */ mb->needs_flush_to_id = 0; mb->lastelem = nullptr; - mb->batch_cache = nullptr; /* write LibData */ BLO_write_id_struct(writer, MetaBall, id_address, &mb->id); @@ -144,7 +145,6 @@ static void metaball_blend_read_data(BlendDataReader *reader, ID *id) mb->needs_flush_to_id = 0; // mb->edit_elems.first = mb->edit_elems.last = nullptr; mb->lastelem = nullptr; - mb->batch_cache = nullptr; } static void metaball_blend_read_lib(BlendLibReader *reader, ID *id) @@ -249,63 +249,36 @@ MetaElem *BKE_mball_element_add(MetaBall *mb, const int type) return ml; } -void BKE_mball_texspace_calc(Object *ob) -{ - DispList *dl; - BoundBox *bb; - float *data, min[3], max[3] /*, loc[3], size[3] */; - int tot; - bool do_it = false; - - if (ob->runtime.bb == nullptr) { - ob->runtime.bb = MEM_cnew<BoundBox>(__func__); - } - bb = ob->runtime.bb; - - /* Weird one, this. */ - // INIT_MINMAX(min, max); - (min)[0] = (min)[1] = (min)[2] = 1.0e30f; - (max)[0] = (max)[1] = (max)[2] = -1.0e30f; - - dl = static_cast<DispList *>(ob->runtime.curve_cache->disp.first); - while (dl) { - tot = dl->nr; - if (tot) { - do_it = true; - } - data = dl->verts; - while (tot--) { - /* Also weird... but longer. From utildefines. */ - minmax_v3v3_v3(min, max, data); - data += 3; - } - dl = dl->next; - } - - if (!do_it) { - min[0] = min[1] = min[2] = -1.0f; - max[0] = max[1] = max[2] = 1.0f; - } - - BKE_boundbox_init_from_minmax(bb, min, max); - - bb->flag &= ~BOUNDBOX_DIRTY; -} BoundBox *BKE_mball_boundbox_get(Object *ob) { BLI_assert(ob->type == OB_MBALL); - - if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) { + if (ob->runtime.bb != NULL && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) { return ob->runtime.bb; } + if (ob->runtime.bb == NULL) { + ob->runtime.bb = MEM_cnew<BoundBox>(__func__); + } - /* This should always only be called with evaluated objects, - * but currently RNA is a problem here... */ - if (ob->runtime.curve_cache != nullptr) { - BKE_mball_texspace_calc(ob); + /* Expect that this function is only called for evaluated objects. */ + const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob); + float min[3]; + float max[3]; + if (mesh_eval) { + INIT_MINMAX(min, max); + if (!BKE_mesh_minmax(mesh_eval, min, max)) { + copy_v3_fl(min, -1.0f); + copy_v3_fl(max, 1.0f); + } + } + else { + copy_v3_fl(min, 0.0f); + copy_v3_fl(max, 0.0f); } + BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max); + ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY; + return ob->runtime.bb; } @@ -735,20 +708,44 @@ bool BKE_mball_select_swap_multi_ex(Base **bases, int bases_len) /* **** Depsgraph evaluation **** */ -/* Draw Engine */ +void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob) +{ + BLI_assert(ob->type == OB_MBALL); -void (*BKE_mball_batch_cache_dirty_tag_cb)(MetaBall *mb, int mode) = nullptr; -void (*BKE_mball_batch_cache_free_cb)(MetaBall *mb) = nullptr; + BKE_object_free_derived_caches(ob); -void BKE_mball_batch_cache_dirty_tag(MetaBall *mb, int mode) -{ - if (mb->batch_cache) { - BKE_mball_batch_cache_dirty_tag_cb(mb, mode); + const Object *basis_object = BKE_mball_basis_find(scene, ob); + if (ob != basis_object) { + return; } -} -void BKE_mball_batch_cache_free(MetaBall *mb) -{ - if (mb->batch_cache) { - BKE_mball_batch_cache_free_cb(mb); + + Mesh *mesh = BKE_mball_polygonize(depsgraph, scene, ob); + if (mesh == NULL) { + return; } -} + + const MetaBall *mball = static_cast<MetaBall *>(ob->data); + mesh->mat = static_cast<Material **>(MEM_dupallocN(mball->mat)); + mesh->totcol = mball->totcol; + + if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) { + int verts_num; + float(*positions)[3] = BKE_mesh_vert_coords_alloc(mesh, &verts_num); + BKE_lattice_deform_coords(ob->parent, ob, positions, verts_num, 0, NULL, 1.0f); + BKE_mesh_vert_coords_apply(mesh, positions); + MEM_freeN(positions); + } + + ob->runtime.geometry_set_eval = new GeometrySet(GeometrySet::create_with_mesh(mesh)); + + if (ob->runtime.bb == NULL) { + ob->runtime.bb = MEM_cnew<BoundBox>(__func__); + } + blender::float3 min(std::numeric_limits<float>::max()); + blender::float3 max(-std::numeric_limits<float>::max()); + if (!ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max)) { + min = blender::float3(0); + max = blender::float3(0); + } + BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max); +}; diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c index 54def0189b1..96b3681b333 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.c +++ b/source/blender/blenkernel/intern/mball_tessellate.c @@ -14,6 +14,8 @@ #include "MEM_guardedalloc.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -24,10 +26,11 @@ #include "BLI_string_utils.h" #include "BLI_utildefines.h" -#include "BKE_global.h" - #include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_lib_id.h" #include "BKE_mball_tessellate.h" /* own include */ +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_scene.h" @@ -1371,7 +1374,7 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje } } -void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase) +Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) { PROCESS process = {0}; const bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER; @@ -1394,10 +1397,10 @@ void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBa } if (!is_render && (mb->flag == MB_UPDATE_NEVER)) { - return; + return NULL; } if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) { - return; + return NULL; } if (is_render) { @@ -1418,7 +1421,7 @@ void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBa init_meta(depsgraph, &process, scene, ob); if (process.totelem == 0) { freepolygonize(&process); - return; + return NULL; } build_bvh_spatial(&process, &process.metaball_bvh, 0, process.totelem, &process.allbb); @@ -1430,40 +1433,63 @@ void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBa ob->scale[1] < 0.00001f * (process.allbb.max[1] - process.allbb.min[1]) || ob->scale[2] < 0.00001f * (process.allbb.max[2] - process.allbb.min[2])) { freepolygonize(&process); - return; + return NULL; } polygonize(&process); if (process.curindex == 0) { freepolygonize(&process); - return; + return NULL; } - /* add resulting surface to displist */ + freepolygonize(&process); + + Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name + 2); - /* Avoid over-allocation since this is stored in the displist. */ - if (process.curindex != process.totindex) { - process.indices = MEM_reallocN(process.indices, sizeof(int[4]) * process.curindex); + mesh->totvert = (int)process.curvertex; + MVert *mvert = CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_DEFAULT, NULL, mesh->totvert); + for (int i = 0; i < mesh->totvert; i++) { + copy_v3_v3(mvert[i].co, process.co[i]); + mvert->bweight = 0; + mvert->flag = 0; } - if (process.curvertex != process.totvertex) { - process.co = MEM_reallocN(process.co, process.curvertex * sizeof(float[3])); - process.no = MEM_reallocN(process.no, process.curvertex * sizeof(float[3])); + MEM_freeN(process.co); + + mesh->totpoly = (int)process.curindex; + MPoly *mpoly = CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_DEFAULT, NULL, mesh->totpoly); + MLoop *mloop = CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_DEFAULT, NULL, mesh->totpoly * 4); + + int loop_offset = 0; + for (int i = 0; i < mesh->totpoly; i++) { + const int *indices = process.indices[i]; + + const int count = indices[2] != indices[3] ? 4 : 3; + mpoly[i].loopstart = loop_offset; + mpoly[i].totloop = count; + mpoly[i].flag = ME_SMOOTH; + + mloop[loop_offset].v = (uint32_t)indices[0]; + mloop[loop_offset + 1].v = (uint32_t)indices[1]; + mloop[loop_offset + 2].v = (uint32_t)indices[2]; + if (count == 4) { + mloop[loop_offset + 3].v = (uint32_t)indices[3]; + } + + loop_offset += count; } + MEM_freeN(process.indices); - DispList *dl = MEM_callocN(sizeof(DispList), "mballdisp"); - BLI_addtail(dispbase, dl); - dl->type = DL_INDEX4; - dl->nr = (int)process.curvertex; - dl->parts = (int)process.curindex; + for (int i = 0; i < mesh->totvert; i++) { + normalize_v3(process.no[i]); + } + mesh->runtime.vert_normals = process.no; + BKE_mesh_vertex_normals_clear_dirty(mesh); - dl->index = (int *)process.indices; + mesh->totloop = loop_offset; - for (uint a = 0; a < process.curvertex; a++) { - normalize_v3(process.no[a]); - } + BKE_mesh_update_customdata_pointers(mesh, false); - dl->verts = (float *)process.co; - dl->nors = (float *)process.no; + BKE_mesh_calc_edges(mesh, false, false); - freepolygonize(&process); + return mesh; } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 24b81bce784..3806ea76cfe 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -72,61 +72,6 @@ using blender::Span; static CLG_LogRef LOG = {"bke.mesh_convert"}; -void BKE_mesh_from_metaball(ListBase *lb, Mesh *me) -{ - DispList *dl; - MVert *mvert; - MLoop *mloop, *allloop; - MPoly *mpoly; - int a, *index; - - dl = (DispList *)lb->first; - if (dl == nullptr) { - return; - } - - if (dl->type == DL_INDEX4) { - mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, dl->nr); - allloop = mloop = (MLoop *)CustomData_add_layer( - &me->ldata, CD_MLOOP, CD_CALLOC, nullptr, dl->parts * 4); - mpoly = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, nullptr, dl->parts); - me->mvert = mvert; - me->mloop = mloop; - me->mpoly = mpoly; - me->totvert = dl->nr; - me->totpoly = dl->parts; - - for (const int i : IndexRange(dl->nr)) { - copy_v3_v3(me->mvert[i].co, &dl->verts[3 * i]); - } - - a = dl->parts; - index = dl->index; - while (a--) { - int count = index[2] != index[3] ? 4 : 3; - - mloop[0].v = index[0]; - mloop[1].v = index[1]; - mloop[2].v = index[2]; - if (count == 4) { - mloop[3].v = index[3]; - } - - mpoly->totloop = count; - mpoly->loopstart = (int)(mloop - allloop); - mpoly->flag = ME_SMOOTH; - - mpoly++; - mloop += count; - me->totloop += count; - index += 4; - } - - BKE_mesh_update_customdata_pointers(me, true); - BKE_mesh_calc_edges(me, true, false); - } -} - /** * Specialized function to use when we _know_ existing edges don't overlap with poly edges. */ @@ -929,32 +874,21 @@ static Mesh *mesh_new_from_curve_type_object(const Object *object) static Mesh *mesh_new_from_mball_object(Object *object) { - MetaBall *mball = (MetaBall *)object->data; - /* NOTE: We can only create mesh for a polygonized meta ball. This figures out all original meta * balls and all evaluated child meta balls (since polygonization is only stored in the mother * ball). * * Create empty mesh so script-authors don't run into None objects. */ - if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == nullptr || - BLI_listbase_is_empty(&object->runtime.curve_cache->disp)) { + if (!DEG_is_evaluated_object(object)) { return (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2); } - Mesh *mesh_result = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2); - BKE_mesh_from_metaball(&object->runtime.curve_cache->disp, mesh_result); - BKE_mesh_texspace_copy_from_object(mesh_result, object); - - /* Copy materials. */ - mesh_result->totcol = mball->totcol; - mesh_result->mat = (Material **)MEM_dupallocN(mball->mat); - if (mball->mat != nullptr) { - for (int i = mball->totcol; i-- > 0;) { - mesh_result->mat[i] = BKE_object_material_get(object, i + 1); - } + const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object); + if (mesh_eval == nullptr) { + return (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2); } - return mesh_result; + return BKE_mesh_copy_for_eval(mesh_eval, false); } static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh) diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index cc3a8b5bb0e..228bc682ddd 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -201,7 +201,7 @@ static DupliObject *make_dupli( /* Meta-balls never draw in duplis, they are instead merged into one by the basis * meta-ball outside of the group. this does mean that if that meta-ball is not in the * scene, they will not show up at all, limitation that should be solved once. */ - if (ob->type == OB_MBALL) { + if (object_data && GS(object_data->name) == ID_MB) { dob->no_draw = true; } @@ -1563,6 +1563,13 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx) return nullptr; } + /* Metaball objects can't create instances, but the dupli system is used to "instance" their + * evaluated mesh to render engines. We need to exit early to avoid recursively instancing the + * evaluated metaball mesh on metaball instances that already contribute to the basis. */ + if (ctx->object->type == OB_MBALL && ctx->level > 0) { + return nullptr; + } + /* Should the dupli's be generated for this object? - Respect restrict flags. */ if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (visibility_flag & OB_HIDE_RENDER) : (visibility_flag & OB_HIDE_VIEWPORT)) { diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index af0c5107348..5656a9f6c92 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -168,7 +168,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o break; case OB_MBALL: - BKE_displist_make_mball(depsgraph, scene, ob); + BKE_mball_data_update(depsgraph, scene, ob); break; case OB_CURVES_LEGACY: @@ -292,9 +292,15 @@ void BKE_object_batch_cache_dirty_tag(Object *ob) case OB_CURVES_LEGACY: BKE_curve_batch_cache_dirty_tag((struct Curve *)ob->data, BKE_CURVE_BATCH_DIRTY_ALL); break; - case OB_MBALL: - BKE_mball_batch_cache_dirty_tag((struct MetaBall *)ob->data, BKE_MBALL_BATCH_DIRTY_ALL); + case OB_MBALL: { + /* This function is currently called on original objects, so to properly + * clear the actual displayed geometry, we have to tag the evaluated mesh. */ + Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(ob); + if (mesh) { + BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL); + } break; + } case OB_GPENCIL: BKE_gpencil_batch_cache_dirty_tag((struct bGPdata *)ob->data); break; diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 171c9875e2a..2d2ee5dc4b4 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -153,10 +153,10 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data) if (dob->no_draw) { continue; } - if (obd->type == OB_MBALL) { + if (dob->ob_data && GS(dob->ob_data->name) == ID_MB) { continue; } - if (deg_object_hide_original(data->eval_mode, dob->ob, dob)) { + if (obd->type != OB_MBALL && deg_object_hide_original(data->eval_mode, dob->ob, dob)) { continue; } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 0a62263ce3b..684134609c9 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -71,11 +71,9 @@ set(SRC intern/draw_attributes.cc intern/draw_cache_impl_curve.cc intern/draw_cache_impl_curves.cc - intern/draw_cache_impl_displist.c intern/draw_cache_impl_gpencil.c intern/draw_cache_impl_lattice.c intern/draw_cache_impl_mesh.cc - intern/draw_cache_impl_metaball.c intern/draw_cache_impl_particles.c intern/draw_cache_impl_pointcloud.cc intern/draw_cache_impl_subdivision.cc diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index ffe0863fb9f..cc7d0c6b22e 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -109,7 +109,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob) } if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) { - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { + if (ELEM(ob->type, OB_MESH, OB_SURF)) { EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow); } else if (ob->type == OB_CURVES) { diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index efd27c19654..94f29d64628 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -806,7 +806,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, !DRW_state_is_image_render(); /* First get materials for this mesh. */ - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { + if (ELEM(ob->type, OB_MESH, OB_SURF)) { const int materials_len = DRW_cache_object_material_count_get(ob); EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len); diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 82944f237ea..3e268758076 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -224,7 +224,7 @@ void EEVEE_render_cache(void *vedata, } if (ob_visibility & OB_VISIBLE_SELF) { - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { + if (ELEM(ob->type, OB_MESH, OB_SURF)) { EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow); if (do_cryptomatte) { EEVEE_cryptomatte_cache_populate(data, sldata, ob); diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 6665b3a7c9b..eb32ebe9555 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -144,8 +144,7 @@ void Instance::object_sync(Object *ob) case OB_MESH: case OB_CURVES_LEGACY: case OB_SURF: - case OB_FONT: - case OB_MBALL: { + case OB_FONT: { sync.sync_mesh(ob, ob_handle); break; } diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index 5edd68bffff..6e2da95e405 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -320,7 +320,6 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) OB_MESH, OB_CURVES_LEGACY, OB_SURF, - OB_MBALL, OB_FONT, OB_GPENCIL, OB_CURVES, diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 9eb35c25bf4..ad32618e636 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -409,7 +409,7 @@ void workbench_cache_populate(void *ved, Object *ob) return; } - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL, OB_POINTCLOUD)) { + if (ELEM(ob->type, OB_MESH, OB_SURF, OB_POINTCLOUD)) { bool use_sculpt_pbvh, use_texpaint_mode, draw_shadow, has_transp_mat = false; eV3DShadingColorType color_type = workbench_color_type_get( wpd, ob, &use_sculpt_pbvh, &use_texpaint_mode, &draw_shadow); diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 4c0f025e934..275392ec56a 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -780,6 +780,39 @@ GPUBatch *DRW_cache_normal_arrow_get(void) return SHC.drw_normal_arrow; } +void DRW_vertbuf_create_wiredata(GPUVertBuf *vbo, const int vert_len) +{ + static GPUVertFormat format = {0}; + static struct { + uint wd; + } attr_id; + if (format.attr_len == 0) { + /* initialize vertex format */ + if (!GPU_crappy_amd_driver()) { + /* Some AMD drivers strangely crash with a vbo with this format. */ + attr_id.wd = GPU_vertformat_attr_add( + &format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); + } + else { + attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + } + } + + GPU_vertbuf_init_with_format(vbo, &format); + GPU_vertbuf_data_alloc(vbo, vert_len); + + if (GPU_vertbuf_get_format(vbo)->stride == 1) { + memset(GPU_vertbuf_get_data(vbo), 0xFF, (size_t)vert_len); + } + else { + GPUVertBufRaw wd_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step); + for (int i = 0; i < vert_len; i++) { + *((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f; + } + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -836,8 +869,6 @@ GPUBatch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_edge_detection_get(ob, r_is_manifold); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -860,8 +891,6 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_face_wireframe_get(ob); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -887,8 +916,6 @@ GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return NULL; case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -911,8 +938,6 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_surface_get(ob); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -936,8 +961,6 @@ GPUVertBuf *DRW_cache_object_pos_vertbuf_get(Object *ob) case OB_SURF: case OB_FONT: return NULL; - case OB_MBALL: - return DRW_mball_batch_cache_pos_vertbuf_get(ob); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -968,8 +991,6 @@ int DRW_cache_object_material_count_get(struct Object *ob) case OB_SURF: case OB_FONT: return DRW_curve_material_count_get(ob->data); - case OB_MBALL: - return DRW_metaball_material_count_get(ob->data); case OB_CURVES: return DRW_curves_material_count_get(ob->data); case OB_POINTCLOUD: @@ -997,8 +1018,6 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob, return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_surface_shaded_get(ob, gpumat_array, gpumat_array_len); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -2972,39 +2991,6 @@ GPUBatch *DRW_cache_curve_vert_overlay_get(Object *ob) /** \} */ /* -------------------------------------------------------------------- */ -/** \name MetaBall - * \{ */ - -GPUBatch *DRW_cache_mball_surface_get(Object *ob) -{ - BLI_assert(ob->type == OB_MBALL); - return DRW_metaball_batch_cache_get_triangles_with_normals(ob); -} - -GPUBatch *DRW_cache_mball_edge_detection_get(Object *ob, bool *r_is_manifold) -{ - BLI_assert(ob->type == OB_MBALL); - return DRW_metaball_batch_cache_get_edge_detection(ob, r_is_manifold); -} - -GPUBatch *DRW_cache_mball_face_wireframe_get(Object *ob) -{ - BLI_assert(ob->type == OB_MBALL); - return DRW_metaball_batch_cache_get_wireframes_face(ob); -} - -GPUBatch **DRW_cache_mball_surface_shaded_get(Object *ob, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len) -{ - BLI_assert(ob->type == OB_MBALL); - MetaBall *mb = ob->data; - return DRW_metaball_batch_cache_get_surface_shaded(ob, mb, gpumat_array, gpumat_array_len); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Font * \{ */ @@ -3322,9 +3308,6 @@ void drw_batch_cache_validate(Object *ob) case OB_SURF: DRW_curve_batch_cache_validate((Curve *)ob->data); break; - case OB_MBALL: - DRW_mball_batch_cache_validate((MetaBall *)ob->data); - break; case OB_LATTICE: DRW_lattice_batch_cache_validate((Lattice *)ob->data); break; diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index a107eb7c75c..4e8788ada08 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -213,15 +213,6 @@ struct GPUBatch *DRW_cache_particles_get_edit_tip_points(struct Object *object, struct PTCacheEdit *edit); struct GPUBatch *DRW_cache_particles_get_prim(int type); -/* Metaball */ - -struct GPUBatch *DRW_cache_mball_surface_get(struct Object *ob); -struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len); -struct GPUBatch *DRW_cache_mball_face_wireframe_get(struct Object *ob); -struct GPUBatch *DRW_cache_mball_edge_detection_get(struct Object *ob, bool *r_is_manifold); - /* Curves */ struct GPUBatch *DRW_cache_curves_surface_get(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 91dbef8d7b1..7f7d0a7613f 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -36,10 +36,6 @@ extern "C" { /** \name Expose via BKE callbacks * \{ */ -void DRW_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode); -void DRW_mball_batch_cache_validate(struct MetaBall *mb); -void DRW_mball_batch_cache_free(struct MetaBall *mb); - void DRW_curve_batch_cache_dirty_tag(struct Curve *cu, int mode); void DRW_curve_batch_cache_validate(struct Curve *cu); void DRW_curve_batch_cache_free(struct Curve *cu); @@ -111,39 +107,6 @@ struct GPUBatch *DRW_curve_batch_cache_get_edit_verts(struct Curve *cu); /** \} */ /* -------------------------------------------------------------------- */ -/** \name Metaball - * \{ */ - -int DRW_metaball_material_count_get(struct MetaBall *mb); - -struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob); -struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, - struct MetaBall *mb, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len); -struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob); -struct GPUBatch *DRW_metaball_batch_cache_get_edge_detection(struct Object *ob, - bool *r_is_manifold); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name DispList - * \{ */ - -void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, - struct GPUVertBuf *vbo, - const struct Scene *scene); -void DRW_displist_vertbuf_create_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo); -void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo); -void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo); -void DRW_displist_indexbuf_create_edges_adjacency_lines(struct ListBase *lb, - struct GPUIndexBuf *ibo, - bool *r_is_manifold); - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Lattice * \{ */ @@ -309,7 +272,6 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(struct Mesh *me); * \{ */ struct GPUVertBuf *DRW_mesh_batch_cache_pos_vertbuf_get(struct Mesh *me); -struct GPUVertBuf *DRW_mball_batch_cache_pos_vertbuf_get(struct Object *ob); int DRW_mesh_material_count_get(const struct Object *object, const struct Mesh *me); diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c deleted file mode 100644 index 96c088c3ee9..00000000000 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ /dev/null @@ -1,354 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2017 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup draw - * - * \brief DispList API for render engines - * - * \note DispList may be removed soon! This is a utility for object types that use render. - */ - -#include "BLI_edgehash.h" -#include "BLI_listbase.h" -#include "BLI_math_vector.h" -#include "BLI_utildefines.h" - -#include "DNA_curve_types.h" -#include "DNA_scene_types.h" - -#include "BKE_displist.h" - -#include "GPU_batch.h" -#include "GPU_capabilities.h" - -#include "draw_cache_inline.h" - -#include "draw_cache_impl.h" /* own include */ - -static int dl_vert_len(const DispList *dl) -{ - switch (dl->type) { - case DL_INDEX3: - case DL_INDEX4: - return dl->nr; - case DL_SURF: - return dl->parts * dl->nr; - } - return 0; -} - -static int dl_tri_len(const DispList *dl) -{ - switch (dl->type) { - case DL_INDEX3: - return dl->parts; - case DL_INDEX4: - return dl->parts * 2; - case DL_SURF: - return dl->totindex * 2; - } - return 0; -} - -/* see: displist_vert_coords_alloc */ -static int curve_render_surface_vert_len_get(const ListBase *lb) -{ - int vert_len = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - vert_len += dl_vert_len(dl); - } - return vert_len; -} - -static int curve_render_surface_tri_len_get(const ListBase *lb) -{ - int tri_len = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - tri_len += dl_tri_len(dl); - } - return tri_len; -} - -typedef void(SetTriIndicesFn)(void *thunk, uint v1, uint v2, uint v3); - -static void displist_indexbufbuilder_set( - SetTriIndicesFn *set_tri_indices, - SetTriIndicesFn *set_quad_tri_indices, /* meh, find a better solution. */ - void *thunk, - const DispList *dl, - const int ofs) -{ - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - const int *idx = dl->index; - if (dl->type == DL_INDEX3) { - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++, idx += 3) { - set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); - } - } - else if (dl->type == DL_SURF) { - const int i_end = dl->totindex; - for (int i = 0; i < i_end; i++, idx += 4) { - set_quad_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); - set_quad_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[3] + ofs); - } - } - else { - BLI_assert(dl->type == DL_INDEX4); - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++, idx += 4) { - if (idx[2] != idx[3]) { - set_quad_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[1] + ofs); - set_quad_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); - } - else { - set_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[1] + ofs); - } - } - } - } -} - -void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo, const Scene *scene) -{ - const bool do_hq_normals = (scene->r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 || - GPU_use_hq_normals_workaround(); - - static GPUVertFormat format = {0}; - static GPUVertFormat format_hq = {0}; - static struct { - uint pos, nor; - uint pos_hq, nor_hq; - } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.nor = GPU_vertformat_attr_add( - &format, "nor", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - /* initialize vertex format */ - attr_id.pos_hq = GPU_vertformat_attr_add(&format_hq, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.nor_hq = GPU_vertformat_attr_add( - &format_hq, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - - uint pos_id = do_hq_normals ? attr_id.pos_hq : attr_id.pos; - uint nor_id = do_hq_normals ? attr_id.nor_hq : attr_id.nor; - - GPU_vertbuf_init_with_format(vbo, do_hq_normals ? &format_hq : &format); - GPU_vertbuf_data_alloc(vbo, curve_render_surface_vert_len_get(lb)); - - BKE_displist_normals_add(lb); - - int vbo_len_used = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - const bool ndata_is_single = dl->type == DL_INDEX3; - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - const float *fp_co = dl->verts; - const float *fp_no = dl->nors; - const int vbo_end = vbo_len_used + dl_vert_len(dl); - while (vbo_len_used < vbo_end) { - GPU_vertbuf_attr_set(vbo, pos_id, vbo_len_used, fp_co); - if (fp_no) { - GPUNormal vnor_pack; - GPU_normal_convert_v3(&vnor_pack, fp_no, do_hq_normals); - GPU_vertbuf_attr_set(vbo, nor_id, vbo_len_used, &vnor_pack); - if (ndata_is_single == false) { - fp_no += 3; - } - } - fp_co += 3; - vbo_len_used += 1; - } - } - } -} - -void DRW_vertbuf_create_wiredata(GPUVertBuf *vbo, const int vert_len) -{ - static GPUVertFormat format = {0}; - static struct { - uint wd; - } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - if (!GPU_crappy_amd_driver()) { - /* Some AMD drivers strangely crash with a vbo with this format. */ - attr_id.wd = GPU_vertformat_attr_add( - &format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - else { - attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - } - } - - GPU_vertbuf_init_with_format(vbo, &format); - GPU_vertbuf_data_alloc(vbo, vert_len); - - if (GPU_vertbuf_get_format(vbo)->stride == 1) { - memset(GPU_vertbuf_get_data(vbo), 0xFF, (size_t)vert_len); - } - else { - GPUVertBufRaw wd_step; - GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step); - for (int i = 0; i < vert_len; i++) { - *((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f; - } - } -} - -void DRW_displist_vertbuf_create_wiredata(ListBase *lb, GPUVertBuf *vbo) -{ - const int vert_len = curve_render_surface_vert_len_get(lb); - DRW_vertbuf_create_wiredata(vbo, vert_len); -} - -void DRW_displist_indexbuf_create_triangles_in_order(ListBase *lb, GPUIndexBuf *ibo) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - const int vert_len = curve_render_surface_vert_len_get(lb); - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); - - int ofs = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - displist_indexbufbuilder_set((SetTriIndicesFn *)GPU_indexbuf_add_tri_verts, - (SetTriIndicesFn *)GPU_indexbuf_add_tri_verts, - &elb, - dl, - ofs); - ofs += dl_vert_len(dl); - } - - GPU_indexbuf_build_in_place(&elb, ibo); -} - -static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3) -{ - GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk; - GPU_indexbuf_add_line_verts(eld, v1, v2); - GPU_indexbuf_add_line_verts(eld, v2, v3); - GPU_indexbuf_add_line_verts(eld, v3, v1); -} - -static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, uint v3) -{ - GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk; - GPU_indexbuf_add_line_verts(eld, v1, v3); - GPU_indexbuf_add_line_verts(eld, v3, v2); -} - -void DRW_displist_indexbuf_create_lines_in_order(ListBase *lb, GPUIndexBuf *ibo) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - const int vert_len = curve_render_surface_vert_len_get(lb); - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES, tri_len * 3, vert_len); - - int ofs = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - displist_indexbufbuilder_set( - set_overlay_wires_tri_indices, set_overlay_wires_quad_tri_indices, &elb, dl, ofs); - ofs += dl_vert_len(dl); - } - - GPU_indexbuf_build_in_place(&elb, ibo); -} - -/* Edge detection/adjacency. */ -#define NO_EDGE INT_MAX -static void set_edge_adjacency_lines_indices( - EdgeHash *eh, GPUIndexBufBuilder *elb, bool *r_is_manifold, uint v1, uint v2, uint v3) -{ - bool inv_indices = (v2 > v3); - void **pval; - bool value_is_init = BLI_edgehash_ensure_p(eh, v2, v3, &pval); - int v_data = POINTER_AS_INT(*pval); - if (!value_is_init || v_data == NO_EDGE) { - /* Save the winding order inside the sign bit. Because the - * edgehash sort the keys and we need to compare winding later. */ - int value = (int)v1 + 1; /* Int 0 bm_looptricannot be signed */ - *pval = POINTER_FROM_INT((inv_indices) ? -value : value); - } - else { - /* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */ - *pval = POINTER_FROM_INT(NO_EDGE); - bool inv_opposite = (v_data < 0); - uint v_opposite = (uint)abs(v_data) - 1; - - if (inv_opposite == inv_indices) { - /* Don't share edge if triangles have non matching winding. */ - GPU_indexbuf_add_line_adj_verts(elb, v1, v2, v3, v1); - GPU_indexbuf_add_line_adj_verts(elb, v_opposite, v2, v3, v_opposite); - *r_is_manifold = false; - } - else { - GPU_indexbuf_add_line_adj_verts(elb, v1, v2, v3, v_opposite); - } - } -} - -static void set_edges_adjacency_lines_indices(void *thunk, uint v1, uint v2, uint v3) -{ - void **packed = (void **)thunk; - GPUIndexBufBuilder *elb = (GPUIndexBufBuilder *)packed[0]; - EdgeHash *eh = (EdgeHash *)packed[1]; - bool *r_is_manifold = (bool *)packed[2]; - - set_edge_adjacency_lines_indices(eh, elb, r_is_manifold, v1, v2, v3); - set_edge_adjacency_lines_indices(eh, elb, r_is_manifold, v2, v3, v1); - set_edge_adjacency_lines_indices(eh, elb, r_is_manifold, v3, v1, v2); -} - -void DRW_displist_indexbuf_create_edges_adjacency_lines(struct ListBase *lb, - struct GPUIndexBuf *ibo, - bool *r_is_manifold) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - const int vert_len = curve_render_surface_vert_len_get(lb); - - *r_is_manifold = true; - - /* Allocate max but only used indices are sent to GPU. */ - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, tri_len * 3, vert_len); - - EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3); - - /* pack values to pass to `set_edges_adjacency_lines_indices` function. */ - void *thunk[3] = {&elb, eh, r_is_manifold}; - int v_idx = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - displist_indexbufbuilder_set((SetTriIndicesFn *)set_edges_adjacency_lines_indices, - (SetTriIndicesFn *)set_edges_adjacency_lines_indices, - thunk, - dl, - v_idx); - v_idx += dl_vert_len(dl); - } - - /* Create edges for remaining non manifold edges. */ - EdgeHashIterator *ehi; - for (ehi = BLI_edgehashIterator_new(eh); BLI_edgehashIterator_isDone(ehi) == false; - BLI_edgehashIterator_step(ehi)) { - uint v1, v2; - int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); - if (v_data == NO_EDGE) { - continue; - } - BLI_edgehashIterator_getKey(ehi, &v1, &v2); - uint v0 = (uint)abs(v_data) - 1; - if (v_data < 0) { /* inv_opposite */ - SWAP(uint, v1, v2); - } - GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0); - *r_is_manifold = false; - } - BLI_edgehashIterator_free(ehi); - BLI_edgehash_free(eh, NULL); - - GPU_indexbuf_build_in_place(&elb, ibo); -} -#undef NO_EDGE diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c deleted file mode 100644 index 1408dc91069..00000000000 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ /dev/null @@ -1,294 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2017 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup draw - * - * \brief MetaBall API for render engines - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_math_base.h" -#include "BLI_utildefines.h" - -#include "DNA_meta_types.h" -#include "DNA_object_types.h" - -#include "BKE_curve.h" -#include "BKE_mball.h" - -#include "GPU_batch.h" - -#include "DRW_render.h" -#include "draw_cache_impl.h" /* own include */ - -static void metaball_batch_cache_clear(MetaBall *mb); - -/* -------------------------------------------------------------------- */ -/** \name MetaBall GPUBatch Cache - * \{ */ - -typedef struct MetaBallBatchCache { - GPUBatch *batch; - GPUBatch **shaded_triangles; - - int mat_len; - - /* Shared */ - GPUVertBuf *pos_nor_in_order; - - /* Wireframe */ - struct { - GPUBatch *batch; - } face_wire; - - /* Edge detection */ - GPUBatch *edge_detection; - GPUIndexBuf *edges_adj_lines; - - /* settings to determine if cache is invalid */ - bool is_dirty; - - /* Valid only if edge_detection is up to date. */ - bool is_manifold; -} MetaBallBatchCache; - -/* GPUBatch cache management. */ - -static bool metaball_batch_cache_valid(MetaBall *mb) -{ - MetaBallBatchCache *cache = mb->batch_cache; - - if (cache == NULL) { - return false; - } - - return cache->is_dirty == false; -} - -static void metaball_batch_cache_init(MetaBall *mb) -{ - MetaBallBatchCache *cache = mb->batch_cache; - - if (!cache) { - cache = mb->batch_cache = MEM_mallocN(sizeof(*cache), __func__); - } - cache->batch = NULL; - cache->mat_len = 0; - cache->shaded_triangles = NULL; - cache->is_dirty = false; - cache->pos_nor_in_order = NULL; - cache->face_wire.batch = NULL; - cache->edge_detection = NULL; - cache->edges_adj_lines = NULL; - cache->is_manifold = false; -} - -void DRW_mball_batch_cache_validate(MetaBall *mb) -{ - if (!metaball_batch_cache_valid(mb)) { - metaball_batch_cache_clear(mb); - metaball_batch_cache_init(mb); - } -} - -static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb) -{ - return mb->batch_cache; -} - -void DRW_mball_batch_cache_dirty_tag(MetaBall *mb, int mode) -{ - MetaBallBatchCache *cache = mb->batch_cache; - if (cache == NULL) { - return; - } - switch (mode) { - case BKE_MBALL_BATCH_DIRTY_ALL: - cache->is_dirty = true; - break; - default: - BLI_assert(0); - } -} - -static void metaball_batch_cache_clear(MetaBall *mb) -{ - MetaBallBatchCache *cache = mb->batch_cache; - if (!cache) { - return; - } - - GPU_BATCH_DISCARD_SAFE(cache->face_wire.batch); - GPU_BATCH_DISCARD_SAFE(cache->batch); - GPU_BATCH_DISCARD_SAFE(cache->edge_detection); - GPU_VERTBUF_DISCARD_SAFE(cache->pos_nor_in_order); - GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adj_lines); - /* NOTE: shaded_triangles[0] is already freed by `cache->batch`. */ - MEM_SAFE_FREE(cache->shaded_triangles); - cache->mat_len = 0; - cache->is_manifold = false; -} - -void DRW_mball_batch_cache_free(MetaBall *mb) -{ - metaball_batch_cache_clear(mb); - MEM_SAFE_FREE(mb->batch_cache); -} - -static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, - MetaBallBatchCache *cache, - const struct Scene *scene) -{ - if (cache->pos_nor_in_order == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - cache->pos_nor_in_order = GPU_vertbuf_calloc(); - DRW_displist_vertbuf_create_pos_and_nor(lb, cache->pos_nor_in_order, scene); - } - return cache->pos_nor_in_order; -} - -static GPUIndexBuf *mball_batch_cache_get_edges_adj_lines(Object *ob, MetaBallBatchCache *cache) -{ - if (cache->edges_adj_lines == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - cache->edges_adj_lines = GPU_indexbuf_calloc(); - DRW_displist_indexbuf_create_edges_adjacency_lines( - lb, cache->edges_adj_lines, &cache->is_manifold); - } - return cache->edges_adj_lines; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Public Object/MetaBall API - * \{ */ - -GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - if (cache->batch == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - GPUIndexBuf *ibo = GPU_indexbuf_calloc(); - DRW_displist_indexbuf_create_triangles_in_order(lb, ibo); - cache->batch = GPU_batch_create_ex(GPU_PRIM_TRIS, - mball_batch_cache_get_pos_and_normals(ob, cache, scene), - ibo, - GPU_BATCH_OWNS_INDEX); - } - - return cache->batch; -} - -GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(Object *ob, - MetaBall *mb, - struct GPUMaterial **UNUSED(gpumat_array), - uint gpumat_array_len) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - BLI_assert(gpumat_array_len == DRW_metaball_material_count_get(mb)); - - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - if (cache->shaded_triangles == NULL) { - cache->mat_len = gpumat_array_len; - cache->shaded_triangles = MEM_callocN(sizeof(*cache->shaded_triangles) * cache->mat_len, - __func__); - cache->shaded_triangles[0] = DRW_metaball_batch_cache_get_triangles_with_normals(ob); - for (int i = 1; i < cache->mat_len; i++) { - cache->shaded_triangles[i] = NULL; - } - } - return cache->shaded_triangles; -} - -GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - if (cache->face_wire.batch == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - - GPUVertBuf *vbo_wiredata = GPU_vertbuf_calloc(); - DRW_displist_vertbuf_create_wiredata(lb, vbo_wiredata); - - GPUIndexBuf *ibo = GPU_indexbuf_calloc(); - DRW_displist_indexbuf_create_lines_in_order(lb, ibo); - - cache->face_wire.batch = GPU_batch_create_ex( - GPU_PRIM_LINES, - mball_batch_cache_get_pos_and_normals(ob, cache, scene), - ibo, - GPU_BATCH_OWNS_INDEX); - - GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wiredata, true); - } - - return cache->face_wire.batch; -} - -struct GPUBatch *DRW_metaball_batch_cache_get_edge_detection(struct Object *ob, - bool *r_is_manifold) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - if (cache->edge_detection == NULL) { - cache->edge_detection = GPU_batch_create( - GPU_PRIM_LINES_ADJ, - mball_batch_cache_get_pos_and_normals(ob, cache, scene), - mball_batch_cache_get_edges_adj_lines(ob, cache)); - } - - if (r_is_manifold) { - *r_is_manifold = cache->is_manifold; - } - - return cache->edge_detection; -} - -struct GPUVertBuf *DRW_mball_batch_cache_pos_vertbuf_get(Object *ob) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - return mball_batch_cache_get_pos_and_normals(ob, cache, scene); -} - -int DRW_metaball_material_count_get(MetaBall *mb) -{ - return max_ii(1, mb->totcol); -} - -/** \} */ diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 0f330dbb519..de56b34df78 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -417,7 +417,6 @@ bool DRW_object_is_flat(Object *ob, int *r_axis) OB_CURVES_LEGACY, OB_SURF, OB_FONT, - OB_MBALL, OB_CURVES, OB_POINTCLOUD, OB_VOLUME)) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 4693e5f8e20..3be2ddf5173 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2989,9 +2989,6 @@ void DRW_engines_register(void) /* setup callbacks */ { - BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag; - BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; - BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag; BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free; diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index acd7a8e3c13..058c9740a96 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -2771,25 +2771,6 @@ static const EnumPropertyItem convert_target_items[] = { {0, nullptr, 0, nullptr, nullptr}, }; -static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob) -{ - if (ob->runtime.curve_cache == nullptr) { - /* Force creation. This is normally not needed but on operator - * redo we might end up with an object which isn't evaluated yet. - * Also happens in case we are working on a copy of the object - * (all its caches have been nuked then). - */ - if (ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY, OB_FONT)) { - /* We need 'for render' ON here, to enable computing bevel #DispList if needed. - * Also makes sense anyway, we would not want e.g. to lose hidden parts etc. */ - BKE_displist_make_curveTypes(depsgraph, scene, ob, true); - } - else if (ob->type == OB_MBALL) { - BKE_displist_make_mball(depsgraph, scene, ob); - } - } -} - static void object_data_convert_curve_to_mesh(Main *bmain, Depsgraph *depsgraph, Object *ob) { Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); @@ -2908,7 +2889,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) const bool use_faces = RNA_boolean_get(op->ptr, "faces"); const float offset = RNA_float_get(op->ptr, "offset"); - int a, mballConverted = 0; + int mballConverted = 0; bool gpencilConverted = false; bool gpencilCurveConverted = false; @@ -3332,21 +3313,13 @@ static int object_convert_exec(bContext *C, wmOperator *op) MetaBall *mb = static_cast<MetaBall *>(newob->data); id_us_min(&mb->id); - newob->data = BKE_mesh_add(bmain, "Mesh"); - newob->type = OB_MESH; - - Mesh *me = static_cast<Mesh *>(newob->data); - me->totcol = mb->totcol; - if (newob->totcol) { - me->mat = static_cast<Material **>(MEM_dupallocN(mb->mat)); - for (a = 0; a < newob->totcol; a++) { - id_us_plus((ID *)me->mat[a]); - } - } + /* Find the evaluated mesh of the basis metaball object. */ + Object *object_eval = DEG_get_evaluated_object(depsgraph, baseob); + Mesh *mesh = BKE_mesh_new_from_object_to_bmain(bmain, depsgraph, object_eval, true); - object_data_convert_ensure_curve_cache(depsgraph, scene, baseob); - BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp, - static_cast<Mesh *>(newob->data)); + id_us_plus(&mesh->id); + newob->data = mesh; + newob->type = OB_MESH; if (obact->type == OB_MBALL) { basact = basen; diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 010a01f9d30..75f9fdd485e 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -50,6 +50,7 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_mball.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_runtime.h" @@ -111,7 +112,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object * BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval); } else if (ob->type == OB_MBALL) { - BKE_displist_make_mball(depsgraph, scene_eval, ob_eval); + BKE_mball_data_update(depsgraph, scene_eval, ob_eval); } else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) { BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false); diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc index e41ff02254b..ee83197ec0c 100644 --- a/source/blender/editors/space_info/info_stats.cc +++ b/source/blender/editors/space_info/info_stats.cc @@ -168,33 +168,7 @@ static void stats_object(Object *ob, if ((me_eval != nullptr) && !BLI_gset_add(objects_gset, (void *)me_eval)) { break; } - - if (stats_mesheval(me_eval, is_selected, stats)) { - break; - } - ATTR_FALLTHROUGH; /* Fall-through to displist. */ - } - case OB_MBALL: { - int totv = 0, totf = 0, tottri = 0; - - if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first) { - /* NOTE: We only get the same curve_cache for instances of the same curve/font/... - * For simple linked duplicated objects, each has its own dispList. */ - if (!BLI_gset_add(objects_gset, ob->runtime.curve_cache)) { - break; - } - - BKE_displist_count(&ob->runtime.curve_cache->disp, &totv, &totf, &tottri); - } - - stats->totvert += totv; - stats->totface += totf; - stats->tottri += tottri; - - if (is_selected) { - stats->totvertsel += totv; - stats->totfacesel += totf; - } + stats_mesheval(me_eval, is_selected, stats); break; } case OB_GPENCIL: { diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index e76e74b89e4..ab357890096 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -77,6 +77,11 @@ NodeGroup *BlenderFileLoader::Load() continue; } + /* Evaluated metaballs will appear as mesh objects in the iterator. */ + if (ob->type == OB_MBALL) { + continue; + } + Mesh *mesh = BKE_object_to_mesh(nullptr, ob, false); if (mesh) { diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc index 6aec848573f..f582064e0c1 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -60,7 +60,7 @@ TEST_F(obj_exporter_test, filter_objects_curves_as_mesh) return; } auto [objmeshes, objcurves]{filter_supported_objects(depsgraph, _export.params)}; - EXPECT_EQ(objmeshes.size(), 20); + EXPECT_EQ(objmeshes.size(), 21); EXPECT_EQ(objcurves.size(), 0); } diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h index 519dfb7e9b3..d0c09a0d6ab 100644 --- a/source/blender/makesdna/DNA_meta_types.h +++ b/source/blender/makesdna/DNA_meta_types.h @@ -92,8 +92,6 @@ typedef struct MetaBall { /* used in editmode */ // ListBase edit_elems; MetaElem *lastelem; - - void *batch_cache; } MetaBall; /* **************** METABALL ********************* */ diff --git a/source/blender/makesrna/intern/rna_meta_api.c b/source/blender/makesrna/intern/rna_meta_api.c index 6595c811abc..1f8748143e3 100644 --- a/source/blender/makesrna/intern/rna_meta_api.c +++ b/source/blender/makesrna/intern/rna_meta_api.c @@ -28,7 +28,7 @@ static void rna_Meta_transform(struct MetaBall *mb, float mat[16]) static void rna_Mball_update_gpu_tag(MetaBall *mb) { - BKE_mball_batch_cache_dirty_tag(mb, BKE_MBALL_BATCH_DIRTY_ALL); + DEG_id_tag_update(&mb->id, ID_RECALC_SHADING); } #else |