[Bf-blender-cvs] [f6b1094973d] temp-alembic-exporter-T73363-ms2: Alembic: added NURBS surface support to the new exporter

Sybren A. Stüvel noreply at git.blender.org
Tue Apr 28 13:20:20 CEST 2020


Commit: f6b1094973da30e13521bdeddd8aa3512d1b77ce
Author: Sybren A. Stüvel
Date:   Tue Apr 28 12:22:56 2020 +0200
Branches: temp-alembic-exporter-T73363-ms2
https://developer.blender.org/rBf6b1094973da30e13521bdeddd8aa3512d1b77ce

Alembic: added NURBS surface support to the new exporter

Exporting NURBS as polymesh works fine. Exporting as Alembic NURBS patches
is spotty at best, just like the original exporter, so the new exporter
is at feature parity here.

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

M	source/blender/io/alembic/CMakeLists.txt
M	source/blender/io/alembic/intern/export/abc_hierarchy_iterator.cc
A	source/blender/io/alembic/intern/export/abc_writer_nurbs.cc
A	source/blender/io/alembic/intern/export/abc_writer_nurbs.h

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

diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt
index 4757825dd5d..569f151003e 100644
--- a/source/blender/io/alembic/CMakeLists.txt
+++ b/source/blender/io/alembic/CMakeLists.txt
@@ -100,6 +100,7 @@ set(SRC
   intern/export/abc_writer_curve.cc
   intern/export/abc_writer_mesh.cc
   intern/export/abc_writer_metaball.cc
+  intern/export/abc_writer_nurbs.cc
   intern/export/abc_writer_transform.cc
 
   intern/export/abc_archive.h
@@ -110,6 +111,7 @@ set(SRC
   intern/export/abc_writer_curve.h
   intern/export/abc_writer_mesh.h
   intern/export/abc_writer_metaball.h
+  intern/export/abc_writer_nurbs.h
   intern/export/abc_writer_transform.h
 )
 
diff --git a/source/blender/io/alembic/intern/export/abc_hierarchy_iterator.cc b/source/blender/io/alembic/intern/export/abc_hierarchy_iterator.cc
index c2e5df1ac7d..ad4c3afa1f4 100644
--- a/source/blender/io/alembic/intern/export/abc_hierarchy_iterator.cc
+++ b/source/blender/io/alembic/intern/export/abc_hierarchy_iterator.cc
@@ -23,6 +23,7 @@
 #include "abc_writer_curve.h"
 #include "abc_writer_mesh.h"
 #include "abc_writer_metaball.h"
+#include "abc_writer_nurbs.h"
 #include "abc_writer_transform.h"
 
 #include <string>
@@ -131,13 +132,20 @@ AbstractHierarchyWriter *ABCHierarchyIterator::create_data_writer(const Hierarch
         data_writer = new ABCCurveWriter(writer_args);
       }
       break;
+    case OB_SURF:
+      if (params_.curves_as_mesh) {
+        data_writer = new ABCCurveMeshWriter(writer_args);
+      }
+      else {
+        data_writer = new ABCNurbsWriter(writer_args);
+      }
+      break;
     case OB_MBALL:
       data_writer = new ABCMetaballWriter(writer_args);
       break;
 
     case OB_EMPTY:
     case OB_LAMP:
-    case OB_SURF:
     case OB_FONT:
     case OB_SPEAKER:
     case OB_LIGHTPROBE:
diff --git a/source/blender/io/alembic/intern/export/abc_writer_nurbs.cc b/source/blender/io/alembic/intern/export/abc_writer_nurbs.cc
new file mode 100644
index 00000000000..e5d5ce2f31b
--- /dev/null
+++ b/source/blender/io/alembic/intern/export/abc_writer_nurbs.cc
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#include "abc_writer_nurbs.h"
+#include "intern/abc_axis_conversion.h"
+
+extern "C" {
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_listbase.h"
+
+#include "BKE_curve.h"
+}
+
+namespace ABC {
+
+using Alembic::Abc::OObject;
+using Alembic::AbcGeom::FloatArraySample;
+using Alembic::AbcGeom::OBoolProperty;
+using Alembic::AbcGeom::OCompoundProperty;
+using Alembic::AbcGeom::ONuPatch;
+using Alembic::AbcGeom::ONuPatchSchema;
+
+ABCNurbsWriter::ABCNurbsWriter(const ABCWriterConstructorArgs &args) : ABCAbstractWriter(args)
+{
+}
+
+void ABCNurbsWriter::create_alembic_objects()
+{
+  /* If the object is static, use the default static time sampling. */
+  uint32_t timesample_index = is_animated_ ? timesample_index_geometry_ : 0;
+
+  Curve *curve = static_cast<Curve *>(args_.object->data);
+  size_t num_nurbs = BLI_listbase_count(&curve->nurb);
+  OObject abc_parent = args_.abc_parent;
+
+  for (size_t i = 0; i < num_nurbs; i++) {
+    std::stringstream str;
+    str << args_.abc_name << '_' << i;
+
+    while (abc_parent.getChildHeader(str.str())) {
+      str << "_";
+    }
+
+    ONuPatch nurbs(abc_parent, str.str().c_str(), timesample_index);
+    abc_nurbs_.push_back(nurbs);
+    abc_nurbs_schemas_.push_back(nurbs.getSchema());
+  }
+}
+
+const OObject ABCNurbsWriter::get_alembic_object() const
+{
+  if (abc_nurbs_.empty()) {
+    return OObject();
+  }
+  /* For parenting purposes within the Alembic file, all NURBS patches are equal, so just use the
+   * first one. */
+  return abc_nurbs_[0];
+}
+
+bool ABCNurbsWriter::check_is_animated(const HierarchyContext &context) const
+{
+  /* Check if object has shape keys. */
+  Curve *cu = static_cast<Curve *>(context.object->data);
+  return (cu->key != NULL);
+}
+
+bool ABCNurbsWriter::is_supported(const HierarchyContext *context) const
+{
+  return ELEM(context->object->type, OB_SURF, OB_CURVE);
+}
+
+static void get_knots(std::vector<float> &knots, const int num_knots, float *nu_knots)
+{
+  if (num_knots <= 1) {
+    return;
+  }
+
+  /* Add an extra knot at the beginning and end of the array since most apps
+   * require/expect them. */
+  knots.reserve(num_knots + 2);
+
+  knots.push_back(0.0f);
+
+  for (int i = 0; i < num_knots; i++) {
+    knots.push_back(nu_knots[i]);
+  }
+
+  knots[0] = 2.0f * knots[1] - knots[2];
+  knots.push_back(2.0f * knots[num_knots] - knots[num_knots - 1]);
+}
+
+void ABCNurbsWriter::do_write(HierarchyContext &context)
+{
+  Curve *curve = static_cast<Curve *>(context.object->data);
+  ListBase *nulb;
+
+  if (context.object->runtime.curve_cache->deformed_nurbs.first != NULL) {
+    nulb = &context.object->runtime.curve_cache->deformed_nurbs;
+  }
+  else {
+    nulb = BKE_curve_nurbs_get(curve);
+  }
+
+  size_t count = 0;
+  for (Nurb *nu = static_cast<Nurb *>(nulb->first); nu; nu = nu->next, count++) {
+    std::vector<float> knotsU;
+    get_knots(knotsU, KNOTSU(nu), nu->knotsu);
+
+    std::vector<float> knotsV;
+    get_knots(knotsV, KNOTSV(nu), nu->knotsv);
+
+    const int size = nu->pntsu * nu->pntsv;
+    std::vector<Imath::V3f> positions(size);
+    std::vector<float> weights(size);
+
+    const BPoint *bp = nu->bp;
+
+    for (int i = 0; i < size; i++, bp++) {
+      copy_yup_from_zup(positions[i].getValue(), bp->vec);
+      weights[i] = bp->vec[3];
+    }
+
+    ONuPatchSchema::Sample sample;
+    sample.setUOrder(nu->orderu + 1);
+    sample.setVOrder(nu->orderv + 1);
+    sample.setPositions(positions);
+    sample.setPositionWeights(weights);
+    sample.setUKnot(FloatArraySample(knotsU));
+    sample.setVKnot(FloatArraySample(knotsV));
+    sample.setNu(nu->pntsu);
+    sample.setNv(nu->pntsv);
+
+    /* TODO(kevin): to accommodate other software we should duplicate control
+     * points to indicate that a NURBS is cyclic. */
+    OCompoundProperty user_props = abc_nurbs_schemas_[count].getUserProperties();
+
+    if ((nu->flagu & CU_NURB_ENDPOINT) != 0) {
+      OBoolProperty prop(user_props, "endpoint_u");
+      prop.set(true);
+    }
+
+    if ((nu->flagv & CU_NURB_ENDPOINT) != 0) {
+      OBoolProperty prop(user_props, "endpoint_v");
+      prop.set(true);
+    }
+
+    if ((nu->flagu & CU_NURB_CYCLIC) != 0) {
+      OBoolProperty prop(user_props, "cyclic_u");
+      prop.set(true);
+    }
+
+    if ((nu->flagv & CU_NURB_CYCLIC) != 0) {
+      OBoolProperty prop(user_props, "cyclic_v");
+      prop.set(true);
+    }
+
+    abc_nurbs_schemas_[count].set(sample);
+  }
+}
+
+}  // namespace ABC
diff --git a/source/blender/io/alembic/intern/export/abc_writer_nurbs.h b/source/blender/io/alembic/intern/export/abc_writer_nurbs.h
new file mode 100644
index 00000000000..8048fdcf81d
--- /dev/null
+++ b/source/blender/io/alembic/intern/export/abc_writer_nurbs.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include "abc_writer_abstract.h"
+#include "abc_writer_mesh.h"
+
+#include <vector>
+
+namespace ABC {
+
+class ABCNurbsWriter : public ABCAbstractWriter {
+ private:
+  std::vector<Alembic::AbcGeom::ONuPatch> abc_nurbs_;
+  std::vector<Alembic::AbcGeom::ONuPatchSchema> abc_nurbs_schemas_;
+
+ public:
+  ABCNurbsWriter(const ABCWriterConstructorArgs &args);
+
+  void create_alembic_objects() override;
+  const Alembic::Abc::OObject get_alembic_object() const override;
+
+ protected:
+  bool is_supported(const HierarchyContext *context) const override;
+  void do_write(HierarchyContext &context) override;
+  bool check_is_animated(const HierarchyContext &context) const override;
+};
+
+class ABCNurbsMeshWriter : public ABCGenericMeshWriter {
+ public:
+  ABCNurbsMeshWriter(const ABCWriterConstructorArgs &args);
+
+ protected:
+  virtual Mesh *get_export_mesh(Object *object_eval, bool &r_needsfree) override;
+};
+
+}  // namespace ABC



More information about the Bf-blender-cvs mailing list