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:
authorClément Foucault <foucault.clem@gmail.com>2022-01-27 00:06:17 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-01-27 14:34:42 +0300
commit032baf06f31063c956ab818a927200241529fa99 (patch)
tree6df0d1b8b12683cf2b6c1bdcb54387f8100df88e
parent4226c484bdbe7336f1221094916fcdfb12850034 (diff)
parent0bdf574ea20e6b138e243f2bf08e93b2e1ee5771 (diff)
Merge branch 'draw-viewport-data' into eevee-rewrite
-rw-r--r--source/blender/draw/engines/eevee/eevee_film.cc6
-rw-r--r--source/blender/draw/engines/eevee/eevee_light.cc4
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.cc2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobe.cc2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobe.hh4
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.cc2
-rw-r--r--source/blender/draw/engines/eevee/eevee_shader_shared.hh5
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadow.cc12
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadow.hh2
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader.cc46
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.cc41
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.cc61
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.hh22
-rw-r--r--source/blender/editors/space_outliner/outliner_select.cc13
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc17
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.cc59
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.cc9
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_rna.cc71
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_rna.hh11
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_seq.cc111
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_seq.hh60
-rw-r--r--source/blender/gpu/GPU_material.h6
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c104
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder_stubs.cc5
-rw-r--r--source/blender/nodes/NOD_shader.h5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_id.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc3
-rw-r--r--source/blender/nodes/intern/node_exec.cc59
-rw-r--r--source/blender/nodes/intern/node_exec.h20
-rw-r--r--source/blender/nodes/shader/node_shader_tree.cc6
-rw-r--r--source/blender/nodes/shader/node_shader_util.hh5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc14
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc30
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc11
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc81
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_emission.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_material.cc39
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc17
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.cc18
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_transform.cc39
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c57
-rw-r--r--source/blender/nodes/texture/node_texture_util.h12
55 files changed, 689 insertions, 461 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_film.cc b/source/blender/draw/engines/eevee/eevee_film.cc
index a45d503a25c..2542e39aed0 100644
--- a/source/blender/draw/engines/eevee/eevee_film.cc
+++ b/source/blender/draw/engines/eevee/eevee_film.cc
@@ -92,9 +92,9 @@ void Film::init(const ivec2 &full_extent, const rcti *output_rect)
}
data_.opacity = 1.0f;
- data_.uv_scale = 1.0f / vec2(full_extent);
- data_.uv_scale_inv = full_extent;
- data_.uv_bias = data_.offset / vec2(full_extent);
+ data_.uv_scale_inv = vec2(full_extent);
+ data_.uv_scale = 1.0f / data_.uv_scale_inv;
+ data_.uv_bias = vec2(data_.offset) * data_.uv_scale;
}
void Film::sync(void)
diff --git a/source/blender/draw/engines/eevee/eevee_light.cc b/source/blender/draw/engines/eevee/eevee_light.cc
index ab09ff4b0e5..bcc68d773f5 100644
--- a/source/blender/draw/engines/eevee/eevee_light.cc
+++ b/source/blender/draw/engines/eevee/eevee_light.cc
@@ -76,8 +76,8 @@ void Light::sync(ShadowModule &shadows, const Object *ob, float threshold)
this->color = vec3(&la->r) * la->energy;
normalize_m4_m4_ex(this->object_mat, ob->obmat, scale);
/* Make sure we have consistent handedness (in case of negatively scaled Z axis). */
- vec3 cross = vec3::cross(this->_right, this->_up);
- if (vec3::dot(cross, this->_back) < 0.0f) {
+ vec3 cross = math::cross(float3(this->_right), float3(this->_up));
+ if (math::dot(cross, float3(this->_back)) < 0.0f) {
negate_v3(this->_up);
}
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.cc b/source/blender/draw/engines/eevee/eevee_lightcache.cc
index c778c07f098..8c6625e4515 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.cc
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.cc
@@ -1104,7 +1104,7 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
void EEVEE_lightcache_free(struct LightCache *lcache_)
{
eevee::LightCache *lcache = reinterpret_cast<eevee::LightCache *>(lcache_);
- OBJECT_GUARDED_SAFE_DELETE(lcache, eevee::LightCache);
+ MEM_delete(lcache);
}
void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee)
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobe.cc b/source/blender/draw/engines/eevee/eevee_lightprobe.cc
index 2acce4ee203..c8eadea5f9e 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobe.cc
+++ b/source/blender/draw/engines/eevee/eevee_lightprobe.cc
@@ -38,7 +38,7 @@ void LightProbeModule::init()
bool use_lookdev = inst_.use_studio_light();
if (!use_lookdev && lightcache_ && lightcache_->load()) {
- OBJECT_GUARDED_SAFE_DELETE(lightcache_lookdev_, LightCache);
+ MEM_delete(lightcache_lookdev_);
}
else {
if (lightcache_ && (lightcache_->flag & LIGHTCACHE_NOT_USABLE)) {
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobe.hh b/source/blender/draw/engines/eevee/eevee_lightprobe.hh
index 1a58f73409b..c13f7a75ca4 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobe.hh
+++ b/source/blender/draw/engines/eevee/eevee_lightprobe.hh
@@ -89,8 +89,8 @@ class LightProbeModule {
~LightProbeModule()
{
- OBJECT_GUARDED_SAFE_DELETE(lightcache_lookdev_, LightCache);
- OBJECT_GUARDED_SAFE_DELETE(lightcache_baking_, LightCache);
+ MEM_delete(lightcache_lookdev_);
+ MEM_delete(lightcache_baking_);
}
void init();
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.cc b/source/blender/draw/engines/eevee/eevee_lookdev.cc
index e5633ac47ee..881ab90343f 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.cc
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.cc
@@ -314,7 +314,7 @@ void LookDev::sync_overlay(void)
/* Pass 2D scale and bias factor in the last column. */
vec2 scale = sphere_size_ / vec2(viewport_size);
- vec2 bias = -1.0f + scale + 2.0f * (anchor_ + offset + jitter) / vec2(viewport_size);
+ vec2 bias = -1.0f + scale + 2.0f * (vec2(anchor_) + offset + jitter) / vec2(viewport_size);
copy_v4_fl4(sphere_mat[3], UNPACK2(scale), UNPACK2(bias));
DRW_shgroup_call_obmat(grp, sphere, sphere_mat);
diff --git a/source/blender/draw/engines/eevee/eevee_shader_shared.hh b/source/blender/draw/engines/eevee/eevee_shader_shared.hh
index 746087ad232..07690744367 100644
--- a/source/blender/draw/engines/eevee/eevee_shader_shared.hh
+++ b/source/blender/draw/engines/eevee/eevee_shader_shared.hh
@@ -43,12 +43,7 @@
#else /* C++ */
# pragma once
-# include "BLI_float2.hh"
-# include "BLI_float3.hh"
-# include "BLI_float4.hh"
# include "BLI_float4x4.hh"
-# include "BLI_int2.hh"
-# include "BLI_int3.hh"
typedef float mat4[4][4];
using vec4 = blender::float4;
diff --git a/source/blender/draw/engines/eevee/eevee_shadow.cc b/source/blender/draw/engines/eevee/eevee_shadow.cc
index 70eb49ec487..06306ff770a 100644
--- a/source/blender/draw/engines/eevee/eevee_shadow.cc
+++ b/source/blender/draw/engines/eevee/eevee_shadow.cc
@@ -77,7 +77,7 @@ void ShadowTileMap::sync_clipmap(const float3 &camera_position,
float4x4 viewinv = object_mat;
copy_v3_v3(viewinv.values[3], tilemap_center);
- float camera_distance_to_plane = float3::dot(float3(object_mat.values[2]), camera_position);
+ float camera_distance_to_plane = math::dot(float3(object_mat.values[2]), camera_position);
float visible_near = camera_distance_to_plane - half_size;
float visible_far = camera_distance_to_plane + half_size;
@@ -444,7 +444,7 @@ void ShadowDirectional::end_sync(int min_level,
far_ = -1.0e30f;
BoundBox bbox = casters_bounds;
for (auto i : IndexRange(8)) {
- float dist = -float3::dot(z_axis, float3(bbox.vec[i]));
+ float dist = -math::dot(z_axis, float3(bbox.vec[i]));
near_ = min_ff(near_, dist);
far_ = max_ff(far_, dist);
}
@@ -471,8 +471,8 @@ void ShadowDirectional::end_sync(int min_level,
/* Compute full offset from origin to the smallest clipmap tile size. */
float tile_size = first_clipmap.tile_size_get();
base_offset_ = int2(
- roundf(float3::dot(float3(object_mat_.values[0]), camera_position) / tile_size),
- roundf(float3::dot(float3(object_mat_.values[1]), camera_position) / tile_size));
+ roundf(math::dot(float3(object_mat_.values[0]), camera_position) / tile_size),
+ roundf(math::dot(float3(object_mat_.values[1]), camera_position) / tile_size));
int level = min_level;
int divisor = 1;
@@ -653,7 +653,7 @@ void ShadowModule::end_sync(void)
/* Get the farthest point from camera to know what distance to cover. */
float3 farthest_point = float3(1.0f, 1.0f, 1.0f);
mul_project_m4_v3(inst_.camera.data_get().wininv, farthest_point);
- float far_dist = farthest_point.length();
+ float far_dist = math::length(farthest_point);
float near_dist = fabsf(inst_.camera.data_get().clip_near);
float3 cam_position = inst_.camera.position();
@@ -1041,7 +1041,7 @@ void ShadowModule::set_view(const DRWView *view, GPUTexture *depth_tx)
p0 = p0 / p0.z;
p1 = p1 / p1.z;
}
- screen_pixel_radius_inv_ = min_dim / float3::distance(p0, p1);
+ screen_pixel_radius_inv_ = min_dim / math::distance(p0, p1);
}
#ifdef SHADOW_DEBUG_FREEZE_CAMERA
diff --git a/source/blender/draw/engines/eevee/eevee_shadow.hh b/source/blender/draw/engines/eevee/eevee_shadow.hh
index 65456f11326..a7db2f6dc0e 100644
--- a/source/blender/draw/engines/eevee/eevee_shadow.hh
+++ b/source/blender/draw/engines/eevee/eevee_shadow.hh
@@ -107,7 +107,7 @@ struct AABB {
float radius(void) const
{
- return (max - min).length() / 2.0f;
+ return math::length(max - min) / 2.0f;
}
operator BoundBox() const
diff --git a/source/blender/draw/engines/workbench/workbench_shader.cc b/source/blender/draw/engines/workbench/workbench_shader.cc
index b38286303f1..011a3fd3b13 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.cc
+++ b/source/blender/draw/engines/workbench/workbench_shader.cc
@@ -27,52 +27,6 @@
#include "workbench_engine.h"
#include "workbench_private.h"
-extern char datatoc_common_math_lib_glsl[];
-extern char datatoc_common_math_geom_lib_glsl[];
-extern char datatoc_common_hair_lib_glsl[];
-extern char datatoc_common_pointcloud_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_smaa_lib_glsl[];
-
-extern char datatoc_workbench_prepass_vert_glsl[];
-extern char datatoc_workbench_prepass_hair_vert_glsl[];
-extern char datatoc_workbench_prepass_pointcloud_vert_glsl[];
-extern char datatoc_workbench_prepass_frag_glsl[];
-
-extern char datatoc_workbench_effect_cavity_frag_glsl[];
-extern char datatoc_workbench_effect_outline_frag_glsl[];
-extern char datatoc_workbench_effect_dof_frag_glsl[];
-extern char datatoc_workbench_effect_taa_frag_glsl[];
-extern char datatoc_workbench_effect_smaa_frag_glsl[];
-extern char datatoc_workbench_effect_smaa_vert_glsl[];
-
-extern char datatoc_workbench_composite_frag_glsl[];
-
-extern char datatoc_workbench_transparent_accum_frag_glsl[];
-extern char datatoc_workbench_transparent_resolve_frag_glsl[];
-
-extern char datatoc_workbench_merge_infront_frag_glsl[];
-
-extern char datatoc_workbench_shadow_vert_glsl[];
-extern char datatoc_workbench_shadow_geom_glsl[];
-extern char datatoc_workbench_shadow_caps_geom_glsl[];
-extern char datatoc_workbench_shadow_debug_frag_glsl[];
-
-extern char datatoc_workbench_volume_vert_glsl[];
-extern char datatoc_workbench_volume_frag_glsl[];
-
-extern char datatoc_workbench_cavity_lib_glsl[];
-extern char datatoc_workbench_common_lib_glsl[];
-extern char datatoc_workbench_curvature_lib_glsl[];
-extern char datatoc_workbench_data_lib_glsl[];
-extern char datatoc_workbench_image_lib_glsl[];
-extern char datatoc_workbench_matcap_lib_glsl[];
-extern char datatoc_workbench_material_lib_glsl[];
-extern char datatoc_workbench_world_light_lib_glsl[];
-
-extern char datatoc_gpu_shader_depth_only_frag_glsl[];
-extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
-
/* Maximum number of variations. */
#define MAX_LIGHTING 3
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 60b881fb32b..bc6db978a4f 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -67,6 +67,7 @@ set(SRC
tree/tree_element_overrides.cc
tree/tree_element_rna.cc
tree/tree_element_scene_objects.cc
+ tree/tree_element_seq.cc
tree/tree_element_view_layer.cc
outliner_intern.hh
@@ -84,6 +85,7 @@ set(SRC
tree/tree_element_overrides.hh
tree/tree_element_rna.hh
tree/tree_element_scene_objects.hh
+ tree/tree_element_seq.hh
tree/tree_element_view_layer.hh
)
diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc
index 6de8d9539a9..5fd7559370f 100644
--- a/source/blender/editors/space_outliner/outliner_draw.cc
+++ b/source/blender/editors/space_outliner/outliner_draw.cc
@@ -81,6 +81,7 @@
#include "outliner_intern.hh"
#include "tree/tree_display.hh"
#include "tree/tree_element.hh"
+#include "tree/tree_element_rna.hh"
using namespace blender::ed::outliner;
@@ -1909,20 +1910,20 @@ static void outliner_draw_rnacols(ARegion *region, int sizex)
static void outliner_draw_rnabuts(
uiBlock *block, ARegion *region, SpaceOutliner *space_outliner, int sizex, ListBase *lb)
{
- PointerRNA *ptr;
+ PointerRNA ptr;
PropertyRNA *prop;
LISTBASE_FOREACH (TreeElement *, te, lb) {
TreeStoreElem *tselem = TREESTORE(te);
if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) {
- if (tselem->type == TSE_RNA_PROPERTY) {
- ptr = &te->rnaptr;
- prop = reinterpret_cast<PropertyRNA *>(te->directdata);
+ if (TreeElementRNAProperty *te_rna_prop = tree_element_cast<TreeElementRNAProperty>(te)) {
+ ptr = te_rna_prop->getPointerRNA();
+ prop = te_rna_prop->getPropertyRNA();
if (!TSELEM_OPEN(tselem, space_outliner)) {
if (RNA_property_type(prop) == PROP_POINTER) {
uiBut *but = uiDefAutoButR(block,
- ptr,
+ &ptr,
prop,
-1,
"",
@@ -1935,7 +1936,7 @@ static void outliner_draw_rnabuts(
}
else if (RNA_property_type(prop) == PROP_ENUM) {
uiDefAutoButR(block,
- ptr,
+ &ptr,
prop,
-1,
nullptr,
@@ -1947,7 +1948,7 @@ static void outliner_draw_rnabuts(
}
else {
uiDefAutoButR(block,
- ptr,
+ &ptr,
prop,
-1,
"",
@@ -1959,12 +1960,13 @@ static void outliner_draw_rnabuts(
}
}
}
- else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
- ptr = &te->rnaptr;
- prop = reinterpret_cast<PropertyRNA *>(te->directdata);
+ else if (TreeElementRNAArrayElement *te_rna_array_elem =
+ tree_element_cast<TreeElementRNAArrayElement>(te)) {
+ ptr = te_rna_array_elem->getPointerRNA();
+ prop = te_rna_array_elem->getPropertyRNA();
uiDefAutoButR(block,
- ptr,
+ &ptr,
prop,
te->index,
"",
@@ -2554,15 +2556,19 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case TSE_SEQUENCE_DUP:
data.icon = ICON_SEQ_STRIP_DUPLICATE;
break;
- case TSE_RNA_STRUCT:
- if (RNA_struct_is_ID(te->rnaptr.type)) {
- data.drag_id = (ID *)te->rnaptr.data;
- data.icon = RNA_struct_ui_icon(te->rnaptr.type);
+ case TSE_RNA_STRUCT: {
+ const TreeElementRNAStruct *te_rna_struct = tree_element_cast<TreeElementRNAStruct>(te);
+ const PointerRNA &ptr = te_rna_struct->getPointerRNA();
+
+ if (RNA_struct_is_ID(ptr.type)) {
+ data.drag_id = reinterpret_cast<ID *>(ptr.data);
+ data.icon = RNA_struct_ui_icon(ptr.type);
}
else {
- data.icon = RNA_struct_ui_icon(te->rnaptr.type);
+ data.icon = RNA_struct_ui_icon(ptr.type);
}
break;
+ }
case TSE_LAYER_COLLECTION:
case TSE_SCENE_COLLECTION_BASE:
case TSE_VIEW_COLLECTION_BASE: {
@@ -3319,8 +3325,9 @@ static void outliner_draw_tree_element(bContext *C,
offsx += 2 * ufac;
}
+ const TreeElementRNAStruct *te_rna_struct = tree_element_cast<TreeElementRNAStruct>(te);
if (ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION) ||
- ((tselem->type == TSE_RNA_STRUCT) && RNA_struct_is_ID(te->rnaptr.type))) {
+ (te_rna_struct && RNA_struct_is_ID(te_rna_struct->getPointerRNA().type))) {
const BIFIconID lib_icon = (BIFIconID)UI_icon_from_library(tselem->id);
if (lib_icon != ICON_NONE) {
UI_icon_draw_alpha(
diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc
index a10dbc94b34..b41b260b14a 100644
--- a/source/blender/editors/space_outliner/outliner_edit.cc
+++ b/source/blender/editors/space_outliner/outliner_edit.cc
@@ -74,6 +74,9 @@
#include "GPU_material.h"
#include "outliner_intern.hh"
+#include "tree/tree_element_rna.hh"
+
+using namespace blender::ed::outliner;
static void outliner_show_active(SpaceOutliner *space_outliner,
ARegion *region,
@@ -1714,11 +1717,6 @@ static void tree_element_to_path(TreeElement *te,
short *UNUSED(groupmode))
{
ListBase hierarchy = {nullptr, nullptr};
- LinkData *ld;
- TreeElement *tem, *temnext;
- TreeStoreElem *tse /* , *tsenext */ /* UNUSED */;
- PointerRNA *ptr, *nextptr;
- PropertyRNA *prop;
char *newpath = nullptr;
/* optimize tricks:
@@ -1738,20 +1736,19 @@ static void tree_element_to_path(TreeElement *te,
*/
/* step 1: flatten out hierarchy of parents into a flat chain */
- for (tem = te->parent; tem; tem = tem->parent) {
- ld = MEM_cnew<LinkData>("LinkData for tree_element_to_path()");
+ for (TreeElement *tem = te->parent; tem; tem = tem->parent) {
+ LinkData *ld = MEM_cnew<LinkData>("LinkData for tree_element_to_path()");
ld->data = tem;
BLI_addhead(&hierarchy, ld);
}
/* step 2: step down hierarchy building the path
* (NOTE: addhead in previous loop was needed so that we can loop like this) */
- for (ld = reinterpret_cast<LinkData *>(hierarchy.first); ld; ld = ld->next) {
+ LISTBASE_FOREACH (LinkData *, ld, &hierarchy) {
/* get data */
- tem = (TreeElement *)ld->data;
- tse = TREESTORE(tem);
- ptr = &tem->rnaptr;
- prop = reinterpret_cast<PropertyRNA *>(tem->directdata);
+ TreeElement *tem = (TreeElement *)ld->data;
+ TreeElementRNACommon *tem_rna = tree_element_cast<TreeElementRNACommon>(tem);
+ PointerRNA ptr = tem_rna->getPointerRNA();
/* check if we're looking for first ID, or appending to path */
if (*id) {
@@ -1759,19 +1756,19 @@ static void tree_element_to_path(TreeElement *te,
* - to prevent memory leaks, we must write to newpath not path,
* then free old path + swap them.
*/
- if (tse->type == TSE_RNA_PROPERTY) {
+ if (TreeElementRNAProperty *tem_rna_prop = tree_element_cast<TreeElementRNAProperty>(tem)) {
+ PropertyRNA *prop = tem_rna_prop->getPropertyRNA();
+
if (RNA_property_type(prop) == PROP_POINTER) {
/* for pointer we just append property name */
- newpath = RNA_path_append(*path, ptr, prop, 0, nullptr);
+ newpath = RNA_path_append(*path, &ptr, prop, 0, nullptr);
}
else if (RNA_property_type(prop) == PROP_COLLECTION) {
char buf[128], *name;
- temnext = (TreeElement *)(ld->next->data);
- // tsenext = TREESTORE(temnext); /* UNUSED */
-
- nextptr = &temnext->rnaptr;
- name = RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf), nullptr);
+ TreeElement *temnext = (TreeElement *)(ld->next->data);
+ PointerRNA nextptr = tree_element_cast<TreeElementRNACommon>(temnext)->getPointerRNA();
+ name = RNA_struct_name_get_alloc(&nextptr, buf, sizeof(buf), nullptr);
if (name) {
/* if possible, use name as a key in the path */
@@ -1789,6 +1786,7 @@ static void tree_element_to_path(TreeElement *te,
if (temsub == temnext) {
break;
}
+ index++;
}
newpath = RNA_path_append(*path, nullptr, prop, index, nullptr);
}
@@ -1808,11 +1806,11 @@ static void tree_element_to_path(TreeElement *te,
else {
/* no ID, so check if entry is RNA-struct,
* and if that RNA-struct is an ID datablock to extract info from. */
- if (tse->type == TSE_RNA_STRUCT) {
+ if (tree_element_cast<TreeElementRNAStruct>(tem)) {
/* ptr->data not ptr->owner_id seems to be the one we want,
* since ptr->data is sometimes the owner of this ID? */
- if (RNA_struct_is_ID(ptr->type)) {
- *id = reinterpret_cast<ID *>(ptr->data);
+ if (RNA_struct_is_ID(ptr.type)) {
+ *id = reinterpret_cast<ID *>(ptr.data);
/* clear path */
if (*path) {
@@ -1827,8 +1825,7 @@ static void tree_element_to_path(TreeElement *te,
/* step 3: if we've got an ID, add the current item to the path */
if (*id) {
/* add the active property to the path */
- ptr = &te->rnaptr;
- prop = reinterpret_cast<PropertyRNA *>(te->directdata);
+ PropertyRNA *prop = tree_element_cast<TreeElementRNACommon>(te)->getPropertyRNA();
/* array checks */
if (tselem->type == TSE_RNA_ARRAY_ELEM) {
@@ -1886,9 +1883,12 @@ static void do_outliner_drivers_editop(SpaceOutliner *space_outliner,
short flag = 0;
short groupmode = KSP_GROUP_KSNAME;
+ TreeElementRNACommon *te_rna = tree_element_cast<TreeElementRNACommon>(te);
+ PointerRNA ptr = te_rna ? te_rna->getPointerRNA() : PointerRNA_NULL;
+ PropertyRNA *prop = te_rna ? te_rna->getPropertyRNA() : nullptr;
+
/* check if RNA-property described by this selected element is an animatable prop */
- if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
- RNA_property_animateable(&te->rnaptr, reinterpret_cast<PropertyRNA *>(te->directdata))) {
+ if (prop && RNA_property_animateable(&ptr, prop)) {
/* get id + path + index info from the selected element */
tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode);
}
@@ -1901,8 +1901,7 @@ static void do_outliner_drivers_editop(SpaceOutliner *space_outliner,
/* array checks */
if (flag & KSP_FLAG_WHOLE_ARRAY) {
/* entire array was selected, so add drivers for all */
- arraylen = RNA_property_array_length(&te->rnaptr,
- reinterpret_cast<PropertyRNA *>(te->directdata));
+ arraylen = RNA_property_array_length(&ptr, prop);
}
else {
arraylen = array_index;
@@ -2084,8 +2083,10 @@ static void do_outliner_keyingset_editop(SpaceOutliner *space_outliner,
short groupmode = KSP_GROUP_KSNAME;
/* check if RNA-property described by this selected element is an animatable prop */
- if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
- RNA_property_animateable(&te->rnaptr, reinterpret_cast<PropertyRNA *>(te->directdata))) {
+ const TreeElementRNACommon *te_rna = tree_element_cast<TreeElementRNACommon>(te);
+ PointerRNA ptr = te_rna->getPointerRNA();
+ if (te_rna && te_rna->getPropertyRNA() &&
+ RNA_property_animateable(&ptr, te_rna->getPropertyRNA())) {
/* get id + path + index info from the selected element */
tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode);
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh
index a62d35131ca..9db1d73dc76 100644
--- a/source/blender/editors/space_outliner/outliner_intern.hh
+++ b/source/blender/editors/space_outliner/outliner_intern.hh
@@ -27,6 +27,9 @@
#include "RNA_types.h"
+/* Needed for `tree_element_cast()`. */
+#include "tree/tree_element.hh"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -104,8 +107,7 @@ typedef struct TreeElement {
short idcode; /* From TreeStore id. */
short xend; /* Width of item display, for select. */
const char *name;
- void *directdata; /* Armature Bones, Base, Sequence, Strip... */
- PointerRNA rnaptr; /* RNA Pointer. */
+ void *directdata; /* Armature Bones, Base, ... */
} TreeElement;
typedef struct TreeElementIcon {
@@ -686,3 +688,19 @@ int outliner_context(const struct bContext *C,
#ifdef __cplusplus
}
#endif
+
+namespace blender::ed::outliner {
+
+/**
+ * Helper to safely "cast" a #TreeElement to its new C++ #AbstractTreeElement, if possible.
+ * \return nullptr if the tree-element doesn't match the requested type \a TreeElementT or the
+ * element doesn't hold a C++ #AbstractTreeElement pendant yet.
+ */
+template<typename TreeElementT> TreeElementT *tree_element_cast(const TreeElement *te)
+{
+ static_assert(std::is_base_of_v<AbstractTreeElement, TreeElementT>,
+ "Requested tree-element type must be an AbstractTreeElement");
+ return dynamic_cast<TreeElementT *>(te->type.get());
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc
index c2a7bfb9b37..3ff8b9e973f 100644
--- a/source/blender/editors/space_outliner/outliner_select.cc
+++ b/source/blender/editors/space_outliner/outliner_select.cc
@@ -80,6 +80,9 @@
#include "RNA_define.h"
#include "outliner_intern.hh"
+#include "tree/tree_element_seq.hh"
+
+using namespace blender::ed::outliner;
/**
* \note changes to selection are by convention and not essential.
@@ -676,7 +679,8 @@ static void tree_element_sequence_activate(bContext *C,
TreeElement *te,
const eOLSetState set)
{
- Sequence *seq = (Sequence *)te->directdata;
+ const TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
+ Sequence *seq = &te_seq->getSequence();
Editing *ed = SEQ_editing_get(scene);
if (BLI_findindex(ed->seqbasep, seq) != -1) {
@@ -954,7 +958,8 @@ static eOLDrawState tree_element_posegroup_state_get(const ViewLayer *view_layer
static eOLDrawState tree_element_sequence_state_get(const Scene *scene, const TreeElement *te)
{
- const Sequence *seq = (const Sequence *)te->directdata;
+ const TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
+ const Sequence *seq = &te_seq->getSequence();
const Editing *ed = scene->ed;
if (ed && ed->act_seq == seq && seq->flag & SELECT) {
@@ -965,7 +970,9 @@ static eOLDrawState tree_element_sequence_state_get(const Scene *scene, const Tr
static eOLDrawState tree_element_sequence_dup_state_get(const TreeElement *te)
{
- const Sequence *seq = (const Sequence *)te->directdata;
+ const TreeElementSequenceStripDuplicate *te_dup =
+ tree_element_cast<TreeElementSequenceStripDuplicate>(te);
+ const Sequence *seq = &te_dup->getSequence();
if (seq->flag & SELECT) {
return OL_DRAWSEL_NORMAL;
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index 1c1a4f6f4c2..fa31025b550 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -96,9 +96,13 @@
#include "SEQ_sequencer.h"
#include "outliner_intern.hh"
+#include "tree/tree_element_rna.hh"
+#include "tree/tree_element_seq.hh"
static CLG_LogRef LOG = {"ed.outliner.tools"};
+using namespace blender::ed::outliner;
+
/* -------------------------------------------------------------------- */
/** \name ID/Library/Data Set/Un-link Utilities
* \{ */
@@ -1285,7 +1289,8 @@ static void ebone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem),
static void sequence_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *scene_ptr)
{
- Sequence *seq = (Sequence *)te->directdata;
+ TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
+ Sequence *seq = &te_seq->getSequence();
Scene *scene = (Scene *)scene_ptr;
Editing *ed = SEQ_editing_get(scene);
if (BLI_findindex(ed->seqbasep, seq) != -1) {
@@ -1336,10 +1341,16 @@ static void data_select_linked_fn(int event,
TreeStoreElem *UNUSED(tselem),
void *C_v)
{
+ const TreeElementRNAStruct *te_rna_struct = tree_element_cast<TreeElementRNAStruct>(te);
+ if (!te_rna_struct) {
+ return;
+ }
+
if (event == OL_DOP_SELECT_LINKED) {
- if (RNA_struct_is_ID(te->rnaptr.type)) {
+ const PointerRNA &ptr = te_rna_struct->getPointerRNA();
+ if (RNA_struct_is_ID(ptr.type)) {
bContext *C = (bContext *)C_v;
- ID *id = reinterpret_cast<ID *>(te->rnaptr.data);
+ ID *id = reinterpret_cast<ID *>(ptr.data);
ED_object_select_linked_by_id(C, id);
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc
index be792be95a9..eb885eba20d 100644
--- a/source/blender/editors/space_outliner/outliner_tree.cc
+++ b/source/blender/editors/space_outliner/outliner_tree.cc
@@ -925,57 +925,14 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
TSE_NLA,
TSE_NLA_ACTION,
TSE_NLA_TRACK,
- TSE_GP_LAYER)) {
- /* Should already use new AbstractTreeElement design. */
- BLI_assert(0);
- }
- else if (type == TSE_SEQUENCE) {
- Sequence *seq = (Sequence *)idv;
-
- /*
- * The idcode is a little hack, but the outliner
- * only check te->idcode if te->type is equal to zero,
- * so this is "safe".
- */
- te->idcode = seq->type;
- te->directdata = seq;
- te->name = seq->name + 2;
-
- if (!(seq->type & SEQ_TYPE_EFFECT)) {
- /*
- * This work like the sequence.
- * If the sequence have a name (not default name)
- * show it, in other case put the filename.
- */
-
- if (seq->type == SEQ_TYPE_META) {
- LISTBASE_FOREACH (Sequence *, p, &seq->seqbase) {
- outliner_add_element(space_outliner, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- }
- }
- else {
- outliner_add_element(
- space_outliner, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index);
- }
- }
- }
- else if (type == TSE_SEQ_STRIP) {
- Strip *strip = (Strip *)idv;
-
- if (strip->dir[0] != '\0') {
- te->name = strip->dir;
- }
- else {
- te->name = IFACE_("Strip None");
- }
- te->directdata = strip;
- }
- else if (type == TSE_SEQUENCE_DUP) {
- Sequence *seq = (Sequence *)idv;
-
- te->idcode = seq->type;
- te->directdata = seq;
- te->name = seq->strip->stripdata->name;
+ TSE_GP_LAYER,
+ TSE_RNA_STRUCT,
+ TSE_RNA_PROPERTY,
+ TSE_RNA_ARRAY_ELEM,
+ TSE_SEQUENCE,
+ TSE_SEQ_STRIP,
+ TSE_SEQUENCE_DUP)) {
+ BLI_assert_msg(false, "Element type should already use new AbstractTreeElement design");
}
if (tree_element_warnings_get(te, nullptr, nullptr)) {
diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc
index bed28e59f0b..5685d8964f5 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element.cc
@@ -35,6 +35,7 @@
#include "tree_element_overrides.hh"
#include "tree_element_rna.hh"
#include "tree_element_scene_objects.hh"
+#include "tree_element_seq.hh"
#include "tree_element_view_layer.hh"
#include "../outliner_intern.hh"
@@ -96,6 +97,14 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i
case TSE_RNA_ARRAY_ELEM:
return std::make_unique<TreeElementRNAArrayElement>(
legacy_te, *reinterpret_cast<PointerRNA *>(idv), legacy_te.index);
+ case TSE_SEQUENCE:
+ return std::make_unique<TreeElementSequence>(legacy_te, *reinterpret_cast<Sequence *>(idv));
+ case TSE_SEQ_STRIP:
+ return std::make_unique<TreeElementSequenceStrip>(legacy_te,
+ *reinterpret_cast<Strip *>(idv));
+ case TSE_SEQUENCE_DUP:
+ return std::make_unique<TreeElementSequenceStripDuplicate>(
+ legacy_te, *reinterpret_cast<Sequence *>(idv));
default:
break;
}
diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
index 0152f59268d..7a9f1b6f0fa 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
@@ -54,8 +54,6 @@ TreeElementRNACommon::TreeElementRNACommon(TreeElement &legacy_te, PointerRNA &r
legacy_te_.name = IFACE_("(empty)");
return;
}
-
- legacy_te_.rnaptr = rna_ptr;
}
bool TreeElementRNACommon::isExpandValid() const
@@ -73,12 +71,24 @@ bool TreeElementRNACommon::expandPoll(const SpaceOutliner &) const
return isRNAValid();
}
+const PointerRNA &TreeElementRNACommon::getPointerRNA() const
+{
+ return rna_ptr_;
+}
+
+PropertyRNA *TreeElementRNACommon::getPropertyRNA() const
+{
+ return nullptr;
+}
+
/* -------------------------------------------------------------------- */
/* RNA Struct */
TreeElementRNAStruct::TreeElementRNAStruct(TreeElement &legacy_te, PointerRNA &rna_ptr)
: TreeElementRNACommon(legacy_te, rna_ptr)
{
+ BLI_assert(legacy_te.store_elem->type == TSE_RNA_STRUCT);
+
if (!isRNAValid()) {
return;
}
@@ -95,21 +105,23 @@ TreeElementRNAStruct::TreeElementRNAStruct(TreeElement &legacy_te, PointerRNA &r
void TreeElementRNAStruct::expand(SpaceOutliner &space_outliner) const
{
TreeStoreElem &tselem = *TREESTORE(&legacy_te_);
- PointerRNA *ptr = &legacy_te_.rnaptr;
+ PointerRNA ptr = rna_ptr_;
/* If searching don't expand RNA entries */
if (SEARCHING_OUTLINER(&space_outliner) && BLI_strcasecmp("RNA", legacy_te_.name) == 0) {
tselem.flag &= ~TSE_CHILDSEARCH;
}
- PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
- int tot = RNA_property_collection_length(ptr, iterprop);
+ PropertyRNA *iterprop = RNA_struct_iterator_property(ptr.type);
+ int tot = RNA_property_collection_length(&ptr, iterprop);
CLAMP_MAX(tot, max_index);
+ TreeElementRNAProperty *parent_prop_te = legacy_te_.parent ?
+ tree_element_cast<TreeElementRNAProperty>(
+ legacy_te_.parent) :
+ nullptr;
/* auto open these cases */
- if (!legacy_te_.parent ||
- (RNA_property_type(reinterpret_cast<PropertyRNA *>(legacy_te_.parent->directdata))) ==
- PROP_POINTER) {
+ if (!parent_prop_te || (RNA_property_type(parent_prop_te->getPropertyRNA()) == PROP_POINTER)) {
if (!tselem.used) {
tselem.flag &= ~TSE_CLOSED;
}
@@ -118,14 +130,10 @@ void TreeElementRNAStruct::expand(SpaceOutliner &space_outliner) const
if (TSELEM_OPEN(&tselem, &space_outliner)) {
for (int index = 0; index < tot; index++) {
PointerRNA propptr;
- RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
+ RNA_property_collection_lookup_int(&ptr, iterprop, index, &propptr);
if (!(RNA_property_flag(reinterpret_cast<PropertyRNA *>(propptr.data)) & PROP_HIDDEN)) {
- outliner_add_element(&space_outliner,
- &legacy_te_.subtree,
- (void *)ptr,
- &legacy_te_,
- TSE_RNA_PROPERTY,
- index);
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, &ptr, &legacy_te_, TSE_RNA_PROPERTY, index);
}
}
}
@@ -142,6 +150,8 @@ TreeElementRNAProperty::TreeElementRNAProperty(TreeElement &legacy_te,
const int index)
: TreeElementRNACommon(legacy_te, rna_ptr)
{
+ BLI_assert(legacy_te.store_elem->type == TSE_RNA_PROPERTY);
+
if (!isRNAValid()) {
return;
}
@@ -153,7 +163,6 @@ TreeElementRNAProperty::TreeElementRNAProperty(TreeElement &legacy_te,
PropertyRNA *prop = reinterpret_cast<PropertyRNA *>(propptr.data);
legacy_te_.name = RNA_property_ui_name(prop);
- legacy_te_.directdata = prop;
rna_prop_ = prop;
}
@@ -174,7 +183,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
if (pptr.data) {
if (TSELEM_OPEN(&tselem, &space_outliner)) {
outliner_add_element(
- &space_outliner, &legacy_te_.subtree, (void *)&pptr, &legacy_te_, TSE_RNA_STRUCT, -1);
+ &space_outliner, &legacy_te_.subtree, &pptr, &legacy_te_, TSE_RNA_STRUCT, -1);
}
else {
legacy_te_.flag |= TE_LAZY_CLOSED;
@@ -189,12 +198,8 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
for (int index = 0; index < tot; index++) {
PointerRNA pptr;
RNA_property_collection_lookup_int(&rna_ptr, rna_prop_, index, &pptr);
- outliner_add_element(&space_outliner,
- &legacy_te_.subtree,
- (void *)&pptr,
- &legacy_te_,
- TSE_RNA_STRUCT,
- index);
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, &pptr, &legacy_te_, TSE_RNA_STRUCT, index);
}
}
else if (tot) {
@@ -221,6 +226,11 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
}
}
+PropertyRNA *TreeElementRNAProperty::getPropertyRNA() const
+{
+ return rna_prop_;
+}
+
/* -------------------------------------------------------------------- */
/* RNA Array Element */
@@ -229,11 +239,12 @@ TreeElementRNAArrayElement::TreeElementRNAArrayElement(TreeElement &legacy_te,
const int index)
: TreeElementRNACommon(legacy_te, rna_ptr)
{
- PropertyRNA *prop = reinterpret_cast<PropertyRNA *>(legacy_te_.parent->directdata);
- legacy_te_.directdata = prop;
+ BLI_assert(legacy_te.store_elem->type == TSE_RNA_ARRAY_ELEM);
+
+ BLI_assert(legacy_te.parent && (legacy_te.parent->store_elem->type == TSE_RNA_PROPERTY));
legacy_te_.index = index;
- char c = RNA_property_array_item_char(prop, index);
+ char c = RNA_property_array_item_char(TreeElementRNAArrayElement::getPropertyRNA(), index);
legacy_te_.name = reinterpret_cast<char *>(
MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName"));
@@ -246,4 +257,12 @@ TreeElementRNAArrayElement::TreeElementRNAArrayElement(TreeElement &legacy_te,
legacy_te_.flag |= TE_FREE_NAME;
}
+PropertyRNA *TreeElementRNAArrayElement::getPropertyRNA() const
+{
+ /* Forward query to the parent (which is expected to be a #TreeElementRNAProperty). */
+ const TreeElementRNAProperty *parent_prop_te = tree_element_cast<TreeElementRNAProperty>(
+ legacy_te_.parent);
+ return parent_prop_te ? parent_prop_te->getPropertyRNA() : nullptr;
+}
+
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.hh b/source/blender/editors/space_outliner/tree/tree_element_rna.hh
index 352b8763acb..1f107ddbf88 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_rna.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element_rna.hh
@@ -43,6 +43,13 @@ class TreeElementRNACommon : public AbstractTreeElement {
bool isExpandValid() const override;
bool expandPoll(const SpaceOutliner &) const override;
+ const PointerRNA &getPointerRNA() const;
+ /**
+ * If this element represents a property or is part of a property (array element), this returns
+ * the property. Otherwise nullptr.
+ */
+ virtual PropertyRNA *getPropertyRNA() const;
+
bool isRNAValid() const;
};
@@ -63,6 +70,8 @@ class TreeElementRNAProperty : public TreeElementRNACommon {
public:
TreeElementRNAProperty(TreeElement &legacy_te, PointerRNA &rna_ptr, int index);
void expand(SpaceOutliner &space_outliner) const override;
+
+ PropertyRNA *getPropertyRNA() const override;
};
/* -------------------------------------------------------------------- */
@@ -70,6 +79,8 @@ class TreeElementRNAProperty : public TreeElementRNACommon {
class TreeElementRNAArrayElement : public TreeElementRNACommon {
public:
TreeElementRNAArrayElement(TreeElement &legacy_te, PointerRNA &rna_ptr, int index);
+
+ PropertyRNA *getPropertyRNA() const override;
};
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_seq.cc b/source/blender/editors/space_outliner/tree/tree_element_seq.cc
new file mode 100644
index 00000000000..8d0b4c140c7
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_seq.cc
@@ -0,0 +1,111 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "DNA_outliner_types.h"
+#include "DNA_sequence_types.h"
+
+#include "BLI_listbase.h"
+
+#include "BLT_translation.h"
+
+#include "../outliner_intern.hh"
+#include "tree_element_seq.hh"
+
+namespace blender::ed::outliner {
+
+TreeElementSequence::TreeElementSequence(TreeElement &legacy_te, Sequence &sequence)
+ : AbstractTreeElement(legacy_te), sequence_(sequence)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_SEQUENCE);
+
+ /*
+ * The idcode is a little hack, but the outliner
+ * only check te->idcode if te->type is equal to zero,
+ * so this is "safe".
+ */
+ legacy_te.idcode = sequence_.type;
+ legacy_te.name = sequence_.name + 2;
+}
+
+bool TreeElementSequence::expandPoll(const SpaceOutliner & /*space_outliner*/) const
+{
+ return !(sequence_.type & SEQ_TYPE_EFFECT);
+}
+
+void TreeElementSequence::expand(SpaceOutliner &space_outliner) const
+{
+ /*
+ * This work like the sequence.
+ * If the sequence have a name (not default name)
+ * show it, in other case put the filename.
+ */
+
+ if (sequence_.type == SEQ_TYPE_META) {
+ LISTBASE_FOREACH (Sequence *, child, &sequence_.seqbase) {
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, child, &legacy_te_, TSE_SEQUENCE, 0);
+ }
+ }
+ else {
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, sequence_.strip, &legacy_te_, TSE_SEQ_STRIP, 0);
+ }
+}
+
+Sequence &TreeElementSequence::getSequence() const
+{
+ return sequence_;
+}
+
+/* -------------------------------------------------------------------- */
+/* Strip */
+
+TreeElementSequenceStrip::TreeElementSequenceStrip(TreeElement &legacy_te, Strip &strip)
+ : AbstractTreeElement(legacy_te)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_SEQ_STRIP);
+
+ if (strip.dir[0] != '\0') {
+ legacy_te_.name = strip.dir;
+ }
+ else {
+ legacy_te_.name = IFACE_("Strip None");
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/* Strip Duplicate */
+
+TreeElementSequenceStripDuplicate::TreeElementSequenceStripDuplicate(TreeElement &legacy_te,
+ Sequence &sequence)
+ : AbstractTreeElement(legacy_te), sequence_(sequence)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_SEQUENCE_DUP);
+
+ legacy_te_.idcode = sequence.type;
+ legacy_te_.name = sequence.strip->stripdata->name;
+}
+
+Sequence &TreeElementSequenceStripDuplicate::getSequence() const
+{
+ return sequence_;
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_seq.hh b/source/blender/editors/space_outliner/tree/tree_element_seq.hh
new file mode 100644
index 00000000000..2b334b5b7fa
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_seq.hh
@@ -0,0 +1,60 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#pragma once
+
+#include "tree_element.hh"
+
+struct Sequence;
+struct Strip;
+
+namespace blender::ed::outliner {
+
+class TreeElementSequence : public AbstractTreeElement {
+ Sequence &sequence_;
+
+ public:
+ TreeElementSequence(TreeElement &legacy_te, Sequence &sequence);
+
+ bool expandPoll(const SpaceOutliner &) const override;
+ void expand(SpaceOutliner &) const override;
+
+ Sequence &getSequence() const;
+};
+
+/* -------------------------------------------------------------------- */
+
+class TreeElementSequenceStrip : public AbstractTreeElement {
+ public:
+ TreeElementSequenceStrip(TreeElement &legacy_te, Strip &strip);
+};
+
+/* -------------------------------------------------------------------- */
+
+class TreeElementSequenceStripDuplicate : public AbstractTreeElement {
+ Sequence &sequence_;
+
+ public:
+ TreeElementSequenceStripDuplicate(TreeElement &legacy_te, Sequence &sequence);
+
+ Sequence &getSequence() const;
+};
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 6e3598703a2..f143730c5cb 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -107,6 +107,8 @@ typedef enum eGPUMaterialFlag {
GPU_MATFLAG_LOOKDEV_HACK = (1 << 30),
} eGPUMaterialFlag;
+ENUM_OPERATORS(eGPUMaterialFlag, GPU_MATFLAG_LOOKDEV_HACK);
+
typedef struct GPUNodeStack {
eGPUType type;
float vec[4];
@@ -173,6 +175,10 @@ bool GPU_stack_link(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out,
...);
+/**
+ * This is a special function to call the "*_eval" function of a BSDF node.
+ * \note This must be call right after GPU_stack_link() so that out[0] contains a valid link.
+ */
bool GPU_stack_eval_link(GPUMaterial *material,
struct bNode *bnode,
const char *name,
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 593a89bbf21..65848620339 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -647,27 +647,25 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
}
va_end(params);
- GPUNodeGraph *graph = gpu_material_node_graph(mat);
BLI_addtail(&graph->nodes, node);
return true;
}
-bool GPU_stack_link(GPUMaterial *material,
- bNode *bnode,
- const char *name,
- GPUNodeStack *in,
- GPUNodeStack *out,
- ...)
+static bool gpu_stack_link_v(GPUMaterial *material,
+ bNode *bnode,
+ const char *name,
+ GPUNodeStack *in,
+ GPUNodeStack *out,
+ va_list params)
{
- GSet *used_libraries = gpu_material_used_libraries(material);
+ GPUNodeGraph *graph = gpu_material_node_graph(material);
GPUNode *node;
GPUFunction *function;
GPUNodeLink *link, **linkptr;
- va_list params;
int i, totin, totout;
- function = gpu_material_library_use_function(used_libraries, name);
+ function = gpu_material_library_use_function(graph->used_libraries, name);
if (!function) {
fprintf(stderr, "GPU failed to find function %s\n", name);
return false;
@@ -695,7 +693,6 @@ bool GPU_stack_link(GPUMaterial *material,
}
}
- va_start(params, out);
for (i = 0; i < function->totparam; i++) {
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
if (totout == 0) {
@@ -721,14 +718,51 @@ bool GPU_stack_link(GPUMaterial *material,
}
}
}
- va_end(params);
- GPUNodeGraph *graph = gpu_material_node_graph(material);
BLI_addtail(&graph->nodes, node);
return true;
}
+bool GPU_stack_link(GPUMaterial *material,
+ bNode *bnode,
+ const char *name,
+ GPUNodeStack *in,
+ GPUNodeStack *out,
+ ...)
+{
+ va_list params;
+ va_start(params, out);
+ bool valid = gpu_stack_link_v(material, bnode, name, in, out, params);
+ va_end(params);
+
+ return valid;
+}
+
+bool GPU_stack_eval_link(GPUMaterial *material,
+ bNode *bnode,
+ const char *name,
+ GPUNodeStack *in,
+ GPUNodeStack *out,
+ ...)
+{
+ /* Save the closure link to replace the one created by the eval function call. Avoiding
+ * dependency to the eval call before the end of the graph. */
+ GPUNodeLink *closure_out = out[0].link;
+
+ va_list params;
+ va_start(params, out);
+ bool valid = gpu_stack_link_v(material, bnode, name, in, out, params);
+ va_end(params);
+
+ /* Save both nodes for graph amendment. */
+ GPU_material_add_closure_eval(material, closure_out, out[0].link);
+ /* Restore original link. */
+ out[0].link = closure_out;
+
+ return valid;
+}
+
GPUNodeLink *GPU_uniformbuf_link_out(GPUMaterial *mat,
bNode *node,
GPUNodeStack *stack,
@@ -790,7 +824,11 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
gpu_node_free(node);
}
- graph->outlink = NULL;
+ BLI_freelistN(&graph->eval_nodes);
+ graph->outlink_surface = NULL;
+ graph->outlink_volume = NULL;
+ graph->outlink_displacement = NULL;
+ graph->outlink_thickness = NULL;
}
void gpu_node_graph_free(GPUNodeGraph *graph)
@@ -805,28 +843,32 @@ void gpu_node_graph_free(GPUNodeGraph *graph)
BLI_freelistN(&graph->textures);
BLI_freelistN(&graph->attributes);
GPU_uniform_attr_list_free(&graph->uniform_attrs);
+
+ if (graph->used_libraries) {
+ BLI_gset_free(graph->used_libraries, NULL);
+ graph->used_libraries = NULL;
+ }
}
/* Prune Unused Nodes */
-static void gpu_nodes_tag(GPUNodeLink *link)
+static void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag)
{
GPUNode *node;
- GPUInput *input;
- if (!link->output) {
+ if (!link || !link->output) {
return;
}
node = link->output->node;
- if (node->tag) {
+ if (node->tag & tag) {
return;
}
- node->tag = true;
- for (input = node->inputs.first; input; input = input->next) {
+ node->tag |= tag;
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
if (input->link) {
- gpu_nodes_tag(input->link);
+ gpu_nodes_tag(input->link, tag);
}
}
}
@@ -834,18 +876,30 @@ static void gpu_nodes_tag(GPUNodeLink *link)
void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
{
LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
- node->tag = false;
+ node->tag = GPU_NODE_TAG_NONE;
}
- gpu_nodes_tag(graph->outlink);
+ gpu_nodes_tag(graph->outlink_surface, GPU_NODE_TAG_SURFACE);
+ gpu_nodes_tag(graph->outlink_volume, GPU_NODE_TAG_VOLUME);
+ gpu_nodes_tag(graph->outlink_displacement, GPU_NODE_TAG_DISPLACEMENT);
+ gpu_nodes_tag(graph->outlink_thickness, GPU_NODE_TAG_THICKNESS);
+
LISTBASE_FOREACH (GPUNodeGraphOutputLink *, aovlink, &graph->outlink_aovs) {
- gpu_nodes_tag(aovlink->outlink);
+ gpu_nodes_tag(aovlink->outlink, GPU_NODE_TAG_AOV);
+ }
+
+ LISTBASE_FOREACH (GPUNodeGraphEvalNode *, node, &graph->eval_nodes) {
+ /* Copy weight node tag to avoid pruning of eval node since they are node connected to
+ * output. */
+ if (node->weight_node->tag != GPU_NODE_TAG_NONE) {
+ node->eval_node->tag = GPU_NODE_TAG_EVAL | node->weight_node->tag;
+ }
}
for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
next = node->next;
- if (!node->tag) {
+ if (node->tag == GPU_NODE_TAG_NONE) {
BLI_remlink(&graph->nodes, node);
gpu_node_free(node);
}
diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
index 40e54ab4394..469085026b3 100644
--- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
@@ -216,10 +216,7 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *UNUSED(subdiv_ccg),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_node.h
* \{ */
-void ntreeGPUMaterialNodes(struct bNodeTree *UNUSED(localtree),
- struct GPUMaterial *UNUSED(mat),
- bool *UNUSED(has_surface_output),
- bool *UNUSED(has_volume_output))
+void ntreeGPUMaterialNodes(struct bNodeTree *UNUSED(localtree), struct GPUMaterial *UNUSED(mat))
{
BLI_assert_unreachable();
}
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 57740ce3ad9..3ebd3ef8a2a 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -160,10 +160,7 @@ struct bNode *ntreeShaderOutputNode(struct bNodeTree *ntree, int target);
/**
* This one needs to work on a local tree.
*/
-void ntreeGPUMaterialNodes(struct bNodeTree *localtree,
- struct GPUMaterial *mat,
- bool *has_surface_output,
- bool *has_volume_output);
+void ntreeGPUMaterialNodes(struct bNodeTree *localtree, struct GPUMaterial *mat);
#ifdef __cplusplus
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index 68b609f8045..81421609dfd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -44,7 +44,9 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PropertySubType::PROP_DISTANCE)
.default_value(0.25f)
.supports_field();
- b.add_input<decl::Bool>(N_("Limit Radius"));
+ b.add_input<decl::Bool>(N_("Limit Radius"))
+ .description(
+ N_("Limit the maximum value of the radius in order to avoid overlapping fillets"));
b.add_output<decl::Geometry>(N_("Curve"));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
index ae282017e0c..c2b9ddfb114 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
@@ -30,7 +30,12 @@ namespace blender::nodes::node_geo_curve_subdivide_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
- b.add_input<decl::Int>(N_("Cuts")).default_value(1).min(0).max(1000).supports_field();
+ b.add_input<decl::Int>(N_("Cuts"))
+ .default_value(1)
+ .min(0)
+ .max(1000)
+ .supports_field()
+ .description(N_("The number of control points to create on the segment following each point"));
b.add_output<decl::Geometry>(N_("Curve"));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_id.cc b/source/blender/nodes/geometry/nodes/node_geo_input_id.cc
index 3fe0588a46d..afe7546f7e5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_id.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_id.cc
@@ -20,7 +20,9 @@ namespace blender::nodes::node_geo_input_id_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
- b.add_output<decl::Int>(N_("ID")).field_source();
+ b.add_output<decl::Int>(N_("ID")).field_source().description(
+ N_("The values from the \"id\" attribute on points, or the index if that attribute does not "
+ "exist"));
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
index ddeb3ded511..43c867e0977 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
@@ -27,7 +27,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("Face Count"))
.field_source()
- .description(N_("Number of faces that contain the edge"));
+ .description(N_("The number of faces that use each edge as one of their sides"));
}
class EdgeNeighborCountFieldInput final : public GeometryFieldInput {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
index 68bb93bbb64..f1777c9ebf5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
@@ -29,8 +29,8 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("Island Index"))
.field_source()
- .description(N_("Island indices are based on the order of the lowest-numbered vertex "
- "contained in each island"));
+ .description(N_("The index of the each vertex's island. Indices are based on the "
+ "lowest vertex index contained in each island"));
b.add_output<decl::Int>(N_("Island Count"))
.field_source()
.description(N_("The total number of mesh islands"));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
index 7d79164634d..c2da065cbfc 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
@@ -27,7 +27,8 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("Vertex Count"))
.field_source()
- .description(N_("Vertex count and edge count are equal"));
+ .description(N_("The number of vertices connected to this vertex with an edge, "
+ "equal to the number of connected edges"));
b.add_output<decl::Int>(N_("Face Count"))
.field_source()
.description(N_("Number of faces that contain the vertex"));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
index 71256a7f781..06f24113308 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
@@ -36,7 +36,8 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(N_("Geometry that is instanced on the points"));
b.add_input<decl::Bool>(N_("Pick Instance"))
.supports_field()
- .description(N_("Place different instances on different points"));
+ .description(N_("Choose instances from the \"Instance\" input at each point instead of "
+ "instancing the entire geometry"));
b.add_input<decl::Int>(N_("Instance Index"))
.implicit_field()
.description(N_(
diff --git a/source/blender/nodes/intern/node_exec.cc b/source/blender/nodes/intern/node_exec.cc
index 4ff662036c3..788d938ca6f 100644
--- a/source/blender/nodes/intern/node_exec.cc
+++ b/source/blender/nodes/intern/node_exec.cc
@@ -35,7 +35,7 @@
#include "node_exec.h"
#include "node_util.h"
-int node_exec_socket_use_stack(bNodeSocket *sock)
+static int node_exec_socket_use_stack(bNodeSocket *sock)
{
/* NOTE: INT supported as FLOAT. Only for EEVEE. */
return ELEM(sock->type, SOCK_INT, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER);
@@ -276,60 +276,3 @@ void ntree_exec_end(bNodeTreeExec *exec)
MEM_freeN(exec);
}
-
-/**** Material/Texture trees ****/
-
-bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
-{
- ListBase *lb = &exec->threadstack[thread];
- bNodeThreadStack *nts;
-
- for (nts = (bNodeThreadStack *)lb->first; nts; nts = nts->next) {
- if (!nts->used) {
- nts->used = true;
- break;
- }
- }
-
- if (!nts) {
- nts = MEM_cnew<bNodeThreadStack>("bNodeThreadStack");
- nts->stack = (bNodeStack *)MEM_dupallocN(exec->stack);
- nts->used = true;
- BLI_addtail(lb, nts);
- }
-
- return nts;
-}
-
-void ntreeReleaseThreadStack(bNodeThreadStack *nts)
-{
- nts->used = false;
-}
-
-bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
-{
- bNodeStack *nsin[MAX_SOCKET] = {nullptr}; /* arbitrary... watch this */
- bNodeStack *nsout[MAX_SOCKET] = {nullptr}; /* arbitrary... watch this */
- bNodeExec *nodeexec;
- bNode *node;
- int n;
-
- /* nodes are presorted, so exec is in order of list */
-
- for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; n++, nodeexec++) {
- node = nodeexec->node;
- if (node->need_exec) {
- node_get_stack(node, nts->stack, nsin, nsout);
- /* Handle muted nodes...
- * If the mute func is not set, assume the node should never be muted,
- * and hence execute it!
- */
- if (node->typeinfo->exec_fn && !(node->flag & NODE_MUTED)) {
- node->typeinfo->exec_fn(callerdata, thread, node, &nodeexec->data, nsin, nsout);
- }
- }
- }
-
- /* signal to that all went OK, for render */
- return true;
-}
diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h
index b2e1c6564b6..115389afd67 100644
--- a/source/blender/nodes/intern/node_exec.h
+++ b/source/blender/nodes/intern/node_exec.h
@@ -71,9 +71,6 @@ typedef struct bNodeThreadStack {
bool used;
} bNodeThreadStack;
-/** Supported socket types in old nodes. */
-int node_exec_socket_use_stack(struct bNodeSocket *sock);
-
/** For a given socket, find the actual stack entry. */
struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock);
void node_get_stack(struct bNode *node,
@@ -86,23 +83,6 @@ struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context,
bNodeInstanceKey parent_key);
void ntree_exec_end(struct bNodeTreeExec *exec);
-struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread);
-void ntreeReleaseThreadStack(struct bNodeThreadStack *nts);
-bool ntreeExecThreadNodes(struct bNodeTreeExec *exec,
- struct bNodeThreadStack *nts,
- void *callerdata,
- int thread);
-
-struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context,
- struct bNodeTree *ntree,
- bNodeInstanceKey parent_key);
-void ntreeShaderEndExecTree_internal(struct bNodeTreeExec *exec);
-
-struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context,
- struct bNodeTree *ntree,
- bNodeInstanceKey parent_key);
-void ntreeTexEndExecTree_internal(struct bNodeTreeExec *exec);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc
index 1cb1ee3163d..8bf4f37a70b 100644
--- a/source/blender/nodes/shader/node_shader_tree.cc
+++ b/source/blender/nodes/shader/node_shader_tree.cc
@@ -262,13 +262,13 @@ static bNodeSocket *ntree_shader_node_find_output(bNode *node, const char *ident
/* Find input socket at a specific position. */
static bNodeSocket *ntree_shader_node_input_get(bNode *node, int n)
{
- return BLI_findlink(&node->inputs, n);
+ return reinterpret_cast<bNodeSocket *>(BLI_findlink(&node->inputs, n));
}
/* Find output socket at a specific position. */
static bNodeSocket *ntree_shader_node_output_get(bNode *node, int n)
{
- return BLI_findlink(&node->outputs, n);
+ return reinterpret_cast<bNodeSocket *>(BLI_findlink(&node->outputs, n));
}
/* Return true on success. */
@@ -940,7 +940,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
int node_count = 1;
nodeChainIterBackwards(ntree, output_node, ntree_weight_tree_tag_nodes, &node_count, 0);
/* Make a mirror copy of the weight tree. */
- bNode **nodes_copy = MEM_mallocN(sizeof(bNode *) * node_count, __func__);
+ bNode **nodes_copy = static_cast<bNode **>(MEM_mallocN(sizeof(bNode *) * node_count, __func__));
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->tmp_flag >= 0) {
int id = node->tmp_flag;
diff --git a/source/blender/nodes/shader/node_shader_util.hh b/source/blender/nodes/shader/node_shader_util.hh
index 5a5b4f613f3..31229c8693b 100644
--- a/source/blender/nodes/shader/node_shader_util.hh
+++ b/source/blender/nodes/shader/node_shader_util.hh
@@ -101,6 +101,11 @@ void node_shader_gpu_tex_mapping(struct GPUMaterial *mat,
struct GPUNodeStack *in,
struct GPUNodeStack *out);
+struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context,
+ struct bNodeTree *ntree,
+ bNodeInstanceKey parent_key);
+void ntreeShaderEndExecTree_internal(struct bNodeTreeExec *exec);
+
void ntreeExecGPUNodes(struct bNodeTreeExec *exec,
struct GPUMaterial *mat,
struct bNode *output_node);
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
index 3f0749ab2af..42f56a0b576 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
@@ -40,6 +40,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
b.add_input<decl::Vector>(N_("Tangent")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -67,13 +68,12 @@ static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat,
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
- return GPU_stack_link(mat,
- node,
- "node_bsdf_anisotropic",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- GPU_constant(&node->ssr_id));
+ GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out);
+
+ GPU_stack_eval_link(
+ mat, node, "node_bsdf_anisotropic_eval", in, out, GPU_constant(&use_multi_scatter));
+
+ return true;
}
} // namespace blender::nodes::node_shader_bsdf_anisotropic_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
index 5848ca76cdd..9767da497ed 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
@@ -30,6 +30,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -45,7 +46,8 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out);
+ GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out);
+ return GPU_stack_eval_link(mat, node, "node_bsdf_diffuse_eval", in, out);
}
} // namespace blender::nodes::node_shader_bsdf_diffuse_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
index 47d4b87198b..fbc35c23734 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
@@ -31,6 +31,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -53,17 +54,30 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat,
GPU_link(mat, "set_value_zero", &in[1].link);
}
- GPU_material_flag_set(mat, (eGPUMatFlag)(GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT));
+ GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT);
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
- return GPU_stack_link(mat,
- node,
- "node_bsdf_glass",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- GPU_constant(&node->ssr_id));
+ GPUNodeLink *reflection_weight;
+ GPUNodeLink *refraction_weight;
+
+ GPU_stack_link(mat,
+ node,
+ "node_bsdf_glass",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ &reflection_weight,
+ &refraction_weight);
+
+ return GPU_stack_eval_link(mat,
+ node,
+ "node_bsdf_glass_eval",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ reflection_weight,
+ refraction_weight);
}
} // namespace blender::nodes::node_shader_bsdf_glass_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
index 03a3e634f56..879e00a6995 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
@@ -30,6 +30,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -56,13 +57,9 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat,
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
- return GPU_stack_link(mat,
- node,
- "node_bsdf_glossy",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- GPU_constant(&node->ssr_id));
+ GPU_stack_link(mat, node, "node_bsdf_glossy", in, out);
+ return GPU_stack_eval_link(
+ mat, node, "node_bsdf_glossy_eval", in, out, GPU_constant(&use_multi_scatter));
}
} // namespace blender::nodes::node_shader_bsdf_glossy_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
index 4c378d9bc09..e49a39b5a4a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
@@ -144,8 +144,6 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- GPUNodeLink *sss_scale;
-
/* Normals */
if (!in[22].link) {
GPU_link(mat, "world_normals_get", &in[22].link);
@@ -161,36 +159,17 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
if (!in[24].link) {
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
GPU_link(mat, "tangent_orco_z", orco, &in[24].link);
- GPU_link(mat,
- "node_tangent",
- GPU_builtin(GPU_WORLD_NORMAL),
- in[24].link,
- GPU_builtin(GPU_OBJECT_MATRIX),
- &in[24].link);
+ GPU_link(mat, "node_tangent", in[24].link, &in[24].link);
}
#endif
bool use_diffuse = socket_not_one(6) && socket_not_one(17);
- bool use_subsurf = socket_not_zero(1) && use_diffuse && node->sss_id > 0;
+ bool use_subsurf = socket_not_zero(1) && use_diffuse;
bool use_refract = socket_not_one(6) && socket_not_zero(17);
- bool use_clear = socket_not_zero(14);
+ bool use_transparency = socket_not_one(21);
+ // bool use_clear = socket_not_zero(14);
- /* SSS Profile */
- if (use_subsurf) {
- bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
- bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
- /* For some reason it seems that the socket value is in ARGB format. */
- GPU_material_sss_profile_create(mat, &socket_data->value[1]);
- }
-
- if (in[2].link) {
- sss_scale = in[2].link;
- }
- else {
- GPU_link(mat, "set_rgb_one", &sss_scale);
- }
-
- uint flag = GPU_MATFLAG_GLOSSY;
+ eGPUMaterialFlag flag = GPU_MATFLAG_GLOSSY;
if (use_diffuse) {
flag |= GPU_MATFLAG_DIFFUSE;
}
@@ -198,28 +177,42 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
flag |= GPU_MATFLAG_REFRACT;
}
if (use_subsurf) {
- flag |= GPU_MATFLAG_SSS;
+ flag |= GPU_MATFLAG_SUBSURFACE;
+ }
+ if (use_transparency) {
+ flag |= GPU_MATFLAG_TRANSPARENT;
}
- float f_use_diffuse = use_diffuse ? 1.0f : 0.0f;
- float f_use_clearcoat = use_clear ? 1.0f : 0.0f;
- float f_use_refraction = use_refract ? 1.0f : 0.0f;
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
- GPU_material_flag_set(mat, (eGPUMatFlag)flag);
-
- return GPU_stack_link(mat,
- node,
- "node_bsdf_principled",
- in,
- out,
- GPU_constant(&f_use_diffuse),
- GPU_constant(&f_use_clearcoat),
- GPU_constant(&f_use_refraction),
- GPU_constant(&use_multi_scatter),
- GPU_constant(&node->ssr_id),
- GPU_constant(&node->sss_id),
- sss_scale);
+ GPU_material_flag_set(mat, flag);
+
+ GPUNodeLink *diffuse_weight, *specular_weight, *glass_reflection_weight,
+ *glass_transmission_weight, *clearcoat_weight;
+
+ GPU_stack_link(mat,
+ node,
+ "node_bsdf_principled",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ &diffuse_weight,
+ &specular_weight,
+ &glass_reflection_weight,
+ &glass_transmission_weight,
+ &clearcoat_weight);
+
+ return GPU_stack_eval_link(mat,
+ node,
+ "node_bsdf_principled_eval",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ diffuse_weight,
+ specular_weight,
+ glass_reflection_weight,
+ glass_transmission_weight,
+ clearcoat_weight);
}
static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
index 0d588c82869..b1320714c70 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
@@ -31,6 +31,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -55,7 +56,8 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT);
- return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out);
+ GPU_stack_link(mat, node, "node_bsdf_refraction", in, out);
+ return GPU_stack_eval_link(mat, node, "node_bsdf_refraction_eval", in, out);
}
} // namespace blender::nodes::node_shader_bsdf_refraction_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
index 5093b896764..4c9ca56eab2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
@@ -38,6 +38,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -58,7 +59,8 @@ static int node_shader_gpu_bsdf_toon(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- return GPU_stack_link(mat, node, "node_bsdf_toon", in, out);
+ GPU_stack_link(mat, node, "node_bsdf_toon", in, out);
+ return GPU_stack_eval_link(mat, node, "node_bsdf_toon_eval", in, out);
}
} // namespace blender::nodes::node_shader_bsdf_toon_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
index 22891738299..ec85b5357fa 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
@@ -25,6 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -40,7 +41,8 @@ static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- return GPU_stack_link(mat, node, "node_bsdf_translucent", in, out);
+ GPU_stack_link(mat, node, "node_bsdf_translucent", in, out);
+ return GPU_stack_eval_link(mat, node, "node_bsdf_translucent_eval", in, out);
}
} // namespace blender::nodes::node_shader_bsdf_translucent_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
index d764f4dd76b..d79f3884a4b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
@@ -33,6 +33,9 @@ static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
+ if (in[0].link || !is_zero_v3(in[0].vec)) {
+ GPU_material_flag_set(mat, GPU_MATFLAG_TRANSPARENT);
+ }
return GPU_stack_link(mat, node, "node_bsdf_transparent", in, out);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
index dd090236c08..7822c2f5961 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
@@ -30,6 +30,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -45,7 +46,8 @@ static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- return GPU_stack_link(mat, node, "node_bsdf_velvet", in, out);
+ GPU_stack_link(mat, node, "node_bsdf_velvet", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_velvet_eval", in, out);
}
} // namespace blender::nodes::node_shader_bsdf_velvet_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
index e4c80725c8e..8db56551236 100644
--- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
@@ -49,6 +49,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Clear Coat Normal")).hide_value();
b.add_input<decl::Float>(N_("Ambient Occlusion")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSDF"));
}
@@ -75,9 +76,10 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat,
GPU_link(mat, "set_value", GPU_constant(&one), &in[9].link);
}
- GPU_material_flag_set(mat, static_cast<eGPUMatFlag>(GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY));
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY);
- return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_constant(&node->ssr_id));
+ GPU_stack_link(mat, node, "node_eevee_specular", in, out);
+ return GPU_stack_eval_link(mat, node, "node_eevee_specular_eval", in, out);
}
} // namespace blender::nodes::node_shader_eevee_specular_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_emission.cc b/source/blender/nodes/shader/nodes/node_shader_emission.cc
index ea36763578f..93dadf8e898 100644
--- a/source/blender/nodes/shader/nodes/node_shader_emission.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_emission.cc
@@ -25,6 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Float>(N_("Strength")).default_value(1.0f).min(0.0f).max(1000000.0f);
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("Emission"));
}
@@ -34,7 +35,8 @@ static int node_shader_gpu_emission(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- return GPU_stack_link(mat, node, "node_emission", in, out, GPU_builtin(GPU_VIEW_NORMAL));
+ GPU_material_flag_set(mat, GPU_MATFLAG_EMISSION);
+ return GPU_stack_link(mat, node, "node_emission", in, out);
}
} // namespace blender::nodes::node_shader_emission_cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.cc b/source/blender/nodes/shader/nodes/node_shader_output_material.cc
index 5fc95b92e3f..e96f55cf3cf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_material.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_output_material.cc
@@ -36,31 +36,24 @@ static int node_shader_gpu_output_material(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- GPUNodeLink *outlink, *alpha_threshold_link, *shadow_threshold_link;
- Material *ma = GPU_material_get_material(mat);
-
- static float no_alpha_threshold = -1.0f;
- if (ma) {
- alpha_threshold_link = GPU_uniform((ma->blend_method == MA_BM_CLIP) ? &ma->alpha_threshold :
- &no_alpha_threshold);
- shadow_threshold_link = GPU_uniform((ma->blend_shadow == MA_BS_CLIP) ? &ma->alpha_threshold :
- &no_alpha_threshold);
+ GPUNodeLink *outlink_surface, *outlink_volume, *outlink_displacement, *outlink_thickness;
+ /* Passthrough node in order to do the right socket conversions (important for displacement). */
+ if (in[0].link) {
+ GPU_link(mat, "node_output_material_surface", in[0].link, &outlink_surface);
+ GPU_material_output_surface(mat, outlink_surface);
}
- else {
- alpha_threshold_link = GPU_uniform(&no_alpha_threshold);
- shadow_threshold_link = GPU_uniform(&no_alpha_threshold);
+ if (in[1].link) {
+ GPU_link(mat, "node_output_material_volume", in[1].link, &outlink_volume);
+ GPU_material_output_volume(mat, outlink_volume);
+ }
+ if (in[2].link) {
+ GPU_link(mat, "node_output_material_displacement", in[2].link, &outlink_displacement);
+ GPU_material_output_displacement(mat, outlink_displacement);
+ }
+ if (in[3].link) {
+ GPU_link(mat, "node_output_material_thickness", in[3].link, &outlink_thickness);
+ GPU_material_output_thickness(mat, outlink_thickness);
}
-
- GPU_stack_link(mat,
- node,
- "node_output_material",
- in,
- out,
- alpha_threshold_link,
- shadow_threshold_link,
- &outlink);
- GPU_material_output_link(mat, outlink);
-
return true;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
index f60db81b4a9..a3e03d00a1f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
@@ -41,6 +41,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(N_("BSSRDF"));
}
@@ -65,19 +66,9 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
GPU_link(mat, "world_normals_get", &in[5].link);
}
- if (node->sss_id > 0) {
- bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
- bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
- /* For some reason it seems that the socket value is in ARGB format. */
- GPU_material_sss_profile_create(mat, &socket_data->value[1]);
-
- /* sss_id is 0 only the node is not connected to any output.
- * In this case flagging the material would trigger a bug (see T68736). */
- GPU_material_flag_set(mat, (eGPUMatFlag)(GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS));
- }
-
- return GPU_stack_link(
- mat, node, "node_subsurface_scattering", in, out, GPU_constant(&node->sss_id));
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SUBSURFACE);
+ GPU_stack_link(mat, node, "node_subsurface_scattering", in, out);
+ return GPU_stack_eval_link(mat, node, "node_subsurface_scattering_eval", in, out);
}
static void node_shader_update_subsurface_scattering(bNodeTree *ntree, bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
index 1bbaed88ea5..d81316b0f8b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
@@ -51,24 +51,22 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
{
Object *ob = (Object *)node->id;
- GPUNodeLink *inv_obmat = (ob != nullptr) ? GPU_uniform(&ob->imat[0][0]) :
- GPU_builtin(GPU_INVERSE_OBJECT_MATRIX);
+ /* Use special matrix to let the shader branch to using the render object's matrix. */
+ float dummy_matrix[4][4];
+ dummy_matrix[3][3] = 0.0f;
+ GPUNodeLink *inv_obmat = (ob != NULL) ? GPU_uniform(&ob->imat[0][0]) :
+ GPU_uniform(&dummy_matrix[0][0]);
/* Opti: don't request orco if not needed. */
- const float default_coords[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant(default_coords) :
- GPU_attribute(mat, CD_ORCO, "");
+ float4 zero(0.0f);
+ GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant(zero) : GPU_attribute(mat, CD_ORCO, "");
GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, "");
- GPUNodeLink *viewpos = GPU_builtin(GPU_VIEW_POSITION);
- GPUNodeLink *worldnor = GPU_builtin(GPU_WORLD_NORMAL);
- GPUNodeLink *texcofacs = GPU_builtin(GPU_CAMERA_TEXCO_FACTORS);
if (out[0].hasoutput) {
GPU_link(mat, "generated_from_orco", orco, &orco);
}
- GPU_stack_link(
- mat, node, "node_tex_coord", in, out, viewpos, worldnor, inv_obmat, texcofacs, orco, mtface);
+ GPU_stack_link(mat, node, "node_tex_coord", in, out, inv_obmat, orco, mtface);
int i;
LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &node->outputs, i) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc b/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
index a8a6902e30c..e38f67fb751 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
@@ -59,42 +59,43 @@ static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *nod
node->storage = vect;
}
-static GPUNodeLink *get_gpulink_matrix_from_to(short from, short to)
+static const char *get_gpufn_name_from_to(short from, short to)
{
switch (from) {
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
switch (to) {
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
- return nullptr;
+ return NULL;
case SHD_VECT_TRANSFORM_SPACE_WORLD:
- return GPU_builtin(GPU_OBJECT_MATRIX);
+ return "object_to_world";
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
- return GPU_builtin(GPU_LOC_TO_VIEW_MATRIX);
+ return "object_to_view";
}
break;
case SHD_VECT_TRANSFORM_SPACE_WORLD:
switch (to) {
case SHD_VECT_TRANSFORM_SPACE_WORLD:
- return nullptr;
+ return NULL;
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
- return GPU_builtin(GPU_VIEW_MATRIX);
+ return "world_to_view";
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
- return GPU_builtin(GPU_INVERSE_OBJECT_MATRIX);
+ return "world_to_object";
}
break;
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
switch (to) {
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
- return nullptr;
+ return NULL;
case SHD_VECT_TRANSFORM_SPACE_WORLD:
- return GPU_builtin(GPU_INVERSE_VIEW_MATRIX);
+ return "view_to_world";
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
- return GPU_builtin(GPU_INVERSE_LOC_TO_VIEW_MATRIX);
+ return "view_to_object";
}
break;
}
- return nullptr;
+ return NULL;
}
+
static int gpu_shader_vect_transform(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
@@ -102,11 +103,6 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
GPUNodeStack *out)
{
struct GPUNodeLink *inputlink;
- struct GPUNodeLink *fromto;
-
- const char *vtransform = "direction_transform_m4v3";
- const char *ptransform = "point_transform_m4v3";
- const char *func_name = nullptr;
NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage;
@@ -117,9 +113,10 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
inputlink = GPU_constant(in[0].vec);
}
- fromto = get_gpulink_matrix_from_to(nodeprop->convert_from, nodeprop->convert_to);
+ const char *xform = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? "point_transform_" :
+ "direction_transform_";
+ const char *fromto = get_gpufn_name_from_to(nodeprop->convert_from, nodeprop->convert_to);
- func_name = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? ptransform : vtransform;
if (fromto) {
/* For cycles we have inverted Z */
/* TODO: pass here the correct matrices */
@@ -127,7 +124,11 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
nodeprop->convert_to != SHD_VECT_TRANSFORM_SPACE_CAMERA) {
GPU_link(mat, "invert_z", inputlink, &inputlink);
}
- GPU_link(mat, func_name, inputlink, fromto, &out[0].link);
+
+ char func_name[48];
+ SNPRINTF(func_name, "%s%s", xform, fromto);
+ GPU_link(mat, func_name, inputlink, &out[0].link);
+
if (nodeprop->convert_to == SHD_VECT_TRANSFORM_SPACE_CAMERA &&
nodeprop->convert_from != SHD_VECT_TRANSFORM_SPACE_CAMERA) {
GPU_link(mat, "invert_z", out[0].link, &out[0].link);
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 3d914d486c3..82ed43be779 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -170,6 +170,63 @@ void register_node_tree_type_tex(void)
ntreeTypeAdd(tt);
}
+/**** Material/Texture trees ****/
+
+bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
+{
+ ListBase *lb = &exec->threadstack[thread];
+ bNodeThreadStack *nts;
+
+ for (nts = (bNodeThreadStack *)lb->first; nts; nts = nts->next) {
+ if (!nts->used) {
+ nts->used = true;
+ break;
+ }
+ }
+
+ if (!nts) {
+ nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
+ nts->stack = (bNodeStack *)MEM_dupallocN(exec->stack);
+ nts->used = true;
+ BLI_addtail(lb, nts);
+ }
+
+ return nts;
+}
+
+void ntreeReleaseThreadStack(bNodeThreadStack *nts)
+{
+ nts->used = false;
+}
+
+bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
+{
+ bNodeStack *nsin[MAX_SOCKET] = {NULL}; /* arbitrary... watch this */
+ bNodeStack *nsout[MAX_SOCKET] = {NULL}; /* arbitrary... watch this */
+ bNodeExec *nodeexec;
+ bNode *node;
+ int n;
+
+ /* nodes are presorted, so exec is in order of list */
+
+ for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; n++, nodeexec++) {
+ node = nodeexec->node;
+ if (node->need_exec) {
+ node_get_stack(node, nts->stack, nsin, nsout);
+ /* Handle muted nodes...
+ * If the mute func is not set, assume the node should never be muted,
+ * and hence execute it!
+ */
+ if (node->typeinfo->exec_fn && !(node->flag & NODE_MUTED)) {
+ node->typeinfo->exec_fn(callerdata, thread, node, &nodeexec->data, nsin, nsout);
+ }
+ }
+ }
+
+ /* signal to that all went OK, for render */
+ return true;
+}
+
bNodeTreeExec *ntreeTexBeginExecTree_internal(bNodeExecContext *context,
bNodeTree *ntree,
bNodeInstanceKey parent_key)
diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h
index d53000058a3..7c8e39925bc 100644
--- a/source/blender/nodes/texture/node_texture_util.h
+++ b/source/blender/nodes/texture/node_texture_util.h
@@ -123,6 +123,18 @@ void tex_output(bNode *node,
void params_from_cdata(TexParams *out, TexCallData *in);
+struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread);
+void ntreeReleaseThreadStack(struct bNodeThreadStack *nts);
+bool ntreeExecThreadNodes(struct bNodeTreeExec *exec,
+ struct bNodeThreadStack *nts,
+ void *callerdata,
+ int thread);
+
+struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context,
+ struct bNodeTree *ntree,
+ bNodeInstanceKey parent_key);
+void ntreeTexEndExecTree_internal(struct bNodeTreeExec *exec);
+
#ifdef __cplusplus
}
#endif