Alembic import/export: write curve resolution to user property
Curve resolution isn't natively supported by Alembic, hence it is stored in a user property "blender:resolution". I've looked at a Maya curves example file, but that also didn't contain any information about curve resolution. Differential Revision: https://developer.blender.org/D2634 Reviewers: kevindietrich
This commit is contained in:
@@ -49,19 +49,26 @@ using Alembic::Abc::Int32ArraySamplePtr;
|
|||||||
using Alembic::Abc::FloatArraySamplePtr;
|
using Alembic::Abc::FloatArraySamplePtr;
|
||||||
using Alembic::Abc::P3fArraySamplePtr;
|
using Alembic::Abc::P3fArraySamplePtr;
|
||||||
using Alembic::Abc::UcharArraySamplePtr;
|
using Alembic::Abc::UcharArraySamplePtr;
|
||||||
|
using Alembic::Abc::PropertyHeader;
|
||||||
|
|
||||||
|
using Alembic::AbcGeom::ICompoundProperty;
|
||||||
using Alembic::AbcGeom::ICurves;
|
using Alembic::AbcGeom::ICurves;
|
||||||
using Alembic::AbcGeom::ICurvesSchema;
|
using Alembic::AbcGeom::ICurvesSchema;
|
||||||
using Alembic::AbcGeom::IFloatGeomParam;
|
using Alembic::AbcGeom::IFloatGeomParam;
|
||||||
|
using Alembic::AbcGeom::IInt16Property;
|
||||||
using Alembic::AbcGeom::ISampleSelector;
|
using Alembic::AbcGeom::ISampleSelector;
|
||||||
using Alembic::AbcGeom::kWrapExisting;
|
using Alembic::AbcGeom::kWrapExisting;
|
||||||
using Alembic::AbcGeom::CurvePeriodicity;
|
using Alembic::AbcGeom::CurvePeriodicity;
|
||||||
|
|
||||||
|
using Alembic::AbcGeom::OCompoundProperty;
|
||||||
using Alembic::AbcGeom::OCurves;
|
using Alembic::AbcGeom::OCurves;
|
||||||
using Alembic::AbcGeom::OCurvesSchema;
|
using Alembic::AbcGeom::OCurvesSchema;
|
||||||
|
using Alembic::AbcGeom::OInt16Property;
|
||||||
using Alembic::AbcGeom::ON3fGeomParam;
|
using Alembic::AbcGeom::ON3fGeomParam;
|
||||||
using Alembic::AbcGeom::OV2fGeomParam;
|
using Alembic::AbcGeom::OV2fGeomParam;
|
||||||
|
|
||||||
|
#define ABC_CURVE_RESOLUTION_U_PROPNAME "blender:resolution"
|
||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
AbcCurveWriter::AbcCurveWriter(Scene *scene,
|
AbcCurveWriter::AbcCurveWriter(Scene *scene,
|
||||||
@@ -73,6 +80,11 @@ AbcCurveWriter::AbcCurveWriter(Scene *scene,
|
|||||||
{
|
{
|
||||||
OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
|
OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
|
||||||
m_schema = curves.getSchema();
|
m_schema = curves.getSchema();
|
||||||
|
|
||||||
|
Curve *cu = static_cast<Curve *>(m_object->data);
|
||||||
|
OCompoundProperty user_props = m_schema.getUserProperties();
|
||||||
|
OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME);
|
||||||
|
user_prop_resolu.set(cu->resolu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbcCurveWriter::do_write()
|
void AbcCurveWriter::do_write()
|
||||||
@@ -205,12 +217,22 @@ void AbcCurveReader::readObjectData(Main *bmain, float time)
|
|||||||
|
|
||||||
cu->flag |= CU_DEFORM_FILL | CU_3D;
|
cu->flag |= CU_DEFORM_FILL | CU_3D;
|
||||||
cu->actvert = CU_ACT_NONE;
|
cu->actvert = CU_ACT_NONE;
|
||||||
|
|
||||||
|
const ISampleSelector sample_sel(time);
|
||||||
|
ICompoundProperty user_props = m_curves_schema.getUserProperties();
|
||||||
|
const PropertyHeader *header = user_props.getPropertyHeader(ABC_CURVE_RESOLUTION_U_PROPNAME);
|
||||||
|
if (header != NULL && header->isScalar() && IInt16Property::matches(*header)) {
|
||||||
|
IInt16Property resolu(user_props, header->getName());
|
||||||
|
cu->resolu = resolu.getValue(sample_sel);
|
||||||
|
}
|
||||||
|
else {
|
||||||
cu->resolu = 1;
|
cu->resolu = 1;
|
||||||
|
}
|
||||||
|
|
||||||
m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str());
|
m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str());
|
||||||
m_object->data = cu;
|
m_object->data = cu;
|
||||||
|
|
||||||
read_curve_sample(cu, m_curves_schema, time);
|
read_curve_sample(cu, m_curves_schema, sample_sel);
|
||||||
|
|
||||||
if (has_animations(m_curves_schema, m_settings)) {
|
if (has_animations(m_curves_schema, m_settings)) {
|
||||||
addCacheModifier();
|
addCacheModifier();
|
||||||
@@ -219,9 +241,8 @@ void AbcCurveReader::readObjectData(Main *bmain, float time)
|
|||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
|
void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSelector &sample_sel)
|
||||||
{
|
{
|
||||||
const ISampleSelector sample_sel(time);
|
|
||||||
ICurvesSchema::Sample smp = schema.getValue(sample_sel);
|
ICurvesSchema::Sample smp = schema.getValue(sample_sel);
|
||||||
const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
|
const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
|
||||||
const P3fArraySamplePtr positions = smp.getPositions();
|
const P3fArraySamplePtr positions = smp.getPositions();
|
||||||
@@ -383,7 +404,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, const float
|
|||||||
|
|
||||||
if (curve_count != num_vertices->size()) {
|
if (curve_count != num_vertices->size()) {
|
||||||
BKE_nurbList_free(&curve->nurb);
|
BKE_nurbList_free(&curve->nurb);
|
||||||
read_curve_sample(curve, m_curves_schema, time);
|
read_curve_sample(curve, m_curves_schema, sample_sel);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
|
Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
|
||||||
|
@@ -61,6 +61,8 @@ public:
|
|||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
void read_curve_sample(Curve *cu, const Alembic::AbcGeom::ICurvesSchema &schema, const float time);
|
void read_curve_sample(Curve *cu,
|
||||||
|
const Alembic::AbcGeom::ICurvesSchema &schema,
|
||||||
|
const Alembic::Abc::ISampleSelector &sample_selector);
|
||||||
|
|
||||||
#endif /* __ABC_CURVES_H__ */
|
#endif /* __ABC_CURVES_H__ */
|
||||||
|
@@ -128,6 +128,7 @@ class AbstractAlembicTest(unittest.TestCase):
|
|||||||
converters = {
|
converters = {
|
||||||
'bool_t': int,
|
'bool_t': int,
|
||||||
'uint8_t': int,
|
'uint8_t': int,
|
||||||
|
'int16_t': int,
|
||||||
'int32_t': int,
|
'int32_t': int,
|
||||||
'float64_t': float,
|
'float64_t': float,
|
||||||
'float32_t': float,
|
'float32_t': float,
|
||||||
@@ -141,7 +142,13 @@ class AbstractAlembicTest(unittest.TestCase):
|
|||||||
info = lines.popleft()
|
info = lines.popleft()
|
||||||
if not info:
|
if not info:
|
||||||
continue
|
continue
|
||||||
proptype, valtype_and_arrsize, name_and_extent = info.split()
|
parts = info.split()
|
||||||
|
proptype = parts[0]
|
||||||
|
|
||||||
|
if proptype == 'CompoundProperty':
|
||||||
|
# To read those, call self.abcprop() on it.
|
||||||
|
continue
|
||||||
|
valtype_and_arrsize, name_and_extent = parts[1:]
|
||||||
|
|
||||||
# Parse name and extent
|
# Parse name and extent
|
||||||
m = self.abcls_array.match(name_and_extent)
|
m = self.abcls_array.match(name_and_extent)
|
||||||
@@ -291,6 +298,9 @@ class CurveExportTest(AbstractAlembicTest):
|
|||||||
abcprop = self.abcprop(abc, '/NurbsCurve/NurbsCurveShape/.geom')
|
abcprop = self.abcprop(abc, '/NurbsCurve/NurbsCurveShape/.geom')
|
||||||
self.assertEqual(abcprop['.orders'], [4])
|
self.assertEqual(abcprop['.orders'], [4])
|
||||||
|
|
||||||
|
abcprop = self.abcprop(abc, '/NurbsCurve/NurbsCurveShape/.geom/.userProperties')
|
||||||
|
self.assertEqual(abcprop['blender:resolution'], 10)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
Reference in New Issue
Block a user