Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2019-04-11 16:03:08 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2019-04-11 17:22:55 +0300
commit0576f4ca9b41f1f0e7dfdd896e539488419306ff (patch)
tree4349044db3dc7169f7086968b0defdc4a0d3554f /source/blender/alembic
parent7509d0bbf1f24e0c6ac519f807d4210c9befe94f (diff)
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.
Diffstat (limited to 'source/blender/alembic')
-rw-r--r--source/blender/alembic/intern/abc_mball.cc40
-rw-r--r--source/blender/alembic/intern/abc_mball.h16
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc9
-rw-r--r--source/blender/alembic/intern/abc_mesh.h1
4 files changed, 33 insertions, 33 deletions
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);