[Bf-blender-cvs] [0576f4ca9b4] master: Fix T62664: Exporting Metaballs as Alembic crashes Blender

Sybren A. Stüvel noreply at git.blender.org
Thu Apr 11 16:45:02 CEST 2019


Commit: 0576f4ca9b41f1f0e7dfdd896e539488419306ff
Author: Sybren A. Stüvel
Date:   Thu Apr 11 15:03:08 2019 +0200
Branches: master
https://developer.blender.org/rB0576f4ca9b41f1f0e7dfdd896e539488419306ff

Fix T62664: Exporting Metaballs as Alembic crashes Blender

The `AbcMetaballWriter` now subclasses `AbcGenericMeshWriter` instead of
wrapping an `AbcMeshWriter`. `AbcGenericMeshWriter` was created for this
purpose (writing non-mesh objects as mesh to Alembic) and performs the work
in a cleaner and, more importantly, not crashing way.

===================================================================

M	source/blender/alembic/intern/abc_mball.cc
M	source/blender/alembic/intern/abc_mball.h
M	source/blender/alembic/intern/abc_mesh.cc
M	source/blender/alembic/intern/abc_mesh.h

===================================================================

diff --git a/source/blender/alembic/intern/abc_mball.cc b/source/blender/alembic/intern/abc_mball.cc
index d023150106b..bb6ab57643f 100644
--- a/source/blender/alembic/intern/abc_mball.cc
+++ b/source/blender/alembic/intern/abc_mball.cc
@@ -44,41 +44,33 @@ AbcMBallWriter::AbcMBallWriter(
         AbcTransformWriter *parent,
         uint32_t time_sampling,
         ExportSettings &settings)
-    : AbcObjectWriter(ob, time_sampling, settings, parent)
+    : AbcGenericMeshWriter(ob, parent, time_sampling, settings)
     , m_bmain(bmain)
 {
 	m_is_animated = isAnimated();
-
-	m_mesh_ob = BKE_object_copy(bmain, ob);
-	m_mesh_ob->runtime.curve_cache = (CurveCache *)MEM_callocN(
-	                             sizeof(CurveCache),
-	                             "CurveCache for AbcMBallWriter");
-	/* TODO(Sybren): reimplement metaball writing as subclass of AbcGenericMeshWriter. */
-	m_mesh_writer = new AbcMeshWriter(m_mesh_ob, parent, time_sampling, settings);
-	m_mesh_writer->setIsAnimated(m_is_animated);
 }
 
 
 AbcMBallWriter::~AbcMBallWriter()
-{
-	delete m_mesh_writer;
-	BKE_object_free(m_mesh_ob);
-}
+{}
 
 bool AbcMBallWriter::isAnimated() const
 {
 	return true;
 }
 
-void AbcMBallWriter::do_write()
+Mesh *AbcMBallWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
 {
-	/* We have already stored a sample for this object. */
-	if (!m_first_frame && !m_is_animated)
-		return;
-
+	if (ob_eval->runtime.mesh_eval != NULL) {
+		/* Mesh_eval only exists when generative modifiers are in use. */
+		r_needsfree = false;
+		return ob_eval->runtime.mesh_eval;
+	}
+	r_needsfree = true;
+
+	/* The approach below is copied from BKE_mesh_new_from_object() */
 	Mesh *tmpmesh = BKE_mesh_add(m_bmain, ((ID *)m_object->data)->name + 2);
 	BLI_assert(tmpmesh != NULL);
-	m_mesh_ob->data = tmpmesh;
 
 	/* BKE_mesh_add gives us a user count we don't need */
 	id_us_min(&tmpmesh->id);
@@ -92,12 +84,14 @@ void AbcMBallWriter::do_write()
 	BKE_mesh_from_metaball(&disp, tmpmesh);
 	BKE_displist_free(&disp);
 
-	BKE_mesh_texspace_copy_from_object(tmpmesh, m_mesh_ob);
+	BKE_mesh_texspace_copy_from_object(tmpmesh, m_object);
 
-	m_mesh_writer->write();
+	return tmpmesh;
+}
 
-	BKE_id_free(m_bmain, tmpmesh);
-	m_mesh_ob->data = NULL;
+void AbcMBallWriter::freeEvaluatedMesh(struct Mesh *mesh)
+{
+	BKE_id_free(m_bmain, mesh);
 }
 
 bool AbcMBallWriter::isBasisBall(Scene *scene, Object *ob)
diff --git a/source/blender/alembic/intern/abc_mball.h b/source/blender/alembic/intern/abc_mball.h
index 629a584e89e..18ceda01f87 100644
--- a/source/blender/alembic/intern/abc_mball.h
+++ b/source/blender/alembic/intern/abc_mball.h
@@ -22,24 +22,21 @@
 #define __ABC_MBALL_H__
 
 #include "abc_object.h"
+#include "abc_mesh.h"
 
-class AbcMeshWriter;
 struct EvaluationContext;
 struct Main;
 struct MetaBall;
 struct Object;
 
 /* AbcMBallWriter converts the metaballs to meshes at every frame,
- * and defers to a wrapped AbcMeshWriter to perform the writing
+ * and defers to AbcGenericMeshWriter to perform the writing
  * to the Alembic file. Only the basis balls are exported, as this
  * results in the entire shape as one mesh. */
-class AbcMBallWriter : public AbcObjectWriter {
-	AbcMeshWriter *m_mesh_writer;
-	Object *m_mesh_ob;
-	bool m_is_animated;
+class AbcMBallWriter : public AbcGenericMeshWriter {
 	Main *m_bmain;
 public:
-	AbcMBallWriter(
+	explicit AbcMBallWriter(
 	        Main *bmain,
 	        Object *ob,
 	        AbcTransformWriter *parent,
@@ -50,8 +47,11 @@ public:
 
 	static bool isBasisBall(Scene *scene, Object *ob);
 
+protected:
+	Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) override;
+	void freeEvaluatedMesh(struct Mesh *mesh) override;
+
 private:
-	virtual void do_write();
 	bool isAnimated() const;
 };
 
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 2472fe1945f..97cd6ffc0e3 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -387,14 +387,19 @@ void AbcGenericMeshWriter::do_write()
 			writeMesh(mesh);
 		}
 
-		if (needsfree) BKE_id_free(NULL, mesh);
+		if (needsfree) freeEvaluatedMesh(mesh);
 	}
 	catch (...) {
-		if (needsfree) BKE_id_free(NULL, mesh);
+		if (needsfree) freeEvaluatedMesh(mesh);
 		throw;
 	}
 }
 
+void AbcGenericMeshWriter::freeEvaluatedMesh(struct Mesh *mesh)
+{
+	BKE_id_free(NULL, mesh);
+}
+
 void AbcGenericMeshWriter::writeMesh(struct Mesh *mesh)
 {
 	std::vector<Imath::V3f> points, normals;
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 938c292b686..35ad0f8b297 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -61,6 +61,7 @@ protected:
 	virtual void do_write();
 	virtual bool isAnimated() const;
 	virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) = 0;
+	virtual void freeEvaluatedMesh(struct Mesh *mesh);
 
 	Mesh *getFinalMesh(bool &r_needsfree);



More information about the Bf-blender-cvs mailing list