2023-06-14 16:52:36 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "scene/shader.h"
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "scene/background.h"
|
|
|
|
|
#include "scene/integrator.h"
|
|
|
|
|
#include "scene/light.h"
|
|
|
|
|
#include "scene/osl.h"
|
|
|
|
|
#include "scene/scene.h"
|
|
|
|
|
#include "scene/shader_graph.h"
|
|
|
|
|
#include "scene/shader_nodes.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "blender/image.h"
|
|
|
|
|
#include "blender/sync.h"
|
|
|
|
|
#include "blender/texture.h"
|
|
|
|
|
#include "blender/util.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "util/set.h"
|
|
|
|
|
#include "util/string.h"
|
|
|
|
|
#include "util/task.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2024-02-14 10:51:40 -05:00
|
|
|
#include "BKE_duplilist.hh"
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
using PtrInputMap = unordered_multimap<void *, ShaderInput *>;
|
|
|
|
|
using PtrOutputMap = map<void *, ShaderOutput *>;
|
|
|
|
|
using ProxyMap = map<string, ConvertNode *>;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
|
/* Find */
|
|
|
|
|
|
2025-02-24 23:44:14 +01:00
|
|
|
void BlenderSync::find_shader(const BL::ID &id,
|
|
|
|
|
array<Node *> &used_shaders,
|
|
|
|
|
Shader *default_shader)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2022-02-17 17:21:06 +01:00
|
|
|
Shader *synced_shader = (id) ? shader_map.find(id) : nullptr;
|
|
|
|
|
Shader *shader = (synced_shader) ? synced_shader : default_shader;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
used_shaders.push_back_slow(shader);
|
2016-05-14 14:50:03 +02:00
|
|
|
shader->tag_used(scene);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-02-10 15:09:45 +01:00
|
|
|
/* RNA translation utilities */
|
|
|
|
|
|
|
|
|
|
static VolumeSampling get_volume_sampling(PointerRNA &ptr)
|
|
|
|
|
{
|
|
|
|
|
return (VolumeSampling)get_enum(
|
|
|
|
|
ptr, "volume_sampling", VOLUME_NUM_SAMPLING, VOLUME_SAMPLING_DISTANCE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static VolumeInterpolation get_volume_interpolation(PointerRNA &ptr)
|
|
|
|
|
{
|
|
|
|
|
return (VolumeInterpolation)get_enum(
|
|
|
|
|
ptr, "volume_interpolation", VOLUME_NUM_INTERPOLATION, VOLUME_INTERPOLATION_LINEAR);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
static EmissionSampling get_emission_sampling(PointerRNA &ptr)
|
|
|
|
|
{
|
|
|
|
|
return (EmissionSampling)get_enum(
|
|
|
|
|
ptr, "emission_sampling", EMISSION_SAMPLING_NUM, EMISSION_SAMPLING_AUTO);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static int validate_enum_value(const int value, const int num_values, const int default_value)
|
2016-02-10 15:09:45 +01:00
|
|
|
{
|
|
|
|
|
if (value >= num_values) {
|
|
|
|
|
return default_value;
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-21 19:55:38 +01:00
|
|
|
static DisplacementMethod get_displacement_method(BL::Material &b_mat)
|
|
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const int value = b_mat.displacement_method();
|
2023-11-21 19:55:38 +01:00
|
|
|
return (DisplacementMethod)validate_enum_value(value, DISPLACE_NUM_METHODS, DISPLACE_BUMP);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-16 15:32:26 +01:00
|
|
|
template<typename NodeType> static InterpolationType get_image_interpolation(NodeType &b_node)
|
2016-02-10 15:09:45 +01:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const int value = b_node.interpolation();
|
2016-02-10 15:09:45 +01:00
|
|
|
return (InterpolationType)validate_enum_value(
|
|
|
|
|
value, INTERPOLATION_NUM_TYPES, INTERPOLATION_LINEAR);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-16 15:32:26 +01:00
|
|
|
template<typename NodeType> static ExtensionType get_image_extension(NodeType &b_node)
|
2016-02-10 15:09:45 +01:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const int value = b_node.extension();
|
2016-02-10 15:09:45 +01:00
|
|
|
return (ExtensionType)validate_enum_value(value, EXTENSION_NUM_TYPES, EXTENSION_REPEAT);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-18 20:52:20 +02:00
|
|
|
static ImageAlphaType get_image_alpha_type(BL::Image &b_image)
|
|
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const int value = b_image.alpha_mode();
|
2019-05-18 20:52:20 +02:00
|
|
|
return (ImageAlphaType)validate_enum_value(value, IMAGE_ALPHA_NUM_TYPES, IMAGE_ALPHA_AUTO);
|
|
|
|
|
}
|
|
|
|
|
|
Materials: add custom object properties as uniform attributes.
This patch allows the user to type a property name into the
Attribute node, which will then output the value of the property
for each individual object, allowing to e.g. customize shaders
by object without duplicating the shader.
In order to make supporting this easier for Eevee, it is necessary
to explicitly choose whether the attribute is varying or uniform
via a dropdown option of the Attribute node. The dropdown also
allows choosing whether instancing should be taken into account.
The Cycles design treats all attributes as one common namespace,
so the Blender interface converts the enum to a name prefix that
can't be entered using keyboard.
In Eevee, the attributes are provided to the shader via a UBO indexed
with resource_id, similar to the existing Object Info data. Unlike it,
however, it is necessary to maintain a separate buffer for every
requested combination of attributes.
This is done using a hash table with the attribute set as the key,
as it is expected that technically different but similar materials
may use the same set of attributes. In addition, in order to minimize
wasted memory, a sparse UBO pool is implemented, so that chunks that
don't contain any data don't have to be allocated.
The back-end Cycles code is already refactored and committed by Brecht.
Differential Revision: https://developer.blender.org/D2057
2020-08-05 19:14:40 +03:00
|
|
|
/* Attribute name translation utilities */
|
|
|
|
|
|
|
|
|
|
/* Since Eevee needs to know whether the attribute is uniform or varying
|
|
|
|
|
* at the time it compiles the shader for the material, Blender had to
|
|
|
|
|
* introduce different namespaces (types) in its attribute node. However,
|
|
|
|
|
* Cycles already has object attributes that form a uniform namespace with
|
|
|
|
|
* the more common varying attributes. Without completely reworking the
|
|
|
|
|
* attribute handling in Cycles to introduce separate namespaces (this could
|
|
|
|
|
* be especially hard for OSL which directly uses the name string), the
|
|
|
|
|
* space identifier has to be added to the attribute name as a prefix.
|
|
|
|
|
*
|
|
|
|
|
* The prefixes include a control character to ensure the user specified
|
|
|
|
|
* name can't accidentally include a special prefix.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static const string_view object_attr_prefix("\x01object:");
|
|
|
|
|
static const string_view instancer_attr_prefix("\x01instancer:");
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
static const string_view view_layer_attr_prefix("\x01layer:");
|
Materials: add custom object properties as uniform attributes.
This patch allows the user to type a property name into the
Attribute node, which will then output the value of the property
for each individual object, allowing to e.g. customize shaders
by object without duplicating the shader.
In order to make supporting this easier for Eevee, it is necessary
to explicitly choose whether the attribute is varying or uniform
via a dropdown option of the Attribute node. The dropdown also
allows choosing whether instancing should be taken into account.
The Cycles design treats all attributes as one common namespace,
so the Blender interface converts the enum to a name prefix that
can't be entered using keyboard.
In Eevee, the attributes are provided to the shader via a UBO indexed
with resource_id, similar to the existing Object Info data. Unlike it,
however, it is necessary to maintain a separate buffer for every
requested combination of attributes.
This is done using a hash table with the attribute set as the key,
as it is expected that technically different but similar materials
may use the same set of attributes. In addition, in order to minimize
wasted memory, a sparse UBO pool is implemented, so that chunks that
don't contain any data don't have to be allocated.
The back-end Cycles code is already refactored and committed by Brecht.
Differential Revision: https://developer.blender.org/D2057
2020-08-05 19:14:40 +03:00
|
|
|
|
|
|
|
|
static ustring blender_attribute_name_add_type(const string &name, BlenderAttributeType type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case BL::ShaderNodeAttribute::attribute_type_OBJECT:
|
|
|
|
|
return ustring::concat(object_attr_prefix, name);
|
|
|
|
|
case BL::ShaderNodeAttribute::attribute_type_INSTANCER:
|
|
|
|
|
return ustring::concat(instancer_attr_prefix, name);
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
case BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER:
|
|
|
|
|
return ustring::concat(view_layer_attr_prefix, name);
|
Materials: add custom object properties as uniform attributes.
This patch allows the user to type a property name into the
Attribute node, which will then output the value of the property
for each individual object, allowing to e.g. customize shaders
by object without duplicating the shader.
In order to make supporting this easier for Eevee, it is necessary
to explicitly choose whether the attribute is varying or uniform
via a dropdown option of the Attribute node. The dropdown also
allows choosing whether instancing should be taken into account.
The Cycles design treats all attributes as one common namespace,
so the Blender interface converts the enum to a name prefix that
can't be entered using keyboard.
In Eevee, the attributes are provided to the shader via a UBO indexed
with resource_id, similar to the existing Object Info data. Unlike it,
however, it is necessary to maintain a separate buffer for every
requested combination of attributes.
This is done using a hash table with the attribute set as the key,
as it is expected that technically different but similar materials
may use the same set of attributes. In addition, in order to minimize
wasted memory, a sparse UBO pool is implemented, so that chunks that
don't contain any data don't have to be allocated.
The back-end Cycles code is already refactored and committed by Brecht.
Differential Revision: https://developer.blender.org/D2057
2020-08-05 19:14:40 +03:00
|
|
|
default:
|
|
|
|
|
return ustring(name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name)
|
|
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const string_view sname(name);
|
Materials: add custom object properties as uniform attributes.
This patch allows the user to type a property name into the
Attribute node, which will then output the value of the property
for each individual object, allowing to e.g. customize shaders
by object without duplicating the shader.
In order to make supporting this easier for Eevee, it is necessary
to explicitly choose whether the attribute is varying or uniform
via a dropdown option of the Attribute node. The dropdown also
allows choosing whether instancing should be taken into account.
The Cycles design treats all attributes as one common namespace,
so the Blender interface converts the enum to a name prefix that
can't be entered using keyboard.
In Eevee, the attributes are provided to the shader via a UBO indexed
with resource_id, similar to the existing Object Info data. Unlike it,
however, it is necessary to maintain a separate buffer for every
requested combination of attributes.
This is done using a hash table with the attribute set as the key,
as it is expected that technically different but similar materials
may use the same set of attributes. In addition, in order to minimize
wasted memory, a sparse UBO pool is implemented, so that chunks that
don't contain any data don't have to be allocated.
The back-end Cycles code is already refactored and committed by Brecht.
Differential Revision: https://developer.blender.org/D2057
2020-08-05 19:14:40 +03:00
|
|
|
|
|
|
|
|
if (sname.substr(0, object_attr_prefix.size()) == object_attr_prefix) {
|
|
|
|
|
*r_real_name = sname.substr(object_attr_prefix.size());
|
|
|
|
|
return BL::ShaderNodeAttribute::attribute_type_OBJECT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sname.substr(0, instancer_attr_prefix.size()) == instancer_attr_prefix) {
|
|
|
|
|
*r_real_name = sname.substr(instancer_attr_prefix.size());
|
|
|
|
|
return BL::ShaderNodeAttribute::attribute_type_INSTANCER;
|
|
|
|
|
}
|
|
|
|
|
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
if (sname.substr(0, view_layer_attr_prefix.size()) == view_layer_attr_prefix) {
|
|
|
|
|
*r_real_name = sname.substr(view_layer_attr_prefix.size());
|
|
|
|
|
return BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER;
|
|
|
|
|
}
|
|
|
|
|
|
Materials: add custom object properties as uniform attributes.
This patch allows the user to type a property name into the
Attribute node, which will then output the value of the property
for each individual object, allowing to e.g. customize shaders
by object without duplicating the shader.
In order to make supporting this easier for Eevee, it is necessary
to explicitly choose whether the attribute is varying or uniform
via a dropdown option of the Attribute node. The dropdown also
allows choosing whether instancing should be taken into account.
The Cycles design treats all attributes as one common namespace,
so the Blender interface converts the enum to a name prefix that
can't be entered using keyboard.
In Eevee, the attributes are provided to the shader via a UBO indexed
with resource_id, similar to the existing Object Info data. Unlike it,
however, it is necessary to maintain a separate buffer for every
requested combination of attributes.
This is done using a hash table with the attribute set as the key,
as it is expected that technically different but similar materials
may use the same set of attributes. In addition, in order to minimize
wasted memory, a sparse UBO pool is implemented, so that chunks that
don't contain any data don't have to be allocated.
The back-end Cycles code is already refactored and committed by Brecht.
Differential Revision: https://developer.blender.org/D2057
2020-08-05 19:14:40 +03:00
|
|
|
return BL::ShaderNodeAttribute::attribute_type_GEOMETRY;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Graph */
|
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_out : b_node.outputs) {
|
2021-08-11 15:42:36 +02:00
|
|
|
if (b_out.identifier() == name) {
|
2021-01-25 16:20:10 +01:00
|
|
|
return b_out;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
assert(0);
|
2021-01-25 16:20:10 +01:00
|
|
|
return *b_node.outputs.begin();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::NodeSocket b_sock = get_node_output(b_node, name);
|
|
|
|
|
float value[4];
|
|
|
|
|
RNA_float_get_array(&b_sock.ptr, "default_value", value);
|
|
|
|
|
return make_float3(value[0], value[1], value[2]);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static float get_node_output_value(BL::Node &b_node, const string &name)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::NodeSocket b_sock = get_node_output(b_node, name);
|
|
|
|
|
return RNA_float_get(&b_sock.ptr, "default_value");
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static float3 get_node_output_vector(BL::Node &b_node, const string &name)
|
2012-06-12 07:27:50 +00:00
|
|
|
{
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::NodeSocket b_sock = get_node_output(b_node, name);
|
|
|
|
|
float value[3];
|
|
|
|
|
RNA_float_get_array(&b_sock.ptr, "default_value", value);
|
|
|
|
|
return make_float3(value[0], value[1], value[2]);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-08 01:32:09 +02:00
|
|
|
static SocketType::Type convert_socket_type(BL::NodeSocket &b_socket)
|
2013-03-18 16:34:57 +00:00
|
|
|
{
|
2015-10-08 19:08:28 +05:00
|
|
|
switch (b_socket.type()) {
|
2013-03-18 16:34:57 +00:00
|
|
|
case BL::NodeSocket::type_VALUE:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::FLOAT;
|
2023-10-05 21:55:10 +02:00
|
|
|
case BL::NodeSocket::type_BOOLEAN:
|
2013-03-18 16:34:57 +00:00
|
|
|
case BL::NodeSocket::type_INT:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::INT;
|
2013-03-18 16:34:57 +00:00
|
|
|
case BL::NodeSocket::type_VECTOR:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::VECTOR;
|
2013-03-18 16:34:57 +00:00
|
|
|
case BL::NodeSocket::type_RGBA:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::COLOR;
|
2013-03-18 16:34:57 +00:00
|
|
|
case BL::NodeSocket::type_STRING:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::STRING;
|
2013-03-18 16:34:57 +00:00
|
|
|
case BL::NodeSocket::type_SHADER:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::CLOSURE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
default:
|
2016-05-08 01:32:09 +02:00
|
|
|
return SocketType::UNDEFINED;
|
2012-06-12 07:27:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static void set_default_value(ShaderInput *input,
|
|
|
|
|
BL::NodeSocket &b_sock,
|
|
|
|
|
BL::BlendData &b_data,
|
|
|
|
|
BL::ID &b_id)
|
2012-06-12 07:27:50 +00:00
|
|
|
{
|
2016-05-07 19:48:28 +02:00
|
|
|
Node *node = input->parent;
|
|
|
|
|
const SocketType &socket = input->socket_type;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-12 07:27:50 +00:00
|
|
|
/* copy values for non linked inputs */
|
2016-05-08 01:32:09 +02:00
|
|
|
switch (input->type()) {
|
|
|
|
|
case SocketType::FLOAT: {
|
2016-05-07 19:48:28 +02:00
|
|
|
node->set(socket, get_float(b_sock.ptr, "default_value"));
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2016-05-08 01:32:09 +02:00
|
|
|
case SocketType::INT: {
|
2021-08-11 15:42:36 +02:00
|
|
|
if (b_sock.type() == BL::NodeSocket::type_BOOLEAN) {
|
2022-10-10 01:03:12 +02:00
|
|
|
/* Make sure to call the int overload of set() since this is an integer socket as far as
|
|
|
|
|
* Cycles is concerned. */
|
|
|
|
|
node->set(socket, get_boolean(b_sock.ptr, "default_value") ? 1 : 0);
|
2021-08-11 15:42:36 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
node->set(socket, get_int(b_sock.ptr, "default_value"));
|
|
|
|
|
}
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2016-05-08 01:32:09 +02:00
|
|
|
case SocketType::COLOR: {
|
2024-12-19 09:41:55 +01:00
|
|
|
node->set(socket, make_float3(get_float4(b_sock.ptr, "default_value")));
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2016-05-08 01:32:09 +02:00
|
|
|
case SocketType::NORMAL:
|
|
|
|
|
case SocketType::POINT:
|
|
|
|
|
case SocketType::VECTOR: {
|
2016-05-07 19:48:28 +02:00
|
|
|
node->set(socket, get_float3(b_sock.ptr, "default_value"));
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2016-05-08 01:32:09 +02:00
|
|
|
case SocketType::STRING: {
|
2016-05-07 19:48:28 +02:00
|
|
|
node->set(
|
|
|
|
|
socket,
|
|
|
|
|
(ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2016-05-08 01:32:09 +02:00
|
|
|
default:
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
2012-06-12 07:27:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping)
|
2011-11-04 20:58:00 +00:00
|
|
|
{
|
2023-09-17 09:01:48 +10:00
|
|
|
if (!b_mapping) {
|
2011-11-21 16:28:19 +00:00
|
|
|
return;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2011-11-21 16:28:19 +00:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
mapping->set_tex_mapping_translation(get_float3(b_mapping.translation()));
|
|
|
|
|
mapping->set_tex_mapping_rotation(get_float3(b_mapping.rotation()));
|
|
|
|
|
mapping->set_tex_mapping_scale(get_float3(b_mapping.scale()));
|
|
|
|
|
mapping->set_tex_mapping_type((TextureMapping::Type)b_mapping.vector_type());
|
2011-11-04 20:58:00 +00:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
mapping->set_tex_mapping_x_mapping((TextureMapping::Mapping)b_mapping.mapping_x());
|
|
|
|
|
mapping->set_tex_mapping_y_mapping((TextureMapping::Mapping)b_mapping.mapping_y());
|
|
|
|
|
mapping->set_tex_mapping_z_mapping((TextureMapping::Mapping)b_mapping.mapping_z());
|
2011-11-04 20:58:00 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-15 19:27:46 +02:00
|
|
|
static bool is_image_animated(BL::Image::source_enum b_image_source, BL::ImageUser &b_image_user)
|
|
|
|
|
{
|
|
|
|
|
return (b_image_source == BL::Image::source_MOVIE ||
|
|
|
|
|
b_image_source == BL::Image::source_SEQUENCE) &&
|
|
|
|
|
b_image_user.use_auto_refresh();
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
static ShaderNode *add_node(Scene *scene,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::RenderEngine &b_engine,
|
|
|
|
|
BL::BlendData &b_data,
|
2018-02-28 13:54:00 -03:00
|
|
|
BL::Depsgraph &b_depsgraph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::Scene &b_scene,
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
ShaderGraph *graph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::ShaderNodeTree &b_ntree,
|
|
|
|
|
BL::ShaderNode &b_node)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2024-12-26 17:53:55 +01:00
|
|
|
ShaderNode *node = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
/* existing blender nodes */
|
2015-03-28 00:15:15 +05:00
|
|
|
if (b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeRGBCurve b_curve_node(b_node);
|
2015-12-04 20:17:25 +05:00
|
|
|
BL::CurveMapping mapping(b_curve_node.mapping());
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
RGBCurvesNode *curves = graph->create_node<RGBCurvesNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
array<float3> curve_mapping_curves;
|
2024-12-29 17:32:00 +01:00
|
|
|
float min_x;
|
|
|
|
|
float max_x;
|
2020-11-04 11:17:38 +01:00
|
|
|
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true);
|
2021-09-30 19:05:08 +01:00
|
|
|
curvemapping_minmax(mapping, 4, &min_x, &max_x);
|
2020-11-04 11:17:38 +01:00
|
|
|
curves->set_min_x(min_x);
|
|
|
|
|
curves->set_max_x(max_x);
|
|
|
|
|
curves->set_curves(curve_mapping_curves);
|
2024-12-26 17:53:59 +01:00
|
|
|
curves->set_extrapolate(mapping.extend() == BL::CurveMapping::extend_EXTRAPOLATED);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = curves;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeVectorCurve b_curve_node(b_node);
|
2015-12-15 16:23:33 +05:00
|
|
|
BL::CurveMapping mapping(b_curve_node.mapping());
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VectorCurvesNode *curves = graph->create_node<VectorCurvesNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
array<float3> curve_mapping_curves;
|
2024-12-29 17:32:00 +01:00
|
|
|
float min_x;
|
|
|
|
|
float max_x;
|
2020-11-04 11:17:38 +01:00
|
|
|
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false);
|
2021-09-30 19:05:08 +01:00
|
|
|
curvemapping_minmax(mapping, 3, &min_x, &max_x);
|
2020-11-04 11:17:38 +01:00
|
|
|
curves->set_min_x(min_x);
|
|
|
|
|
curves->set_max_x(max_x);
|
|
|
|
|
curves->set_curves(curve_mapping_curves);
|
2024-12-26 17:53:59 +01:00
|
|
|
curves->set_extrapolate(mapping.extend() == BL::CurveMapping::extend_EXTRAPOLATED);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = curves;
|
|
|
|
|
}
|
2021-09-30 19:05:08 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
|
|
|
|
|
BL::ShaderNodeFloatCurve b_curve_node(b_node);
|
|
|
|
|
BL::CurveMapping mapping(b_curve_node.mapping());
|
|
|
|
|
FloatCurveNode *curve = graph->create_node<FloatCurveNode>();
|
|
|
|
|
array<float> curve_mapping_curve;
|
2024-12-29 17:32:00 +01:00
|
|
|
float min_x;
|
|
|
|
|
float max_x;
|
2021-09-30 19:05:08 +01:00
|
|
|
curvemapping_float_to_array(mapping, curve_mapping_curve, RAMP_TABLE_SIZE);
|
|
|
|
|
curvemapping_minmax(mapping, 1, &min_x, &max_x);
|
|
|
|
|
curve->set_min_x(min_x);
|
|
|
|
|
curve->set_max_x(max_x);
|
|
|
|
|
curve->set_curve(curve_mapping_curve);
|
2024-12-26 17:53:59 +01:00
|
|
|
curve->set_extrapolate(mapping.extend() == BL::CurveMapping::extend_EXTRAPOLATED);
|
2021-09-30 19:05:08 +01:00
|
|
|
node = curve;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
RGBRampNode *ramp = graph->create_node<RGBRampNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeValToRGB b_ramp_node(b_node);
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
|
2020-11-04 11:17:38 +01:00
|
|
|
array<float3> ramp_values;
|
|
|
|
|
array<float> ramp_alpha;
|
|
|
|
|
colorramp_to_array(b_color_ramp, ramp_values, ramp_alpha, RAMP_TABLE_SIZE);
|
|
|
|
|
ramp->set_ramp(ramp_values);
|
|
|
|
|
ramp->set_ramp_alpha(ramp_alpha);
|
|
|
|
|
ramp->set_interpolate(b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = ramp;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeRGB)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ColorNode *color = graph->create_node<ColorNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
color->set_value(get_node_output_rgba(b_node, "Color"));
|
2013-03-18 16:34:57 +00:00
|
|
|
node = color;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeValue)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ValueNode *value = graph->create_node<ValueNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
value->set_value(get_node_output_value(b_node, "Value"));
|
2013-03-18 16:34:57 +00:00
|
|
|
node = value;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeCameraData)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<CameraNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeInvert)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<InvertNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeGamma)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<GammaNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<BrightContrastNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeMixRGB b_mix_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MixNode *mix = graph->create_node<MixNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
mix->set_mix_type((NodeMix)b_mix_node.blend_type());
|
|
|
|
|
mix->set_use_clamp(b_mix_node.use_clamp());
|
2013-03-18 16:34:57 +00:00
|
|
|
node = mix;
|
|
|
|
|
}
|
2022-08-30 11:05:46 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeMix)) {
|
|
|
|
|
BL::ShaderNodeMix b_mix_node(b_node);
|
|
|
|
|
if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_VECTOR) {
|
|
|
|
|
if (b_mix_node.factor_mode() == BL::ShaderNodeMix::factor_mode_UNIFORM) {
|
|
|
|
|
MixVectorNode *mix_node = graph->create_node<MixVectorNode>();
|
|
|
|
|
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
|
|
|
|
node = mix_node;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MixVectorNonUniformNode *mix_node = graph->create_node<MixVectorNonUniformNode>();
|
|
|
|
|
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
|
|
|
|
node = mix_node;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_RGBA) {
|
|
|
|
|
MixColorNode *mix_node = graph->create_node<MixColorNode>();
|
|
|
|
|
mix_node->set_blend_type((NodeMix)b_mix_node.blend_type());
|
|
|
|
|
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
|
|
|
|
mix_node->set_use_clamp_result(b_mix_node.clamp_result());
|
|
|
|
|
node = mix_node;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MixFloatNode *mix_node = graph->create_node<MixFloatNode>();
|
|
|
|
|
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
|
|
|
|
node = mix_node;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<SeparateRGBNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<CombineRGBNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeSeparateHSV)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<SeparateHSVNode>();
|
2013-07-03 23:46:56 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<CombineHSVNode>();
|
2013-07-03 23:46:56 +00:00
|
|
|
}
|
Nodes: Add general Combine/Separate Color nodes
Inspired by D12936 and D12929, this patch adds general purpose
"Combine Color" and "Separate Color" nodes to Geometry, Compositor,
Shader and Texture nodes.
- Within Geometry Nodes, it replaces the existing "Combine RGB" and
"Separate RGB" nodes.
- Within Compositor Nodes, it replaces the existing
"Combine RGBA/HSVA/YCbCrA/YUVA" and "Separate RGBA/HSVA/YCbCrA/YUVA"
nodes.
- Within Texture Nodes, it replaces the existing "Combine RGBA" and
"Separate RGBA" nodes.
- Within Shader Nodes, it replaces the existing "Combine RGB/HSV" and
"Separate RGB/HSV" nodes.
Python addons have not been updated to the new nodes yet.
**New shader code**
In node_color.h, color.h and gpu_shader_material_color_util.glsl,
missing methods hsl_to_rgb and rgb_to_hsl are added by directly
converting existing C code. They always produce the same result.
**Old code**
As requested by T96219, old nodes still exist but are not displayed in
the add menu. This means Python scripts can still create them as usual.
Otherwise, versioning replaces the old nodes with the new nodes when
opening .blend files.
Differential Revision: https://developer.blender.org/D14034
2022-05-04 18:44:03 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeSeparateColor)) {
|
|
|
|
|
BL::ShaderNodeSeparateColor b_separate_node(b_node);
|
|
|
|
|
SeparateColorNode *separate_node = graph->create_node<SeparateColorNode>();
|
|
|
|
|
separate_node->set_color_type((NodeCombSepColorType)b_separate_node.mode());
|
|
|
|
|
node = separate_node;
|
|
|
|
|
}
|
|
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeCombineColor)) {
|
|
|
|
|
BL::ShaderNodeCombineColor b_combine_node(b_node);
|
|
|
|
|
CombineColorNode *combine_node = graph->create_node<CombineColorNode>();
|
|
|
|
|
combine_node->set_color_type((NodeCombSepColorType)b_combine_node.mode());
|
|
|
|
|
node = combine_node;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<SeparateXYZNode>();
|
2014-06-13 21:44:48 +02:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<CombineXYZNode>();
|
2014-06-13 21:44:48 +02:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<HSVNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<RGBToBWNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2019-08-13 16:29:32 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
|
2019-08-14 10:53:19 +02:00
|
|
|
BL::ShaderNodeMapRange b_map_range_node(b_node);
|
2021-12-13 21:20:07 +00:00
|
|
|
if (b_map_range_node.data_type() == BL::ShaderNodeMapRange::data_type_FLOAT_VECTOR) {
|
|
|
|
|
VectorMapRangeNode *vector_map_range_node = graph->create_node<VectorMapRangeNode>();
|
|
|
|
|
vector_map_range_node->set_use_clamp(b_map_range_node.clamp());
|
|
|
|
|
vector_map_range_node->set_range_type(
|
|
|
|
|
(NodeMapRangeType)b_map_range_node.interpolation_type());
|
|
|
|
|
node = vector_map_range_node;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
|
|
|
|
|
map_range_node->set_clamp(b_map_range_node.clamp());
|
|
|
|
|
map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type());
|
|
|
|
|
node = map_range_node;
|
|
|
|
|
}
|
2019-08-13 16:29:32 +02:00
|
|
|
}
|
2019-08-13 22:22:15 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
|
2019-12-07 12:35:07 +00:00
|
|
|
BL::ShaderNodeClamp b_clamp_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ClampNode *clamp_node = graph->create_node<ClampNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
clamp_node->set_clamp_type((NodeClampType)b_clamp_node.clamp_type());
|
2019-12-07 12:35:07 +00:00
|
|
|
node = clamp_node;
|
2019-08-13 22:22:15 +02:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeMath)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeMath b_math_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MathNode *math_node = graph->create_node<MathNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
math_node->set_math_type((NodeMathType)b_math_node.operation());
|
|
|
|
|
math_node->set_use_clamp(b_math_node.use_clamp());
|
2019-08-18 11:16:04 +02:00
|
|
|
node = math_node;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeVectorMath b_vector_math_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VectorMathNode *vector_math_node = graph->create_node<VectorMathNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
vector_math_node->set_math_type((NodeVectorMathType)b_vector_math_node.operation());
|
Shading: Add more operators to Vector Math node.
Add Multiply, Divide, Project, Reflect, Distance, Length, Scale, Snap,
Floor, Ceil, Modulo, Fraction, Absolute, Minimum, and Maximum operators
to the Vector Math node. The Value output has been removed from operators
whose output is a vector, and the other way around. All of those removals
has been handled properly in versioning code.
The patch doesn't include tests for the new operators. Tests will be added
in a later patch.
Reviewers: brecht, JacquesLucke
Differential Revision: https://developer.blender.org/D5523
2019-08-21 19:36:33 +02:00
|
|
|
node = vector_math_node;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2020-02-17 15:15:46 +00:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVectorRotate)) {
|
|
|
|
|
BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VectorRotateNode *vector_rotate_node = graph->create_node<VectorRotateNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
vector_rotate_node->set_rotate_type(
|
|
|
|
|
(NodeVectorRotateType)b_vector_rotate_node.rotation_type());
|
|
|
|
|
vector_rotate_node->set_invert(b_vector_rotate_node.invert());
|
2020-02-17 15:15:46 +00:00
|
|
|
node = vector_rotate_node;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
|
2013-07-31 21:18:23 +00:00
|
|
|
BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VectorTransformNode *vtransform = graph->create_node<VectorTransformNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
vtransform->set_transform_type((NodeVectorTransformType)b_vector_transform_node.vector_type());
|
|
|
|
|
vtransform->set_convert_from(
|
|
|
|
|
(NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from());
|
|
|
|
|
vtransform->set_convert_to(
|
|
|
|
|
(NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to());
|
2013-07-31 21:18:23 +00:00
|
|
|
node = vtransform;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeNormal)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::Node::outputs_iterator out_it;
|
|
|
|
|
b_node.outputs.begin(out_it);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
NormalNode *norm = graph->create_node<NormalNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
norm->set_direction(get_node_output_vector(b_node, "Normal"));
|
2013-03-18 16:34:57 +00:00
|
|
|
node = norm;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeMapping b_mapping_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MappingNode *mapping = graph->create_node<MappingNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
mapping->set_mapping_type((NodeMappingType)b_mapping_node.vector_type());
|
2013-03-18 16:34:57 +00:00
|
|
|
node = mapping;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<FresnelNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<LayerWeightNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeAddShader)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<AddClosureNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<MixClosureNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeAttribute b_attr_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
AttributeNode *attr = graph->create_node<AttributeNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
attr->set_attribute(blender_attribute_name_add_type(b_attr_node.attribute_name(),
|
|
|
|
|
b_attr_node.attribute_type()));
|
2013-03-18 16:34:57 +00:00
|
|
|
node = attr;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBackground)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<BackgroundNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<HoldoutNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<DiffuseBsdfNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
|
2013-08-18 14:15:57 +00:00
|
|
|
BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
SubsurfaceScatteringNode *subsurface = graph->create_node<SubsurfaceScatteringNode>();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-18 14:15:57 +00:00
|
|
|
switch (b_subsurface_node.falloff()) {
|
2021-10-07 17:27:22 +02:00
|
|
|
case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
|
|
|
|
|
subsurface->set_method(CLOSURE_BSSRDF_BURLEY_ID);
|
|
|
|
|
break;
|
2018-01-21 14:04:22 +01:00
|
|
|
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
2018-01-21 14:04:22 +01:00
|
|
|
break;
|
2023-09-22 17:32:13 +02:00
|
|
|
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK_SKIN:
|
|
|
|
|
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
|
|
|
|
|
break;
|
2013-08-18 14:15:57 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-18 14:15:57 +00:00
|
|
|
node = subsurface;
|
2013-04-01 20:26:52 +00:00
|
|
|
}
|
2024-08-27 17:20:46 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfMetallic)) {
|
|
|
|
|
BL::ShaderNodeBsdfMetallic b_metallic_node(b_node);
|
|
|
|
|
MetallicBsdfNode *metal = graph->create_node<MetallicBsdfNode>();
|
|
|
|
|
|
|
|
|
|
switch (b_metallic_node.distribution()) {
|
|
|
|
|
case BL::ShaderNodeBsdfMetallic::distribution_BECKMANN:
|
|
|
|
|
metal->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfMetallic::distribution_GGX:
|
|
|
|
|
metal->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfMetallic::distribution_MULTI_GGX:
|
|
|
|
|
metal->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (b_metallic_node.fresnel_type()) {
|
|
|
|
|
case BL::ShaderNodeBsdfMetallic::fresnel_type_PHYSICAL_CONDUCTOR:
|
|
|
|
|
metal->set_fresnel_type(CLOSURE_BSDF_PHYSICAL_CONDUCTOR);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfMetallic::fresnel_type_F82:
|
|
|
|
|
metal->set_fresnel_type(CLOSURE_BSDF_F82_CONDUCTOR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = metal;
|
|
|
|
|
}
|
Cycles: Merge Anisotropic BSDF node into Glossy BSDF node
Used to be https://archive.blender.org/developer/D17123.
Internally these are already using the same code path anyways, there's no point in maintaining two distinct nodes.
The obvious approach would be to add Anisotropy controls to the Glossy BSDF node and remove the Anisotropic BSDF node. However, that would break forward compability, since older Blender versions don't know how to handle the Anisotropy input on the Glossy BSDF node.
Therefore, this commit technically removes the Glossy BSDF node, uses versioning to replace them with an Anisotropic BSDF node, and renames that node to "Glossy BSDF".
That way, when you open a new file in an older version, all the nodes show up as Anisotropic BSDF nodes and render correctly.
This is a bit ugly internally since we need to preserve the old `idname` which now no longer matches the UI name, but that's not too bad.
Also removes the "Sharp" distribution option and replaces it with GGX, sets Roughness to zero and disconnects any input to the Roughness socket.
Pull Request: https://projects.blender.org/blender/blender/pulls/104445
2023-05-18 23:12:20 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
|
|
|
|
|
BL::ShaderNodeBsdfAnisotropic b_glossy_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
GlossyBsdfNode *glossy = graph->create_node<GlossyBsdfNode>();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
switch (b_glossy_node.distribution()) {
|
Cycles: Merge Anisotropic BSDF node into Glossy BSDF node
Used to be https://archive.blender.org/developer/D17123.
Internally these are already using the same code path anyways, there's no point in maintaining two distinct nodes.
The obvious approach would be to add Anisotropy controls to the Glossy BSDF node and remove the Anisotropic BSDF node. However, that would break forward compability, since older Blender versions don't know how to handle the Anisotropy input on the Glossy BSDF node.
Therefore, this commit technically removes the Glossy BSDF node, uses versioning to replace them with an Anisotropic BSDF node, and renames that node to "Glossy BSDF".
That way, when you open a new file in an older version, all the nodes show up as Anisotropic BSDF nodes and render correctly.
This is a bit ugly internally since we need to preserve the old `idname` which now no longer matches the UI name, but that's not too bad.
Also removes the "Sharp" distribution option and replaces it with GGX, sets Roughness to zero and disconnects any input to the Roughness socket.
Pull Request: https://projects.blender.org/blender/blender/pulls/104445
2023-05-18 23:12:20 +02:00
|
|
|
case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
|
2020-11-04 11:17:38 +01:00
|
|
|
glossy->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
Cycles: Merge Anisotropic BSDF node into Glossy BSDF node
Used to be https://archive.blender.org/developer/D17123.
Internally these are already using the same code path anyways, there's no point in maintaining two distinct nodes.
The obvious approach would be to add Anisotropy controls to the Glossy BSDF node and remove the Anisotropic BSDF node. However, that would break forward compability, since older Blender versions don't know how to handle the Anisotropy input on the Glossy BSDF node.
Therefore, this commit technically removes the Glossy BSDF node, uses versioning to replace them with an Anisotropic BSDF node, and renames that node to "Glossy BSDF".
That way, when you open a new file in an older version, all the nodes show up as Anisotropic BSDF nodes and render correctly.
This is a bit ugly internally since we need to preserve the old `idname` which now no longer matches the UI name, but that's not too bad.
Also removes the "Sharp" distribution option and replaces it with GGX, sets Roughness to zero and disconnects any input to the Roughness socket.
Pull Request: https://projects.blender.org/blender/blender/pulls/104445
2023-05-18 23:12:20 +02:00
|
|
|
case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
glossy->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID);
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
Cycles: Merge Anisotropic BSDF node into Glossy BSDF node
Used to be https://archive.blender.org/developer/D17123.
Internally these are already using the same code path anyways, there's no point in maintaining two distinct nodes.
The obvious approach would be to add Anisotropy controls to the Glossy BSDF node and remove the Anisotropic BSDF node. However, that would break forward compability, since older Blender versions don't know how to handle the Anisotropy input on the Glossy BSDF node.
Therefore, this commit technically removes the Glossy BSDF node, uses versioning to replace them with an Anisotropic BSDF node, and renames that node to "Glossy BSDF".
That way, when you open a new file in an older version, all the nodes show up as Anisotropic BSDF nodes and render correctly.
This is a bit ugly internally since we need to preserve the old `idname` which now no longer matches the UI name, but that's not too bad.
Also removes the "Sharp" distribution option and replaces it with GGX, sets Roughness to zero and disconnects any input to the Roughness socket.
Pull Request: https://projects.blender.org/blender/blender/pulls/104445
2023-05-18 23:12:20 +02:00
|
|
|
case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
|
2020-11-04 11:17:38 +01:00
|
|
|
glossy->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
Cycles: Merge Anisotropic BSDF node into Glossy BSDF node
Used to be https://archive.blender.org/developer/D17123.
Internally these are already using the same code path anyways, there's no point in maintaining two distinct nodes.
The obvious approach would be to add Anisotropy controls to the Glossy BSDF node and remove the Anisotropic BSDF node. However, that would break forward compability, since older Blender versions don't know how to handle the Anisotropy input on the Glossy BSDF node.
Therefore, this commit technically removes the Glossy BSDF node, uses versioning to replace them with an Anisotropic BSDF node, and renames that node to "Glossy BSDF".
That way, when you open a new file in an older version, all the nodes show up as Anisotropic BSDF nodes and render correctly.
This is a bit ugly internally since we need to preserve the old `idname` which now no longer matches the UI name, but that's not too bad.
Also removes the "Sharp" distribution option and replaces it with GGX, sets Roughness to zero and disconnects any input to the Roughness socket.
Pull Request: https://projects.blender.org/blender/blender/pulls/104445
2023-05-18 23:12:20 +02:00
|
|
|
case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
glossy->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
|
Cycles: Add multi-scattering, energy-conserving GGX as an option to the Glossy, Anisotropic and Glass BSDFs
This commit adds a new distribution to the Glossy, Anisotropic and Glass BSDFs that implements the
multiple-scattering microfacet model described in the paper "Multiple-Scattering Microfacet BSDFs with the Smith Model".
Essentially, the improvement is that unlike classical GGX, which only models single scattering and assumes
the contribution of multiple bounces to be zero, this new model performs a random walk on the microsurface until
the ray leaves it again, which ensures perfect energy conservation.
In practise, this means that the "darkening problem" - GGX materials becoming darker with increasing
roughness - is solved in a physically correct and efficient way.
The downside of this model is that it has no (known) analytic expression for evalation. However, it can be
evaluated stochastically, and although the correct PDF isn't known either, the properties of MIS and the
balance heuristic guarantee an unbiased result at the cost of slightly higher noise.
Reviewers: dingto, #cycles, brecht
Reviewed By: dingto, #cycles, brecht
Subscribers: bliblubli, ace_dragon, gregzaal, brecht, harvester, dingto, marcog, swerner, jtheninja, Blendify, nutel
Differential Revision: https://developer.blender.org/D2002
2016-06-23 22:56:43 +02:00
|
|
|
break;
|
2012-05-07 20:24:38 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
node = glossy;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeBsdfGlass b_glass_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
GlassBsdfNode *glass = graph->create_node<GlassBsdfNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
switch (b_glass_node.distribution()) {
|
2016-02-03 15:00:55 +01:00
|
|
|
case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
|
2020-11-04 11:17:38 +01:00
|
|
|
glass->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfGlass::distribution_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
glass->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
|
2016-02-03 15:00:55 +01:00
|
|
|
break;
|
Cycles: Add multi-scattering, energy-conserving GGX as an option to the Glossy, Anisotropic and Glass BSDFs
This commit adds a new distribution to the Glossy, Anisotropic and Glass BSDFs that implements the
multiple-scattering microfacet model described in the paper "Multiple-Scattering Microfacet BSDFs with the Smith Model".
Essentially, the improvement is that unlike classical GGX, which only models single scattering and assumes
the contribution of multiple bounces to be zero, this new model performs a random walk on the microsurface until
the ray leaves it again, which ensures perfect energy conservation.
In practise, this means that the "darkening problem" - GGX materials becoming darker with increasing
roughness - is solved in a physically correct and efficient way.
The downside of this model is that it has no (known) analytic expression for evalation. However, it can be
evaluated stochastically, and although the correct PDF isn't known either, the properties of MIS and the
balance heuristic guarantee an unbiased result at the cost of slightly higher noise.
Reviewers: dingto, #cycles, brecht
Reviewed By: dingto, #cycles, brecht
Subscribers: bliblubli, ace_dragon, gregzaal, brecht, harvester, dingto, marcog, swerner, jtheninja, Blendify, nutel
Differential Revision: https://developer.blender.org/D2002
2016-06-23 22:56:43 +02:00
|
|
|
case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
glass->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
|
Cycles: Add multi-scattering, energy-conserving GGX as an option to the Glossy, Anisotropic and Glass BSDFs
This commit adds a new distribution to the Glossy, Anisotropic and Glass BSDFs that implements the
multiple-scattering microfacet model described in the paper "Multiple-Scattering Microfacet BSDFs with the Smith Model".
Essentially, the improvement is that unlike classical GGX, which only models single scattering and assumes
the contribution of multiple bounces to be zero, this new model performs a random walk on the microsurface until
the ray leaves it again, which ensures perfect energy conservation.
In practise, this means that the "darkening problem" - GGX materials becoming darker with increasing
roughness - is solved in a physically correct and efficient way.
The downside of this model is that it has no (known) analytic expression for evalation. However, it can be
evaluated stochastically, and although the correct PDF isn't known either, the properties of MIS and the
balance heuristic guarantee an unbiased result at the cost of slightly higher noise.
Reviewers: dingto, #cycles, brecht
Reviewed By: dingto, #cycles, brecht
Subscribers: bliblubli, ace_dragon, gregzaal, brecht, harvester, dingto, marcog, swerner, jtheninja, Blendify, nutel
Differential Revision: https://developer.blender.org/D2002
2016-06-23 22:56:43 +02:00
|
|
|
break;
|
2012-12-28 14:21:30 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
node = glass;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
RefractionBsdfNode *refraction = graph->create_node<RefractionBsdfNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
switch (b_refraction_node.distribution()) {
|
|
|
|
|
case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
|
2020-11-04 11:17:38 +01:00
|
|
|
refraction->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
|
2013-03-18 16:34:57 +00:00
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfRefraction::distribution_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
refraction->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
|
2013-03-18 16:34:57 +00:00
|
|
|
break;
|
2012-10-10 15:56:43 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
node = refraction;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
|
2013-05-23 17:45:20 +00:00
|
|
|
BL::ShaderNodeBsdfToon b_toon_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ToonBsdfNode *toon = graph->create_node<ToonBsdfNode>();
|
2013-05-23 17:45:20 +00:00
|
|
|
switch (b_toon_node.component()) {
|
|
|
|
|
case BL::ShaderNodeBsdfToon::component_DIFFUSE:
|
2020-11-04 11:17:38 +01:00
|
|
|
toon->set_component(CLOSURE_BSDF_DIFFUSE_TOON_ID);
|
2013-05-23 17:45:20 +00:00
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfToon::component_GLOSSY:
|
2020-11-04 11:17:38 +01:00
|
|
|
toon->set_component(CLOSURE_BSDF_GLOSSY_TOON_ID);
|
2013-05-23 17:45:20 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = toon;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
|
2013-09-15 23:58:00 +00:00
|
|
|
BL::ShaderNodeBsdfHair b_hair_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
HairBsdfNode *hair = graph->create_node<HairBsdfNode>();
|
2013-09-15 23:58:00 +00:00
|
|
|
switch (b_hair_node.component()) {
|
|
|
|
|
case BL::ShaderNodeBsdfHair::component_Reflection:
|
2020-11-04 11:17:38 +01:00
|
|
|
hair->set_component(CLOSURE_BSDF_HAIR_REFLECTION_ID);
|
2013-09-15 23:58:00 +00:00
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfHair::component_Transmission:
|
2020-11-04 11:17:38 +01:00
|
|
|
hair->set_component(CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
|
2013-09-15 23:58:00 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = hair;
|
|
|
|
|
}
|
2018-07-18 11:14:43 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
|
|
|
|
|
BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
PrincipledHairBsdfNode *principled_hair = graph->create_node<PrincipledHairBsdfNode>();
|
Cycles: new Principled Hair BSDF variant with elliptical cross-section support
Implements the paper [A Microfacet-based Hair Scattering
Model](https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.14588) by
Weizhen Huang, Matthias B. Hullin and Johannes Hanika.
### Features:
- This is a far-field model, as opposed to the previous near-field
Principled Hair BSDF model. The hair is expected to be less noisy, but
lower roughness values takes longer to render due to numerical
integration along the hair width. The hair also appears to be flat when
viewed up-close.
- The longitudinal width of the scattering lobe differs along the
azimuth, providing a higher contrast compared to the evenly spread
scattering in the near-field Principled Hair BSDF model. For a more
detailed comparison, please refer to the original paper.
- Supports elliptical cross-sections, adding more realism as human hairs
are usually elliptical. The orientation of the cross-section is aligned
with the curve normal, which can be adjusted using geometry nodes.
Default is minimal twist. During sampling, light rays that hit outside
the hair width will continue propogating as if the material is
transparent.
- There is non-physical modulation factors for the first three
lobes (Reflection, Transmission, Secondary Reflection).
### Missing:
- A good default for cross-section orientation. There was an
attempt (9039f76928) to default the orientation to align with the curve
normal in the mathematical sense, but the stability (when animated) is
unclear and it would be a hassle to generalise to all curve types. After
the model is in main, we could experiment with the geometry nodes team
to see what works the best as a default.
Co-authored-by: Lukas Stockner <lukas.stockner@freenet.de>
Pull Request: https://projects.blender.org/blender/blender/pulls/105600
2023-08-18 12:46:13 +02:00
|
|
|
principled_hair->set_model((NodePrincipledHairModel)get_enum(b_principled_hair_node.ptr,
|
|
|
|
|
"model",
|
|
|
|
|
NODE_PRINCIPLED_HAIR_MODEL_NUM,
|
|
|
|
|
NODE_PRINCIPLED_HAIR_HUANG));
|
2020-11-04 11:17:38 +01:00
|
|
|
principled_hair->set_parametrization(
|
|
|
|
|
(NodePrincipledHairParametrization)get_enum(b_principled_hair_node.ptr,
|
|
|
|
|
"parametrization",
|
Cycles: new Principled Hair BSDF variant with elliptical cross-section support
Implements the paper [A Microfacet-based Hair Scattering
Model](https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.14588) by
Weizhen Huang, Matthias B. Hullin and Johannes Hanika.
### Features:
- This is a far-field model, as opposed to the previous near-field
Principled Hair BSDF model. The hair is expected to be less noisy, but
lower roughness values takes longer to render due to numerical
integration along the hair width. The hair also appears to be flat when
viewed up-close.
- The longitudinal width of the scattering lobe differs along the
azimuth, providing a higher contrast compared to the evenly spread
scattering in the near-field Principled Hair BSDF model. For a more
detailed comparison, please refer to the original paper.
- Supports elliptical cross-sections, adding more realism as human hairs
are usually elliptical. The orientation of the cross-section is aligned
with the curve normal, which can be adjusted using geometry nodes.
Default is minimal twist. During sampling, light rays that hit outside
the hair width will continue propogating as if the material is
transparent.
- There is non-physical modulation factors for the first three
lobes (Reflection, Transmission, Secondary Reflection).
### Missing:
- A good default for cross-section orientation. There was an
attempt (9039f76928) to default the orientation to align with the curve
normal in the mathematical sense, but the stability (when animated) is
unclear and it would be a hassle to generalise to all curve types. After
the model is in main, we could experiment with the geometry nodes team
to see what works the best as a default.
Co-authored-by: Lukas Stockner <lukas.stockner@freenet.de>
Pull Request: https://projects.blender.org/blender/blender/pulls/105600
2023-08-18 12:46:13 +02:00
|
|
|
NODE_PRINCIPLED_HAIR_PARAMETRIZATION_NUM,
|
2020-11-04 11:17:38 +01:00
|
|
|
NODE_PRINCIPLED_HAIR_REFLECTANCE));
|
2018-07-18 11:14:43 +02:00
|
|
|
node = principled_hair;
|
|
|
|
|
}
|
2017-04-18 11:43:09 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
|
|
|
|
|
BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
PrincipledBsdfNode *principled = graph->create_node<PrincipledBsdfNode>();
|
2017-04-18 11:43:09 +02:00
|
|
|
switch (b_principled_node.distribution()) {
|
|
|
|
|
case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
principled->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
|
2017-04-18 11:43:09 +02:00
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX:
|
2020-11-04 11:17:38 +01:00
|
|
|
principled->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
|
2017-04-18 11:43:09 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2018-02-08 16:19:04 +01:00
|
|
|
switch (b_principled_node.subsurface_method()) {
|
2021-10-07 17:27:22 +02:00
|
|
|
case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
|
|
|
|
|
principled->set_subsurface_method(CLOSURE_BSSRDF_BURLEY_ID);
|
|
|
|
|
break;
|
2018-02-08 16:19:04 +01:00
|
|
|
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
2018-02-08 16:19:04 +01:00
|
|
|
break;
|
2023-09-22 17:32:13 +02:00
|
|
|
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK_SKIN:
|
|
|
|
|
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
|
|
|
|
|
break;
|
2018-02-08 16:19:04 +01:00
|
|
|
}
|
2017-04-18 11:43:09 +02:00
|
|
|
node = principled;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<TranslucentBsdfNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<TransparentBsdfNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2024-04-29 12:37:51 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfRayPortal)) {
|
|
|
|
|
node = graph->create_node<RayPortalBsdfNode>();
|
|
|
|
|
}
|
2023-07-24 15:36:36 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBsdfSheen)) {
|
|
|
|
|
BL::ShaderNodeBsdfSheen b_sheen_node(b_node);
|
|
|
|
|
SheenBsdfNode *sheen = graph->create_node<SheenBsdfNode>();
|
|
|
|
|
switch (b_sheen_node.distribution()) {
|
|
|
|
|
case BL::ShaderNodeBsdfSheen::distribution_ASHIKHMIN:
|
|
|
|
|
sheen->set_distribution(CLOSURE_BSDF_ASHIKHMIN_VELVET_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeBsdfSheen::distribution_MICROFIBER:
|
|
|
|
|
sheen->set_distribution(CLOSURE_BSDF_SHEEN_ID);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = sheen;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeEmission)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<EmissionNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
|
2018-06-15 11:03:29 +02:00
|
|
|
BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
AmbientOcclusionNode *ao = graph->create_node<AmbientOcclusionNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
ao->set_samples(b_ao_node.samples());
|
|
|
|
|
ao->set_inside(b_ao_node.inside());
|
|
|
|
|
ao->set_only_local(b_ao_node.only_local());
|
2018-06-15 11:03:29 +02:00
|
|
|
node = ao;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
|
2024-10-02 11:05:28 +02:00
|
|
|
BL::ShaderNodeVolumeScatter b_scatter_node(b_node);
|
|
|
|
|
ScatterVolumeNode *scatter = graph->create_node<ScatterVolumeNode>();
|
|
|
|
|
switch (b_scatter_node.phase()) {
|
|
|
|
|
case BL::ShaderNodeVolumeScatter::phase_HENYEY_GREENSTEIN:
|
|
|
|
|
scatter->set_phase(CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeVolumeScatter::phase_FOURNIER_FORAND:
|
|
|
|
|
scatter->set_phase(CLOSURE_VOLUME_FOURNIER_FORAND_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeVolumeScatter::phase_DRAINE:
|
|
|
|
|
scatter->set_phase(CLOSURE_VOLUME_DRAINE_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeVolumeScatter::phase_RAYLEIGH:
|
|
|
|
|
scatter->set_phase(CLOSURE_VOLUME_RAYLEIGH_ID);
|
|
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeVolumeScatter::phase_MIE:
|
|
|
|
|
scatter->set_phase(CLOSURE_VOLUME_MIE_ID);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = scatter;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<AbsorptionVolumeNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2018-01-30 15:05:19 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
|
2018-01-30 15:05:19 +01:00
|
|
|
node = principled;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<GeometryNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeWireframe)) {
|
2013-05-20 15:58:37 +00:00
|
|
|
BL::ShaderNodeWireframe b_wireframe_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
WireframeNode *wire = graph->create_node<WireframeNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
wire->set_use_pixel_size(b_wireframe_node.use_pixel_size());
|
2013-05-20 15:58:37 +00:00
|
|
|
node = wire;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeWavelength)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<WavelengthNode>();
|
2013-06-09 20:46:22 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBlackbody)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<BlackbodyNode>();
|
2013-07-31 20:56:32 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeLightPath)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<LightPathNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<LightFalloffNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<ObjectInfoNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<ParticleInfoNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<HairInfoNode>();
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2022-01-25 13:25:33 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodePointInfo)) {
|
|
|
|
|
node = graph->create_node<PointInfoNode>();
|
|
|
|
|
}
|
2019-08-21 20:22:24 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = graph->create_node<VolumeInfoNode>();
|
2019-08-21 20:22:24 +02:00
|
|
|
}
|
2019-09-12 17:42:13 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVertexColor)) {
|
|
|
|
|
BL::ShaderNodeVertexColor b_vertex_color_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VertexColorNode *vertex_color_node = graph->create_node<VertexColorNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
vertex_color_node->set_layer_name(ustring(b_vertex_color_node.layer_name()));
|
2019-09-12 17:42:13 +02:00
|
|
|
node = vertex_color_node;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBump)) {
|
2013-05-10 16:57:17 +00:00
|
|
|
BL::ShaderNodeBump b_bump_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
BumpNode *bump = graph->create_node<BumpNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
bump->set_invert(b_bump_node.invert());
|
2013-05-10 16:57:17 +00:00
|
|
|
node = bump;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeScript)) {
|
2012-11-03 14:32:35 +00:00
|
|
|
#ifdef WITH_OSL
|
2013-03-18 16:34:57 +00:00
|
|
|
if (scene->shader_manager->use_osl()) {
|
2012-11-03 14:32:35 +00:00
|
|
|
/* create script node */
|
|
|
|
|
BL::ShaderNodeScript b_script_node(b_node);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const string bytecode_hash = b_script_node.bytecode_hash();
|
2015-11-25 20:21:06 +05:00
|
|
|
if (!bytecode_hash.empty()) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
node = OSLShaderManager::osl_node(
|
2025-03-04 17:27:10 +01:00
|
|
|
graph, scene, "", bytecode_hash, b_script_node.bytecode());
|
2015-11-25 20:21:06 +05:00
|
|
|
}
|
|
|
|
|
else {
|
2024-12-29 17:32:00 +01:00
|
|
|
const string absolute_filepath = blender_absolute_path(
|
2016-05-29 15:10:34 +02:00
|
|
|
b_data, b_ntree, b_script_node.filepath());
|
2025-03-04 17:27:10 +01:00
|
|
|
node = OSLShaderManager::osl_node(graph, scene, absolute_filepath, "");
|
2012-11-03 14:32:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
2015-03-27 19:09:41 +05:00
|
|
|
#else
|
2018-11-09 12:08:51 +01:00
|
|
|
(void)b_data;
|
|
|
|
|
(void)b_ntree;
|
2013-03-18 16:34:57 +00:00
|
|
|
#endif
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexImage)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexImage b_image_node(b_node);
|
|
|
|
|
BL::Image b_image(b_image_node.image());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::ImageUser b_image_user(b_image_node.image_user());
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ImageTextureNode *image = graph->create_node<ImageTextureNode>();
|
2020-02-20 00:52:50 +01:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
image->set_interpolation(get_image_interpolation(b_image_node));
|
|
|
|
|
image->set_extension(get_image_extension(b_image_node));
|
|
|
|
|
image->set_projection((NodeImageProjection)b_image_node.projection());
|
|
|
|
|
image->set_projection_blend(b_image_node.projection_blend());
|
2020-02-20 00:52:50 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_image_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(image, b_texture_mapping);
|
2020-02-20 00:52:50 +01:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
if (b_image) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const BL::Image::source_enum b_image_source = b_image.source();
|
2020-03-08 14:21:29 +01:00
|
|
|
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
2020-11-04 11:17:38 +01:00
|
|
|
image->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name")));
|
2020-03-08 14:21:29 +01:00
|
|
|
|
2022-08-15 19:27:46 +02:00
|
|
|
image->set_animated(is_image_animated(b_image_source, b_image_user));
|
2020-11-04 11:17:38 +01:00
|
|
|
image->set_alpha_type(get_image_alpha_type(b_image));
|
2020-03-08 14:21:29 +01:00
|
|
|
|
2025-01-23 21:20:01 +01:00
|
|
|
if (b_image_source == BL::Image::source_TILED) {
|
|
|
|
|
array<int> tiles;
|
|
|
|
|
for (BL::UDIMTile &b_tile : b_image.tiles) {
|
|
|
|
|
tiles.push_back_slow(b_tile.number());
|
|
|
|
|
}
|
|
|
|
|
image->set_tiles(tiles);
|
2020-03-08 14:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
/* builtin images will use callback-based reading because
|
|
|
|
|
* they could only be loaded correct from blender side
|
|
|
|
|
*/
|
2024-09-19 00:40:30 +02:00
|
|
|
const bool is_builtin = image_is_builtin(b_image, b_engine);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
if (is_builtin) {
|
|
|
|
|
/* for builtin images we're using image datablock name to find an image to
|
|
|
|
|
* read pixels from later
|
|
|
|
|
*
|
|
|
|
|
* also store frame number as well, so there's no differences in handling
|
|
|
|
|
* builtin names for packed images and movies
|
Packed and generated images support for Cycles
This commit adds support of packed and generated images
for Cycles when using SVM backend. Movies are still not
supported. This changes also doesn't touch OSL which is
much less trivial to adopt for any images which are not
saved to disk.
Implementation details:
- When adding images to Image Manager is now possible
to mark image as builtin. Builtin images will bypass
OIIO loader and will use special loading callbacks.
- Callbacks are set by Blender Session and they're
using C++ RNA interface to obtain needed data (pixels,
dimensions, is_float flag).
- Image Manager assumes file path is used as reference
to a builtin images, but in fact currently image
datablock name is used for reference. This makes it
easy to find an image in BlendData database.
- Added some extra properties to Image RNA:
* channels, which denotes actual number of channels
in ImBuf. This is needed to treat image's pixels
correct (before it wasn't possible because API
used internal number of channels for pixels which
is in fact doesn't correlate with image depth)
* is_float, which is truth if image is stored in
float buffer of ImBuf.
- Implemented string lookup for C++ RNA collections
for cases there's no manual lookup function.
OSL is not supported because it used own image loading
and filtering routines and there's seems to be no API
to feed pre-loaded pixels directly to the library.
Think we'll either need to add some API to support
such kind of feeding or consider OSL does not have
support of packed images at all.
Movies are not supported at this moment because of lack
of RNA API to load specified frame. It's not difficult
to solve, just need to consider what to best here:
* Either write some general python interface for ImBuf
and use it via C++ API, or
* Write a PY API function which will return pixels for
given frame, or
* Use bad-level BKE_* call
Anyway, small steps, further improvements later.
Reviewed by Brecht, thanks!
2013-01-12 10:59:13 +00:00
|
|
|
*/
|
2024-12-29 17:32:00 +01:00
|
|
|
const int scene_frame = b_scene.frame_current();
|
|
|
|
|
const int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
|
2022-08-15 19:27:46 +02:00
|
|
|
if (b_image_source != BL::Image::source_TILED) {
|
2022-05-11 20:11:44 -07:00
|
|
|
image->handle = scene->image_manager->add_image(
|
2025-01-17 10:21:44 +01:00
|
|
|
make_unique<BlenderImageLoader>(static_cast<::Image *>(b_image.ptr.data),
|
|
|
|
|
static_cast<::ImageUser *>(b_image_user.ptr.data),
|
|
|
|
|
image_frame,
|
|
|
|
|
0,
|
|
|
|
|
b_engine.is_preview()),
|
2022-05-11 20:11:44 -07:00
|
|
|
image->image_params());
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-12-29 23:13:45 +01:00
|
|
|
vector<unique_ptr<ImageLoader>> loaders;
|
2022-05-11 20:11:44 -07:00
|
|
|
loaders.reserve(image->get_tiles().size());
|
2024-12-29 17:32:00 +01:00
|
|
|
for (const int tile_number : image->get_tiles()) {
|
2025-01-17 10:21:44 +01:00
|
|
|
loaders.push_back(
|
|
|
|
|
make_unique<BlenderImageLoader>(static_cast<::Image *>(b_image.ptr.data),
|
|
|
|
|
static_cast<::ImageUser *>(b_image_user.ptr.data),
|
|
|
|
|
image_frame,
|
|
|
|
|
tile_number,
|
|
|
|
|
b_engine.is_preview()));
|
2022-05-11 20:11:44 -07:00
|
|
|
}
|
|
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
image->handle = scene->image_manager->add_image(std::move(loaders),
|
|
|
|
|
image->image_params());
|
2022-05-11 20:11:44 -07:00
|
|
|
}
|
2012-11-21 13:00:51 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
else {
|
2024-12-29 17:32:00 +01:00
|
|
|
const ustring filename = ustring(
|
2022-08-08 16:58:34 +02:00
|
|
|
image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current()));
|
2020-11-04 11:17:38 +01:00
|
|
|
image->set_filename(filename);
|
Add support for tiled images and the UDIM naming scheme
This patch contains the work that I did during my week at the Code Quest - adding support for tiled images to Blender.
With this patch, images now contain a list of tiles. By default, this just contains one tile, but if the source type is set to Tiled, the user can add additional tiles. When acquiring an ImBuf, the tile to be loaded is specified in the ImageUser.
Therefore, code that is not yet aware of tiles will just access the default tile as usual.
The filenames of the additional tiles are derived from the original filename according to the UDIM naming scheme - the filename contains an index that is calculated as (1001 + 10*<y coordinate of the tile> + <x coordinate of the tile>), where the x coordinate never goes above 9.
Internally, the various tiles are stored in a cache just like sequences. When acquired for the first time, the code will try to load the corresponding file from disk. Alternatively, a new operator can be used to initialize the tile similar to the New Image operator.
The following features are supported so far:
- Automatic detection and loading of all tiles when opening the first tile (1001)
- Saving all tiles
- Adding and removing tiles
- Filling tiles with generated images
- Drawing all tiles in the Image Editor
- Viewing a tiled grid even if no image is selected
- Rendering tiled images in Eevee
- Rendering tiled images in Cycles (in SVM mode)
- Automatically skipping loading of unused tiles in Cycles
- 2D texture painting (also across tiles)
- 3D texture painting (also across tiles, only limitation: individual faces can not cross tile borders)
- Assigning custom labels to individual tiles (drawn in the Image Editor instead of the ID)
- Different resolutions between tiles
There still are some missing features that will be added later (see T72390):
- Workbench engine support
- Packing/Unpacking support
- Baking support
- Cycles OSL support
- many other Blender features that rely on images
Thanks to Brecht for the review and to all who tested the intermediate versions!
Differential Revision: https://developer.blender.org/D3509
2019-12-12 16:06:08 +01:00
|
|
|
}
|
2012-11-06 19:59:02 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
node = image;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexEnvironment b_env_node(b_node);
|
|
|
|
|
BL::Image b_image(b_env_node.image());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::ImageUser b_image_user(b_env_node.image_user());
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
EnvironmentTextureNode *env = graph->create_node<EnvironmentTextureNode>();
|
2020-02-20 00:52:50 +01:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
env->set_interpolation(get_image_interpolation(b_env_node));
|
|
|
|
|
env->set_projection((NodeEnvironmentProjection)b_env_node.projection());
|
2020-02-20 00:52:50 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_env_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(env, b_texture_mapping);
|
2020-02-20 00:52:50 +01:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
if (b_image) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const BL::Image::source_enum b_image_source = b_image.source();
|
2020-03-08 14:21:29 +01:00
|
|
|
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
2020-11-04 11:17:38 +01:00
|
|
|
env->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name")));
|
2022-08-15 19:27:46 +02:00
|
|
|
env->set_animated(is_image_animated(b_image_source, b_image_user));
|
2020-11-04 11:17:38 +01:00
|
|
|
env->set_alpha_type(get_image_alpha_type(b_image));
|
2020-03-08 14:21:29 +01:00
|
|
|
|
2024-09-19 00:40:30 +02:00
|
|
|
const bool is_builtin = image_is_builtin(b_image, b_engine);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
if (is_builtin) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int scene_frame = b_scene.frame_current();
|
|
|
|
|
const int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
|
2021-12-02 16:34:16 +01:00
|
|
|
env->handle = scene->image_manager->add_image(
|
2025-01-17 10:21:44 +01:00
|
|
|
make_unique<BlenderImageLoader>(static_cast<::Image *>(b_image.ptr.data),
|
|
|
|
|
static_cast<::ImageUser *>(b_image_user.ptr.data),
|
|
|
|
|
image_frame,
|
|
|
|
|
0,
|
|
|
|
|
b_engine.is_preview()),
|
2021-12-02 16:34:16 +01:00
|
|
|
env->image_params());
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-11-04 11:17:38 +01:00
|
|
|
env->set_filename(
|
2022-08-08 16:58:34 +02:00
|
|
|
ustring(image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current())));
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2012-11-06 10:18:42 +00:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
node = env;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexGradient b_gradient_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
GradientTextureNode *gradient = graph->create_node<GradientTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
gradient->set_gradient_type((NodeGradientType)b_gradient_node.gradient_type());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(gradient, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = gradient;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VoronoiTextureNode *voronoi = graph->create_node<VoronoiTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
voronoi->set_dimensions(b_voronoi_node.voronoi_dimensions());
|
|
|
|
|
voronoi->set_feature((NodeVoronoiFeature)b_voronoi_node.feature());
|
|
|
|
|
voronoi->set_metric((NodeVoronoiDistanceMetric)b_voronoi_node.distance());
|
2023-06-13 19:51:49 +02:00
|
|
|
voronoi->set_use_normalize(b_voronoi_node.normalize());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(voronoi, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = voronoi;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexMagic b_magic_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MagicTextureNode *magic = graph->create_node<MagicTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
magic->set_depth(b_magic_node.turbulence_depth());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(magic, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = magic;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexWave)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexWave b_wave_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
WaveTextureNode *wave = graph->create_node<WaveTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
wave->set_wave_type((NodeWaveType)b_wave_node.wave_type());
|
|
|
|
|
wave->set_bands_direction((NodeWaveBandsDirection)b_wave_node.bands_direction());
|
|
|
|
|
wave->set_rings_direction((NodeWaveRingsDirection)b_wave_node.rings_direction());
|
|
|
|
|
wave->set_profile((NodeWaveProfile)b_wave_node.wave_profile());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(wave, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = wave;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexChecker b_checker_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
CheckerTextureNode *checker = graph->create_node<CheckerTextureNode>();
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(checker, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = checker;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexBrick b_brick_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
BrickTextureNode *brick = graph->create_node<BrickTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
brick->set_offset(b_brick_node.offset());
|
|
|
|
|
brick->set_offset_frequency(b_brick_node.offset_frequency());
|
|
|
|
|
brick->set_squash(b_brick_node.squash());
|
|
|
|
|
brick->set_squash_frequency(b_brick_node.squash_frequency());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(brick, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = brick;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexNoise b_noise_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
NoiseTextureNode *noise = graph->create_node<NoiseTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
noise->set_dimensions(b_noise_node.noise_dimensions());
|
2023-12-18 10:35:20 +01:00
|
|
|
noise->set_type((NodeNoiseType)b_noise_node.noise_type());
|
2023-08-15 17:38:45 +02:00
|
|
|
noise->set_use_normalize(b_noise_node.normalize());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(noise, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = noise;
|
|
|
|
|
}
|
Nodes: Implement Gabor noise
This patch implements a new Gabor noise node based on [1] but with the
improvements from [2] and the phasor formulation from [3].
We compare with the most popular existing implementation, that of OSL,
from the user's point of view:
- This implementation produces C1 continuous noise as opposed to the
non continuous OSL implementation, so it can be used for bump
mapping and is generally smother. This is achieved by windowing the
Gabor kernel using a Hann window.
- The Bandwidth input of OSL was hard-coded to 1 and was replaced with
a frequency input, which OSL hard codes to 2, since frequency is
more natural to control. This is even more true now that that Gabor
kernel is windowed as opposed to truncated, which means increasing
the bandwidth will just turn the Gaussian component of the Gabor
into a Hann window. While decreasing the bandwidth will eliminate
the harmonic from the Gabor kernel, which is the point of Gabor
noise.
- OSL had three discrete modes of operation for orienting the kernel.
Anisotropic, Isotropic, and a hybrid mode. While this implementation
provides a continuous Anisotropy parameter which users are already
familiar with from the Glossy BSDF node.
- This implementation provides not just the Gabor noise value, but
also its phase and intensity components. The Gabor noise value is
basically sin(phase) * intensity, but the phase is arguably more
useful since it does not suffer from the low contrast issues that
Gabor suffers from. While the intensity is useful to hide the
singularities in the phase.
- This implementation converges faster that OSL's relative to the
impulse count, so we fix the impulses count to 8 for simplicitly.
- This implementation does not implement anisotropic filtering.
Future improvements to the node includes implementing surface noise and
filtering. As well as extending the spectral control of the noise,
either by providing specialized kernels as was done in #110802, or by
providing some more procedural control over the frequencies of the
Gabor.
References:
[1]: Lagae, Ares, et al. "Procedural noise using sparse Gabor
convolution." ACM Transactions on Graphics (TOG) 28.3 (2009): 1-10.
[2]: Tavernier, Vincent, et al. "Making gabor noise fast and
normalized." Eurographics 2019-40th Annual Conference of the European
Association for Computer Graphics. 2019.
[3]: Tricard, Thibault, et al. "Procedural phasor noise." ACM
Transactions on Graphics (TOG) 38.4 (2019): 1-13.
Pull Request: https://projects.blender.org/blender/blender/pulls/121820
2024-06-19 09:33:32 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexGabor)) {
|
|
|
|
|
BL::ShaderNodeTexGabor b_gabor_node(b_node);
|
|
|
|
|
GaborTextureNode *gabor = graph->create_node<GaborTextureNode>();
|
|
|
|
|
gabor->set_type((NodeGaborType)b_gabor_node.gabor_type());
|
|
|
|
|
BL::TexMapping b_texture_mapping(b_gabor_node.texture_mapping());
|
|
|
|
|
get_tex_mapping(gabor, b_texture_mapping);
|
|
|
|
|
node = gabor;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
TextureCoordinateNode *tex_coord = graph->create_node<TextureCoordinateNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
tex_coord->set_from_dupli(b_tex_coord_node.from_instancer());
|
2015-01-21 22:19:31 +05:00
|
|
|
if (b_tex_coord_node.object()) {
|
2020-11-04 11:17:38 +01:00
|
|
|
tex_coord->set_use_transform(true);
|
|
|
|
|
tex_coord->set_ob_tfm(get_transform(b_tex_coord_node.object().matrix_world()));
|
2015-01-21 22:19:31 +05:00
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
node = tex_coord;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTexSky b_sky_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
SkyTextureNode *sky = graph->create_node<SkyTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
sky->set_sky_type((NodeSkyType)b_sky_node.sky_type());
|
|
|
|
|
sky->set_sun_direction(normalize(get_float3(b_sky_node.sun_direction())));
|
|
|
|
|
sky->set_turbidity(b_sky_node.turbidity());
|
|
|
|
|
sky->set_ground_albedo(b_sky_node.ground_albedo());
|
|
|
|
|
sky->set_sun_disc(b_sky_node.sun_disc());
|
|
|
|
|
sky->set_sun_size(b_sky_node.sun_size());
|
|
|
|
|
sky->set_sun_intensity(b_sky_node.sun_intensity());
|
2023-04-17 17:29:27 +02:00
|
|
|
sky->set_sun_elevation(b_sky_node.sun_elevation());
|
|
|
|
|
sky->set_sun_rotation(b_sky_node.sun_rotation());
|
2021-01-27 14:54:51 +01:00
|
|
|
sky->set_altitude(b_sky_node.altitude());
|
2020-11-04 11:17:38 +01:00
|
|
|
sky->set_air_density(b_sky_node.air_density());
|
|
|
|
|
sky->set_dust_density(b_sky_node.dust_density());
|
|
|
|
|
sky->set_ozone_density(b_sky_node.ozone_density());
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping());
|
2020-11-04 11:17:38 +01:00
|
|
|
get_tex_mapping(sky, b_texture_mapping);
|
2013-03-18 16:34:57 +00:00
|
|
|
node = sky;
|
|
|
|
|
}
|
Cycles: Add Support for IES files as textures for light strength
This patch adds support for IES files, a file format that is commonly used to store the directional intensity distribution of light sources.
The new IES node is supposed to be plugged into the Strength input of the Emission node of the lamp.
Since people generating IES files do not really seem to care about the standard, the parser is flexible enough to accept all test files I have tried.
Some common weirdnesses are distributing values over multiple lines that should go into one line, using commas instead of spaces as delimiters and adding various useless stuff at the end of the file.
The user interface of the node is similar to the script node, the user can either select an internal Text or load a file.
Internally, IES files are handled similar to Image textures: They are stored in slots by the LightManager and each unique IES is assigned to one slot.
The local coordinate system of the lamp is used, so that the direction of the light can be changed. For UI reasons, it's usually best to add an area light,
rotate it and then change its type, since especially the point light does not immediately show its local coordinate system in the viewport.
Reviewers: #cycles, dingto, sergey, brecht
Reviewed By: #cycles, dingto, brecht
Subscribers: OgDEV, crazyrobinhood, secundar, cardboard, pisuke, intrah, swerner, micah_denn, harvester, gottfried, disnel, campbellbarton, duarteframos, Lapineige, brecht, juicyfruit, dingto, marek, rickyblender, bliblubli, lockal, sergey
Differential Revision: https://developer.blender.org/D1543
2018-05-27 00:46:37 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexIES)) {
|
|
|
|
|
BL::ShaderNodeTexIES b_ies_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
IESLightNode *ies = graph->create_node<IESLightNode>();
|
Cycles: Add Support for IES files as textures for light strength
This patch adds support for IES files, a file format that is commonly used to store the directional intensity distribution of light sources.
The new IES node is supposed to be plugged into the Strength input of the Emission node of the lamp.
Since people generating IES files do not really seem to care about the standard, the parser is flexible enough to accept all test files I have tried.
Some common weirdnesses are distributing values over multiple lines that should go into one line, using commas instead of spaces as delimiters and adding various useless stuff at the end of the file.
The user interface of the node is similar to the script node, the user can either select an internal Text or load a file.
Internally, IES files are handled similar to Image textures: They are stored in slots by the LightManager and each unique IES is assigned to one slot.
The local coordinate system of the lamp is used, so that the direction of the light can be changed. For UI reasons, it's usually best to add an area light,
rotate it and then change its type, since especially the point light does not immediately show its local coordinate system in the viewport.
Reviewers: #cycles, dingto, sergey, brecht
Reviewed By: #cycles, dingto, brecht
Subscribers: OgDEV, crazyrobinhood, secundar, cardboard, pisuke, intrah, swerner, micah_denn, harvester, gottfried, disnel, campbellbarton, duarteframos, Lapineige, brecht, juicyfruit, dingto, marek, rickyblender, bliblubli, lockal, sergey
Differential Revision: https://developer.blender.org/D1543
2018-05-27 00:46:37 +02:00
|
|
|
switch (b_ies_node.mode()) {
|
|
|
|
|
case BL::ShaderNodeTexIES::mode_EXTERNAL:
|
2020-11-04 11:17:38 +01:00
|
|
|
ies->set_filename(ustring(blender_absolute_path(b_data, b_ntree, b_ies_node.filepath())));
|
Cycles: Add Support for IES files as textures for light strength
This patch adds support for IES files, a file format that is commonly used to store the directional intensity distribution of light sources.
The new IES node is supposed to be plugged into the Strength input of the Emission node of the lamp.
Since people generating IES files do not really seem to care about the standard, the parser is flexible enough to accept all test files I have tried.
Some common weirdnesses are distributing values over multiple lines that should go into one line, using commas instead of spaces as delimiters and adding various useless stuff at the end of the file.
The user interface of the node is similar to the script node, the user can either select an internal Text or load a file.
Internally, IES files are handled similar to Image textures: They are stored in slots by the LightManager and each unique IES is assigned to one slot.
The local coordinate system of the lamp is used, so that the direction of the light can be changed. For UI reasons, it's usually best to add an area light,
rotate it and then change its type, since especially the point light does not immediately show its local coordinate system in the viewport.
Reviewers: #cycles, dingto, sergey, brecht
Reviewed By: #cycles, dingto, brecht
Subscribers: OgDEV, crazyrobinhood, secundar, cardboard, pisuke, intrah, swerner, micah_denn, harvester, gottfried, disnel, campbellbarton, duarteframos, Lapineige, brecht, juicyfruit, dingto, marek, rickyblender, bliblubli, lockal, sergey
Differential Revision: https://developer.blender.org/D1543
2018-05-27 00:46:37 +02:00
|
|
|
break;
|
|
|
|
|
case BL::ShaderNodeTexIES::mode_INTERNAL:
|
2020-11-04 11:17:38 +01:00
|
|
|
ustring ies_content = ustring(get_text_datablock_content(b_ies_node.ies().ptr));
|
|
|
|
|
if (ies_content.empty()) {
|
|
|
|
|
ies_content = "\n";
|
2018-05-27 17:14:01 +02:00
|
|
|
}
|
2020-11-04 11:17:38 +01:00
|
|
|
ies->set_ies(ies_content);
|
Cycles: Add Support for IES files as textures for light strength
This patch adds support for IES files, a file format that is commonly used to store the directional intensity distribution of light sources.
The new IES node is supposed to be plugged into the Strength input of the Emission node of the lamp.
Since people generating IES files do not really seem to care about the standard, the parser is flexible enough to accept all test files I have tried.
Some common weirdnesses are distributing values over multiple lines that should go into one line, using commas instead of spaces as delimiters and adding various useless stuff at the end of the file.
The user interface of the node is similar to the script node, the user can either select an internal Text or load a file.
Internally, IES files are handled similar to Image textures: They are stored in slots by the LightManager and each unique IES is assigned to one slot.
The local coordinate system of the lamp is used, so that the direction of the light can be changed. For UI reasons, it's usually best to add an area light,
rotate it and then change its type, since especially the point light does not immediately show its local coordinate system in the viewport.
Reviewers: #cycles, dingto, sergey, brecht
Reviewed By: #cycles, dingto, brecht
Subscribers: OgDEV, crazyrobinhood, secundar, cardboard, pisuke, intrah, swerner, micah_denn, harvester, gottfried, disnel, campbellbarton, duarteframos, Lapineige, brecht, juicyfruit, dingto, marek, rickyblender, bliblubli, lockal, sergey
Differential Revision: https://developer.blender.org/D1543
2018-05-27 00:46:37 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = ies;
|
|
|
|
|
}
|
2019-08-21 20:04:09 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexWhiteNoise)) {
|
|
|
|
|
BL::ShaderNodeTexWhiteNoise b_tex_white_noise_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
WhiteNoiseTextureNode *white_noise_node = graph->create_node<WhiteNoiseTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
white_noise_node->set_dimensions(b_tex_white_noise_node.noise_dimensions());
|
2019-08-21 20:04:09 +02:00
|
|
|
node = white_noise_node;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeNormalMap b_normal_map_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
NormalMapNode *nmap = graph->create_node<NormalMapNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
nmap->set_space((NodeNormalMapSpace)b_normal_map_node.space());
|
|
|
|
|
nmap->set_attribute(ustring(b_normal_map_node.uv_map()));
|
2013-03-18 16:34:57 +00:00
|
|
|
node = nmap;
|
|
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTangent)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
BL::ShaderNodeTangent b_tangent_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
TangentNode *tangent = graph->create_node<TangentNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
tangent->set_direction_type((NodeTangentDirectionType)b_tangent_node.direction_type());
|
|
|
|
|
tangent->set_axis((NodeTangentAxis)b_tangent_node.axis());
|
|
|
|
|
tangent->set_attribute(ustring(b_tangent_node.uv_map()));
|
2013-03-18 16:34:57 +00:00
|
|
|
node = tangent;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2015-03-28 00:15:15 +05:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeUVMap)) {
|
2014-04-02 11:40:29 +02:00
|
|
|
BL::ShaderNodeUVMap b_uvmap_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
UVMapNode *uvm = graph->create_node<UVMapNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
uvm->set_attribute(ustring(b_uvmap_node.uv_map()));
|
|
|
|
|
uvm->set_from_dupli(b_uvmap_node.from_instancer());
|
2014-04-02 11:40:29 +02:00
|
|
|
node = uvm;
|
|
|
|
|
}
|
2015-07-18 22:36:09 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
|
|
|
|
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
PointDensityTextureNode *point_density = graph->create_node<PointDensityTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
point_density->set_space((NodeTexVoxelSpace)b_point_density_node.space());
|
|
|
|
|
point_density->set_interpolation(get_image_interpolation(b_point_density_node));
|
2020-03-08 14:21:29 +01:00
|
|
|
point_density->handle = scene->image_manager->add_image(
|
2024-12-29 23:13:45 +01:00
|
|
|
make_unique<BlenderPointDensityLoader>(b_depsgraph, b_point_density_node),
|
2020-03-08 14:21:29 +01:00
|
|
|
point_density->image_params());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-08 10:42:11 +01:00
|
|
|
b_point_density_node.cache_point_density(b_depsgraph);
|
2015-07-18 22:36:09 +02:00
|
|
|
node = point_density;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-26 12:50:55 +01:00
|
|
|
/* Transformation form world space to texture space.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: Do this after the texture is cached, this is because getting
|
|
|
|
|
* min/max will need to access this cache.
|
|
|
|
|
*/
|
|
|
|
|
BL::Object b_ob(b_point_density_node.object());
|
|
|
|
|
if (b_ob) {
|
2024-12-29 17:32:00 +01:00
|
|
|
float3 loc;
|
|
|
|
|
float3 size;
|
2018-02-28 13:54:00 -03:00
|
|
|
point_density_texture_space(b_depsgraph, b_point_density_node, loc, size);
|
2020-11-04 11:17:38 +01:00
|
|
|
point_density->set_tfm(transform_translate(-loc) * transform_scale(size) *
|
|
|
|
|
transform_inverse(get_transform(b_ob.matrix_world())));
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2016-01-26 12:50:55 +01:00
|
|
|
}
|
2017-08-18 18:37:05 +02:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeBevel)) {
|
|
|
|
|
BL::ShaderNodeBevel b_bevel_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
BevelNode *bevel = graph->create_node<BevelNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
bevel->set_samples(b_bevel_node.samples());
|
2017-08-18 18:37:05 +02:00
|
|
|
node = bevel;
|
|
|
|
|
}
|
2018-01-13 13:11:03 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) {
|
2018-01-21 00:40:42 +01:00
|
|
|
BL::ShaderNodeDisplacement b_disp_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
DisplacementNode *disp = graph->create_node<DisplacementNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
disp->set_space((NodeNormalMapSpace)b_disp_node.space());
|
2018-01-21 00:40:42 +01:00
|
|
|
node = disp;
|
|
|
|
|
}
|
|
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
|
|
|
|
|
BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
VectorDisplacementNode *disp = graph->create_node<VectorDisplacementNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
disp->set_space((NodeNormalMapSpace)b_disp_node.space());
|
|
|
|
|
disp->set_attribute(ustring(""));
|
2018-01-21 00:40:42 +01:00
|
|
|
node = disp;
|
2018-01-13 13:11:03 +01:00
|
|
|
}
|
2019-12-04 19:57:28 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeOutputAOV)) {
|
|
|
|
|
BL::ShaderNodeOutputAOV b_aov_node(b_node);
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
OutputAOVNode *aov = graph->create_node<OutputAOVNode>();
|
2024-03-11 15:57:30 +01:00
|
|
|
aov->set_name(ustring(b_aov_node.aov_name()));
|
2019-12-04 19:57:28 +01:00
|
|
|
node = aov;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-08-04 14:48:34 +03:00
|
|
|
if (node) {
|
|
|
|
|
node->name = b_node.name();
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-30 11:21:31 +00:00
|
|
|
static bool node_use_modified_socket_name(ShaderNode *node)
|
|
|
|
|
{
|
2023-09-17 09:01:48 +10:00
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_OSL) {
|
2013-10-30 11:21:31 +00:00
|
|
|
return false;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2014-09-19 12:57:09 +02:00
|
|
|
|
2013-10-30 11:21:31 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-30 11:05:46 +01:00
|
|
|
static ShaderInput *node_find_input_by_name(BL::Node b_node,
|
|
|
|
|
ShaderNode *node,
|
|
|
|
|
BL::NodeSocket &b_socket)
|
2011-09-16 13:14:02 +00:00
|
|
|
{
|
2021-08-11 15:42:36 +02:00
|
|
|
string name = b_socket.identifier();
|
|
|
|
|
ShaderInput *input = node->input(name.c_str());
|
2018-07-06 10:17:58 +02:00
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
if (!input && node_use_modified_socket_name(node)) {
|
|
|
|
|
/* Different internal name for shader. */
|
|
|
|
|
if (string_startswith(name, "Shader")) {
|
|
|
|
|
string_replace(name, "Shader", "Closure");
|
|
|
|
|
}
|
2022-08-30 11:05:46 +01:00
|
|
|
|
|
|
|
|
/* Map mix node internal name for shader. */
|
|
|
|
|
if (b_node.is_a(&RNA_ShaderNodeMix)) {
|
|
|
|
|
if (string_endswith(name, "Factor_Float")) {
|
|
|
|
|
string_replace(name, "Factor_Float", "Factor");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "Factor_Vector")) {
|
|
|
|
|
string_replace(name, "Factor_Vector", "Factor");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "A_Float")) {
|
|
|
|
|
string_replace(name, "A_Float", "A");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "B_Float")) {
|
|
|
|
|
string_replace(name, "B_Float", "B");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "A_Color")) {
|
|
|
|
|
string_replace(name, "A_Color", "A");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "B_Color")) {
|
|
|
|
|
string_replace(name, "B_Color", "B");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "A_Vector")) {
|
|
|
|
|
string_replace(name, "A_Vector", "A");
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "B_Vector")) {
|
|
|
|
|
string_replace(name, "B_Vector", "B");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
input = node->input(name.c_str());
|
2014-09-19 12:57:09 +02:00
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
if (!input) {
|
2021-08-19 20:08:44 +02:00
|
|
|
/* Different internal numbering of two sockets with same name.
|
|
|
|
|
* Note that the Blender convention for unique socket names changed
|
|
|
|
|
* from . to _ at some point, so we check both to handle old files. */
|
2021-08-11 15:42:36 +02:00
|
|
|
if (string_endswith(name, "_001")) {
|
|
|
|
|
string_replace(name, "_001", "2");
|
|
|
|
|
}
|
2021-08-19 20:08:44 +02:00
|
|
|
else if (string_endswith(name, ".001")) {
|
|
|
|
|
string_replace(name, ".001", "2");
|
|
|
|
|
}
|
2021-08-16 15:40:18 +02:00
|
|
|
else if (string_endswith(name, "_002")) {
|
|
|
|
|
string_replace(name, "_002", "3");
|
|
|
|
|
}
|
2021-08-19 20:08:44 +02:00
|
|
|
else if (string_endswith(name, ".002")) {
|
|
|
|
|
string_replace(name, ".002", "3");
|
|
|
|
|
}
|
2021-08-11 15:42:36 +02:00
|
|
|
else {
|
|
|
|
|
name += "1";
|
2013-10-30 11:21:31 +00:00
|
|
|
}
|
2014-09-19 12:57:09 +02:00
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
input = node->input(name.c_str());
|
2011-10-12 15:45:52 +00:00
|
|
|
}
|
2011-09-16 13:14:02 +00:00
|
|
|
}
|
2014-09-19 12:57:09 +02:00
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
return input;
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2011-09-16 13:14:02 +00:00
|
|
|
|
2022-08-30 11:05:46 +01:00
|
|
|
static ShaderOutput *node_find_output_by_name(BL::Node b_node,
|
|
|
|
|
ShaderNode *node,
|
|
|
|
|
BL::NodeSocket &b_socket)
|
2013-03-18 16:34:57 +00:00
|
|
|
{
|
2021-08-11 15:42:36 +02:00
|
|
|
string name = b_socket.identifier();
|
|
|
|
|
ShaderOutput *output = node->output(name.c_str());
|
2014-09-19 12:57:09 +02:00
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
if (!output && node_use_modified_socket_name(node)) {
|
|
|
|
|
/* Different internal name for shader. */
|
|
|
|
|
if (name == "Shader") {
|
2013-10-30 11:21:31 +00:00
|
|
|
name = "Closure";
|
2021-08-11 15:42:36 +02:00
|
|
|
output = node->output(name.c_str());
|
|
|
|
|
}
|
2022-08-30 11:05:46 +01:00
|
|
|
/* Map internal name for shader. */
|
|
|
|
|
if (b_node.is_a(&RNA_ShaderNodeMix)) {
|
|
|
|
|
if (string_endswith(name, "Result_Float")) {
|
|
|
|
|
string_replace(name, "Result_Float", "Result");
|
|
|
|
|
output = node->output(name.c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "Result_Color")) {
|
|
|
|
|
string_replace(name, "Result_Color", "Result");
|
|
|
|
|
output = node->output(name.c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (string_endswith(name, "Result_Vector")) {
|
|
|
|
|
string_replace(name, "Result_Vector", "Result");
|
|
|
|
|
output = node->output(name.c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2014-09-19 12:57:09 +02:00
|
|
|
|
2021-08-11 15:42:36 +02:00
|
|
|
return output;
|
2011-09-16 13:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
static void add_nodes(Scene *scene,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::RenderEngine &b_engine,
|
|
|
|
|
BL::BlendData &b_data,
|
2018-02-28 13:54:00 -03:00
|
|
|
BL::Depsgraph &b_depsgraph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::Scene &b_scene,
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
ShaderGraph *graph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::ShaderNodeTree &b_ntree,
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
const ProxyMap &proxy_input_map,
|
|
|
|
|
const ProxyMap &proxy_output_map)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
/* add nodes */
|
2013-03-18 16:34:57 +00:00
|
|
|
PtrInputMap input_map;
|
|
|
|
|
PtrOutputMap output_map;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-20 20:29:05 +01:00
|
|
|
/* find the node to use for output if there are multiple */
|
2024-12-29 17:32:00 +01:00
|
|
|
const BL::ShaderNode output_node = b_ntree.get_output_node(
|
2018-07-05 12:44:15 +02:00
|
|
|
BL::ShaderNodeOutputMaterial::target_CYCLES);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-20 20:29:05 +01:00
|
|
|
/* add nodes */
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::Node &b_node : b_ntree.nodes) {
|
|
|
|
|
if (b_node.mute() || b_node.is_a(&RNA_NodeReroute)) {
|
2013-03-18 16:34:57 +00:00
|
|
|
/* replace muted node with internal links */
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeLink &b_link : b_node.internal_links) {
|
|
|
|
|
BL::NodeSocket to_socket(b_link.to_socket());
|
2024-12-29 17:32:00 +01:00
|
|
|
const SocketType::Type to_socket_type = convert_socket_type(to_socket);
|
2018-08-24 14:36:18 +02:00
|
|
|
if (to_socket_type == SocketType::UNDEFINED) {
|
2018-01-30 15:05:19 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-01-12 00:48:56 +01:00
|
|
|
/* Muted nodes can result in multiple Cycles input sockets mapping to the same Blender
|
|
|
|
|
* input socket, so this needs to be a multimap. */
|
|
|
|
|
input_map.emplace(b_link.from_socket().ptr.data, proxy->inputs[0]);
|
2021-01-25 16:20:10 +01:00
|
|
|
output_map[b_link.to_socket().ptr.data] = proxy->outputs[0];
|
2012-10-24 21:05:44 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-01-25 16:20:10 +01:00
|
|
|
else if (b_node.is_a(&RNA_ShaderNodeGroup) || b_node.is_a(&RNA_NodeCustomGroup) ||
|
|
|
|
|
b_node.is_a(&RNA_ShaderNodeCustomGroup))
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-10 12:19:39 +00:00
|
|
|
BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
|
2024-12-26 17:53:59 +01:00
|
|
|
if (b_node.is_a(&RNA_ShaderNodeGroup)) {
|
2021-01-25 16:20:10 +01:00
|
|
|
b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(b_node)).node_tree());
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
else if (b_node.is_a(&RNA_NodeCustomGroup)) {
|
2021-01-25 16:20:10 +01:00
|
|
|
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(b_node)).node_tree());
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2021-01-25 16:20:10 +01:00
|
|
|
b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(b_node)).node_tree());
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
ProxyMap group_proxy_input_map;
|
|
|
|
|
ProxyMap group_proxy_output_map;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-20 13:17:35 +00:00
|
|
|
/* Add a proxy node for each socket
|
|
|
|
|
* Do this even if the node group has no internal tree,
|
|
|
|
|
* so that links have something to connect to and assert won't fail.
|
|
|
|
|
*/
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const SocketType::Type input_type = convert_socket_type(b_input);
|
2018-08-24 14:36:18 +02:00
|
|
|
if (input_type == SocketType::UNDEFINED) {
|
2018-01-30 15:05:19 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ConvertNode *proxy = graph->create_node<ConvertNode>(input_type, input_type, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-20 13:17:35 +00:00
|
|
|
/* register the proxy node for internal binding */
|
2021-01-25 16:20:10 +01:00
|
|
|
group_proxy_input_map[b_input.identifier()] = proxy;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-01-12 00:48:56 +01:00
|
|
|
input_map.emplace(b_input.ptr.data, proxy->inputs[0]);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
|
2011-12-18 15:34:06 +00:00
|
|
|
}
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const SocketType::Type output_type = convert_socket_type(b_output);
|
2018-08-24 14:36:18 +02:00
|
|
|
if (output_type == SocketType::UNDEFINED) {
|
2018-01-30 15:05:19 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
ConvertNode *proxy = graph->create_node<ConvertNode>(output_type, output_type, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-20 13:17:35 +00:00
|
|
|
/* register the proxy node for internal binding */
|
2021-01-25 16:20:10 +01:00
|
|
|
group_proxy_output_map[b_output.identifier()] = proxy;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
output_map[b_output.ptr.data] = proxy->outputs[0];
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-06-01 18:11:57 +05:00
|
|
|
if (b_group_ntree) {
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
add_nodes(scene,
|
|
|
|
|
b_engine,
|
|
|
|
|
b_data,
|
2018-02-28 13:54:00 -03:00
|
|
|
b_depsgraph,
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
b_scene,
|
|
|
|
|
graph,
|
|
|
|
|
b_group_ntree,
|
|
|
|
|
group_proxy_input_map,
|
|
|
|
|
group_proxy_output_map);
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-01-25 16:20:10 +01:00
|
|
|
else if (b_node.is_a(&RNA_NodeGroupInput)) {
|
2013-03-20 13:17:35 +00:00
|
|
|
/* map each socket to a proxy node */
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output.identifier());
|
2015-03-28 00:15:15 +05:00
|
|
|
if (proxy_it != proxy_input_map.end()) {
|
2016-05-02 00:05:16 +02:00
|
|
|
ConvertNode *proxy = proxy_it->second;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
output_map[b_output.ptr.data] = proxy->outputs[0];
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-01-25 16:20:10 +01:00
|
|
|
else if (b_node.is_a(&RNA_NodeGroupOutput)) {
|
|
|
|
|
BL::NodeGroupOutput b_output_node(b_node);
|
2013-03-20 13:17:35 +00:00
|
|
|
/* only the active group output is used */
|
2015-03-28 00:15:15 +05:00
|
|
|
if (b_output_node.is_active_output()) {
|
2013-03-20 13:17:35 +00:00
|
|
|
/* map each socket to a proxy node */
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input.identifier());
|
2015-03-28 00:15:15 +05:00
|
|
|
if (proxy_it != proxy_output_map.end()) {
|
2016-05-02 00:05:16 +02:00
|
|
|
ConvertNode *proxy = proxy_it->second;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-01-12 00:48:56 +01:00
|
|
|
input_map.emplace(b_input.ptr.data, proxy->inputs[0]);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
else {
|
2024-12-26 17:53:55 +01:00
|
|
|
ShaderNode *node = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
if (b_node.ptr.data == output_node.ptr.data) {
|
2017-08-01 18:03:16 +02:00
|
|
|
node = graph->output();
|
2014-01-20 20:29:05 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2021-01-25 16:20:10 +01:00
|
|
|
BL::ShaderNode b_shader_node(b_node);
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
node = add_node(
|
2016-01-30 14:18:29 +01:00
|
|
|
scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
|
2014-01-20 20:29:05 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
if (node) {
|
2013-03-18 16:34:57 +00:00
|
|
|
/* map node sockets for linking */
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_input : b_node.inputs) {
|
2022-08-30 11:05:46 +01:00
|
|
|
if (b_input.is_unavailable()) {
|
|
|
|
|
/* Skip unavailable sockets. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ShaderInput *input = node_find_input_by_name(b_node, node, b_input);
|
2015-03-28 00:15:15 +05:00
|
|
|
if (!input) {
|
2014-06-06 09:25:05 +02:00
|
|
|
/* XXX should not happen, report error? */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-01-12 00:48:56 +01:00
|
|
|
input_map.emplace(b_input.ptr.data, input);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
set_default_value(input, b_input, b_data, b_ntree);
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeSocket &b_output : b_node.outputs) {
|
2022-08-30 11:05:46 +01:00
|
|
|
if (b_output.is_unavailable()) {
|
|
|
|
|
/* Skip unavailable sockets. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ShaderOutput *output = node_find_output_by_name(b_node, node, b_output);
|
2015-03-28 00:15:15 +05:00
|
|
|
if (!output) {
|
2014-06-06 09:25:05 +02:00
|
|
|
/* XXX should not happen, report error? */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-01-25 16:20:10 +01:00
|
|
|
output_map[b_output.ptr.data] = output;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* connect nodes */
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::NodeLink &b_link : b_ntree.links) {
|
2019-09-11 18:32:50 +02:00
|
|
|
/* Ignore invalid links to avoid unwanted cycles created in graph.
|
|
|
|
|
* Also ignore links with unavailable sockets. */
|
2021-03-16 19:11:54 +00:00
|
|
|
if (!(b_link.is_valid() && b_link.from_socket().enabled() && b_link.to_socket().enabled()) ||
|
|
|
|
|
b_link.is_muted())
|
|
|
|
|
{
|
2015-03-25 13:46:59 +05:00
|
|
|
continue;
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
/* get blender link data */
|
2024-12-29 17:32:00 +01:00
|
|
|
const BL::NodeSocket b_from_sock = b_link.from_socket();
|
|
|
|
|
const BL::NodeSocket b_to_sock = b_link.to_socket();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-01-12 00:48:56 +01:00
|
|
|
ShaderOutput *output = nullptr;
|
2024-12-29 17:32:00 +01:00
|
|
|
const PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
|
2024-12-26 17:53:59 +01:00
|
|
|
if (output_it != output_map.end()) {
|
2013-03-18 16:34:57 +00:00
|
|
|
output = output_it->second;
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 17:53:55 +01:00
|
|
|
/* either socket may be nullptr when the node was not exported, typically
|
2012-06-09 17:22:52 +00:00
|
|
|
* because the node type is not supported */
|
2023-01-12 00:48:56 +01:00
|
|
|
if (output != nullptr) {
|
|
|
|
|
ShaderOutput *output = output_it->second;
|
|
|
|
|
auto inputs = input_map.equal_range(b_to_sock.ptr.data);
|
|
|
|
|
for (PtrInputMap::iterator input_it = inputs.first; input_it != inputs.second; ++input_it) {
|
|
|
|
|
ShaderInput *input = input_it->second;
|
|
|
|
|
if (input != nullptr) {
|
|
|
|
|
graph->connect(output, input);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
static void add_nodes(Scene *scene,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::RenderEngine &b_engine,
|
|
|
|
|
BL::BlendData &b_data,
|
2018-02-28 13:54:00 -03:00
|
|
|
BL::Depsgraph &b_depsgraph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::Scene &b_scene,
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
ShaderGraph *graph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::ShaderNodeTree &b_ntree)
|
2013-04-11 09:16:36 +00:00
|
|
|
{
|
|
|
|
|
static const ProxyMap empty_proxy_map;
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
add_nodes(scene,
|
|
|
|
|
b_engine,
|
|
|
|
|
b_data,
|
2018-02-28 13:54:00 -03:00
|
|
|
b_depsgraph,
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 21:55:24 +05:00
|
|
|
b_scene,
|
|
|
|
|
graph,
|
|
|
|
|
b_ntree,
|
|
|
|
|
empty_proxy_map,
|
|
|
|
|
empty_proxy_map);
|
2013-04-11 09:16:36 +00:00
|
|
|
}
|
|
|
|
|
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
/* Look up and constant fold all references to View Layer attributes. */
|
|
|
|
|
void BlenderSync::resolve_view_layer_attributes(Shader *shader,
|
|
|
|
|
ShaderGraph *graph,
|
|
|
|
|
BL::Depsgraph &b_depsgraph)
|
|
|
|
|
{
|
|
|
|
|
bool updated = false;
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderNode *node : graph->nodes) {
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
if (node->is_a(AttributeNode::node_type)) {
|
|
|
|
|
AttributeNode *attr_node = static_cast<AttributeNode *>(node);
|
|
|
|
|
|
|
|
|
|
std::string real_name;
|
2024-12-29 17:32:00 +01:00
|
|
|
const BlenderAttributeType type = blender_attribute_name_split_type(
|
|
|
|
|
attr_node->get_attribute(), &real_name);
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
|
|
|
|
|
if (type == BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER) {
|
|
|
|
|
/* Look up the value. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const BL::ViewLayer b_layer = b_depsgraph.view_layer_eval();
|
|
|
|
|
const BL::Scene b_scene = b_depsgraph.scene_eval();
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
float4 value;
|
|
|
|
|
|
|
|
|
|
BKE_view_layer_find_rgba_attribute((::Scene *)b_scene.ptr.data,
|
|
|
|
|
(::ViewLayer *)b_layer.ptr.data,
|
|
|
|
|
real_name.c_str(),
|
|
|
|
|
&value.x);
|
|
|
|
|
|
|
|
|
|
/* Replace all outgoing links, using appropriate output types. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const float val_avg = (value.x + value.y + value.z) / 3.0f;
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderOutput *output : node->outputs) {
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
float val_float;
|
|
|
|
|
float3 val_float3;
|
|
|
|
|
|
|
|
|
|
if (output->type() == SocketType::FLOAT) {
|
|
|
|
|
val_float = (output->name() == "Alpha") ? value.w : val_avg;
|
|
|
|
|
val_float3 = make_float3(val_float);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val_float = val_avg;
|
2024-12-19 09:41:55 +01:00
|
|
|
val_float3 = make_float3(value);
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderInput *sock : output->links) {
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
if (sock->type() == SocketType::FLOAT) {
|
|
|
|
|
sock->set(val_float);
|
|
|
|
|
}
|
|
|
|
|
else if (SocketType::is_float3(sock->type())) {
|
|
|
|
|
sock->set(val_float3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sock->constant_folded_in = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
graph->disconnect(output);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear the attribute name to avoid further attempts to look up. */
|
|
|
|
|
attr_node->set_attribute(ustring());
|
|
|
|
|
updated = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (updated) {
|
|
|
|
|
shader_map.set_flag(shader, SHADER_WITH_LAYER_ATTRS);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
shader_map.clear_flag(shader, SHADER_WITH_LAYER_ATTRS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BlenderSync::scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph)
|
|
|
|
|
{
|
|
|
|
|
if (shader && shader_map.test_flag(shader, SHADER_WITH_LAYER_ATTRS)) {
|
|
|
|
|
BL::Scene scene = b_depsgraph.scene_eval();
|
|
|
|
|
|
|
|
|
|
return shader_map.check_recalc(scene) || shader_map.check_recalc(scene.world()) ||
|
|
|
|
|
shader_map.check_recalc(scene.camera());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Sync Materials */
|
|
|
|
|
|
2018-02-26 16:46:48 +01:00
|
|
|
void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2016-05-14 14:50:03 +02:00
|
|
|
shader_map.set_default(scene->default_surface);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-12-14 23:47:39 +01:00
|
|
|
TaskPool pool;
|
2017-04-04 13:36:58 +02:00
|
|
|
set<Shader *> updated_shaders;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::ID &b_id : b_depsgraph.ids) {
|
|
|
|
|
if (!b_id.is_a(&RNA_Material)) {
|
2018-05-29 15:57:14 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
BL::Material b_mat(b_id);
|
2011-04-27 11:58:34 +00:00
|
|
|
Shader *shader;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* test if we need to sync */
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
if (shader_map.add_or_update(&shader, b_mat) || update_all ||
|
|
|
|
|
scene_attr_needs_recalc(shader, b_depsgraph))
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-29 15:57:14 +02:00
|
|
|
shader->name = b_mat.name().c_str();
|
2020-11-04 11:17:38 +01:00
|
|
|
shader->set_pass_id(b_mat.pass_index());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-05-31 11:28:04 +00:00
|
|
|
/* create nodes */
|
2018-05-29 15:57:14 +02:00
|
|
|
if (b_mat.use_nodes() && b_mat.node_tree()) {
|
|
|
|
|
BL::ShaderNodeTree b_ntree(b_mat.node_tree());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph.get(), b_ntree);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2011-05-31 11:28:04 +00:00
|
|
|
else {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
diffuse->set_color(get_float3(b_mat.diffuse_color()));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-07 19:48:28 +02:00
|
|
|
ShaderNode *out = graph->output();
|
|
|
|
|
graph->connect(diffuse->output("BSDF"), out->input("Surface"));
|
2011-05-31 11:28:04 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* settings */
|
2018-05-29 15:57:14 +02:00
|
|
|
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
|
2022-11-30 20:50:11 +01:00
|
|
|
shader->set_emission_sampling_method(get_emission_sampling(cmat));
|
2023-11-06 15:45:00 +01:00
|
|
|
shader->set_use_transparent_shadow(b_mat.use_transparent_shadow());
|
2023-10-11 15:07:21 +02:00
|
|
|
shader->set_use_bump_map_correction(get_boolean(cmat, "use_bump_map_correction"));
|
2020-11-04 11:17:38 +01:00
|
|
|
shader->set_heterogeneous_volume(!get_boolean(cmat, "homogeneous_volume"));
|
|
|
|
|
shader->set_volume_sampling_method(get_volume_sampling(cmat));
|
|
|
|
|
shader->set_volume_interpolation_method(get_volume_interpolation(cmat));
|
|
|
|
|
shader->set_volume_step_rate(get_float(cmat, "volume_step_rate"));
|
2023-11-21 19:55:38 +01:00
|
|
|
shader->set_displacement_method(get_displacement_method(b_mat));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-03-31 15:29:20 +02:00
|
|
|
/* By simplifying the shader graph as soon as possible, some
|
|
|
|
|
* redundant shader nodes might be removed which prevents loading
|
|
|
|
|
* unnecessary attributes later.
|
2016-12-14 23:47:39 +01:00
|
|
|
*
|
2017-03-31 15:29:20 +02:00
|
|
|
* However, since graph simplification also accounts for e.g. mix
|
|
|
|
|
* weight, this would cause frequent expensive resyncs in interactive
|
|
|
|
|
* sessions, so for those sessions optimization is only performed
|
|
|
|
|
* right before compiling.
|
|
|
|
|
*/
|
2016-12-14 23:47:39 +01:00
|
|
|
if (!preview) {
|
2024-12-29 23:13:45 +01:00
|
|
|
pool.push([graph = shader->graph.get(), scene = scene] { graph->simplify(scene); });
|
2017-04-04 13:36:58 +02:00
|
|
|
/* NOTE: Update shaders out of the threads since those routines
|
|
|
|
|
* are accessing and writing to a global context.
|
|
|
|
|
*/
|
|
|
|
|
updated_shaders.insert(shader);
|
2017-03-31 15:29:20 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* NOTE: Update tagging can access links which are being
|
|
|
|
|
* optimized out.
|
|
|
|
|
*/
|
|
|
|
|
shader->tag_update(scene);
|
2016-12-14 23:47:39 +01:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-12-14 23:47:39 +01:00
|
|
|
pool.wait_work();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Shader *shader : updated_shaders) {
|
2017-04-04 13:36:58 +02:00
|
|
|
shader->tag_update(scene);
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sync World */
|
|
|
|
|
|
2019-08-27 15:47:30 +02:00
|
|
|
void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
Background *background = scene->background;
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
Integrator *integrator = scene->integrator;
|
2021-10-21 17:42:15 +02:00
|
|
|
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-09 12:16:16 +01:00
|
|
|
BL::World b_world = view_layer.world_override ? view_layer.world_override : b_scene.world();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
|
2019-08-27 15:47:30 +02:00
|
|
|
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
Shader *shader = scene->default_background;
|
|
|
|
|
|
2019-08-27 15:47:30 +02:00
|
|
|
if (world_recalc || update_all || b_world.ptr.data != world_map ||
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
viewport_parameters.shader_modified(new_viewport_parameters) ||
|
|
|
|
|
scene_attr_needs_recalc(shader, b_depsgraph))
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* create nodes */
|
2019-08-27 15:47:30 +02:00
|
|
|
if (new_viewport_parameters.use_scene_world && b_world && b_world.use_nodes() &&
|
|
|
|
|
b_world.node_tree())
|
|
|
|
|
{
|
2011-04-27 11:58:34 +00:00
|
|
|
BL::ShaderNodeTree b_ntree(b_world.node_tree());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph.get(), b_ntree);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-08 11:00:06 +01:00
|
|
|
/* volume */
|
|
|
|
|
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
|
2020-11-04 11:17:38 +01:00
|
|
|
shader->set_heterogeneous_volume(!get_boolean(cworld, "homogeneous_volume"));
|
|
|
|
|
shader->set_volume_sampling_method(get_volume_sampling(cworld));
|
|
|
|
|
shader->set_volume_interpolation_method(get_volume_interpolation(cworld));
|
|
|
|
|
shader->set_volume_step_rate(get_float(cworld, "volume_step_size"));
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-08-27 15:47:30 +02:00
|
|
|
else if (new_viewport_parameters.use_scene_world && b_world) {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
BackgroundNode *background = graph->create_node<BackgroundNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
background->set_color(get_float3(b_world.color()));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-07 19:48:28 +02:00
|
|
|
ShaderNode *out = graph->output();
|
|
|
|
|
graph->connect(background->output("Background"), out->input("Surface"));
|
2011-05-31 11:28:04 +00:00
|
|
|
}
|
2019-08-27 15:47:30 +02:00
|
|
|
else if (!new_viewport_parameters.use_scene_world) {
|
2019-10-07 11:31:47 +02:00
|
|
|
float3 world_color;
|
|
|
|
|
if (b_world) {
|
|
|
|
|
world_color = get_float3(b_world.color());
|
|
|
|
|
}
|
|
|
|
|
else {
|
2021-02-17 01:47:18 +01:00
|
|
|
world_color = zero_float3();
|
2019-10-07 11:31:47 +02:00
|
|
|
}
|
|
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
BackgroundNode *background = graph->create_node<BackgroundNode>();
|
|
|
|
|
LightPathNode *light_path = graph->create_node<LightPathNode>();
|
2019-08-27 15:47:30 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MixNode *mix_scene_with_background = graph->create_node<MixNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
mix_scene_with_background->set_color2(world_color);
|
2019-08-27 15:47:30 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
EnvironmentTextureNode *texture_environment = graph->create_node<EnvironmentTextureNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
texture_environment->set_tex_mapping_type(TextureMapping::VECTOR);
|
|
|
|
|
float3 rotation_z = texture_environment->get_tex_mapping_rotation();
|
|
|
|
|
rotation_z[2] = new_viewport_parameters.studiolight_rotate_z;
|
|
|
|
|
texture_environment->set_tex_mapping_rotation(rotation_z);
|
|
|
|
|
texture_environment->set_filename(new_viewport_parameters.studiolight_path);
|
2019-08-27 15:47:30 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MixNode *mix_intensity = graph->create_node<MixNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
mix_intensity->set_mix_type(NODE_MIX_MUL);
|
|
|
|
|
mix_intensity->set_fac(1.0f);
|
|
|
|
|
mix_intensity->set_color2(make_float3(new_viewport_parameters.studiolight_intensity,
|
|
|
|
|
new_viewport_parameters.studiolight_intensity,
|
|
|
|
|
new_viewport_parameters.studiolight_intensity));
|
2019-09-04 16:22:47 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
TextureCoordinateNode *texture_coordinate = graph->create_node<TextureCoordinateNode>();
|
2019-08-27 15:47:30 +02:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
MixNode *mix_background_with_environment = graph->create_node<MixNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
mix_background_with_environment->set_fac(
|
|
|
|
|
new_viewport_parameters.studiolight_background_alpha);
|
|
|
|
|
mix_background_with_environment->set_color1(world_color);
|
2019-08-27 15:47:30 +02:00
|
|
|
|
|
|
|
|
ShaderNode *out = graph->output();
|
|
|
|
|
|
|
|
|
|
graph->connect(texture_coordinate->output("Generated"),
|
|
|
|
|
texture_environment->input("Vector"));
|
2019-09-04 16:22:47 +02:00
|
|
|
graph->connect(texture_environment->output("Color"), mix_intensity->input("Color1"));
|
2019-08-27 15:47:30 +02:00
|
|
|
graph->connect(light_path->output("Is Camera Ray"), mix_scene_with_background->input("Fac"));
|
2019-09-04 16:22:47 +02:00
|
|
|
graph->connect(mix_intensity->output("Color"), mix_scene_with_background->input("Color1"));
|
|
|
|
|
graph->connect(mix_intensity->output("Color"),
|
2019-08-27 15:47:30 +02:00
|
|
|
mix_background_with_environment->input("Color2"));
|
|
|
|
|
graph->connect(mix_background_with_environment->output("Color"),
|
|
|
|
|
mix_scene_with_background->input("Color2"));
|
|
|
|
|
graph->connect(mix_scene_with_background->output("Color"), background->input("Color"));
|
|
|
|
|
graph->connect(background->output("Background"), out->input("Surface"));
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-10-21 17:42:15 +02:00
|
|
|
/* Visibility */
|
2012-02-28 16:45:08 +00:00
|
|
|
if (b_world) {
|
2013-06-10 20:34:34 +00:00
|
|
|
PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
|
|
|
|
|
uint visibility = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-10 20:34:34 +00:00
|
|
|
visibility |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
|
|
|
|
|
visibility |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0;
|
|
|
|
|
visibility |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0;
|
|
|
|
|
visibility |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0;
|
2014-09-05 16:17:24 +02:00
|
|
|
visibility |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
background->set_visibility(visibility);
|
2012-02-28 16:45:08 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->tag_update(scene);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-10-21 17:42:15 +02:00
|
|
|
/* Fast GI */
|
|
|
|
|
if (b_world) {
|
|
|
|
|
BL::WorldLighting b_light = b_world.light_settings();
|
|
|
|
|
enum { FAST_GI_METHOD_REPLACE = 0, FAST_GI_METHOD_ADD = 1, FAST_GI_METHOD_NUM };
|
|
|
|
|
|
|
|
|
|
const bool use_fast_gi = get_boolean(cscene, "use_fast_gi");
|
|
|
|
|
if (use_fast_gi) {
|
|
|
|
|
const int fast_gi_method = get_enum(
|
|
|
|
|
cscene, "fast_gi_method", FAST_GI_METHOD_NUM, FAST_GI_METHOD_REPLACE);
|
|
|
|
|
integrator->set_ao_factor((fast_gi_method == FAST_GI_METHOD_REPLACE) ? b_light.ao_factor() :
|
|
|
|
|
0.0f);
|
|
|
|
|
integrator->set_ao_additive_factor(
|
|
|
|
|
(fast_gi_method == FAST_GI_METHOD_ADD) ? b_light.ao_factor() : 0.0f);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
integrator->set_ao_factor(0.0f);
|
|
|
|
|
integrator->set_ao_additive_factor(0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
integrator->set_ao_distance(b_light.distance());
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
integrator->set_ao_factor(0.0f);
|
|
|
|
|
integrator->set_ao_additive_factor(0.0f);
|
|
|
|
|
integrator->set_ao_distance(10.0f);
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
background->set_transparent(b_scene.render().film_transparent());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
if (background->get_transparent()) {
|
|
|
|
|
background->set_transparent_glass(get_boolean(cscene, "film_transparent_glass"));
|
|
|
|
|
background->set_transparent_roughness_threshold(
|
|
|
|
|
get_float(cscene, "film_transparent_roughness"));
|
2018-01-11 20:03:31 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2020-11-04 11:17:38 +01:00
|
|
|
background->set_transparent_glass(false);
|
|
|
|
|
background->set_transparent_roughness_threshold(0.0f);
|
2018-01-11 20:03:31 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-27 11:11:49 +02:00
|
|
|
background->set_use_shader(view_layer.use_background_shader ||
|
2021-05-27 11:16:40 +02:00
|
|
|
viewport_parameters.use_custom_shader());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-04-02 00:11:11 +02:00
|
|
|
background->set_lightgroup(ustring(b_world ? b_world.lightgroup() : ""));
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
background->tag_update(scene);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-27 14:41:53 +02:00
|
|
|
/* Sync Lights */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2018-06-27 14:41:53 +02:00
|
|
|
void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2016-05-14 14:50:03 +02:00
|
|
|
shader_map.set_default(scene->default_light);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
for (BL::ID &b_id : b_depsgraph.ids) {
|
|
|
|
|
if (!b_id.is_a(&RNA_Light)) {
|
2018-05-29 15:57:14 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-01-25 16:20:10 +01:00
|
|
|
BL::Light b_light(b_id);
|
2011-04-27 11:58:34 +00:00
|
|
|
Shader *shader;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* test if we need to sync */
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
if (shader_map.add_or_update(&shader, b_light) || update_all ||
|
|
|
|
|
scene_attr_needs_recalc(shader, b_depsgraph))
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* create nodes */
|
2018-06-27 14:41:53 +02:00
|
|
|
if (b_light.use_nodes() && b_light.node_tree()) {
|
|
|
|
|
shader->name = b_light.name().c_str();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-27 14:41:53 +02:00
|
|
|
BL::ShaderNodeTree b_ntree(b_light.node_tree());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph.get(), b_ntree);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2011-05-31 11:28:04 +00:00
|
|
|
else {
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 23:20:51 +02:00
|
|
|
EmissionNode *emission = graph->create_node<EmissionNode>();
|
2021-02-17 01:47:18 +01:00
|
|
|
emission->set_color(one_float3());
|
2020-11-04 11:17:38 +01:00
|
|
|
emission->set_strength(1.0f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-07 19:48:28 +02:00
|
|
|
ShaderNode *out = graph->output();
|
|
|
|
|
graph->connect(emission->output("Emission"), out->input("Surface"));
|
2011-05-31 11:28:04 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
|
Attribute Node: support accessing attributes of View Layer and Scene.
The attribute node already allows accessing attributes associated
with objects and meshes, which allows changing the behavior of the
same material between different objects or instances. The same idea
can be extended to an even more global level of layers and scenes.
Currently view layers provide an option to replace all materials
with a different one. However, since the same material will be applied
to all objects in the layer, varying the behavior between layers while
preserving distinct materials requires duplicating objects.
Providing access to properties of layers and scenes via the attribute
node enables making materials with built-in switches or settings that
can be controlled globally at the view layer level. This is probably
most useful for complex NPR shading and compositing. Like with objects,
the node can also access built-in scene properties, like render resolution
or FOV of the active camera. Lookup is also attempted in World, similar
to how the Object mode checks the Mesh datablock.
In Cycles this mode is implemented by replacing the attribute node with
the attribute value during sync, allowing constant folding to take the
values into account. This means however that materials that use this
feature have to be re-synced upon any changes to scene, world or camera.
The Eevee version uses a new uniform buffer containing a sorted array
mapping name hashes to values, with binary search lookup. The array
is limited to 512 entries, which is effectively limitless even
considering it is shared by all materials in the scene; it is also
just 16KB of memory so no point trying to optimize further.
The buffer has to be rebuilt when new attributes are detected in a
material, so the draw engine keeps a table of recently seen attribute
names to minimize the chance of extra rebuilds mid-draw.
Differential Revision: https://developer.blender.org/D15941
2022-09-12 00:30:58 +03:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->tag_update(scene);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-01 19:45:36 +01:00
|
|
|
void BlenderSync::sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
shader_map.pre_sync();
|
|
|
|
|
|
2022-03-01 19:45:36 +01:00
|
|
|
sync_world(b_depsgraph, b_v3d, update_all);
|
|
|
|
|
sync_lights(b_depsgraph, update_all);
|
|
|
|
|
sync_materials(b_depsgraph, update_all);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|