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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2020-11-04 13:17:38 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2020-11-04 15:03:33 +0300
commit31a620b9420cab6292b0aa1ea21c9dd1cf70b8bc (patch)
tree76cf425e110fe1c78930e54f3b56d24e1485877a /intern/cycles/render
parenta4a848d01b26ad094dabe0e935dd698847ac8f16 (diff)
Cycles API: encapsulate Node socket members
This encapsulates Node socket members behind a set of specific methods; as such it is no longer possible to directly access Node class members from exporters and parts of Cycles. The methods are defined via the NODE_SOCKET_API macros in `graph/ node.h`, and are for getting or setting a specific socket's value, as well as querying or modifying the state of its update flag. The setters will check whether the value has changed and tag the socket as modified appropriately. This will let us know how a Node has changed and what to update, which is the first concrete step toward a more granular scene update system. Since the setters will tag the Node sockets as modified when passed different data, this patch also removes the various modified methods on Nodes in favor of Node::is_modified which checks the sockets' update flags status. Reviewed By: brecht Maniphest Tasks: T79174 Differential Revision: https://developer.blender.org/D8544
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/attribute.cpp36
-rw-r--r--intern/cycles/render/background.cpp14
-rw-r--r--intern/cycles/render/background.h23
-rw-r--r--intern/cycles/render/bake.cpp15
-rw-r--r--intern/cycles/render/camera.cpp76
-rw-r--r--intern/cycles/render/camera.h103
-rw-r--r--intern/cycles/render/film.cpp65
-rw-r--r--intern/cycles/render/film.h52
-rw-r--r--intern/cycles/render/geometry.cpp144
-rw-r--r--intern/cycles/render/geometry.h34
-rw-r--r--intern/cycles/render/graph.cpp22
-rw-r--r--intern/cycles/render/hair.cpp11
-rw-r--r--intern/cycles/render/hair.h8
-rw-r--r--intern/cycles/render/image.cpp2
-rw-r--r--intern/cycles/render/image.h2
-rw-r--r--intern/cycles/render/integrator.cpp16
-rw-r--r--intern/cycles/render/integrator.h71
-rw-r--r--intern/cycles/render/light.cpp98
-rw-r--r--intern/cycles/render/light.h60
-rw-r--r--intern/cycles/render/mesh.cpp165
-rw-r--r--intern/cycles/render/mesh.h79
-rw-r--r--intern/cycles/render/mesh_displace.cpp19
-rw-r--r--intern/cycles/render/mesh_subdivision.cpp69
-rw-r--r--intern/cycles/render/nodes.cpp147
-rw-r--r--intern/cycles/render/nodes.h661
-rw-r--r--intern/cycles/render/object.cpp75
-rw-r--r--intern/cycles/render/object.h41
-rw-r--r--intern/cycles/render/osl.cpp10
-rw-r--r--intern/cycles/render/scene.cpp40
-rw-r--r--intern/cycles/render/session.cpp27
-rw-r--r--intern/cycles/render/shader.cpp51
-rw-r--r--intern/cycles/render/shader.h24
-rw-r--r--intern/cycles/render/svm.cpp10
-rw-r--r--intern/cycles/render/volume.cpp20
-rw-r--r--intern/cycles/render/volume.h6
35 files changed, 1342 insertions, 954 deletions
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 05f3d619989..b478aae9ae2 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -167,62 +167,62 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const
size = 1;
break;
case ATTR_ELEMENT_VERTEX:
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
- size = mesh->verts.size() + mesh->num_ngons;
+ size = mesh->get_verts().size() + mesh->get_num_ngons();
if (prim == ATTR_PRIM_SUBD) {
- size -= mesh->num_subd_verts;
+ size -= mesh->get_num_subd_verts();
}
}
break;
case ATTR_ELEMENT_VERTEX_MOTION:
- if (geom->type == Geometry::MESH) {
+ if (geom->geometry_type == Geometry::MESH) {
Mesh *mesh = static_cast<Mesh *>(geom);
- size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1);
+ size = (mesh->get_verts().size() + mesh->get_num_ngons()) * (mesh->get_motion_steps() - 1);
if (prim == ATTR_PRIM_SUBD) {
- size -= mesh->num_subd_verts * (mesh->motion_steps - 1);
+ size -= mesh->get_num_subd_verts() * (mesh->get_motion_steps() - 1);
}
}
break;
case ATTR_ELEMENT_FACE:
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (prim == ATTR_PRIM_GEOMETRY) {
size = mesh->num_triangles();
}
else {
- size = mesh->subd_faces.size() + mesh->num_ngons;
+ size = mesh->get_num_subd_faces() + mesh->get_num_ngons();
}
}
break;
case ATTR_ELEMENT_CORNER:
case ATTR_ELEMENT_CORNER_BYTE:
- if (geom->type == Geometry::MESH) {
+ if (geom->geometry_type == Geometry::MESH) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (prim == ATTR_PRIM_GEOMETRY) {
size = mesh->num_triangles() * 3;
}
else {
- size = mesh->subd_face_corners.size() + mesh->num_ngons;
+ size = mesh->get_subd_face_corners().size() + mesh->get_num_ngons();
}
}
break;
case ATTR_ELEMENT_CURVE:
- if (geom->type == Geometry::HAIR) {
+ if (geom->geometry_type == Geometry::HAIR) {
Hair *hair = static_cast<Hair *>(geom);
size = hair->num_curves();
}
break;
case ATTR_ELEMENT_CURVE_KEY:
- if (geom->type == Geometry::HAIR) {
+ if (geom->geometry_type == Geometry::HAIR) {
Hair *hair = static_cast<Hair *>(geom);
- size = hair->curve_keys.size();
+ size = hair->get_curve_keys().size();
}
break;
case ATTR_ELEMENT_CURVE_KEY_MOTION:
- if (geom->type == Geometry::HAIR) {
+ if (geom->geometry_type == Geometry::HAIR) {
Hair *hair = static_cast<Hair *>(geom);
- size = hair->curve_keys.size() * (hair->motion_steps - 1);
+ size = hair->get_curve_keys().size() * (hair->get_motion_steps() - 1);
}
break;
default:
@@ -445,7 +445,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
if (name == ustring())
name = Attribute::standard_name(std);
- if (geometry->type == Geometry::MESH) {
+ if (geometry->geometry_type == Geometry::MESH) {
switch (std) {
case ATTR_STD_VERTEX_NORMAL:
attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
@@ -496,7 +496,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
break;
}
}
- else if (geometry->type == Geometry::VOLUME) {
+ else if (geometry->geometry_type == Geometry::VOLUME) {
switch (std) {
case ATTR_STD_VERTEX_NORMAL:
attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
@@ -521,7 +521,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
break;
}
}
- else if (geometry->type == Geometry::HAIR) {
+ else if (geometry->geometry_type == Geometry::HAIR) {
switch (std) {
case ATTR_STD_UV:
attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index d2463454522..7bdcb1578c3 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -54,7 +54,6 @@ NODE_DEFINE(Background)
Background::Background() : Node(node_type)
{
- need_update = true;
shader = NULL;
}
@@ -64,7 +63,7 @@ Background::~Background()
void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- if (!need_update)
+ if (!is_modified())
return;
scoped_callback_timer timer([scene](double time) {
@@ -102,7 +101,7 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
else
kbackground->volume_shader = SHADER_NONE;
- kbackground->volume_step_size = volume_step_size * scene->integrator->volume_step_rate;
+ kbackground->volume_step_size = volume_step_size * scene->integrator->get_volume_step_rate();
/* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
if (bg_shader->graph->nodes.size() <= 1) {
@@ -122,22 +121,17 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
}
- need_update = false;
+ clear_modified();
}
void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
}
-bool Background::modified(const Background &background)
-{
- return !Node::equals(background);
-}
-
void Background::tag_update(Scene *scene)
{
scene->integrator->tag_update(scene);
- need_update = true;
+ tag_modified();
}
Shader *Background::get_shader(const Scene *scene)
diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h
index c2ca1f75179..e89ffbc2445 100644
--- a/intern/cycles/render/background.h
+++ b/intern/cycles/render/background.h
@@ -32,22 +32,20 @@ class Background : public Node {
public:
NODE_DECLARE
- float ao_factor;
- float ao_distance;
+ NODE_SOCKET_API(float, ao_factor)
+ NODE_SOCKET_API(float, ao_distance)
- bool use_shader;
- bool use_ao;
+ NODE_SOCKET_API(bool, use_shader)
+ NODE_SOCKET_API(bool, use_ao)
- uint visibility;
- Shader *shader;
+ NODE_SOCKET_API(uint, visibility)
+ NODE_SOCKET_API(Shader *, shader)
- bool transparent;
- bool transparent_glass;
- float transparent_roughness_threshold;
+ NODE_SOCKET_API(bool, transparent)
+ NODE_SOCKET_API(bool, transparent_glass)
+ NODE_SOCKET_API(float, transparent_roughness_threshold)
- float volume_step_size;
-
- bool need_update;
+ NODE_SOCKET_API(float, volume_step_size)
Background();
~Background();
@@ -55,7 +53,6 @@ class Background : public Node {
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
- bool modified(const Background &background);
void tag_update(Scene *scene);
Shader *get_shader(const Scene *scene);
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 05f52159671..439ebdedb8e 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -33,10 +33,11 @@ static int aa_samples(Scene *scene, Object *object, ShaderEvalType type)
}
else if (type == SHADER_EVAL_NORMAL) {
/* Only antialias normal if mesh has bump mapping. */
- if (object->geometry) {
- foreach (Shader *shader, object->geometry->used_shaders) {
+ if (object->get_geometry()) {
+ foreach (Node *node, object->get_geometry()->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->has_bump) {
- return scene->integrator->aa_samples;
+ return scene->integrator->get_aa_samples();
}
}
}
@@ -44,7 +45,7 @@ static int aa_samples(Scene *scene, Object *object, ShaderEvalType type)
return 1;
}
else {
- return scene->integrator->aa_samples;
+ return scene->integrator->get_aa_samples();
}
}
@@ -112,7 +113,7 @@ void BakeManager::set(Scene *scene,
}
/* create device and update scene */
- scene->film->tag_update(scene);
+ scene->film->tag_modified();
scene->integrator->tag_update(scene);
need_update = true;
@@ -140,8 +141,8 @@ void BakeManager::device_update(Device * /*device*/,
int object_index = 0;
foreach (Object *object, scene->objects) {
- const Geometry *geom = object->geometry;
- if (object->name == object_name && geom->type == Geometry::MESH) {
+ const Geometry *geom = object->get_geometry();
+ if (object->name == object_name && geom->geometry_type == Geometry::MESH) {
kbake->object_index = object_index;
kbake->tri_offset = geom->prim_offset;
kintegrator->aa_samples = aa_samples(scene, object, type);
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 0f2befae320..92cf712d32a 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -98,7 +98,7 @@ NODE_DEFINE(Camera)
type_enum.insert("perspective", CAMERA_PERSPECTIVE);
type_enum.insert("orthograph", CAMERA_ORTHOGRAPHIC);
type_enum.insert("panorama", CAMERA_PANORAMA);
- SOCKET_ENUM(type, "Type", type_enum, CAMERA_PERSPECTIVE);
+ SOCKET_ENUM(camera_type, "Type", type_enum, CAMERA_PERSPECTIVE);
static NodeEnum panorama_type_enum;
panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR);
@@ -148,8 +148,18 @@ NODE_DEFINE(Camera)
SOCKET_FLOAT(border.bottom, "Border Bottom", 0);
SOCKET_FLOAT(border.top, "Border Top", 0);
+ SOCKET_FLOAT(viewport_camera_border.left, "Viewport Border Left", 0);
+ SOCKET_FLOAT(viewport_camera_border.right, "Viewport Border Right", 0);
+ SOCKET_FLOAT(viewport_camera_border.bottom, "Viewport Border Bottom", 0);
+ SOCKET_FLOAT(viewport_camera_border.top, "Viewport Border Top", 0);
+
SOCKET_FLOAT(offscreen_dicing_scale, "Offscreen Dicing Scale", 1.0f);
+ SOCKET_INT(full_width, "Full Width", 1024);
+ SOCKET_INT(full_height, "Full Height", 512);
+
+ SOCKET_BOOLEAN(use_perspective_motion, "Use Perspective Motion", false);
+
return type;
}
@@ -182,7 +192,6 @@ Camera::Camera() : Node(node_type)
dx = make_float3(0.0f, 0.0f, 0.0f);
dy = make_float3(0.0f, 0.0f, 0.0f);
- need_update = true;
need_device_update = true;
need_flags_update = true;
previous_need_motion = -1;
@@ -196,7 +205,7 @@ Camera::~Camera()
void Camera::compute_auto_viewplane()
{
- if (type == CAMERA_PANORAMA) {
+ if (camera_type == CAMERA_PANORAMA) {
viewplane.left = 0.0f;
viewplane.right = 1.0f;
viewplane.bottom = 0.0f;
@@ -230,7 +239,7 @@ void Camera::update(Scene *scene)
need_device_update = true;
}
- if (!need_update)
+ if (!is_modified())
return;
scoped_callback_timer timer([scene](double time) {
@@ -257,9 +266,9 @@ void Camera::update(Scene *scene)
/* screen to camera */
ProjectionTransform cameratoscreen;
- if (type == CAMERA_PERSPECTIVE)
+ if (camera_type == CAMERA_PERSPECTIVE)
cameratoscreen = projection_perspective(fov, nearclip, farclip);
- else if (type == CAMERA_ORTHOGRAPHIC)
+ else if (camera_type == CAMERA_ORTHOGRAPHIC)
cameratoscreen = projection_orthographic(nearclip, farclip);
else
cameratoscreen = projection_identity();
@@ -284,13 +293,13 @@ void Camera::update(Scene *scene)
worldtoraster = ndctoraster * worldtondc;
/* differentials */
- if (type == CAMERA_ORTHOGRAPHIC) {
+ if (camera_type == CAMERA_ORTHOGRAPHIC) {
dx = transform_perspective_direction(&rastertocamera, make_float3(1, 0, 0));
dy = transform_perspective_direction(&rastertocamera, make_float3(0, 1, 0));
full_dx = transform_perspective_direction(&full_rastertocamera, make_float3(1, 0, 0));
full_dy = transform_perspective_direction(&full_rastertocamera, make_float3(0, 1, 0));
}
- else if (type == CAMERA_PERSPECTIVE) {
+ else if (camera_type == CAMERA_PERSPECTIVE) {
dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
transform_perspective(&rastertocamera, make_float3(0, 0, 0));
dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
@@ -310,7 +319,7 @@ void Camera::update(Scene *scene)
full_dx = transform_direction(&cameratoworld, full_dx);
full_dy = transform_direction(&cameratoworld, full_dy);
- if (type == CAMERA_PERSPECTIVE) {
+ if (camera_type == CAMERA_PERSPECTIVE) {
float3 v = transform_perspective(&full_rastertocamera,
make_float3(full_width, full_height, 1.0f));
frustum_right_normal = normalize(make_float3(v.z, 0.0f, -v.x));
@@ -348,7 +357,7 @@ void Camera::update(Scene *scene)
if (need_motion == Scene::MOTION_PASS) {
/* TODO(sergey): Support perspective (zoom, fov) motion. */
- if (type == CAMERA_PANORAMA) {
+ if (camera_type == CAMERA_PANORAMA) {
if (have_motion) {
kcam->motion_pass_pre = transform_inverse(motion[0]);
kcam->motion_pass_post = transform_inverse(motion[motion.size() - 1]);
@@ -377,7 +386,7 @@ void Camera::update(Scene *scene)
}
/* TODO(sergey): Support other types of camera. */
- if (use_perspective_motion && type == CAMERA_PERSPECTIVE) {
+ if (use_perspective_motion && camera_type == CAMERA_PERSPECTIVE) {
/* TODO(sergey): Move to an utility function and de-duplicate with
* calculation above.
*/
@@ -402,7 +411,7 @@ void Camera::update(Scene *scene)
kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime : -1.0f;
/* type */
- kcam->type = type;
+ kcam->type = camera_type;
/* anamorphic lens bokeh */
kcam->inv_aperture_ratio = 1.0f / aperture_ratio;
@@ -464,7 +473,7 @@ void Camera::update(Scene *scene)
kcam->rolling_shutter_duration = rolling_shutter_duration;
/* Set further update flags */
- need_update = false;
+ clear_modified();
need_device_update = true;
need_flags_update = true;
previous_need_motion = need_motion;
@@ -527,7 +536,7 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen
[&](const blocked_range<size_t> &r) {
for (size_t i = r.begin(); i != r.end(); i++) {
Object *object = scene->objects[i];
- if (object->geometry->has_volume &&
+ if (object->get_geometry()->has_volume &&
viewplane_boundbox.intersects(object->bounds)) {
/* TODO(sergey): Consider adding more grained check. */
VLOG(1) << "Detected camera inside volume.";
@@ -553,25 +562,10 @@ void Camera::device_free(Device * /*device*/, DeviceScene *dscene, Scene *scene)
dscene->camera_motion.free();
}
-bool Camera::modified(const Camera &cam)
-{
- return !Node::equals(cam);
-}
-
-bool Camera::motion_modified(const Camera &cam)
-{
- return !((motion == cam.motion) && (use_perspective_motion == cam.use_perspective_motion));
-}
-
-void Camera::tag_update()
-{
- need_update = true;
-}
-
float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
{
float3 D, P;
- if (type == CAMERA_PERSPECTIVE) {
+ if (camera_type == CAMERA_PERSPECTIVE) {
D = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
float3 Pclip = normalize(D);
P = make_float3(0.0f, 0.0f, 0.0f);
@@ -584,7 +578,7 @@ float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
*/
P += nearclip * D / Pclip.z;
}
- else if (type == CAMERA_ORTHOGRAPHIC) {
+ else if (camera_type == CAMERA_ORTHOGRAPHIC) {
D = make_float3(0.0f, 0.0f, 1.0f);
/* TODO(sergey): Aperture support? */
P = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
@@ -603,7 +597,7 @@ BoundBox Camera::viewplane_bounds_get()
* checks we need in a more clear and smart fashion? */
BoundBox bounds = BoundBox::empty;
- if (type == CAMERA_PANORAMA) {
+ if (camera_type == CAMERA_PANORAMA) {
if (use_spherical_stereo == false) {
bounds.grow(make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w));
}
@@ -628,7 +622,7 @@ BoundBox Camera::viewplane_bounds_get()
bounds.grow(transform_raster_to_world(0.0f, (float)height));
bounds.grow(transform_raster_to_world((float)width, (float)height));
bounds.grow(transform_raster_to_world((float)width, 0.0f));
- if (type == CAMERA_PERSPECTIVE) {
+ if (camera_type == CAMERA_PERSPECTIVE) {
/* Center point has the most distance in local Z axis,
* use it to construct bounding box/
*/
@@ -642,7 +636,7 @@ float Camera::world_to_raster_size(float3 P)
{
float res = 1.0f;
- if (type == CAMERA_ORTHOGRAPHIC) {
+ if (camera_type == CAMERA_ORTHOGRAPHIC) {
res = min(len(full_dx), len(full_dy));
if (offscreen_dicing_scale > 1.0f) {
@@ -668,7 +662,7 @@ float Camera::world_to_raster_size(float3 P)
}
}
}
- else if (type == CAMERA_PERSPECTIVE) {
+ else if (camera_type == CAMERA_PERSPECTIVE) {
/* Calculate as if point is directly ahead of the camera. */
float3 raster = make_float3(0.5f * full_width, 0.5f * full_height, 0.0f);
float3 Pcamera = transform_perspective(&full_rastertocamera, raster);
@@ -743,7 +737,7 @@ float Camera::world_to_raster_size(float3 P)
}
}
}
- else if (type == CAMERA_PANORAMA) {
+ else if (camera_type == CAMERA_PANORAMA) {
float3 D = transform_point(&worldtocamera, P);
float dist = len(D);
@@ -794,6 +788,16 @@ bool Camera::use_motion() const
return motion.size() > 1;
}
+void Camera::set_screen_size_and_resolution(int width_, int height_, int resolution_)
+{
+ if (width_ != width || height_ != height || resolution_ != resolution) {
+ width = width_;
+ height = height_;
+ resolution = resolution_;
+ tag_modified();
+ }
+}
+
float Camera::motion_time(int step) const
{
return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 21dad5eea3b..7970381f338 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -73,78 +73,92 @@ class Camera : public Node {
};
/* motion blur */
- float shuttertime;
- MotionPosition motion_position;
- array<float> shutter_curve;
+ NODE_SOCKET_API(float, shuttertime)
+ NODE_SOCKET_API(MotionPosition, motion_position)
+ NODE_SOCKET_API_ARRAY(array<float>, shutter_curve)
size_t shutter_table_offset;
/* ** Rolling shutter effect. ** */
/* Defines rolling shutter effect type. */
- RollingShutterType rolling_shutter_type;
+ NODE_SOCKET_API(RollingShutterType, rolling_shutter_type)
/* Specifies exposure time of scanlines when using
* rolling shutter effect.
*/
- float rolling_shutter_duration;
+ NODE_SOCKET_API(float, rolling_shutter_duration)
/* depth of field */
- float focaldistance;
- float aperturesize;
- uint blades;
- float bladesrotation;
+ NODE_SOCKET_API(float, focaldistance)
+ NODE_SOCKET_API(float, aperturesize)
+ NODE_SOCKET_API(uint, blades)
+ NODE_SOCKET_API(float, bladesrotation)
/* type */
- CameraType type;
- float fov;
+ NODE_SOCKET_API(CameraType, camera_type)
+ NODE_SOCKET_API(float, fov)
/* panorama */
- PanoramaType panorama_type;
- float fisheye_fov;
- float fisheye_lens;
- float latitude_min;
- float latitude_max;
- float longitude_min;
- float longitude_max;
+ NODE_SOCKET_API(PanoramaType, panorama_type)
+ NODE_SOCKET_API(float, fisheye_fov)
+ NODE_SOCKET_API(float, fisheye_lens)
+ NODE_SOCKET_API(float, latitude_min)
+ NODE_SOCKET_API(float, latitude_max)
+ NODE_SOCKET_API(float, longitude_min)
+ NODE_SOCKET_API(float, longitude_max)
/* panorama stereo */
- StereoEye stereo_eye;
- bool use_spherical_stereo;
- float interocular_distance;
- float convergence_distance;
- bool use_pole_merge;
- float pole_merge_angle_from;
- float pole_merge_angle_to;
+ NODE_SOCKET_API(StereoEye, stereo_eye)
+ NODE_SOCKET_API(bool, use_spherical_stereo)
+ NODE_SOCKET_API(float, interocular_distance)
+ NODE_SOCKET_API(float, convergence_distance)
+ NODE_SOCKET_API(bool, use_pole_merge)
+ NODE_SOCKET_API(float, pole_merge_angle_from)
+ NODE_SOCKET_API(float, pole_merge_angle_to)
/* anamorphic lens bokeh */
- float aperture_ratio;
+ NODE_SOCKET_API(float, aperture_ratio)
/* sensor */
- float sensorwidth;
- float sensorheight;
+ NODE_SOCKET_API(float, sensorwidth)
+ NODE_SOCKET_API(float, sensorheight)
/* clipping */
- float nearclip;
- float farclip;
+ NODE_SOCKET_API(float, nearclip)
+ NODE_SOCKET_API(float, farclip)
/* screen */
- int width, height;
- int resolution;
BoundBox2D viewplane;
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, left)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, right)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, bottom)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, top)
+
/* width and height change during preview, so we need these for calculating dice rates. */
- int full_width, full_height;
+ NODE_SOCKET_API(int, full_width)
+ NODE_SOCKET_API(int, full_height)
/* controls how fast the dicing rate falls off for geometry out side of view */
- float offscreen_dicing_scale;
+ NODE_SOCKET_API(float, offscreen_dicing_scale)
/* border */
BoundBox2D border;
+ NODE_SOCKET_API_STRUCT_MEMBER(float, border, left)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, border, right)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, border, bottom)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, border, top)
+
BoundBox2D viewport_camera_border;
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, left)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, right)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, bottom)
+ NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, top)
/* transformation */
- Transform matrix;
+ NODE_SOCKET_API(Transform, matrix)
/* motion */
- array<Transform> motion;
- bool use_perspective_motion;
- float fov_pre, fov_post;
+ NODE_SOCKET_API_ARRAY(array<Transform>, motion)
+ NODE_SOCKET_API(bool, use_perspective_motion)
+ NODE_SOCKET_API(float, fov_pre)
+ NODE_SOCKET_API(float, fov_post)
/* computed camera parameters */
ProjectionTransform screentoworld;
@@ -174,7 +188,6 @@ class Camera : public Node {
float3 frustum_bottom_normal;
/* update */
- bool need_update;
bool need_device_update;
bool need_flags_update;
int previous_need_motion;
@@ -183,6 +196,12 @@ class Camera : public Node {
KernelCamera kernel_camera;
array<DecomposedTransform> kernel_camera_motion;
+ private:
+ int width;
+ int height;
+ int resolution;
+
+ public:
/* functions */
Camera();
~Camera();
@@ -195,10 +214,6 @@ class Camera : public Node {
void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene, Scene *scene);
- bool modified(const Camera &cam);
- bool motion_modified(const Camera &cam);
- void tag_update();
-
/* Public utility functions. */
BoundBox viewplane_bounds_get();
@@ -210,6 +225,8 @@ class Camera : public Node {
int motion_step(float time) const;
bool use_motion() const;
+ void set_screen_size_and_resolution(int width_, int height_, int resolution_);
+
private:
/* Private utility functions. */
float3 transform_raster_to_world(float raster_x, float raster_y);
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index e4c1e452bd5..5c3778f6ae5 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -40,10 +40,8 @@ static bool compare_pass_order(const Pass &a, const Pass &b)
return (a.components > b.components);
}
-NODE_DEFINE(Pass)
+static NodeEnum *get_pass_type_enum()
{
- NodeType *type = NodeType::add("pass", create);
-
static NodeEnum pass_type_enum;
pass_type_enum.insert("combined", PASS_COMBINED);
pass_type_enum.insert("depth", PASS_DEPTH);
@@ -84,7 +82,15 @@ NODE_DEFINE(Pass)
pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE);
pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL);
- SOCKET_ENUM(type, "Type", pass_type_enum, PASS_COMBINED);
+ return &pass_type_enum;
+}
+
+NODE_DEFINE(Pass)
+{
+ NodeType *type = NodeType::add("pass", create);
+
+ NodeEnum *pass_type_enum = get_pass_type_enum();
+ SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED);
SOCKET_STRING(name, "Name", ustring());
return type;
@@ -383,6 +389,21 @@ NODE_DEFINE(Film)
SOCKET_INT(denoising_flags, "Denoising Flags", 0);
SOCKET_BOOLEAN(use_adaptive_sampling, "Use Adaptive Sampling", false);
+ SOCKET_BOOLEAN(use_light_visibility, "Use Light Visibility", false);
+
+ NodeEnum *pass_type_enum = get_pass_type_enum();
+ SOCKET_ENUM(display_pass, "Display Pass", *pass_type_enum, PASS_COMBINED);
+
+ static NodeEnum cryptomatte_passes_enum;
+ cryptomatte_passes_enum.insert("none", CRYPT_NONE);
+ cryptomatte_passes_enum.insert("object", CRYPT_OBJECT);
+ cryptomatte_passes_enum.insert("material", CRYPT_MATERIAL);
+ cryptomatte_passes_enum.insert("asset", CRYPT_ASSET);
+ cryptomatte_passes_enum.insert("accurate", CRYPT_ACCURATE);
+ SOCKET_ENUM(cryptomatte_passes, "Cryptomatte Passes", cryptomatte_passes_enum, CRYPT_NONE);
+
+ SOCKET_INT(cryptomatte_depth, "Cryptomatte Depth", 0);
+
return type;
}
@@ -392,8 +413,6 @@ Film::Film() : Node(node_type)
filter_table_offset = TABLE_OFFSET_INVALID;
cryptomatte_passes = CRYPT_NONE;
display_pass = PASS_COMBINED;
-
- need_update = true;
}
Film::~Film()
@@ -407,7 +426,7 @@ void Film::add_default(Scene *scene)
void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- if (!need_update)
+ if (!is_modified())
return;
scoped_callback_timer timer([scene](double time) {
@@ -658,7 +677,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
denoising_data_offset = kfilm->pass_denoising_data;
denoising_clean_offset = kfilm->pass_denoising_clean;
- need_update = false;
+ clear_modified();
}
void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *scene)
@@ -666,11 +685,6 @@ void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *sce
scene->lookup_tables->remove_table(&filter_table_offset);
}
-bool Film::modified(const Film &film)
-{
- return !Node::equals(film);
-}
-
void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes)
{
if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
@@ -691,11 +705,6 @@ void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool upd
}
}
-void Film::tag_update(Scene * /*scene*/)
-{
- need_update = true;
-}
-
int Film::get_aov_offset(Scene *scene, string name, bool &is_color)
{
int num_color = 0, num_value = 0;
@@ -719,4 +728,24 @@ int Film::get_aov_offset(Scene *scene, string name, bool &is_color)
return -1;
}
+int Film::get_pass_stride() const
+{
+ return pass_stride;
+}
+
+int Film::get_denoising_data_offset() const
+{
+ return denoising_data_offset;
+}
+
+int Film::get_denoising_clean_offset() const
+{
+ return denoising_clean_offset;
+}
+
+size_t Film::get_filter_table_offset() const
+{
+ return filter_table_offset;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index 961058c008e..462a7275491 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -60,34 +60,35 @@ class Film : public Node {
public:
NODE_DECLARE
- float exposure;
- bool denoising_data_pass;
- bool denoising_clean_pass;
- bool denoising_prefiltered_pass;
- int denoising_flags;
- float pass_alpha_threshold;
-
- PassType display_pass;
- int pass_stride;
- int denoising_data_offset;
- int denoising_clean_offset;
+ NODE_SOCKET_API(float, exposure)
+ NODE_SOCKET_API(bool, denoising_data_pass)
+ NODE_SOCKET_API(bool, denoising_clean_pass)
+ NODE_SOCKET_API(bool, denoising_prefiltered_pass)
+ NODE_SOCKET_API(int, denoising_flags)
+ NODE_SOCKET_API(float, pass_alpha_threshold)
- FilterType filter_type;
- float filter_width;
- size_t filter_table_offset;
+ NODE_SOCKET_API(PassType, display_pass)
- float mist_start;
- float mist_depth;
- float mist_falloff;
+ NODE_SOCKET_API(FilterType, filter_type)
+ NODE_SOCKET_API(float, filter_width)
- bool use_light_visibility;
- CryptomatteType cryptomatte_passes;
- int cryptomatte_depth;
+ NODE_SOCKET_API(float, mist_start)
+ NODE_SOCKET_API(float, mist_depth)
+ NODE_SOCKET_API(float, mist_falloff)
- bool use_adaptive_sampling;
+ NODE_SOCKET_API(bool, use_light_visibility)
+ NODE_SOCKET_API(CryptomatteType, cryptomatte_passes)
+ NODE_SOCKET_API(int, cryptomatte_depth)
- bool need_update;
+ NODE_SOCKET_API(bool, use_adaptive_sampling)
+ private:
+ int pass_stride;
+ int denoising_data_offset;
+ int denoising_clean_offset;
+ size_t filter_table_offset;
+
+ public:
Film();
~Film();
@@ -97,11 +98,14 @@ class Film : public Node {
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene, Scene *scene);
- bool modified(const Film &film);
void tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes = true);
- void tag_update(Scene *scene);
int get_aov_offset(Scene *scene, string name, bool &is_color);
+
+ int get_pass_stride() const;
+ int get_denoising_data_offset() const;
+ int get_denoising_clean_offset() const;
+ size_t get_filter_table_offset() const;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 7b410a0c5ea..a63fc620c69 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -52,14 +52,14 @@ NODE_ABSTRACT_DEFINE(Geometry)
SOCKET_UINT(motion_steps, "Motion Steps", 3);
SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
+ SOCKET_NODE_ARRAY(used_shaders, "Shaders", &Shader::node_type);
return type;
}
Geometry::Geometry(const NodeType *node_type, const Type type)
- : Node(node_type), type(type), attributes(this, ATTR_PRIM_GEOMETRY)
+ : Node(node_type), geometry_type(type), attributes(this, ATTR_PRIM_GEOMETRY)
{
- need_update = true;
need_update_rebuild = false;
transform_applied = false;
@@ -99,9 +99,11 @@ bool Geometry::need_attribute(Scene *scene, AttributeStandard std)
if (scene->need_global_attribute(std))
return true;
- foreach (Shader *shader, used_shaders)
+ foreach (Node *node, used_shaders) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->attributes.find(std))
return true;
+ }
return false;
}
@@ -111,9 +113,11 @@ bool Geometry::need_attribute(Scene * /*scene*/, ustring name)
if (name == ustring())
return false;
- foreach (Shader *shader, used_shaders)
+ foreach (Node *node, used_shaders) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->attributes.find(name))
return true;
+ }
return false;
}
@@ -122,8 +126,10 @@ AttributeRequestSet Geometry::needed_attributes()
{
AttributeRequestSet result;
- foreach (Shader *shader, used_shaders)
+ foreach (Node *node, used_shaders) {
+ Shader *shader = static_cast<Shader *>(node);
result.add(shader->attributes);
+ }
return result;
}
@@ -171,8 +177,9 @@ bool Geometry::is_instanced() const
bool Geometry::has_true_displacement() const
{
- foreach (Shader *shader, used_shaders) {
- if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) {
+ foreach (Node *node, used_shaders) {
+ Shader *shader = static_cast<Shader *>(node);
+ if (shader->has_displacement && shader->get_displacement_method() != DISPLACE_BUMP) {
return true;
}
}
@@ -198,7 +205,7 @@ void Geometry::compute_bvh(
msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
Object object;
- object.geometry = this;
+ object.set_geometry(this);
vector<Geometry *> geometry;
geometry.push_back(this);
@@ -232,7 +239,7 @@ void Geometry::compute_bvh(
}
}
- need_update = false;
+ clear_modified();
need_update_rebuild = false;
}
@@ -254,16 +261,18 @@ bool Geometry::has_voxel_attributes() const
void Geometry::tag_update(Scene *scene, bool rebuild)
{
- need_update = true;
+ tag_modified();
if (rebuild) {
need_update_rebuild = true;
scene->light_manager->need_update = true;
}
else {
- foreach (Shader *shader, used_shaders)
+ foreach (Node *node, used_shaders) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->has_surface_emission)
scene->light_manager->need_update = true;
+ }
}
scene->geometry_manager->need_update = true;
@@ -433,9 +442,9 @@ static void emit_attribute_mapping(
emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
- if (geom->type == Geometry::MESH) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
- if (mesh->subd_faces.size()) {
+ if (mesh->get_num_subd_faces()) {
emit_attribute_map_entry(attr_map, index + 1, id, req.subd_type, req.subd_desc);
}
}
@@ -547,19 +556,19 @@ static void update_attribute_element_size(Geometry *geom,
}
}
-static void update_attribute_element_offset(Geometry *geom,
- device_vector<float> &attr_float,
- size_t &attr_float_offset,
- device_vector<float2> &attr_float2,
- size_t &attr_float2_offset,
- device_vector<float4> &attr_float3,
- size_t &attr_float3_offset,
- device_vector<uchar4> &attr_uchar4,
- size_t &attr_uchar4_offset,
- Attribute *mattr,
- AttributePrimitive prim,
- TypeDesc &type,
- AttributeDescriptor &desc)
+void GeometryManager::update_attribute_element_offset(Geometry *geom,
+ device_vector<float> &attr_float,
+ size_t &attr_float_offset,
+ device_vector<float2> &attr_float2,
+ size_t &attr_float2_offset,
+ device_vector<float4> &attr_float3,
+ size_t &attr_float3_offset,
+ device_vector<uchar4> &attr_uchar4,
+ size_t &attr_uchar4_offset,
+ Attribute *mattr,
+ AttributePrimitive prim,
+ TypeDesc &type,
+ AttributeDescriptor &desc)
{
if (mattr) {
/* store element and type */
@@ -631,7 +640,7 @@ static void update_attribute_element_offset(Geometry *geom,
/* mesh vertex/curve index is global, not per object, so we sneak
* a correction for that in here */
- if (geom->type == Geometry::MESH) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK &&
desc.flags & ATTR_SUBDIVIDED) {
@@ -655,7 +664,7 @@ static void update_attribute_element_offset(Geometry *geom,
offset -= mesh->corner_offset;
}
}
- else if (geom->type == Geometry::HAIR) {
+ else if (geom->is_hair()) {
Hair *hair = static_cast<Hair *>(geom);
if (element == ATTR_ELEMENT_CURVE)
offset -= hair->prim_offset;
@@ -690,7 +699,8 @@ void GeometryManager::device_update_attributes(Device *device,
geom->index = i;
scene->need_global_attributes(geom_attributes[i]);
- foreach (Shader *shader, geom->used_shaders) {
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
geom_attributes[i].add(shader->attributes);
}
}
@@ -754,7 +764,7 @@ void GeometryManager::device_update_attributes(Device *device,
&attr_float3_size,
&attr_uchar4_size);
- if (geom->type == Geometry::MESH) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
Attribute *subd_attr = mesh->subd_attributes.find(req);
@@ -816,7 +826,7 @@ void GeometryManager::device_update_attributes(Device *device,
req.type,
req.desc);
- if (geom->type == Geometry::MESH) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
Attribute *subd_attr = mesh->subd_attributes.find(req);
@@ -919,7 +929,7 @@ void GeometryManager::mesh_calc_offset(Scene *scene)
size_t optix_prim_size = 0;
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
mesh->vert_offset = vert_size;
@@ -932,8 +942,8 @@ void GeometryManager::mesh_calc_offset(Scene *scene)
vert_size += mesh->verts.size();
tri_size += mesh->num_triangles();
- if (mesh->subd_faces.size()) {
- Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1];
+ if (mesh->get_num_subd_faces()) {
+ Mesh::SubdFace last = mesh->get_subd_face(mesh->get_num_subd_faces() - 1);
patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
/* patch tables are stored in same array so include them in patch_size */
@@ -943,19 +953,19 @@ void GeometryManager::mesh_calc_offset(Scene *scene)
}
}
- face_size += mesh->subd_faces.size();
+ face_size += mesh->get_num_subd_faces();
corner_size += mesh->subd_face_corners.size();
mesh->optix_prim_offset = optix_prim_size;
optix_prim_size += mesh->num_triangles();
}
- else if (geom->type == Geometry::HAIR) {
+ else if (geom->is_hair()) {
Hair *hair = static_cast<Hair *>(geom);
hair->curvekey_offset = curve_key_size;
hair->prim_offset = curve_size;
- curve_key_size += hair->curve_keys.size();
+ curve_key_size += hair->get_curve_keys().size();
curve_size += hair->num_curves();
hair->optix_prim_offset = optix_prim_size;
@@ -977,14 +987,14 @@ void GeometryManager::device_update_mesh(
size_t patch_size = 0;
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
vert_size += mesh->verts.size();
tri_size += mesh->num_triangles();
- if (mesh->subd_faces.size()) {
- Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1];
+ if (mesh->get_num_subd_faces()) {
+ Mesh::SubdFace last = mesh->get_subd_face(mesh->get_num_subd_faces() - 1);
patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
/* patch tables are stored in same array so include them in patch_size */
@@ -994,10 +1004,10 @@ void GeometryManager::device_update_mesh(
}
}
}
- else if (geom->type == Geometry::HAIR) {
+ else if (geom->is_hair()) {
Hair *hair = static_cast<Hair *>(geom);
- curve_key_size += hair->curve_keys.size();
+ curve_key_size += hair->get_curve_keys().size();
curve_size += hair->num_curves();
}
}
@@ -1011,7 +1021,7 @@ void GeometryManager::device_update_mesh(
* really use same semantic of arrays.
*/
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
for (size_t i = 0; i < mesh->num_triangles(); ++i) {
tri_prim_index[i + mesh->prim_offset] = 3 * (i + mesh->prim_offset);
@@ -1039,7 +1049,7 @@ void GeometryManager::device_update_mesh(
float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
mesh->pack_normals(&vnormal[mesh->vert_offset]);
@@ -1071,7 +1081,7 @@ void GeometryManager::device_update_mesh(
float4 *curves = dscene->curves.alloc(curve_size);
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::HAIR) {
+ if (geom->is_hair()) {
Hair *hair = static_cast<Hair *>(geom);
hair->pack_curves(scene,
&curve_keys[hair->curvekey_offset],
@@ -1092,7 +1102,7 @@ void GeometryManager::device_update_mesh(
uint *patch_data = dscene->patches.alloc(patch_size);
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::MESH) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
mesh->pack_patches(&patch_data[mesh->patch_offset],
mesh->vert_offset,
@@ -1115,7 +1125,7 @@ void GeometryManager::device_update_mesh(
if (for_displacement) {
float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3);
foreach (Geometry *geom, scene->geometry) {
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
for (size_t i = 0; i < mesh->num_triangles(); ++i) {
Mesh::Triangle t = mesh->get_triangle(i);
@@ -1242,7 +1252,8 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
foreach (Geometry *geom, scene->geometry) {
geom->has_volume = false;
- foreach (const Shader *shader, geom->used_shaders) {
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->has_volume) {
geom->has_volume = true;
}
@@ -1254,7 +1265,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
/* Re-create volume mesh if we will rebuild or refit the BVH. Note we
* should only do it in that case, otherwise the BVH and mesh can go
* out of sync. */
- if (geom->need_update && geom->type == Geometry::VOLUME) {
+ if (geom->is_modified() && geom->geometry_type == Geometry::VOLUME) {
/* Create volume meshes if there is voxel data. */
if (!volume_images_updated) {
progress.set_status("Updating Meshes Volume Bounds");
@@ -1266,7 +1277,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
create_volume_mesh(volume, progress);
}
- if (geom->type == Geometry::HAIR) {
+ if (geom->is_hair()) {
/* Set curve shape, still a global scene setting for now. */
Hair *hair = static_cast<Hair *>(geom);
hair->curve_shape = scene->params.hair_shape;
@@ -1285,9 +1296,10 @@ void GeometryManager::device_update_displacement_images(Device *device,
ImageManager *image_manager = scene->image_manager;
set<int> bump_images;
foreach (Geometry *geom, scene->geometry) {
- if (geom->need_update) {
- foreach (Shader *shader, geom->used_shaders) {
- if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
+ if (geom->is_modified()) {
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+ if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) {
continue;
}
foreach (ShaderNode *node, shader->graph->nodes) {
@@ -1321,7 +1333,7 @@ void GeometryManager::device_update_volume_images(Device *device, Scene *scene,
set<int> volume_images;
foreach (Geometry *geom, scene->geometry) {
- if (!geom->need_update) {
+ if (!geom->is_modified()) {
continue;
}
@@ -1370,12 +1382,14 @@ void GeometryManager::device_update(Device *device,
});
foreach (Geometry *geom, scene->geometry) {
- foreach (Shader *shader, geom->used_shaders) {
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->need_update_geometry)
- geom->need_update = true;
+ geom->tag_modified();
}
- if (geom->need_update && (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME)) {
+ if (geom->is_modified() &&
+ (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) {
Mesh *mesh = static_cast<Mesh *>(geom);
/* Update normals. */
@@ -1387,8 +1401,7 @@ void GeometryManager::device_update(Device *device,
}
/* Test if we need tessellation. */
- if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 &&
- mesh->subd_params) {
+ if (mesh->need_tesselation()) {
total_tess_needed++;
}
@@ -1413,17 +1426,18 @@ void GeometryManager::device_update(Device *device,
});
Camera *dicing_camera = scene->dicing_camera;
+ dicing_camera->set_screen_size_and_resolution(
+ dicing_camera->get_full_width(), dicing_camera->get_full_height(), 1);
dicing_camera->update(scene);
size_t i = 0;
foreach (Geometry *geom, scene->geometry) {
- if (!(geom->need_update && geom->type == Geometry::MESH)) {
+ if (!(geom->is_modified() && geom->is_mesh())) {
continue;
}
Mesh *mesh = static_cast<Mesh *>(geom);
- if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 &&
- mesh->subd_params) {
+ if (mesh->need_tesselation()) {
string msg = "Tessellating ";
if (mesh->name == "")
msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
@@ -1500,8 +1514,8 @@ void GeometryManager::device_update(Device *device,
});
foreach (Geometry *geom, scene->geometry) {
- if (geom->need_update) {
- if (geom->type == Geometry::MESH) {
+ if (geom->is_modified()) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (displace(device, dscene, scene, mesh, progress)) {
displacement_done = true;
@@ -1543,7 +1557,7 @@ void GeometryManager::device_update(Device *device,
size_t i = 0;
foreach (Geometry *geom, scene->geometry) {
- if (geom->need_update) {
+ if (geom->is_modified()) {
pool.push(function_bind(
&Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
if (geom->need_build_bvh(bvh_layout)) {
diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h
index 6d4364a6454..1c101540464 100644
--- a/intern/cycles/render/geometry.h
+++ b/intern/cycles/render/geometry.h
@@ -56,13 +56,13 @@ class Geometry : public Node {
VOLUME,
};
- Type type;
+ Type geometry_type;
/* Attributes */
AttributeSet attributes;
/* Shaders */
- vector<Shader *> used_shaders;
+ NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders)
/* Transform */
BoundBox bounds;
@@ -71,8 +71,8 @@ class Geometry : public Node {
Transform transform_normal;
/* Motion Blur */
- uint motion_steps;
- bool use_motion_blur;
+ NODE_SOCKET_API(uint, motion_steps)
+ NODE_SOCKET_API(bool, use_motion_blur)
/* Maximum number of motion steps supported (due to Embree). */
static const uint MAX_MOTION_STEPS = 129;
@@ -88,7 +88,6 @@ class Geometry : public Node {
bool has_surface_bssrdf; /* Set in the device_update_flags(). */
/* Update Flags */
- bool need_update;
bool need_update_rebuild;
/* Index into scene->geometry (only valid during update) */
@@ -143,6 +142,16 @@ class Geometry : public Node {
bool has_motion_blur() const;
bool has_voxel_attributes() const;
+ bool is_mesh() const
+ {
+ return geometry_type == MESH;
+ }
+
+ bool is_hair() const
+ {
+ return geometry_type == HAIR;
+ }
+
/* Updates */
void tag_update(Scene *scene, bool rebuild);
};
@@ -206,6 +215,21 @@ class GeometryManager {
void device_update_displacement_images(Device *device, Scene *scene, Progress &progress);
void device_update_volume_images(Device *device, Scene *scene, Progress &progress);
+
+ private:
+ static void update_attribute_element_offset(Geometry *geom,
+ device_vector<float> &attr_float,
+ size_t &attr_float_offset,
+ device_vector<float2> &attr_float2,
+ size_t &attr_float2_offset,
+ device_vector<float4> &attr_float3,
+ size_t &attr_float3_offset,
+ device_vector<uchar4> &attr_uchar4,
+ size_t &attr_uchar4_offset,
+ Attribute *mattr,
+ AttributePrimitive prim,
+ TypeDesc &type,
+ AttributeDescriptor &desc);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 485d6167ee3..1de48aa8b0d 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -273,8 +273,8 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
if (to->type() == SocketType::CLOSURE) {
EmissionNode *emission = create_node<EmissionNode>();
- emission->color = make_float3(1.0f, 1.0f, 1.0f);
- emission->strength = 1.0f;
+ emission->set_color(make_float3(1.0f, 1.0f, 1.0f));
+ emission->set_strength(1.0f);
convert = add(emission);
/* Connect float inputs to Strength to save an additional Falue->Color conversion. */
if (from->type() == SocketType::FLOAT) {
@@ -586,7 +586,7 @@ void ShaderGraph::constant_fold(Scene *scene)
*/
if (has_displacement && !output()->input("Displacement")->link) {
ColorNode *value = (ColorNode *)add(create_node<ColorNode>());
- value->value = output()->displacement;
+ value->set_value(output()->get_displacement());
connect(value->output("Color"), output()->input("Displacement"));
}
@@ -1003,8 +1003,8 @@ void ShaderGraph::bump_from_displacement(bool use_object_space)
/* add bump node and connect copied graphs to it */
BumpNode *bump = (BumpNode *)add(create_node<BumpNode>());
- bump->use_object_space = use_object_space;
- bump->distance = 1.0f;
+ bump->set_use_object_space(use_object_space);
+ bump->set_distance(1.0f);
ShaderOutput *out = displacement_in->link;
ShaderOutput *out_center = nodes_center[out->parent]->output(out->name());
@@ -1016,9 +1016,9 @@ void ShaderGraph::bump_from_displacement(bool use_object_space)
VectorMathNode *dot_dx = (VectorMathNode *)add(create_node<VectorMathNode>());
VectorMathNode *dot_dy = (VectorMathNode *)add(create_node<VectorMathNode>());
- dot_center->type = NODE_VECTOR_MATH_DOT_PRODUCT;
- dot_dx->type = NODE_VECTOR_MATH_DOT_PRODUCT;
- dot_dy->type = NODE_VECTOR_MATH_DOT_PRODUCT;
+ dot_center->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT);
+ dot_dx->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT);
+ dot_dy->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT);
GeometryNode *geom = (GeometryNode *)add(create_node<GeometryNode>());
connect(geom->output("Normal"), dot_center->input("Vector2"));
@@ -1072,7 +1072,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
if (fin->link)
connect(fin->link, fac_in);
else
- mix_node->fac = node->get_float(fin->socket_type);
+ mix_node->set_fac(node->get_float(fin->socket_type));
if (weight_out)
connect(weight_out, weight_in);
@@ -1107,12 +1107,12 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
if (weight_in->link)
connect(weight_in->link, math_node->input("Value1"));
else
- math_node->value1 = weight_value;
+ math_node->set_value1(weight_value);
if (weight_out)
connect(weight_out, math_node->input("Value2"));
else
- math_node->value2 = 1.0f;
+ math_node->set_value2(1.0f);
weight_out = math_node->output("Value");
if (weight_in->link)
diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp
index 3853604f78a..d67bd209142 100644
--- a/intern/cycles/render/hair.cpp
+++ b/intern/cycles/render/hair.cpp
@@ -337,12 +337,18 @@ void Hair::add_curve_key(float3 co, float radius)
{
curve_keys.push_back_reserved(co);
curve_radius.push_back_reserved(radius);
+
+ tag_curve_keys_modified();
+ tag_curve_radius_modified();
}
void Hair::add_curve(int first_key, int shader)
{
curve_first_key.push_back_reserved(first_key);
curve_shader.push_back_reserved(shader);
+
+ tag_curve_first_key_modified();
+ tag_curve_shader_modified();
}
void Hair::copy_center_to_motion_step(const int motion_step)
@@ -474,8 +480,9 @@ void Hair::pack_curves(Scene *scene,
for (size_t i = 0; i < curve_num; i++) {
Curve curve = get_curve(i);
int shader_id = curve_shader[i];
- Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] :
- scene->default_surface;
+ Shader *shader = (shader_id < used_shaders.size()) ?
+ static_cast<Shader *>(used_shaders[shader_id]) :
+ scene->default_surface;
shader_id = scene->shader_manager->get_shader_id(shader, false);
curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset),
diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h
index bb6fa7fa4d8..32c5b00e879 100644
--- a/intern/cycles/render/hair.h
+++ b/intern/cycles/render/hair.h
@@ -89,10 +89,10 @@ class Hair : public Geometry {
float4 r_keys[4]) const;
};
- array<float3> curve_keys;
- array<float> curve_radius;
- array<int> curve_first_key;
- array<int> curve_shader;
+ NODE_SOCKET_API(array<float3>, curve_keys)
+ NODE_SOCKET_API(array<float>, curve_radius)
+ NODE_SOCKET_API(array<int>, curve_first_key)
+ NODE_SOCKET_API(array<int>, curve_shader)
/* BVH */
size_t curvekey_offset;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index e50e70c8591..3e6ff289c85 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -381,7 +381,7 @@ ImageHandle ImageManager::add_image(const string &filename, const ImageParams &p
ImageHandle ImageManager::add_image(const string &filename,
const ImageParams &params,
- const vector<int> &tiles)
+ const array<int> &tiles)
{
ImageHandle handle;
handle.manager = this;
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index c9eccb3468a..6ac1db9ed63 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -174,7 +174,7 @@ class ImageManager {
ImageHandle add_image(const string &filename, const ImageParams &params);
ImageHandle add_image(const string &filename,
const ImageParams &params,
- const vector<int> &tiles);
+ const array<int> &tiles);
ImageHandle add_image(ImageLoader *loader, const ImageParams &params, const bool builtin = true);
void device_update(Device *device, Scene *scene, Progress &progress);
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index cc085af20a0..3dc4b2fd4c5 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -96,7 +96,6 @@ NODE_DEFINE(Integrator)
Integrator::Integrator() : Node(node_type)
{
- need_update = true;
}
Integrator::~Integrator()
@@ -105,7 +104,7 @@ Integrator::~Integrator()
void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- if (!need_update)
+ if (!is_modified())
return;
scoped_callback_timer timer([scene](double time) {
@@ -144,7 +143,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->transparent_shadows = false;
foreach (Shader *shader, scene->shaders) {
/* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */
- if ((shader->has_surface_transparent && shader->use_transparent_shadow) ||
+ if ((shader->has_surface_transparent && shader->get_use_transparent_shadow()) ||
shader->has_volume) {
kintegrator->transparent_shadows = true;
break;
@@ -227,7 +226,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
if (method == BRANCHED_PATH) {
foreach (Light *light, scene->lights)
- max_samples = max(max_samples, light->samples);
+ max_samples = max(max_samples, light->get_samples());
max_samples = max(max_samples,
max(diffuse_samples, max(glossy_samples, transmission_samples)));
@@ -265,7 +264,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
dscene->sample_pattern_lut.copy_to_device();
}
- need_update = false;
+ clear_modified();
}
void Integrator::device_free(Device *, DeviceScene *dscene)
@@ -273,11 +272,6 @@ void Integrator::device_free(Device *, DeviceScene *dscene)
dscene->sample_pattern_lut.free();
}
-bool Integrator::modified(const Integrator &integrator)
-{
- return !Node::equals(integrator);
-}
-
void Integrator::tag_update(Scene *scene)
{
foreach (Shader *shader, scene->shaders) {
@@ -286,7 +280,7 @@ void Integrator::tag_update(Scene *scene)
break;
}
}
- need_update = true;
+ tag_modified();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 9804caebe6e..9fe46ad591c 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -31,52 +31,52 @@ class Integrator : public Node {
public:
NODE_DECLARE
- int min_bounce;
- int max_bounce;
+ NODE_SOCKET_API(int, min_bounce)
+ NODE_SOCKET_API(int, max_bounce)
- int max_diffuse_bounce;
- int max_glossy_bounce;
- int max_transmission_bounce;
- int max_volume_bounce;
+ NODE_SOCKET_API(int, max_diffuse_bounce)
+ NODE_SOCKET_API(int, max_glossy_bounce)
+ NODE_SOCKET_API(int, max_transmission_bounce)
+ NODE_SOCKET_API(int, max_volume_bounce)
- int transparent_min_bounce;
- int transparent_max_bounce;
+ NODE_SOCKET_API(int, transparent_min_bounce)
+ NODE_SOCKET_API(int, transparent_max_bounce)
- int ao_bounces;
+ NODE_SOCKET_API(int, ao_bounces)
- int volume_max_steps;
- float volume_step_rate;
+ NODE_SOCKET_API(int, volume_max_steps)
+ NODE_SOCKET_API(float, volume_step_rate)
- bool caustics_reflective;
- bool caustics_refractive;
- float filter_glossy;
+ NODE_SOCKET_API(bool, caustics_reflective)
+ NODE_SOCKET_API(bool, caustics_refractive)
+ NODE_SOCKET_API(float, filter_glossy)
- int seed;
+ NODE_SOCKET_API(int, seed)
- float sample_clamp_direct;
- float sample_clamp_indirect;
- bool motion_blur;
+ NODE_SOCKET_API(float, sample_clamp_direct)
+ NODE_SOCKET_API(float, sample_clamp_indirect)
+ NODE_SOCKET_API(bool, motion_blur)
/* Maximum number of samples, beyond which we are likely to run into
* precision issues for sampling patterns. */
static const int MAX_SAMPLES = (1 << 24);
- int aa_samples;
- int diffuse_samples;
- int glossy_samples;
- int transmission_samples;
- int ao_samples;
- int mesh_light_samples;
- int subsurface_samples;
- int volume_samples;
- int start_sample;
+ NODE_SOCKET_API(int, aa_samples)
+ NODE_SOCKET_API(int, diffuse_samples)
+ NODE_SOCKET_API(int, glossy_samples)
+ NODE_SOCKET_API(int, transmission_samples)
+ NODE_SOCKET_API(int, ao_samples)
+ NODE_SOCKET_API(int, mesh_light_samples)
+ NODE_SOCKET_API(int, subsurface_samples)
+ NODE_SOCKET_API(int, volume_samples)
+ NODE_SOCKET_API(int, start_sample)
- bool sample_all_lights_direct;
- bool sample_all_lights_indirect;
- float light_sampling_threshold;
+ NODE_SOCKET_API(bool, sample_all_lights_direct)
+ NODE_SOCKET_API(bool, sample_all_lights_indirect)
+ NODE_SOCKET_API(float, light_sampling_threshold)
- int adaptive_min_samples;
- float adaptive_threshold;
+ NODE_SOCKET_API(int, adaptive_min_samples)
+ NODE_SOCKET_API(float, adaptive_threshold)
enum Method {
BRANCHED_PATH = 0,
@@ -85,11 +85,9 @@ class Integrator : public Node {
NUM_METHODS,
};
- Method method;
+ NODE_SOCKET_API(Method, method)
- SamplingPattern sampling_pattern;
-
- bool need_update;
+ NODE_SOCKET_API(SamplingPattern, sampling_pattern)
Integrator();
~Integrator();
@@ -97,7 +95,6 @@ class Integrator : public Node {
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
- bool modified(const Integrator &integrator);
void tag_update(Scene *scene);
};
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 100530ffba6..80190dcbf82 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -114,7 +114,7 @@ NODE_DEFINE(Light)
type_enum.insert("background", LIGHT_BACKGROUND);
type_enum.insert("area", LIGHT_AREA);
type_enum.insert("spot", LIGHT_SPOT);
- SOCKET_ENUM(type, "Type", type_enum, LIGHT_POINT);
+ SOCKET_ENUM(light_type, "Type", type_enum, LIGHT_POINT);
SOCKET_COLOR(strength, "Strength", make_float3(1.0f, 1.0f, 1.0f));
@@ -162,7 +162,7 @@ Light::Light() : Node(node_type)
void Light::tag_update(Scene *scene)
{
- scene->light_manager->need_update = true;
+ scene->light_manager->need_update = is_modified();
}
bool Light::has_contribution(Scene *scene)
@@ -173,7 +173,7 @@ bool Light::has_contribution(Scene *scene)
if (is_portal) {
return false;
}
- if (type == LIGHT_BACKGROUND) {
+ if (light_type == LIGHT_BACKGROUND) {
return true;
}
return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission;
@@ -200,7 +200,7 @@ LightManager::~LightManager()
bool LightManager::has_background_light(Scene *scene)
{
foreach (Light *light, scene->lights) {
- if (light->type == LIGHT_BACKGROUND && light->is_enabled) {
+ if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) {
return true;
}
}
@@ -217,7 +217,7 @@ void LightManager::test_enabled_lights(Scene *scene)
foreach (Light *light, scene->lights) {
light->is_enabled = light->has_contribution(scene);
has_portal |= light->is_portal;
- has_background |= light->type == LIGHT_BACKGROUND;
+ has_background |= light->light_type == LIGHT_BACKGROUND;
}
bool background_enabled = false;
@@ -232,7 +232,7 @@ void LightManager::test_enabled_lights(Scene *scene)
const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
VLOG_IF(1, disable_mis) << "Background MIS has been disabled.\n";
foreach (Light *light, scene->lights) {
- if (light->type == LIGHT_BACKGROUND) {
+ if (light->light_type == LIGHT_BACKGROUND) {
light->is_enabled = !disable_mis;
background_enabled = !disable_mis;
background_resolution = light->map_resolution;
@@ -250,8 +250,8 @@ void LightManager::test_enabled_lights(Scene *scene)
bool LightManager::object_usable_as_light(Object *object)
{
- Geometry *geom = object->geometry;
- if (geom->type != Geometry::MESH && geom->type != Geometry::VOLUME) {
+ Geometry *geom = object->get_geometry();
+ if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) {
return false;
}
/* Skip objects with NaNs */
@@ -259,7 +259,7 @@ bool LightManager::object_usable_as_light(Object *object)
return false;
}
/* Skip if we are not visible for BSDFs. */
- if (!(object->visibility & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) {
+ if (!(object->get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) {
return false;
}
/* Skip if we have no emission shaders. */
@@ -267,8 +267,9 @@ bool LightManager::object_usable_as_light(Object *object)
* iterate all geometry shaders twice (when counting and when calculating
* triangle area.
*/
- foreach (const Shader *shader, geom->used_shaders) {
- if (shader->use_mis && shader->has_surface_emission) {
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+ if (shader->get_use_mis() && shader->has_surface_emission) {
return true;
}
}
@@ -308,15 +309,15 @@ void LightManager::device_update_distribution(Device *,
}
/* Count triangles. */
- Mesh *mesh = static_cast<Mesh *>(object->geometry);
+ Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
size_t mesh_num_triangles = mesh->num_triangles();
for (size_t i = 0; i < mesh_num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] :
+ int shader_index = mesh->get_shader()[i];
+ Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
+ static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) :
scene->default_surface;
- if (shader->use_mis && shader->has_surface_emission) {
+ if (shader->get_use_mis() && shader->has_surface_emission) {
num_triangles++;
}
}
@@ -342,37 +343,37 @@ void LightManager::device_update_distribution(Device *,
continue;
}
/* Sum area. */
- Mesh *mesh = static_cast<Mesh *>(object->geometry);
+ Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
bool transform_applied = mesh->transform_applied;
- Transform tfm = object->tfm;
+ Transform tfm = object->get_tfm();
int object_id = j;
int shader_flag = 0;
- if (!(object->visibility & PATH_RAY_DIFFUSE)) {
+ if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) {
shader_flag |= SHADER_EXCLUDE_DIFFUSE;
use_light_visibility = true;
}
- if (!(object->visibility & PATH_RAY_GLOSSY)) {
+ if (!(object->get_visibility() & PATH_RAY_GLOSSY)) {
shader_flag |= SHADER_EXCLUDE_GLOSSY;
use_light_visibility = true;
}
- if (!(object->visibility & PATH_RAY_TRANSMIT)) {
+ if (!(object->get_visibility() & PATH_RAY_TRANSMIT)) {
shader_flag |= SHADER_EXCLUDE_TRANSMIT;
use_light_visibility = true;
}
- if (!(object->visibility & PATH_RAY_VOLUME_SCATTER)) {
+ if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) {
shader_flag |= SHADER_EXCLUDE_SCATTER;
use_light_visibility = true;
}
size_t mesh_num_triangles = mesh->num_triangles();
for (size_t i = 0; i < mesh_num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] :
+ int shader_index = mesh->get_shader()[i];
+ Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
+ static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) :
scene->default_surface;
- if (shader->use_mis && shader->has_surface_emission) {
+ if (shader->get_use_mis() && shader->has_surface_emission) {
distribution[offset].totarea = totarea;
distribution[offset].prim = i + mesh->prim_offset;
distribution[offset].mesh_light.shader_flag = shader_flag;
@@ -380,12 +381,12 @@ void LightManager::device_update_distribution(Device *,
offset++;
Mesh::Triangle t = mesh->get_triangle(i);
- if (!t.valid(&mesh->verts[0])) {
+ if (!t.valid(&mesh->get_verts()[0])) {
continue;
}
- float3 p1 = mesh->verts[t.v[0]];
- float3 p2 = mesh->verts[t.v[1]];
- float3 p3 = mesh->verts[t.v[2]];
+ float3 p1 = mesh->get_verts()[t.v[0]];
+ float3 p2 = mesh->get_verts()[t.v[1]];
+ float3 p3 = mesh->get_verts()[t.v[2]];
if (!transform_applied) {
p1 = transform_point(&tfm, p1);
@@ -417,16 +418,16 @@ void LightManager::device_update_distribution(Device *,
distribution[offset].lamp.size = light->size;
totarea += lightarea;
- if (light->type == LIGHT_DISTANT) {
+ if (light->light_type == LIGHT_DISTANT) {
use_lamp_mis |= (light->angle > 0.0f && light->use_mis);
}
- else if (light->type == LIGHT_POINT || light->type == LIGHT_SPOT) {
+ else if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) {
use_lamp_mis |= (light->size > 0.0f && light->use_mis);
}
- else if (light->type == LIGHT_AREA) {
+ else if (light->light_type == LIGHT_AREA) {
use_lamp_mis |= light->use_mis;
}
- else if (light->type == LIGHT_BACKGROUND) {
+ else if (light->light_type == LIGHT_BACKGROUND) {
num_background_lights++;
background_mis |= light->use_mis;
}
@@ -576,7 +577,7 @@ void LightManager::device_update_background(Device *device,
/* find background light */
foreach (Light *light, scene->lights) {
- if (light->type == LIGHT_BACKGROUND) {
+ if (light->light_type == LIGHT_BACKGROUND) {
background_light = light;
break;
}
@@ -611,7 +612,7 @@ void LightManager::device_update_background(Device *device,
}
if (node->type == SkyTextureNode::node_type) {
SkyTextureNode *sky = (SkyTextureNode *)node;
- if (sky->type == NODE_SKY_NISHITA && sky->sun_disc) {
+ if (sky->get_sky_type() == NODE_SKY_NISHITA && sky->get_sun_disc()) {
/* Ensure that the input coordinates aren't transformed before they reach the node.
* If that is the case, the logic used for sampling the sun's location does not work
* and we have to fall back to map-based sampling. */
@@ -627,8 +628,8 @@ void LightManager::device_update_background(Device *device,
}
/* Determine sun direction from lat/long and texture mapping. */
- float latitude = sky->sun_elevation;
- float longitude = M_2PI_F - sky->sun_rotation + M_PI_2_F;
+ float latitude = sky->get_sun_elevation();
+ float longitude = M_2PI_F - sky->get_sun_rotation() + M_PI_2_F;
float3 sun_direction = make_float3(
cosf(latitude) * cosf(longitude), cosf(latitude) * sinf(longitude), sinf(latitude));
Transform sky_transform = transform_inverse(sky->tex_mapping.compute_transform());
@@ -771,13 +772,13 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
use_light_visibility = true;
}
- klights[light_index].type = light->type;
+ klights[light_index].type = light->light_type;
klights[light_index].samples = light->samples;
klights[light_index].strength[0] = light->strength.x;
klights[light_index].strength[1] = light->strength.y;
klights[light_index].strength[2] = light->strength.z;
- if (light->type == LIGHT_POINT) {
+ if (light->light_type == LIGHT_POINT) {
shader_id &= ~SHADER_AREA_LIGHT;
float radius = light->size;
@@ -793,7 +794,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
klights[light_index].spot.radius = radius;
klights[light_index].spot.invarea = invarea;
}
- else if (light->type == LIGHT_DISTANT) {
+ else if (light->light_type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
float angle = light->angle / 2.0f;
@@ -816,8 +817,8 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
klights[light_index].distant.radius = radius;
klights[light_index].distant.cosangle = cosangle;
}
- else if (light->type == LIGHT_BACKGROUND) {
- uint visibility = scene->background->visibility;
+ else if (light->light_type == LIGHT_BACKGROUND) {
+ uint visibility = scene->background->get_visibility();
shader_id &= ~SHADER_AREA_LIGHT;
shader_id |= SHADER_USE_MIS;
@@ -839,7 +840,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
use_light_visibility = true;
}
}
- else if (light->type == LIGHT_AREA) {
+ else if (light->light_type == LIGHT_AREA) {
float3 axisu = light->axisu * (light->sizeu * light->size);
float3 axisv = light->axisv * (light->sizev * light->size);
float area = len(axisu) * len(axisv);
@@ -869,7 +870,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
klights[light_index].area.dir[1] = dir.y;
klights[light_index].area.dir[2] = dir.z;
}
- else if (light->type == LIGHT_SPOT) {
+ else if (light->light_type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
float radius = light->size;
@@ -913,7 +914,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
foreach (Light *light, scene->lights) {
if (!light->is_portal)
continue;
- assert(light->type == LIGHT_AREA);
+ assert(light->light_type == LIGHT_AREA);
float3 co = light->co;
float3 axisu = light->axisu * (light->sizeu * light->size);
@@ -995,10 +996,7 @@ void LightManager::device_update(Device *device,
if (progress.get_cancel())
return;
- if (use_light_visibility != scene->film->use_light_visibility) {
- scene->film->use_light_visibility = use_light_visibility;
- scene->film->tag_update(scene);
- }
+ scene->film->set_use_light_visibility(use_light_visibility);
need_update = false;
need_update_background = false;
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index d136e8f1a08..e590e13b489 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -21,6 +21,10 @@
#include "graph/node.h"
+/* included as Light::set_shader defined through NODE_SOCKET_API does not select
+ * the right Node::set overload as it does not know that Shader is a Node */
+#include "render/shader.h"
+
#include "util/util_ies.h"
#include "util/util_thread.h"
#include "util/util_types.h"
@@ -41,46 +45,48 @@ class Light : public Node {
Light();
- LightType type;
- float3 strength;
- float3 co;
+ NODE_SOCKET_API(LightType, light_type)
+ NODE_SOCKET_API(float3, strength)
+ NODE_SOCKET_API(float3, co)
- float3 dir;
- float size;
- float angle;
+ NODE_SOCKET_API(float3, dir)
+ NODE_SOCKET_API(float, size)
+ NODE_SOCKET_API(float, angle)
- float3 axisu;
- float sizeu;
- float3 axisv;
- float sizev;
- bool round;
+ NODE_SOCKET_API(float3, axisu)
+ NODE_SOCKET_API(float, sizeu)
+ NODE_SOCKET_API(float3, axisv)
+ NODE_SOCKET_API(float, sizev)
+ NODE_SOCKET_API(bool, round)
- Transform tfm;
+ NODE_SOCKET_API(Transform, tfm)
- int map_resolution;
+ NODE_SOCKET_API(int, map_resolution)
- float spot_angle;
- float spot_smooth;
+ NODE_SOCKET_API(float, spot_angle)
+ NODE_SOCKET_API(float, spot_smooth)
- bool cast_shadow;
- bool use_mis;
- bool use_diffuse;
- bool use_glossy;
- bool use_transmission;
- bool use_scatter;
+ NODE_SOCKET_API(bool, cast_shadow)
+ NODE_SOCKET_API(bool, use_mis)
+ NODE_SOCKET_API(bool, use_diffuse)
+ NODE_SOCKET_API(bool, use_glossy)
+ NODE_SOCKET_API(bool, use_transmission)
+ NODE_SOCKET_API(bool, use_scatter)
- bool is_portal;
- bool is_enabled;
+ NODE_SOCKET_API(bool, is_portal)
+ NODE_SOCKET_API(bool, is_enabled)
- Shader *shader;
- int samples;
- int max_bounces;
- uint random_id;
+ NODE_SOCKET_API(Shader *, shader)
+ NODE_SOCKET_API(int, samples)
+ NODE_SOCKET_API(int, max_bounces)
+ NODE_SOCKET_API(uint, random_id)
void tag_update(Scene *scene);
/* Check whether the light has contribution the scene. */
bool has_contribution(Scene *scene);
+
+ friend class LightManager;
};
class LightManager {
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 49a737f5b1f..11c8e240afd 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -132,11 +132,58 @@ NODE_DEFINE(Mesh)
SOCKET_INT_ARRAY(shader, "Shader", array<int>());
SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>());
+ SOCKET_INT_ARRAY(triangle_patch, "Triangle Patch", array<int>());
+ SOCKET_POINT2_ARRAY(vert_patch_uv, "Patch UVs", array<float2>());
+
+ static NodeEnum subdivision_type_enum;
+ subdivision_type_enum.insert("none", SUBDIVISION_NONE);
+ subdivision_type_enum.insert("linear", SUBDIVISION_LINEAR);
+ subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK);
+ SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE);
+
+ SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>());
+ SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>());
+ SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>());
+ SOCKET_INT_ARRAY(subd_start_corner, "Subdivision Face Start Corner", array<int>());
+ SOCKET_INT_ARRAY(subd_num_corners, "Subdivision Face Corner Count", array<int>());
+ SOCKET_INT_ARRAY(subd_shader, "Subdivision Face Shader", array<int>());
+ SOCKET_BOOLEAN_ARRAY(subd_smooth, "Subdivision Face Smooth", array<bool>());
+ SOCKET_INT_ARRAY(subd_ptex_offset, "Subdivision Face PTex Offset", array<int>());
+ SOCKET_INT(num_ngons, "NGons Number", 0);
+
+ /* Subdivisions parameters */
+ SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 0.0f)
+ SOCKET_INT(subd_max_level, "Subdivision Dicing Rate", 0);
+ SOCKET_TRANSFORM(subd_objecttoworld, "Subdivision Object Transform", transform_identity());
+
return type;
}
-Mesh::Mesh(const NodeType *node_type_, Type geom_type_)
- : Geometry(node_type_, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD)
+SubdParams *Mesh::get_subd_params()
+{
+ if (subdivision_type == SubdivisionType::SUBDIVISION_NONE) {
+ return nullptr;
+ }
+
+ if (!subd_params) {
+ subd_params = new SubdParams(this);
+ }
+
+ subd_params->dicing_rate = subd_dicing_rate;
+ subd_params->max_level = subd_max_level;
+ subd_params->objecttoworld = subd_objecttoworld;
+
+ return subd_params;
+}
+
+bool Mesh::need_tesselation()
+{
+ return get_subd_params() && (verts_is_modified() || subd_dicing_rate_is_modified() ||
+ subd_objecttoworld_is_modified() || subd_max_level_is_modified());
+}
+
+Mesh::Mesh(const NodeType *node_type, Type geom_type_)
+ : Geometry(node_type, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD)
{
vert_offset = 0;
@@ -145,6 +192,7 @@ Mesh::Mesh(const NodeType *node_type_, Type geom_type_)
corner_offset = 0;
num_subd_verts = 0;
+ num_subd_faces = 0;
num_ngons = 0;
@@ -171,7 +219,7 @@ void Mesh::resize_mesh(int numverts, int numtris)
shader.resize(numtris);
smooth.resize(numtris);
- if (subd_faces.size()) {
+ if (get_num_subd_faces()) {
triangle_patch.resize(numtris);
vert_patch_uv.resize(numverts);
}
@@ -187,7 +235,7 @@ void Mesh::reserve_mesh(int numverts, int numtris)
shader.reserve(numtris);
smooth.reserve(numtris);
- if (subd_faces.size()) {
+ if (get_num_subd_faces()) {
triangle_patch.reserve(numtris);
vert_patch_uv.reserve(numverts);
}
@@ -197,22 +245,38 @@ void Mesh::reserve_mesh(int numverts, int numtris)
void Mesh::resize_subd_faces(int numfaces, int num_ngons_, int numcorners)
{
- subd_faces.resize(numfaces);
+ subd_start_corner.resize(numfaces);
+ subd_num_corners.resize(numfaces);
+ subd_shader.resize(numfaces);
+ subd_smooth.resize(numfaces);
+ subd_ptex_offset.resize(numfaces);
subd_face_corners.resize(numcorners);
num_ngons = num_ngons_;
+ num_subd_faces = numfaces;
subd_attributes.resize();
}
void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners)
{
- subd_faces.reserve(numfaces);
+ subd_start_corner.reserve(numfaces);
+ subd_num_corners.reserve(numfaces);
+ subd_shader.reserve(numfaces);
+ subd_smooth.reserve(numfaces);
+ subd_ptex_offset.reserve(numfaces);
subd_face_corners.reserve(numcorners);
num_ngons = num_ngons_;
+ num_subd_faces = numfaces;
subd_attributes.resize(true);
}
+void Mesh::reserve_subd_creases(size_t num_creases)
+{
+ subd_creases_edge.reserve(num_creases * 2);
+ subd_creases_weight.reserve(num_creases);
+}
+
void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
{
Geometry::clear(preserve_shaders);
@@ -226,12 +290,18 @@ void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
triangle_patch.clear();
vert_patch_uv.clear();
- subd_faces.clear();
+ subd_start_corner.clear();
+ subd_num_corners.clear();
+ subd_shader.clear();
+ subd_smooth.clear();
+ subd_ptex_offset.clear();
subd_face_corners.clear();
num_subd_verts = 0;
+ num_subd_faces = 0;
- subd_creases.clear();
+ subd_creases_edge.clear();
+ subd_creases_weight.clear();
subd_attributes.clear();
attributes.clear(preserve_voxel_data);
@@ -239,6 +309,8 @@ void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
vert_to_stitching_key_map.clear();
vert_stitching_map.clear();
+ subdivision_type = SubdivisionType::SUBDIVISION_NONE;
+
delete patch_table;
patch_table = NULL;
}
@@ -251,18 +323,22 @@ void Mesh::clear(bool preserve_shaders)
void Mesh::add_vertex(float3 P)
{
verts.push_back_reserved(P);
+ tag_verts_modified();
- if (subd_faces.size()) {
+ if (get_num_subd_faces()) {
vert_patch_uv.push_back_reserved(make_float2(0.0f, 0.0f));
+ tag_vert_patch_uv_modified();
}
}
void Mesh::add_vertex_slow(float3 P)
{
verts.push_back_slow(P);
+ tag_verts_modified();
- if (subd_faces.size()) {
+ if (get_num_subd_faces()) {
vert_patch_uv.push_back_slow(make_float2(0.0f, 0.0f));
+ tag_vert_patch_uv_modified();
}
}
@@ -274,8 +350,13 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
shader.push_back_reserved(shader_);
smooth.push_back_reserved(smooth_);
- if (subd_faces.size()) {
+ tag_triangles_modified();
+ tag_shader_modified();
+ tag_smooth_modified();
+
+ if (get_num_subd_faces()) {
triangle_patch.push_back_reserved(-1);
+ tag_triangle_patch_modified();
}
}
@@ -288,14 +369,47 @@ void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth
}
int ptex_offset = 0;
-
- if (subd_faces.size()) {
- SubdFace &s = subd_faces[subd_faces.size() - 1];
+ // cannot use get_num_subd_faces here as it holds the total number of subd_faces, but we do not
+ // have the total amount of data yet
+ if (subd_shader.size()) {
+ SubdFace s = get_subd_face(subd_shader.size() - 1);
ptex_offset = s.ptex_offset + s.num_ptex_faces();
}
- SubdFace face = {start_corner, num_corners, shader_, smooth_, ptex_offset};
- subd_faces.push_back_reserved(face);
+ subd_start_corner.push_back_reserved(start_corner);
+ subd_num_corners.push_back_reserved(num_corners);
+ subd_shader.push_back_reserved(shader_);
+ subd_smooth.push_back_reserved(smooth_);
+ subd_ptex_offset.push_back_reserved(ptex_offset);
+
+ tag_subd_face_corners_modified();
+ tag_subd_start_corner_modified();
+ tag_subd_num_corners_modified();
+ tag_subd_shader_modified();
+ tag_subd_smooth_modified();
+ tag_subd_ptex_offset_modified();
+}
+
+Mesh::SubdFace Mesh::get_subd_face(size_t index) const
+{
+ Mesh::SubdFace s;
+ s.shader = subd_shader[index];
+ s.num_corners = subd_num_corners[index];
+ s.smooth = subd_smooth[index];
+ s.ptex_offset = subd_ptex_offset[index];
+ s.start_corner = subd_start_corner[index];
+ return s;
+}
+
+void Mesh::add_crease(int v0, int v1, float weight)
+{
+ subd_creases_edge.push_back_slow(v0);
+ subd_creases_edge.push_back_slow(v1);
+ subd_creases_weight.push_back_slow(weight);
+
+ tag_subd_creases_edge_modified();
+ tag_subd_creases_edge_modified();
+ tag_subd_creases_weight_modified();
}
void Mesh::copy_center_to_motion_step(const int motion_step)
@@ -505,7 +619,7 @@ void Mesh::add_vertex_normals()
}
/* subd vertex normals */
- if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && subd_faces.size()) {
+ if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && get_num_subd_faces()) {
/* get attributes */
Attribute *attr_vN = subd_attributes.add(ATTR_STD_VERTEX_NORMAL);
float3 *vN = attr_vN->data_float3();
@@ -513,8 +627,8 @@ void Mesh::add_vertex_normals()
/* compute vertex normals */
memset(vN, 0, verts.size() * sizeof(float3));
- for (size_t i = 0; i < subd_faces.size(); i++) {
- SubdFace &face = subd_faces[i];
+ for (size_t i = 0; i < get_num_subd_faces(); i++) {
+ SubdFace face = get_subd_face(i);
float3 fN = face.normal(this);
for (size_t j = 0; j < face.num_corners; j++) {
@@ -574,8 +688,9 @@ void Mesh::pack_shaders(Scene *scene, uint *tri_shader)
if (shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
last_shader = shader_ptr[i];
last_smooth = smooth[i];
- Shader *shader = (last_shader < used_shaders.size()) ? used_shaders[last_shader] :
- scene->default_surface;
+ Shader *shader = (last_shader < used_shaders.size()) ?
+ static_cast<Shader *>(used_shaders[last_shader]) :
+ scene->default_surface;
shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
}
@@ -616,7 +731,7 @@ void Mesh::pack_verts(const vector<uint> &tri_prim_index,
{
size_t verts_size = verts.size();
- if (verts_size && subd_faces.size()) {
+ if (verts_size && get_num_subd_faces()) {
float2 *vert_patch_uv_ptr = vert_patch_uv.data();
for (size_t i = 0; i < verts_size; i++) {
@@ -633,17 +748,17 @@ void Mesh::pack_verts(const vector<uint> &tri_prim_index,
t.v[2] + vert_offset,
tri_prim_index[i + tri_offset]);
- tri_patch[i] = (!subd_faces.size()) ? -1 : (triangle_patch[i] * 8 + patch_offset);
+ tri_patch[i] = (!get_num_subd_faces()) ? -1 : (triangle_patch[i] * 8 + patch_offset);
}
}
void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset)
{
- size_t num_faces = subd_faces.size();
+ size_t num_faces = get_num_subd_faces();
int ngons = 0;
for (size_t f = 0; f < num_faces; f++) {
- SubdFace face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (face.is_quad()) {
int c[4];
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index b03b826cd9f..6630dcd8a35 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -118,36 +118,57 @@ class Mesh : public Geometry {
float crease;
};
+ SubdEdgeCrease get_subd_crease(size_t i) const
+ {
+ SubdEdgeCrease s;
+ s.v[0] = subd_creases_edge[i * 2];
+ s.v[1] = subd_creases_edge[i * 2 + 1];
+ s.crease = subd_creases_weight[i];
+ return s;
+ }
+
+ bool need_tesselation();
+
enum SubdivisionType {
SUBDIVISION_NONE,
SUBDIVISION_LINEAR,
SUBDIVISION_CATMULL_CLARK,
};
- SubdivisionType subdivision_type;
+ NODE_SOCKET_API(SubdivisionType, subdivision_type)
/* Mesh Data */
- array<int> triangles;
- array<float3> verts;
- array<int> shader;
- array<bool> smooth;
+ NODE_SOCKET_API_ARRAY(array<int>, triangles)
+ NODE_SOCKET_API_ARRAY(array<float3>, verts)
+ NODE_SOCKET_API_ARRAY(array<int>, shader)
+ NODE_SOCKET_API_ARRAY(array<bool>, smooth)
/* used for storing patch info for subd triangles, only allocated if there are patches */
- array<int> triangle_patch; /* must be < 0 for non subd triangles */
- array<float2> vert_patch_uv;
+ NODE_SOCKET_API_ARRAY(array<int>, triangle_patch) /* must be < 0 for non subd triangles */
+ NODE_SOCKET_API_ARRAY(array<float2>, vert_patch_uv)
+
+ /* SubdFaces */
+ NODE_SOCKET_API_ARRAY(array<int>, subd_start_corner)
+ NODE_SOCKET_API_ARRAY(array<int>, subd_num_corners)
+ NODE_SOCKET_API_ARRAY(array<int>, subd_shader)
+ NODE_SOCKET_API_ARRAY(array<bool>, subd_smooth)
+ NODE_SOCKET_API_ARRAY(array<int>, subd_ptex_offset)
- array<SubdFace> subd_faces;
- array<int> subd_face_corners;
- int num_ngons;
+ NODE_SOCKET_API_ARRAY(array<int>, subd_face_corners)
+ NODE_SOCKET_API(int, num_ngons)
- array<SubdEdgeCrease> subd_creases;
+ NODE_SOCKET_API_ARRAY(array<int>, subd_creases_edge)
+ NODE_SOCKET_API_ARRAY(array<float>, subd_creases_weight)
- SubdParams *subd_params;
+ /* Subdivisions parameters */
+ NODE_SOCKET_API(float, subd_dicing_rate)
+ NODE_SOCKET_API(int, subd_max_level)
+ NODE_SOCKET_API(Transform, subd_objecttoworld)
AttributeSet subd_attributes;
+ private:
PackedPatchTable *patch_table;
-
/* BVH */
size_t vert_offset;
@@ -157,13 +178,22 @@ class Mesh : public Geometry {
size_t corner_offset;
size_t num_subd_verts;
+ size_t num_subd_faces;
- private:
unordered_map<int, int> vert_to_stitching_key_map; /* real vert index -> stitching index */
unordered_multimap<int, int>
vert_stitching_map; /* stitching index -> multiple real vert indices */
+
+ friend class BVH;
+ friend class BVHBuild;
+ friend class BVHEmbree;
+ friend class BVHSpatialSplit;
friend class DiagSplit;
+ friend class EdgeDice;
friend class GeometryManager;
+ friend class ObjectManager;
+
+ SubdParams *subd_params = nullptr;
public:
/* Functions */
@@ -174,11 +204,13 @@ class Mesh : public Geometry {
void reserve_mesh(int numverts, int numfaces);
void resize_subd_faces(int numfaces, int num_ngons, int numcorners);
void reserve_subd_faces(int numfaces, int num_ngons, int numcorners);
+ void reserve_subd_creases(size_t num_creases);
void clear(bool preserve_shaders = false) override;
void add_vertex(float3 P);
void add_vertex_slow(float3 P);
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_);
+ void add_crease(int v0, int v1, float weight);
void copy_center_to_motion_step(const int motion_step);
@@ -202,6 +234,25 @@ class Mesh : public Geometry {
void tessellate(DiagSplit *split);
+ SubdFace get_subd_face(size_t index) const;
+
+ SubdParams *get_subd_params();
+
+ size_t get_num_subd_faces() const
+ {
+ return num_subd_faces;
+ }
+
+ void set_num_subd_faces(size_t num_subd_faces_)
+ {
+ num_subd_faces = num_subd_faces_;
+ }
+
+ size_t get_num_subd_verts()
+ {
+ return num_subd_verts;
+ }
+
protected:
void clear(bool preserve_shaders, bool preserve_voxel_data);
};
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index 467810f9273..b4fb5dcdea2 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -58,7 +58,7 @@ bool GeometryManager::displace(
size_t object_index = OBJECT_NONE;
for (size_t i = 0; i < scene->objects.size(); i++) {
- if (scene->objects[i]->geometry == mesh) {
+ if (scene->objects[i]->get_geometry() == mesh) {
object_index = i;
break;
}
@@ -76,10 +76,10 @@ bool GeometryManager::displace(
Mesh::Triangle t = mesh->get_triangle(i);
int shader_index = mesh->shader[i];
Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] :
+ static_cast<Shader *>(mesh->used_shaders[shader_index]) :
scene->default_surface;
- if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
+ if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) {
continue;
}
@@ -160,10 +160,10 @@ bool GeometryManager::displace(
Mesh::Triangle t = mesh->get_triangle(i);
int shader_index = mesh->shader[i];
Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] :
+ static_cast<Shader *>(mesh->used_shaders[shader_index]) :
scene->default_surface;
- if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
+ if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) {
continue;
}
@@ -227,8 +227,9 @@ bool GeometryManager::displace(
bool need_recompute_vertex_normals = false;
- foreach (Shader *shader, mesh->used_shaders) {
- if (shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) {
+ foreach (Node *node, mesh->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+ if (shader->has_displacement && shader->get_displacement_method() == DISPLACE_TRUE) {
need_recompute_vertex_normals = true;
break;
}
@@ -241,11 +242,11 @@ bool GeometryManager::displace(
for (size_t i = 0; i < num_triangles; i++) {
int shader_index = mesh->shader[i];
Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] :
+ static_cast<Shader *>(mesh->used_shaders[shader_index]) :
scene->default_surface;
tri_has_true_disp[i] = shader->has_displacement &&
- shader->displacement_method == DISPLACE_TRUE;
+ shader->get_displacement_method() == DISPLACE_TRUE;
}
/* static vertex normals */
diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp
index 3d72b2fab91..7408ee2dbdf 100644
--- a/intern/cycles/render/mesh_subdivision.cpp
+++ b/intern/cycles/render/mesh_subdivision.cpp
@@ -46,13 +46,11 @@ template<>
bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
ccl::Mesh const &mesh)
{
- setNumBaseVertices(refiner, mesh.verts.size());
- setNumBaseFaces(refiner, mesh.subd_faces.size());
+ setNumBaseVertices(refiner, mesh.get_verts().size());
+ setNumBaseFaces(refiner, mesh.get_num_subd_faces());
- const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
-
- for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
- setNumBaseFaceVertices(refiner, i, face->num_corners);
+ for (int i = 0; i < mesh.get_num_subd_faces(); i++) {
+ setNumBaseFaceVertices(refiner, i, mesh.get_subd_num_corners()[i]);
}
return true;
@@ -62,14 +60,17 @@ template<>
bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
ccl::Mesh const &mesh)
{
- const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
+ const ccl::array<int> &subd_face_corners = mesh.get_subd_face_corners();
+ const ccl::array<int> &subd_start_corner = mesh.get_subd_start_corner();
+ const ccl::array<int> &subd_num_corners = mesh.get_subd_num_corners();
- for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
+ for (int i = 0; i < mesh.get_num_subd_faces(); i++) {
IndexArray face_verts = getBaseFaceVertices(refiner, i);
- int *corner = &mesh.subd_face_corners[face->start_corner];
+ int start_corner = subd_start_corner[i];
+ int *corner = &subd_face_corners[start_corner];
- for (int j = 0; j < face->num_corners; j++, corner++) {
+ for (int j = 0; j < subd_num_corners[i]; j++, corner++) {
face_verts[j] = *corner;
}
}
@@ -81,17 +82,18 @@ template<>
bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
ccl::Mesh const &mesh)
{
- const ccl::Mesh::SubdEdgeCrease *crease = mesh.subd_creases.data();
+ size_t num_creases = mesh.get_subd_creases_weight().size();
- for (int i = 0; i < mesh.subd_creases.size(); i++, crease++) {
- Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]);
+ for (int i = 0; i < num_creases; i++) {
+ ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i);
+ Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]);
if (edge != INDEX_INVALID) {
- setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f);
+ setBaseEdgeSharpness(refiner, edge, crease.crease * 10.0f);
}
}
- for (int i = 0; i < mesh.verts.size(); i++) {
+ for (int i = 0; i < mesh.get_verts().size(); i++) {
ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
if (vert_edges.size() == 2) {
@@ -203,8 +205,8 @@ class OsdData {
int num_local_points = patch_table->GetNumLocalPoints();
verts.resize(num_refiner_verts + num_local_points);
- for (int i = 0; i < mesh->verts.size(); i++) {
- verts[i].value = mesh->verts[i];
+ for (int i = 0; i < mesh->get_verts().size(); i++) {
+ verts[i].value = mesh->get_verts()[i];
}
OsdValue<float3> *src = verts.data();
@@ -278,16 +280,17 @@ class OsdData {
{
/* loop over all edges to find longest in screen space */
const Far::TopologyLevel &level = refiner->GetLevel(0);
- Transform objecttoworld = mesh->subd_params->objecttoworld;
- Camera *cam = mesh->subd_params->camera;
+ const SubdParams *subd_params = mesh->get_subd_params();
+ Transform objecttoworld = subd_params->objecttoworld;
+ Camera *cam = subd_params->camera;
float longest_edge = 0.0f;
for (size_t i = 0; i < level.GetNumEdges(); i++) {
Far::ConstIndexArray verts = level.GetEdgeVertices(i);
- float3 a = mesh->verts[verts[0]];
- float3 b = mesh->verts[verts[1]];
+ float3 a = mesh->get_verts()[verts[0]];
+ float3 b = mesh->get_verts()[verts[1]];
float edge_len;
@@ -305,7 +308,7 @@ class OsdData {
}
/* calculate isolation level */
- int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
+ int isolation = (int)(log2f(max(longest_edge / subd_params->dicing_rate, 1.0f)) + 1.0f);
return min(isolation, 10);
}
@@ -368,12 +371,16 @@ struct OsdPatch : Patch {
void Mesh::tessellate(DiagSplit *split)
{
+ /* reset the number of subdivision vertices, in case the Mesh was not cleared
+ * between calls or data updates */
+ num_subd_verts = 0;
+
#ifdef WITH_OPENSUBDIV
OsdData osd_data;
bool need_packed_patch_table = false;
if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
- if (subd_faces.size()) {
+ if (get_num_subd_faces()) {
osd_data.build_from_mesh(this);
}
}
@@ -391,7 +398,7 @@ void Mesh::tessellate(DiagSplit *split)
}
}
- int num_faces = subd_faces.size();
+ int num_faces = get_num_subd_faces();
Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
float3 *vN = (attr_vN) ? attr_vN->data_float3() : NULL;
@@ -399,7 +406,7 @@ void Mesh::tessellate(DiagSplit *split)
/* count patches */
int num_patches = 0;
for (int f = 0; f < num_faces; f++) {
- SubdFace &face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (face.is_quad()) {
num_patches++;
@@ -416,7 +423,7 @@ void Mesh::tessellate(DiagSplit *split)
OsdPatch *patch = osd_patches.data();
for (int f = 0; f < num_faces; f++) {
- SubdFace &face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (face.is_quad()) {
patch->patch_index = face.ptex_offset;
@@ -444,7 +451,7 @@ void Mesh::tessellate(DiagSplit *split)
LinearQuadPatch *patch = linear_patches.data();
for (int f = 0; f < num_faces; f++) {
- SubdFace &face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (face.is_quad()) {
float3 *hull = patch->hull;
@@ -542,7 +549,7 @@ void Mesh::tessellate(DiagSplit *split)
/* keep subdivision for corner attributes disabled for now */
attr.flags &= ~ATTR_SUBDIVIDED;
}
- else if (subd_faces.size()) {
+ else if (get_num_subd_faces()) {
osd_data.subdivide_attribute(attr);
need_packed_patch_table = true;
@@ -558,7 +565,7 @@ void Mesh::tessellate(DiagSplit *split)
switch (attr.element) {
case ATTR_ELEMENT_VERTEX: {
for (int f = 0; f < num_faces; f++) {
- SubdFace &face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (!face.is_quad()) {
char *center = data + (verts.size() - num_subd_verts + ngons) * stride;
@@ -581,7 +588,7 @@ void Mesh::tessellate(DiagSplit *split)
} break;
case ATTR_ELEMENT_CORNER: {
for (int f = 0; f < num_faces; f++) {
- SubdFace &face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (!face.is_quad()) {
char *center = data + (subd_face_corners.size() + ngons) * stride;
@@ -600,7 +607,7 @@ void Mesh::tessellate(DiagSplit *split)
} break;
case ATTR_ELEMENT_CORNER_BYTE: {
for (int f = 0; f < num_faces; f++) {
- SubdFace &face = subd_faces[f];
+ SubdFace face = get_subd_face(f);
if (!face.is_quad()) {
uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 500496dc738..43dff896db7 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -247,6 +247,9 @@ NODE_DEFINE(ImageTextureNode)
SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
+ SOCKET_INT_ARRAY(tiles, "Tiles", array<int>());
+ SOCKET_BOOLEAN(animated, "Animated", false);
+
SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV);
SOCKET_OUT_COLOR(color, "Color");
@@ -259,7 +262,7 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
{
colorspace = u_colorspace_raw;
animated = false;
- tiles.push_back(1001);
+ tiles.push_back_slow(1001);
}
ShaderNode *ImageTextureNode::clone(ShaderGraph *graph) const
@@ -286,7 +289,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph)
* 1001 tile, so there's no point in loading any others. */
if (projection == NODE_IMAGE_PROJ_BOX) {
tiles.clear();
- tiles.push_back(1001);
+ tiles.push_back_slow(1001);
return;
}
@@ -308,7 +311,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph)
ShaderNode *node = vector_in->link->parent;
if (node->type == UVMapNode::node_type) {
UVMapNode *uvmap = (UVMapNode *)node;
- attribute = uvmap->attribute;
+ attribute = uvmap->get_attribute();
}
else if (node->type == TextureCoordinateNode::node_type) {
if (vector_in->link != node->output("UV")) {
@@ -325,20 +328,21 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph)
* be to have a cache in each mesh that is indexed by attribute.
* Additionally, building a graph-to-meshes list once could help. */
foreach (Geometry *geom, scene->geometry) {
- foreach (Shader *shader, geom->used_shaders) {
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->graph == graph) {
geom->get_uv_tiles(attribute, used_tiles);
}
}
}
- ccl::vector<int> new_tiles;
+ array<int> new_tiles;
foreach (int tile, tiles) {
if (used_tiles.count(tile)) {
- new_tiles.push_back(tile);
+ new_tiles.push_back_slow(tile);
}
}
- tiles.swap(new_tiles);
+ tiles.steal_data(new_tiles);
}
void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
@@ -511,6 +515,8 @@ NODE_DEFINE(EnvironmentTextureNode)
projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL);
SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR);
+ SOCKET_BOOLEAN(animated, "Animated", false);
+
SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION);
SOCKET_OUT_COLOR(color, "Color");
@@ -790,7 +796,7 @@ NODE_DEFINE(SkyTextureNode)
type_enum.insert("preetham", NODE_SKY_PREETHAM);
type_enum.insert("hosek_wilkie", NODE_SKY_HOSEK);
type_enum.insert("nishita_improved", NODE_SKY_NISHITA);
- SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NISHITA);
+ SOCKET_ENUM(sky_type, "Type", type_enum, NODE_SKY_NISHITA);
SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f));
SOCKET_FLOAT(turbidity, "Turbidity", 2.2f);
@@ -823,11 +829,11 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
ShaderOutput *color_out = output("Color");
SunSky sunsky;
- if (type == NODE_SKY_PREETHAM)
+ if (sky_type == NODE_SKY_PREETHAM)
sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
- else if (type == NODE_SKY_HOSEK)
+ else if (sky_type == NODE_SKY_HOSEK)
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
- else if (type == NODE_SKY_NISHITA) {
+ else if (sky_type == NODE_SKY_NISHITA) {
/* Clamp altitude to reasonable values.
* Below 1m causes numerical issues and above 60km is space. */
float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
@@ -860,9 +866,9 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
compiler.stack_assign(color_out);
- compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), type);
+ compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_type);
/* nishita doesn't need this data */
- if (type != NODE_SKY_NISHITA) {
+ if (sky_type != NODE_SKY_NISHITA) {
compiler.add_node(__float_as_uint(sunsky.phi),
__float_as_uint(sunsky.theta),
__float_as_uint(sunsky.radiance_x),
@@ -919,11 +925,11 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
tex_mapping.compile(compiler);
SunSky sunsky;
- if (type == NODE_SKY_PREETHAM)
+ if (sky_type == NODE_SKY_PREETHAM)
sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
- else if (type == NODE_SKY_HOSEK)
+ else if (sky_type == NODE_SKY_HOSEK)
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
- else if (type == NODE_SKY_NISHITA) {
+ else if (sky_type == NODE_SKY_NISHITA) {
/* Clamp altitude to reasonable values.
* Below 1m causes numerical issues and above 60km is space. */
float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
@@ -963,7 +969,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
compiler.parameter_array("config_z", sunsky.config_z, 9);
compiler.parameter_array("nishita_data", sunsky.nishita_data, 10);
/* nishita texture */
- if (type == NODE_SKY_NISHITA) {
+ if (sky_type == NODE_SKY_NISHITA) {
compiler.parameter_texture("filename", handle.svm_slot());
}
compiler.add(this, "node_sky_texture");
@@ -985,7 +991,7 @@ NODE_DEFINE(GradientTextureNode)
type_enum.insert("radial", NODE_BLEND_RADIAL);
type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE);
type_enum.insert("spherical", NODE_BLEND_SPHERICAL);
- SOCKET_ENUM(type, "Type", type_enum, NODE_BLEND_LINEAR);
+ SOCKET_ENUM(gradient_type, "Type", type_enum, NODE_BLEND_LINEAR);
SOCKET_IN_POINT(
vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
@@ -1009,7 +1015,7 @@ void GradientTextureNode::compile(SVMCompiler &compiler)
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
compiler.add_node(NODE_TEX_GRADIENT,
- compiler.encode_uchar4(type,
+ compiler.encode_uchar4(gradient_type,
vector_offset,
compiler.stack_assign_if_linked(fac_out),
compiler.stack_assign_if_linked(color_out)));
@@ -1369,7 +1375,7 @@ NODE_DEFINE(MusgraveTextureNode)
type_enum.insert("hybrid_multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL);
type_enum.insert("ridged_multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL);
type_enum.insert("hetero_terrain", NODE_MUSGRAVE_HETERO_TERRAIN);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MUSGRAVE_FBM);
+ SOCKET_ENUM(musgrave_type, "Type", type_enum, NODE_MUSGRAVE_FBM);
SOCKET_IN_POINT(
vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
@@ -1414,7 +1420,7 @@ void MusgraveTextureNode::compile(SVMCompiler &compiler)
compiler.add_node(
NODE_TEX_MUSGRAVE,
- compiler.encode_uchar4(type, dimensions, vector_stack_offset, w_stack_offset),
+ compiler.encode_uchar4(musgrave_type, dimensions, vector_stack_offset, w_stack_offset),
compiler.encode_uchar4(scale_stack_offset,
detail_stack_offset,
dimension_stack_offset,
@@ -1447,7 +1453,7 @@ NODE_DEFINE(WaveTextureNode)
static NodeEnum type_enum;
type_enum.insert("bands", NODE_WAVE_BANDS);
type_enum.insert("rings", NODE_WAVE_RINGS);
- SOCKET_ENUM(type, "Type", type_enum, NODE_WAVE_BANDS);
+ SOCKET_ENUM(wave_type, "Type", type_enum, NODE_WAVE_BANDS);
static NodeEnum bands_direction_enum;
bands_direction_enum.insert("x", NODE_WAVE_BANDS_DIRECTION_X);
@@ -1504,7 +1510,7 @@ void WaveTextureNode::compile(SVMCompiler &compiler)
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
compiler.add_node(NODE_TEX_WAVE,
- compiler.encode_uchar4(type, bands_direction, rings_direction, profile),
+ compiler.encode_uchar4(wave_type, bands_direction, rings_direction, profile),
compiler.encode_uchar4(vector_offset,
compiler.stack_assign_if_linked(scale_in),
compiler.stack_assign_if_linked(distortion_in)),
@@ -1926,7 +1932,7 @@ NODE_DEFINE(MappingNode)
type_enum.insert("texture", NODE_MAPPING_TYPE_TEXTURE);
type_enum.insert("vector", NODE_MAPPING_TYPE_VECTOR);
type_enum.insert("normal", NODE_MAPPING_TYPE_NORMAL);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MAPPING_TYPE_POINT);
+ SOCKET_ENUM(mapping_type, "Type", type_enum, NODE_MAPPING_TYPE_POINT);
SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_IN_POINT(location, "Location", make_float3(0.0f, 0.0f, 0.0f));
@@ -1945,11 +1951,11 @@ MappingNode::MappingNode() : ShaderNode(node_type)
void MappingNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
- float3 result = svm_mapping((NodeMappingType)type, vector, location, rotation, scale);
+ float3 result = svm_mapping((NodeMappingType)mapping_type, vector, location, rotation, scale);
folder.make_constant(result);
}
else {
- folder.fold_mapping((NodeMappingType)type);
+ folder.fold_mapping((NodeMappingType)mapping_type);
}
}
@@ -1969,7 +1975,7 @@ void MappingNode::compile(SVMCompiler &compiler)
compiler.add_node(
NODE_MAPPING,
- type,
+ mapping_type,
compiler.encode_uchar4(
vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset),
result_stack_offset);
@@ -2385,7 +2391,7 @@ void GlossyBsdfNode::simplify_settings(Scene *scene)
}
Integrator *integrator = scene->integrator;
ShaderInput *roughness_input = input("Roughness");
- if (integrator->filter_glossy == 0.0f) {
+ if (integrator->get_filter_glossy() == 0.0f) {
/* Fallback to Sharp closure for Roughness close to 0.
* Note: Keep the epsilon in sync with kernel!
*/
@@ -2478,7 +2484,7 @@ void GlassBsdfNode::simplify_settings(Scene *scene)
}
Integrator *integrator = scene->integrator;
ShaderInput *roughness_input = input("Roughness");
- if (integrator->filter_glossy == 0.0f) {
+ if (integrator->get_filter_glossy() == 0.0f) {
/* Fallback to Sharp closure for Roughness close to 0.
* Note: Keep the epsilon in sync with kernel!
*/
@@ -2571,7 +2577,7 @@ void RefractionBsdfNode::simplify_settings(Scene *scene)
}
Integrator *integrator = scene->integrator;
ShaderInput *roughness_input = input("Roughness");
- if (integrator->filter_glossy == 0.0f) {
+ if (integrator->get_filter_glossy() == 0.0f) {
/* Fallback to Sharp closure for Roughness close to 0.
* Note: Keep the epsilon in sync with kernel!
*/
@@ -4481,7 +4487,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *color_out = output("Color");
if (!color_out->links.empty()) {
AttributeNode *attr = graph->create_node<AttributeNode>();
- attr->attribute = "color";
+ attr->set_attribute(ustring("color"));
graph->add(attr);
graph->relink(color_out, attr->output("Color"));
}
@@ -4489,7 +4495,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *density_out = output("Density");
if (!density_out->links.empty()) {
AttributeNode *attr = graph->create_node<AttributeNode>();
- attr->attribute = "density";
+ attr->set_attribute(ustring("density"));
graph->add(attr);
graph->relink(density_out, attr->output("Fac"));
}
@@ -4497,7 +4503,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *flame_out = output("Flame");
if (!flame_out->links.empty()) {
AttributeNode *attr = graph->create_node<AttributeNode>();
- attr->attribute = "flame";
+ attr->set_attribute(ustring("flame"));
graph->add(attr);
graph->relink(flame_out, attr->output("Fac"));
}
@@ -4505,7 +4511,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph)
ShaderOutput *temperature_out = output("Temperature");
if (!temperature_out->links.empty()) {
AttributeNode *attr = graph->create_node<AttributeNode>();
- attr->attribute = "temperature";
+ attr->set_attribute(ustring("temperature"));
graph->add(attr);
graph->relink(temperature_out, attr->output("Fac"));
}
@@ -4882,7 +4888,7 @@ NODE_DEFINE(MixNode)
type_enum.insert("color", NODE_MIX_COLOR);
type_enum.insert("soft_light", NODE_MIX_SOFT);
type_enum.insert("linear_light", NODE_MIX_LINEAR);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MIX_BLEND);
+ SOCKET_ENUM(mix_type, "Type", type_enum, NODE_MIX_BLEND);
SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
@@ -4910,7 +4916,7 @@ void MixNode::compile(SVMCompiler &compiler)
compiler.stack_assign(fac_in),
compiler.stack_assign(color1_in),
compiler.stack_assign(color2_in));
- compiler.add_node(NODE_MIX, type, compiler.stack_assign(color_out));
+ compiler.add_node(NODE_MIX, mix_type, compiler.stack_assign(color_out));
if (use_clamp) {
compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out));
@@ -4928,10 +4934,10 @@ void MixNode::compile(OSLCompiler &compiler)
void MixNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
- folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp);
+ folder.make_constant_clamp(svm_mix(mix_type, fac, color1, color2), use_clamp);
}
else {
- folder.fold_mix(type, use_clamp);
+ folder.fold_mix(mix_type, use_clamp);
}
}
@@ -5761,7 +5767,7 @@ NODE_DEFINE(MapRangeNode)
type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED);
type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP);
type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MAP_RANGE_LINEAR);
+ SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR);
SOCKET_IN_FLOAT(value, "Value", 1.0f);
SOCKET_IN_FLOAT(from_min, "From Min", 0.0f);
@@ -5786,7 +5792,7 @@ void MapRangeNode::expand(ShaderGraph *graph)
ShaderOutput *result_out = output("Result");
if (!result_out->links.empty()) {
ClampNode *clamp_node = graph->create_node<ClampNode>();
- clamp_node->type = NODE_CLAMP_RANGE;
+ clamp_node->set_clamp_type(NODE_CLAMP_RANGE);
graph->add(clamp_node);
graph->relink(result_out, clamp_node->output("Result"));
graph->connect(result_out, clamp_node->input("Value"));
@@ -5794,13 +5800,13 @@ void MapRangeNode::expand(ShaderGraph *graph)
graph->connect(input("To Min")->link, clamp_node->input("Min"));
}
else {
- clamp_node->min = to_min;
+ clamp_node->set_min(to_min);
}
if (input("To Max")->link) {
graph->connect(input("To Max")->link, clamp_node->input("Max"));
}
else {
- clamp_node->max = to_max;
+ clamp_node->set_max(to_max);
}
}
}
@@ -5829,7 +5835,7 @@ void MapRangeNode::compile(SVMCompiler &compiler)
value_stack_offset,
compiler.encode_uchar4(
from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset),
- compiler.encode_uchar4(type, steps_stack_offset, result_stack_offset));
+ compiler.encode_uchar4(range_type, steps_stack_offset, result_stack_offset));
compiler.add_node(__float_as_int(from_min),
__float_as_int(from_max),
@@ -5853,7 +5859,7 @@ NODE_DEFINE(ClampNode)
static NodeEnum type_enum;
type_enum.insert("minmax", NODE_CLAMP_MINMAX);
type_enum.insert("range", NODE_CLAMP_RANGE);
- SOCKET_ENUM(type, "Type", type_enum, NODE_CLAMP_MINMAX);
+ SOCKET_ENUM(clamp_type, "Type", type_enum, NODE_CLAMP_MINMAX);
SOCKET_IN_FLOAT(value, "Value", 1.0f);
SOCKET_IN_FLOAT(min, "Min", 0.0f);
@@ -5871,7 +5877,7 @@ ClampNode::ClampNode() : ShaderNode(node_type)
void ClampNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
- if (type == NODE_CLAMP_RANGE && (min > max)) {
+ if (clamp_type == NODE_CLAMP_RANGE && (min > max)) {
folder.make_constant(clamp(value, max, min));
}
else {
@@ -5894,7 +5900,7 @@ void ClampNode::compile(SVMCompiler &compiler)
compiler.add_node(NODE_CLAMP,
value_stack_offset,
- compiler.encode_uchar4(min_stack_offset, max_stack_offset, type),
+ compiler.encode_uchar4(min_stack_offset, max_stack_offset, clamp_type),
result_stack_offset);
compiler.add_node(__float_as_int(min), __float_as_int(max));
}
@@ -6004,7 +6010,7 @@ NODE_DEFINE(MathNode)
type_enum.insert("smoothmin", NODE_MATH_SMOOTH_MIN);
type_enum.insert("smoothmax", NODE_MATH_SMOOTH_MAX);
type_enum.insert("compare", NODE_MATH_COMPARE);
- SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD);
+ SOCKET_ENUM(math_type, "Type", type_enum, NODE_MATH_ADD);
SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
@@ -6027,9 +6033,9 @@ void MathNode::expand(ShaderGraph *graph)
ShaderOutput *result_out = output("Value");
if (!result_out->links.empty()) {
ClampNode *clamp_node = graph->create_node<ClampNode>();
- clamp_node->type = NODE_CLAMP_MINMAX;
- clamp_node->min = 0.0f;
- clamp_node->max = 1.0f;
+ clamp_node->set_clamp_type(NODE_CLAMP_MINMAX);
+ clamp_node->set_min(0.0f);
+ clamp_node->set_max(1.0f);
graph->add(clamp_node);
graph->relink(result_out, clamp_node->output("Result"));
graph->connect(result_out, clamp_node->input("Value"));
@@ -6040,10 +6046,10 @@ void MathNode::expand(ShaderGraph *graph)
void MathNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
- folder.make_constant(svm_math(type, value1, value2, value3));
+ folder.make_constant(svm_math(math_type, value1, value2, value3));
}
else {
- folder.fold_math(type);
+ folder.fold_math(math_type);
}
}
@@ -6061,7 +6067,7 @@ void MathNode::compile(SVMCompiler &compiler)
compiler.add_node(
NODE_MATH,
- type,
+ math_type,
compiler.encode_uchar4(value1_stack_offset, value2_stack_offset, value3_stack_offset),
value_stack_offset);
}
@@ -6107,7 +6113,7 @@ NODE_DEFINE(VectorMathNode)
type_enum.insert("sine", NODE_VECTOR_MATH_SINE);
type_enum.insert("cosine", NODE_VECTOR_MATH_COSINE);
type_enum.insert("tangent", NODE_VECTOR_MATH_TANGENT);
- SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
+ SOCKET_ENUM(math_type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f));
@@ -6130,7 +6136,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder)
float3 vector = make_float3(0.0f, 0.0f, 0.0f);
if (folder.all_inputs_constant()) {
- svm_vector_math(&value, &vector, type, vector1, vector2, vector3, scale);
+ svm_vector_math(&value, &vector, math_type, vector1, vector2, vector3, scale);
if (folder.output == output("Value")) {
folder.make_constant(value);
}
@@ -6139,7 +6145,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder)
}
}
else {
- folder.fold_vector_math(type);
+ folder.fold_vector_math(math_type);
}
}
@@ -6158,12 +6164,12 @@ void VectorMathNode::compile(SVMCompiler &compiler)
int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
/* 3 Vector Operators */
- if (type == NODE_VECTOR_MATH_WRAP) {
+ if (math_type == NODE_VECTOR_MATH_WRAP) {
ShaderInput *vector3_in = input("Vector3");
int vector3_stack_offset = compiler.stack_assign(vector3_in);
compiler.add_node(
NODE_VECTOR_MATH,
- type,
+ math_type,
compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
compiler.add_node(vector3_stack_offset);
@@ -6171,7 +6177,7 @@ void VectorMathNode::compile(SVMCompiler &compiler)
else {
compiler.add_node(
NODE_VECTOR_MATH,
- type,
+ math_type,
compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
}
@@ -6195,7 +6201,7 @@ NODE_DEFINE(VectorRotateNode)
type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y);
type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z);
type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ);
- SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
+ SOCKET_ENUM(rotate_type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
SOCKET_BOOLEAN(invert, "Invert", false);
@@ -6222,14 +6228,15 @@ void VectorRotateNode::compile(SVMCompiler &compiler)
ShaderInput *angle_in = input("Angle");
ShaderOutput *vector_out = output("Vector");
- compiler.add_node(
- NODE_VECTOR_ROTATE,
- compiler.encode_uchar4(
- type, compiler.stack_assign(vector_in), compiler.stack_assign(rotation_in), invert),
- compiler.encode_uchar4(compiler.stack_assign(center_in),
- compiler.stack_assign(axis_in),
- compiler.stack_assign(angle_in)),
- compiler.stack_assign(vector_out));
+ compiler.add_node(NODE_VECTOR_ROTATE,
+ compiler.encode_uchar4(rotate_type,
+ compiler.stack_assign(vector_in),
+ compiler.stack_assign(rotation_in),
+ invert),
+ compiler.encode_uchar4(compiler.stack_assign(center_in),
+ compiler.stack_assign(axis_in),
+ compiler.stack_assign(angle_in)),
+ compiler.stack_assign(vector_out));
}
void VectorRotateNode::compile(OSLCompiler &compiler)
@@ -6249,7 +6256,7 @@ NODE_DEFINE(VectorTransformNode)
type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT);
type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
- SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
+ SOCKET_ENUM(transform_type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
static NodeEnum space_enum;
space_enum.insert("world", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
@@ -6275,7 +6282,7 @@ void VectorTransformNode::compile(SVMCompiler &compiler)
compiler.add_node(
NODE_VECTOR_TRANSFORM,
- compiler.encode_uchar4(type, convert_from, convert_to),
+ compiler.encode_uchar4(transform_type, convert_from, convert_to),
compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out)));
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 62dd9d843a8..4d51b4fccaf 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -70,6 +70,17 @@ class TextureNode : public ShaderNode {
{
}
TextureMapping tex_mapping;
+ NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, translation)
+ NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, rotation)
+ NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, scale)
+ NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, min)
+ NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, max)
+ NODE_SOCKET_API_STRUCT_MEMBER(bool, tex_mapping, use_minmax)
+ NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Type, tex_mapping, type)
+ NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, x_mapping)
+ NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, y_mapping)
+ NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, z_mapping)
+ NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Projection, tex_mapping, projection)
};
/* Any node which uses image manager's slot should be a subclass of this one. */
@@ -108,16 +119,16 @@ class ImageTextureNode : public ImageSlotTextureNode {
ImageParams image_params() const;
/* Parameters. */
- ustring filename;
- ustring colorspace;
- ImageAlphaType alpha_type;
- NodeImageProjection projection;
- InterpolationType interpolation;
- ExtensionType extension;
- float projection_blend;
- bool animated;
- float3 vector;
- ccl::vector<int> tiles;
+ NODE_SOCKET_API(ustring, filename)
+ NODE_SOCKET_API(ustring, colorspace)
+ NODE_SOCKET_API(ImageAlphaType, alpha_type)
+ NODE_SOCKET_API(NodeImageProjection, projection)
+ NODE_SOCKET_API(InterpolationType, interpolation)
+ NODE_SOCKET_API(ExtensionType, extension)
+ NODE_SOCKET_API(float, projection_blend)
+ NODE_SOCKET_API(bool, animated)
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(array<int>, tiles)
protected:
void cull_tiles(Scene *scene, ShaderGraph *graph);
@@ -146,13 +157,13 @@ class EnvironmentTextureNode : public ImageSlotTextureNode {
ImageParams image_params() const;
/* Parameters. */
- ustring filename;
- ustring colorspace;
- ImageAlphaType alpha_type;
- NodeEnvironmentProjection projection;
- InterpolationType interpolation;
- bool animated;
- float3 vector;
+ NODE_SOCKET_API(ustring, filename)
+ NODE_SOCKET_API(ustring, colorspace)
+ NODE_SOCKET_API(ImageAlphaType, alpha_type)
+ NODE_SOCKET_API(NodeEnvironmentProjection, projection)
+ NODE_SOCKET_API(InterpolationType, interpolation)
+ NODE_SOCKET_API(bool, animated)
+ NODE_SOCKET_API(float3, vector)
};
class SkyTextureNode : public TextureNode {
@@ -164,20 +175,20 @@ class SkyTextureNode : public TextureNode {
return NODE_GROUP_LEVEL_2;
}
- NodeSkyType type;
- float3 sun_direction;
- float turbidity;
- float ground_albedo;
- bool sun_disc;
- float sun_size;
- float sun_intensity;
- float sun_elevation;
- float sun_rotation;
- float altitude;
- float air_density;
- float dust_density;
- float ozone_density;
- float3 vector;
+ NODE_SOCKET_API(NodeSkyType, sky_type)
+ NODE_SOCKET_API(float3, sun_direction)
+ NODE_SOCKET_API(float, turbidity)
+ NODE_SOCKET_API(float, ground_albedo)
+ NODE_SOCKET_API(bool, sun_disc)
+ NODE_SOCKET_API(float, sun_size)
+ NODE_SOCKET_API(float, sun_intensity)
+ NODE_SOCKET_API(float, sun_elevation)
+ NODE_SOCKET_API(float, sun_rotation)
+ NODE_SOCKET_API(float, altitude)
+ NODE_SOCKET_API(float, air_density)
+ NODE_SOCKET_API(float, dust_density)
+ NODE_SOCKET_API(float, ozone_density)
+ NODE_SOCKET_API(float3, vector)
ImageHandle handle;
float get_sun_size()
@@ -191,10 +202,10 @@ class OutputNode : public ShaderNode {
public:
SHADER_NODE_CLASS(OutputNode)
- void *surface;
- void *volume;
- float3 displacement;
- float3 normal;
+ NODE_SOCKET_API(Node *, surface)
+ NODE_SOCKET_API(Node *, volume)
+ NODE_SOCKET_API(float3, displacement)
+ NODE_SOCKET_API(float3, normal)
/* Don't allow output node de-duplication. */
virtual bool equals(const ShaderNode & /*other*/)
@@ -208,10 +219,10 @@ class OutputAOVNode : public ShaderNode {
SHADER_NODE_CLASS(OutputAOVNode)
virtual void simplify_settings(Scene *scene);
- float value;
- float3 color;
+ NODE_SOCKET_API(float, value)
+ NODE_SOCKET_API(float3, color)
- ustring name;
+ NODE_SOCKET_API(ustring, name)
virtual int get_group()
{
@@ -237,17 +248,21 @@ class GradientTextureNode : public TextureNode {
return NODE_GROUP_LEVEL_2;
}
- NodeGradientType type;
- float3 vector;
+ NODE_SOCKET_API(NodeGradientType, gradient_type)
+ NODE_SOCKET_API(float3, vector)
};
class NoiseTextureNode : public TextureNode {
public:
SHADER_NODE_CLASS(NoiseTextureNode)
- int dimensions;
- float w, scale, detail, roughness, distortion;
- float3 vector;
+ NODE_SOCKET_API(int, dimensions)
+ NODE_SOCKET_API(float, w)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float, detail)
+ NODE_SOCKET_API(float, roughness)
+ NODE_SOCKET_API(float, distortion)
+ NODE_SOCKET_API(float3, vector)
};
class VoronoiTextureNode : public TextureNode {
@@ -271,11 +286,15 @@ class VoronoiTextureNode : public TextureNode {
return result;
}
- int dimensions;
- NodeVoronoiDistanceMetric metric;
- NodeVoronoiFeature feature;
- float w, scale, exponent, smoothness, randomness;
- float3 vector;
+ NODE_SOCKET_API(int, dimensions)
+ NODE_SOCKET_API(NodeVoronoiDistanceMetric, metric)
+ NODE_SOCKET_API(NodeVoronoiFeature, feature)
+ NODE_SOCKET_API(float, w)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float, exponent)
+ NODE_SOCKET_API(float, smoothness)
+ NODE_SOCKET_API(float, randomness)
+ NODE_SOCKET_API(float3, vector)
};
class MusgraveTextureNode : public TextureNode {
@@ -287,10 +306,16 @@ class MusgraveTextureNode : public TextureNode {
return NODE_GROUP_LEVEL_2;
}
- int dimensions;
- NodeMusgraveType type;
- float w, scale, detail, dimension, lacunarity, offset, gain;
- float3 vector;
+ NODE_SOCKET_API(int, dimensions)
+ NODE_SOCKET_API(NodeMusgraveType, musgrave_type)
+ NODE_SOCKET_API(float, w)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float, detail)
+ NODE_SOCKET_API(float, dimension)
+ NODE_SOCKET_API(float, lacunarity)
+ NODE_SOCKET_API(float, offset)
+ NODE_SOCKET_API(float, gain)
+ NODE_SOCKET_API(float3, vector)
};
class WaveTextureNode : public TextureNode {
@@ -302,13 +327,18 @@ class WaveTextureNode : public TextureNode {
return NODE_GROUP_LEVEL_2;
}
- NodeWaveType type;
- NodeWaveBandsDirection bands_direction;
- NodeWaveRingsDirection rings_direction;
- NodeWaveProfile profile;
+ NODE_SOCKET_API(NodeWaveType, wave_type)
+ NODE_SOCKET_API(NodeWaveBandsDirection, bands_direction)
+ NODE_SOCKET_API(NodeWaveRingsDirection, rings_direction)
+ NODE_SOCKET_API(NodeWaveProfile, profile)
- float scale, distortion, detail, detail_scale, detail_roughness, phase;
- float3 vector;
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float, distortion)
+ NODE_SOCKET_API(float, detail)
+ NODE_SOCKET_API(float, detail_scale)
+ NODE_SOCKET_API(float, detail_roughness)
+ NODE_SOCKET_API(float, phase)
+ NODE_SOCKET_API(float3, vector)
};
class MagicTextureNode : public TextureNode {
@@ -320,17 +350,20 @@ class MagicTextureNode : public TextureNode {
return NODE_GROUP_LEVEL_2;
}
- int depth;
- float3 vector;
- float scale, distortion;
+ NODE_SOCKET_API(int, depth)
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float, distortion)
};
class CheckerTextureNode : public TextureNode {
public:
SHADER_NODE_CLASS(CheckerTextureNode)
- float3 vector, color1, color2;
- float scale;
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float3, color1)
+ NODE_SOCKET_API(float3, color2)
+ NODE_SOCKET_API(float, scale)
virtual int get_group()
{
@@ -342,12 +375,21 @@ class BrickTextureNode : public TextureNode {
public:
SHADER_NODE_CLASS(BrickTextureNode)
- float offset, squash;
- int offset_frequency, squash_frequency;
-
- float3 color1, color2, mortar;
- float scale, mortar_size, mortar_smooth, bias, brick_width, row_height;
- float3 vector;
+ NODE_SOCKET_API(float, offset)
+ NODE_SOCKET_API(float, squash)
+ NODE_SOCKET_API(int, offset_frequency)
+ NODE_SOCKET_API(int, squash_frequency)
+
+ NODE_SOCKET_API(float3, color1)
+ NODE_SOCKET_API(float3, color2)
+ NODE_SOCKET_API(float3, mortar)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float, mortar_size)
+ NODE_SOCKET_API(float, mortar_smooth)
+ NODE_SOCKET_API(float, bias)
+ NODE_SOCKET_API(float, brick_width)
+ NODE_SOCKET_API(float, row_height)
+ NODE_SOCKET_API(float3, vector)
virtual int get_group()
{
@@ -377,11 +419,11 @@ class PointDensityTextureNode : public ShaderNode {
}
/* Parameters. */
- ustring filename;
- NodeTexVoxelSpace space;
- InterpolationType interpolation;
- Transform tfm;
- float3 vector;
+ NODE_SOCKET_API(ustring, filename)
+ NODE_SOCKET_API(NodeTexVoxelSpace, space)
+ NODE_SOCKET_API(InterpolationType, interpolation)
+ NODE_SOCKET_API(Transform, tfm)
+ NODE_SOCKET_API(float3, vector)
/* Runtime. */
ImageHandle handle;
@@ -406,11 +448,11 @@ class IESLightNode : public TextureNode {
return NODE_GROUP_LEVEL_2;
}
- ustring filename;
- ustring ies;
+ NODE_SOCKET_API(ustring, filename)
+ NODE_SOCKET_API(ustring, ies)
- float strength;
- float3 vector;
+ NODE_SOCKET_API(float, strength)
+ NODE_SOCKET_API(float3, vector)
private:
LightManager *light_manager;
@@ -427,9 +469,9 @@ class WhiteNoiseTextureNode : public ShaderNode {
return NODE_GROUP_LEVEL_2;
}
- int dimensions;
- float3 vector;
- float w;
+ NODE_SOCKET_API(int, dimensions)
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float, w)
};
class MappingNode : public ShaderNode {
@@ -441,8 +483,11 @@ class MappingNode : public ShaderNode {
}
void constant_fold(const ConstantFolder &folder);
- float3 vector, location, rotation, scale;
- NodeMappingType type;
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float3, location)
+ NODE_SOCKET_API(float3, rotation)
+ NODE_SOCKET_API(float3, scale)
+ NODE_SOCKET_API(NodeMappingType, mapping_type)
};
class RGBToBWNode : public ShaderNode {
@@ -450,7 +495,7 @@ class RGBToBWNode : public ShaderNode {
SHADER_NODE_CLASS(RGBToBWNode)
void constant_fold(const ConstantFolder &folder);
- float3 color;
+ NODE_SOCKET_API(float3, color)
};
class ConvertNode : public ShaderNode {
@@ -460,6 +505,7 @@ class ConvertNode : public ShaderNode {
void constant_fold(const ConstantFolder &folder);
+ private:
SocketType::Type from, to;
union {
@@ -472,7 +518,6 @@ class ConvertNode : public ShaderNode {
};
ustring value_string;
- private:
static const int MAX_TYPE = 12;
static bool register_types();
static Node *create(const NodeType *type);
@@ -500,6 +545,7 @@ class BsdfBaseNode : public ShaderNode {
return false;
}
+ protected:
ClosureType closure;
};
@@ -514,18 +560,20 @@ class BsdfNode : public BsdfBaseNode {
ShaderInput *param3 = NULL,
ShaderInput *param4 = NULL);
- float3 color;
- float3 normal;
- float surface_mix_weight;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(float, surface_mix_weight)
};
class AnisotropicBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(AnisotropicBsdfNode)
- float3 tangent;
- float roughness, anisotropy, rotation;
- ClosureType distribution;
+ NODE_SOCKET_API(float3, tangent)
+ NODE_SOCKET_API(float, roughness)
+ NODE_SOCKET_API(float, anisotropy)
+ NODE_SOCKET_API(float, rotation)
+ NODE_SOCKET_API(ClosureType, distribution)
ClosureType get_closure_type()
{
@@ -542,7 +590,7 @@ class DiffuseBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(DiffuseBsdfNode)
- float roughness;
+ NODE_SOCKET_API(float, roughness)
};
/* Disney principled BRDF */
@@ -570,19 +618,37 @@ class PrincipledBsdfNode : public BsdfBaseNode {
ShaderInput *anisotropic_rotation,
ShaderInput *transmission_roughness);
- float3 base_color;
- float3 subsurface_color, subsurface_radius;
- float metallic, subsurface, specular, roughness, specular_tint, anisotropic, sheen, sheen_tint,
- clearcoat, clearcoat_roughness, ior, transmission, anisotropic_rotation,
- transmission_roughness;
- float3 normal, clearcoat_normal, tangent;
- float surface_mix_weight;
- ClosureType distribution, distribution_orig;
- ClosureType subsurface_method;
- float3 emission;
- float emission_strength;
- float alpha;
+ NODE_SOCKET_API(float3, base_color)
+ NODE_SOCKET_API(float3, subsurface_color)
+ NODE_SOCKET_API(float3, subsurface_radius)
+ NODE_SOCKET_API(float, metallic)
+ NODE_SOCKET_API(float, subsurface)
+ NODE_SOCKET_API(float, specular)
+ NODE_SOCKET_API(float, roughness)
+ NODE_SOCKET_API(float, specular_tint)
+ NODE_SOCKET_API(float, anisotropic)
+ NODE_SOCKET_API(float, sheen)
+ NODE_SOCKET_API(float, sheen_tint)
+ NODE_SOCKET_API(float, clearcoat)
+ NODE_SOCKET_API(float, clearcoat_roughness)
+ NODE_SOCKET_API(float, ior)
+ NODE_SOCKET_API(float, transmission)
+ NODE_SOCKET_API(float, anisotropic_rotation)
+ NODE_SOCKET_API(float, transmission_roughness)
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(float3, clearcoat_normal)
+ NODE_SOCKET_API(float3, tangent)
+ NODE_SOCKET_API(float, surface_mix_weight)
+ NODE_SOCKET_API(ClosureType, distribution)
+ NODE_SOCKET_API(ClosureType, subsurface_method)
+ NODE_SOCKET_API(float3, emission)
+ NODE_SOCKET_API(float, emission_strength)
+ NODE_SOCKET_API(float, alpha)
+ private:
+ ClosureType distribution_orig;
+
+ public:
bool has_integrator_dependency();
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
@@ -610,7 +676,7 @@ class VelvetBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(VelvetBsdfNode)
- float sigma;
+ NODE_SOCKET_API(float, sigma)
};
class GlossyBsdfNode : public BsdfNode {
@@ -624,8 +690,12 @@ class GlossyBsdfNode : public BsdfNode {
return distribution;
}
- float roughness, roughness_orig;
- ClosureType distribution, distribution_orig;
+ NODE_SOCKET_API(float, roughness)
+ NODE_SOCKET_API(ClosureType, distribution)
+
+ private:
+ float roughness_orig;
+ ClosureType distribution_orig;
};
class GlassBsdfNode : public BsdfNode {
@@ -639,8 +709,13 @@ class GlassBsdfNode : public BsdfNode {
return distribution;
}
- float roughness, roughness_orig, IOR;
- ClosureType distribution, distribution_orig;
+ NODE_SOCKET_API(float, roughness)
+ NODE_SOCKET_API(float, IOR)
+ NODE_SOCKET_API(ClosureType, distribution)
+
+ private:
+ float roughness_orig;
+ ClosureType distribution_orig;
};
class RefractionBsdfNode : public BsdfNode {
@@ -654,16 +729,22 @@ class RefractionBsdfNode : public BsdfNode {
return distribution;
}
- float roughness, roughness_orig, IOR;
- ClosureType distribution, distribution_orig;
+ NODE_SOCKET_API(float, roughness)
+ NODE_SOCKET_API(float, IOR)
+ NODE_SOCKET_API(ClosureType, distribution)
+
+ private:
+ float roughness_orig;
+ ClosureType distribution_orig;
};
class ToonBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(ToonBsdfNode)
- float smooth, size;
- ClosureType component;
+ NODE_SOCKET_API(float, smooth)
+ NODE_SOCKET_API(float, size)
+ NODE_SOCKET_API(ClosureType, component)
};
class SubsurfaceScatteringNode : public BsdfNode {
@@ -679,11 +760,11 @@ class SubsurfaceScatteringNode : public BsdfNode {
return falloff;
}
- float scale;
- float3 radius;
- float sharpness;
- float texture_blur;
- ClosureType falloff;
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float3, radius)
+ NODE_SOCKET_API(float, sharpness)
+ NODE_SOCKET_API(float, texture_blur)
+ NODE_SOCKET_API(ClosureType, falloff)
};
class EmissionNode : public ShaderNode {
@@ -700,9 +781,9 @@ class EmissionNode : public ShaderNode {
return true;
}
- float3 color;
- float strength;
- float surface_mix_weight;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float, strength)
+ NODE_SOCKET_API(float, surface_mix_weight)
};
class BackgroundNode : public ShaderNode {
@@ -710,9 +791,9 @@ class BackgroundNode : public ShaderNode {
SHADER_NODE_CLASS(BackgroundNode)
void constant_fold(const ConstantFolder &folder);
- float3 color;
- float strength;
- float surface_mix_weight;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float, strength)
+ NODE_SOCKET_API(float, surface_mix_weight)
};
class HoldoutNode : public ShaderNode {
@@ -727,8 +808,8 @@ class HoldoutNode : public ShaderNode {
return CLOSURE_HOLDOUT_ID;
}
- float surface_mix_weight;
- float volume_mix_weight;
+ NODE_SOCKET_API(float, surface_mix_weight)
+ NODE_SOCKET_API(float, volume_mix_weight)
};
class AmbientOcclusionNode : public ShaderNode {
@@ -748,13 +829,13 @@ class AmbientOcclusionNode : public ShaderNode {
return true;
}
- float3 color;
- float distance;
- float3 normal;
- int samples;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float, distance)
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(int, samples)
- bool only_local;
- bool inside;
+ NODE_SOCKET_API(bool, only_local)
+ NODE_SOCKET_API(bool, inside)
};
class VolumeNode : public ShaderNode {
@@ -780,11 +861,14 @@ class VolumeNode : public ShaderNode {
return true;
}
- float3 color;
- float density;
- float volume_mix_weight;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float, density)
+ NODE_SOCKET_API(float, volume_mix_weight)
+
+ protected:
ClosureType closure;
+ public:
virtual bool equals(const ShaderNode & /*other*/)
{
/* TODO(sergey): With some care Volume nodes can be de-duplicated. */
@@ -801,7 +885,7 @@ class ScatterVolumeNode : public VolumeNode {
public:
SHADER_NODE_CLASS(ScatterVolumeNode)
- float anisotropy;
+ NODE_SOCKET_API(float, anisotropy)
};
class PrincipledVolumeNode : public VolumeNode {
@@ -813,17 +897,17 @@ class PrincipledVolumeNode : public VolumeNode {
return true;
}
- ustring density_attribute;
- ustring color_attribute;
- ustring temperature_attribute;
+ NODE_SOCKET_API(ustring, density_attribute)
+ NODE_SOCKET_API(ustring, color_attribute)
+ NODE_SOCKET_API(ustring, temperature_attribute)
- float anisotropy;
- float3 absorption_color;
- float emission_strength;
- float3 emission_color;
- float blackbody_intensity;
- float3 blackbody_tint;
- float temperature;
+ NODE_SOCKET_API(float, anisotropy)
+ NODE_SOCKET_API(float3, absorption_color)
+ NODE_SOCKET_API(float, emission_strength)
+ NODE_SOCKET_API(float3, emission_color)
+ NODE_SOCKET_API(float, blackbody_intensity)
+ NODE_SOCKET_API(float3, blackbody_tint)
+ NODE_SOCKET_API(float, temperature)
};
/* Interface between the I/O sockets and the SVM/OSL backend. */
@@ -833,36 +917,36 @@ class PrincipledHairBsdfNode : public BsdfBaseNode {
void attributes(Shader *shader, AttributeRequestSet *attributes);
/* Longitudinal roughness. */
- float roughness;
+ NODE_SOCKET_API(float, roughness)
/* Azimuthal roughness. */
- float radial_roughness;
+ NODE_SOCKET_API(float, radial_roughness)
/* Randomization factor for roughnesses. */
- float random_roughness;
+ NODE_SOCKET_API(float, random_roughness)
/* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */
- float coat;
+ NODE_SOCKET_API(float, coat)
/* Index of reflection. */
- float ior;
+ NODE_SOCKET_API(float, ior)
/* Cuticle tilt angle. */
- float offset;
+ NODE_SOCKET_API(float, offset)
/* Direct coloring's color. */
- float3 color;
+ NODE_SOCKET_API(float3, color)
/* Melanin concentration. */
- float melanin;
+ NODE_SOCKET_API(float, melanin)
/* Melanin redness ratio. */
- float melanin_redness;
+ NODE_SOCKET_API(float, melanin_redness)
/* Dye color. */
- float3 tint;
+ NODE_SOCKET_API(float3, tint)
/* Randomization factor for melanin quantities. */
- float random_color;
+ NODE_SOCKET_API(float, random_color)
/* Absorption coefficient (unfiltered). */
- float3 absorption_coefficient;
+ NODE_SOCKET_API(float3, absorption_coefficient)
- float3 normal;
- float surface_mix_weight;
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(float, surface_mix_weight)
/* If linked, here will be the given random number. */
- float random;
+ NODE_SOCKET_API(float, random)
/* Selected coloring parametrization. */
- NodePrincipledHairParametrization parametrization;
+ NODE_SOCKET_API(NodePrincipledHairParametrization, parametrization)
};
class HairBsdfNode : public BsdfNode {
@@ -873,11 +957,11 @@ class HairBsdfNode : public BsdfNode {
return component;
}
- ClosureType component;
- float offset;
- float roughness_u;
- float roughness_v;
- float3 tangent;
+ NODE_SOCKET_API(ClosureType, component)
+ NODE_SOCKET_API(float, offset)
+ NODE_SOCKET_API(float, roughness_u)
+ NODE_SOCKET_API(float, roughness_v)
+ NODE_SOCKET_API(float3, tangent)
};
class GeometryNode : public ShaderNode {
@@ -894,7 +978,7 @@ class GeometryNode : public ShaderNode {
}
int get_group();
- float3 normal_osl;
+ NODE_SOCKET_API(float3, normal_osl)
};
class TextureCoordinateNode : public ShaderNode {
@@ -910,10 +994,10 @@ class TextureCoordinateNode : public ShaderNode {
return true;
}
- float3 normal_osl;
- bool from_dupli;
- bool use_transform;
- Transform ob_tfm;
+ NODE_SOCKET_API(float3, normal_osl)
+ NODE_SOCKET_API(bool, from_dupli)
+ NODE_SOCKET_API(bool, use_transform)
+ NODE_SOCKET_API(Transform, ob_tfm)
};
class UVMapNode : public ShaderNode {
@@ -933,8 +1017,8 @@ class UVMapNode : public ShaderNode {
return NODE_GROUP_LEVEL_1;
}
- ustring attribute;
- bool from_dupli;
+ NODE_SOCKET_API(ustring, attribute)
+ NODE_SOCKET_API(bool, from_dupli)
};
class LightPathNode : public ShaderNode {
@@ -958,8 +1042,8 @@ class LightFalloffNode : public ShaderNode {
return NODE_GROUP_LEVEL_2;
}
- float strength;
- float smooth;
+ NODE_SOCKET_API(float, strength)
+ NODE_SOCKET_API(float, smooth)
};
class ObjectInfoNode : public ShaderNode {
@@ -1036,7 +1120,7 @@ class VertexColorNode : public ShaderNode {
return true;
}
- ustring layer_name;
+ NODE_SOCKET_API(ustring, layer_name)
};
class ValueNode : public ShaderNode {
@@ -1045,7 +1129,7 @@ class ValueNode : public ShaderNode {
void constant_fold(const ConstantFolder &folder);
- float value;
+ NODE_SOCKET_API(float, value)
};
class ColorNode : public ShaderNode {
@@ -1054,7 +1138,7 @@ class ColorNode : public ShaderNode {
void constant_fold(const ConstantFolder &folder);
- float3 value;
+ NODE_SOCKET_API(float3, value)
};
class AddClosureNode : public ShaderNode {
@@ -1068,15 +1152,15 @@ class MixClosureNode : public ShaderNode {
SHADER_NODE_CLASS(MixClosureNode)
void constant_fold(const ConstantFolder &folder);
- float fac;
+ NODE_SOCKET_API(float, fac)
};
class MixClosureWeightNode : public ShaderNode {
public:
SHADER_NODE_CLASS(MixClosureWeightNode)
- float weight;
- float fac;
+ NODE_SOCKET_API(float, weight)
+ NODE_SOCKET_API(float, fac)
};
class InvertNode : public ShaderNode {
@@ -1088,8 +1172,8 @@ class InvertNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float fac;
- float3 color;
+ NODE_SOCKET_API(float, fac)
+ NODE_SOCKET_API(float3, color)
};
class MixNode : public ShaderNode {
@@ -1102,11 +1186,11 @@ class MixNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- NodeMix type;
- bool use_clamp;
- float3 color1;
- float3 color2;
- float fac;
+ NODE_SOCKET_API(NodeMix, mix_type)
+ NODE_SOCKET_API(bool, use_clamp)
+ NODE_SOCKET_API(float3, color1)
+ NODE_SOCKET_API(float3, color2)
+ NODE_SOCKET_API(float, fac)
};
class CombineRGBNode : public ShaderNode {
@@ -1118,7 +1202,9 @@ class CombineRGBNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float r, g, b;
+ NODE_SOCKET_API(float, r)
+ NODE_SOCKET_API(float, g)
+ NODE_SOCKET_API(float, b)
};
class CombineHSVNode : public ShaderNode {
@@ -1130,7 +1216,9 @@ class CombineHSVNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float h, s, v;
+ NODE_SOCKET_API(float, h)
+ NODE_SOCKET_API(float, s)
+ NODE_SOCKET_API(float, v)
};
class CombineXYZNode : public ShaderNode {
@@ -1142,7 +1230,9 @@ class CombineXYZNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float x, y, z;
+ NODE_SOCKET_API(float, x)
+ NODE_SOCKET_API(float, y)
+ NODE_SOCKET_API(float, z)
};
class GammaNode : public ShaderNode {
@@ -1154,8 +1244,8 @@ class GammaNode : public ShaderNode {
return NODE_GROUP_LEVEL_1;
}
- float3 color;
- float gamma;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float, gamma)
};
class BrightContrastNode : public ShaderNode {
@@ -1167,9 +1257,9 @@ class BrightContrastNode : public ShaderNode {
return NODE_GROUP_LEVEL_1;
}
- float3 color;
- float bright;
- float contrast;
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float, bright)
+ NODE_SOCKET_API(float, contrast)
};
class SeparateRGBNode : public ShaderNode {
@@ -1181,7 +1271,7 @@ class SeparateRGBNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float3 color;
+ NODE_SOCKET_API(float3, color)
};
class SeparateHSVNode : public ShaderNode {
@@ -1193,7 +1283,7 @@ class SeparateHSVNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float3 color;
+ NODE_SOCKET_API(float3, color)
};
class SeparateXYZNode : public ShaderNode {
@@ -1205,18 +1295,18 @@ class SeparateXYZNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float3 vector;
+ NODE_SOCKET_API(float3, vector)
};
class HSVNode : public ShaderNode {
public:
SHADER_NODE_CLASS(HSVNode)
- float hue;
- float saturation;
- float value;
- float fac;
- float3 color;
+ NODE_SOCKET_API(float, hue)
+ NODE_SOCKET_API(float, saturation)
+ NODE_SOCKET_API(float, value)
+ NODE_SOCKET_API(float, fac)
+ NODE_SOCKET_API(float3, color)
};
class AttributeNode : public ShaderNode {
@@ -1232,7 +1322,7 @@ class AttributeNode : public ShaderNode {
return true;
}
- ustring attribute;
+ NODE_SOCKET_API(ustring, attribute)
};
class CameraNode : public ShaderNode {
@@ -1260,8 +1350,8 @@ class FresnelNode : public ShaderNode {
return NODE_GROUP_LEVEL_1;
}
- float3 normal;
- float IOR;
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(float, IOR)
};
class LayerWeightNode : public ShaderNode {
@@ -1276,8 +1366,8 @@ class LayerWeightNode : public ShaderNode {
return NODE_GROUP_LEVEL_1;
}
- float3 normal;
- float blend;
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(float, blend)
};
class WireframeNode : public ShaderNode {
@@ -1292,8 +1382,8 @@ class WireframeNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float size;
- bool use_pixel_size;
+ NODE_SOCKET_API(float, size)
+ NODE_SOCKET_API(bool, use_pixel_size)
};
class WavelengthNode : public ShaderNode {
@@ -1304,7 +1394,7 @@ class WavelengthNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float wavelength;
+ NODE_SOCKET_API(float, wavelength)
};
class BlackbodyNode : public ShaderNode {
@@ -1316,7 +1406,7 @@ class BlackbodyNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- float temperature;
+ NODE_SOCKET_API(float, temperature)
};
class MapRangeNode : public ShaderNode {
@@ -1328,9 +1418,14 @@ class MapRangeNode : public ShaderNode {
}
void expand(ShaderGraph *graph);
- float value, from_min, from_max, to_min, to_max, steps;
- NodeMapRangeType type;
- bool clamp;
+ NODE_SOCKET_API(float, value)
+ NODE_SOCKET_API(float, from_min)
+ NODE_SOCKET_API(float, from_max)
+ NODE_SOCKET_API(float, to_min)
+ NODE_SOCKET_API(float, to_max)
+ NODE_SOCKET_API(float, steps)
+ NODE_SOCKET_API(NodeMapRangeType, range_type)
+ NODE_SOCKET_API(bool, clamp)
};
class ClampNode : public ShaderNode {
@@ -1341,8 +1436,10 @@ class ClampNode : public ShaderNode {
{
return NODE_GROUP_LEVEL_3;
}
- float value, min, max;
- NodeClampType type;
+ NODE_SOCKET_API(float, value)
+ NODE_SOCKET_API(float, min)
+ NODE_SOCKET_API(float, max)
+ NODE_SOCKET_API(NodeClampType, clamp_type)
};
class MathNode : public ShaderNode {
@@ -1355,11 +1452,11 @@ class MathNode : public ShaderNode {
void expand(ShaderGraph *graph);
void constant_fold(const ConstantFolder &folder);
- float value1;
- float value2;
- float value3;
- NodeMathType type;
- bool use_clamp;
+ NODE_SOCKET_API(float, value1)
+ NODE_SOCKET_API(float, value2)
+ NODE_SOCKET_API(float, value3)
+ NODE_SOCKET_API(NodeMathType, math_type)
+ NODE_SOCKET_API(bool, use_clamp)
};
class NormalNode : public ShaderNode {
@@ -1370,8 +1467,8 @@ class NormalNode : public ShaderNode {
return NODE_GROUP_LEVEL_2;
}
- float3 direction;
- float3 normal;
+ NODE_SOCKET_API(float3, direction)
+ NODE_SOCKET_API(float3, normal)
};
class VectorMathNode : public ShaderNode {
@@ -1383,11 +1480,11 @@ class VectorMathNode : public ShaderNode {
}
void constant_fold(const ConstantFolder &folder);
- float3 vector1;
- float3 vector2;
- float3 vector3;
- float scale;
- NodeVectorMathType type;
+ NODE_SOCKET_API(float3, vector1)
+ NODE_SOCKET_API(float3, vector2)
+ NODE_SOCKET_API(float3, vector3)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(NodeVectorMathType, math_type)
};
class VectorRotateNode : public ShaderNode {
@@ -1398,13 +1495,13 @@ class VectorRotateNode : public ShaderNode {
{
return NODE_GROUP_LEVEL_3;
}
- NodeVectorRotateType type;
- bool invert;
- float3 vector;
- float3 center;
- float3 axis;
- float angle;
- float3 rotation;
+ NODE_SOCKET_API(NodeVectorRotateType, rotate_type)
+ NODE_SOCKET_API(bool, invert)
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float3, center)
+ NODE_SOCKET_API(float3, axis)
+ NODE_SOCKET_API(float, angle)
+ NODE_SOCKET_API(float3, rotation)
};
class VectorTransformNode : public ShaderNode {
@@ -1416,10 +1513,10 @@ class VectorTransformNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- NodeVectorTransformType type;
- NodeVectorTransformConvertSpace convert_from;
- NodeVectorTransformConvertSpace convert_to;
- float3 vector;
+ NODE_SOCKET_API(NodeVectorTransformType, transform_type)
+ NODE_SOCKET_API(NodeVectorTransformConvertSpace, convert_from)
+ NODE_SOCKET_API(NodeVectorTransformConvertSpace, convert_to)
+ NODE_SOCKET_API(float3, vector)
};
class BumpNode : public ShaderNode {
@@ -1435,15 +1532,15 @@ class BumpNode : public ShaderNode {
return NODE_FEATURE_BUMP;
}
- bool invert;
- bool use_object_space;
- float height;
- float sample_center;
- float sample_x;
- float sample_y;
- float3 normal;
- float strength;
- float distance;
+ NODE_SOCKET_API(bool, invert)
+ NODE_SOCKET_API(bool, use_object_space)
+ NODE_SOCKET_API(float, height)
+ NODE_SOCKET_API(float, sample_center)
+ NODE_SOCKET_API(float, sample_x)
+ NODE_SOCKET_API(float, sample_y)
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(float, strength)
+ NODE_SOCKET_API(float, distance)
};
class CurvesNode : public ShaderNode {
@@ -1456,9 +1553,11 @@ class CurvesNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- array<float3> curves;
- float min_x, max_x, fac;
- float3 value;
+ NODE_SOCKET_API(array<float3>, curves)
+ NODE_SOCKET_API(float, min_x)
+ NODE_SOCKET_API(float, max_x)
+ NODE_SOCKET_API(float, fac)
+ NODE_SOCKET_API(float3, value)
protected:
using ShaderNode::constant_fold;
@@ -1488,16 +1587,16 @@ class RGBRampNode : public ShaderNode {
return NODE_GROUP_LEVEL_1;
}
- array<float3> ramp;
- array<float> ramp_alpha;
- float fac;
- bool interpolate;
+ NODE_SOCKET_API(array<float3>, ramp)
+ NODE_SOCKET_API(array<float>, ramp_alpha)
+ NODE_SOCKET_API(float, fac)
+ NODE_SOCKET_API(bool, interpolate)
};
class SetNormalNode : public ShaderNode {
public:
SHADER_NODE_CLASS(SetNormalNode)
- float3 direction;
+ NODE_SOCKET_API(float3, direction)
};
class OSLNode : public ShaderNode {
@@ -1549,11 +1648,11 @@ class NormalMapNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- NodeNormalMapSpace space;
- ustring attribute;
- float strength;
- float3 color;
- float3 normal_osl;
+ NODE_SOCKET_API(NodeNormalMapSpace, space)
+ NODE_SOCKET_API(ustring, attribute)
+ NODE_SOCKET_API(float, strength)
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(float3, normal_osl)
};
class TangentNode : public ShaderNode {
@@ -1573,10 +1672,10 @@ class TangentNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
- NodeTangentDirectionType direction_type;
- NodeTangentAxis axis;
- ustring attribute;
- float3 normal_osl;
+ NODE_SOCKET_API(NodeTangentDirectionType, direction_type)
+ NODE_SOCKET_API(NodeTangentAxis, axis)
+ NODE_SOCKET_API(ustring, attribute)
+ NODE_SOCKET_API(float3, normal_osl)
};
class BevelNode : public ShaderNode {
@@ -1595,9 +1694,9 @@ class BevelNode : public ShaderNode {
return true;
}
- float radius;
- float3 normal;
- int samples;
+ NODE_SOCKET_API(float, radius)
+ NODE_SOCKET_API(float3, normal)
+ NODE_SOCKET_API(int, samples)
};
class DisplacementNode : public ShaderNode {
@@ -1609,11 +1708,11 @@ class DisplacementNode : public ShaderNode {
return NODE_FEATURE_BUMP;
}
- NodeNormalMapSpace space;
- float height;
- float midlevel;
- float scale;
- float3 normal;
+ NODE_SOCKET_API(NodeNormalMapSpace, space)
+ NODE_SOCKET_API(float, height)
+ NODE_SOCKET_API(float, midlevel)
+ NODE_SOCKET_API(float, scale)
+ NODE_SOCKET_API(float3, normal)
};
class VectorDisplacementNode : public ShaderNode {
@@ -1630,11 +1729,11 @@ class VectorDisplacementNode : public ShaderNode {
return NODE_FEATURE_BUMP;
}
- NodeNormalMapSpace space;
- ustring attribute;
- float3 vector;
- float midlevel;
- float scale;
+ NODE_SOCKET_API(NodeNormalMapSpace, space)
+ NODE_SOCKET_API(ustring, attribute)
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float, midlevel)
+ NODE_SOCKET_API(float, scale)
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 96c5fcd4fcb..105e968c265 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -104,9 +104,13 @@ NODE_DEFINE(Object)
SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>());
SOCKET_FLOAT(shadow_terminator_offset, "Terminator Offset", 0.0f);
+ SOCKET_STRING(asset_name, "Asset Name", ustring());
SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
+ SOCKET_NODE(particle_system, "Particle System", &ParticleSystem::node_type);
+ SOCKET_INT(particle_index, "Particle Index", 0);
+
return type;
}
@@ -213,10 +217,11 @@ void Object::tag_update(Scene *scene)
{
if (geometry) {
if (geometry->transform_applied)
- geometry->need_update = true;
+ geometry->tag_modified();
- foreach (Shader *shader, geometry->used_shaders) {
- if (shader->use_mis && shader->has_surface_emission)
+ foreach (Node *node, geometry->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+ if (shader->get_use_mis() && shader->has_surface_emission)
scene->light_manager->need_update = true;
}
}
@@ -273,7 +278,7 @@ uint Object::visibility_for_tracing() const
float Object::compute_volume_step_size() const
{
- if (geometry->type != Geometry::MESH && geometry->type != Geometry::VOLUME) {
+ if (geometry->geometry_type != Geometry::MESH && geometry->geometry_type != Geometry::VOLUME) {
return FLT_MAX;
}
@@ -286,11 +291,12 @@ float Object::compute_volume_step_size() const
/* Compute step rate from shaders. */
float step_rate = FLT_MAX;
- foreach (Shader *shader, mesh->used_shaders) {
+ foreach (Node *node, mesh->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
if (shader->has_volume) {
- if ((shader->heterogeneous_volume && shader->has_volume_spatial_varying) ||
+ if ((shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) ||
(shader->has_volume_attribute_dependency)) {
- step_rate = fminf(shader->volume_step_rate, step_rate);
+ step_rate = fminf(shader->get_volume_step_rate(), step_rate);
}
}
}
@@ -302,7 +308,7 @@ float Object::compute_volume_step_size() const
/* Compute step size from voxel grids. */
float step_size = FLT_MAX;
- if (geometry->type == Geometry::VOLUME) {
+ if (geometry->geometry_type == Geometry::VOLUME) {
Volume *volume = static_cast<Volume *>(geometry);
foreach (Attribute &attr, volume->attributes.attributes) {
@@ -314,7 +320,7 @@ float Object::compute_volume_step_size() const
}
/* User specified step size. */
- float voxel_step_size = volume->step_size;
+ float voxel_step_size = volume->get_step_size();
if (voxel_step_size == 0.0f) {
/* Auto detect step size. */
@@ -328,7 +334,7 @@ float Object::compute_volume_step_size() const
}
voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size)));
}
- else if (volume->object_space) {
+ else if (volume->get_object_space()) {
/* User specified step size in object space. */
float3 size = make_float3(voxel_step_size, voxel_step_size, voxel_step_size);
voxel_step_size = min3(fabs(transform_direction(&tfm, size)));
@@ -372,14 +378,15 @@ static float object_surface_area(UpdateObjectTransformState *state,
const Transform &tfm,
Geometry *geom)
{
- if (geom->type != Geometry::MESH && geom->type != Geometry::VOLUME) {
+ if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) {
return 0.0f;
}
Mesh *mesh = static_cast<Mesh *>(geom);
- if (mesh->has_volume || geom->type == Geometry::VOLUME) {
+ if (mesh->has_volume || geom->geometry_type == Geometry::VOLUME) {
/* Volume density automatically adjust to object scale. */
- if (geom->type == Geometry::VOLUME && static_cast<Volume *>(geom)->object_space) {
+ if (geom->geometry_type == Geometry::VOLUME &&
+ static_cast<Volume *>(geom)->get_object_space()) {
const float3 unit = normalize(make_float3(1.0f, 1.0f, 1.0f));
return 1.0f / len(transform_direction(&tfm, unit));
}
@@ -411,9 +418,9 @@ static float object_surface_area(UpdateObjectTransformState *state,
size_t num_triangles = mesh->num_triangles();
for (size_t j = 0; j < num_triangles; j++) {
Mesh::Triangle t = mesh->get_triangle(j);
- float3 p1 = mesh->verts[t.v[0]];
- float3 p2 = mesh->verts[t.v[1]];
- float3 p3 = mesh->verts[t.v[2]];
+ float3 p1 = mesh->get_verts()[t.v[0]];
+ float3 p2 = mesh->get_verts()[t.v[1]];
+ float3 p3 = mesh->get_verts()[t.v[2]];
surface_area += triangle_area(p1, p2, p3);
}
@@ -432,9 +439,9 @@ static float object_surface_area(UpdateObjectTransformState *state,
size_t num_triangles = mesh->num_triangles();
for (size_t j = 0; j < num_triangles; j++) {
Mesh::Triangle t = mesh->get_triangle(j);
- float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
- float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
- float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
+ float3 p1 = transform_point(&tfm, mesh->get_verts()[t.v[0]]);
+ float3 p2 = transform_point(&tfm, mesh->get_verts()[t.v[1]]);
+ float3 p3 = transform_point(&tfm, mesh->get_verts()[t.v[2]]);
surface_area += triangle_area(p1, p2, p3);
}
@@ -473,11 +480,11 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.particle_index = particle_index;
kobject.motion_offset = 0;
- if (geom->use_motion_blur) {
+ if (geom->get_use_motion_blur()) {
state->have_motion = true;
}
- if (geom->type == Geometry::MESH) {
+ if (geom->geometry_type == Geometry::MESH) {
/* TODO: why only mesh? */
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
@@ -528,14 +535,16 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.dupli_generated[0] = ob->dupli_generated[0];
kobject.dupli_generated[1] = ob->dupli_generated[1];
kobject.dupli_generated[2] = ob->dupli_generated[2];
- kobject.numkeys = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom)->curve_keys.size() :
- 0;
+ kobject.numkeys = (geom->geometry_type == Geometry::HAIR) ?
+ static_cast<Hair *>(geom)->get_curve_keys().size() :
+ 0;
kobject.dupli_uv[0] = ob->dupli_uv[0];
kobject.dupli_uv[1] = ob->dupli_uv[1];
- int totalsteps = geom->motion_steps;
+ int totalsteps = geom->get_motion_steps();
kobject.numsteps = (totalsteps - 1) / 2;
- kobject.numverts = (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) ?
- static_cast<Mesh *>(geom)->verts.size() :
+ kobject.numverts = (geom->geometry_type == Geometry::MESH ||
+ geom->geometry_type == Geometry::VOLUME) ?
+ static_cast<Mesh *>(geom)->get_verts().size() :
0;
kobject.patch_map_offset = 0;
kobject.attribute_map_offset = 0;
@@ -553,7 +562,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
state->object_volume_step[ob->index] = FLT_MAX;
/* Have curves. */
- if (geom->type == Geometry::HAIR) {
+ if (geom->geometry_type == Geometry::HAIR) {
state->have_curves = true;
}
}
@@ -688,6 +697,10 @@ void ObjectManager::device_update(Device *device,
progress.set_status("Updating Objects", "Applying Static Transformations");
apply_static_transforms(dscene, scene, progress);
}
+
+ foreach (Object *object, scene->objects) {
+ object->clear_modified();
+ }
}
void ObjectManager::device_update_flags(
@@ -787,7 +800,7 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc
foreach (Object *object, scene->objects) {
Geometry *geom = object->geometry;
- if (geom->type == Geometry::MESH) {
+ if (geom->geometry_type == Geometry::MESH) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->patch_table) {
uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() -
@@ -865,11 +878,11 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
bool apply = (geometry_users[geom] == 1) && !geom->has_surface_bssrdf &&
!geom->has_true_displacement();
- if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
+ if (geom->geometry_type == Geometry::MESH) {
Mesh *mesh = static_cast<Mesh *>(geom);
- apply = apply && mesh->subdivision_type == Mesh::SUBDIVISION_NONE;
+ apply = apply && mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE;
}
- else if (geom->type == Geometry::HAIR) {
+ else if (geom->geometry_type == Geometry::HAIR) {
/* Can't apply non-uniform scale to curves, this can't be represented by
* control points and radius alone. */
float scale;
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index dfd9790313b..76c9c30abb0 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -18,6 +18,11 @@
#define __OBJECT_H__
#include "graph/node.h"
+
+/* included as Object::set_particle_system defined through NODE_SOCKET_API does
+ * not select the right Node::set overload as it does not know that ParticleSystem
+ * is a Node */
+#include "render/particles.h"
#include "render/scene.h"
#include "util/util_array.h"
@@ -46,26 +51,26 @@ class Object : public Node {
public:
NODE_DECLARE
- Geometry *geometry;
- Transform tfm;
+ NODE_SOCKET_API(Geometry *, geometry)
+ NODE_SOCKET_API(Transform, tfm)
BoundBox bounds;
- uint random_id;
- int pass_id;
- float3 color;
- ustring asset_name;
+ NODE_SOCKET_API(uint, random_id)
+ NODE_SOCKET_API(int, pass_id)
+ NODE_SOCKET_API(float3, color)
+ NODE_SOCKET_API(ustring, asset_name)
vector<ParamValue> attributes;
- uint visibility;
- array<Transform> motion;
- bool hide_on_missing_motion;
- bool use_holdout;
- bool is_shadow_catcher;
- float shadow_terminator_offset;
-
- float3 dupli_generated;
- float2 dupli_uv;
-
- ParticleSystem *particle_system;
- int particle_index;
+ NODE_SOCKET_API(uint, visibility)
+ NODE_SOCKET_API_ARRAY(array<Transform>, motion)
+ NODE_SOCKET_API(bool, hide_on_missing_motion)
+ NODE_SOCKET_API(bool, use_holdout)
+ NODE_SOCKET_API(bool, is_shadow_catcher)
+ NODE_SOCKET_API(float, shadow_terminator_offset)
+
+ NODE_SOCKET_API(float3, dupli_generated)
+ NODE_SOCKET_API(float2, dupli_uv)
+
+ NODE_SOCKET_API(ParticleSystem *, particle_system);
+ NODE_SOCKET_API(int, particle_index);
Object();
~Object();
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 0c2b2cf27e9..bea2c534bd1 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -131,7 +131,7 @@ void OSLShaderManager::device_update(Device *device,
compiler.background = (shader == background_shader);
compiler.compile(og, shader);
- if (shader->use_mis && shader->has_surface_emission)
+ if (shader->get_use_mis() && shader->has_surface_emission)
scene->light_manager->need_update = true;
}
@@ -145,7 +145,7 @@ void OSLShaderManager::device_update(Device *device,
og->use = true;
foreach (Shader *shader, scene->shaders)
- shader->need_update = false;
+ shader->clear_modified();
need_update = false;
@@ -1120,18 +1120,18 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
{
- if (shader->need_update) {
+ if (shader->is_modified()) {
ShaderGraph *graph = shader->graph;
ShaderNode *output = (graph) ? graph->output() : NULL;
- bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
+ bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) &&
output->input("Surface")->link && output->input("Displacement")->link;
/* finalize */
shader->graph->finalize(scene,
has_bump,
shader->has_integrator_dependency,
- shader->displacement_method == DISPLACE_BOTH);
+ shader->get_displacement_method() == DISPLACE_BOTH);
current_shader = shader;
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 3fb6c9620e6..98c256a43b5 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -339,7 +339,7 @@ void Scene::device_update(Device *device_, Progress &progress)
Scene::MotionType Scene::need_motion()
{
- if (integrator->motion_blur)
+ if (integrator->get_motion_blur())
return MOTION_BLUR;
else if (Pass::contains(passes, PASS_MOTION))
return MOTION_PASS;
@@ -352,7 +352,7 @@ float Scene::motion_shutter_time()
if (need_motion() == Scene::MOTION_PASS)
return 2.0f;
else
- return camera->shuttertime;
+ return camera->get_shuttertime();
}
bool Scene::need_global_attribute(AttributeStandard std)
@@ -376,20 +376,21 @@ void Scene::need_global_attributes(AttributeRequestSet &attributes)
bool Scene::need_update()
{
- return (need_reset() || film->need_update);
+ return (need_reset() || film->is_modified());
}
bool Scene::need_data_update()
{
- return (background->need_update || image_manager->need_update || object_manager->need_update ||
+ return (background->is_modified() || image_manager->need_update || object_manager->need_update ||
geometry_manager->need_update || light_manager->need_update ||
- lookup_tables->need_update || integrator->need_update || shader_manager->need_update ||
- particle_system_manager->need_update || bake_manager->need_update || film->need_update);
+ lookup_tables->need_update || integrator->is_modified() || shader_manager->need_update ||
+ particle_system_manager->need_update || bake_manager->need_update ||
+ film->is_modified());
}
bool Scene::need_reset()
{
- return need_data_update() || camera->need_update;
+ return need_data_update() || camera->is_modified();
}
void Scene::reset()
@@ -398,9 +399,9 @@ void Scene::reset()
shader_manager->add_default(this);
/* ensure all objects are updated */
- camera->tag_update();
- dicing_camera->tag_update();
- film->tag_update(this);
+ camera->tag_modified();
+ dicing_camera->tag_modified();
+ film->tag_modified();
background->tag_update(this);
integrator->tag_update(this);
object_manager->tag_update(this);
@@ -442,24 +443,24 @@ DeviceRequestedFeatures Scene::get_requested_device_features()
requested_features.use_object_motion = false;
requested_features.use_camera_motion = use_motion && camera->use_motion();
foreach (Object *object, objects) {
- Geometry *geom = object->geometry;
+ Geometry *geom = object->get_geometry();
if (use_motion) {
- requested_features.use_object_motion |= object->use_motion() | geom->use_motion_blur;
- requested_features.use_camera_motion |= geom->use_motion_blur;
+ requested_features.use_object_motion |= object->use_motion() | geom->get_use_motion_blur();
+ requested_features.use_camera_motion |= geom->get_use_motion_blur();
}
- if (object->is_shadow_catcher) {
+ if (object->get_is_shadow_catcher()) {
requested_features.use_shadow_tricks = true;
}
- if (geom->type == Geometry::MESH) {
+ if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
#ifdef WITH_OPENSUBDIV
- if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
+ if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) {
requested_features.use_patch_evaluation = true;
}
#endif
requested_features.use_true_displacement |= mesh->has_true_displacement();
}
- else if (geom->type == Geometry::HAIR) {
+ else if (geom->is_hair()) {
requested_features.use_hair = true;
}
}
@@ -467,8 +468,9 @@ DeviceRequestedFeatures Scene::get_requested_device_features()
requested_features.use_background_light = light_manager->has_background_light(this);
requested_features.use_baking = bake_manager->get_baking();
- requested_features.use_integrator_branched = (integrator->method == Integrator::BRANCHED_PATH);
- if (film->denoising_data_pass) {
+ requested_features.use_integrator_branched = (integrator->get_method() ==
+ Integrator::BRANCHED_PATH);
+ if (film->get_denoising_data_pass()) {
requested_features.use_denoising = true;
requested_features.use_shadow_tricks = true;
}
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 3e12e183771..a60542259f6 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -1008,23 +1008,19 @@ bool Session::update_scene()
int height = tile_manager.state.buffer.full_height;
int resolution = tile_manager.state.resolution_divider;
- if (width != cam->width || height != cam->height || resolution != cam->resolution) {
- cam->width = width;
- cam->height = height;
- cam->resolution = resolution;
- cam->tag_update();
- }
+ cam->set_screen_size_and_resolution(width, height, resolution);
/* number of samples is needed by multi jittered
* sampling pattern and by baking */
Integrator *integrator = scene->integrator;
BakeManager *bake_manager = scene->bake_manager;
- if (integrator->sampling_pattern != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) {
+ if (integrator->get_sampling_pattern() != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) {
int aa_samples = tile_manager.num_samples;
- if (aa_samples != integrator->aa_samples) {
- integrator->aa_samples = aa_samples;
+ integrator->set_aa_samples(aa_samples);
+
+ if (integrator->is_modified()) {
integrator->tag_update(scene);
}
}
@@ -1118,7 +1114,7 @@ bool Session::render_need_denoise(bool &delayed)
/* Viewport render. */
/* It can happen that denoising was already enabled, but the scene still needs an update. */
- if (scene->film->need_update || !scene->film->denoising_data_offset) {
+ if (scene->film->is_modified() || !scene->film->get_denoising_data_offset()) {
return false;
}
@@ -1163,9 +1159,10 @@ void Session::render(bool need_denoise)
task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2);
task.get_tile_stolen = function_bind(&Session::get_tile_stolen, this);
task.need_finish_queue = params.progressive_refine;
- task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH;
+ task.integrator_branched = scene->integrator->get_method() == Integrator::BRANCHED_PATH;
- task.adaptive_sampling.use = (scene->integrator->sampling_pattern == SAMPLING_PATTERN_PMJ) &&
+ task.adaptive_sampling.use = (scene->integrator->get_sampling_pattern() ==
+ SAMPLING_PATTERN_PMJ) &&
scene->dscene.data.film.pass_adaptive_aux_buffer;
task.adaptive_sampling.min_samples = scene->dscene.data.integrator.adaptive_min_samples;
task.adaptive_sampling.adaptive_step = scene->dscene.data.integrator.adaptive_step;
@@ -1176,10 +1173,10 @@ void Session::render(bool need_denoise)
if (need_denoise) {
task.denoising = params.denoising;
- task.pass_stride = scene->film->pass_stride;
+ task.pass_stride = scene->film->get_pass_stride();
task.target_pass_stride = task.pass_stride;
- task.pass_denoising_data = scene->film->denoising_data_offset;
- task.pass_denoising_clean = scene->film->denoising_clean_offset;
+ task.pass_denoising_data = scene->film->get_denoising_data_offset();
+ task.pass_denoising_clean = scene->film->get_denoising_clean_offset();
task.denoising_from_render = true;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 135d0dc962b..cf49dedc426 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -187,6 +187,8 @@ NODE_DEFINE(Shader)
displacement_method_enum.insert("both", DISPLACE_BOTH);
SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP);
+ SOCKET_INT(pass_id, "Pass ID", 0);
+
return type;
}
@@ -216,7 +218,6 @@ Shader::Shader() : Node(node_type)
id = -1;
used = false;
- need_update = true;
need_update_geometry = true;
}
@@ -250,7 +251,7 @@ bool Shader::is_constant_emission(float3 *emission)
return false;
}
- *emission = node->color * node->strength;
+ *emission = node->get_color() * node->get_strength();
}
else if (surf->link->parent->type == BackgroundNode::node_type) {
BackgroundNode *node = (BackgroundNode *)surf->link->parent;
@@ -262,7 +263,7 @@ bool Shader::is_constant_emission(float3 *emission)
return false;
}
- *emission = node->color * node->strength;
+ *emission = node->get_color() * node->get_strength();
}
else {
return false;
@@ -306,7 +307,7 @@ void Shader::set_graph(ShaderGraph *graph_)
void Shader::tag_update(Scene *scene)
{
/* update tag */
- need_update = true;
+ tag_modified();
scene->shader_manager->need_update = true;
/* if the shader previously was emissive, update light distribution,
@@ -369,7 +370,7 @@ void Shader::tag_used(Scene *scene)
/* if an unused shader suddenly gets used somewhere, it needs to be
* recompiled because it was skipped for compilation before */
if (!used) {
- need_update = true;
+ tag_modified();
scene->shader_manager->need_update = true;
}
}
@@ -493,16 +494,18 @@ void ShaderManager::update_shaders_used(Scene *scene)
scene->default_background->used = true;
scene->default_empty->used = true;
- if (scene->background->shader)
- scene->background->shader->used = true;
+ if (scene->background->get_shader())
+ scene->background->get_shader()->used = true;
foreach (Geometry *geom, scene->geometry)
- foreach (Shader *shader, geom->used_shaders)
+ foreach (Node *node, geom->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
shader->used = true;
+ }
foreach (Light *light, scene->lights)
- if (light->shader)
- light->shader->used = true;
+ if (light->get_shader())
+ const_cast<Shader *>(light->get_shader())->used = true;
}
void ShaderManager::device_update_common(Device *device,
@@ -522,9 +525,9 @@ void ShaderManager::device_update_common(Device *device,
foreach (Shader *shader, scene->shaders) {
uint flag = 0;
- if (shader->use_mis)
+ if (shader->get_use_mis())
flag |= SD_USE_MIS;
- if (shader->has_surface_transparent && shader->use_transparent_shadow)
+ if (shader->has_surface_transparent && shader->get_use_transparent_shadow())
flag |= SD_HAS_TRANSPARENT_SHADOW;
if (shader->has_volume) {
flag |= SD_HAS_VOLUME;
@@ -539,7 +542,7 @@ void ShaderManager::device_update_common(Device *device,
if (shader->has_volume_connected && !shader->has_surface)
flag |= SD_HAS_ONLY_VOLUME;
if (shader->has_volume) {
- if (shader->heterogeneous_volume && shader->has_volume_spatial_varying)
+ if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying)
flag |= SD_HETEROGENEOUS_VOLUME;
}
if (shader->has_volume_attribute_dependency)
@@ -547,16 +550,16 @@ void ShaderManager::device_update_common(Device *device,
if (shader->has_bssrdf_bump)
flag |= SD_HAS_BSSRDF_BUMP;
if (device->info.has_volume_decoupled) {
- if (shader->volume_sampling_method == VOLUME_SAMPLING_EQUIANGULAR)
+ if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR)
flag |= SD_VOLUME_EQUIANGULAR;
- if (shader->volume_sampling_method == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
+ if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
flag |= SD_VOLUME_MIS;
}
- if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC)
+ if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC)
flag |= SD_VOLUME_CUBIC;
if (shader->has_bump)
flag |= SD_HAS_BUMP;
- if (shader->displacement_method != DISPLACE_BUMP)
+ if (shader->get_displacement_method() != DISPLACE_BUMP)
flag |= SD_HAS_DISPLACEMENT;
/* constant emission check */
@@ -568,7 +571,7 @@ void ShaderManager::device_update_common(Device *device,
/* regular shader */
kshader->flags = flag;
- kshader->pass_id = shader->pass_id;
+ kshader->pass_id = shader->get_pass_id();
kshader->constant_emission[0] = constant_emission.x;
kshader->constant_emission[1] = constant_emission.y;
kshader->constant_emission[2] = constant_emission.z;
@@ -625,7 +628,7 @@ void ShaderManager::add_default(Scene *scene)
ShaderGraph *graph = new ShaderGraph();
DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
- diffuse->color = make_float3(0.8f, 0.8f, 0.8f);
+ diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f));
graph->add(diffuse);
graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
@@ -658,8 +661,8 @@ void ShaderManager::add_default(Scene *scene)
ShaderGraph *graph = new ShaderGraph();
EmissionNode *emission = graph->create_node<EmissionNode>();
- emission->color = make_float3(0.8f, 0.8f, 0.8f);
- emission->strength = 0.0f;
+ emission->set_color(make_float3(0.8f, 0.8f, 0.8f));
+ emission->set_strength(0.0f);
graph->add(emission);
graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
@@ -703,10 +706,10 @@ void ShaderManager::get_requested_graph_features(ShaderGraph *graph,
requested_features->nodes_features |= node->get_feature();
if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node);
- if (CLOSURE_IS_VOLUME(bsdf_node->closure)) {
+ if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) {
requested_features->nodes_features |= NODE_FEATURE_VOLUME;
}
- else if (CLOSURE_IS_PRINCIPLED(bsdf_node->closure)) {
+ else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) {
requested_features->use_principled = true;
}
}
@@ -738,7 +741,7 @@ void ShaderManager::get_requested_features(Scene *scene,
ShaderNode *output_node = shader->graph->output();
if (output_node->input("Displacement")->link != NULL) {
requested_features->nodes_features |= NODE_FEATURE_BUMP;
- if (shader->displacement_method == DISPLACE_BOTH) {
+ if (shader->get_displacement_method() == DISPLACE_BOTH) {
requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
requested_features->max_nodes_group = max(requested_features->max_nodes_group,
NODE_GROUP_LEVEL_1);
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 897b0984a7e..de19048d8e1 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -81,22 +81,25 @@ class Shader : public Node {
public:
NODE_DECLARE
- int pass_id;
-
/* shader graph */
ShaderGraph *graph;
+ NODE_SOCKET_API(int, pass_id)
+
/* sampling */
- bool use_mis;
- bool use_transparent_shadow;
- bool heterogeneous_volume;
- VolumeSampling volume_sampling_method;
- int volume_interpolation_method;
- float volume_step_rate;
+ NODE_SOCKET_API(bool, use_mis)
+ NODE_SOCKET_API(bool, use_transparent_shadow)
+ NODE_SOCKET_API(bool, heterogeneous_volume)
+ NODE_SOCKET_API(VolumeSampling, volume_sampling_method)
+ NODE_SOCKET_API(int, volume_interpolation_method)
+ NODE_SOCKET_API(float, volume_step_rate)
+
+ /* displacement */
+ NODE_SOCKET_API(DisplacementMethod, displacement_method)
+
float prev_volume_step_rate;
/* synchronization */
- bool need_update;
bool need_update_geometry;
/* If the shader has only volume components, the surface is assumed to
@@ -122,9 +125,6 @@ class Shader : public Node {
bool has_volume_attribute_dependency;
bool has_integrator_dependency;
- /* displacement */
- DisplacementMethod displacement_method;
-
/* requested mesh attributes */
AttributeRequestSet attributes;
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index d66744d06be..b2bc17aec19 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -123,8 +123,8 @@ void SVMShaderManager::device_update(Device *device,
for (int i = 0; i < num_shaders; i++) {
Shader *shader = scene->shaders[i];
- shader->need_update = false;
- if (shader->use_mis && shader->has_surface_emission) {
+ shader->clear_modified();
+ if (shader->get_use_mis() && shader->has_surface_emission) {
scene->light_manager->need_update = true;
}
@@ -749,7 +749,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
/* for the bump shader we need add a node to store the shader state */
bool need_bump_state = (type == SHADER_TYPE_BUMP) &&
- (shader->displacement_method == DISPLACE_BOTH);
+ (shader->get_displacement_method() == DISPLACE_BOTH);
int bump_state_offset = SVM_STACK_INVALID;
if (need_bump_state) {
bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE);
@@ -840,7 +840,7 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum
const double time_start = time_dt();
- bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
+ bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) &&
output->input("Surface")->link && output->input("Displacement")->link;
/* finalize */
@@ -849,7 +849,7 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum
shader->graph->finalize(scene,
has_bump,
shader->has_integrator_dependency,
- shader->displacement_method == DISPLACE_BOTH);
+ shader->get_displacement_method() == DISPLACE_BOTH);
}
current_shader = shader;
diff --git a/intern/cycles/render/volume.cpp b/intern/cycles/render/volume.cpp
index 6d5e9126955..4d9bf1df5cb 100644
--- a/intern/cycles/render/volume.cpp
+++ b/intern/cycles/render/volume.cpp
@@ -518,20 +518,20 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
if (image_memory->data_elements == 1) {
grid = openvdb_grid_from_device_texture<openvdb::FloatGrid>(
- image_memory, volume->clipping, handle.metadata().transform_3d);
+ image_memory, volume->get_clipping(), handle.metadata().transform_3d);
}
else if (image_memory->data_elements == 3) {
grid = openvdb_grid_from_device_texture<openvdb::Vec3fGrid>(
- image_memory, volume->clipping, handle.metadata().transform_3d);
+ image_memory, volume->get_clipping(), handle.metadata().transform_3d);
}
else if (image_memory->data_elements == 4) {
grid = openvdb_grid_from_device_texture<openvdb::Vec4fGrid>(
- image_memory, volume->clipping, handle.metadata().transform_3d);
+ image_memory, volume->get_clipping(), handle.metadata().transform_3d);
}
}
if (grid) {
- builder.add_grid(grid, do_clipping, volume->clipping);
+ builder.add_grid(grid, do_clipping, volume->get_clipping());
}
}
#endif
@@ -544,17 +544,19 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
Shader *volume_shader = NULL;
int pad_size = 0;
- foreach (Shader *shader, volume->used_shaders) {
+ foreach (Node *node, volume->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+
if (!shader->has_volume) {
continue;
}
volume_shader = shader;
- if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
+ if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_LINEAR) {
pad_size = max(1, pad_size);
}
- else if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
+ else if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) {
pad_size = max(2, pad_size);
}
@@ -582,8 +584,8 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
volume->clear();
volume->reserve_mesh(vertices.size(), indices.size() / 3);
- volume->used_shaders.push_back(volume_shader);
- volume->need_update = true;
+ volume->used_shaders.push_back_slow(volume_shader);
+ volume->tag_modified();
volume->need_update_rebuild = true;
for (size_t i = 0; i < vertices.size(); ++i) {
diff --git a/intern/cycles/render/volume.h b/intern/cycles/render/volume.h
index 21568e8e852..2e9703bf7ed 100644
--- a/intern/cycles/render/volume.h
+++ b/intern/cycles/render/volume.h
@@ -28,9 +28,9 @@ class Volume : public Mesh {
Volume();
- float clipping;
- float step_size;
- bool object_space;
+ NODE_SOCKET_API(float, clipping)
+ NODE_SOCKET_API(float, step_size)
+ NODE_SOCKET_API(bool, object_space)
virtual void clear(bool preserve_shaders = false) override;
};