Fix: Adaptive subdivision not updated when camera changes
Regression from ba5cf35d2a. Now that adaptive subdivision is not
excessively updated on all object changes, we need to specifically
check for this case.
Ref #141381
Pull Request: https://projects.blender.org/blender/blender/pulls/141886
This commit is contained in:
@@ -717,6 +717,28 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
|
||||
}
|
||||
}
|
||||
|
||||
BL::Object BlenderSync::get_dicing_camera_object(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d)
|
||||
{
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
BL::Object b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
|
||||
if (b_ob) {
|
||||
return b_ob;
|
||||
}
|
||||
|
||||
BL::Object b_camera_override = b_engine.camera_override();
|
||||
if (b_camera_override) {
|
||||
return b_camera_override;
|
||||
}
|
||||
|
||||
if (b_v3d && b_rv3d && b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA &&
|
||||
b_v3d.use_local_camera())
|
||||
{
|
||||
return b_v3d.camera();
|
||||
}
|
||||
|
||||
return b_scene.camera();
|
||||
}
|
||||
|
||||
void BlenderSync::sync_camera_motion(BL::RenderSettings &b_render,
|
||||
BL::Object &b_ob,
|
||||
const int width,
|
||||
|
||||
@@ -227,7 +227,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
||||
}
|
||||
else {
|
||||
/* Sync recalculations to do just the required updates. */
|
||||
sync->sync_recalc(b_depsgraph, b_v3d);
|
||||
sync->sync_recalc(b_depsgraph, b_v3d, b_rv3d);
|
||||
}
|
||||
|
||||
BL::Object b_camera_override(b_engine.camera_override());
|
||||
@@ -798,7 +798,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
|
||||
|
||||
/* copy recalc flags, outside of mutex so we can decide to do the real
|
||||
* synchronization at a later time to not block on running updates */
|
||||
sync->sync_recalc(b_depsgraph_, b_v3d);
|
||||
sync->sync_recalc(b_depsgraph_, b_v3d, b_rv3d);
|
||||
|
||||
/* don't do synchronization if on pause */
|
||||
if (session_pause) {
|
||||
|
||||
@@ -94,46 +94,14 @@ void BlenderSync::set_bake_target(BL::Object &b_object)
|
||||
|
||||
/* Sync */
|
||||
|
||||
void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d)
|
||||
void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph,
|
||||
BL::SpaceView3D &b_v3d,
|
||||
BL::RegionView3D &b_rv3d)
|
||||
{
|
||||
/* Sync recalc flags from blender to cycles. Actual update is done separate,
|
||||
* so we can do it later on if doing it immediate is not suitable. */
|
||||
|
||||
if (use_adaptive_subdivision) {
|
||||
/* Mark all meshes as needing to be exported again if dicing changed. */
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
bool dicing_prop_changed = false;
|
||||
|
||||
const float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
|
||||
RNA_float_get(&cscene, "dicing_rate");
|
||||
|
||||
if (dicing_rate != updated_dicing_rate) {
|
||||
dicing_rate = updated_dicing_rate;
|
||||
dicing_prop_changed = true;
|
||||
}
|
||||
|
||||
const int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
|
||||
|
||||
if (max_subdivisions != updated_max_subdivisions) {
|
||||
max_subdivisions = updated_max_subdivisions;
|
||||
dicing_prop_changed = true;
|
||||
}
|
||||
|
||||
if (dicing_prop_changed) {
|
||||
has_updates_ = true;
|
||||
|
||||
for (const pair<const GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) {
|
||||
Geometry *geom = iter.second;
|
||||
if (geom->is_mesh()) {
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) {
|
||||
const PointerRNA id_ptr = RNA_id_pointer_create((::ID *)iter.first.id);
|
||||
geometry_map.set_recalc(BL::ID(id_ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BL::Object b_dicing_camera_object = get_dicing_camera_object(b_v3d, b_rv3d);
|
||||
bool dicing_camera_updated = false;
|
||||
|
||||
/* Iterate over all IDs in this depsgraph. */
|
||||
for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
|
||||
@@ -223,6 +191,10 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
||||
else if (object_is_camera(b_ob)) {
|
||||
shader_map.set_recalc(b_ob);
|
||||
}
|
||||
|
||||
if (b_dicing_camera_object == b_ob) {
|
||||
dicing_camera_updated = true;
|
||||
}
|
||||
}
|
||||
/* Mesh */
|
||||
else if (b_id.is_a(&RNA_Mesh)) {
|
||||
@@ -246,6 +218,48 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
||||
const BL::Volume b_volume(b_id);
|
||||
geometry_map.set_recalc(b_volume);
|
||||
}
|
||||
/* Camera */
|
||||
else if (b_id.is_a(&RNA_Camera)) {
|
||||
if (b_dicing_camera_object && b_dicing_camera_object.data() == b_id) {
|
||||
dicing_camera_updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (use_adaptive_subdivision) {
|
||||
/* Mark all meshes as needing to be exported again if dicing changed. */
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
bool dicing_prop_changed = false;
|
||||
|
||||
const float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
|
||||
RNA_float_get(&cscene, "dicing_rate");
|
||||
|
||||
if (dicing_rate != updated_dicing_rate) {
|
||||
dicing_rate = updated_dicing_rate;
|
||||
dicing_prop_changed = true;
|
||||
}
|
||||
|
||||
const int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
|
||||
|
||||
if (max_subdivisions != updated_max_subdivisions) {
|
||||
max_subdivisions = updated_max_subdivisions;
|
||||
dicing_prop_changed = true;
|
||||
}
|
||||
|
||||
if (dicing_camera_updated || dicing_prop_changed) {
|
||||
has_updates_ = true;
|
||||
|
||||
for (const pair<const GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) {
|
||||
Geometry *geom = iter.second;
|
||||
if (geom->is_mesh()) {
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) {
|
||||
const PointerRNA id_ptr = RNA_id_pointer_create((::ID *)iter.first.id);
|
||||
geometry_map.set_recalc(BL::ID(id_ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b_v3d) {
|
||||
|
||||
@@ -52,7 +52,7 @@ class BlenderSync {
|
||||
void set_bake_target(BL::Object &b_object);
|
||||
|
||||
/* sync */
|
||||
void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
|
||||
void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d);
|
||||
void sync_data(BL::RenderSettings &b_render,
|
||||
BL::Depsgraph &b_depsgraph,
|
||||
BL::SpaceView3D &b_v3d,
|
||||
@@ -213,6 +213,7 @@ class BlenderSync {
|
||||
bool object_can_have_geometry(BL::Object &b_ob);
|
||||
bool object_is_light(BL::Object &b_ob);
|
||||
bool object_is_camera(BL::Object &b_ob);
|
||||
BL::Object get_dicing_camera_object(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d);
|
||||
|
||||
/* variables */
|
||||
BL::RenderEngine b_engine;
|
||||
|
||||
Reference in New Issue
Block a user