diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2019-04-11 16:03:08 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2019-04-11 17:22:55 +0300 |
commit | 0576f4ca9b41f1f0e7dfdd896e539488419306ff (patch) | |
tree | 4349044db3dc7169f7086968b0defdc4a0d3554f /source/blender/alembic/intern/abc_mball.cc | |
parent | 7509d0bbf1f24e0c6ac519f807d4210c9befe94f (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/intern/abc_mball.cc')
-rw-r--r-- | source/blender/alembic/intern/abc_mball.cc | 40 |
1 files changed, 17 insertions, 23 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) |