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
path: root/intern
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2021-08-20 03:30:50 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2021-08-20 03:40:37 +0300
commitf8637cd8af451661a306edd5682cc17029e7e7e5 (patch)
tree4db9a5a8e1cf1b0ef9b5806af3a79bb6927c440e /intern
parent5b51df0f3301ac829e22e2efcc4c81437668bb58 (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')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp4
-rw-r--r--intern/cycles/blender/blender_object.cpp11
-rw-r--r--intern/cycles/blender/blender_sync.h4
-rw-r--r--intern/cycles/blender/blender_util.h12
-rw-r--r--intern/cycles/render/alembic.cpp57
-rw-r--r--intern/cycles/render/alembic.h9
6 files changed, 85 insertions, 12 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index d1042277183..ebba6981502 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -1078,7 +1078,7 @@ static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *me
return;
}
- BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob, true);
+ BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob, true, nullptr);
if (!b_mesh_cache) {
return;
@@ -1241,7 +1241,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
}
/* Cached motion blur already exported. */
- BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob, true);
+ BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob, true, nullptr);
if (mesh_cache) {
return;
}
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 657ecdeeeb7..2dbebac4cc3 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -485,7 +485,9 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
/* Object Loop */
-void BlenderSync::sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifier &b_mesh_cache)
+void BlenderSync::sync_procedural(BL::Object &b_ob,
+ BL::MeshSequenceCacheModifier &b_mesh_cache,
+ bool has_subdivision_modifier)
{
#ifdef WITH_ALEMBIC
BL::CacheFile cache_file = b_mesh_cache.cache_file();
@@ -534,6 +536,8 @@ void BlenderSync::sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifie
abc_object->set_subd_dicing_rate(subd_dicing_rate);
abc_object->set_subd_max_level(max_subdivisions);
+ abc_object->set_ignore_subdivision(!has_subdivision_modifier);
+
if (abc_object->is_modified() || procedural->is_modified()) {
procedural->tag_update(scene);
}
@@ -601,13 +605,14 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
if (b_instance.show_self()) {
#ifdef WITH_ALEMBIC
bool use_procedural = false;
+ bool has_subdivision_modifier = false;
BL::MeshSequenceCacheModifier b_mesh_cache(PointerRNA_NULL);
/* Experimental as Blender does not have good support for procedurals at the moment, also
* only available in preview renders since currently do not have a good cache policy, the
* data being loaded at once for all the frames. */
if (experimental && b_v3d) {
- b_mesh_cache = object_mesh_cache_find(b_ob, false);
+ b_mesh_cache = object_mesh_cache_find(b_ob, false, &has_subdivision_modifier);
use_procedural = b_mesh_cache && b_mesh_cache.cache_file().use_render_procedural();
}
@@ -615,7 +620,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
/* Skip in the motion case, as generating motion blur data will be handled in the
* procedural. */
if (!motion) {
- sync_procedural(b_ob, b_mesh_cache);
+ sync_procedural(b_ob, b_mesh_cache, has_subdivision_modifier);
}
}
else
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 0e605fcbf16..44322dda6b9 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -151,7 +151,9 @@ class BlenderSync {
TaskPool *geom_task_pool);
void sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object);
- void sync_procedural(BL::Object &b_ob, BL::MeshSequenceCacheModifier &b_mesh_cache);
+ void sync_procedural(BL::Object &b_ob,
+ BL::MeshSequenceCacheModifier &b_mesh_cache,
+ bool has_subdivision);
bool sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object);
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index e50b1a4760e..3cf75b338dc 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -573,7 +573,8 @@ static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b
}
static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob,
- bool check_velocity)
+ bool check_velocity,
+ bool *has_subdivision_modifier)
{
for (int i = b_ob.modifiers.length() - 1; i >= 0; --i) {
BL::Modifier b_mod = b_ob.modifiers[i];
@@ -595,6 +596,15 @@ static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b
continue;
}
+ /* Only skip the subsurf modifier if we are not checking for the mesh sequence cache modifier
+ * for motion blur. */
+ if (b_mod.type() == BL::Modifier::type_SUBSURF && !check_velocity) {
+ if (has_subdivision_modifier) {
+ *has_subdivision_modifier = true;
+ }
+ continue;
+ }
+
break;
}
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;