From 89eb05a8908130f8668e4c677d63f3d2b89e68bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=83=C2=83=C3=82=C2=BCvel?= Date: Sat, 28 Oct 2017 19:18:27 +0200 Subject: Alembic: exporting MetaBalls as mesh - Only basis balls are exported, as they represent the resulting mesh. As a result the mesh is written to Alembic using the name of the basis ball. - MetaBalls are converted to a mesh on every frame, then an AbcMeshWriter is used to write that mesh to Alembic. --- source/blender/alembic/CMakeLists.txt | 3 + source/blender/alembic/intern/abc_exporter.cc | 30 +++++-- source/blender/alembic/intern/abc_exporter.h | 3 +- source/blender/alembic/intern/abc_mball.cc | 122 ++++++++++++++++++++++++++ source/blender/alembic/intern/abc_mball.h | 61 +++++++++++++ source/blender/alembic/intern/abc_mesh.cc | 5 ++ source/blender/alembic/intern/abc_mesh.h | 1 + source/blender/alembic/intern/alembic_capi.cc | 2 +- 8 files changed, 218 insertions(+), 9 deletions(-) create mode 100644 source/blender/alembic/intern/abc_mball.cc create mode 100644 source/blender/alembic/intern/abc_mball.h (limited to 'source/blender/alembic') diff --git a/source/blender/alembic/CMakeLists.txt b/source/blender/alembic/CMakeLists.txt index a6e0be6a7f3..fb08887c076 100644 --- a/source/blender/alembic/CMakeLists.txt +++ b/source/blender/alembic/CMakeLists.txt @@ -33,6 +33,7 @@ set(INC ../makesdna ../makesrna ../windowmanager + ../depsgraph ../../../intern/guardedalloc ../../../intern/utfconv ) @@ -51,6 +52,7 @@ set(SRC intern/abc_curves.cc intern/abc_exporter.cc intern/abc_hair.cc + intern/abc_mball.cc intern/abc_mesh.cc intern/abc_nurbs.cc intern/abc_object.cc @@ -66,6 +68,7 @@ set(SRC intern/abc_curves.h intern/abc_exporter.h intern/abc_hair.h + intern/abc_mball.h intern/abc_mesh.h intern/abc_nurbs.h intern/abc_object.h diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 4fe65b96f36..946b89213e6 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -28,6 +28,7 @@ #include "abc_camera.h" #include "abc_curves.h" #include "abc_hair.h" +#include "abc_mball.h" #include "abc_mesh.h" #include "abc_nurbs.h" #include "abc_points.h" @@ -37,6 +38,7 @@ extern "C" { #include "DNA_camera_types.h" #include "DNA_curve_types.h" +#include "DNA_meta_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -54,6 +56,7 @@ extern "C" { #include "BKE_global.h" #include "BKE_idprop.h" #include "BKE_main.h" +#include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_scene.h" @@ -108,7 +111,7 @@ static bool object_is_smoke_sim(Object *ob) return false; } -static bool object_type_is_exportable(Object *ob) +static bool object_type_is_exportable(Scene *scene, Object *ob) { switch (ob->type) { case OB_MESH: @@ -122,6 +125,8 @@ static bool object_type_is_exportable(Object *ob) case OB_SURF: case OB_CAMERA: return true; + case OB_MBALL: + return AbcMBallWriter::isBasisBall(scene, ob); default: return false; } @@ -163,8 +168,9 @@ static bool export_object(const ExportSettings * const settings, Object *ob, /* ************************************************************************** */ -AbcExporter::AbcExporter(Scene *scene, const char *filename, ExportSettings &settings) - : m_settings(settings) +AbcExporter::AbcExporter(Main *bmain, Scene *scene, const char *filename, ExportSettings &settings) + : m_bmain(bmain) + , m_settings(settings) , m_filename(filename) , m_trans_sampling_index(0) , m_shape_sampling_index(0) @@ -361,11 +367,9 @@ void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx) switch (ob->type) { case OB_LAMP: case OB_LATTICE: - case OB_MBALL: case OB_SPEAKER: /* We do not export transforms for objects of these classes. */ break; - default: exploreTransform(eval_ctx, ob, ob->parent); } @@ -382,7 +386,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje return; } - if (object_type_is_exportable(ob)) { + if (object_type_is_exportable(m_scene, ob)) { createTransformWriter(ob, parent, dupliObParent); } @@ -547,7 +551,7 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) { - if (!object_type_is_exportable(ob)) { + if (!object_type_is_exportable(m_scene, ob)) { return; } @@ -613,6 +617,18 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) break; } + case OB_MBALL: + { + MetaBall *mball = static_cast(ob->data); + if (!mball) { + return; + } + + m_shapes.push_back(new AbcMBallWriter( + m_bmain, m_scene, ob, xform, + m_shape_sampling_index, m_settings)); + break; + } } } diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h index f763922a73b..280682b2896 100644 --- a/source/blender/alembic/intern/abc_exporter.h +++ b/source/blender/alembic/intern/abc_exporter.h @@ -81,6 +81,7 @@ struct ExportSettings { }; class AbcExporter { + Main *m_bmain; ExportSettings &m_settings; const char *m_filename; @@ -98,7 +99,7 @@ class AbcExporter { std::vector m_shapes; public: - AbcExporter(Scene *scene, const char *filename, ExportSettings &settings); + AbcExporter(Main *bmain, Scene *scene, const char *filename, ExportSettings &settings); ~AbcExporter(); void operator()(Main *bmain, float &progress, bool &was_canceled); diff --git a/source/blender/alembic/intern/abc_mball.cc b/source/blender/alembic/intern/abc_mball.cc new file mode 100644 index 00000000000..56bb609ace0 --- /dev/null +++ b/source/blender/alembic/intern/abc_mball.cc @@ -0,0 +1,122 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Sybren A. Stüvel + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "abc_mball.h" +#include "abc_mesh.h" +#include "abc_transform.h" + +extern "C" { +#include "DNA_meta_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" + +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_displist.h" +#include "BKE_main.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_object.h" + +#include "DEG_depsgraph.h" +#include "MEM_guardedalloc.h" +} + +AbcMBallWriter::AbcMBallWriter( + Main *bmain, + Scene *scene, + Object *ob, + AbcTransformWriter *parent, + uint32_t time_sampling, + ExportSettings &settings) + : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + , m_bmain(bmain) +{ + m_is_animated = isAnimated(); + + m_mesh_ob = BKE_object_copy(bmain, ob); + m_mesh_ob->curve_cache = (CurveCache*)MEM_callocN( + sizeof(CurveCache), + "CurveCache for AbcMBallWriter"); + + m_mesh_writer = new AbcMeshWriter(scene, 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 +{ + MetaBall *mb = static_cast(m_object->data); + if (mb->adt != NULL) return true; + + /* Any movement of any object in the parent chain + * could cause the mball to deform. */ + for (Object *ob = m_object; ob != NULL; ob = ob->parent) { + if (ob->adt != NULL) return true; + } + return false; +} + +void AbcMBallWriter::do_write() +{ + /* We have already stored a sample for this object. */ + if (!m_first_frame && !m_is_animated) + return; + + 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); + + ListBase disp = {NULL, NULL}; + /* TODO(sergey): This is gonna to work for until EvaluationContext + * only contains for_render flag. As soon as CoW is + * implemented, this is to be rethinked. + */ + EvaluationContext eval_ctx; + DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_RENDER); + BKE_displist_make_mball_forRender(&eval_ctx, m_scene, m_object, &disp); + BKE_mesh_from_metaball(&disp, tmpmesh); + BKE_displist_free(&disp); + + BKE_mesh_texspace_copy_from_object(tmpmesh, m_mesh_ob); + + m_mesh_writer->write(); + + BKE_id_free(m_bmain, tmpmesh); + m_mesh_ob->data = NULL; +} + +bool AbcMBallWriter::isBasisBall(Scene *scene, Object *ob) +{ + Object *basis_ob = BKE_mball_basis_find(scene, ob); + return ob == basis_ob; +} diff --git a/source/blender/alembic/intern/abc_mball.h b/source/blender/alembic/intern/abc_mball.h new file mode 100644 index 00000000000..46b61151216 --- /dev/null +++ b/source/blender/alembic/intern/abc_mball.h @@ -0,0 +1,61 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Sybren A. Stüvel + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __ABC_MBALL_H__ +#define __ABC_MBALL_H__ + +#include "abc_object.h" + +struct AbcMeshWriter; +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 + * 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; + Main *m_bmain; +public: + AbcMBallWriter( + Main *bmain, + Scene *scene, + Object *ob, + AbcTransformWriter *parent, + uint32_t time_sampling, + ExportSettings &settings); + + ~AbcMBallWriter(); + + static bool isBasisBall(Scene *scene, Object *ob); + +private: + virtual void do_write(); + bool isAnimated() const; +}; + + +#endif /* __ABC_MBALL_H__ */ diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 36b134f8b0c..ffaa516d81a 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -358,6 +358,11 @@ bool AbcMeshWriter::isAnimated() const return me->adt != NULL; } +void AbcMeshWriter::setIsAnimated(bool is_animated) +{ + m_is_animated = is_animated; +} + void AbcMeshWriter::do_write() { /* We have already stored a sample for this object. */ diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 5c1eb01d8e0..77c352d7cd3 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -57,6 +57,7 @@ public: ExportSettings &settings); ~AbcMeshWriter(); + void setIsAnimated(bool is_animated); private: virtual void do_write(); diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index 5503dcb1527..0d2316ce7d9 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -259,7 +259,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo try { Scene *scene = data->scene; - AbcExporter exporter(scene, data->filename, data->settings); + AbcExporter exporter(data->bmain, scene, data->filename, data->settings); const int orig_frame = CFRA; -- cgit v1.2.3