Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/blender_geometry.cpp6
-rw-r--r--intern/cycles/blender/blender_id_map.h49
-rw-r--r--intern/cycles/blender/blender_light.cpp6
-rw-r--r--intern/cycles/blender/blender_object.cpp14
-rw-r--r--intern/cycles/blender/blender_particles.cpp3
-rw-r--r--intern/cycles/blender/blender_shader.cpp205
-rw-r--r--intern/cycles/blender/blender_sync.cpp12
-rw-r--r--intern/cycles/graph/node.cpp16
-rw-r--r--intern/cycles/graph/node.h10
-rw-r--r--intern/cycles/render/graph.cpp32
-rw-r--r--intern/cycles/render/graph.h30
-rw-r--r--intern/cycles/render/nodes.cpp49
-rw-r--r--intern/cycles/render/nodes.h12
-rw-r--r--intern/cycles/render/osl.cpp5
-rw-r--r--intern/cycles/render/osl.h3
-rw-r--r--intern/cycles/render/particles.cpp8
-rw-r--r--intern/cycles/render/particles.h6
-rw-r--r--intern/cycles/render/scene.cpp134
-rw-r--r--intern/cycles/render/scene.h72
-rw-r--r--intern/cycles/render/shader.cpp21
20 files changed, 461 insertions, 232 deletions
diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp
index 9a82c5e9371..002f5e0fdb7 100644
--- a/intern/cycles/blender/blender_geometry.cpp
+++ b/intern/cycles/blender/blender_geometry.cpp
@@ -83,13 +83,13 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
if (geom == NULL) {
/* Add new geometry if it did not exist yet. */
if (geom_type == Geometry::HAIR) {
- geom = new Hair();
+ geom = scene->create_node<Hair>();
}
else if (geom_type == Geometry::VOLUME) {
- geom = new Volume();
+ geom = scene->create_node<Volume>();
}
else {
- geom = new Mesh();
+ geom = scene->create_node<Mesh>();
}
geometry_map.add(key, geom);
}
diff --git a/intern/cycles/blender/blender_id_map.h b/intern/cycles/blender/blender_id_map.h
index b5f6aaa67a8..f9f201c2e4e 100644
--- a/intern/cycles/blender/blender_id_map.h
+++ b/intern/cycles/blender/blender_id_map.h
@@ -19,6 +19,8 @@
#include <string.h>
+#include "render/scene.h"
+
#include "util/util_map.h"
#include "util/util_set.h"
#include "util/util_vector.h"
@@ -32,9 +34,8 @@ CCL_NAMESPACE_BEGIN
template<typename K, typename T> class id_map {
public:
- id_map(vector<T *> *scene_data_)
+ id_map()
{
- scene_data = scene_data_;
}
T *find(const BL::ID &id)
@@ -76,7 +77,6 @@ template<typename K, typename T> class id_map {
void add(const K &key, T *data)
{
assert(find(key) == NULL);
- scene_data->push_back(data);
b_map[key] = data;
used(data);
}
@@ -97,22 +97,23 @@ template<typename K, typename T> class id_map {
}
/* Combined add and update as needed. */
- bool add_or_update(T **r_data, const BL::ID &id)
+ bool add_or_update(Scene *scene, T **r_data, const BL::ID &id)
{
- return add_or_update(r_data, id, id, id.ptr.owner_id);
+ return add_or_update(scene, r_data, id, id, id.ptr.owner_id);
}
- bool add_or_update(T **r_data, const BL::ID &id, const K &key)
+ bool add_or_update(Scene *scene, T **r_data, const BL::ID &id, const K &key)
{
- return add_or_update(r_data, id, id, key);
+ return add_or_update(scene, r_data, id, id, key);
}
- bool add_or_update(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key)
+ bool add_or_update(
+ Scene *scene, T **r_data, const BL::ID &id, const BL::ID &parent, const K &key)
{
T *data = find(key);
bool recalc;
if (!data) {
/* Add data if it didn't exist yet. */
- data = new T();
+ data = scene->create_node<T>();
add(key, data);
recalc = true;
}
@@ -144,27 +145,8 @@ template<typename K, typename T> class id_map {
b_map[NULL] = data;
}
- bool post_sync(bool do_delete = true)
+ void post_sync(Scene *scene, bool do_delete = true)
{
- /* remove unused data */
- vector<T *> new_scene_data;
- typename vector<T *>::iterator it;
- bool deleted = false;
-
- for (it = scene_data->begin(); it != scene_data->end(); it++) {
- T *data = *it;
-
- if (do_delete && used_set.find(data) == used_set.end()) {
- delete data;
- deleted = true;
- }
- else
- new_scene_data.push_back(data);
- }
-
- *scene_data = new_scene_data;
-
- /* update mapping */
map<K, T *> new_map;
typedef pair<const K, T *> TMapPair;
typename map<K, T *>::iterator jt;
@@ -172,15 +154,17 @@ template<typename K, typename T> class id_map {
for (jt = b_map.begin(); jt != b_map.end(); jt++) {
TMapPair &pair = *jt;
- if (used_set.find(pair.second) != used_set.end())
+ if (do_delete && used_set.find(pair.second) == used_set.end()) {
+ scene->delete_node(pair.second);
+ }
+ else {
new_map[pair.first] = pair.second;
+ }
}
used_set.clear();
b_recalc.clear();
b_map = new_map;
-
- return deleted;
}
const map<K, T *> &key_to_scene_data()
@@ -189,7 +173,6 @@ template<typename K, typename T> class id_map {
}
protected:
- vector<T *> *scene_data;
map<K, T *> b_map;
set<T *> used_set;
set<void *> b_recalc;
diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp
index 6f95821e31e..117e9214e5a 100644
--- a/intern/cycles/blender/blender_light.cpp
+++ b/intern/cycles/blender/blender_light.cpp
@@ -39,9 +39,9 @@ void BlenderSync::sync_light(BL::Object &b_parent,
BL::Light b_light(b_ob.data());
/* Update if either object or light data changed. */
- if (!light_map.add_or_update(&light, b_ob, b_parent, key)) {
+ if (!light_map.add_or_update(scene, &light, b_ob, b_parent, key)) {
Shader *shader;
- if (!shader_map.add_or_update(&shader, b_light)) {
+ if (!shader_map.add_or_update(scene, &shader, b_light)) {
if (light->is_portal)
*use_portal = true;
return;
@@ -176,7 +176,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
Light *light;
ObjectKey key(b_world, 0, b_world, false);
- if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc ||
+ if (light_map.add_or_update(scene, &light, b_world, b_world, key) || world_recalc ||
b_world.ptr.data != world_map) {
light->type = LIGHT_BACKGROUND;
if (sampling_method == SAMPLING_MANUAL) {
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index e0792962b01..212b9cbe103 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -207,7 +207,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* test if we need to sync */
bool object_updated = false;
- if (object_map.add_or_update(&object, b_ob, b_parent, key))
+ if (object_map.add_or_update(scene, &object, b_ob, b_parent, key))
object_updated = true;
/* mesh sync */
@@ -405,14 +405,10 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
sync_background_light(b_v3d, use_portal);
/* handle removed data and modified pointers */
- if (light_map.post_sync())
- scene->light_manager->tag_update(scene);
- if (geometry_map.post_sync())
- scene->geometry_manager->tag_update(scene);
- if (object_map.post_sync())
- scene->object_manager->tag_update(scene);
- if (particle_system_map.post_sync())
- scene->particle_system_manager->tag_update(scene);
+ light_map.post_sync(scene);
+ geometry_map.post_sync(scene);
+ object_map.post_sync(scene);
+ particle_system_map.post_sync(scene);
}
if (motion)
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index e5eab1ae62b..ee14217988b 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -53,7 +53,8 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
ParticleSystem *psys;
bool first_use = !particle_system_map.is_used(key);
- bool need_update = particle_system_map.add_or_update(&psys, b_ob, b_instance.object(), key);
+ bool need_update = particle_system_map.add_or_update(
+ scene, &psys, b_ob, b_instance.object(), key);
/* no update needed? */
if (!need_update && !object->geometry->need_update && !scene->object_manager->need_update)
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index ae681432a43..03ed88ea9ec 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -224,7 +224,7 @@ static ShaderNode *add_node(Scene *scene,
if (b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
BL::ShaderNodeRGBCurve b_curve_node(b_node);
BL::CurveMapping mapping(b_curve_node.mapping());
- RGBCurvesNode *curves = new RGBCurvesNode();
+ RGBCurvesNode *curves = graph->create_node<RGBCurvesNode>();
curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true);
curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x);
node = curves;
@@ -232,13 +232,13 @@ static ShaderNode *add_node(Scene *scene,
if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
BL::ShaderNodeVectorCurve b_curve_node(b_node);
BL::CurveMapping mapping(b_curve_node.mapping());
- VectorCurvesNode *curves = new VectorCurvesNode();
+ VectorCurvesNode *curves = graph->create_node<VectorCurvesNode>();
curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false);
curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x);
node = curves;
}
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
- RGBRampNode *ramp = new RGBRampNode();
+ RGBRampNode *ramp = graph->create_node<RGBRampNode>();
BL::ShaderNodeValToRGB b_ramp_node(b_node);
BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE);
@@ -246,94 +246,94 @@ static ShaderNode *add_node(Scene *scene,
node = ramp;
}
else if (b_node.is_a(&RNA_ShaderNodeRGB)) {
- ColorNode *color = new ColorNode();
+ ColorNode *color = graph->create_node<ColorNode>();
color->value = get_node_output_rgba(b_node, "Color");
node = color;
}
else if (b_node.is_a(&RNA_ShaderNodeValue)) {
- ValueNode *value = new ValueNode();
+ ValueNode *value = graph->create_node<ValueNode>();
value->value = get_node_output_value(b_node, "Value");
node = value;
}
else if (b_node.is_a(&RNA_ShaderNodeCameraData)) {
- node = new CameraNode();
+ node = graph->create_node<CameraNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeInvert)) {
- node = new InvertNode();
+ node = graph->create_node<InvertNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeGamma)) {
- node = new GammaNode();
+ node = graph->create_node<GammaNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
- node = new BrightContrastNode();
+ node = graph->create_node<BrightContrastNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) {
BL::ShaderNodeMixRGB b_mix_node(b_node);
- MixNode *mix = new MixNode();
+ MixNode *mix = graph->create_node<MixNode>();
mix->type = (NodeMix)b_mix_node.blend_type();
mix->use_clamp = b_mix_node.use_clamp();
node = mix;
}
else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
- node = new SeparateRGBNode();
+ node = graph->create_node<SeparateRGBNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
- node = new CombineRGBNode();
+ node = graph->create_node<CombineRGBNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeSeparateHSV)) {
- node = new SeparateHSVNode();
+ node = graph->create_node<SeparateHSVNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
- node = new CombineHSVNode();
+ node = graph->create_node<CombineHSVNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
- node = new SeparateXYZNode();
+ node = graph->create_node<SeparateXYZNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
- node = new CombineXYZNode();
+ node = graph->create_node<CombineXYZNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
- node = new HSVNode();
+ node = graph->create_node<HSVNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
- node = new RGBToBWNode();
+ node = graph->create_node<RGBToBWNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
BL::ShaderNodeMapRange b_map_range_node(b_node);
- MapRangeNode *map_range_node = new MapRangeNode();
+ MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
map_range_node->clamp = b_map_range_node.clamp();
map_range_node->type = (NodeMapRangeType)b_map_range_node.interpolation_type();
node = map_range_node;
}
else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
BL::ShaderNodeClamp b_clamp_node(b_node);
- ClampNode *clamp_node = new ClampNode();
+ ClampNode *clamp_node = graph->create_node<ClampNode>();
clamp_node->type = (NodeClampType)b_clamp_node.clamp_type();
node = clamp_node;
}
else if (b_node.is_a(&RNA_ShaderNodeMath)) {
BL::ShaderNodeMath b_math_node(b_node);
- MathNode *math_node = new MathNode();
+ MathNode *math_node = graph->create_node<MathNode>();
math_node->type = (NodeMathType)b_math_node.operation();
math_node->use_clamp = b_math_node.use_clamp();
node = math_node;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
BL::ShaderNodeVectorMath b_vector_math_node(b_node);
- VectorMathNode *vector_math_node = new VectorMathNode();
+ VectorMathNode *vector_math_node = graph->create_node<VectorMathNode>();
vector_math_node->type = (NodeVectorMathType)b_vector_math_node.operation();
node = vector_math_node;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorRotate)) {
BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node);
- VectorRotateNode *vector_rotate_node = new VectorRotateNode();
+ VectorRotateNode *vector_rotate_node = graph->create_node<VectorRotateNode>();
vector_rotate_node->type = (NodeVectorRotateType)b_vector_rotate_node.rotation_type();
vector_rotate_node->invert = b_vector_rotate_node.invert();
node = vector_rotate_node;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
- VectorTransformNode *vtransform = new VectorTransformNode();
+ VectorTransformNode *vtransform = graph->create_node<VectorTransformNode>();
vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type();
vtransform->convert_from = (NodeVectorTransformConvertSpace)
b_vector_transform_node.convert_from();
@@ -344,43 +344,43 @@ static ShaderNode *add_node(Scene *scene,
BL::Node::outputs_iterator out_it;
b_node.outputs.begin(out_it);
- NormalNode *norm = new NormalNode();
+ NormalNode *norm = graph->create_node<NormalNode>();
norm->direction = get_node_output_vector(b_node, "Normal");
node = norm;
}
else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
BL::ShaderNodeMapping b_mapping_node(b_node);
- MappingNode *mapping = new MappingNode();
+ MappingNode *mapping = graph->create_node<MappingNode>();
mapping->type = (NodeMappingType)b_mapping_node.vector_type();
node = mapping;
}
else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
- node = new FresnelNode();
+ node = graph->create_node<FresnelNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
- node = new LayerWeightNode();
+ node = graph->create_node<LayerWeightNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeAddShader)) {
- node = new AddClosureNode();
+ node = graph->create_node<AddClosureNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
- node = new MixClosureNode();
+ node = graph->create_node<MixClosureNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
BL::ShaderNodeAttribute b_attr_node(b_node);
- AttributeNode *attr = new AttributeNode();
+ AttributeNode *attr = graph->create_node<AttributeNode>();
attr->attribute = b_attr_node.attribute_name();
node = attr;
}
else if (b_node.is_a(&RNA_ShaderNodeBackground)) {
- node = new BackgroundNode();
+ node = graph->create_node<BackgroundNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
- node = new HoldoutNode();
+ node = graph->create_node<HoldoutNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
- AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
+ AnisotropicBsdfNode *aniso = graph->create_node<AnisotropicBsdfNode>();
switch (b_aniso_node.distribution()) {
case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
@@ -400,12 +400,12 @@ static ShaderNode *add_node(Scene *scene,
node = aniso;
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
- node = new DiffuseBsdfNode();
+ node = graph->create_node<DiffuseBsdfNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
- SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
+ SubsurfaceScatteringNode *subsurface = graph->create_node<SubsurfaceScatteringNode>();
switch (b_subsurface_node.falloff()) {
case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
@@ -426,7 +426,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
- GlossyBsdfNode *glossy = new GlossyBsdfNode();
+ GlossyBsdfNode *glossy = graph->create_node<GlossyBsdfNode>();
switch (b_glossy_node.distribution()) {
case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
@@ -449,7 +449,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
BL::ShaderNodeBsdfGlass b_glass_node(b_node);
- GlassBsdfNode *glass = new GlassBsdfNode();
+ GlassBsdfNode *glass = graph->create_node<GlassBsdfNode>();
switch (b_glass_node.distribution()) {
case BL::ShaderNodeBsdfGlass::distribution_SHARP:
glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
@@ -468,7 +468,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
- RefractionBsdfNode *refraction = new RefractionBsdfNode();
+ RefractionBsdfNode *refraction = graph->create_node<RefractionBsdfNode>();
switch (b_refraction_node.distribution()) {
case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
refraction->distribution = CLOSURE_BSDF_REFRACTION_ID;
@@ -484,7 +484,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
BL::ShaderNodeBsdfToon b_toon_node(b_node);
- ToonBsdfNode *toon = new ToonBsdfNode();
+ ToonBsdfNode *toon = graph->create_node<ToonBsdfNode>();
switch (b_toon_node.component()) {
case BL::ShaderNodeBsdfToon::component_DIFFUSE:
toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID;
@@ -497,7 +497,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
BL::ShaderNodeBsdfHair b_hair_node(b_node);
- HairBsdfNode *hair = new HairBsdfNode();
+ HairBsdfNode *hair = graph->create_node<HairBsdfNode>();
switch (b_hair_node.component()) {
case BL::ShaderNodeBsdfHair::component_Reflection:
hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID;
@@ -510,7 +510,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
- PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode();
+ PrincipledHairBsdfNode *principled_hair = graph->create_node<PrincipledHairBsdfNode>();
principled_hair->parametrization = (NodePrincipledHairParametrization)get_enum(
b_principled_hair_node.ptr,
"parametrization",
@@ -520,7 +520,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
- PrincipledBsdfNode *principled = new PrincipledBsdfNode();
+ PrincipledBsdfNode *principled = graph->create_node<PrincipledBsdfNode>();
switch (b_principled_node.distribution()) {
case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
@@ -540,77 +540,77 @@ static ShaderNode *add_node(Scene *scene,
node = principled;
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
- node = new TranslucentBsdfNode();
+ node = graph->create_node<TranslucentBsdfNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
- node = new TransparentBsdfNode();
+ node = graph->create_node<TransparentBsdfNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) {
- node = new VelvetBsdfNode();
+ node = graph->create_node<VelvetBsdfNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeEmission)) {
- node = new EmissionNode();
+ node = graph->create_node<EmissionNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
- AmbientOcclusionNode *ao = new AmbientOcclusionNode();
+ AmbientOcclusionNode *ao = graph->create_node<AmbientOcclusionNode>();
ao->samples = b_ao_node.samples();
ao->inside = b_ao_node.inside();
ao->only_local = b_ao_node.only_local();
node = ao;
}
else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
- node = new ScatterVolumeNode();
+ node = graph->create_node<ScatterVolumeNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
- node = new AbsorptionVolumeNode();
+ node = graph->create_node<AbsorptionVolumeNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
- PrincipledVolumeNode *principled = new PrincipledVolumeNode();
+ PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
node = principled;
}
else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
- node = new GeometryNode();
+ node = graph->create_node<GeometryNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeWireframe)) {
BL::ShaderNodeWireframe b_wireframe_node(b_node);
- WireframeNode *wire = new WireframeNode();
+ WireframeNode *wire = graph->create_node<WireframeNode>();
wire->use_pixel_size = b_wireframe_node.use_pixel_size();
node = wire;
}
else if (b_node.is_a(&RNA_ShaderNodeWavelength)) {
- node = new WavelengthNode();
+ node = graph->create_node<WavelengthNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeBlackbody)) {
- node = new BlackbodyNode();
+ node = graph->create_node<BlackbodyNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeLightPath)) {
- node = new LightPathNode();
+ node = graph->create_node<LightPathNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
- node = new LightFalloffNode();
+ node = graph->create_node<LightFalloffNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
- node = new ObjectInfoNode();
+ node = graph->create_node<ObjectInfoNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
- node = new ParticleInfoNode();
+ node = graph->create_node<ParticleInfoNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
- node = new HairInfoNode();
+ node = graph->create_node<HairInfoNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
- node = new VolumeInfoNode();
+ node = graph->create_node<VolumeInfoNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeVertexColor)) {
BL::ShaderNodeVertexColor b_vertex_color_node(b_node);
- VertexColorNode *vertex_color_node = new VertexColorNode();
+ VertexColorNode *vertex_color_node = graph->create_node<VertexColorNode>();
vertex_color_node->layer_name = b_vertex_color_node.layer_name();
node = vertex_color_node;
}
else if (b_node.is_a(&RNA_ShaderNodeBump)) {
BL::ShaderNodeBump b_bump_node(b_node);
- BumpNode *bump = new BumpNode();
+ BumpNode *bump = graph->create_node<BumpNode>();
bump->invert = b_bump_node.invert();
node = bump;
}
@@ -624,12 +624,13 @@ static ShaderNode *add_node(Scene *scene,
string bytecode_hash = b_script_node.bytecode_hash();
if (!bytecode_hash.empty()) {
- node = OSLShaderManager::osl_node(manager, "", bytecode_hash, b_script_node.bytecode());
+ node = OSLShaderManager::osl_node(
+ graph, manager, "", bytecode_hash, b_script_node.bytecode());
}
else {
string absolute_filepath = blender_absolute_path(
b_data, b_ntree, b_script_node.filepath());
- node = OSLShaderManager::osl_node(manager, absolute_filepath, "");
+ node = OSLShaderManager::osl_node(graph, manager, absolute_filepath, "");
}
}
#else
@@ -641,7 +642,7 @@ static ShaderNode *add_node(Scene *scene,
BL::ShaderNodeTexImage b_image_node(b_node);
BL::Image b_image(b_image_node.image());
BL::ImageUser b_image_user(b_image_node.image_user());
- ImageTextureNode *image = new ImageTextureNode();
+ ImageTextureNode *image = graph->create_node<ImageTextureNode>();
image->interpolation = get_image_interpolation(b_image_node);
image->extension = get_image_extension(b_image_node);
@@ -693,7 +694,7 @@ static ShaderNode *add_node(Scene *scene,
BL::ShaderNodeTexEnvironment b_env_node(b_node);
BL::Image b_image(b_env_node.image());
BL::ImageUser b_image_user(b_env_node.image_user());
- EnvironmentTextureNode *env = new EnvironmentTextureNode();
+ EnvironmentTextureNode *env = graph->create_node<EnvironmentTextureNode>();
env->interpolation = get_image_interpolation(b_env_node);
env->projection = (NodeEnvironmentProjection)b_env_node.projection();
@@ -726,7 +727,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) {
BL::ShaderNodeTexGradient b_gradient_node(b_node);
- GradientTextureNode *gradient = new GradientTextureNode();
+ GradientTextureNode *gradient = graph->create_node<GradientTextureNode>();
gradient->type = (NodeGradientType)b_gradient_node.gradient_type();
BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
get_tex_mapping(&gradient->tex_mapping, b_texture_mapping);
@@ -734,7 +735,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
- VoronoiTextureNode *voronoi = new VoronoiTextureNode();
+ VoronoiTextureNode *voronoi = graph->create_node<VoronoiTextureNode>();
voronoi->dimensions = b_voronoi_node.voronoi_dimensions();
voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature();
voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance();
@@ -744,7 +745,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) {
BL::ShaderNodeTexMagic b_magic_node(b_node);
- MagicTextureNode *magic = new MagicTextureNode();
+ MagicTextureNode *magic = graph->create_node<MagicTextureNode>();
magic->depth = b_magic_node.turbulence_depth();
BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
get_tex_mapping(&magic->tex_mapping, b_texture_mapping);
@@ -752,7 +753,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexWave)) {
BL::ShaderNodeTexWave b_wave_node(b_node);
- WaveTextureNode *wave = new WaveTextureNode();
+ WaveTextureNode *wave = graph->create_node<WaveTextureNode>();
wave->type = (NodeWaveType)b_wave_node.wave_type();
wave->bands_direction = (NodeWaveBandsDirection)b_wave_node.bands_direction();
wave->rings_direction = (NodeWaveRingsDirection)b_wave_node.rings_direction();
@@ -763,14 +764,14 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) {
BL::ShaderNodeTexChecker b_checker_node(b_node);
- CheckerTextureNode *checker = new CheckerTextureNode();
+ CheckerTextureNode *checker = graph->create_node<CheckerTextureNode>();
BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
get_tex_mapping(&checker->tex_mapping, b_texture_mapping);
node = checker;
}
else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) {
BL::ShaderNodeTexBrick b_brick_node(b_node);
- BrickTextureNode *brick = new BrickTextureNode();
+ BrickTextureNode *brick = graph->create_node<BrickTextureNode>();
brick->offset = b_brick_node.offset();
brick->offset_frequency = b_brick_node.offset_frequency();
brick->squash = b_brick_node.squash();
@@ -781,7 +782,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) {
BL::ShaderNodeTexNoise b_noise_node(b_node);
- NoiseTextureNode *noise = new NoiseTextureNode();
+ NoiseTextureNode *noise = graph->create_node<NoiseTextureNode>();
noise->dimensions = b_noise_node.noise_dimensions();
BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
get_tex_mapping(&noise->tex_mapping, b_texture_mapping);
@@ -789,7 +790,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) {
BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
- MusgraveTextureNode *musgrave_node = new MusgraveTextureNode();
+ MusgraveTextureNode *musgrave_node = graph->create_node<MusgraveTextureNode>();
musgrave_node->type = (NodeMusgraveType)b_musgrave_node.musgrave_type();
musgrave_node->dimensions = b_musgrave_node.musgrave_dimensions();
BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping());
@@ -798,7 +799,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) {
BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
- TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
+ TextureCoordinateNode *tex_coord = graph->create_node<TextureCoordinateNode>();
tex_coord->from_dupli = b_tex_coord_node.from_instancer();
if (b_tex_coord_node.object()) {
tex_coord->use_transform = true;
@@ -808,7 +809,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
BL::ShaderNodeTexSky b_sky_node(b_node);
- SkyTextureNode *sky = new SkyTextureNode();
+ SkyTextureNode *sky = graph->create_node<SkyTextureNode>();
sky->type = (NodeSkyType)b_sky_node.sky_type();
sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction()));
sky->turbidity = b_sky_node.turbidity();
@@ -828,7 +829,7 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexIES)) {
BL::ShaderNodeTexIES b_ies_node(b_node);
- IESLightNode *ies = new IESLightNode();
+ IESLightNode *ies = graph->create_node<IESLightNode>();
switch (b_ies_node.mode()) {
case BL::ShaderNodeTexIES::mode_EXTERNAL:
ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath());
@@ -844,20 +845,20 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeTexWhiteNoise)) {
BL::ShaderNodeTexWhiteNoise b_tex_white_noise_node(b_node);
- WhiteNoiseTextureNode *white_noise_node = new WhiteNoiseTextureNode();
+ WhiteNoiseTextureNode *white_noise_node = graph->create_node<WhiteNoiseTextureNode>();
white_noise_node->dimensions = b_tex_white_noise_node.noise_dimensions();
node = white_noise_node;
}
else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
BL::ShaderNodeNormalMap b_normal_map_node(b_node);
- NormalMapNode *nmap = new NormalMapNode();
+ NormalMapNode *nmap = graph->create_node<NormalMapNode>();
nmap->space = (NodeNormalMapSpace)b_normal_map_node.space();
nmap->attribute = b_normal_map_node.uv_map();
node = nmap;
}
else if (b_node.is_a(&RNA_ShaderNodeTangent)) {
BL::ShaderNodeTangent b_tangent_node(b_node);
- TangentNode *tangent = new TangentNode();
+ TangentNode *tangent = graph->create_node<TangentNode>();
tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type();
tangent->axis = (NodeTangentAxis)b_tangent_node.axis();
tangent->attribute = b_tangent_node.uv_map();
@@ -865,14 +866,14 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeUVMap)) {
BL::ShaderNodeUVMap b_uvmap_node(b_node);
- UVMapNode *uvm = new UVMapNode();
+ UVMapNode *uvm = graph->create_node<UVMapNode>();
uvm->attribute = b_uvmap_node.uv_map();
uvm->from_dupli = b_uvmap_node.from_instancer();
node = uvm;
}
else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
- PointDensityTextureNode *point_density = new PointDensityTextureNode();
+ PointDensityTextureNode *point_density = graph->create_node<PointDensityTextureNode>();
point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
point_density->interpolation = get_image_interpolation(b_point_density_node);
point_density->handle = scene->image_manager->add_image(
@@ -897,26 +898,26 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeBevel)) {
BL::ShaderNodeBevel b_bevel_node(b_node);
- BevelNode *bevel = new BevelNode();
+ BevelNode *bevel = graph->create_node<BevelNode>();
bevel->samples = b_bevel_node.samples();
node = bevel;
}
else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) {
BL::ShaderNodeDisplacement b_disp_node(b_node);
- DisplacementNode *disp = new DisplacementNode();
+ DisplacementNode *disp = graph->create_node<DisplacementNode>();
disp->space = (NodeNormalMapSpace)b_disp_node.space();
node = disp;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
- VectorDisplacementNode *disp = new VectorDisplacementNode();
+ VectorDisplacementNode *disp = graph->create_node<VectorDisplacementNode>();
disp->space = (NodeNormalMapSpace)b_disp_node.space();
disp->attribute = "";
node = disp;
}
else if (b_node.is_a(&RNA_ShaderNodeOutputAOV)) {
BL::ShaderNodeOutputAOV b_aov_node(b_node);
- OutputAOVNode *aov = new OutputAOVNode();
+ OutputAOVNode *aov = graph->create_node<OutputAOVNode>();
aov->name = b_aov_node.name();
node = aov;
}
@@ -1038,7 +1039,7 @@ static void add_nodes(Scene *scene,
continue;
}
- ConvertNode *proxy = new ConvertNode(to_socket_type, to_socket_type, true);
+ ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
@@ -1069,7 +1070,7 @@ static void add_nodes(Scene *scene,
continue;
}
- ConvertNode *proxy = new ConvertNode(input_type, input_type, true);
+ ConvertNode *proxy = graph->create_node<ConvertNode>(input_type, input_type, true);
graph->add(proxy);
/* register the proxy node for internal binding */
@@ -1085,7 +1086,7 @@ static void add_nodes(Scene *scene,
continue;
}
- ConvertNode *proxy = new ConvertNode(output_type, output_type, true);
+ ConvertNode *proxy = graph->create_node<ConvertNode>(output_type, output_type, true);
graph->add(proxy);
/* register the proxy node for internal binding */
@@ -1240,7 +1241,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
- if (shader_map.add_or_update(&shader, b_mat) || update_all) {
+ if (shader_map.add_or_update(scene, &shader, b_mat) || update_all) {
ShaderGraph *graph = new ShaderGraph();
shader->name = b_mat.name().c_str();
@@ -1253,7 +1254,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
}
else {
- DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
+ DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
diffuse->color = get_float3(b_mat.diffuse_color());
graph->add(diffuse);
@@ -1336,7 +1337,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
shader->volume_step_rate = get_float(cworld, "volume_step_size");
}
else if (new_viewport_parameters.use_scene_world && b_world) {
- BackgroundNode *background = new BackgroundNode();
+ BackgroundNode *background = graph->create_node<BackgroundNode>();
background->color = get_float3(b_world.color());
graph->add(background);
@@ -1352,23 +1353,23 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
world_color = make_float3(0.0f, 0.0f, 0.0f);
}
- BackgroundNode *background = new BackgroundNode();
+ BackgroundNode *background = graph->create_node<BackgroundNode>();
graph->add(background);
- LightPathNode *light_path = new LightPathNode();
+ LightPathNode *light_path = graph->create_node<LightPathNode>();
graph->add(light_path);
- MixNode *mix_scene_with_background = new MixNode();
+ MixNode *mix_scene_with_background = graph->create_node<MixNode>();
mix_scene_with_background->color2 = world_color;
graph->add(mix_scene_with_background);
- EnvironmentTextureNode *texture_environment = new EnvironmentTextureNode();
+ EnvironmentTextureNode *texture_environment = graph->create_node<EnvironmentTextureNode>();
texture_environment->tex_mapping.type = TextureMapping::VECTOR;
texture_environment->tex_mapping.rotation[2] = new_viewport_parameters.studiolight_rotate_z;
texture_environment->filename = new_viewport_parameters.studiolight_path;
graph->add(texture_environment);
- MixNode *mix_intensity = new MixNode();
+ MixNode *mix_intensity = graph->create_node<MixNode>();
mix_intensity->type = NODE_MIX_MUL;
mix_intensity->fac = 1.0f;
mix_intensity->color2 = make_float3(new_viewport_parameters.studiolight_intensity,
@@ -1376,10 +1377,10 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
new_viewport_parameters.studiolight_intensity);
graph->add(mix_intensity);
- TextureCoordinateNode *texture_coordinate = new TextureCoordinateNode();
+ TextureCoordinateNode *texture_coordinate = graph->create_node<TextureCoordinateNode>();
graph->add(texture_coordinate);
- MixNode *mix_background_with_environment = new MixNode();
+ MixNode *mix_background_with_environment = graph->create_node<MixNode>();
mix_background_with_environment->fac = new_viewport_parameters.studiolight_background_alpha;
mix_background_with_environment->color1 = world_color;
graph->add(mix_background_with_environment);
@@ -1466,7 +1467,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
- if (shader_map.add_or_update(&shader, b_light) || update_all) {
+ if (shader_map.add_or_update(scene, &shader, b_light) || update_all) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@@ -1478,7 +1479,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
}
else {
- EmissionNode *emission = new EmissionNode();
+ EmissionNode *emission = graph->create_node<EmissionNode>();
emission->color = make_float3(1.0f, 1.0f, 1.0f);
emission->strength = 1.0f;
graph->add(emission);
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index f0b5ab087bb..0126e5c8874 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -55,11 +55,11 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
: b_engine(b_engine),
b_data(b_data),
b_scene(b_scene),
- shader_map(&scene->shaders),
- object_map(&scene->objects),
- geometry_map(&scene->geometry),
- light_map(&scene->lights),
- particle_system_map(&scene->particle_systems),
+ shader_map(),
+ object_map(),
+ geometry_map(),
+ light_map(),
+ particle_system_map(),
world_map(NULL),
world_recalc(false),
scene(scene),
@@ -239,7 +239,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
/* Shader sync done at the end, since object sync uses it.
* false = don't delete unused shaders, not supported. */
- shader_map.post_sync(false);
+ shader_map.post_sync(scene, false);
free_data_after_sync(b_depsgraph);
}
diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp
index c437c6fda1e..14e66959f4f 100644
--- a/intern/cycles/graph/node.cpp
+++ b/intern/cycles/graph/node.cpp
@@ -26,10 +26,16 @@ CCL_NAMESPACE_BEGIN
/* Node Type */
+NodeOwner::~NodeOwner()
+{
+}
+
Node::Node(const NodeType *type_, ustring name_) : name(name_), type(type_)
{
assert(type);
+ owner = nullptr;
+
/* assign non-empty name, convenient for debugging */
if (name.empty()) {
name = type->name;
@@ -679,4 +685,14 @@ bool Node::is_a(const NodeType *type_)
return false;
}
+const NodeOwner *Node::get_owner() const
+{
+ return owner;
+}
+
+void Node::set_owner(const NodeOwner *owner_)
+{
+ owner_ = owner;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h
index 4473b8aca28..3c84dbdb4a7 100644
--- a/intern/cycles/graph/node.h
+++ b/intern/cycles/graph/node.h
@@ -31,6 +31,10 @@ struct Transform;
/* Node */
+struct NodeOwner {
+ virtual ~NodeOwner();
+};
+
struct Node {
explicit Node(const NodeType *type, ustring name = ustring());
virtual ~Node() = 0;
@@ -99,6 +103,12 @@ struct Node {
ustring name;
const NodeType *type;
+
+ const NodeOwner *get_owner() const;
+ void set_owner(const NodeOwner *owner_);
+
+ protected:
+ const NodeOwner *owner;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 1b138455515..684fe6a82c4 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -221,7 +221,7 @@ ShaderGraph::ShaderGraph()
finalized = false;
simplified = false;
num_node_ids = 0;
- add(new OutputNode());
+ add(create_node<OutputNode>());
}
ShaderGraph::~ShaderGraph()
@@ -272,7 +272,7 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
ShaderInput *convert_in;
if (to->type() == SocketType::CLOSURE) {
- EmissionNode *emission = new EmissionNode();
+ EmissionNode *emission = create_node<EmissionNode>();
emission->color = make_float3(1.0f, 1.0f, 1.0f);
emission->strength = 1.0f;
convert = add(emission);
@@ -285,7 +285,7 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
}
}
else {
- convert = add(new ConvertNode(from->type(), to->type(), true));
+ convert = add(create_node<ConvertNode>(from->type(), to->type(), true));
convert_in = convert->inputs[0];
}
@@ -416,7 +416,7 @@ void ShaderGraph::find_dependencies(ShaderNodeSet &dependencies, ShaderInput *in
void ShaderGraph::clear_nodes()
{
foreach (ShaderNode *node, nodes) {
- delete node;
+ delete_node(node);
}
nodes.clear();
}
@@ -428,7 +428,7 @@ void ShaderGraph::copy_nodes(ShaderNodeSet &nodes, ShaderNodeMap &nnodemap)
/* copy nodes */
foreach (ShaderNode *node, nodes) {
- ShaderNode *nnode = node->clone();
+ ShaderNode *nnode = node->clone(this);
nnodemap[node] = nnode;
/* create new inputs and outputs to recreate links and ensure
@@ -523,7 +523,7 @@ void ShaderGraph::remove_proxy_nodes()
if (!removed[node->id])
newnodes.push_back(node);
else
- delete node;
+ delete_node(node);
}
nodes = newnodes;
@@ -821,7 +821,7 @@ void ShaderGraph::clean(Scene *scene)
if (visited[node->id])
newnodes.push_back(node);
else
- delete node;
+ delete_node(node);
}
nodes = newnodes;
@@ -848,43 +848,43 @@ void ShaderGraph::default_inputs(bool do_osl)
if (!input->link && (!(input->flags() & SocketType::OSL_INTERNAL) || do_osl)) {
if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
if (!texco)
- texco = new TextureCoordinateNode();
+ texco = create_node<TextureCoordinateNode>();
connect(texco->output("Generated"), input);
}
if (input->flags() & SocketType::LINK_TEXTURE_NORMAL) {
if (!texco)
- texco = new TextureCoordinateNode();
+ texco = create_node<TextureCoordinateNode>();
connect(texco->output("Normal"), input);
}
else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
if (!texco)
- texco = new TextureCoordinateNode();
+ texco = create_node<TextureCoordinateNode>();
connect(texco->output("UV"), input);
}
else if (input->flags() & SocketType::LINK_INCOMING) {
if (!geom)
- geom = new GeometryNode();
+ geom = create_node<GeometryNode>();
connect(geom->output("Incoming"), input);
}
else if (input->flags() & SocketType::LINK_NORMAL) {
if (!geom)
- geom = new GeometryNode();
+ geom = create_node<GeometryNode>();
connect(geom->output("Normal"), input);
}
else if (input->flags() & SocketType::LINK_POSITION) {
if (!geom)
- geom = new GeometryNode();
+ geom = create_node<GeometryNode>();
connect(geom->output("Position"), input);
}
else if (input->flags() & SocketType::LINK_TANGENT) {
if (!geom)
- geom = new GeometryNode();
+ geom = create_node<GeometryNode>();
connect(geom->output("Tangent"), input);
}
@@ -1064,7 +1064,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
if (fin) {
/* mix closure: add node to mix closure weights */
- MixClosureWeightNode *mix_node = new MixClosureWeightNode();
+ MixClosureWeightNode *mix_node = create_node<MixClosureWeightNode>();
add(mix_node);
ShaderInput *fac_in = mix_node->input("Fac");
ShaderInput *weight_in = mix_node->input("Weight");
@@ -1101,7 +1101,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
/* already has a weight connected to it? add weights */
float weight_value = node->get_float(weight_in->socket_type);
if (weight_in->link || weight_value != 0.0f) {
- MathNode *math_node = new MathNode();
+ MathNode *math_node = create_node<MathNode>();
add(math_node);
if (weight_in->link)
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index febd7a76f03..f6ee708b3f8 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -159,7 +159,7 @@ class ShaderNode : public Node {
ShaderInput *input(ustring name);
ShaderOutput *output(ustring name);
- virtual ShaderNode *clone() const = 0;
+ virtual ShaderNode *clone(ShaderGraph *graph) const = 0;
virtual void attributes(Shader *shader, AttributeRequestSet *attributes);
virtual void compile(SVMCompiler &compiler) = 0;
virtual void compile(OSLCompiler &compiler) = 0;
@@ -275,9 +275,9 @@ class ShaderNode : public Node {
#define SHADER_NODE_CLASS(type) \
NODE_DECLARE \
type(); \
- virtual ShaderNode *clone() const \
+ virtual ShaderNode *clone(ShaderGraph *graph) const \
{ \
- return new type(*this); \
+ return graph->create_node<type>(*this); \
} \
virtual void compile(SVMCompiler &compiler); \
virtual void compile(OSLCompiler &compiler);
@@ -289,9 +289,9 @@ class ShaderNode : public Node {
virtual void compile(OSLCompiler &compiler);
#define SHADER_NODE_BASE_CLASS(type) \
- virtual ShaderNode *clone() const \
+ virtual ShaderNode *clone(ShaderGraph *graph) const \
{ \
- return new type(*this); \
+ return graph->create_node<type>(*this); \
} \
virtual void compile(SVMCompiler &compiler); \
virtual void compile(OSLCompiler &compiler);
@@ -312,7 +312,7 @@ typedef map<ShaderNode *, ShaderNode *, ShaderNodeIDComparator> ShaderNodeMap;
* Shader graph of nodes. Also does graph manipulations for default inputs,
* bump mapping from displacement, and possibly other things in the future. */
-class ShaderGraph {
+class ShaderGraph : public NodeOwner {
public:
list<ShaderNode *> nodes;
size_t num_node_ids;
@@ -345,6 +345,24 @@ class ShaderGraph {
void dump_graph(const char *filename);
+ /* This function is used to create a node of a specified type instead of
+ * calling 'new', and sets the graph as the owner of the node.
+ */
+ template<typename T, typename... Args> T *create_node(Args &&... args)
+ {
+ T *node = new T(args...);
+ node->set_owner(this);
+ return node;
+ }
+
+ /* This function is used to delete a node created and owned by the graph.
+ */
+ template<typename T> void delete_node(T *node)
+ {
+ assert(node->get_owner() == this);
+ delete node;
+ }
+
protected:
typedef pair<ShaderNode *const, ShaderNode *> NodePair;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index f62d64a7eb3..de32ce53ad7 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -262,9 +262,9 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
tiles.push_back(1001);
}
-ShaderNode *ImageTextureNode::clone() const
+ShaderNode *ImageTextureNode::clone(ShaderGraph *graph) const
{
- ImageTextureNode *node = new ImageTextureNode(*this);
+ ImageTextureNode *node = graph->create_node<ImageTextureNode>(*this);
node->handle = handle;
return node;
}
@@ -525,9 +525,9 @@ EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_typ
animated = false;
}
-ShaderNode *EnvironmentTextureNode::clone() const
+ShaderNode *EnvironmentTextureNode::clone(ShaderGraph *graph) const
{
- EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
+ EnvironmentTextureNode *node = graph->create_node<EnvironmentTextureNode>(*this);
node->handle = handle;
return node;
}
@@ -1234,9 +1234,9 @@ IESLightNode::IESLightNode() : TextureNode(node_type)
slot = -1;
}
-ShaderNode *IESLightNode::clone() const
+ShaderNode *IESLightNode::clone(ShaderGraph *graph) const
{
- IESLightNode *node = new IESLightNode(*this);
+ IESLightNode *node = graph->create_node<IESLightNode>(*this);
node->light_manager = NULL;
node->slot = -1;
@@ -1782,12 +1782,12 @@ PointDensityTextureNode::~PointDensityTextureNode()
{
}
-ShaderNode *PointDensityTextureNode::clone() const
+ShaderNode *PointDensityTextureNode::clone(ShaderGraph *graph) const
{
/* Increase image user count for new node. We need to ensure to not call
* add_image again, to work around access of freed data on the Blender
* side. A better solution should be found to avoid this. */
- PointDensityTextureNode *node = new PointDensityTextureNode(*this);
+ PointDensityTextureNode *node = graph->create_node<PointDensityTextureNode>(*this);
node->handle = handle; /* TODO: not needed? */
return node;
}
@@ -2783,8 +2783,8 @@ void PrincipledBsdfNode::expand(ShaderGraph *graph)
ShaderInput *emission_in = input("Emission");
if (emission_in->link || emission != make_float3(0.0f, 0.0f, 0.0f)) {
/* Create add closure and emission. */
- AddClosureNode *add = new AddClosureNode();
- EmissionNode *emission_node = new EmissionNode();
+ AddClosureNode *add = graph->create_node<AddClosureNode>();
+ EmissionNode *emission_node = graph->create_node<EmissionNode>();
ShaderOutput *new_out = add->output("Closure");
graph->add(add);
@@ -2802,8 +2802,8 @@ void PrincipledBsdfNode::expand(ShaderGraph *graph)
ShaderInput *alpha_in = input("Alpha");
if (alpha_in->link || alpha != 1.0f) {
/* Create mix and transparent BSDF for alpha transparency. */
- MixClosureNode *mix = new MixClosureNode();
- TransparentBsdfNode *transparent = new TransparentBsdfNode();
+ MixClosureNode *mix = graph->create_node<MixClosureNode>();
+ TransparentBsdfNode *transparent = graph->create_node<TransparentBsdfNode>();
graph->add(mix);
graph->add(transparent);
@@ -4475,7 +4475,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
{
ShaderOutput *color_out = output("Color");
if (!color_out->links.empty()) {
- AttributeNode *attr = new AttributeNode();
+ AttributeNode *attr = graph->create_node<AttributeNode>();
attr->attribute = "color";
graph->add(attr);
graph->relink(color_out, attr->output("Color"));
@@ -4483,7 +4483,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *density_out = output("Density");
if (!density_out->links.empty()) {
- AttributeNode *attr = new AttributeNode();
+ AttributeNode *attr = graph->create_node<AttributeNode>();
attr->attribute = "density";
graph->add(attr);
graph->relink(density_out, attr->output("Fac"));
@@ -4491,7 +4491,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *flame_out = output("Flame");
if (!flame_out->links.empty()) {
- AttributeNode *attr = new AttributeNode();
+ AttributeNode *attr = graph->create_node<AttributeNode>();
attr->attribute = "flame";
graph->add(attr);
graph->relink(flame_out, attr->output("Fac"));
@@ -4499,7 +4499,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *temperature_out = output("Temperature");
if (!temperature_out->links.empty()) {
- AttributeNode *attr = new AttributeNode();
+ AttributeNode *attr = graph->create_node<AttributeNode>();
attr->attribute = "temperature";
graph->add(attr);
graph->relink(temperature_out, attr->output("Fac"));
@@ -5768,7 +5768,7 @@ void MapRangeNode::expand(ShaderGraph *graph)
if (clamp) {
ShaderOutput *result_out = output("Result");
if (!result_out->links.empty()) {
- ClampNode *clamp_node = new ClampNode();
+ ClampNode *clamp_node = graph->create_node<ClampNode>();
clamp_node->type = NODE_CLAMP_RANGE;
graph->add(clamp_node);
graph->relink(result_out, clamp_node->output("Result"));
@@ -6009,7 +6009,7 @@ void MathNode::expand(ShaderGraph *graph)
if (use_clamp) {
ShaderOutput *result_out = output("Value");
if (!result_out->links.empty()) {
- ClampNode *clamp_node = new ClampNode();
+ ClampNode *clamp_node = graph->create_node<ClampNode>();
clamp_node->type = NODE_CLAMP_MINMAX;
clamp_node->min = 0.0f;
clamp_node->max = 1.0f;
@@ -6337,7 +6337,7 @@ void BumpNode::constant_fold(const ConstantFolder &folder)
if (height_in->link == NULL) {
if (normal_in->link == NULL) {
- GeometryNode *geom = new GeometryNode();
+ GeometryNode *geom = folder.graph->create_node<GeometryNode>();
folder.graph->add(geom);
folder.bypass(geom->output("Normal"));
}
@@ -6620,12 +6620,12 @@ OSLNode::~OSLNode()
delete type;
}
-ShaderNode *OSLNode::clone() const
+ShaderNode *OSLNode::clone(ShaderGraph *graph) const
{
- return OSLNode::create(this->inputs.size(), this);
+ return OSLNode::create(graph, this->inputs.size(), this);
}
-OSLNode *OSLNode::create(size_t num_inputs, const OSLNode *from)
+OSLNode *OSLNode::create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from)
{
/* allocate space for the node itself and parameters, aligned to 16 bytes
* assuming that's the most parameter types need */
@@ -6636,7 +6636,9 @@ OSLNode *OSLNode::create(size_t num_inputs, const OSLNode *from)
memset(node_memory, 0, node_size + inputs_size);
if (!from) {
- return new (node_memory) OSLNode();
+ OSLNode *node = new (node_memory) OSLNode();
+ node->set_owner(graph);
+ return node;
}
else {
/* copy input default values and node type for cloning */
@@ -6644,6 +6646,7 @@ OSLNode *OSLNode::create(size_t num_inputs, const OSLNode *from)
OSLNode *node = new (node_memory) OSLNode(*from);
node->type = new NodeType(*(from->type));
+ node->set_owner(from->owner);
return node;
}
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index c21bcacb3ce..59e00231c2c 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -92,7 +92,7 @@ class ImageSlotTextureNode : public TextureNode {
class ImageTextureNode : public ImageSlotTextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
- ShaderNode *clone() const;
+ ShaderNode *clone(ShaderGraph *graph) const;
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
{
@@ -126,7 +126,7 @@ class ImageTextureNode : public ImageSlotTextureNode {
class EnvironmentTextureNode : public ImageSlotTextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
- ShaderNode *clone() const;
+ ShaderNode *clone(ShaderGraph *graph) const;
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
{
@@ -364,7 +364,7 @@ class PointDensityTextureNode : public ShaderNode {
}
~PointDensityTextureNode();
- ShaderNode *clone() const;
+ ShaderNode *clone(ShaderGraph *graph) const;
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
{
@@ -400,7 +400,7 @@ class IESLightNode : public TextureNode {
SHADER_NODE_NO_CLONE_CLASS(IESLightNode)
~IESLightNode();
- ShaderNode *clone() const;
+ ShaderNode *clone(ShaderGraph *graph) const;
virtual int get_group()
{
return NODE_GROUP_LEVEL_2;
@@ -1501,10 +1501,10 @@ class SetNormalNode : public ShaderNode {
class OSLNode : public ShaderNode {
public:
- static OSLNode *create(size_t num_inputs, const OSLNode *from = NULL);
+ static OSLNode *create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from = NULL);
~OSLNode();
- ShaderNode *clone() const;
+ ShaderNode *clone(ShaderGraph *graph) const;
char *input_default_value();
void add_input(ustring name, SocketType::Type type);
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 5c62ae73e47..1c54dc2d531 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -439,7 +439,8 @@ const char *OSLShaderManager::shader_load_bytecode(const string &hash, const str
/* This is a static function to avoid RTTI link errors with only this
* file being compiled without RTTI to match OSL and LLVM libraries. */
-OSLNode *OSLShaderManager::osl_node(ShaderManager *manager,
+OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
+ ShaderManager *manager,
const std::string &filepath,
const std::string &bytecode_hash,
const std::string &bytecode)
@@ -482,7 +483,7 @@ OSLNode *OSLShaderManager::osl_node(ShaderManager *manager,
}
/* create node */
- OSLNode *node = OSLNode::create(num_inputs);
+ OSLNode *node = OSLNode::create(graph, num_inputs);
/* add new sockets from parameters */
set<void *> used_sockets;
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 4dd9f6630f2..ea2d0ca492c 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -93,7 +93,8 @@ class OSLShaderManager : public ShaderManager {
OSLShaderInfo *shader_loaded_info(const string &hash);
/* create OSL node using OSLQuery */
- static OSLNode *osl_node(ShaderManager *manager,
+ static OSLNode *osl_node(ShaderGraph *graph,
+ ShaderManager *manager,
const std::string &filepath,
const std::string &bytecode_hash = "",
const std::string &bytecode = "");
diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp
index ec9276eff86..494f5929df2 100644
--- a/intern/cycles/render/particles.cpp
+++ b/intern/cycles/render/particles.cpp
@@ -29,7 +29,13 @@ CCL_NAMESPACE_BEGIN
/* Particle System */
-ParticleSystem::ParticleSystem()
+NODE_DEFINE(ParticleSystem)
+{
+ NodeType *type = NodeType::add("particle_system", create);
+ return type;
+}
+
+ParticleSystem::ParticleSystem() : Node(node_type)
{
}
diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h
index 65663c31c37..0b0408184fe 100644
--- a/intern/cycles/render/particles.h
+++ b/intern/cycles/render/particles.h
@@ -20,6 +20,8 @@
#include "util/util_array.h"
#include "util/util_types.h"
+#include "graph/node.h"
+
CCL_NAMESPACE_BEGIN
class Device;
@@ -40,8 +42,10 @@ struct Particle {
float3 angular_velocity;
};
-class ParticleSystem {
+class ParticleSystem : public Node {
public:
+ NODE_DECLARE
+
ParticleSystem();
~ParticleSystem();
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index a8a5b50e6a2..8f863b5d15f 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -33,6 +33,7 @@
#include "render/shader.h"
#include "render/svm.h"
#include "render/tables.h"
+#include "render/volume.h"
#include "util/util_foreach.h"
#include "util/util_guarded_allocator.h"
@@ -98,15 +99,15 @@ Scene::Scene(const SceneParams &params_, Device *device)
{
memset((void *)&dscene.data, 0, sizeof(dscene.data));
- camera = new Camera();
- dicing_camera = new Camera();
+ camera = create_node<Camera>();
+ dicing_camera = create_node<Camera>();
lookup_tables = new LookupTables();
- film = new Film();
- background = new Background();
+ film = create_node<Film>();
+ background = create_node<Background>();
light_manager = new LightManager();
geometry_manager = new GeometryManager();
object_manager = new ObjectManager();
- integrator = new Integrator();
+ integrator = create_node<Integrator>();
image_manager = new ImageManager(device->info);
particle_system_manager = new ParticleSystemManager();
bake_manager = new BakeManager();
@@ -560,4 +561,127 @@ int Scene::get_max_closure_count()
return max_closure_global;
}
+template<> Light *Scene::create_node<Light>()
+{
+ Light *node = new Light();
+ node->set_owner(this);
+ lights.push_back(node);
+ light_manager->tag_update(this);
+ return node;
+}
+
+template<> Mesh *Scene::create_node<Mesh>()
+{
+ Mesh *node = new Mesh();
+ node->set_owner(this);
+ geometry.push_back(node);
+ geometry_manager->tag_update(this);
+ return node;
+}
+
+template<> Hair *Scene::create_node<Hair>()
+{
+ Hair *node = new Hair();
+ node->set_owner(this);
+ geometry.push_back(node);
+ geometry_manager->tag_update(this);
+ return node;
+}
+
+template<> Volume *Scene::create_node<Volume>()
+{
+ Volume *node = new Volume();
+ node->set_owner(this);
+ geometry.push_back(node);
+ geometry_manager->tag_update(this);
+ return node;
+}
+
+template<> Object *Scene::create_node<Object>()
+{
+ Object *node = new Object();
+ node->set_owner(this);
+ objects.push_back(node);
+ object_manager->tag_update(this);
+ return node;
+}
+
+template<> ParticleSystem *Scene::create_node<ParticleSystem>()
+{
+ ParticleSystem *node = new ParticleSystem();
+ node->set_owner(this);
+ particle_systems.push_back(node);
+ particle_system_manager->tag_update(this);
+ return node;
+}
+
+template<> Shader *Scene::create_node<Shader>()
+{
+ Shader *node = new Shader();
+ node->set_owner(this);
+ shaders.push_back(node);
+ shader_manager->need_update = true;
+ return node;
+}
+
+template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
+{
+ for (size_t i = 0; i < nodes.size(); ++i) {
+ if (nodes[i] == node) {
+ std::swap(nodes[i], nodes[nodes.size() - 1]);
+ break;
+ }
+ }
+
+ nodes.resize(nodes.size() - 1);
+ delete node;
+}
+
+template<> void Scene::delete_node_impl(Light *node)
+{
+ delete_node_from_array(lights, node);
+ light_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(Mesh *node)
+{
+ delete_node_from_array(geometry, static_cast<Geometry *>(node));
+ geometry_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(Hair *node)
+{
+ delete_node_from_array(geometry, static_cast<Geometry *>(node));
+ geometry_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(Volume *node)
+{
+ delete_node_from_array(geometry, static_cast<Geometry *>(node));
+ geometry_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(Geometry *node)
+{
+ delete_node_from_array(geometry, node);
+ geometry_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(Object *node)
+{
+ delete_node_from_array(objects, node);
+ object_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(ParticleSystem *node)
+{
+ delete_node_from_array(particle_systems, node);
+ particle_system_manager->tag_update(this);
+}
+
+template<> void Scene::delete_node_impl(Shader * /*node*/)
+{
+ /* don't delete unused shaders, not supported */
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 25b6b2ef0e4..0e32a70952b 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -59,6 +59,7 @@ class Progress;
class BakeManager;
class BakeData;
class RenderStats;
+class Volume;
/* Scene Device Data */
@@ -212,7 +213,7 @@ class SceneParams {
/* Scene */
-class Scene {
+class Scene : public NodeOwner {
public:
/* Optional name. Is used for logging and reporting. */
string name;
@@ -281,6 +282,40 @@ class Scene {
bool update(Progress &progress, bool &kernel_switch_needed);
+ /* This function is used to create a node of a specified type instead of
+ * calling 'new', and sets the scene as the owner of the node.
+ * The function has overloads that will also add the created node to the right
+ * node array (e.g. Scene::geometry for Geometry nodes) and tag the appropriate
+ * manager for an update.
+ */
+ template<typename T, typename... Args> T *create_node(Args &&... args)
+ {
+ T *node = new T(args...);
+ node->set_owner(this);
+ return node;
+ }
+
+ /* This function is used to delete a node from the scene instead of calling 'delete'
+ * and manually removing the node from the data array. It also tags the
+ * appropriate manager for an update, if any, and checks that the scene is indeed
+ * the owner of the node. Calling this function on a node not owned by the scene
+ * will likely cause a crash which we want in order to detect such cases.
+ */
+ template<typename T> void delete_node(T *node)
+ {
+ assert(node->get_owner() == this);
+ delete_node_impl(node);
+ }
+
+ /* Same as above, but specify the actual owner.
+ */
+ template<typename T> void delete_node(T *node, const NodeOwner *owner)
+ {
+ assert(node->get_owner() == owner);
+ delete_node_impl(node);
+ (void)owner;
+ }
+
protected:
/* Check if some heavy data worth logging was updated.
* Mainly used to suppress extra annoying logging.
@@ -303,8 +338,43 @@ class Scene {
/* Get maximum number of closures to be used in kernel. */
int get_max_closure_count();
+
+ template<typename T> void delete_node_impl(T *node)
+ {
+ delete node;
+ }
};
+template<> Light *Scene::create_node<Light>();
+
+template<> Mesh *Scene::create_node<Mesh>();
+
+template<> Object *Scene::create_node<Object>();
+
+template<> Hair *Scene::create_node<Hair>();
+
+template<> Volume *Scene::create_node<Volume>();
+
+template<> ParticleSystem *Scene::create_node<ParticleSystem>();
+
+template<> Shader *Scene::create_node<Shader>();
+
+template<> void Scene::delete_node_impl(Light *node);
+
+template<> void Scene::delete_node_impl(Mesh *node);
+
+template<> void Scene::delete_node_impl(Volume *node);
+
+template<> void Scene::delete_node_impl(Hair *node);
+
+template<> void Scene::delete_node_impl(Geometry *node);
+
+template<> void Scene::delete_node_impl(Object *node);
+
+template<> void Scene::delete_node_impl(ParticleSystem *node);
+
+template<> void Scene::delete_node_impl(Shader *node);
+
CCL_NAMESPACE_END
#endif /* __SCENE_H__ */
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 1120d909e98..135d0dc962b 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -624,16 +624,15 @@ void ShaderManager::add_default(Scene *scene)
{
ShaderGraph *graph = new ShaderGraph();
- DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
+ DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
diffuse->color = make_float3(0.8f, 0.8f, 0.8f);
graph->add(diffuse);
graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
- Shader *shader = new Shader();
+ Shader *shader = scene->create_node<Shader>();
shader->name = "default_surface";
shader->set_graph(graph);
- scene->shaders.push_back(shader);
scene->default_surface = shader;
shader->tag_update(scene);
}
@@ -642,15 +641,14 @@ void ShaderManager::add_default(Scene *scene)
{
ShaderGraph *graph = new ShaderGraph();
- PrincipledVolumeNode *principled = new PrincipledVolumeNode();
+ PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
graph->add(principled);
graph->connect(principled->output("Volume"), graph->output()->input("Volume"));
- Shader *shader = new Shader();
+ Shader *shader = scene->create_node<Shader>();
shader->name = "default_volume";
shader->set_graph(graph);
- scene->shaders.push_back(shader);
scene->default_volume = shader;
shader->tag_update(scene);
}
@@ -659,17 +657,16 @@ void ShaderManager::add_default(Scene *scene)
{
ShaderGraph *graph = new ShaderGraph();
- EmissionNode *emission = new EmissionNode();
+ EmissionNode *emission = graph->create_node<EmissionNode>();
emission->color = make_float3(0.8f, 0.8f, 0.8f);
emission->strength = 0.0f;
graph->add(emission);
graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
- Shader *shader = new Shader();
+ Shader *shader = scene->create_node<Shader>();
shader->name = "default_light";
shader->set_graph(graph);
- scene->shaders.push_back(shader);
scene->default_light = shader;
shader->tag_update(scene);
}
@@ -678,10 +675,9 @@ void ShaderManager::add_default(Scene *scene)
{
ShaderGraph *graph = new ShaderGraph();
- Shader *shader = new Shader();
+ Shader *shader = scene->create_node<Shader>();
shader->name = "default_background";
shader->set_graph(graph);
- scene->shaders.push_back(shader);
scene->default_background = shader;
shader->tag_update(scene);
}
@@ -690,10 +686,9 @@ void ShaderManager::add_default(Scene *scene)
{
ShaderGraph *graph = new ShaderGraph();
- Shader *shader = new Shader();
+ Shader *shader = scene->create_node<Shader>();
shader->name = "default_empty";
shader->set_graph(graph);
- scene->shaders.push_back(shader);
scene->default_empty = shader;
shader->tag_update(scene);
}