Calling Object.to_mesh on a Metaball object yields an empty mesh #61156

Closed
opened 2019-02-03 11:52:50 +01:00 by Tom Edwards · 8 comments

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.

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.
Author

Added subscriber: @artfunkel

Added subscriber: @artfunkel
Member

Added subscriber: @lichtwerk

Added subscriber: @lichtwerk
Member

bandaid:
P902: #61156 snippet



diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index a61d9da2c70..cd2e91fb29c 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -955,9 +955,10 @@ Mesh *BKE_mesh_new_from_object(
 			}
 			else {
 				ListBase disp = {NULL, NULL};
-				if (ob->runtime.curve_cache) {
-					disp = ob->runtime.curve_cache->disp;
+				if (!ob->runtime.curve_cache) {
+					BKE_displist_make_mball(depsgraph, sce, ob);
 				}
+				disp = ob->runtime.curve_cache->disp;
 				BKE_mesh_from_metaball(&disp, tmpmesh);
 			}
 
bandaid: [P902: #61156 snippet](https://archive.blender.org/developer/P902.txt) ``` diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index a61d9da2c70..cd2e91fb29c 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -955,9 +955,10 @@ Mesh *BKE_mesh_new_from_object( } else { ListBase disp = {NULL, NULL}; - if (ob->runtime.curve_cache) { - disp = ob->runtime.curve_cache->disp; + if (!ob->runtime.curve_cache) { + BKE_displist_make_mball(depsgraph, sce, ob); } + disp = ob->runtime.curve_cache->disp; BKE_mesh_from_metaball(&disp, tmpmesh); } ```
Sergey Sharybin was assigned by Philipp Oeser 2019-02-04 13:16:49 +01:00
Member

Added subscriber: @Sergey

Added subscriber: @Sergey
Member

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:
P903: #61156 snippet 2



diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index a4c4acb8006..1da2a68fd0d 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -309,6 +309,7 @@ Mesh *rna_Main_meshes_new_from_object(
         Object *ob, bool apply_modifiers, bool calc_undeformed)
 {
 	Scene *sce = DEG_get_evaluated_scene(depsgraph);
+	Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
 
 	switch (ob->type) {
 		case OB_FONT:
@@ -322,7 +323,7 @@ Mesh *rna_Main_meshes_new_from_object(
 			return NULL;
 	}
 
-	return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob, apply_modifiers, calc_undeformed);
+	return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob_eval, apply_modifiers, calc_undeformed);
 }
 
 static Lamp *rna_Main_lights_new(Main *bmain, const char *name, int type)

or even earlier here:
P904: #61156 snippet 3



diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 43f41f2704a..0e6c81aafcb 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -217,8 +217,8 @@ static Mesh *rna_Object_to_mesh(
         bool apply_modifiers, bool calc_undeformed)
 {
 	Main *bmain = CTX_data_main(C);
-
-	return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob, apply_modifiers, calc_undeformed);
+	Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+	return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob_eval, apply_modifiers, calc_undeformed);
 }
 
 static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *reports,

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

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: [P903: #61156 snippet 2](https://archive.blender.org/developer/P903.txt) ``` diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index a4c4acb8006..1da2a68fd0d 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -309,6 +309,7 @@ Mesh *rna_Main_meshes_new_from_object( Object *ob, bool apply_modifiers, bool calc_undeformed) { Scene *sce = DEG_get_evaluated_scene(depsgraph); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); switch (ob->type) { case OB_FONT: @@ -322,7 +323,7 @@ Mesh *rna_Main_meshes_new_from_object( return NULL; } - return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob, apply_modifiers, calc_undeformed); + return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob_eval, apply_modifiers, calc_undeformed); } static Lamp *rna_Main_lights_new(Main *bmain, const char *name, int type) ``` or even earlier here: [P904: #61156 snippet 3](https://archive.blender.org/developer/P904.txt) ``` diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 43f41f2704a..0e6c81aafcb 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -217,8 +217,8 @@ static Mesh *rna_Object_to_mesh( bool apply_modifiers, bool calc_undeformed) { Main *bmain = CTX_data_main(C); - - return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob, apply_modifiers, calc_undeformed); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob_eval, apply_modifiers, calc_undeformed); } static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *reports, ``` @Sergey: what do you think? (reminds me of #60083 btw. where we argued that evaluated object should be done on the python side of things...)
Author

This bug has been open a month without being addressed, so I'm going to use Phillip's suggested Python workaround. A fix before 2.80 ships would be appreciated!

This bug has been open a month without being addressed, so I'm going to use Phillip's suggested Python workaround. A fix before 2.80 ships would be appreciated!

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'

This is now addressed by the re-designed python API of the related calls. See the depsgraph python examples in the documentation.

If there are other issues which we did not spot yet please make a new report.

For until then considering the issue solved, closing.

This is now addressed by the re-designed python API of the related calls. See the depsgraph python examples in the documentation. If there are other issues which we did not spot yet please make a new report. For until then considering the issue solved, closing.
Sign in to join this conversation.
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#61156
No description provided.