diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-08-20 03:30:50 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-08-20 03:40:37 +0300 |
commit | f8637cd8af451661a306edd5682cc17029e7e7e5 (patch) | |
tree | 4db9a5a8e1cf1b0ef9b5806af3a79bb6927c440e /intern/cycles/render | |
parent | 5b51df0f3301ac829e22e2efcc4c81437668bb58 (diff) |
Alembic Procedural: only subdivide if subsurf modifier is present
As subdivision objects are first class citizens in Alembic, to
differentiate them with non-subdivided polygon meshes, the Alembic
Procedural automatically sets up subdivision properties on the generated
Cycles Mesh.
However, for real-time playback subdivision is far too slow, so this
modifies the detection of a MeshSeqCache modifier used to activate the
procedural to allow for a Subsurf modifier right after the cache one. If
present, the procedural will tag the object for subdivision, if absent, the
object will be treated as a regular mesh.
This is a temporary measure for until subdivision surface settings are part
of the Mesh datablock (see T68891).
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D11162
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/alembic.cpp | 57 | ||||
-rw-r--r-- | intern/cycles/render/alembic.h | 9 |
2 files changed, 61 insertions, 5 deletions
diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp index c1817016955..81f47256739 100644 --- a/intern/cycles/render/alembic.cpp +++ b/intern/cycles/render/alembic.cpp @@ -385,6 +385,8 @@ NODE_DEFINE(AlembicObject) SOCKET_STRING(path, "Alembic Path", ustring()); SOCKET_NODE_ARRAY(used_shaders, "Used Shaders", Shader::get_node_type()); + SOCKET_BOOLEAN(ignore_subdivision, "Ignore Subdivision", true); + SOCKET_INT(subd_max_level, "Max Subdivision Level", 1); SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 1.0f); @@ -470,6 +472,33 @@ void AlembicObject::load_data_in_cache(CachedData &cached_data, cached_data.clear(); + if (this->get_ignore_subdivision()) { + PolyMeshSchemaData data; + data.topology_variance = schema.getTopologyVariance(); + data.time_sampling = schema.getTimeSampling(); + data.positions = schema.getPositionsProperty(); + data.face_counts = schema.getFaceCountsProperty(); + data.face_indices = schema.getFaceIndicesProperty(); + data.num_samples = schema.getNumSamples(); + data.velocities = schema.getVelocitiesProperty(); + data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders()); + + read_geometry_data(proc, cached_data, data, progress); + + if (progress.get_cancel()) { + return; + } + + /* Use the schema as the base compound property to also be able to look for top level + * properties. */ + read_attributes( + proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress); + + cached_data.invalidate_last_loaded_time(true); + data_loaded = true; + return; + } + SubDSchemaData data; data.time_sampling = schema.getTimeSampling(); data.num_samples = schema.getNumSamples(); @@ -781,6 +810,19 @@ void AlembicProcedural::generate(Scene *scene, Progress &progress) const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate); + /* Clear the subdivision caches as the data is stored differently. */ + for (Node *node : objects) { + AlembicObject *object = static_cast<AlembicObject *>(node); + + if (object->schema_type != AlembicObject::SUBD) { + continue; + } + + if (object->ignore_subdivision_is_modified()) { + object->clear_cache(); + } + } + build_caches(progress); foreach (Node *node, objects) { @@ -967,13 +1009,13 @@ void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame_time) { - CachedData &cached_data = abc_object->get_cached_data(); - - 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(); + if (abc_object->get_ignore_subdivision()) { + read_mesh(abc_object, frame_time); + return; } + CachedData &cached_data = abc_object->get_cached_data(); + /* Update sockets. */ Object *object = abc_object->get_object(); @@ -988,6 +1030,11 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame return; } + 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(); + } + Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); /* Make sure shader ids are also updated. */ diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h index 61c0e40fe4a..9c58af720f6 100644 --- a/intern/cycles/render/alembic.h +++ b/intern/cycles/render/alembic.h @@ -353,6 +353,10 @@ class AlembicObject : public Node { /* Shaders used for rendering. */ NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders) + /* Treat this subdivision object as a regular polygon mesh, so no subdivision will be performed. + */ + NODE_SOCKET_API(bool, ignore_subdivision) + /* Maximum number of subdivisions for ISubD objects. */ NODE_SOCKET_API(int, subd_max_level) @@ -416,6 +420,11 @@ class AlembicObject : public Node { return cached_data_.is_constant(); } + void clear_cache() + { + cached_data_.clear(); + } + Object *object = nullptr; bool data_loaded = false; |