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 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh12
-rw-r--r--source/blender/blenkernel/BKE_subdiv_eval.h11
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc4
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c4
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/blenkernel/intern/node_tree_update.cc31
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c54
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c39
-rw-r--r--source/blender/blenlib/BLI_math_base.hh12
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc19
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc11
-rw-r--r--source/blender/editors/space_clip/clip_draw.c62
-rw-r--r--source/blender/makesdna/DNA_node_types.h13
13 files changed, 223 insertions, 50 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index 4482e13e1cf..3d194ba77dc 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -56,7 +56,7 @@ template<typename T> T mix3(const float3 &weights, const T &v0, const T &v1, con
template<>
inline int8_t mix3(const float3 &weights, const int8_t &v0, const int8_t &v1, const int8_t &v2)
{
- return static_cast<int8_t>(weights.x * v0 + weights.y * v1 + weights.z * v2);
+ return static_cast<int8_t>(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
}
template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v1, const bool &v2)
@@ -66,7 +66,7 @@ template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v
template<> inline int mix3(const float3 &weights, const int &v0, const int &v1, const int &v2)
{
- return static_cast<int>(weights.x * v0 + weights.y * v1 + weights.z * v2);
+ return static_cast<int>(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
}
template<>
@@ -131,12 +131,12 @@ template<> inline bool mix2(const float factor, const bool &a, const bool &b)
template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
{
- return static_cast<int8_t>((1.0f - factor) * a + factor * b);
+ return static_cast<int8_t>(std::round((1.0f - factor) * a + factor * b));
}
template<> inline int mix2(const float factor, const int &a, const int &b)
{
- return static_cast<int>((1.0f - factor) * a + factor * b);
+ return static_cast<int>(std::round((1.0f - factor) * a + factor * b));
}
template<> inline float mix2(const float factor, const float &a, const float &b)
@@ -356,7 +356,7 @@ template<> struct DefaultMixerStruct<ColorGeometry4b> {
template<> struct DefaultMixerStruct<int> {
static int double_to_int(const double &value)
{
- return static_cast<int>(value);
+ return static_cast<int>(std::round(value));
}
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
* uses double instead of float so that it is accurate for all 32 bit integers. */
@@ -375,7 +375,7 @@ template<> struct DefaultMixerStruct<bool> {
template<> struct DefaultMixerStruct<int8_t> {
static int8_t float_to_int8_t(const float &value)
{
- return static_cast<int8_t>(value);
+ return static_cast<int8_t>(std::round(value));
}
/* Store interpolated 8 bit integers in a float temporarily to increase accuracy. */
using type = SimpleMixerWithAccumulationType<int8_t, float, float_to_int8_t>;
diff --git a/source/blender/blenkernel/BKE_subdiv_eval.h b/source/blender/blenkernel/BKE_subdiv_eval.h
index a33140b721d..7673f18317a 100644
--- a/source/blender/blenkernel/BKE_subdiv_eval.h
+++ b/source/blender/blenkernel/BKE_subdiv_eval.h
@@ -15,6 +15,7 @@ extern "C" {
struct Mesh;
struct OpenSubdiv_EvaluatorCache;
+struct OpenSubdiv_EvaluatorSettings;
struct Subdiv;
typedef enum eSubdivEvaluatorType {
@@ -25,7 +26,8 @@ typedef enum eSubdivEvaluatorType {
/* Returns true if evaluator is ready for use. */
bool BKE_subdiv_eval_begin(struct Subdiv *subdiv,
eSubdivEvaluatorType evaluator_type,
- struct OpenSubdiv_EvaluatorCache *evaluator_cache);
+ struct OpenSubdiv_EvaluatorCache *evaluator_cache,
+ const struct OpenSubdiv_EvaluatorSettings *settings);
/* coarse_vertex_cos is an optional argument which allows to override coordinates of the coarse
* mesh. */
@@ -60,6 +62,13 @@ void BKE_subdiv_eval_limit_point_and_derivatives(struct Subdiv *subdiv,
void BKE_subdiv_eval_limit_point_and_normal(
struct Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3], float r_N[3]);
+/* Evaluate smoothly interpolated vertex data (such as orco). */
+void BKE_subdiv_eval_vertex_data(struct Subdiv *subdiv,
+ const int ptex_face_index,
+ const float u,
+ const float v,
+ float r_vertex_data[]);
+
/* Evaluate face-varying layer (such as UV). */
void BKE_subdiv_eval_face_varying(struct Subdiv *subdiv,
int face_varying_channel,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index fb44fc46531..5cf0ca6e062 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -1165,6 +1165,10 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
BKE_id_free(nullptr, mesh_orco_cloth);
}
+ /* Remove temporary data layer only needed for modifier evaluation.
+ * Save some memory, and ensure GPU subdivision does not need to deal with this. */
+ CustomData_free_layers(&mesh_final->vdata, CD_CLOTH_ORCO, mesh_final->totvert);
+
/* Compute normals. */
if (is_own_mesh) {
mesh_calc_modifier_final_normals(mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index b76e2b3aec6..8246de12ebf 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -1073,7 +1073,9 @@ static void reshape_subdiv_create(MultiresReshapeSmoothContext *reshape_smooth_c
converter_init(reshape_smooth_context, &converter);
Subdiv *reshape_subdiv = BKE_subdiv_new_from_converter(settings, &converter);
- BKE_subdiv_eval_begin(reshape_subdiv, SUBDIV_EVALUATOR_TYPE_CPU, NULL);
+
+ OpenSubdiv_EvaluatorSettings evaluator_settings = {0};
+ BKE_subdiv_eval_begin(reshape_subdiv, SUBDIV_EVALUATOR_TYPE_CPU, NULL, &evaluator_settings);
reshape_smooth_context->reshape_subdiv = reshape_subdiv;
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 49a8406d92d..cf3b4f7bdf2 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -670,6 +670,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
ntree->progress = nullptr;
ntree->execdata = nullptr;
+ ntree->runtime_flag = 0;
ntree->field_inferencing_interface = nullptr;
BKE_ntree_update_tag_missing_runtime_data(ntree);
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index baf3a0c8d22..8afe7ce7520 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -12,6 +12,7 @@
#include "DNA_node_types.h"
#include "BKE_anim_data.h"
+#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_node_tree_update.h"
@@ -984,6 +985,7 @@ class NodeTreeMainUpdater {
this->remove_unused_previews_when_necessary(ntree);
this->ensure_tree_ref(ntree, tree_ref);
+ this->update_has_image_animation(*tree_ref);
if (ntree.type == NTREE_GEOMETRY) {
if (node_field_inferencing::update_field_inferencing(*tree_ref)) {
result.interface_changed = true;
@@ -1254,6 +1256,35 @@ class NodeTreeMainUpdater {
BKE_node_preview_remove_unused(&ntree);
}
+ void update_has_image_animation(const NodeTreeRef &tree_ref)
+ {
+ bNodeTree &ntree = *tree_ref.btree();
+ ntree.runtime_flag &= ~NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION;
+ if (ntree.type != NTREE_SHADER) {
+ return;
+ }
+
+ /* Check if a used node group has an animated image. */
+ for (const NodeRef *group_node : tree_ref.nodes_by_type("NodeGroup")) {
+ const bNodeTree *group = reinterpret_cast<bNodeTree *>(group_node->bnode()->id);
+ if (group != nullptr) {
+ if (group->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) {
+ ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION;
+ return;
+ }
+ }
+ }
+ /* Check if the tree itself has an animated image. */
+ for (const StringRefNull idname : {"ShaderNodeTexImage", "ShaderNodeTexEnvironment"})
+ for (const NodeRef *node : tree_ref.nodes_by_type(idname)) {
+ Image *image = reinterpret_cast<Image *>(node->bnode()->id);
+ if (image != nullptr && BKE_image_is_animated(image)) {
+ ntree.runtime_flag |= NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION;
+ return;
+ }
+ }
+ }
+
void update_node_levels(bNodeTree &ntree)
{
ntreeUpdateNodeLevels(&ntree);
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 37978d5c2cc..562bf2e7d61 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -48,7 +48,8 @@ static eOpenSubdivEvaluator opensubdiv_evalutor_from_subdiv_evaluator_type(
bool BKE_subdiv_eval_begin(Subdiv *subdiv,
eSubdivEvaluatorType evaluator_type,
- OpenSubdiv_EvaluatorCache *evaluator_cache)
+ OpenSubdiv_EvaluatorCache *evaluator_cache,
+ const OpenSubdiv_EvaluatorSettings *settings)
{
BKE_subdiv_stats_reset(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
if (subdiv->topology_refiner == NULL) {
@@ -61,7 +62,7 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv,
opensubdiv_evalutor_from_subdiv_evaluator_type(evaluator_type);
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(
- subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache);
+ subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache, settings);
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
if (subdiv->evaluator == NULL) {
return false;
@@ -183,13 +184,52 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv,
MEM_freeN(buffer);
}
+static void set_vertex_data_from_orco(Subdiv *subdiv, const Mesh *mesh)
+{
+ const float(*orco)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO);
+ const float(*cloth_orco)[3] = CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO);
+
+ if (orco || cloth_orco) {
+ OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
+ OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
+ const int num_verts = topology_refiner->getNumVertices(topology_refiner);
+
+ if (orco && cloth_orco) {
+ /* Set one by one if have both. */
+ for (int i = 0; i < num_verts; i++) {
+ float data[6];
+ copy_v3_v3(data, orco[i]);
+ copy_v3_v3(data + 3, cloth_orco[i]);
+ evaluator->setVertexData(evaluator, data, i, 1);
+ }
+ }
+ else {
+ /* Faster single call if we have either. */
+ if (orco) {
+ evaluator->setVertexData(evaluator, orco[0], 0, num_verts);
+ }
+ else if (cloth_orco) {
+ evaluator->setVertexData(evaluator, cloth_orco[0], 0, num_verts);
+ }
+ }
+ }
+}
+
+static void get_mesh_evaluator_settings(OpenSubdiv_EvaluatorSettings *settings, const Mesh *mesh)
+{
+ settings->num_vertex_data = (CustomData_has_layer(&mesh->vdata, CD_ORCO) ? 3 : 0) +
+ (CustomData_has_layer(&mesh->vdata, CD_CLOTH_ORCO) ? 3 : 0);
+}
+
bool BKE_subdiv_eval_begin_from_mesh(Subdiv *subdiv,
const Mesh *mesh,
const float (*coarse_vertex_cos)[3],
eSubdivEvaluatorType evaluator_type,
OpenSubdiv_EvaluatorCache *evaluator_cache)
{
- if (!BKE_subdiv_eval_begin(subdiv, evaluator_type, evaluator_cache)) {
+ OpenSubdiv_EvaluatorSettings settings = {0};
+ get_mesh_evaluator_settings(&settings, mesh);
+ if (!BKE_subdiv_eval_begin(subdiv, evaluator_type, evaluator_cache, &settings)) {
return false;
}
return BKE_subdiv_eval_refine_from_mesh(subdiv, mesh, coarse_vertex_cos);
@@ -212,6 +252,8 @@ bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv,
const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index);
set_face_varying_data_from_uv(subdiv, mesh, mloopuv, layer_index);
}
+ /* Set vertex data to orco. */
+ set_vertex_data_from_orco(subdiv, mesh);
/* Update evaluator to the new coarse geometry. */
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
subdiv->evaluator->refine(subdiv->evaluator);
@@ -287,6 +329,12 @@ void BKE_subdiv_eval_limit_point_and_normal(Subdiv *subdiv,
normalize_v3(r_N);
}
+void BKE_subdiv_eval_vertex_data(
+ Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_vertex_data[])
+{
+ subdiv->evaluator->evaluateVertexData(subdiv->evaluator, ptex_face_index, u, v, r_vertex_data);
+}
+
void BKE_subdiv_eval_face_varying(Subdiv *subdiv,
const int face_varying_channel,
const int ptex_face_index,
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 83427adcb43..e846dc2d807 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -44,6 +44,9 @@ typedef struct SubdivMeshContext {
/* UV layers interpolation. */
int num_uv_layers;
MLoopUV *uv_layers[MAX_MTFACE];
+ /* Orco interpolation. */
+ float (*orco)[3];
+ float (*cloth_orco)[3];
/* Per-subdivided vertex counter of averaged values. */
int *accumulated_counters;
bool have_displacement;
@@ -69,6 +72,9 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
ctx->poly_origindex = CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX);
/* UV layers interpolation. */
subdiv_mesh_ctx_cache_uv_layers(ctx);
+ /* Orco interpolation. */
+ ctx->orco = CustomData_get_layer(&subdiv_mesh->vdata, CD_ORCO);
+ ctx->cloth_orco = CustomData_get_layer(&subdiv_mesh->vdata, CD_CLOTH_ORCO);
}
static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)
@@ -417,6 +423,34 @@ static void subdiv_mesh_tls_free(void *tls_v)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Evaluation helper functions
+ * \{ */
+
+static void subdiv_vertex_orco_evaluate(const SubdivMeshContext *ctx,
+ const int ptex_face_index,
+ const float u,
+ const float v,
+ const int subdiv_vertex_index)
+{
+ if (ctx->orco || ctx->cloth_orco) {
+ float vertex_data[6];
+ BKE_subdiv_eval_vertex_data(ctx->subdiv, ptex_face_index, u, v, vertex_data);
+
+ if (ctx->orco) {
+ copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data);
+ if (ctx->cloth_orco) {
+ copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data + 3);
+ }
+ }
+ else if (ctx->cloth_orco) {
+ copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data);
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Accumulation helpers
* \{ */
@@ -530,6 +564,8 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
/* Apply displacement. */
add_v3_v3(subdiv_vert->co, D);
+ /* Evaluate undeformed texture coordinate. */
+ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
/* Remove facedot flag. This can happen if there is more than one subsurf modifier. */
BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
}
@@ -556,6 +592,8 @@ static void evaluate_vertex_and_apply_displacement_interpolate(
BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
/* Apply displacement. */
add_v3_v3(subdiv_vert->co, D);
+ /* Evaluate undeformed texture coordinate. */
+ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
}
static void subdiv_mesh_vertex_displacement_every_corner_or_edge(
@@ -723,6 +761,7 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co);
subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vertex_index, u, v, subdiv_mesh);
+ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
}
/** \} */
diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh
index 81f5343056e..034c6968c94 100644
--- a/source/blender/blenlib/BLI_math_base.hh
+++ b/source/blender/blenlib/BLI_math_base.hh
@@ -108,12 +108,20 @@ template<typename T,
BLI_ENABLE_IF((is_math_float_type<FactorT>))>
inline T interpolate(const T &a, const T &b, const FactorT &t)
{
- return a * (1 - t) + b * t;
+ auto result = a * (1 - t) + b * t;
+ if constexpr (std::is_integral_v<T> && std::is_floating_point_v<FactorT>) {
+ result = std::round(result);
+ }
+ return result;
}
template<typename T> inline T midpoint(const T &a, const T &b)
{
- return (a + b) * T(0.5);
+ auto result = (a + b) * T(0.5);
+ if constexpr (std::is_integral_v<T>) {
+ result = std::round(result);
+ }
+ return result;
}
} // namespace blender::math
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 4782f1c4a5d..c6fc3cd5d0b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1078,14 +1078,17 @@ void DepsgraphNodeBuilder::build_animdata_nlastrip_targets(ListBase *strips)
void DepsgraphNodeBuilder::build_animation_images(ID *id)
{
- /* GPU materials might use an animated image. However, these materials have no been built yet. We
- * could scan the entire node tree recursively to check if any texture node has a video. That is
- * quite expensive. For now just always add this operation node, because it is very fast. */
- /* TODO: Add a more precise check when it is cheaper to iterate over all image nodes in a node
- * tree. */
- const bool can_have_gpu_material = ELEM(GS(id->name), ID_MA, ID_WO);
-
- if (can_have_gpu_material || BKE_image_user_id_has_animation(id)) {
+ /* GPU materials might use an animated image. However, these materials have no been built yet so
+ * we have to check if they might be created during evaluation. */
+ bool has_image_animation = false;
+ if (ELEM(GS(id->name), ID_MA, ID_WO)) {
+ bNodeTree *ntree = *BKE_ntree_ptr_from_id(id);
+ if (ntree != nullptr && ntree->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) {
+ has_image_animation = true;
+ }
+ }
+
+ if (has_image_animation || BKE_image_user_id_has_animation(id)) {
ID *id_cow = get_cow_id(id);
add_operation_node(
id,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 5eccb5a4eb2..3eeab23823c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1446,10 +1446,15 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
void DepsgraphRelationBuilder::build_animation_images(ID *id)
{
/* See #DepsgraphNodeBuilder::build_animation_images. */
- const bool can_have_gpu_material = ELEM(GS(id->name), ID_MA, ID_WO);
+ bool has_image_animation = false;
+ if (ELEM(GS(id->name), ID_MA, ID_WO)) {
+ bNodeTree *ntree = *BKE_ntree_ptr_from_id(id);
+ if (ntree != nullptr && ntree->runtime_flag & NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION) {
+ has_image_animation = true;
+ }
+ }
- /* TODO: can we check for existence of node for performance? */
- if (can_have_gpu_material || BKE_image_user_id_has_animation(id)) {
+ if (has_image_animation || BKE_image_user_id_has_animation(id)) {
OperationKey image_animation_key(
id, NodeType::IMAGE_ANIMATION, OperationCode::IMAGE_ANIMATION);
TimeSourceKey time_src_key;
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 99524184323..7800ce797aa 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -676,6 +676,40 @@ static void track_colors(MovieTrackingTrack *track, int act, float col[3], float
}
}
+static void set_draw_marker_area_color(const MovieTrackingTrack *track,
+ const MovieTrackingMarker *marker,
+ const bool is_track_active,
+ const bool is_area_selected,
+ const float color[3],
+ const float selected_color[3])
+{
+ if (track->flag & TRACK_LOCKED) {
+ if (is_track_active) {
+ immUniformThemeColor(TH_ACT_MARKER);
+ }
+ else if (is_area_selected) {
+ immUniformThemeColorShade(TH_LOCK_MARKER, 64);
+ }
+ else {
+ immUniformThemeColor(TH_LOCK_MARKER);
+ }
+ }
+ else if (marker->flag & MARKER_DISABLED) {
+ if (is_track_active) {
+ immUniformThemeColor(TH_ACT_MARKER);
+ }
+ else if (is_area_selected) {
+ immUniformThemeColorShade(TH_DIS_MARKER, 128);
+ }
+ else {
+ immUniformThemeColor(TH_DIS_MARKER);
+ }
+ }
+ else {
+ immUniformColor3fv(is_area_selected ? selected_color : color);
+ }
+}
+
static void draw_marker_areas(SpaceClip *sc,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
@@ -785,31 +819,7 @@ static void draw_marker_areas(SpaceClip *sc,
GPU_matrix_push();
GPU_matrix_translate_2fv(marker_pos);
- if (track->flag & TRACK_LOCKED) {
- if (act) {
- immUniformThemeColor(TH_ACT_MARKER);
- }
- else if (track->pat_flag & SELECT) {
- immUniformThemeColorShade(TH_LOCK_MARKER, 64);
- }
- else {
- immUniformThemeColor(TH_LOCK_MARKER);
- }
- }
- else if (marker->flag & MARKER_DISABLED) {
- if (act) {
- immUniformThemeColor(TH_ACT_MARKER);
- }
- else if (track->pat_flag & SELECT) {
- immUniformThemeColorShade(TH_DIS_MARKER, 128);
- }
- else {
- immUniformThemeColor(TH_DIS_MARKER);
- }
- }
- else {
- immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
- }
+ set_draw_marker_area_color(track, marker, act, track->pat_flag & SELECT, col, scol);
if (tiny) {
immUniform1f("dash_width", 6.0f);
@@ -834,6 +844,8 @@ static void draw_marker_areas(SpaceClip *sc,
0;
if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
+ set_draw_marker_area_color(track, marker, act, track->search_flag & SELECT, col, scol);
+
imm_draw_box_wire_2d(shdr_pos,
marker->search_min[0],
marker->search_min[1],
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 92c4d8fe938..e9c12e52bce 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -499,7 +499,13 @@ typedef struct bNodeTree {
int type;
- char _pad1[4];
+ /**
+ * Used to cache run-time information of the node tree.
+ * #eNodeTreeRuntimeFlag.
+ */
+ uint8_t runtime_flag;
+
+ char _pad1[3];
/**
* Sockets in groups have unique identifiers, adding new sockets always
@@ -601,6 +607,11 @@ typedef enum eNodeTreeExecutionMode {
NTREE_EXECUTION_MODE_FULL_FRAME = 1,
} eNodeTreeExecutionMode;
+typedef enum eNodeTreeRuntimeFlag {
+ /** There is a node that references an image with animation. */
+ NTREE_RUNTIME_FLAG_HAS_IMAGE_ANIMATION = 1 << 0,
+} eNodeTreeRuntimeFlag;
+
/* socket value structs for input buttons
* DEPRECATED now using ID properties
*/