[Bf-blender-cvs] [80fa6d2] alembic_basic_io: Curves: fix corrupted displist.

Kévin Dietrich noreply at git.blender.org
Fri Jul 8 09:45:17 CEST 2016


Commit: 80fa6d2b8a8e9d099ff10671f46b5d50c9f5755d
Author: Kévin Dietrich
Date:   Fri Jul 8 09:44:10 2016 +0200
Branches: alembic_basic_io
https://developer.blender.org/rB80fa6d2b8a8e9d099ff10671f46b5d50c9f5755d

Curves: fix corrupted displist.

See comment in the code for explanation.

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

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_hair.cc
M	source/blender/alembic/intern/alembic_capi.cc
M	source/blender/modifiers/intern/MOD_meshsequencecache.c

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

diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index 896b66b..1e2850a 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -85,6 +85,7 @@ void ABC_get_transform(AbcArchiveHandle *handle,
                        float scale);
 
 struct DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle,
+                                  struct Object *ob,
                                   struct DerivedMesh *dm,
                                   const char *object_path,
                                   const float time);
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 15442fb..6c08435 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -203,9 +203,22 @@ void AbcCurveReader::readObjectData(Main *bmain, Scene *scene, float time)
 	cu->flag |= CU_DEFORM_FILL | CU_3D;
 	cu->actvert = CU_ACT_NONE;
 
-	const ISampleSelector sample_sel(time);
+	m_object = BKE_object_add(bmain, scene, OB_CURVE, m_object_name.c_str());
+	m_object->data = cu;
+
+	read_curve_sample(cu, m_curves_schema, time);
+
+	if (m_settings->is_sequence || !m_curves_schema.isConstant()) {
+		addDefaultModifier(bmain);
+	}
+}
+
+/* ************************************************************************** */
 
-	ICurvesSchema::Sample smp = m_curves_schema.getValue(sample_sel);
+void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
+{
+	const ISampleSelector sample_sel(time);
+	ICurvesSchema::Sample smp = schema.getValue(sample_sel);
 	const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
 	const P3fArraySamplePtr positions = smp.getPositions();
 	const FloatArraySamplePtr weights = smp.getPositionWeights();
@@ -213,7 +226,7 @@ void AbcCurveReader::readObjectData(Main *bmain, Scene *scene, float time)
 	const CurvePeriodicity periodicity = smp.getWrap();
 	const UcharArraySamplePtr orders = smp.getOrders();
 
-	const IFloatGeomParam widths_param = m_curves_schema.getWidthsParam();
+	const IFloatGeomParam widths_param = schema.getWidthsParam();
 	FloatArraySamplePtr radiuses;
 
 	if (widths_param.valid()) {
@@ -221,9 +234,6 @@ void AbcCurveReader::readObjectData(Main *bmain, Scene *scene, float time)
 		radiuses = wsample.getVals();
 	}
 
-	m_object = BKE_object_add(bmain, scene, OB_CURVE, m_object_name.c_str());
-	m_object->data = cu;
-
 	int knot_offset = 0;
 
 	size_t idx = 0;
@@ -237,12 +247,12 @@ void AbcCurveReader::readObjectData(Main *bmain, Scene *scene, float time)
 		nu->pntsv = 1;
 		nu->flag |= CU_SMOOTH;
 
-		nu->orderu = 1;
+		nu->orderu = num_verts;
 
 		if (smp.getType() == Alembic::AbcGeom::kCubic) {
             nu->orderu = 3;
         }
-        else if (orders->size() > i) {
+        else if (orders && orders->size() > i) {
             nu->orderu = static_cast<short>((*orders)[i] - 1);
         }
 
@@ -290,7 +300,7 @@ void AbcCurveReader::readObjectData(Main *bmain, Scene *scene, float time)
 		float weight = 1.0f;
 
 		const bool do_radius = (radiuses != NULL) && (radiuses->size() > 1);
-		float radius = (radiuses->size() == 1) ? (*radiuses)[0] : 1.0f;
+		float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : 1.0f;
 
 		nu->type = CU_NURBS;
 
@@ -339,8 +349,4 @@ void AbcCurveReader::readObjectData(Main *bmain, Scene *scene, float time)
 
 		BLI_addtail(BKE_curve_nurbs_get(cu), nu);
 	}
-
-	if (m_settings->is_sequence || !m_curves_schema.isConstant()) {
-		addDefaultModifier(bmain);
-	}
 }
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index 8c754db..382ded4 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -26,6 +26,8 @@
 
 #include "abc_object.h"
 
+struct Curve;
+
 /* ************************************************************************** */
 
 class AbcCurveWriter : public AbcObjectWriter {
@@ -54,3 +56,7 @@ public:
 
 	void readObjectData(Main *bmain, Scene *scene, float time);
 };
+
+/* ************************************************************************** */
+
+void read_curve_sample(Curve *cu, const Alembic::AbcGeom::ICurvesSchema &schema, const float time);
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc
index 3e76479..45bf9b7 100644
--- a/source/blender/alembic/intern/abc_hair.cc
+++ b/source/blender/alembic/intern/abc_hair.cc
@@ -288,4 +288,3 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
 		}
 	}
 }
-
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index a4817a6..ec62248 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -42,6 +42,7 @@ extern "C" {
 #include "MEM_guardedalloc.h"
 
 #include "DNA_cachefile_types.h"
+#include "DNA_curve_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
@@ -63,6 +64,7 @@ extern "C" {
 
 #include "BLI_fileops.h"
 #include "BLI_ghash.h"
+#include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
@@ -71,6 +73,7 @@ extern "C" {
 #include "WM_types.h"
 }
 
+using Alembic::Abc::Int32ArraySamplePtr;
 using Alembic::Abc::ObjectHeader;
 
 using Alembic::AbcGeom::ErrorHandler;
@@ -821,7 +824,13 @@ static DerivedMesh *read_points_sample(DerivedMesh *dm, const IObject &iobject,
 	return dm;
 }
 
-static DerivedMesh *read_curves_sample(DerivedMesh *dm, const IObject &iobject, const float time)
+/* NOTE: Alembic only stores data about control points, but the DerivedMesh
+ * passed from the cache modifier contains the displist, which has more data
+ * than the control points, so to avoid corrupting the displist we modify the
+ * object directly and create a new DerivedMesh from that. Also we might need to
+ * create new or delete existing NURBS in the curve.
+ */
+static DerivedMesh *read_curves_sample(Object *ob, const IObject &iobject, const float time)
 {
 	ICurves points(iobject, kWrapExisting);
 	ICurvesSchema schema = points.getSchema();
@@ -829,13 +838,46 @@ static DerivedMesh *read_curves_sample(DerivedMesh *dm, const IObject &iobject,
 	const ICurvesSchema::Sample sample = schema.getValue(sample_sel);
 
 	const P3fArraySamplePtr &positions = sample.getPositions();
+	const Int32ArraySamplePtr num_vertices = sample.getCurvesNumVertices();
 
-	read_mverts(dm->getVertArray(dm), positions, N3fArraySamplePtr());
+	int vertex_idx = 0;
+	int curve_idx = 0;
+	Curve *curve = static_cast<Curve *>(ob->data);
 
-	return dm;
+	const int curve_count = BLI_listbase_count(&curve->nurb);
+
+	if (curve_count != num_vertices->size()) {
+		BLI_freelistN(&curve->nurb);
+		read_curve_sample(curve, schema, time);
+	}
+	else {
+		Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
+		for (; nurbs; nurbs = nurbs->next, ++curve_idx) {
+			const int totpoint = (*num_vertices)[curve_idx];
+
+			if (nurbs->bp) {
+				BPoint *point = nurbs->bp;
+
+				for (int i = 0; i < totpoint; ++i, ++point, ++vertex_idx) {
+					const Imath::V3f &pos = (*positions)[vertex_idx];
+					copy_yup_zup(point->vec, pos.getValue());
+				}
+			}
+			else if (nurbs->bezt) {
+				BezTriple *bezier = nurbs->bezt;
+
+				for (int i = 0; i < totpoint; ++i, ++bezier, ++vertex_idx) {
+					const Imath::V3f &pos = (*positions)[vertex_idx];
+					copy_yup_zup(bezier->vec[1], pos.getValue());
+				}
+			}
+		}
+	}
+
+	return CDDM_from_curve(ob);
 }
 
-DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle, DerivedMesh *dm, const char *object_path, const float time)
+DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle, Object *ob, DerivedMesh *dm, const char *object_path, const float time)
 {
 	IArchive *archive = archive_from_handle(handle);
 
@@ -859,7 +901,7 @@ DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle, DerivedMesh *dm, const char
 		return read_points_sample(dm, iobject, time);
 	}
 	else if (ICurves::matches(header)) {
-		return read_curves_sample(dm, iobject, time);
+		return read_curves_sample(ob, iobject, time);
 	}
 
 	return NULL;
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index e1beb1f..c6a26e8 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -94,12 +94,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 	const float time = BKE_cachefile_time_offset(mcmd->cache_file, frame, FPS);
 
 	DerivedMesh *result = ABC_read_mesh(mcmd->cache_file->handle,
+	                                    ob,
 	                                    dm,
 	                                    mcmd->abc_object_path,
 	                                    time);
 
 	return result ? result : dm;
-	UNUSED_VARS(ob, flag);
+	UNUSED_VARS(flag);
 #else
 	return dm;
 	UNUSED_VARS(md, ob, flag);




More information about the Bf-blender-cvs mailing list