Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/alembic.cpp')
-rw-r--r--intern/cycles/render/alembic.cpp310
1 files changed, 188 insertions, 122 deletions
diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp
index 468ebf7140f..0841a3c09cd 100644
--- a/intern/cycles/render/alembic.cpp
+++ b/intern/cycles/render/alembic.cpp
@@ -402,16 +402,16 @@ static void add_uvs(AlembicProcedural *proc,
}
const ISampleSelector iss = ISampleSelector(time);
- const IV2fGeomParam::Sample sample = uvs.getExpandedValue(iss);
-
const IV2fGeomParam::Sample uvsample = uvs.getIndexedValue(iss);
if (!uvsample.valid()) {
continue;
}
- const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
- const array<int3> *triangles_loops = cached_data.triangles_loops.data_for_time_no_check(time);
+ const array<int3> *triangles =
+ cached_data.triangles.data_for_time_no_check(time).get_data_or_null();
+ const array<int3> *triangles_loops =
+ cached_data.triangles_loops.data_for_time_no_check(time).get_data_or_null();
if (!triangles || !triangles_loops) {
continue;
@@ -458,7 +458,8 @@ static void add_normals(const Int32ArraySamplePtr face_indices,
*normals.getTimeSampling());
attr.std = ATTR_STD_VERTEX_NORMAL;
- const array<float3> *vertices = cached_data.vertices.data_for_time_no_check(time);
+ const array<float3> *vertices =
+ cached_data.vertices.data_for_time_no_check(time).get_data_or_null();
if (!vertices) {
return;
@@ -493,7 +494,8 @@ static void add_normals(const Int32ArraySamplePtr face_indices,
*normals.getTimeSampling());
attr.std = ATTR_STD_VERTEX_NORMAL;
- const array<float3> *vertices = cached_data.vertices.data_for_time_no_check(time);
+ const array<float3> *vertices =
+ cached_data.vertices.data_for_time_no_check(time).get_data_or_null();
if (!vertices) {
return;
@@ -717,11 +719,15 @@ void AlembicObject::read_face_sets(SchemaType &schema,
void AlembicObject::load_all_data(AlembicProcedural *proc,
IPolyMeshSchema &schema,
- float scale,
Progress &progress)
{
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);
@@ -780,22 +786,18 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
add_uvs(proc, uvs, cached_data, progress);
}
- if (progress.get_cancel()) {
- return;
- }
-
- setup_transform_cache(scale);
-
data_loaded = true;
}
-void AlembicObject::load_all_data(AlembicProcedural *proc,
- ISubDSchema &schema,
- float scale,
- Progress &progress)
+void AlembicObject::load_all_data(AlembicProcedural *proc, ISubDSchema &schema, Progress &progress)
{
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();
@@ -920,19 +922,21 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
return;
}
- setup_transform_cache(scale);
-
data_loaded = true;
}
void AlembicObject::load_all_data(AlembicProcedural *proc,
const ICurvesSchema &schema,
- float scale,
Progress &progress,
float default_radius)
{
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);
@@ -1007,8 +1011,6 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
// TODO(@kevindietrich): attributes, need example files
- setup_transform_cache(scale);
-
data_loaded = true;
}
@@ -1017,6 +1019,10 @@ void AlembicObject::setup_transform_cache(float scale)
cached_data.transforms.clear();
cached_data.transforms.invalidate_last_loaded_time();
+ if (scale == 0.0f) {
+ scale = 1.0f;
+ }
+
if (xform_time_sampling) {
cached_data.transforms.set_time_sampling(*xform_time_sampling);
}
@@ -1107,9 +1113,10 @@ void AlembicObject::read_attribute(const ICompoundProperty &arb_geom_params,
attribute.element = ATTR_ELEMENT_CORNER;
attribute.type_desc = TypeFloat2;
- const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
- const array<int3> *triangles_loops = cached_data.triangles_loops.data_for_time_no_check(
- time);
+ const array<int3> *triangles =
+ cached_data.triangles.data_for_time_no_check(time).get_data_or_null();
+ const array<int3> *triangles_loops =
+ cached_data.triangles_loops.data_for_time_no_check(time).get_data_or_null();
if (!triangles || !triangles_loops) {
return;
@@ -1162,7 +1169,8 @@ void AlembicObject::read_attribute(const ICompoundProperty &arb_geom_params,
attribute.element = ATTR_ELEMENT_CORNER_BYTE;
attribute.type_desc = TypeRGBA;
- const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
+ const array<int3> *triangles =
+ cached_data.triangles.data_for_time_no_check(time).get_data_or_null();
if (!triangles) {
return;
@@ -1218,7 +1226,8 @@ void AlembicObject::read_attribute(const ICompoundProperty &arb_geom_params,
attribute.element = ATTR_ELEMENT_CORNER_BYTE;
attribute.type_desc = TypeRGBA;
- const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
+ const array<int3> *triangles =
+ cached_data.triangles.data_for_time_no_check(time).get_data_or_null();
if (!triangles) {
return;
@@ -1257,7 +1266,7 @@ static void update_attributes(AttributeSet &attributes, CachedData &cached_data,
set<Attribute *> cached_attributes;
for (CachedData::CachedAttribute &attribute : cached_data.attributes) {
- const array<char> *attr_data = attribute.data.data_for_time(frame_time);
+ const array<char> *attr_data = attribute.data.data_for_time(frame_time).get_data_or_null();
Attribute *attr = nullptr;
if (attribute.std != ATTR_STD_NONE) {
@@ -1282,6 +1291,7 @@ static void update_attributes(AttributeSet &attributes, CachedData &cached_data,
}
memcpy(attr->data(), attr_data->data(), attr_data->size());
+ attr->modified = true;
}
/* remove any attributes not in cached_attributes */
@@ -1289,6 +1299,7 @@ static void update_attributes(AttributeSet &attributes, CachedData &cached_data,
for (it = attributes.attributes.begin(); it != attributes.attributes.end();) {
if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
attributes.attributes.erase(it++);
+ attributes.modified = true;
continue;
}
@@ -1406,6 +1417,8 @@ void AlembicProcedural::generate(Scene *scene, Progress &progress)
const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate);
+ build_caches(progress);
+
foreach (Node *node, objects) {
AlembicObject *object = static_cast<AlembicObject *>(node);
@@ -1414,19 +1427,19 @@ void AlembicProcedural::generate(Scene *scene, Progress &progress)
}
/* skip constant objects */
- if (object->has_data_loaded() && object->is_constant() && !object->is_modified() &&
- !object->need_shader_update && !scale_is_modified()) {
+ if (object->is_constant() && !object->is_modified() && !object->need_shader_update &&
+ !scale_is_modified()) {
continue;
}
if (object->schema_type == AlembicObject::POLY_MESH) {
- read_mesh(object, frame_time, progress);
+ read_mesh(object, frame_time);
}
else if (object->schema_type == AlembicObject::CURVES) {
- read_curves(object, frame_time, progress);
+ read_curves(object, frame_time);
}
else if (object->schema_type == AlembicObject::SUBD) {
- read_subd(object, frame_time, progress);
+ read_subd(object, frame_time);
}
object->clear_modified();
@@ -1489,22 +1502,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);
@@ -1513,31 +1528,22 @@ void AlembicProcedural::load_objects(Progress &progress)
abc_object->set_object(object);
}
-}
-void AlembicProcedural::read_mesh(AlembicObject *abc_object,
- Abc::chrono_t frame_time,
- Progress &progress)
-{
- IPolyMesh polymesh(abc_object->iobject, Alembic::Abc::kWrapExisting);
-
- Mesh *mesh = static_cast<Mesh *>(abc_object->get_object()->get_geometry());
-
- CachedData &cached_data = abc_object->get_cached_data();
- IPolyMeshSchema schema = polymesh.getSchema();
-
- if (!abc_object->has_data_loaded()) {
- abc_object->load_all_data(this, schema, scale, progress);
- }
- else {
- if (abc_object->need_shader_update) {
- abc_object->update_shader_attributes(schema.getArbGeomParams(), progress);
- }
+ /* Share geometries between instances. */
+ foreach (Node *node, objects) {
+ AlembicObject *abc_object = static_cast<AlembicObject *>(node);
- if (scale_is_modified()) {
- abc_object->setup_transform_cache(scale);
+ 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)
+{
+ CachedData &cached_data = abc_object->get_cached_data();
/* update sockets */
@@ -1548,11 +1554,18 @@ void AlembicProcedural::read_mesh(AlembicObject *abc_object,
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());
cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket());
- array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time);
+ array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time).get_data_or_null();
if (triangle_data) {
array<int> triangles;
array<bool> smooth;
@@ -1590,41 +1603,31 @@ void AlembicProcedural::read_mesh(AlembicObject *abc_object,
}
}
-void AlembicProcedural::read_subd(AlembicObject *abc_object,
- Abc::chrono_t frame_time,
- Progress &progress)
+void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame_time)
{
- ISubD subd_mesh(abc_object->iobject, Alembic::Abc::kWrapExisting);
- ISubDSchema schema = subd_mesh.getSchema();
-
- Mesh *mesh = static_cast<Mesh *>(abc_object->get_object()->get_geometry());
-
- /* Alembic is OpenSubDiv compliant, there is no option to set another subdivision type. */
- mesh->set_subdivision_type(Mesh::SubdivisionType::SUBDIVISION_CATMULL_CLARK);
+ CachedData &cached_data = abc_object->get_cached_data();
- if (!abc_object->has_data_loaded()) {
- abc_object->load_all_data(this, schema, scale, progress);
+ if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
+ /* need to reset the current data is something changed */
+ cached_data.invalidate_last_loaded_time();
}
- else {
- if (abc_object->need_shader_update) {
- abc_object->update_shader_attributes(schema.getArbGeomParams(), progress);
- }
- if (scale_is_modified()) {
- abc_object->setup_transform_cache(scale);
- }
- }
+ /* Update sockets. */
- mesh->set_subd_max_level(abc_object->get_subd_max_level());
- mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
+ Object *object = abc_object->get_object();
+ cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket());
- CachedData &cached_data = abc_object->get_cached_data();
+ if (object->is_modified()) {
+ object->tag_update(scene_);
+ }
- if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
- /* need to reset the current data is something changed */
- cached_data.invalidate_last_loaded_time();
+ /* 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
* repass the data if something is animated (vertices most likely) to avoid buffer overflows. */
if (!cached_data.is_constant()) {
@@ -1637,14 +1640,10 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object,
mesh->clear_non_sockets();
- /* Update sockets. */
-
- Object *object = abc_object->get_object();
- cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket());
-
- if (object->is_modified()) {
- object->tag_update(scene_);
- }
+ /* Alembic is OpenSubDiv compliant, there is no option to set another subdivision type. */
+ mesh->set_subdivision_type(Mesh::SubdivisionType::SUBDIVISION_CATMULL_CLARK);
+ mesh->set_subd_max_level(abc_object->get_subd_max_level());
+ mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
@@ -1699,25 +1698,8 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object,
}
}
-void AlembicProcedural::read_curves(AlembicObject *abc_object,
- Abc::chrono_t frame_time,
- Progress &progress)
+void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t frame_time)
{
- ICurves curves(abc_object->iobject, Alembic::Abc::kWrapExisting);
- Hair *hair = static_cast<Hair *>(abc_object->get_object()->get_geometry());
-
- ICurvesSchema schema = curves.getSchema();
-
- if (!abc_object->has_data_loaded() || default_radius_is_modified() ||
- abc_object->radius_scale_is_modified()) {
- abc_object->load_all_data(this, schema, scale, progress, default_radius);
- }
- else {
- if (scale_is_modified()) {
- abc_object->setup_transform_cache(scale);
- }
- }
-
CachedData &cached_data = abc_object->get_cached_data();
/* update sockets */
@@ -1729,6 +1711,13 @@ void AlembicProcedural::read_curves(AlembicObject *abc_object,
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());
cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
@@ -1867,9 +1856,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()) {
@@ -1880,6 +1898,54 @@ void AlembicProcedural::walk_hierarchy(
}
}
+void AlembicProcedural::build_caches(Progress &progress)
+{
+ for (Node *node : objects) {
+ AlembicObject *object = static_cast<AlembicObject *>(node);
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ if (object->schema_type == AlembicObject::POLY_MESH) {
+ if (!object->has_data_loaded()) {
+ IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
+ IPolyMeshSchema schema = polymesh.getSchema();
+ object->load_all_data(this, schema, progress);
+ }
+ else if (object->need_shader_update) {
+ IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
+ IPolyMeshSchema schema = polymesh.getSchema();
+ object->update_shader_attributes(schema.getArbGeomParams(), progress);
+ }
+ }
+ else if (object->schema_type == AlembicObject::CURVES) {
+ if (!object->has_data_loaded() || default_radius_is_modified() ||
+ object->radius_scale_is_modified()) {
+ ICurves curves(object->iobject, Alembic::Abc::kWrapExisting);
+ ICurvesSchema schema = curves.getSchema();
+ object->load_all_data(this, schema, progress, default_radius);
+ }
+ }
+ else if (object->schema_type == AlembicObject::SUBD) {
+ if (!object->has_data_loaded()) {
+ ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
+ ISubDSchema schema = subd_mesh.getSchema();
+ object->load_all_data(this, schema, progress);
+ }
+ else if (object->need_shader_update) {
+ ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
+ ISubDSchema schema = subd_mesh.getSchema();
+ object->update_shader_attributes(schema.getArbGeomParams(), progress);
+ }
+ }
+
+ if (scale_is_modified() || object->get_cached_data().transforms.size() == 0) {
+ object->setup_transform_cache(scale);
+ }
+ }
+}
+
CCL_NAMESPACE_END
#endif