diff options
-rw-r--r-- | intern/cycles/render/alembic.cpp | 102 | ||||
-rw-r--r-- | intern/cycles/render/alembic.h | 2 |
2 files changed, 89 insertions, 15 deletions
diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp index de51e6fe0ac..59454eac8a5 100644 --- a/intern/cycles/render/alembic.cpp +++ b/intern/cycles/render/alembic.cpp @@ -719,6 +719,11 @@ void AlembicObject::load_all_data(AlembicProcedural *proc, { cached_data.clear(); + /* Only load data for the original Geometry. */ + if (instance_of) { + return; + } + const TimeSamplingPtr time_sampling = schema.getTimeSampling(); cached_data.set_time_sampling(*time_sampling); @@ -784,6 +789,11 @@ void AlembicObject::load_all_data(AlembicProcedural *proc, ISubDSchema &schema, { cached_data.clear(); + /* Only load data for the original Geometry. */ + if (instance_of) { + return; + } + AttributeRequestSet requested_attributes = get_requested_attributes(); const TimeSamplingPtr time_sampling = schema.getTimeSampling(); @@ -918,6 +928,11 @@ void AlembicObject::load_all_data(AlembicProcedural *proc, { cached_data.clear(); + /* Only load data for the original Geometry. */ + if (instance_of) { + return; + } + const TimeSamplingPtr time_sampling = schema.getTimeSampling(); cached_data.set_time_sampling(*time_sampling); @@ -1480,22 +1495,24 @@ void AlembicProcedural::load_objects(Progress &progress) Geometry *geometry = nullptr; - if (abc_object->schema_type == AlembicObject::CURVES) { - geometry = scene_->create_node<Hair>(); - } - else if (abc_object->schema_type == AlembicObject::POLY_MESH || - abc_object->schema_type == AlembicObject::SUBD) { - geometry = scene_->create_node<Mesh>(); - } - else { - continue; - } + if (!abc_object->instance_of) { + if (abc_object->schema_type == AlembicObject::CURVES) { + geometry = scene_->create_node<Hair>(); + } + else if (abc_object->schema_type == AlembicObject::POLY_MESH || + abc_object->schema_type == AlembicObject::SUBD) { + geometry = scene_->create_node<Mesh>(); + } + else { + continue; + } - geometry->set_owner(this); - geometry->name = abc_object->iobject.getName(); + geometry->set_owner(this); + geometry->name = abc_object->iobject.getName(); - array<Node *> used_shaders = abc_object->get_used_shaders(); - geometry->set_used_shaders(used_shaders); + array<Node *> used_shaders = abc_object->get_used_shaders(); + geometry->set_used_shaders(used_shaders); + } Object *object = scene_->create_node<Object>(); object->set_owner(this); @@ -1504,6 +1521,17 @@ void AlembicProcedural::load_objects(Progress &progress) abc_object->set_object(object); } + + /* Share geometries between instances. */ + foreach (Node *node, objects) { + AlembicObject *abc_object = static_cast<AlembicObject *>(node); + + if (abc_object->instance_of) { + abc_object->get_object()->set_geometry( + abc_object->instance_of->get_object()->get_geometry()); + abc_object->schema_type = abc_object->instance_of->schema_type; + } + } } void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame_time) @@ -1519,6 +1547,11 @@ void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame object->tag_update(scene_); } + /* Only update sockets for the original Geometry. */ + if (abc_object->instance_of) { + return; + } + Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket()); @@ -1581,6 +1614,11 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame object->tag_update(scene_); } + /* Only update sockets for the original Geometry. */ + if (abc_object->instance_of) { + return; + } + Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); /* Cycles overwrites the original triangles when computing displacement, so we always have to @@ -1666,6 +1704,11 @@ void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t fra object->tag_update(scene_); } + /* Only update sockets for the original Geometry. */ + if (abc_object->instance_of) { + return; + } + Hair *hair = static_cast<Hair *>(object->get_geometry()); cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket()); @@ -1806,9 +1849,38 @@ void AlembicProcedural::walk_hierarchy( else if (IFaceSet::matches(header)) { // ignore the face set, it will be read along with the data } + else if (IPoints::matches(header)) { + // unsupported for now + } + else if (INuPatch::matches(header)) { + // unsupported for now + } else { - // unsupported type for now (Points, NuPatch) next_object = parent.getChild(header.getName()); + + if (next_object.isInstanceRoot()) { + unordered_map<std::string, AlembicObject *>::const_iterator iter; + + /* Was this object asked to be rendered? */ + iter = object_map.find(next_object.getFullName()); + + if (iter != object_map.end()) { + AlembicObject *abc_object = iter->second; + + /* Only try to render an instance if the original object is also rendered. */ + iter = object_map.find(next_object.instanceSourcePath()); + + if (iter != object_map.end()) { + abc_object->iobject = next_object; + abc_object->instance_of = iter->second; + + if (matrix_samples_data.samples) { + abc_object->xform_samples = *matrix_samples_data.samples; + abc_object->xform_time_sampling = matrix_samples_data.time_sampling; + } + } + } + } } if (next_object.valid()) { diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h index a84e97f551b..6552336e6ab 100644 --- a/intern/cycles/render/alembic.h +++ b/intern/cycles/render/alembic.h @@ -276,6 +276,8 @@ class AlembicObject : public Node { bool need_shader_update = true; + AlembicObject *instance_of = nullptr; + Alembic::AbcCoreAbstract::TimeSamplingPtr xform_time_sampling; MatrixSampleMap xform_samples; Alembic::AbcGeom::IObject iobject; |