Merge branch 'master' into sculpt-dev
This commit is contained in:
commit
44fd07c1c8
|
@ -93,6 +93,7 @@ set(SRC_BVH_HEADERS
|
|||
bvh/bvh_local.h
|
||||
bvh/bvh_traversal.h
|
||||
bvh/bvh_types.h
|
||||
bvh/bvh_util.h
|
||||
bvh/bvh_volume.h
|
||||
bvh/bvh_volume_all.h
|
||||
bvh/bvh_embree.h
|
||||
|
|
|
@ -29,9 +29,10 @@
|
|||
# include "kernel/bvh/bvh_embree.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#include "kernel/bvh/bvh_types.h"
|
||||
#include "kernel/bvh/bvh_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#ifndef __KERNEL_OPTIX__
|
||||
|
||||
|
@ -533,97 +534,4 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
|
|||
}
|
||||
#endif /* __VOLUME_RECORD_ALL__ */
|
||||
|
||||
/* Ray offset to avoid self intersection.
|
||||
*
|
||||
* This function should be used to compute a modified ray start position for
|
||||
* rays leaving from a surface. */
|
||||
|
||||
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
|
||||
{
|
||||
#ifdef __INTERSECTION_REFINE__
|
||||
const float epsilon_f = 1e-5f;
|
||||
/* ideally this should match epsilon_f, but instancing and motion blur
|
||||
* precision makes it problematic */
|
||||
const float epsilon_test = 1.0f;
|
||||
const int epsilon_i = 32;
|
||||
|
||||
float3 res;
|
||||
|
||||
/* x component */
|
||||
if (fabsf(P.x) < epsilon_test) {
|
||||
res.x = P.x + Ng.x * epsilon_f;
|
||||
}
|
||||
else {
|
||||
uint ix = __float_as_uint(P.x);
|
||||
ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
|
||||
res.x = __uint_as_float(ix);
|
||||
}
|
||||
|
||||
/* y component */
|
||||
if (fabsf(P.y) < epsilon_test) {
|
||||
res.y = P.y + Ng.y * epsilon_f;
|
||||
}
|
||||
else {
|
||||
uint iy = __float_as_uint(P.y);
|
||||
iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
|
||||
res.y = __uint_as_float(iy);
|
||||
}
|
||||
|
||||
/* z component */
|
||||
if (fabsf(P.z) < epsilon_test) {
|
||||
res.z = P.z + Ng.z * epsilon_f;
|
||||
}
|
||||
else {
|
||||
uint iz = __float_as_uint(P.z);
|
||||
iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
|
||||
res.z = __uint_as_float(iz);
|
||||
}
|
||||
|
||||
return res;
|
||||
#else
|
||||
const float epsilon_f = 1e-4f;
|
||||
return P + epsilon_f * Ng;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
|
||||
/* ToDo: Move to another file? */
|
||||
ccl_device int intersections_compare(const void *a, const void *b)
|
||||
{
|
||||
const Intersection *isect_a = (const Intersection *)a;
|
||||
const Intersection *isect_b = (const Intersection *)b;
|
||||
|
||||
if (isect_a->t < isect_b->t)
|
||||
return -1;
|
||||
else if (isect_a->t > isect_b->t)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__SHADOW_RECORD_ALL__)
|
||||
ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
|
||||
{
|
||||
# ifdef __KERNEL_GPU__
|
||||
/* Use bubble sort which has more friendly memory pattern on GPU. */
|
||||
bool swapped;
|
||||
do {
|
||||
swapped = false;
|
||||
for (int j = 0; j < num_hits - 1; ++j) {
|
||||
if (hits[j].t > hits[j + 1].t) {
|
||||
struct Intersection tmp = hits[j];
|
||||
hits[j] = hits[j + 1];
|
||||
hits[j + 1] = tmp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
--num_hits;
|
||||
} while (swapped);
|
||||
# else
|
||||
qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
|
||||
# endif
|
||||
}
|
||||
#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -180,25 +180,10 @@ ccl_device_inline
|
|||
|
||||
/* todo: optimize so primitive visibility flag indicates if
|
||||
* the primitive has a transparent shadow shader? */
|
||||
int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
|
||||
int shader = 0;
|
||||
|
||||
#ifdef __HAIR__
|
||||
if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
|
||||
#endif
|
||||
{
|
||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else {
|
||||
float4 str = kernel_tex_fetch(__curves, prim);
|
||||
shader = __float_as_int(str.z);
|
||||
}
|
||||
#endif
|
||||
int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
|
||||
const int flags = intersection_get_shader_flags(kg, isect_array);
|
||||
|
||||
/* if no transparent shadows, all light is blocked */
|
||||
if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
|
||||
if (!(flags & SD_HAS_TRANSPARENT_SHADOW)) {
|
||||
return true;
|
||||
}
|
||||
/* if maximum number of hits reached, block all light */
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright 2011-2013 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Ray offset to avoid self intersection.
|
||||
*
|
||||
* This function should be used to compute a modified ray start position for
|
||||
* rays leaving from a surface. */
|
||||
|
||||
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
|
||||
{
|
||||
#ifdef __INTERSECTION_REFINE__
|
||||
const float epsilon_f = 1e-5f;
|
||||
/* ideally this should match epsilon_f, but instancing and motion blur
|
||||
* precision makes it problematic */
|
||||
const float epsilon_test = 1.0f;
|
||||
const int epsilon_i = 32;
|
||||
|
||||
float3 res;
|
||||
|
||||
/* x component */
|
||||
if (fabsf(P.x) < epsilon_test) {
|
||||
res.x = P.x + Ng.x * epsilon_f;
|
||||
}
|
||||
else {
|
||||
uint ix = __float_as_uint(P.x);
|
||||
ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
|
||||
res.x = __uint_as_float(ix);
|
||||
}
|
||||
|
||||
/* y component */
|
||||
if (fabsf(P.y) < epsilon_test) {
|
||||
res.y = P.y + Ng.y * epsilon_f;
|
||||
}
|
||||
else {
|
||||
uint iy = __float_as_uint(P.y);
|
||||
iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
|
||||
res.y = __uint_as_float(iy);
|
||||
}
|
||||
|
||||
/* z component */
|
||||
if (fabsf(P.z) < epsilon_test) {
|
||||
res.z = P.z + Ng.z * epsilon_f;
|
||||
}
|
||||
else {
|
||||
uint iz = __float_as_uint(P.z);
|
||||
iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
|
||||
res.z = __uint_as_float(iz);
|
||||
}
|
||||
|
||||
return res;
|
||||
#else
|
||||
const float epsilon_f = 1e-4f;
|
||||
return P + epsilon_f * Ng;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
|
||||
/* ToDo: Move to another file? */
|
||||
ccl_device int intersections_compare(const void *a, const void *b)
|
||||
{
|
||||
const Intersection *isect_a = (const Intersection *)a;
|
||||
const Intersection *isect_b = (const Intersection *)b;
|
||||
|
||||
if (isect_a->t < isect_b->t)
|
||||
return -1;
|
||||
else if (isect_a->t > isect_b->t)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__SHADOW_RECORD_ALL__)
|
||||
ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
|
||||
{
|
||||
kernel_assert(num_hits > 0);
|
||||
|
||||
# ifdef __KERNEL_GPU__
|
||||
/* Use bubble sort which has more friendly memory pattern on GPU. */
|
||||
bool swapped;
|
||||
do {
|
||||
swapped = false;
|
||||
for (int j = 0; j < num_hits - 1; ++j) {
|
||||
if (hits[j].t > hits[j + 1].t) {
|
||||
struct Intersection tmp = hits[j];
|
||||
hits[j] = hits[j + 1];
|
||||
hits[j + 1] = tmp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
--num_hits;
|
||||
} while (swapped);
|
||||
# else
|
||||
qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
|
||||
# endif
|
||||
}
|
||||
#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
|
||||
|
||||
/* Utility to quickly get a shader flags from an intersection. */
|
||||
|
||||
ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals *ccl_restrict kg,
|
||||
const Intersection *isect)
|
||||
{
|
||||
const int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
||||
int shader = 0;
|
||||
|
||||
#ifdef __HAIR__
|
||||
if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE)
|
||||
#endif
|
||||
{
|
||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else {
|
||||
float4 str = kernel_tex_fetch(__curves, prim);
|
||||
shader = __float_as_int(str.z);
|
||||
}
|
||||
#endif
|
||||
|
||||
return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
|
||||
}
|
||||
|
||||
ccl_device_forceinline int intersection_get_shader(KernelGlobals *ccl_restrict kg,
|
||||
const Intersection *isect)
|
||||
{
|
||||
const int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
||||
int shader = 0;
|
||||
|
||||
#ifdef __HAIR__
|
||||
if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE)
|
||||
#endif
|
||||
{
|
||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else {
|
||||
float4 str = kernel_tex_fetch(__curves, prim);
|
||||
shader = __float_as_int(str.z);
|
||||
}
|
||||
#endif
|
||||
|
||||
return shader & SHADER_MASK;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -65,7 +65,6 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg,
|
|||
uint visibility = path_state_ray_visibility(kg, state);
|
||||
|
||||
if (path_state_ao_bounce(kg, state)) {
|
||||
visibility = PATH_RAY_SHADOW;
|
||||
ray->t = kernel_data.background.ao_distance;
|
||||
}
|
||||
|
||||
|
@ -416,7 +415,13 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
|||
break;
|
||||
}
|
||||
else if (path_state_ao_bounce(kg, state)) {
|
||||
break;
|
||||
if (intersection_get_shader_flags(kg, &isect) &
|
||||
(SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) {
|
||||
state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup shader data. */
|
||||
|
@ -554,7 +559,13 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg,
|
|||
break;
|
||||
}
|
||||
else if (path_state_ao_bounce(kg, state)) {
|
||||
break;
|
||||
if (intersection_get_shader_flags(kg, &isect) &
|
||||
(SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) {
|
||||
state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup shader data. */
|
||||
|
|
|
@ -895,6 +895,8 @@ enum ShaderDataFlag {
|
|||
SD_HAS_CONSTANT_EMISSION = (1 << 27),
|
||||
/* Needs to access attributes for volume rendering */
|
||||
SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
|
||||
/* Shader has emission */
|
||||
SD_HAS_EMISSION = (1 << 29),
|
||||
|
||||
SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
|
||||
SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
|
||||
|
|
|
@ -528,6 +528,8 @@ void ShaderManager::device_update_common(Device *device,
|
|||
|
||||
if (shader->get_use_mis())
|
||||
flag |= SD_USE_MIS;
|
||||
if (shader->has_surface_emission)
|
||||
flag |= SD_HAS_EMISSION;
|
||||
if (shader->has_surface_transparent && shader->get_use_transparent_shadow())
|
||||
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
||||
if (shader->has_volume) {
|
||||
|
|
|
@ -152,6 +152,7 @@ void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, struct Main *bma
|
|||
void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain);
|
||||
|
||||
void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph);
|
||||
void BKE_scene_graph_update_for_newframe_ex(struct Depsgraph *depsgraph, const bool clear_recalc);
|
||||
|
||||
void BKE_scene_view_layer_graph_evaluated_ensure(struct Main *bmain,
|
||||
struct Scene *scene,
|
||||
|
|
|
@ -2636,6 +2636,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
|
|||
|
||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
|
||||
bool used_multiple_passes = false;
|
||||
|
||||
bool run_callbacks = DEG_id_type_any_updated(depsgraph);
|
||||
if (run_callbacks) {
|
||||
|
@ -2672,8 +2673,6 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
|
|||
* If there are no relations changed by the callback this call will do nothing. */
|
||||
DEG_graph_relations_update(depsgraph);
|
||||
}
|
||||
/* Inform editors about possible changes. */
|
||||
DEG_editors_update(bmain, depsgraph, scene, view_layer, false);
|
||||
|
||||
/* If user callback did not tag anything for update we can skip second iteration.
|
||||
* Otherwise we update scene once again, but without running callbacks to bring
|
||||
|
@ -2682,8 +2681,22 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
|
|||
break;
|
||||
}
|
||||
|
||||
/* Clear recalc flags for second pass, but back them up for editors update. */
|
||||
const bool backup = true;
|
||||
DEG_ids_clear_recalc(depsgraph, backup);
|
||||
used_multiple_passes = true;
|
||||
run_callbacks = false;
|
||||
}
|
||||
|
||||
/* Inform editors about changes, using recalc flags from both passes. */
|
||||
if (used_multiple_passes) {
|
||||
DEG_ids_restore_recalc(depsgraph);
|
||||
}
|
||||
const bool is_time_update = false;
|
||||
DEG_editors_update(depsgraph, is_time_update);
|
||||
|
||||
const bool backup = false;
|
||||
DEG_ids_clear_recalc(depsgraph, backup);
|
||||
}
|
||||
|
||||
void BKE_scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain)
|
||||
|
@ -2697,11 +2710,11 @@ void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
|
|||
}
|
||||
|
||||
/* applies changes right away, does all sets too */
|
||||
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
|
||||
void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool clear_recalc)
|
||||
{
|
||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
|
||||
Main *bmain = DEG_get_bmain(depsgraph);
|
||||
bool used_multiple_passes = false;
|
||||
|
||||
/* Keep this first. */
|
||||
BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE);
|
||||
|
@ -2738,16 +2751,38 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
|
|||
DEG_graph_relations_update(depsgraph);
|
||||
}
|
||||
|
||||
/* Inform editors about possible changes. */
|
||||
DEG_editors_update(bmain, depsgraph, scene, view_layer, true);
|
||||
|
||||
/* If user callback did not tag anything for update we can skip second iteration.
|
||||
* Otherwise we update scene once again, but without running callbacks to bring
|
||||
* scene to a fully evaluated state with user modifications taken into account. */
|
||||
if (DEG_is_fully_evaluated(depsgraph)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear recalc flags for second pass, but back them up for editors update. */
|
||||
const bool backup = true;
|
||||
DEG_ids_clear_recalc(depsgraph, backup);
|
||||
used_multiple_passes = true;
|
||||
}
|
||||
|
||||
/* Inform editors about changes, using recalc flags from both passes. */
|
||||
if (used_multiple_passes) {
|
||||
DEG_ids_restore_recalc(depsgraph);
|
||||
}
|
||||
|
||||
const bool is_time_update = true;
|
||||
DEG_editors_update(depsgraph, is_time_update);
|
||||
|
||||
/* Clear recalc flags, can be skipped for e.g. renderers that will read these
|
||||
* and clear the flags later. */
|
||||
if (clear_recalc) {
|
||||
const bool backup = false;
|
||||
DEG_ids_clear_recalc(depsgraph, backup);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
|
||||
{
|
||||
BKE_scene_graph_update_for_newframe_ex(depsgraph, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3507,8 +3542,8 @@ GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain)
|
|||
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
if (scene->depsgraph_hash == NULL) {
|
||||
/* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will be
|
||||
* built so this pointer may be NULL. */
|
||||
/* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will
|
||||
* be built so this pointer may be NULL. */
|
||||
continue;
|
||||
}
|
||||
for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
|
||||
|
|
|
@ -143,16 +143,15 @@ void DEG_id_type_tag(struct Main *bmain, short id_type);
|
|||
* for viewport depsgraphs, but not render or export depsgraph for example. */
|
||||
void DEG_enable_editors_update(struct Depsgraph *depsgraph);
|
||||
|
||||
/* Check if something was changed in the database and inform editors about this,
|
||||
* then clear recalc flags. */
|
||||
void DEG_editors_update(struct Main *bmain,
|
||||
struct Depsgraph *depsgraph,
|
||||
struct Scene *scene,
|
||||
struct ViewLayer *view_layer,
|
||||
bool time);
|
||||
/* Check if something was changed in the database and inform editors about this. */
|
||||
void DEG_editors_update(struct Depsgraph *depsgraph, bool time);
|
||||
|
||||
/* Clear recalc flags after editors or renderers have handled updates. */
|
||||
void DEG_ids_clear_recalc(Depsgraph *depsgraph);
|
||||
void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup);
|
||||
|
||||
/* Restore recalc flags, backed up by a previous call to DEG_ids_clear_recalc.
|
||||
* This also clears the backup. */
|
||||
void DEG_ids_restore_recalc(Depsgraph *depsgraph);
|
||||
|
||||
/* ************************************************ */
|
||||
/* Evaluation Engine API */
|
||||
|
|
|
@ -824,23 +824,24 @@ void DEG_enable_editors_update(Depsgraph *depsgraph)
|
|||
|
||||
/* Check if something was changed in the database and inform
|
||||
* editors about this. */
|
||||
void DEG_editors_update(
|
||||
Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, bool time)
|
||||
void DEG_editors_update(Depsgraph *depsgraph, bool time)
|
||||
{
|
||||
deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph;
|
||||
|
||||
if (graph->use_editors_update) {
|
||||
bool updated = time || DEG_id_type_any_updated(depsgraph);
|
||||
|
||||
DEGEditorUpdateContext update_ctx = {nullptr};
|
||||
update_ctx.bmain = bmain;
|
||||
update_ctx.depsgraph = depsgraph;
|
||||
update_ctx.scene = scene;
|
||||
update_ctx.view_layer = view_layer;
|
||||
deg::deg_editors_scene_update(&update_ctx, updated);
|
||||
if (!graph->use_editors_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEG_ids_clear_recalc(depsgraph);
|
||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
|
||||
Main *bmain = DEG_get_bmain(depsgraph);
|
||||
bool updated = time || DEG_id_type_any_updated(depsgraph);
|
||||
|
||||
DEGEditorUpdateContext update_ctx = {nullptr};
|
||||
update_ctx.bmain = bmain;
|
||||
update_ctx.depsgraph = depsgraph;
|
||||
update_ctx.scene = scene;
|
||||
update_ctx.view_layer = view_layer;
|
||||
deg::deg_editors_scene_update(&update_ctx, updated);
|
||||
}
|
||||
|
||||
static void deg_graph_clear_id_recalc_flags(ID *id)
|
||||
|
@ -854,7 +855,7 @@ static void deg_graph_clear_id_recalc_flags(ID *id)
|
|||
/* XXX And what about scene's master collection here? */
|
||||
}
|
||||
|
||||
void DEG_ids_clear_recalc(Depsgraph *depsgraph)
|
||||
void DEG_ids_clear_recalc(Depsgraph *depsgraph, const bool backup)
|
||||
{
|
||||
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
|
||||
/* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
|
||||
|
@ -864,6 +865,9 @@ void DEG_ids_clear_recalc(Depsgraph *depsgraph)
|
|||
}
|
||||
/* Go over all ID nodes nodes, clearing tags. */
|
||||
for (deg::IDNode *id_node : deg_graph->id_nodes) {
|
||||
if (backup) {
|
||||
id_node->id_cow_recalc_backup |= id_node->id_cow->recalc;
|
||||
}
|
||||
/* TODO: we clear original ID recalc flags here, but this may not work
|
||||
* correctly when there are multiple depsgraph with others still using
|
||||
* the recalc flag. */
|
||||
|
@ -875,3 +879,13 @@ void DEG_ids_clear_recalc(Depsgraph *depsgraph)
|
|||
}
|
||||
memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
|
||||
}
|
||||
|
||||
void DEG_ids_restore_recalc(Depsgraph *depsgraph)
|
||||
{
|
||||
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
|
||||
|
||||
for (deg::IDNode *id_node : deg_graph->id_nodes) {
|
||||
id_node->id_cow->recalc |= id_node->id_cow_recalc_backup;
|
||||
id_node->id_cow_recalc_backup = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata))
|
|||
is_collection_fully_expanded = false;
|
||||
has_base = false;
|
||||
is_user_modified = false;
|
||||
id_cow_recalc_backup = 0;
|
||||
|
||||
visible_components_mask = 0;
|
||||
previously_visible_components_mask = 0;
|
||||
|
|
|
@ -120,6 +120,9 @@ struct IDNode : public Node {
|
|||
/* Accumulated flag from operation. Is initialized and used during updates flush. */
|
||||
bool is_user_modified;
|
||||
|
||||
/* Accumulate recalc flags from multiple update passes. */
|
||||
int id_cow_recalc_backup;
|
||||
|
||||
IDComponentsMask visible_components_mask;
|
||||
IDComponentsMask previously_visible_components_mask;
|
||||
|
||||
|
|
|
@ -886,7 +886,8 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
|
|||
|
||||
if (treedata->tree == NULL) {
|
||||
/* Operators only update the editmesh looptris of the original mesh. */
|
||||
BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
|
||||
BLI_assert(sod->treedata_editmesh.em ==
|
||||
BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
|
||||
em = sod->treedata_editmesh.em;
|
||||
|
||||
if (sctx->callbacks.edit_mesh.test_face_fn) {
|
||||
|
@ -2276,7 +2277,7 @@ static short snapMesh(SnapObjectContext *sctx,
|
|||
if (me_eval->totvert == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (me_eval->totedge == 0 && !(snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
|
||||
if (me_eval->totedge == 0 && !(snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3115,8 +3116,15 @@ static short transform_snap_context_project_view3d_mixed_impl(
|
|||
new_clipplane[3] += 0.01f;
|
||||
|
||||
/* Try to snap only to the polygon. */
|
||||
elem_test = snap_mesh_polygon(
|
||||
sctx, &snapdata, ob_eval, obmat, params->use_backface_culling, &dist_px_tmp, loc, no, &index);
|
||||
elem_test = snap_mesh_polygon(sctx,
|
||||
&snapdata,
|
||||
ob_eval,
|
||||
obmat,
|
||||
params->use_backface_culling,
|
||||
&dist_px_tmp,
|
||||
loc,
|
||||
no,
|
||||
&index);
|
||||
if (elem_test) {
|
||||
elem = elem_test;
|
||||
}
|
||||
|
|
|
@ -690,7 +690,7 @@ static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer)
|
|||
}
|
||||
else {
|
||||
/* Go through update with full Python callbacks for regular render. */
|
||||
BKE_scene_graph_update_for_newframe(engine->depsgraph);
|
||||
BKE_scene_graph_update_for_newframe_ex(engine->depsgraph, false);
|
||||
}
|
||||
|
||||
engine->has_grease_pencil = DRW_render_check_grease_pencil(engine->depsgraph);
|
||||
|
@ -702,7 +702,7 @@ static void engine_depsgraph_exit(RenderEngine *engine)
|
|||
if (engine_keep_depsgraph(engine)) {
|
||||
/* Clear recalc flags since the engine should have handled the updates for the currently
|
||||
* rendered framed by now. */
|
||||
DEG_ids_clear_recalc(engine->depsgraph);
|
||||
DEG_ids_clear_recalc(engine->depsgraph, false);
|
||||
}
|
||||
else {
|
||||
/* Free immediately to save memory. */
|
||||
|
@ -718,14 +718,14 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
|
|||
}
|
||||
|
||||
/* Clear recalc flags before update so engine can detect what changed. */
|
||||
DEG_ids_clear_recalc(engine->depsgraph);
|
||||
DEG_ids_clear_recalc(engine->depsgraph, false);
|
||||
|
||||
Render *re = engine->re;
|
||||
double cfra = (double)frame + (double)subframe;
|
||||
|
||||
CLAMP(cfra, MINAFRAME, MAXFRAME);
|
||||
BKE_scene_frame_set(re->scene, cfra);
|
||||
BKE_scene_graph_update_for_newframe(engine->depsgraph);
|
||||
BKE_scene_graph_update_for_newframe_ex(engine->depsgraph, false);
|
||||
|
||||
BKE_scene_camera_switch_update(re->scene);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue