Page MenuHome

Calling Object.to_mesh on a Metaball object yields an empty mesh
Open, Confirmed, MediumPublic

Description

This is broken in 2.80 but worked in 2.79. Repro script:

bpy.ops.object.metaball_add()
len(bpy.context.active_object.to_mesh(bpy.context.depsgraph, True).polygons) # will be 0

The issue is in BKE_mesh_new_from_object (blenkernel\intern\mesh_convert.c), where on line 958 we check for ob->runtime.curve_cache. It's null, which means we pass null to BKE_mesh_from_metaball, which then bails out without doing any work.

The convert operator works correctly.

Details

Type
Bug

Event Timeline

Jacques Lucke (JacquesLucke) triaged this task as Confirmed, Medium priority.Mon, Feb 4, 12:09 PM

bandaid:

1
2
3diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
4index a61d9da2c70..cd2e91fb29c 100644
5--- a/source/blender/blenkernel/intern/mesh_convert.c
6+++ b/source/blender/blenkernel/intern/mesh_convert.c
7@@ -955,9 +955,10 @@ Mesh *BKE_mesh_new_from_object(
8 }
9 else {
10 ListBase disp = {NULL, NULL};
11- if (ob->runtime.curve_cache) {
12- disp = ob->runtime.curve_cache->disp;
13+ if (!ob->runtime.curve_cache) {
14+ BKE_displist_make_mball(depsgraph, sce, ob);
15 }
16+ disp = ob->runtime.curve_cache->disp;
17 BKE_mesh_from_metaball(&disp, tmpmesh);
18 }
19

hold on, or should we pass the evaluated object here in the first place?

ob = bpy.context.active_object
eval_ob = bpy.context.depsgraph.objects.get(ob.name, None)
len(eval_ob.to_mesh(bpy.context.depsgraph, True).polygons)

this works, it is unclear though if we should do this on the python side (or get the evaluated object on the C side -- since we are passing a depsgraph anyways...)

If we should get the evaluated object from the passed depsgraph, we could do here:

1
2
3diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
4index a4c4acb8006..1da2a68fd0d 100644
5--- a/source/blender/makesrna/intern/rna_main_api.c
6+++ b/source/blender/makesrna/intern/rna_main_api.c
7@@ -309,6 +309,7 @@ Mesh *rna_Main_meshes_new_from_object(
8 Object *ob, bool apply_modifiers, bool calc_undeformed)
9 {
10 Scene *sce = DEG_get_evaluated_scene(depsgraph);
11+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
12
13 switch (ob->type) {
14 case OB_FONT:
15@@ -322,7 +323,7 @@ Mesh *rna_Main_meshes_new_from_object(
16 return NULL;
17 }
18
19- return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob, apply_modifiers, calc_undeformed);
20+ return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob_eval, apply_modifiers, calc_undeformed);
21 }
22
23 static Lamp *rna_Main_lights_new(Main *bmain, const char *name, int type)

or even earlier here:

1
2
3diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
4index 43f41f2704a..0e6c81aafcb 100644
5--- a/source/blender/makesrna/intern/rna_object_api.c
6+++ b/source/blender/makesrna/intern/rna_object_api.c
7@@ -217,8 +217,8 @@ static Mesh *rna_Object_to_mesh(
8 bool apply_modifiers, bool calc_undeformed)
9 {
10 Main *bmain = CTX_data_main(C);
11-
12- return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob, apply_modifiers, calc_undeformed);
13+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
14+ return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob_eval, apply_modifiers, calc_undeformed);
15 }
16
17 static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *reports,

@Sergey Sharybin (sergey): what do you think? (reminds me of T60083 btw. where we argued that evaluated object should be done on the python side of things...)