diff options
Diffstat (limited to 'intern/cycles/render')
35 files changed, 1334 insertions, 953 deletions
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index cdef1036647..37b98909d78 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 455959512fd..910148a9d3b 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; @@ -97,9 +97,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; } @@ -109,9 +111,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; } @@ -159,8 +163,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; } } @@ -186,7 +191,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); @@ -220,7 +225,7 @@ void Geometry::compute_bvh( } } - need_update = false; + clear_modified(); need_update_rebuild = false; } @@ -242,16 +247,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; @@ -308,7 +315,7 @@ void GeometryManager::update_osl_attributes(Device *device, size_t j; for (j = 0; j < scene->geometry.size(); j++) - if (scene->geometry[j] == object->geometry) + if (scene->geometry[j] == object->get_geometry()) break; AttributeRequestSet &attributes = geom_attributes[j]; @@ -433,9 +440,9 @@ void GeometryManager::update_svm_attributes(Device *, index++; - 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()) { attr_map[index].x = id; attr_map[index].y = req.subd_desc.element; attr_map[index].z = as_uint(req.subd_desc.offset); @@ -505,19 +512,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 */ @@ -589,7 +596,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) { @@ -613,7 +620,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; @@ -647,7 +654,8 @@ void GeometryManager::device_update_attributes(Device *device, 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); } } @@ -677,7 +685,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); @@ -725,7 +733,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); @@ -797,7 +805,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; @@ -810,8 +818,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 */ @@ -821,19 +829,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; @@ -855,14 +863,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 */ @@ -872,10 +880,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(); } } @@ -889,7 +897,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); @@ -917,7 +925,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]); @@ -949,7 +957,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], @@ -970,7 +978,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, @@ -993,7 +1001,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); @@ -1120,7 +1128,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; } @@ -1129,7 +1138,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro } } - if (geom->need_update_rebuild && geom->type == Geometry::VOLUME) { + if (geom->need_update_rebuild && geom->geometry_type == Geometry::VOLUME) { /* Create volume meshes if there is voxel data. */ if (!volume_images_updated) { progress.set_status("Updating Meshes Volume Bounds"); @@ -1141,7 +1150,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; @@ -1160,9 +1169,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) { @@ -1196,7 +1206,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; } @@ -1245,12 +1255,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. */ @@ -1262,8 +1274,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++; } @@ -1288,17 +1299,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); @@ -1375,8 +1387,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; @@ -1418,7 +1430,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 bcadb3a8051..1a374c57463 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; /* Constructor/Destructor */ @@ -138,6 +137,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); }; @@ -200,6 +209,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 816c15cf4ef..ff337b08810 100644 --- a/intern/cycles/render/hair.cpp +++ b/intern/cycles/render/hair.cpp @@ -474,8 +474,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 39d6a34d799..0479eabb4ef 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 ¶ms, - 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 ¶ms); ImageHandle add_image(const string &filename, const ImageParams ¶ms, - const vector<int> &tiles); + const array<int> &tiles); ImageHandle add_image(ImageLoader *loader, const ImageParams ¶ms, 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 3015ac5e569..fea9a99cfa7 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_voxel_data) { Geometry::clear(); @@ -226,12 +290,18 @@ void Mesh::clear(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_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() 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 c8286a01e2c..b8107085006 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,23 @@ 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 Object; + friend class ObjectManager; + + SubdParams *subd_params = nullptr; public: /* Functions */ @@ -174,12 +205,14 @@ 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_voxel_data); void clear() 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 +235,25 @@ class Mesh : public Geometry { void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset); 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; + } }; CCL_NAMESPACE_END 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 fc525e06d1e..546206f593b 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! */ @@ -4479,7 +4485,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")); } @@ -4487,7 +4493,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")); } @@ -4495,7 +4501,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")); } @@ -4503,7 +4509,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")); } @@ -4880,7 +4886,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); @@ -4908,7 +4914,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)); @@ -4926,10 +4932,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); } } @@ -5748,7 +5754,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); @@ -5772,7 +5778,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")); @@ -5780,13 +5786,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); } } } @@ -5815,7 +5821,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), @@ -5839,7 +5845,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); @@ -5857,7 +5863,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 { @@ -5880,7 +5886,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)); } @@ -5990,7 +5996,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); @@ -6013,9 +6019,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")); @@ -6026,10 +6032,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); } } @@ -6047,7 +6053,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); } @@ -6093,7 +6099,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)); @@ -6116,7 +6122,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); } @@ -6125,7 +6131,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder) } } else { - folder.fold_vector_math(type); + folder.fold_vector_math(math_type); } } @@ -6144,12 +6150,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); @@ -6157,7 +6163,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)); } @@ -6181,7 +6187,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); @@ -6208,14 +6214,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) @@ -6235,7 +6242,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); @@ -6261,7 +6268,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 bce2e08b390..3a314437f0b 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; } @@ -212,10 +216,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; } } @@ -272,7 +277,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; } @@ -285,11 +290,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->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); } } } @@ -301,7 +307,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) { @@ -313,7 +319,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. */ @@ -327,7 +333,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))); @@ -371,14 +377,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)); } @@ -410,9 +417,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); } @@ -431,9 +438,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); } @@ -472,11 +479,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)) { @@ -527,14 +534,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; @@ -552,7 +561,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; } } @@ -687,6 +696,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( @@ -786,7 +799,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() - @@ -857,11 +870,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 ac9b4c331f5..e0d221114de 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 e98b2c76e88..57d66645d18 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 c22e29043d3..7560511f97d 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -918,23 +918,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); } } @@ -1028,7 +1024,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; } @@ -1072,9 +1068,10 @@ void Session::render(bool need_denoise) task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1); task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2); 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; @@ -1085,10 +1082,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 89777d8669b..77a8db7aa9b 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,7 +584,7 @@ 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->used_shaders.push_back_slow(volume_shader); 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 05157eb948f..56197ba9859 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() override; }; |