[Bf-blender-cvs] [3ce9bcee705] master: Alembic export: write curve/NURBS as mesh

Sybren A. Stüvel noreply at git.blender.org
Wed Jan 16 11:00:15 CET 2019


Commit: 3ce9bcee70537a52f8d802abfb9e14c34f9a9251
Author: Sybren A. Stüvel
Date:   Tue Jan 15 16:45:12 2019 +0100
Branches: master
https://developer.blender.org/rB3ce9bcee70537a52f8d802abfb9e14c34f9a9251

Alembic export: write curve/NURBS as mesh

It's now possible to export curves and NURBS as mesh data to Alembic.
This allows artists to do any crazy thing on curves and export the
visual result to Alembic for interoperability with other software (or
caching for later use, etc.). It's an often-requested feature.

This works around T60503 and the fixes export part of T51311.

Note that exporting zero-width curves is currently not supported, as
exporting a faceless mesh (e.g. just edges and vertices) is not
supported by the mesh writer at all.

To test, create a curve with thickness (for example extruded), export to
Alembic and check the 'Curves to Mesh' checkbox in the export options.

Reviewers: sergey

Differential Revision: https://developer.blender.org/D4213

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

M	source/blender/alembic/ABC_alembic.h
M	source/blender/alembic/intern/abc_curves.cc
M	source/blender/alembic/intern/abc_curves.h
M	source/blender/alembic/intern/abc_exporter.cc
M	source/blender/alembic/intern/abc_exporter.h
M	source/blender/alembic/intern/abc_mesh.cc
M	source/blender/alembic/intern/abc_mesh.h
M	source/blender/alembic/intern/alembic_capi.cc
M	source/blender/editors/io/io_alembic.c

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

diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index 08136fc2f49..4c06caeae15 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -58,6 +58,7 @@ struct AlembicExportParams {
 	bool normals;
 	bool vcolors;
 	bool apply_subdiv;
+	bool curves_as_mesh;
 	bool flatten_hierarchy;
 	bool visible_layers_only;
 	bool renderable_only;
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 9501c643e32..67754a1732b 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -194,6 +194,27 @@ void AbcCurveWriter::do_write()
 	m_schema.set(m_sample);
 }
 
+
+AbcCurveMeshWriter::AbcCurveMeshWriter(Object *ob,
+                                       AbcTransformWriter *parent,
+                                       uint32_t time_sampling,
+                                       ExportSettings &settings)
+    : AbcGenericMeshWriter(ob, parent, time_sampling, settings)
+{}
+
+Mesh *AbcCurveMeshWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
+{
+	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;
+	return BKE_mesh_new_nomain_from_curve(ob_eval);
+}
+
+
 /* ************************************************************************** */
 
 AbcCurveReader::AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index eb80553620d..1878826468a 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -26,6 +26,7 @@
 #define __ABC_CURVES_H__
 
 #include "abc_object.h"
+#include "abc_mesh.h"
 
 struct Curve;
 
@@ -41,9 +42,21 @@ public:
 	               uint32_t time_sampling,
 	               ExportSettings &settings);
 
+protected:
 	void do_write();
 };
 
+class AbcCurveMeshWriter : public AbcGenericMeshWriter {
+public:
+	AbcCurveMeshWriter(Object *ob,
+	                   AbcTransformWriter *parent,
+	                   uint32_t time_sampling,
+	                   ExportSettings &settings);
+
+protected:
+	Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree);
+};
+
 /* ************************************************************************** */
 
 class AbcCurveReader : public AbcObjectReader {
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index ff1465103eb..a4b5963dd13 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -598,7 +598,13 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
 				return;
 			}
 
-			m_shapes.push_back(new AbcNurbsWriter(ob, xform, m_shape_sampling_index, m_settings));
+			AbcObjectWriter *writer;
+			if (m_settings.curves_as_mesh) {
+				writer = new AbcCurveMeshWriter(ob, xform, m_shape_sampling_index, m_settings);
+			} else {
+				writer = new AbcNurbsWriter(ob, xform, m_shape_sampling_index, m_settings);
+			}
+			m_shapes.push_back(writer);
 			break;
 		}
 		case OB_CURVE:
@@ -609,7 +615,13 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
 				return;
 			}
 
-			m_shapes.push_back(new AbcCurveWriter(ob, xform, m_shape_sampling_index, m_settings));
+			AbcObjectWriter *writer;
+			if (m_settings.curves_as_mesh) {
+				writer = new AbcCurveMeshWriter(ob, xform, m_shape_sampling_index, m_settings);
+			} else {
+				writer = new AbcCurveWriter(ob, xform, m_shape_sampling_index, m_settings);
+			}
+			m_shapes.push_back(writer);
 			break;
 		}
 		case OB_CAMERA:
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index 74af85bfef9..e5604884bad 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -71,6 +71,7 @@ struct ExportSettings {
 	bool export_particles;
 
 	bool apply_subdiv;
+	bool curves_as_mesh;
 	bool use_subdiv_schema;
 	bool export_child_hairs;
 	bool export_ogawa;
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 229f788f87c..2b6e1fd86ec 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -38,6 +38,8 @@ extern "C" {
 #include "BLI_math_geom.h"
 #include "BLI_string.h"
 
+#include "BKE_animsys.h"
+#include "BKE_key.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
@@ -338,10 +340,23 @@ AbcGenericMeshWriter::~AbcGenericMeshWriter()
 
 bool AbcGenericMeshWriter::isAnimated() const
 {
+	if (m_object->data != NULL) {
+		AnimData *adt = BKE_animdata_from_id(static_cast<ID*>(m_object->data));
+		/* TODO(Sybren): make this check more strict, as the AnimationData may
+		 * actually be empty (no fcurves, drivers, etc.) and thus effectively
+		 * have no animation at all. */
+		if (adt != NULL) {
+			return true;
+		}
+	}
+	if (BKE_key_from_object(m_object) != NULL) {
+		return true;
+	}
+
 	/* Test modifiers. */
 	ModifierData *md = static_cast<ModifierData *>(m_object->modifiers.first);
-
 	while (md) {
+
 		if (md->type != eModifierType_Subsurf) {
 			return true;
 		}
@@ -656,27 +671,12 @@ AbcMeshWriter::AbcMeshWriter(Object *ob,
 AbcMeshWriter::~AbcMeshWriter()
 {}
 
-struct Mesh *AbcMeshWriter::getEvaluatedMesh(struct Scene *scene_eval, struct Object *ob_eval,
-                                             bool &UNUSED(r_needsfree))
+Mesh *AbcMeshWriter::getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &UNUSED(r_needsfree))
 {
 	return mesh_get_eval_final(m_settings.depsgraph, scene_eval, ob_eval, CD_MASK_MESH);
 }
 
 
-bool AbcMeshWriter::isAnimated() const
-{
-	Mesh *me = static_cast<Mesh *>(m_object->data);
-	if (me->key != NULL) {
-		return true;
-	}
-	if (me->adt != NULL) {
-		return true;
-	}
-
-	return AbcGenericMeshWriter::isAnimated();
-}
-
-
 /* ************************************************************************** */
 
 /* Some helpers for mesh generation */
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 953c15e5eaf..b1842b14d17 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -52,9 +52,9 @@ protected:
 
 public:
 	AbcGenericMeshWriter(Object *ob,
-	              AbcTransformWriter *parent,
-	              uint32_t time_sampling,
-	              ExportSettings &settings);
+	                     AbcTransformWriter *parent,
+	                     uint32_t time_sampling,
+	                     ExportSettings &settings);
 
 	~AbcGenericMeshWriter();
 	void setIsAnimated(bool is_animated);
@@ -62,9 +62,9 @@ public:
 protected:
 	virtual void do_write();
 	virtual bool isAnimated() const;
-	virtual struct Mesh *getEvaluatedMesh(struct Scene *scene_eval, struct Object *ob_eval, bool &r_needsfree) = 0;
+	virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) = 0;
 
-	struct Mesh *getFinalMesh(bool &r_needsfree);
+	Mesh *getFinalMesh(bool &r_needsfree);
 
 	void writeMesh(struct Mesh *mesh);
 	void writeSubD(struct Mesh *mesh);
@@ -89,8 +89,7 @@ public:
 
 	~AbcMeshWriter();
 protected:
-	bool isAnimated() const override;
-	virtual struct Mesh *getEvaluatedMesh(struct Scene *scene_eval, struct Object *ob_eval, bool &r_needsfree) override;
+	virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) override;
 };
 
 
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 16f6a4410bc..7abb53dc2f4 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -364,6 +364,7 @@ bool ABC_export(
 	job->settings.export_hair = params->export_hair;
 	job->settings.export_particles = params->export_particles;
 	job->settings.apply_subdiv = params->apply_subdiv;
+	job->settings.curves_as_mesh = params->curves_as_mesh;
 	job->settings.flatten_hierarchy = params->flatten_hierarchy;
 
 	/* TODO(Sybren): visible_layer & renderable only is ignored for now,
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 38e0ec0cb3a..cbfb816d12a 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -130,6 +130,7 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
 	    .normals = RNA_boolean_get(op->ptr, "normals"),
 	    .vcolors = RNA_boolean_get(op->ptr, "vcolors"),
 	    .apply_subdiv = RNA_boolean_get(op->ptr, "apply_subdiv"),
+	    .curves_as_mesh = RNA_boolean_get(op->ptr, "curves_as_mesh"),
 	    .flatten_hierarchy = RNA_boolean_get(op->ptr, "flatten"),
 	    .visible_layers_only = RNA_boolean_get(op->ptr, "visible_layers_only"),
 	    .renderable_only = RNA_boolean_get(op->ptr, "renderable_only"),
@@ -245,6 +246,9 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
 	row = uiLayoutRow(box, false);
 	uiItemR(row, imfptr, "apply_subdiv", 0, NULL, ICON_NONE);
 
+	row = uiLayoutRow(box, false);
+	uiItemR(row, imfptr, "curves_as_mesh", 0, NULL, ICON_NONE);
+
 	row = uiLayoutRow(box, false);
 	uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
 
@@ -373,6 +377,9 @@ void WM_OT_alembic_export(wmOperatorType *ot)
 	RNA_def_boolean(ot->srna, "apply_subdiv", 0,
 	                "Apply Subsurf", "Export subdivision surfaces as meshes");
 
+	RNA_def_boolean(ot->srna, "curves_as_mesh", false,
+	                "Curves as Mesh", "Export curves and NURBS surfaces as meshes");
+
 	RNA_def_enum(ot->srna, "compression_type", rna_enum_abc_compression_items,
 	             ABC_ARCHIVE_OGAWA, "Compression", "");



More information about the Bf-blender-cvs mailing list