diff options
Diffstat (limited to 'intern/cycles')
61 files changed, 2388 insertions, 1782 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index e1ab3b3fbc1..c1da9f1983f 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -388,18 +388,19 @@ static void blender_camera_sync(Camera *cam, const char *viewname, PointerRNA *cscene) { - /* copy camera to compare later */ - Camera prevcam = *cam; float aspectratio, sensor_size; /* viewplane */ - blender_camera_viewplane(bcam, width, height, &cam->viewplane, &aspectratio, &sensor_size); + BoundBox2D viewplane; + blender_camera_viewplane(bcam, width, height, &viewplane, &aspectratio, &sensor_size); - cam->width = bcam->full_width; - cam->height = bcam->full_height; + cam->set_viewplane_left(viewplane.left); + cam->set_viewplane_right(viewplane.right); + cam->set_viewplane_top(viewplane.top); + cam->set_viewplane_bottom(viewplane.bottom); - cam->full_width = width; - cam->full_height = height; + cam->set_full_width(width); + cam->set_full_height(height); /* panorama sensor */ if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) { @@ -422,85 +423,91 @@ static void blender_camera_sync(Camera *cam, } if (horizontal_fit) { - cam->sensorwidth = sensor_size; - cam->sensorheight = sensor_size * fit_yratio / fit_xratio; + cam->set_sensorwidth(sensor_size); + cam->set_sensorheight(sensor_size * fit_yratio / fit_xratio); } else { - cam->sensorwidth = sensor_size * fit_xratio / fit_yratio; - cam->sensorheight = sensor_size; + cam->set_sensorwidth(sensor_size * fit_xratio / fit_yratio); + cam->set_sensorheight(sensor_size); } } /* clipping distances */ - cam->nearclip = bcam->nearclip; - cam->farclip = bcam->farclip; + cam->set_nearclip(bcam->nearclip); + cam->set_farclip(bcam->farclip); /* type */ - cam->type = bcam->type; + cam->set_camera_type(bcam->type); /* panorama */ - cam->panorama_type = bcam->panorama_type; - cam->fisheye_fov = bcam->fisheye_fov; - cam->fisheye_lens = bcam->fisheye_lens; - cam->latitude_min = bcam->latitude_min; - cam->latitude_max = bcam->latitude_max; + cam->set_panorama_type(bcam->panorama_type); + cam->set_fisheye_fov(bcam->fisheye_fov); + cam->set_fisheye_lens(bcam->fisheye_lens); + cam->set_latitude_min(bcam->latitude_min); + cam->set_latitude_max(bcam->latitude_max); - cam->longitude_min = bcam->longitude_min; - cam->longitude_max = bcam->longitude_max; + cam->set_longitude_min(bcam->longitude_min); + cam->set_longitude_max(bcam->longitude_max); /* panorama stereo */ - cam->interocular_distance = bcam->interocular_distance; - cam->convergence_distance = bcam->convergence_distance; - cam->use_spherical_stereo = bcam->use_spherical_stereo; + cam->set_interocular_distance(bcam->interocular_distance); + cam->set_convergence_distance(bcam->convergence_distance); + cam->set_use_spherical_stereo(bcam->use_spherical_stereo); - if (cam->use_spherical_stereo) { + if (cam->get_use_spherical_stereo()) { if (strcmp(viewname, "left") == 0) - cam->stereo_eye = Camera::STEREO_LEFT; + cam->set_stereo_eye(Camera::STEREO_LEFT); else if (strcmp(viewname, "right") == 0) - cam->stereo_eye = Camera::STEREO_RIGHT; + cam->set_stereo_eye(Camera::STEREO_RIGHT); else - cam->stereo_eye = Camera::STEREO_NONE; + cam->set_stereo_eye(Camera::STEREO_NONE); } - cam->use_pole_merge = bcam->use_pole_merge; - cam->pole_merge_angle_from = bcam->pole_merge_angle_from; - cam->pole_merge_angle_to = bcam->pole_merge_angle_to; + cam->set_use_pole_merge(bcam->use_pole_merge); + cam->set_pole_merge_angle_from(bcam->pole_merge_angle_from); + cam->set_pole_merge_angle_to(bcam->pole_merge_angle_to); /* anamorphic lens bokeh */ - cam->aperture_ratio = bcam->aperture_ratio; + cam->set_aperture_ratio(bcam->aperture_ratio); /* perspective */ - cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio); - cam->focaldistance = bcam->focaldistance; - cam->aperturesize = bcam->aperturesize; - cam->blades = bcam->apertureblades; - cam->bladesrotation = bcam->aperturerotation; + cam->set_fov(2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio)); + cam->set_focaldistance(bcam->focaldistance); + cam->set_aperturesize(bcam->aperturesize); + cam->set_blades(bcam->apertureblades); + cam->set_bladesrotation(bcam->aperturerotation); /* transform */ - cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type); - cam->motion.clear(); - cam->motion.resize(bcam->motion_steps, cam->matrix); - cam->use_perspective_motion = false; - cam->shuttertime = bcam->shuttertime; - cam->fov_pre = cam->fov; - cam->fov_post = cam->fov; - cam->motion_position = bcam->motion_position; + cam->set_matrix(blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type)); - cam->rolling_shutter_type = bcam->rolling_shutter_type; - cam->rolling_shutter_duration = bcam->rolling_shutter_duration; + array<Transform> motion; + motion.resize(bcam->motion_steps, cam->get_matrix()); + cam->set_motion(motion); + cam->set_use_perspective_motion(false); - cam->shutter_curve = bcam->shutter_curve; + cam->set_shuttertime(bcam->shuttertime); + cam->set_fov_pre(cam->get_fov()); + cam->set_fov_post(cam->get_fov()); + cam->set_motion_position(bcam->motion_position); + + cam->set_rolling_shutter_type(bcam->rolling_shutter_type); + cam->set_rolling_shutter_duration(bcam->rolling_shutter_duration); + + cam->set_shutter_curve(bcam->shutter_curve); /* border */ - cam->border = bcam->border; - cam->viewport_camera_border = bcam->viewport_camera_border; + cam->set_border_left(bcam->border.left); + cam->set_border_right(bcam->border.right); + cam->set_border_top(bcam->border.top); + cam->set_border_bottom(bcam->border.bottom); - bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale"); - cam->offscreen_dicing_scale = bcam->offscreen_dicing_scale; + cam->set_viewport_camera_border_left(bcam->viewport_camera_border.left); + cam->set_viewport_camera_border_right(bcam->viewport_camera_border.right); + cam->set_viewport_camera_border_top(bcam->viewport_camera_border.top); + cam->set_viewport_camera_border_bottom(bcam->viewport_camera_border.bottom); - /* set update flag */ - if (cam->modified(prevcam)) - cam->tag_update(); + bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale"); + cam->set_offscreen_dicing_scale(bcam->offscreen_dicing_scale); } /* Sync Render Camera */ @@ -582,22 +589,24 @@ void BlenderSync::sync_camera_motion( Camera *cam = scene->camera; BL::Array<float, 16> b_ob_matrix; - b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix); + b_engine.camera_model_matrix(b_ob, cam->get_use_spherical_stereo(), b_ob_matrix); Transform tfm = get_transform(b_ob_matrix); - tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type); + tfm = blender_camera_matrix(tfm, cam->get_camera_type(), cam->get_panorama_type()); if (motion_time == 0.0f) { /* When motion blur is not centered in frame, cam->matrix gets reset. */ - cam->matrix = tfm; + cam->set_matrix(tfm); } /* Set transform in motion array. */ int motion_step = cam->motion_step(motion_time); if (motion_step >= 0) { - cam->motion[motion_step] = tfm; + array<Transform> motion = cam->get_motion(); + motion[motion_step] = tfm; + cam->set_motion(motion); } - if (cam->type == CAMERA_PERSPECTIVE) { + if (cam->get_camera_type() == CAMERA_PERSPECTIVE) { BlenderCamera bcam; float aspectratio, sensor_size; blender_camera_init(&bcam, b_render); @@ -610,18 +619,18 @@ void BlenderSync::sync_camera_motion( blender_camera_viewplane(&bcam, width, height, NULL, &aspectratio, &sensor_size); /* TODO(sergey): De-duplicate calculation with camera sync. */ float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio); - if (fov != cam->fov) { + if (fov != cam->get_fov()) { VLOG(1) << "Camera " << b_ob.name() << " FOV change detected."; if (motion_time == 0.0f) { - cam->fov = fov; + cam->set_fov(fov); } else if (motion_time == -1.0f) { - cam->fov_pre = fov; - cam->use_perspective_motion = true; + cam->set_fov_pre(fov); + cam->set_use_perspective_motion(true); } else if (motion_time == 1.0f) { - cam->fov_post = fov; - cam->use_perspective_motion = true; + cam->set_fov_post(fov); + cam->set_use_perspective_motion(true); } } } diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 32aa25354c4..b27de2081ae 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -77,7 +77,7 @@ static bool ObtainCacheParticleData( if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) { - int shader = clamp(b_part.material() - 1, 0, hair->used_shaders.size() - 1); + int shader = clamp(b_part.material() - 1, 0, hair->get_used_shaders().size() - 1); int display_step = background ? b_part.render_step() : b_part.display_step(); int totparts = b_psys.particles.length(); int totchild = background ? b_psys.child_particles.length() : @@ -307,7 +307,7 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa VLOG(1) << "Exporting curve segments for mesh " << hair->name; } - hair->reserve_curves(hair->num_curves() + num_curves, hair->curve_keys.size() + num_keys); + hair->reserve_curves(hair->num_curves() + num_curves, hair->get_curve_keys().size() + num_keys); num_keys = 0; num_curves = 0; @@ -350,7 +350,7 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa } /* check allocation */ - if ((hair->curve_keys.size() != num_keys) || (hair->num_curves() != num_curves)) { + if ((hair->get_curve_keys().size() != num_keys) || (hair->num_curves() != num_curves)) { VLOG(1) << "Allocation failed, clearing data"; hair->clear(true); } @@ -402,7 +402,7 @@ static void export_hair_motion_validate_attribute(Hair *hair, bool have_motion) { Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - const int num_keys = hair->curve_keys.size(); + const int num_keys = hair->get_curve_keys().size(); if (num_motion_keys != num_keys || !have_motion) { /* No motion or hair "topology" changed, remove attributes again. */ @@ -423,8 +423,8 @@ static void export_hair_motion_validate_attribute(Hair *hair, float4 *mP = attr_mP->data_float4() + step * num_keys; for (int key = 0; key < num_keys; key++) { - mP[key] = float3_to_float4(hair->curve_keys[key]); - mP[key].w = hair->curve_radius[key]; + mP[key] = float3_to_float4(hair->get_curve_keys()[key]); + mP[key].w = hair->get_curve_radius()[key]; } } } @@ -447,7 +447,7 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int } /* export motion vectors for curve keys */ - size_t numkeys = hair->curve_keys.size(); + size_t numkeys = hair->get_curve_keys().size(); float4 *mP = attr_mP->data_float4() + motion_step * numkeys; bool have_motion = false; int i = 0; @@ -458,24 +458,24 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { /* Curve lengths may not match! Curves can be clipped. */ - int curve_key_end = (num_curves + 1 < (int)hair->curve_first_key.size() ? - hair->curve_first_key[num_curves + 1] : - (int)hair->curve_keys.size()); - const int num_center_curve_keys = curve_key_end - hair->curve_first_key[num_curves]; + int curve_key_end = (num_curves + 1 < (int)hair->get_curve_first_key().size() ? + hair->get_curve_first_key()[num_curves + 1] : + (int)hair->get_curve_keys().size()); + const int num_center_curve_keys = curve_key_end - hair->get_curve_first_key()[num_curves]; const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys; if (!is_num_keys_different) { for (int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { - if (i < hair->curve_keys.size()) { + if (i < hair->get_curve_keys().size()) { mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey); if (!have_motion) { /* unlike mesh coordinates, these tend to be slightly different * between frames due to particle transforms into/out of object * space, so we use an epsilon to detect actual changes */ - float4 curve_key = float3_to_float4(hair->curve_keys[i]); - curve_key.w = hair->curve_radius[i]; + float4 curve_key = float3_to_float4(hair->get_curve_keys()[i]); + curve_key.w = hair->get_curve_radius()[i]; if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f) have_motion = true; } @@ -560,7 +560,7 @@ void BlenderSync::sync_particle_hair( float3 *generated = attr_generated->data_float3(); for (size_t i = 0; i < hair->num_curves(); i++) { - float3 co = hair->curve_keys[hair->get_curve(i).first_key]; + float3 co = hair->get_curve_keys()[hair->get_curve(i).first_key]; generated[i] = co * size - loc; } } @@ -742,7 +742,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st } /* Export motion keys. */ - const int num_keys = hair->curve_keys.size(); + const int num_keys = hair->get_curve_keys().size(); float4 *mP = attr_mP->data_float4() + motion_step * num_keys; bool have_motion = false; int num_motion_keys = 0; @@ -769,8 +769,8 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st if (!have_motion) { /* TODO: use epsilon for comparison? Was needed for particles due to * transform, but ideally should not happen anymore. */ - float4 curve_key = float3_to_float4(hair->curve_keys[i]); - curve_key.w = hair->curve_radius[i]; + float4 curve_key = float3_to_float4(hair->get_curve_keys()[i]); + curve_key.w = hair->get_curve_radius()[i]; have_motion = !(mP[i] == curve_key); } } @@ -819,36 +819,46 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair) { - /* Compares curve_keys rather than strands in order to handle quick hair - * adjustments in dynamic BVH - other methods could probably do this better. */ - array<float3> oldcurve_keys; - array<float> oldcurve_radius; - oldcurve_keys.steal_data(hair->curve_keys); - oldcurve_radius.steal_data(hair->curve_radius); - - hair->clear(true); + Hair new_hair; + new_hair.set_used_shaders(hair->get_used_shaders()); if (view_layer.use_hair) { if (b_ob.type() == BL::Object::type_HAIR) { /* Hair object. */ - sync_hair(hair, b_ob, false); + sync_hair(&new_hair, b_ob, false); } else { /* Particle hair. */ - bool need_undeformed = hair->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(hair, b_mesh, b_ob, false); + sync_particle_hair(&new_hair, b_mesh, b_ob, false); free_object_to_mesh(b_data, b_ob, b_mesh); } } } + /* update original sockets */ + + for (const SocketType &socket : new_hair.type->inputs) { + /* Those sockets are updated in sync_object, so do not modify them. */ + if (socket.name == "use_motion_blur" || socket.name == "motion_steps") { + continue; + } + hair->set_value(socket, new_hair, socket); + } + + foreach (Attribute &attr, new_hair.attributes.attributes) { + hair->attributes.attributes.push_back(std::move(attr)); + } + /* tag update */ - const bool rebuild = ((oldcurve_keys != hair->curve_keys) || - (oldcurve_radius != hair->curve_radius)); + + /* Compares curve_keys rather than strands in order to handle quick hair + * adjustments in dynamic BVH - other methods could probably do this better. */ + const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified()); hair->tag_update(scene, rebuild); } diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index c9ac9d1068d..bd2f0731030 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -59,7 +59,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, GeometryKey key(b_key_id.ptr.data, geom_type); /* Find shader indices. */ - vector<Shader *> used_shaders; + array<Node *> used_shaders; BL::Object::material_slots_iterator slot; for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { @@ -76,7 +76,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, if (material_override) find_shader(material_override, used_shaders, default_shader); else - used_shaders.push_back(default_shader); + used_shaders.push_back_slow(default_shader); } /* Ensure we only sync instanced geometry once. */ @@ -114,7 +114,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } /* Test if shaders changed, these can be object level so geometry * does not get tagged for recalc. */ - else if (geom->used_shaders != used_shaders) { + else if (geom->get_used_shaders() != used_shaders) { ; } else { @@ -122,7 +122,8 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, * because the shader needs different geometry attributes. */ bool attribute_recalc = false; - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->need_update_geometry) { attribute_recalc = true; } @@ -139,7 +140,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, geom->name = ustring(b_ob_data.name().c_str()); /* Store the shaders immediately for the object attribute code. */ - geom->used_shaders = used_shaders; + geom->set_used_shaders(used_shaders); auto sync_func = [=]() mutable { if (progress.get_cancel()) @@ -180,7 +181,7 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, TaskPool *task_pool) { /* Ensure we only sync instanced geometry once. */ - Geometry *geom = object->geometry; + Geometry *geom = object->get_geometry(); if (geometry_motion_synced.find(geom) != geometry_motion_synced.end()) return; diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index 6f95821e31e..ff4ecc5a3f9 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -42,7 +42,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, if (!light_map.add_or_update(&light, b_ob, b_parent, key)) { Shader *shader; if (!shader_map.add_or_update(&shader, b_light)) { - if (light->is_portal) + if (light->get_is_portal()) *use_portal = true; return; } @@ -52,16 +52,16 @@ void BlenderSync::sync_light(BL::Object &b_parent, switch (b_light.type()) { case BL::Light::type_POINT: { BL::PointLight b_point_light(b_light); - light->size = b_point_light.shadow_soft_size(); - light->type = LIGHT_POINT; + light->set_size(b_point_light.shadow_soft_size()); + light->set_light_type(LIGHT_POINT); break; } case BL::Light::type_SPOT: { BL::SpotLight b_spot_light(b_light); - light->size = b_spot_light.shadow_soft_size(); - light->type = LIGHT_SPOT; - light->spot_angle = b_spot_light.spot_size(); - light->spot_smooth = b_spot_light.spot_blend(); + light->set_size(b_spot_light.shadow_soft_size()); + light->set_light_type(LIGHT_SPOT); + light->set_spot_angle(b_spot_light.spot_size()); + light->set_spot_smooth(b_spot_light.spot_blend()); break; } /* Hemi were removed from 2.8 */ @@ -72,88 +72,88 @@ void BlenderSync::sync_light(BL::Object &b_parent, // } case BL::Light::type_SUN: { BL::SunLight b_sun_light(b_light); - light->angle = b_sun_light.angle(); - light->type = LIGHT_DISTANT; + light->set_angle(b_sun_light.angle()); + light->set_light_type(LIGHT_DISTANT); break; } case BL::Light::type_AREA: { BL::AreaLight b_area_light(b_light); - light->size = 1.0f; - light->axisu = transform_get_column(&tfm, 0); - light->axisv = transform_get_column(&tfm, 1); - light->sizeu = b_area_light.size(); + light->set_size(1.0f); + light->set_axisu(transform_get_column(&tfm, 0)); + light->set_axisv(transform_get_column(&tfm, 1)); + light->set_sizeu(b_area_light.size()); switch (b_area_light.shape()) { case BL::AreaLight::shape_SQUARE: - light->sizev = light->sizeu; - light->round = false; + light->set_sizev(light->get_sizeu()); + light->set_round(false); break; case BL::AreaLight::shape_RECTANGLE: - light->sizev = b_area_light.size_y(); - light->round = false; + light->set_sizev(b_area_light.size_y()); + light->set_round(false); break; case BL::AreaLight::shape_DISK: - light->sizev = light->sizeu; - light->round = true; + light->set_sizev(light->get_sizeu()); + light->set_round(true); break; case BL::AreaLight::shape_ELLIPSE: - light->sizev = b_area_light.size_y(); - light->round = true; + light->set_sizev(b_area_light.size_y()); + light->set_round(true); break; } - light->type = LIGHT_AREA; + light->set_light_type(LIGHT_AREA); break; } } /* strength */ - light->strength = get_float3(b_light.color()); - light->strength *= BL::PointLight(b_light).energy(); + float3 strength = get_float3(b_light.color()) * BL::PointLight(b_light).energy(); + light->set_strength(strength); /* location and (inverted!) direction */ - light->co = transform_get_column(&tfm, 3); - light->dir = -transform_get_column(&tfm, 2); - light->tfm = tfm; + light->set_co(transform_get_column(&tfm, 3)); + light->set_dir(-transform_get_column(&tfm, 2)); + light->set_tfm(tfm); /* shader */ - vector<Shader *> used_shaders; + array<Node *> used_shaders; find_shader(b_light, used_shaders, scene->default_light); - light->shader = used_shaders[0]; + light->set_shader(static_cast<Shader *>(used_shaders[0])); /* shadow */ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles"); - light->cast_shadow = get_boolean(clight, "cast_shadow"); - light->use_mis = get_boolean(clight, "use_multiple_importance_sampling"); + light->set_cast_shadow(get_boolean(clight, "cast_shadow")); + light->set_use_mis(get_boolean(clight, "use_multiple_importance_sampling")); int samples = get_int(clight, "samples"); if (get_boolean(cscene, "use_square_samples")) - light->samples = samples * samples; + light->set_samples(samples * samples); else - light->samples = samples; + light->set_samples(samples); - light->max_bounces = get_int(clight, "max_bounces"); + light->set_max_bounces(get_int(clight, "max_bounces")); if (b_ob != b_ob_instance) { - light->random_id = random_id; + light->set_random_id(random_id); } else { - light->random_id = hash_uint2(hash_string(b_ob.name().c_str()), 0); + light->set_random_id(hash_uint2(hash_string(b_ob.name().c_str()), 0)); } - if (light->type == LIGHT_AREA) - light->is_portal = get_boolean(clight, "is_portal"); + if (light->get_light_type() == LIGHT_AREA) + light->set_is_portal(get_boolean(clight, "is_portal")); else - light->is_portal = false; + light->set_is_portal(false); - if (light->is_portal) + if (light->get_is_portal()) *use_portal = true; /* visibility */ uint visibility = object_ray_visibility(b_ob); - light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0; - light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0; - light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0; - light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0; + light->set_use_diffuse((visibility & PATH_RAY_DIFFUSE) != 0); + light->set_use_glossy((visibility & PATH_RAY_GLOSSY) != 0); + light->set_use_transmission((visibility & PATH_RAY_TRANSMIT) != 0); + light->set_use_scatter((visibility & PATH_RAY_VOLUME_SCATTER) != 0); /* tag */ light->tag_update(scene); @@ -178,25 +178,25 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { - light->type = LIGHT_BACKGROUND; + light->set_light_type(LIGHT_BACKGROUND); if (sampling_method == SAMPLING_MANUAL) { - light->map_resolution = get_int(cworld, "sample_map_resolution"); + light->set_map_resolution(get_int(cworld, "sample_map_resolution")); } else { - light->map_resolution = 0; + light->set_map_resolution(0); } - light->shader = scene->default_background; - light->use_mis = sample_as_light; - light->max_bounces = get_int(cworld, "max_bounces"); + light->set_shader(scene->default_background); + light->set_use_mis(sample_as_light); + light->set_max_bounces(get_int(cworld, "max_bounces")); /* force enable light again when world is resynced */ - light->is_enabled = true; + light->set_is_enabled(true); int samples = get_int(cworld, "samples"); if (get_boolean(cscene, "use_square_samples")) - light->samples = samples * samples; + light->set_samples(samples * samples); else - light->samples = samples; + light->set_samples(samples); light->tag_update(scene); light_map.set_recalc(b_world); diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 1438bfad2b9..079e087ffb6 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -48,8 +48,8 @@ struct MikkUserData { float *tangent_sign) : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign) { - const AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : - mesh->attributes; + const AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes : + mesh->attributes; Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL); vertex_normal = attr_vN->data_float3(); @@ -85,8 +85,8 @@ struct MikkUserData { static int mikk_get_num_faces(const SMikkTSpaceContext *context) { const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; - if (userdata->mesh->subd_faces.size()) { - return userdata->mesh->subd_faces.size(); + if (userdata->mesh->get_num_subd_faces()) { + return userdata->mesh->get_num_subd_faces(); } else { return userdata->mesh->num_triangles(); @@ -96,9 +96,9 @@ static int mikk_get_num_faces(const SMikkTSpaceContext *context) static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num) { const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; - if (userdata->mesh->subd_faces.size()) { + if (userdata->mesh->get_num_subd_faces()) { const Mesh *mesh = userdata->mesh; - return mesh->subd_faces[face_num].num_corners; + return mesh->get_subd_num_corners()[face_num]; } else { return 3; @@ -107,19 +107,19 @@ static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const i static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num) { - if (mesh->subd_faces.size()) { - const Mesh::SubdFace &face = mesh->subd_faces[face_num]; - return mesh->subd_face_corners[face.start_corner + vert_num]; + if (mesh->get_num_subd_faces()) { + const Mesh::SubdFace &face = mesh->get_subd_face(face_num); + return mesh->get_subd_face_corners()[face.start_corner + vert_num]; } else { - return mesh->triangles[face_num * 3 + vert_num]; + return mesh->get_triangles()[face_num * 3 + vert_num]; } } static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num) { - if (mesh->subd_faces.size()) { - const Mesh::SubdFace &face = mesh->subd_faces[face_num]; + if (mesh->get_num_subd_faces()) { + const Mesh::SubdFace &face = mesh->get_subd_face(face_num); return face.start_corner + vert_num; } else { @@ -135,7 +135,7 @@ static void mikk_get_position(const SMikkTSpaceContext *context, const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; const Mesh *mesh = userdata->mesh; const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num); - const float3 vP = mesh->verts[vertex_index]; + const float3 vP = mesh->get_verts()[vertex_index]; P[0] = vP.x; P[1] = vP.y; P[2] = vP.z; @@ -178,8 +178,8 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; const Mesh *mesh = userdata->mesh; float3 vN; - if (mesh->subd_faces.size()) { - const Mesh::SubdFace &face = mesh->subd_faces[face_num]; + if (mesh->get_num_subd_faces()) { + const Mesh::SubdFace &face = mesh->get_subd_face(face_num); if (face.smooth) { const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num); vN = userdata->vertex_normal[vertex_index]; @@ -189,13 +189,13 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, } } else { - if (mesh->smooth[face_num]) { + if (mesh->get_smooth()[face_num]) { const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num); vN = userdata->vertex_normal[vertex_index]; } else { const Mesh::Triangle tri = mesh->get_triangle(face_num); - vN = tri.compute_normal(&mesh->verts[0]); + vN = tri.compute_normal(&mesh->get_verts()[0]); } } N[0] = vN.x; @@ -222,7 +222,8 @@ static void mikk_compute_tangents( const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render) { /* Create tangent attributes. */ - AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : mesh->attributes; + AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes : + mesh->attributes; Attribute *attr; ustring name; if (layer_name != NULL) { @@ -554,7 +555,7 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b for (int vert_index = 0; vert_index < num_verts; ++vert_index) { sorted_vert_indeices[vert_index] = vert_index; } - VertexAverageComparator compare(mesh->verts); + VertexAverageComparator compare(mesh->get_verts()); sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare); /* This array stores index of the original vertex for the given vertex * index. @@ -562,12 +563,12 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b vector<int> vert_orig_index(num_verts); for (int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) { const int vert_index = sorted_vert_indeices[sorted_vert_index]; - const float3 &vert_co = mesh->verts[vert_index]; + const float3 &vert_co = mesh->get_verts()[vert_index]; bool found = false; for (int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts; ++other_sorted_vert_index) { const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index]; - const float3 &other_vert_co = mesh->verts[other_vert_index]; + const float3 &other_vert_co = mesh->get_verts()[other_vert_index]; /* We are too far away now, we wouldn't have duplicate. */ if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) - (vert_co.x + vert_co.y + vert_co.z) > @@ -732,7 +733,7 @@ static void attr_create_random_per_island(Scene *scene, static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, - const vector<Shader *> &used_shaders, + const array<Node *> &used_shaders, bool subdivision = false, bool subdivide_uvs = true) { @@ -743,7 +744,7 @@ static void create_mesh(Scene *scene, int numcorners = 0; int numngons = 0; bool use_loop_normals = b_mesh.use_auto_smooth() && - (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK); + (mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK); /* If no faces, create empty mesh. */ if (numfaces == 0) { @@ -762,8 +763,11 @@ static void create_mesh(Scene *scene, } /* allocate memory */ + if (subdivision) { + mesh->reserve_subd_faces(numfaces, numngons, numcorners); + } + mesh->reserve_mesh(numverts, numtris); - mesh->reserve_subd_faces(numfaces, numngons, numcorners); /* create vertex coordinates and normals */ BL::Mesh::vertices_iterator v; @@ -875,7 +879,7 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Object &b_ob, BL::Mesh &b_mesh, - const vector<Shader *> &used_shaders, + const array<Node *> &used_shaders, float dicing_rate, int max_subdivisions) { @@ -894,31 +898,21 @@ static void create_subd_mesh(Scene *scene, } } - mesh->subd_creases.resize(num_creases); + mesh->reserve_subd_creases(num_creases); - Mesh::SubdEdgeCrease *crease = mesh->subd_creases.data(); for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { if (e->crease() != 0.0f) { - crease->v[0] = e->vertices()[0]; - crease->v[1] = e->vertices()[1]; - crease->crease = e->crease(); - - crease++; + mesh->add_crease(e->vertices()[0], e->vertices()[1], e->crease()); } } /* set subd params */ - if (!mesh->subd_params) { - mesh->subd_params = new SubdParams(mesh); - } - SubdParams &sdparams = *mesh->subd_params; - PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); + float subd_dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate); - sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate); - sdparams.max_level = max_subdivisions; - - sdparams.objecttoworld = get_transform(b_ob.matrix_world()); + mesh->set_subd_dicing_rate(subd_dicing_rate); + mesh->set_subd_max_level(max_subdivisions); + mesh->set_subd_objecttoworld(get_transform(b_ob.matrix_world())); } /* Sync */ @@ -955,14 +949,14 @@ static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *me return; } - const size_t numverts = mesh->verts.size(); + const size_t numverts = mesh->get_verts().size(); if (b_mesh_cache.vertex_velocities.length() != numverts) { return; } /* Find or add attribute */ - float3 *P = &mesh->verts[0]; + float3 *P = &mesh->get_verts()[0]; Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (!attr_mP) { @@ -996,11 +990,11 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) return; /* If the mesh has modifiers following the fluid domain we can't export motion. */ - if (b_fluid_domain.mesh_vertices.length() != mesh->verts.size()) + if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size()) return; /* Find or add attribute */ - float3 *P = &mesh->verts[0]; + float3 *P = &mesh->get_verts()[0]; Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (!attr_mP) { @@ -1011,7 +1005,7 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) float motion_times[2] = {-1.0f, 1.0f}; for (int step = 0; step < 2; step++) { float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; - float3 *mP = attr_mP->data_float3() + step * mesh->verts.size(); + float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size(); BL::FluidDomainSettings::mesh_vertices_iterator svi; int i = 0; @@ -1025,50 +1019,70 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) { - array<int> oldtriangles; - array<Mesh::SubdFace> oldsubd_faces; - array<int> oldsubd_face_corners; - oldtriangles.steal_data(mesh->triangles); - oldsubd_faces.steal_data(mesh->subd_faces); - oldsubd_face_corners.steal_data(mesh->subd_face_corners); - - mesh->clear(true); - - mesh->subdivision_type = Mesh::SUBDIVISION_NONE; + Mesh new_mesh; + new_mesh.set_used_shaders(mesh->get_used_shaders()); if (view_layer.use_surfaces) { /* Adaptive subdivision setup. Not for baking since that requires * exact mapping to the Blender mesh. */ if (!scene->bake_manager->get_baking()) { - mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental); + new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental)); } /* For some reason, meshes do not need this... */ - bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( - b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type); + b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type()); if (b_mesh) { /* Sync mesh itself. */ - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) - create_subd_mesh( - scene, mesh, b_ob, b_mesh, mesh->used_shaders, dicing_rate, max_subdivisions); + if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE) + create_subd_mesh(scene, + &new_mesh, + b_ob, + b_mesh, + new_mesh.get_used_shaders(), + dicing_rate, + max_subdivisions); else - create_mesh(scene, mesh, b_mesh, mesh->used_shaders, false); + create_mesh(scene, &new_mesh, b_mesh, new_mesh.get_used_shaders(), false); free_object_to_mesh(b_data, b_ob, b_mesh); } } /* cached velocities (e.g. from alembic archive) */ - sync_mesh_cached_velocities(b_ob, scene, mesh); + sync_mesh_cached_velocities(b_ob, scene, &new_mesh); /* mesh fluid motion mantaflow */ - sync_mesh_fluid_motion(b_ob, scene, mesh); + sync_mesh_fluid_motion(b_ob, scene, &new_mesh); + + /* update original sockets */ + + for (const SocketType &socket : new_mesh.type->inputs) { + /* Those sockets are updated in sync_object, so do not modify them. */ + if (socket.name == "use_motion_blur" || socket.name == "motion_steps") { + continue; + } + mesh->set_value(socket, new_mesh, socket); + } + + foreach (Attribute &attr, new_mesh.attributes.attributes) { + mesh->attributes.attributes.push_back(std::move(attr)); + } + + foreach (Attribute &attr, new_mesh.subd_attributes.attributes) { + mesh->subd_attributes.attributes.push_back(std::move(attr)); + } + + mesh->set_num_subd_faces(new_mesh.get_num_subd_faces()); /* tag update */ - bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) || - (oldsubd_face_corners != mesh->subd_face_corners); + bool rebuild = (mesh->triangles_is_modified()) || (mesh->subd_num_corners_is_modified()) || + (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) || + (mesh->subd_ptex_offset_is_modified()) || + (mesh->subd_start_corner_is_modified()) || + (mesh->subd_face_corners_is_modified()); mesh->tag_update(scene, rebuild); } @@ -1091,7 +1105,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, } /* Skip if no vertices were exported. */ - size_t numverts = mesh->verts.size(); + size_t numverts = mesh->get_verts().size(); if (numverts == 0) { return; } @@ -1136,7 +1150,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, if (new_attribute) { /* In case of new attribute, we verify if there really was any motion. */ if (b_mesh.vertices.length() != numverts || - memcmp(mP, &mesh->verts[0], sizeof(float3) * numverts) == 0) { + memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) { /* no motion, remove attributes again */ if (b_mesh.vertices.length() != numverts) { VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name(); @@ -1152,7 +1166,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, VLOG(1) << "Filling deformation motion for object " << b_ob.name(); /* motion, fill up previous steps that we might have skipped because * they had no motion, but we need them anyway now */ - float3 *P = &mesh->verts[0]; + float3 *P = &mesh->get_verts()[0]; float3 *N = (attr_N) ? attr_N->data_float3() : NULL; for (int step = 0; step < motion_step; step++) { memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts); @@ -1165,7 +1179,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, if (b_mesh.vertices.length() != numverts) { VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name() << " at time " << motion_step; - memcpy(mP, &mesh->verts[0], sizeof(float3) * numverts); + memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts); if (mN != NULL) { memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts); } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 5e99759fdac..4a70cbbf41f 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -199,11 +199,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* Set transform at matching motion time step. */ int time_index = object->motion_step(motion_time); if (time_index >= 0) { - object->motion[time_index] = tfm; + array<Transform> motion = object->get_motion(); + motion[time_index] = tfm; + object->set_motion(motion); } /* mesh deformation */ - if (object->geometry) + if (object->get_geometry()) sync_geometry_motion(b_depsgraph, b_ob_instance, object, @@ -225,12 +227,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* b_ob is owned by the iterator and will go out of scope at the end of the block. * b_ob_instance is the original object and will remain valid for deferred geometry * sync. */ - object->geometry = sync_geometry(b_depsgraph, - b_ob_instance, - b_ob_instance, - object_updated, - use_particle_hair, - object_geom_task_pool); + Geometry *geometry = sync_geometry(b_depsgraph, + b_ob_instance, + b_ob_instance, + object_updated, + use_particle_hair, + object_geom_task_pool); + object->set_geometry(geometry); /* special case not tracked by object update flags */ @@ -239,28 +242,18 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, } /* holdout */ - if (use_holdout != object->use_holdout) { - object->use_holdout = use_holdout; + object->set_use_holdout(use_holdout); + if (object->use_holdout_is_modified()) { scene->object_manager->tag_update(scene); - object_updated = true; } - if (visibility != object->visibility) { - object->visibility = visibility; - object_updated = true; - } + object->set_visibility(visibility); bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher"); - if (is_shadow_catcher != object->is_shadow_catcher) { - object->is_shadow_catcher = is_shadow_catcher; - object_updated = true; - } + object->set_is_shadow_catcher(is_shadow_catcher); float shadow_terminator_offset = get_float(cobject, "shadow_terminator_offset"); - if (shadow_terminator_offset != object->shadow_terminator_offset) { - object->shadow_terminator_offset = shadow_terminator_offset; - object_updated = true; - } + object->set_shadow_terminator_offset(shadow_terminator_offset); /* sync the asset name for Cryptomatte */ BL::Object parent = b_ob.parent(); @@ -274,48 +267,49 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, else { parent_name = b_ob.name(); } - if (object->asset_name != parent_name) { - object->asset_name = parent_name; - object_updated = true; - } + object->set_asset_name(parent_name); /* object sync * transform comparison should not be needed, but duplis don't work perfect * in the depsgraph and may not signal changes, so this is a workaround */ - if (object_updated || (object->geometry && object->geometry->need_update) || - tfm != object->tfm) { + if (object->is_modified() || object_updated || + (object->get_geometry() && object->get_geometry()->is_modified()) || + tfm != object->get_tfm()) { object->name = b_ob.name().c_str(); - object->pass_id = b_ob.pass_index(); - object->color = get_float3(b_ob.color()); - object->tfm = tfm; - object->motion.clear(); + object->set_pass_id(b_ob.pass_index()); + object->set_color(get_float3(b_ob.color())); + object->set_tfm(tfm); + array<Transform> motion; + object->set_motion(motion); /* motion blur */ Scene::MotionType need_motion = scene->need_motion(); - if (need_motion != Scene::MOTION_NONE && object->geometry) { - Geometry *geom = object->geometry; - geom->use_motion_blur = false; - geom->motion_steps = 0; + if (need_motion != Scene::MOTION_NONE && object->get_geometry()) { + Geometry *geom = object->get_geometry(); + geom->set_use_motion_blur(false); + geom->set_motion_steps(0); uint motion_steps; if (need_motion == Scene::MOTION_BLUR) { motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS); - geom->motion_steps = motion_steps; + geom->set_motion_steps(motion_steps); if (motion_steps && object_use_deform_motion(b_parent, b_ob)) { - geom->use_motion_blur = true; + geom->set_use_motion_blur(true); } } else { motion_steps = 3; - geom->motion_steps = motion_steps; + geom->set_motion_steps(motion_steps); } - object->motion.clear(); - object->motion.resize(motion_steps, transform_empty()); + motion.resize(motion_steps, transform_empty()); if (motion_steps) { - object->motion[motion_steps / 2] = tfm; + motion[motion_steps / 2] = tfm; + + /* update motion socket before trying to access object->motion_time */ + object->set_motion(motion); for (size_t step = 0; step < motion_steps; step++) { motion_times.insert(object->motion_time(step)); @@ -325,15 +319,15 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* dupli texture coordinates and random_id */ if (is_instance) { - object->dupli_generated = 0.5f * get_float3(b_instance.orco()) - - make_float3(0.5f, 0.5f, 0.5f); - object->dupli_uv = get_float2(b_instance.uv()); - object->random_id = b_instance.random_id(); + object->set_dupli_generated(0.5f * get_float3(b_instance.orco()) - + make_float3(0.5f, 0.5f, 0.5f)); + object->set_dupli_uv(get_float2(b_instance.uv())); + object->set_random_id(b_instance.random_id()); } else { - object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f); - object->dupli_uv = make_float2(0.0f, 0.0f); - object->random_id = hash_uint2(hash_string(object->name.c_str()), 0); + object->set_dupli_generated(make_float3(0.0f, 0.0f, 0.0f)); + object->set_dupli_uv(make_float2(0.0f, 0.0f)); + object->set_random_id(hash_uint2(hash_string(object->name.c_str()), 0)); } object->tag_update(scene); @@ -421,7 +415,7 @@ static float4 lookup_instance_property(BL::DepsgraphObjectInstance &b_instance, bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object) { /* Find which attributes are needed. */ - AttributeRequestSet requests = object->geometry->needed_attributes(); + AttributeRequestSet requests = object->get_geometry()->needed_attributes(); /* Delete attributes that became unnecessary. */ vector<ParamValue> &attributes = object->attributes; @@ -591,20 +585,18 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render, if (b_override) b_cam = b_override; - Camera prevcam = *(scene->camera); - int frame_center = b_scene.frame_current(); float subframe_center = b_scene.frame_subframe(); float frame_center_delta = 0.0f; if (scene->need_motion() != Scene::MOTION_PASS && - scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) { - float shuttertime = scene->camera->shuttertime; - if (scene->camera->motion_position == Camera::MOTION_POSITION_END) { + scene->camera->get_motion_position() != Camera::MOTION_POSITION_CENTER) { + float shuttertime = scene->camera->get_shuttertime(); + if (scene->camera->get_motion_position() == Camera::MOTION_POSITION_END) { frame_center_delta = -shuttertime * 0.5f; } else { - assert(scene->camera->motion_position == Camera::MOTION_POSITION_START); + assert(scene->camera->get_motion_position() == Camera::MOTION_POSITION_START); frame_center_delta = shuttertime * 0.5f; } @@ -665,10 +657,6 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render, python_thread_state_restore(python_thread_state); b_engine.frame_set(frame_center, subframe_center); python_thread_state_save(python_thread_state); - - /* tag camera for motion update */ - if (scene->camera->motion_modified(prevcam)) - scene->camera->tag_update(); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp index bebecb364eb..cb7827b3c4a 100644 --- a/intern/cycles/blender/blender_object_cull.cpp +++ b/intern/cycles/blender/blender_object_cull.cpp @@ -34,10 +34,10 @@ BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene &b_scene) if (b_scene.render().use_simplify()) { PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - use_scene_camera_cull_ = scene->camera->type != CAMERA_PANORAMA && + use_scene_camera_cull_ = scene->camera->get_camera_type() != CAMERA_PANORAMA && !b_scene.render().use_multiview() && get_boolean(cscene, "use_camera_cull"); - use_scene_distance_cull_ = scene->camera->type != CAMERA_PANORAMA && + use_scene_distance_cull_ = scene->camera->get_camera_type() != CAMERA_PANORAMA && !b_scene.render().use_multiview() && get_boolean(cscene, "use_distance_cull"); @@ -123,7 +123,7 @@ bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8]) bool BlenderObjectCulling::test_distance(Scene *scene, float3 bb[8]) { - float3 camera_position = transform_get_column(&scene->camera->matrix, 3); + float3 camera_position = transform_get_column(&scene->camera->get_matrix(), 3); float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index e5eab1ae62b..ca221b229b4 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -36,10 +36,10 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, if (!b_psys) return false; - object->hide_on_missing_motion = true; + object->set_hide_on_missing_motion(true); /* test if we need particle data */ - if (!object->geometry->need_attribute(scene, ATTR_STD_PARTICLE)) + if (!object->get_geometry()->need_attribute(scene, ATTR_STD_PARTICLE)) return false; /* don't handle child particles yet */ @@ -56,7 +56,8 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, bool need_update = particle_system_map.add_or_update(&psys, b_ob, b_instance.object(), key); /* no update needed? */ - if (!need_update && !object->geometry->need_update && !scene->object_manager->need_update) + if (!need_update && !object->get_geometry()->is_modified() && + !scene->object_manager->need_update) return true; /* first time used in this sync loop? clear and tag update */ @@ -80,10 +81,11 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, psys->particles.push_back_slow(pa); - if (object->particle_index != psys->particles.size() - 1) + object->set_particle_system(psys); + object->set_particle_index(psys->particles.size() - 1); + + if (object->particle_index_is_modified()) scene->object_manager->tag_update(scene); - object->particle_system = psys; - object->particle_index = psys->particles.size() - 1; /* return that this object has particle data */ return true; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 7abfc6d81bc..770f4ca51c9 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -442,17 +442,17 @@ void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_ } /* Write cryptomatte metadata. */ - if (scene->film->cryptomatte_passes & CRYPT_OBJECT) { + if (scene->film->get_cryptomatte_passes() & CRYPT_OBJECT) { add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoObject", scene->object_manager->get_cryptomatte_objects(scene)); } - if (scene->film->cryptomatte_passes & CRYPT_MATERIAL) { + if (scene->film->get_cryptomatte_passes() & CRYPT_MATERIAL) { add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoMaterial", scene->shader_manager->get_cryptomatte_materials(scene)); } - if (scene->film->cryptomatte_passes & CRYPT_ASSET) { + if (scene->film->get_cryptomatte_passes() & CRYPT_ASSET) { add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoAsset", scene->object_manager->get_cryptomatte_assets(scene)); @@ -508,9 +508,9 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) /* Set buffer params, using film settings from sync_render_passes. */ buffer_params.passes = passes; - buffer_params.denoising_data_pass = scene->film->denoising_data_pass; - buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass; - buffer_params.denoising_prefiltered_pass = scene->film->denoising_prefiltered_pass; + buffer_params.denoising_data_pass = scene->film->get_denoising_data_pass(); + buffer_params.denoising_clean_pass = scene->film->get_denoising_clean_pass(); + buffer_params.denoising_prefiltered_pass = scene->film->get_denoising_prefiltered_pass(); BL::RenderResult::views_iterator b_view_iter; @@ -547,8 +547,9 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) /* Make sure all views have different noise patterns. - hardcoded value just to make it random */ if (view_index != 0) { - scene->integrator->seed += hash_uint2(scene->integrator->seed, - hash_uint2(view_index * 0xdeadbeef, 0)); + int seed = scene->integrator->get_seed(); + seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0)); + scene->integrator->set_seed(seed); scene->integrator->tag_update(scene); } @@ -720,7 +721,7 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay, if (!buffers->copy_from_device()) return; - float exposure = scene->film->exposure; + float exposure = scene->film->get_exposure(); vector<float> pixels(rtile.w * rtile.h * 4); @@ -837,10 +838,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) session->set_denoising(session_params.denoising); /* Update film if denoising data was enabled or disabled. */ - if (scene->film->denoising_data_pass != buffer_params.denoising_data_pass) { - scene->film->denoising_data_pass = buffer_params.denoising_data_pass; - scene->film->tag_update(scene); - } + scene->film->set_denoising_data_pass(buffer_params.denoising_data_pass); /* reset if needed */ if (scene->need_reset()) { @@ -899,7 +897,7 @@ bool BlenderSession::draw(int w, int h) sync->sync_view(b_v3d, b_rv3d, width, height); - if (scene->camera->need_update) + if (scene->camera->is_modified()) reset = true; session->scene->mutex.unlock(); @@ -1114,8 +1112,11 @@ void BlenderSession::update_resumable_tile_manager(int num_samples) VLOG(1) << "Samples range start is " << range_start_sample << ", " << "number of samples to render is " << range_num_samples; - scene->integrator->start_sample = rounded_range_start_sample; - scene->integrator->tag_update(scene); + scene->integrator->set_start_sample(rounded_range_start_sample); + + if (scene->integrator->is_modified()) { + scene->integrator->tag_update(scene); + } session->tile_manager.range_start_sample = rounded_range_start_sample; session->tile_manager.range_num_samples = rounded_range_num_samples; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 0c1b240c593..ac86cf3345c 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -42,11 +42,11 @@ typedef map<string, ConvertNode *> ProxyMap; /* Find */ -void BlenderSync::find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader) +void BlenderSync::find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader) { Shader *shader = (id) ? shader_map.find(id) : default_shader; - used_shaders.push_back(shader); + used_shaders.push_back_slow(shader); shader->tag_used(scene); } @@ -241,19 +241,19 @@ static void set_default_value(ShaderInput *input, } } -static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping &b_mapping) +static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping) { if (!b_mapping) return; - mapping->translation = get_float3(b_mapping.translation()); - mapping->rotation = get_float3(b_mapping.rotation()); - mapping->scale = get_float3(b_mapping.scale()); - mapping->type = (TextureMapping::Type)b_mapping.vector_type(); + mapping->set_tex_mapping_translation(get_float3(b_mapping.translation())); + mapping->set_tex_mapping_rotation(get_float3(b_mapping.rotation())); + mapping->set_tex_mapping_scale(get_float3(b_mapping.scale())); + mapping->set_tex_mapping_type((TextureMapping::Type)b_mapping.vector_type()); - mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x(); - mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y(); - mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z(); + mapping->set_tex_mapping_x_mapping((TextureMapping::Mapping)b_mapping.mapping_x()); + mapping->set_tex_mapping_y_mapping((TextureMapping::Mapping)b_mapping.mapping_y()); + mapping->set_tex_mapping_z_mapping((TextureMapping::Mapping)b_mapping.mapping_z()); } static ShaderNode *add_node(Scene *scene, @@ -272,34 +272,48 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeRGBCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); RGBCurvesNode *curves = graph->create_node<RGBCurvesNode>(); - curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true); - curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x); + array<float3> curve_mapping_curves; + float min_x, max_x; + curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true); + curvemapping_minmax(mapping, true, &min_x, &max_x); + curves->set_min_x(min_x); + curves->set_max_x(max_x); + curves->set_curves(curve_mapping_curves); node = curves; } if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) { BL::ShaderNodeVectorCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); VectorCurvesNode *curves = graph->create_node<VectorCurvesNode>(); - curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false); - curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x); + array<float3> curve_mapping_curves; + float min_x, max_x; + curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false); + curvemapping_minmax(mapping, false, &min_x, &max_x); + curves->set_min_x(min_x); + curves->set_max_x(max_x); + curves->set_curves(curve_mapping_curves); node = curves; } else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) { RGBRampNode *ramp = graph->create_node<RGBRampNode>(); BL::ShaderNodeValToRGB b_ramp_node(b_node); BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp()); - colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE); - ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT; + array<float3> ramp_values; + array<float> ramp_alpha; + colorramp_to_array(b_color_ramp, ramp_values, ramp_alpha, RAMP_TABLE_SIZE); + ramp->set_ramp(ramp_values); + ramp->set_ramp_alpha(ramp_alpha); + ramp->set_interpolate(b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT); node = ramp; } else if (b_node.is_a(&RNA_ShaderNodeRGB)) { ColorNode *color = graph->create_node<ColorNode>(); - color->value = get_node_output_rgba(b_node, "Color"); + color->set_value(get_node_output_rgba(b_node, "Color")); node = color; } else if (b_node.is_a(&RNA_ShaderNodeValue)) { ValueNode *value = graph->create_node<ValueNode>(); - value->value = get_node_output_value(b_node, "Value"); + value->set_value(get_node_output_value(b_node, "Value")); node = value; } else if (b_node.is_a(&RNA_ShaderNodeCameraData)) { @@ -317,8 +331,8 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) { BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = graph->create_node<MixNode>(); - mix->type = (NodeMix)b_mix_node.blend_type(); - mix->use_clamp = b_mix_node.use_clamp(); + mix->set_mix_type((NodeMix)b_mix_node.blend_type()); + mix->set_use_clamp(b_mix_node.use_clamp()); node = mix; } else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) { @@ -348,43 +362,45 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeMapRange)) { BL::ShaderNodeMapRange b_map_range_node(b_node); MapRangeNode *map_range_node = graph->create_node<MapRangeNode>(); - map_range_node->clamp = b_map_range_node.clamp(); - map_range_node->type = (NodeMapRangeType)b_map_range_node.interpolation_type(); + map_range_node->set_clamp(b_map_range_node.clamp()); + map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type()); node = map_range_node; } else if (b_node.is_a(&RNA_ShaderNodeClamp)) { BL::ShaderNodeClamp b_clamp_node(b_node); ClampNode *clamp_node = graph->create_node<ClampNode>(); - clamp_node->type = (NodeClampType)b_clamp_node.clamp_type(); + clamp_node->set_clamp_type((NodeClampType)b_clamp_node.clamp_type()); node = clamp_node; } else if (b_node.is_a(&RNA_ShaderNodeMath)) { BL::ShaderNodeMath b_math_node(b_node); MathNode *math_node = graph->create_node<MathNode>(); - math_node->type = (NodeMathType)b_math_node.operation(); - math_node->use_clamp = b_math_node.use_clamp(); + math_node->set_math_type((NodeMathType)b_math_node.operation()); + math_node->set_use_clamp(b_math_node.use_clamp()); node = math_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) { BL::ShaderNodeVectorMath b_vector_math_node(b_node); VectorMathNode *vector_math_node = graph->create_node<VectorMathNode>(); - vector_math_node->type = (NodeVectorMathType)b_vector_math_node.operation(); + vector_math_node->set_math_type((NodeVectorMathType)b_vector_math_node.operation()); node = vector_math_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorRotate)) { BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node); VectorRotateNode *vector_rotate_node = graph->create_node<VectorRotateNode>(); - vector_rotate_node->type = (NodeVectorRotateType)b_vector_rotate_node.rotation_type(); - vector_rotate_node->invert = b_vector_rotate_node.invert(); + vector_rotate_node->set_rotate_type( + (NodeVectorRotateType)b_vector_rotate_node.rotation_type()); + vector_rotate_node->set_invert(b_vector_rotate_node.invert()); node = vector_rotate_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = graph->create_node<VectorTransformNode>(); - vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type(); - vtransform->convert_from = (NodeVectorTransformConvertSpace) - b_vector_transform_node.convert_from(); - vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to(); + vtransform->set_transform_type((NodeVectorTransformType)b_vector_transform_node.vector_type()); + vtransform->set_convert_from( + (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from()); + vtransform->set_convert_to( + (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to()); node = vtransform; } else if (b_node.is_a(&RNA_ShaderNodeNormal)) { @@ -392,13 +408,13 @@ static ShaderNode *add_node(Scene *scene, b_node.outputs.begin(out_it); NormalNode *norm = graph->create_node<NormalNode>(); - norm->direction = get_node_output_vector(b_node, "Normal"); + norm->set_direction(get_node_output_vector(b_node, "Normal")); node = norm; } else if (b_node.is_a(&RNA_ShaderNodeMapping)) { BL::ShaderNodeMapping b_mapping_node(b_node); MappingNode *mapping = graph->create_node<MappingNode>(); - mapping->type = (NodeMappingType)b_mapping_node.vector_type(); + mapping->set_mapping_type((NodeMappingType)b_mapping_node.vector_type()); node = mapping; } else if (b_node.is_a(&RNA_ShaderNodeFresnel)) { @@ -416,8 +432,8 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeAttribute)) { BL::ShaderNodeAttribute b_attr_node(b_node); AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = blender_attribute_name_add_type(b_attr_node.attribute_name(), - b_attr_node.attribute_type()); + attr->set_attribute(blender_attribute_name_add_type(b_attr_node.attribute_name(), + b_attr_node.attribute_type())); node = attr; } else if (b_node.is_a(&RNA_ShaderNodeBackground)) { @@ -432,16 +448,16 @@ static ShaderNode *add_node(Scene *scene, switch (b_aniso_node.distribution()) { case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: - aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + aniso->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID); break; case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: - aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; + aniso->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID); break; case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX: - aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; + aniso->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); break; case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: - aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID; + aniso->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); break; } @@ -457,16 +473,16 @@ static ShaderNode *add_node(Scene *scene, switch (b_subsurface_node.falloff()) { case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC: - subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_CUBIC_ID); break; case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN: - subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_GAUSSIAN_ID); break; case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY: - subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_BURLEY_ID); break; case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK: - subsurface->falloff = CLOSURE_BSSRDF_RANDOM_WALK_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_RANDOM_WALK_ID); break; } @@ -478,19 +494,19 @@ static ShaderNode *add_node(Scene *scene, switch (b_glossy_node.distribution()) { case BL::ShaderNodeBsdfGlossy::distribution_SHARP: - glossy->distribution = CLOSURE_BSDF_REFLECTION_ID; + glossy->set_distribution(CLOSURE_BSDF_REFLECTION_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: - glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + glossy->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_GGX: - glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; + glossy->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY: - glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID; + glossy->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX: - glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; + glossy->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); break; } node = glossy; @@ -500,16 +516,16 @@ static ShaderNode *add_node(Scene *scene, GlassBsdfNode *glass = graph->create_node<GlassBsdfNode>(); switch (b_glass_node.distribution()) { case BL::ShaderNodeBsdfGlass::distribution_SHARP: - glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_SHARP_GLASS_ID); break; case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: - glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); break; case BL::ShaderNodeBsdfGlass::distribution_GGX: - glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); break; case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX: - glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); break; } node = glass; @@ -519,13 +535,13 @@ static ShaderNode *add_node(Scene *scene, RefractionBsdfNode *refraction = graph->create_node<RefractionBsdfNode>(); switch (b_refraction_node.distribution()) { case BL::ShaderNodeBsdfRefraction::distribution_SHARP: - refraction->distribution = CLOSURE_BSDF_REFRACTION_ID; + refraction->set_distribution(CLOSURE_BSDF_REFRACTION_ID); break; case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN: - refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; + refraction->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); break; case BL::ShaderNodeBsdfRefraction::distribution_GGX: - refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + refraction->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); break; } node = refraction; @@ -535,10 +551,10 @@ static ShaderNode *add_node(Scene *scene, ToonBsdfNode *toon = graph->create_node<ToonBsdfNode>(); switch (b_toon_node.component()) { case BL::ShaderNodeBsdfToon::component_DIFFUSE: - toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID; + toon->set_component(CLOSURE_BSDF_DIFFUSE_TOON_ID); break; case BL::ShaderNodeBsdfToon::component_GLOSSY: - toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID; + toon->set_component(CLOSURE_BSDF_GLOSSY_TOON_ID); break; } node = toon; @@ -548,10 +564,10 @@ static ShaderNode *add_node(Scene *scene, HairBsdfNode *hair = graph->create_node<HairBsdfNode>(); switch (b_hair_node.component()) { case BL::ShaderNodeBsdfHair::component_Reflection: - hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID; + hair->set_component(CLOSURE_BSDF_HAIR_REFLECTION_ID); break; case BL::ShaderNodeBsdfHair::component_Transmission: - hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID; + hair->set_component(CLOSURE_BSDF_HAIR_TRANSMISSION_ID); break; } node = hair; @@ -559,11 +575,11 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) { BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node); PrincipledHairBsdfNode *principled_hair = graph->create_node<PrincipledHairBsdfNode>(); - principled_hair->parametrization = (NodePrincipledHairParametrization)get_enum( - b_principled_hair_node.ptr, - "parametrization", - NODE_PRINCIPLED_HAIR_NUM, - NODE_PRINCIPLED_HAIR_REFLECTANCE); + principled_hair->set_parametrization( + (NodePrincipledHairParametrization)get_enum(b_principled_hair_node.ptr, + "parametrization", + NODE_PRINCIPLED_HAIR_NUM, + NODE_PRINCIPLED_HAIR_REFLECTANCE)); node = principled_hair; } else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) { @@ -571,18 +587,18 @@ static ShaderNode *add_node(Scene *scene, PrincipledBsdfNode *principled = graph->create_node<PrincipledBsdfNode>(); switch (b_principled_node.distribution()) { case BL::ShaderNodeBsdfPrincipled::distribution_GGX: - principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; + principled->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); break; case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX: - principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; + principled->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); break; } switch (b_principled_node.subsurface_method()) { case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY: - principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID; + principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_ID); break; case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK: - principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID; + principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID); break; } node = principled; @@ -602,9 +618,9 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) { BL::ShaderNodeAmbientOcclusion b_ao_node(b_node); AmbientOcclusionNode *ao = graph->create_node<AmbientOcclusionNode>(); - ao->samples = b_ao_node.samples(); - ao->inside = b_ao_node.inside(); - ao->only_local = b_ao_node.only_local(); + ao->set_samples(b_ao_node.samples()); + ao->set_inside(b_ao_node.inside()); + ao->set_only_local(b_ao_node.only_local()); node = ao; } else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) { @@ -623,7 +639,7 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeWireframe)) { BL::ShaderNodeWireframe b_wireframe_node(b_node); WireframeNode *wire = graph->create_node<WireframeNode>(); - wire->use_pixel_size = b_wireframe_node.use_pixel_size(); + wire->set_use_pixel_size(b_wireframe_node.use_pixel_size()); node = wire; } else if (b_node.is_a(&RNA_ShaderNodeWavelength)) { @@ -653,13 +669,13 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeVertexColor)) { BL::ShaderNodeVertexColor b_vertex_color_node(b_node); VertexColorNode *vertex_color_node = graph->create_node<VertexColorNode>(); - vertex_color_node->layer_name = b_vertex_color_node.layer_name(); + vertex_color_node->set_layer_name(ustring(b_vertex_color_node.layer_name())); node = vertex_color_node; } else if (b_node.is_a(&RNA_ShaderNodeBump)) { BL::ShaderNodeBump b_bump_node(b_node); BumpNode *bump = graph->create_node<BumpNode>(); - bump->invert = b_bump_node.invert(); + bump->set_invert(b_bump_node.invert()); node = bump; } else if (b_node.is_a(&RNA_ShaderNodeScript)) { @@ -692,25 +708,26 @@ static ShaderNode *add_node(Scene *scene, BL::ImageUser b_image_user(b_image_node.image_user()); ImageTextureNode *image = graph->create_node<ImageTextureNode>(); - image->interpolation = get_image_interpolation(b_image_node); - image->extension = get_image_extension(b_image_node); - image->projection = (NodeImageProjection)b_image_node.projection(); - image->projection_blend = b_image_node.projection_blend(); + image->set_interpolation(get_image_interpolation(b_image_node)); + image->set_extension(get_image_extension(b_image_node)); + image->set_projection((NodeImageProjection)b_image_node.projection()); + image->set_projection_blend(b_image_node.projection_blend()); BL::TexMapping b_texture_mapping(b_image_node.texture_mapping()); - get_tex_mapping(&image->tex_mapping, b_texture_mapping); + get_tex_mapping(image, b_texture_mapping); if (b_image) { PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; - image->colorspace = get_enum_identifier(colorspace_ptr, "name"); + image->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name"))); - image->animated = b_image_node.image_user().use_auto_refresh(); - image->alpha_type = get_image_alpha_type(b_image); + image->set_animated(b_image_node.image_user().use_auto_refresh()); + image->set_alpha_type(get_image_alpha_type(b_image)); - image->tiles.clear(); + array<int> tiles; BL::Image::tiles_iterator b_iter; for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) { - image->tiles.push_back(b_iter->number()); + tiles.push_back_slow(b_iter->number()); } + image->set_tiles(tiles); /* builtin images will use callback-based reading because * they could only be loaded correct from blender side @@ -732,8 +749,9 @@ static ShaderNode *add_node(Scene *scene, new BlenderImageLoader(b_image, image_frame), image->image_params()); } else { - image->filename = image_user_file_path( - b_image_user, b_image, b_scene.frame_current(), true); + ustring filename = ustring( + image_user_file_path(b_image_user, b_image, b_scene.frame_current(), true)); + image->set_filename(filename); } } node = image; @@ -744,17 +762,17 @@ static ShaderNode *add_node(Scene *scene, BL::ImageUser b_image_user(b_env_node.image_user()); EnvironmentTextureNode *env = graph->create_node<EnvironmentTextureNode>(); - env->interpolation = get_image_interpolation(b_env_node); - env->projection = (NodeEnvironmentProjection)b_env_node.projection(); + env->set_interpolation(get_image_interpolation(b_env_node)); + env->set_projection((NodeEnvironmentProjection)b_env_node.projection()); BL::TexMapping b_texture_mapping(b_env_node.texture_mapping()); - get_tex_mapping(&env->tex_mapping, b_texture_mapping); + get_tex_mapping(env, b_texture_mapping); if (b_image) { PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; - env->colorspace = get_enum_identifier(colorspace_ptr, "name"); + env->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name"))); - env->animated = b_env_node.image_user().use_auto_refresh(); - env->alpha_type = get_image_alpha_type(b_image); + env->set_animated(b_env_node.image_user().use_auto_refresh()); + env->set_alpha_type(get_image_alpha_type(b_image)); bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || b_image.source() == BL::Image::source_MOVIE || @@ -767,8 +785,8 @@ static ShaderNode *add_node(Scene *scene, env->image_params()); } else { - env->filename = image_user_file_path( - b_image_user, b_image, b_scene.frame_current(), false); + env->set_filename( + ustring(image_user_file_path(b_image_user, b_image, b_scene.frame_current(), false))); } } node = env; @@ -776,103 +794,103 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) { BL::ShaderNodeTexGradient b_gradient_node(b_node); GradientTextureNode *gradient = graph->create_node<GradientTextureNode>(); - gradient->type = (NodeGradientType)b_gradient_node.gradient_type(); + gradient->set_gradient_type((NodeGradientType)b_gradient_node.gradient_type()); BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping()); - get_tex_mapping(&gradient->tex_mapping, b_texture_mapping); + get_tex_mapping(gradient, b_texture_mapping); node = gradient; } else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) { BL::ShaderNodeTexVoronoi b_voronoi_node(b_node); VoronoiTextureNode *voronoi = graph->create_node<VoronoiTextureNode>(); - voronoi->dimensions = b_voronoi_node.voronoi_dimensions(); - voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature(); - voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance(); + voronoi->set_dimensions(b_voronoi_node.voronoi_dimensions()); + voronoi->set_feature((NodeVoronoiFeature)b_voronoi_node.feature()); + voronoi->set_metric((NodeVoronoiDistanceMetric)b_voronoi_node.distance()); BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping()); - get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping); + get_tex_mapping(voronoi, b_texture_mapping); node = voronoi; } else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) { BL::ShaderNodeTexMagic b_magic_node(b_node); MagicTextureNode *magic = graph->create_node<MagicTextureNode>(); - magic->depth = b_magic_node.turbulence_depth(); + magic->set_depth(b_magic_node.turbulence_depth()); BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping()); - get_tex_mapping(&magic->tex_mapping, b_texture_mapping); + get_tex_mapping(magic, b_texture_mapping); node = magic; } else if (b_node.is_a(&RNA_ShaderNodeTexWave)) { BL::ShaderNodeTexWave b_wave_node(b_node); WaveTextureNode *wave = graph->create_node<WaveTextureNode>(); - wave->type = (NodeWaveType)b_wave_node.wave_type(); - wave->bands_direction = (NodeWaveBandsDirection)b_wave_node.bands_direction(); - wave->rings_direction = (NodeWaveRingsDirection)b_wave_node.rings_direction(); - wave->profile = (NodeWaveProfile)b_wave_node.wave_profile(); + wave->set_wave_type((NodeWaveType)b_wave_node.wave_type()); + wave->set_bands_direction((NodeWaveBandsDirection)b_wave_node.bands_direction()); + wave->set_rings_direction((NodeWaveRingsDirection)b_wave_node.rings_direction()); + wave->set_profile((NodeWaveProfile)b_wave_node.wave_profile()); BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping()); - get_tex_mapping(&wave->tex_mapping, b_texture_mapping); + get_tex_mapping(wave, b_texture_mapping); node = wave; } else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) { BL::ShaderNodeTexChecker b_checker_node(b_node); CheckerTextureNode *checker = graph->create_node<CheckerTextureNode>(); BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping()); - get_tex_mapping(&checker->tex_mapping, b_texture_mapping); + get_tex_mapping(checker, b_texture_mapping); node = checker; } else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) { BL::ShaderNodeTexBrick b_brick_node(b_node); BrickTextureNode *brick = graph->create_node<BrickTextureNode>(); - brick->offset = b_brick_node.offset(); - brick->offset_frequency = b_brick_node.offset_frequency(); - brick->squash = b_brick_node.squash(); - brick->squash_frequency = b_brick_node.squash_frequency(); + brick->set_offset(b_brick_node.offset()); + brick->set_offset_frequency(b_brick_node.offset_frequency()); + brick->set_squash(b_brick_node.squash()); + brick->set_squash_frequency(b_brick_node.squash_frequency()); BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping()); - get_tex_mapping(&brick->tex_mapping, b_texture_mapping); + get_tex_mapping(brick, b_texture_mapping); node = brick; } else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) { BL::ShaderNodeTexNoise b_noise_node(b_node); NoiseTextureNode *noise = graph->create_node<NoiseTextureNode>(); - noise->dimensions = b_noise_node.noise_dimensions(); + noise->set_dimensions(b_noise_node.noise_dimensions()); BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping()); - get_tex_mapping(&noise->tex_mapping, b_texture_mapping); + get_tex_mapping(noise, b_texture_mapping); node = noise; } else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) { BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); MusgraveTextureNode *musgrave_node = graph->create_node<MusgraveTextureNode>(); - musgrave_node->type = (NodeMusgraveType)b_musgrave_node.musgrave_type(); - musgrave_node->dimensions = b_musgrave_node.musgrave_dimensions(); + musgrave_node->set_musgrave_type((NodeMusgraveType)b_musgrave_node.musgrave_type()); + musgrave_node->set_dimensions(b_musgrave_node.musgrave_dimensions()); BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping()); - get_tex_mapping(&musgrave_node->tex_mapping, b_texture_mapping); + get_tex_mapping(musgrave_node, b_texture_mapping); node = musgrave_node; } else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) { BL::ShaderNodeTexCoord b_tex_coord_node(b_node); TextureCoordinateNode *tex_coord = graph->create_node<TextureCoordinateNode>(); - tex_coord->from_dupli = b_tex_coord_node.from_instancer(); + tex_coord->set_from_dupli(b_tex_coord_node.from_instancer()); if (b_tex_coord_node.object()) { - tex_coord->use_transform = true; - tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world()); + tex_coord->set_use_transform(true); + tex_coord->set_ob_tfm(get_transform(b_tex_coord_node.object().matrix_world())); } node = tex_coord; } else if (b_node.is_a(&RNA_ShaderNodeTexSky)) { BL::ShaderNodeTexSky b_sky_node(b_node); SkyTextureNode *sky = graph->create_node<SkyTextureNode>(); - sky->type = (NodeSkyType)b_sky_node.sky_type(); - sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction())); - sky->turbidity = b_sky_node.turbidity(); - sky->ground_albedo = b_sky_node.ground_albedo(); - sky->sun_disc = b_sky_node.sun_disc(); - sky->sun_size = b_sky_node.sun_size(); - sky->sun_intensity = b_sky_node.sun_intensity(); - sky->sun_elevation = b_sky_node.sun_elevation(); - sky->sun_rotation = b_sky_node.sun_rotation(); - sky->altitude = 1000.0f * b_sky_node.altitude(); - sky->air_density = b_sky_node.air_density(); - sky->dust_density = b_sky_node.dust_density(); - sky->ozone_density = b_sky_node.ozone_density(); + sky->set_sky_type((NodeSkyType)b_sky_node.sky_type()); + sky->set_sun_direction(normalize(get_float3(b_sky_node.sun_direction()))); + sky->set_turbidity(b_sky_node.turbidity()); + sky->set_ground_albedo(b_sky_node.ground_albedo()); + sky->set_sun_disc(b_sky_node.sun_disc()); + sky->set_sun_size(b_sky_node.sun_size()); + sky->set_sun_intensity(b_sky_node.sun_intensity()); + sky->set_sun_elevation(b_sky_node.sun_elevation()); + sky->set_sun_rotation(b_sky_node.sun_rotation()); + sky->set_altitude(1000.0f * b_sky_node.altitude()); + sky->set_air_density(b_sky_node.air_density()); + sky->set_dust_density(b_sky_node.dust_density()); + sky->set_ozone_density(b_sky_node.ozone_density()); BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping()); - get_tex_mapping(&sky->tex_mapping, b_texture_mapping); + get_tex_mapping(sky, b_texture_mapping); node = sky; } else if (b_node.is_a(&RNA_ShaderNodeTexIES)) { @@ -880,13 +898,14 @@ static ShaderNode *add_node(Scene *scene, IESLightNode *ies = graph->create_node<IESLightNode>(); switch (b_ies_node.mode()) { case BL::ShaderNodeTexIES::mode_EXTERNAL: - ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath()); + ies->set_filename(ustring(blender_absolute_path(b_data, b_ntree, b_ies_node.filepath()))); break; case BL::ShaderNodeTexIES::mode_INTERNAL: - ies->ies = get_text_datablock_content(b_ies_node.ies().ptr); - if (ies->ies.empty()) { - ies->ies = "\n"; + ustring ies_content = ustring(get_text_datablock_content(b_ies_node.ies().ptr)); + if (ies_content.empty()) { + ies_content = "\n"; } + ies->set_ies(ies_content); break; } node = ies; @@ -894,36 +913,36 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeTexWhiteNoise)) { BL::ShaderNodeTexWhiteNoise b_tex_white_noise_node(b_node); WhiteNoiseTextureNode *white_noise_node = graph->create_node<WhiteNoiseTextureNode>(); - white_noise_node->dimensions = b_tex_white_noise_node.noise_dimensions(); + white_noise_node->set_dimensions(b_tex_white_noise_node.noise_dimensions()); node = white_noise_node; } else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) { BL::ShaderNodeNormalMap b_normal_map_node(b_node); NormalMapNode *nmap = graph->create_node<NormalMapNode>(); - nmap->space = (NodeNormalMapSpace)b_normal_map_node.space(); - nmap->attribute = b_normal_map_node.uv_map(); + nmap->set_space((NodeNormalMapSpace)b_normal_map_node.space()); + nmap->set_attribute(ustring(b_normal_map_node.uv_map())); node = nmap; } else if (b_node.is_a(&RNA_ShaderNodeTangent)) { BL::ShaderNodeTangent b_tangent_node(b_node); TangentNode *tangent = graph->create_node<TangentNode>(); - tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type(); - tangent->axis = (NodeTangentAxis)b_tangent_node.axis(); - tangent->attribute = b_tangent_node.uv_map(); + tangent->set_direction_type((NodeTangentDirectionType)b_tangent_node.direction_type()); + tangent->set_axis((NodeTangentAxis)b_tangent_node.axis()); + tangent->set_attribute(ustring(b_tangent_node.uv_map())); node = tangent; } else if (b_node.is_a(&RNA_ShaderNodeUVMap)) { BL::ShaderNodeUVMap b_uvmap_node(b_node); UVMapNode *uvm = graph->create_node<UVMapNode>(); - uvm->attribute = b_uvmap_node.uv_map(); - uvm->from_dupli = b_uvmap_node.from_instancer(); + uvm->set_attribute(ustring(b_uvmap_node.uv_map())); + uvm->set_from_dupli(b_uvmap_node.from_instancer()); node = uvm; } else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { BL::ShaderNodeTexPointDensity b_point_density_node(b_node); PointDensityTextureNode *point_density = graph->create_node<PointDensityTextureNode>(); - point_density->space = (NodeTexVoxelSpace)b_point_density_node.space(); - point_density->interpolation = get_image_interpolation(b_point_density_node); + point_density->set_space((NodeTexVoxelSpace)b_point_density_node.space()); + point_density->set_interpolation(get_image_interpolation(b_point_density_node)); point_density->handle = scene->image_manager->add_image( new BlenderPointDensityLoader(b_depsgraph, b_point_density_node), point_density->image_params()); @@ -940,33 +959,33 @@ static ShaderNode *add_node(Scene *scene, if (b_ob) { float3 loc, size; point_density_texture_space(b_depsgraph, b_point_density_node, loc, size); - point_density->tfm = transform_translate(-loc) * transform_scale(size) * - transform_inverse(get_transform(b_ob.matrix_world())); + point_density->set_tfm(transform_translate(-loc) * transform_scale(size) * + transform_inverse(get_transform(b_ob.matrix_world()))); } } else if (b_node.is_a(&RNA_ShaderNodeBevel)) { BL::ShaderNodeBevel b_bevel_node(b_node); BevelNode *bevel = graph->create_node<BevelNode>(); - bevel->samples = b_bevel_node.samples(); + bevel->set_samples(b_bevel_node.samples()); node = bevel; } else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) { BL::ShaderNodeDisplacement b_disp_node(b_node); DisplacementNode *disp = graph->create_node<DisplacementNode>(); - disp->space = (NodeNormalMapSpace)b_disp_node.space(); + disp->set_space((NodeNormalMapSpace)b_disp_node.space()); node = disp; } else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) { BL::ShaderNodeVectorDisplacement b_disp_node(b_node); VectorDisplacementNode *disp = graph->create_node<VectorDisplacementNode>(); - disp->space = (NodeNormalMapSpace)b_disp_node.space(); - disp->attribute = ""; + disp->set_space((NodeNormalMapSpace)b_disp_node.space()); + disp->set_attribute(ustring("")); node = disp; } else if (b_node.is_a(&RNA_ShaderNodeOutputAOV)) { BL::ShaderNodeOutputAOV b_aov_node(b_node); OutputAOVNode *aov = graph->create_node<OutputAOVNode>(); - aov->name = b_aov_node.name(); + aov->set_name(ustring(b_aov_node.name())); node = aov; } @@ -1293,7 +1312,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) ShaderGraph *graph = new ShaderGraph(); shader->name = b_mat.name().c_str(); - shader->pass_id = b_mat.pass_index(); + shader->set_pass_id(b_mat.pass_index()); /* create nodes */ if (b_mat.use_nodes() && b_mat.node_tree()) { @@ -1303,7 +1322,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) } else { DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>(); - diffuse->color = get_float3(b_mat.diffuse_color()); + diffuse->set_color(get_float3(b_mat.diffuse_color())); graph->add(diffuse); ShaderNode *out = graph->output(); @@ -1312,13 +1331,13 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) /* settings */ PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles"); - shader->use_mis = get_boolean(cmat, "sample_as_light"); - shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow"); - shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume"); - shader->volume_sampling_method = get_volume_sampling(cmat); - shader->volume_interpolation_method = get_volume_interpolation(cmat); - shader->volume_step_rate = get_float(cmat, "volume_step_rate"); - shader->displacement_method = get_displacement_method(cmat); + shader->set_use_mis(get_boolean(cmat, "sample_as_light")); + shader->set_use_transparent_shadow(get_boolean(cmat, "use_transparent_shadow")); + shader->set_heterogeneous_volume(!get_boolean(cmat, "homogeneous_volume")); + shader->set_volume_sampling_method(get_volume_sampling(cmat)); + shader->set_volume_interpolation_method(get_volume_interpolation(cmat)); + shader->set_volume_step_rate(get_float(cmat, "volume_step_rate")); + shader->set_displacement_method(get_displacement_method(cmat)); shader->set_graph(graph); @@ -1359,7 +1378,6 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all) { Background *background = scene->background; - Background prevbackground = *background; BL::World b_world = b_scene.world(); @@ -1379,14 +1397,14 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, /* volume */ PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles"); - shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume"); - shader->volume_sampling_method = get_volume_sampling(cworld); - shader->volume_interpolation_method = get_volume_interpolation(cworld); - shader->volume_step_rate = get_float(cworld, "volume_step_size"); + shader->set_heterogeneous_volume(!get_boolean(cworld, "homogeneous_volume")); + shader->set_volume_sampling_method(get_volume_sampling(cworld)); + shader->set_volume_interpolation_method(get_volume_interpolation(cworld)); + shader->set_volume_step_rate(get_float(cworld, "volume_step_size")); } else if (new_viewport_parameters.use_scene_world && b_world) { BackgroundNode *background = graph->create_node<BackgroundNode>(); - background->color = get_float3(b_world.color()); + background->set_color(get_float3(b_world.color())); graph->add(background); ShaderNode *out = graph->output(); @@ -1408,29 +1426,32 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, graph->add(light_path); MixNode *mix_scene_with_background = graph->create_node<MixNode>(); - mix_scene_with_background->color2 = world_color; + mix_scene_with_background->set_color2(world_color); graph->add(mix_scene_with_background); EnvironmentTextureNode *texture_environment = graph->create_node<EnvironmentTextureNode>(); - texture_environment->tex_mapping.type = TextureMapping::VECTOR; - texture_environment->tex_mapping.rotation[2] = new_viewport_parameters.studiolight_rotate_z; - texture_environment->filename = new_viewport_parameters.studiolight_path; + texture_environment->set_tex_mapping_type(TextureMapping::VECTOR); + float3 rotation_z = texture_environment->get_tex_mapping_rotation(); + rotation_z[2] = new_viewport_parameters.studiolight_rotate_z; + texture_environment->set_tex_mapping_rotation(rotation_z); + texture_environment->set_filename(new_viewport_parameters.studiolight_path); graph->add(texture_environment); MixNode *mix_intensity = graph->create_node<MixNode>(); - mix_intensity->type = NODE_MIX_MUL; - mix_intensity->fac = 1.0f; - mix_intensity->color2 = make_float3(new_viewport_parameters.studiolight_intensity, - new_viewport_parameters.studiolight_intensity, - new_viewport_parameters.studiolight_intensity); + mix_intensity->set_mix_type(NODE_MIX_MUL); + mix_intensity->set_fac(1.0f); + mix_intensity->set_color2(make_float3(new_viewport_parameters.studiolight_intensity, + new_viewport_parameters.studiolight_intensity, + new_viewport_parameters.studiolight_intensity)); graph->add(mix_intensity); TextureCoordinateNode *texture_coordinate = graph->create_node<TextureCoordinateNode>(); graph->add(texture_coordinate); MixNode *mix_background_with_environment = graph->create_node<MixNode>(); - mix_background_with_environment->fac = new_viewport_parameters.studiolight_background_alpha; - mix_background_with_environment->color1 = world_color; + mix_background_with_environment->set_fac( + new_viewport_parameters.studiolight_background_alpha); + mix_background_with_environment->set_color1(world_color); graph->add(mix_background_with_environment); ShaderNode *out = graph->output(); @@ -1452,9 +1473,9 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, /* AO */ BL::WorldLighting b_light = b_world.light_settings(); - background->use_ao = b_light.use_ambient_occlusion(); - background->ao_factor = b_light.ao_factor(); - background->ao_distance = b_light.distance(); + background->set_use_ao(b_light.use_ambient_occlusion()); + background->set_ao_factor(b_light.ao_factor()); + background->set_ao_distance(b_light.distance()); /* visibility */ PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility"); @@ -1466,12 +1487,12 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, visibility |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0; visibility |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0; - background->visibility = visibility; + background->set_visibility(visibility); } else { - background->use_ao = false; - background->ao_factor = 0.0f; - background->ao_distance = FLT_MAX; + background->set_use_ao(false); + background->set_ao_factor(0.0f); + background->set_ao_distance(FLT_MAX); } shader->set_graph(graph); @@ -1480,22 +1501,23 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, } PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - background->transparent = b_scene.render().film_transparent(); + background->set_transparent(b_scene.render().film_transparent()); - if (background->transparent) { - background->transparent_glass = get_boolean(cscene, "film_transparent_glass"); - background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness"); + if (background->get_transparent()) { + background->set_transparent_glass(get_boolean(cscene, "film_transparent_glass")); + background->set_transparent_roughness_threshold( + get_float(cscene, "film_transparent_roughness")); } else { - background->transparent_glass = false; - background->transparent_roughness_threshold = 0.0f; + background->set_transparent_glass(false); + background->set_transparent_roughness_threshold(0.0f); } - background->use_shader = view_layer.use_background_shader | - viewport_parameters.custom_viewport_parameters(); - background->use_ao = background->use_ao && view_layer.use_background_ao; + background->set_use_shader(view_layer.use_background_shader | + viewport_parameters.custom_viewport_parameters()); + background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao); - if (background->modified(prevbackground)) + if (background->is_modified()) background->tag_update(scene); } @@ -1528,8 +1550,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all) } else { EmissionNode *emission = graph->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); graph->add(emission); ShaderNode *out = graph->output(); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 0139afb711d..94ff0ff1473 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -118,9 +118,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d if (dicing_prop_changed) { for (const pair<const GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) { Geometry *geom = iter.second; - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) { PointerRNA id_ptr; RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); geometry_map.set_recalc(BL::ID(id_ptr)); @@ -238,7 +238,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, geometry_synced.clear(); /* use for objects and motion sync */ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE || - scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) { + scene->camera->get_motion_position() == Camera::MOTION_POSITION_CENTER) { sync_objects(b_depsgraph, b_v3d); } sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state); @@ -264,70 +264,75 @@ void BlenderSync::sync_integrator() experimental = (get_enum(cscene, "feature_set") != 0); Integrator *integrator = scene->integrator; - Integrator previntegrator = *integrator; - integrator->min_bounce = get_int(cscene, "min_light_bounces"); - integrator->max_bounce = get_int(cscene, "max_bounces"); + integrator->set_min_bounce(get_int(cscene, "min_light_bounces")); + integrator->set_max_bounce(get_int(cscene, "max_bounces")); - integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces"); - integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces"); - integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces"); - integrator->max_volume_bounce = get_int(cscene, "volume_bounces"); + integrator->set_max_diffuse_bounce(get_int(cscene, "diffuse_bounces")); + integrator->set_max_glossy_bounce(get_int(cscene, "glossy_bounces")); + integrator->set_max_transmission_bounce(get_int(cscene, "transmission_bounces")); + integrator->set_max_volume_bounce(get_int(cscene, "volume_bounces")); - integrator->transparent_min_bounce = get_int(cscene, "min_transparent_bounces"); - integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces"); + integrator->set_transparent_min_bounce(get_int(cscene, "min_transparent_bounces")); + integrator->set_transparent_max_bounce(get_int(cscene, "transparent_max_bounces")); - integrator->volume_max_steps = get_int(cscene, "volume_max_steps"); - integrator->volume_step_rate = (preview) ? get_float(cscene, "volume_preview_step_rate") : - get_float(cscene, "volume_step_rate"); + integrator->set_volume_max_steps(get_int(cscene, "volume_max_steps")); + float volume_step_rate = (preview) ? get_float(cscene, "volume_preview_step_rate") : + get_float(cscene, "volume_step_rate"); + integrator->set_volume_step_rate(volume_step_rate); - integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective"); - integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive"); - integrator->filter_glossy = get_float(cscene, "blur_glossy"); + integrator->set_caustics_reflective(get_boolean(cscene, "caustics_reflective")); + integrator->set_caustics_refractive(get_boolean(cscene, "caustics_refractive")); + integrator->set_filter_glossy(get_float(cscene, "blur_glossy")); - integrator->seed = get_int(cscene, "seed"); + int seed = get_int(cscene, "seed"); if (get_boolean(cscene, "use_animated_seed")) { - integrator->seed = hash_uint2(b_scene.frame_current(), get_int(cscene, "seed")); + seed = hash_uint2(b_scene.frame_current(), get_int(cscene, "seed")); if (b_scene.frame_subframe() != 0.0f) { /* TODO(sergey): Ideally should be some sort of hash_merge, * but this is good enough for now. */ - integrator->seed += hash_uint2((int)(b_scene.frame_subframe() * (float)INT_MAX), - get_int(cscene, "seed")); + seed += hash_uint2((int)(b_scene.frame_subframe() * (float)INT_MAX), + get_int(cscene, "seed")); } } - integrator->sampling_pattern = (SamplingPattern)get_enum( - cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); + integrator->set_seed(seed); - integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct"); - integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect"); + integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct")); + integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect")); if (!preview) { - if (integrator->motion_blur != r.use_motion_blur()) { + if (integrator->get_motion_blur() != r.use_motion_blur()) { scene->object_manager->tag_update(scene); - scene->camera->tag_update(); + scene->camera->tag_modified(); } - integrator->motion_blur = r.use_motion_blur(); + integrator->set_motion_blur(r.use_motion_blur()); } - integrator->method = (Integrator::Method)get_enum( - cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH); + integrator->set_method((Integrator::Method)get_enum( + cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH)); + + integrator->set_sample_all_lights_direct(get_boolean(cscene, "sample_all_lights_direct")); + integrator->set_sample_all_lights_indirect(get_boolean(cscene, "sample_all_lights_indirect")); + integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold")); + + SamplingPattern sampling_pattern = (SamplingPattern)get_enum( + cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); - integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct"); - integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect"); - integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold"); + int adaptive_min_samples = INT_MAX; if (RNA_boolean_get(&cscene, "use_adaptive_sampling")) { - integrator->sampling_pattern = SAMPLING_PATTERN_PMJ; - integrator->adaptive_min_samples = get_int(cscene, "adaptive_min_samples"); - integrator->adaptive_threshold = get_float(cscene, "adaptive_threshold"); + sampling_pattern = SAMPLING_PATTERN_PMJ; + adaptive_min_samples = get_int(cscene, "adaptive_min_samples"); + integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold")); } else { - integrator->adaptive_min_samples = INT_MAX; - integrator->adaptive_threshold = 0.0f; + integrator->set_adaptive_threshold(0.0f); } + integrator->set_sampling_pattern(sampling_pattern); + int diffuse_samples = get_int(cscene, "diffuse_samples"); int glossy_samples = get_int(cscene, "glossy_samples"); int transmission_samples = get_int(cscene, "transmission_samples"); @@ -337,39 +342,40 @@ void BlenderSync::sync_integrator() int volume_samples = get_int(cscene, "volume_samples"); if (get_boolean(cscene, "use_square_samples")) { - integrator->diffuse_samples = diffuse_samples * diffuse_samples; - integrator->glossy_samples = glossy_samples * glossy_samples; - integrator->transmission_samples = transmission_samples * transmission_samples; - integrator->ao_samples = ao_samples * ao_samples; - integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples; - integrator->subsurface_samples = subsurface_samples * subsurface_samples; - integrator->volume_samples = volume_samples * volume_samples; - integrator->adaptive_min_samples = min( - integrator->adaptive_min_samples * integrator->adaptive_min_samples, INT_MAX); + integrator->set_diffuse_samples(diffuse_samples * diffuse_samples); + integrator->set_glossy_samples(glossy_samples * glossy_samples); + integrator->set_transmission_samples(transmission_samples * transmission_samples); + integrator->set_ao_samples(ao_samples * ao_samples); + integrator->set_mesh_light_samples(mesh_light_samples * mesh_light_samples); + integrator->set_subsurface_samples(subsurface_samples * subsurface_samples); + integrator->set_volume_samples(volume_samples * volume_samples); + adaptive_min_samples = min(adaptive_min_samples * adaptive_min_samples, INT_MAX); } else { - integrator->diffuse_samples = diffuse_samples; - integrator->glossy_samples = glossy_samples; - integrator->transmission_samples = transmission_samples; - integrator->ao_samples = ao_samples; - integrator->mesh_light_samples = mesh_light_samples; - integrator->subsurface_samples = subsurface_samples; - integrator->volume_samples = volume_samples; + integrator->set_diffuse_samples(diffuse_samples); + integrator->set_glossy_samples(glossy_samples); + integrator->set_transmission_samples(transmission_samples); + integrator->set_ao_samples(ao_samples); + integrator->set_mesh_light_samples(mesh_light_samples); + integrator->set_subsurface_samples(subsurface_samples); + integrator->set_volume_samples(volume_samples); } + integrator->set_adaptive_min_samples(adaptive_min_samples); + if (b_scene.render().use_simplify()) { if (preview) { - integrator->ao_bounces = get_int(cscene, "ao_bounces"); + integrator->set_ao_bounces(get_int(cscene, "ao_bounces")); } else { - integrator->ao_bounces = get_int(cscene, "ao_bounces_render"); + integrator->set_ao_bounces(get_int(cscene, "ao_bounces_render")); } } else { - integrator->ao_bounces = 0; + integrator->set_ao_bounces(0); } - if (integrator->modified(previntegrator)) + if (integrator->is_modified()) integrator->tag_update(scene); } @@ -380,46 +386,42 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d) PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); Film *film = scene->film; - Film prevfilm = *film; vector<Pass> prevpasses = scene->passes; if (b_v3d) { - film->display_pass = update_viewport_display_passes(b_v3d, scene->passes); + film->set_display_pass(update_viewport_display_passes(b_v3d, scene->passes)); } - film->exposure = get_float(cscene, "film_exposure"); - film->filter_type = (FilterType)get_enum( - cscene, "pixel_filter_type", FILTER_NUM_TYPES, FILTER_BLACKMAN_HARRIS); - film->filter_width = (film->filter_type == FILTER_BOX) ? 1.0f : - get_float(cscene, "filter_width"); + film->set_exposure(get_float(cscene, "film_exposure")); + film->set_filter_type( + (FilterType)get_enum(cscene, "pixel_filter_type", FILTER_NUM_TYPES, FILTER_BLACKMAN_HARRIS)); + float filter_width = (film->get_filter_type() == FILTER_BOX) ? 1.0f : + get_float(cscene, "filter_width"); + film->set_filter_width(filter_width); if (b_scene.world()) { BL::WorldMistSettings b_mist = b_scene.world().mist_settings(); - film->mist_start = b_mist.start(); - film->mist_depth = b_mist.depth(); + film->set_mist_start(b_mist.start()); + film->set_mist_depth(b_mist.depth()); switch (b_mist.falloff()) { case BL::WorldMistSettings::falloff_QUADRATIC: - film->mist_falloff = 2.0f; + film->set_mist_falloff(2.0f); break; case BL::WorldMistSettings::falloff_LINEAR: - film->mist_falloff = 1.0f; + film->set_mist_falloff(1.0f); break; case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC: - film->mist_falloff = 0.5f; + film->set_mist_falloff(0.5f); break; } } - if (film->modified(prevfilm)) { - film->tag_update(scene); - } - if (!Pass::equals(prevpasses, scene->passes)) { film->tag_passes_update(scene, prevpasses, false); - film->tag_update(scene); + film->tag_modified(); } } @@ -585,7 +587,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::RenderPass b_pass(*b_pass_iter); PassType pass_type = get_pass_type(b_pass); - if (pass_type == PASS_MOTION && scene->integrator->motion_blur) + if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur()) continue; if (pass_type != PASS_NONE) Pass::add(pass_type, passes, b_pass.name().c_str()); @@ -593,12 +595,12 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles"); - scene->film->denoising_flags = 0; + int denoising_flags = 0; if (denoising.use || denoising.store_passes) { if (denoising.type == DENOISER_NLM) { #define MAP_OPTION(name, flag) \ if (!get_boolean(crl, name)) { \ - scene->film->denoising_flags |= flag; \ + denoising_flags |= flag; \ } \ ((void)0) MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR); @@ -611,6 +613,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, } b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str()); } + scene->film->set_denoising_flags(denoising_flags); if (denoising.store_passes) { b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str()); @@ -622,7 +625,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str()); } - if (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) { + if (scene->film->get_denoising_flags() & DENOISING_CLEAN_ALL_PASSES) { b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str()); } } @@ -665,16 +668,15 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, /* Cryptomatte stores two ID/weight pairs per RGBA layer. * User facing parameter is the number of pairs. */ int crypto_depth = divide_up(min(16, get_int(crl, "pass_crypto_depth")), 2); - scene->film->cryptomatte_depth = crypto_depth; - scene->film->cryptomatte_passes = CRYPT_NONE; + scene->film->set_cryptomatte_depth(crypto_depth); + CryptomatteType cryptomatte_passes = CRYPT_NONE; if (get_boolean(crl, "use_pass_crypto_object")) { for (int i = 0; i < crypto_depth; i++) { string passname = cryptomatte_prefix + string_printf("Object%02d", i); b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str()); } - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_OBJECT); + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT); } if (get_boolean(crl, "use_pass_crypto_material")) { for (int i = 0; i < crypto_depth; i++) { @@ -682,8 +684,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str()); } - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_MATERIAL); + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL); } if (get_boolean(crl, "use_pass_crypto_asset")) { for (int i = 0; i < crypto_depth; i++) { @@ -691,13 +692,12 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str()); } - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_ASSET); + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET); } - if (get_boolean(crl, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) { - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_ACCURATE); + if (get_boolean(crl, "pass_crypto_accurate") && cryptomatte_passes != CRYPT_NONE) { + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ACCURATE); } + scene->film->set_cryptomatte_passes(cryptomatte_passes); if (adaptive_sampling) { Pass::add(PASS_ADAPTIVE_AUX_BUFFER, passes); @@ -721,14 +721,14 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, } RNA_END; - scene->film->denoising_data_pass = denoising.use || denoising.store_passes; - scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES); - scene->film->denoising_prefiltered_pass = denoising.store_passes && - denoising.type == DENOISER_NLM; + scene->film->set_denoising_data_pass(denoising.use || denoising.store_passes); + scene->film->set_denoising_clean_pass(scene->film->get_denoising_flags() & + DENOISING_CLEAN_ALL_PASSES); + scene->film->set_denoising_prefiltered_pass(denoising.store_passes && + denoising.type == DENOISER_NLM); - scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold(); + scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold()); scene->film->tag_passes_update(scene, passes); - scene->film->tag_update(scene); scene->integrator->tag_update(scene); return passes; diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 8ca021ff0d2..ccf059d7704 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -207,7 +207,7 @@ class BlenderSync { void free_data_after_sync(BL::Depsgraph &b_depsgraph); /* util */ - void find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader); + void find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader); bool BKE_object_is_modified(BL::Object &b_ob); bool object_is_geometry(BL::Object &b_ob); bool object_is_light(BL::Object &b_ob); diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index 7ecfd3583d6..1843fecd586 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -202,7 +202,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Volume *volume, fl continue; } - volume->clipping = b_domain.clipping(); + volume->set_clipping(b_domain.clipping()); Attribute *attr = volume->attributes.add(std); @@ -262,9 +262,9 @@ static void sync_volume_object(BL::BlendData &b_data, BL::VolumeRender b_render(b_volume.render()); - volume->clipping = b_render.clipping(); - volume->step_size = b_render.step_size(); - volume->object_space = (b_render.space() == BL::VolumeRender::space_OBJECT); + volume->set_clipping(b_render.clipping()); + volume->set_step_size(b_render.step_size()); + volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT)); /* Find grid with matching name. */ BL::Volume::grids_iterator b_grid_iter; diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 222c1c40f92..a51ac4cf4a9 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -209,30 +209,30 @@ void BVH::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility) /* Primitives. */ if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ - const Hair *hair = static_cast<const Hair *>(ob->geometry); + const Hair *hair = static_cast<const Hair *>(ob->get_geometry()); int prim_offset = (params.top_level) ? hair->prim_offset : 0; Hair::Curve curve = hair->get_curve(pidx - prim_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); - curve.bounds_grow(k, &hair->curve_keys[0], &hair->curve_radius[0], bbox); + curve.bounds_grow(k, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], bbox); /* Motion curves. */ - if (hair->use_motion_blur) { + if (hair->get_use_motion_blur()) { Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr) { - size_t hair_size = hair->curve_keys.size(); - size_t steps = hair->motion_steps - 1; + size_t hair_size = hair->get_curve_keys().size(); + size_t steps = hair->get_motion_steps() - 1; float3 *key_steps = attr->data_float3(); for (size_t i = 0; i < steps; i++) - curve.bounds_grow(k, key_steps + i * hair_size, &hair->curve_radius[0], bbox); + curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox); } } } else { /* Triangles. */ - const Mesh *mesh = static_cast<const Mesh *>(ob->geometry); + const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry()); int prim_offset = (params.top_level) ? mesh->prim_offset : 0; Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset); const float3 *vpos = &mesh->verts[0]; @@ -264,7 +264,7 @@ void BVH::pack_triangle(int idx, float4 tri_verts[3]) { int tob = pack.prim_object[idx]; assert(tob >= 0 && tob < objects.size()); - const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->geometry); + const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->get_geometry()); int tidx = pack.prim_index[idx]; Mesh::Triangle t = mesh->get_triangle(tidx); @@ -329,7 +329,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) */ for (size_t i = 0; i < pack.prim_index.size(); i++) { if (pack.prim_index[i] != -1) { - pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset; + pack.prim_index[i] += objects[pack.prim_object[i]]->get_geometry()->prim_offset; } } @@ -390,7 +390,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) /* merge */ foreach (Object *ob, objects) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); /* We assume that if mesh doesn't need own BVH it was already included * into a top-level BVH and no packing here is needed. diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 360cac59e9b..1727082b7ec 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -169,12 +169,12 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair const size_t num_curves = hair->num_curves(); for (uint j = 0; j < num_curves; j++) { const Hair::Curve curve = hair->get_curve(j); - const float *curve_radius = &hair->curve_radius[0]; + const float *curve_radius = &hair->get_curve_radius()[0]; for (int k = 0; k < curve.num_keys - 1; k++) { if (curve_attr_mP == NULL) { /* Really simple logic for static hair. */ BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); + curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds); if (bounds.valid()) { int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k); references.push_back(BVHReference(bounds, j, i, packed_type)); @@ -189,9 +189,9 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair */ /* TODO(sergey): Support motion steps for spatially split BVH. */ BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); - const size_t num_keys = hair->curve_keys.size(); - const size_t num_steps = hair->motion_steps; + curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds); + const size_t num_keys = hair->get_curve_keys().size(); + const size_t num_steps = hair->get_motion_steps(); const float3 *key_steps = curve_attr_mP->data_float3(); for (size_t step = 0; step < num_steps - 1; step++) { curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds); @@ -210,10 +210,10 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair */ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1; const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1); - const size_t num_steps = hair->motion_steps; - const float3 *curve_keys = &hair->curve_keys[0]; + const size_t num_steps = hair->get_motion_steps(); + const float3 *curve_keys = &hair->get_curve_keys()[0]; const float3 *key_steps = curve_attr_mP->data_float3(); - const size_t num_keys = hair->curve_keys.size(); + const size_t num_keys = hair->get_curve_keys().size(); /* Calculate bounding box of the previous time step. * Will be reused later to avoid duplicated work on * calculating BVH time step boundbox. @@ -270,11 +270,11 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair void BVHBuild::add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i) { - 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); add_reference_triangles(root, center, mesh, i); } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); add_reference_curves(root, center, hair, i); } @@ -299,11 +299,11 @@ static size_t count_curve_segments(Hair *hair) static size_t count_primitives(Geometry *geom) { - 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); return mesh->num_triangles(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); return count_curve_segments(hair); } @@ -321,14 +321,14 @@ void BVHBuild::add_references(BVHRange &root) if (!ob->is_traceable()) { continue; } - if (!ob->geometry->is_instanced()) { - num_alloc_references += count_primitives(ob->geometry); + if (!ob->get_geometry()->is_instanced()) { + num_alloc_references += count_primitives(ob->get_geometry()); } else num_alloc_references++; } else { - num_alloc_references += count_primitives(ob->geometry); + num_alloc_references += count_primitives(ob->get_geometry()); } } @@ -344,13 +344,13 @@ void BVHBuild::add_references(BVHRange &root) ++i; continue; } - if (!ob->geometry->is_instanced()) - add_reference_geometry(bounds, center, ob->geometry, i); + if (!ob->get_geometry()->is_instanced()) + add_reference_geometry(bounds, center, ob->get_geometry(), i); else add_reference_object(bounds, center, ob, i); } else - add_reference_geometry(bounds, center, ob->geometry, i); + add_reference_geometry(bounds, center, ob->get_geometry(), i); i++; diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp index 53776a55257..910e3780b2e 100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@ -300,11 +300,11 @@ static bool rtc_progress_func(void *user_ptr, const double n) static size_t count_primitives(Geometry *geom) { - 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); return mesh->num_triangles(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); return hair->num_segments(); } @@ -402,15 +402,15 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) if (!ob->is_traceable()) { continue; } - if (!ob->geometry->is_instanced()) { - prim_count += count_primitives(ob->geometry); + if (!ob->get_geometry()->is_instanced()) { + prim_count += count_primitives(ob->get_geometry()); } else { ++prim_count; } } else { - prim_count += count_primitives(ob->geometry); + prim_count += count_primitives(ob->get_geometry()); } } @@ -429,7 +429,7 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) ++i; continue; } - if (!ob->geometry->is_instanced()) { + if (!ob->get_geometry()->is_instanced()) { add_object(ob, i); } else { @@ -480,15 +480,15 @@ BVHNode *BVHEmbree::widen_children_nodes(const BVHNode * /*root*/) void BVHEmbree::add_object(Object *ob, int i) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_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); if (mesh->num_triangles() > 0) { add_triangles(ob, mesh, i); } } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); if (hair->num_curves() > 0) { add_curves(ob, hair, i); @@ -498,17 +498,17 @@ void BVHEmbree::add_object(Object *ob, int i) void BVHEmbree::add_instance(Object *ob, int i) { - if (!ob || !ob->geometry) { + if (!ob || !ob->get_geometry()) { assert(0); return; } - BVHEmbree *instance_bvh = (BVHEmbree *)(ob->geometry->bvh); + BVHEmbree *instance_bvh = (BVHEmbree *)(ob->get_geometry()->bvh); if (instance_bvh->top_level != this) { instance_bvh->top_level = this; } - const size_t num_object_motion_steps = ob->use_motion() ? ob->motion.size() : 1; + const size_t num_object_motion_steps = ob->use_motion() ? ob->get_motion().size() : 1; const size_t num_motion_steps = min(num_object_motion_steps, RTC_MAX_TIME_STEP_COUNT); assert(num_object_motion_steps <= RTC_MAX_TIME_STEP_COUNT); @@ -517,8 +517,8 @@ void BVHEmbree::add_instance(Object *ob, int i) rtcSetGeometryTimeStepCount(geom_id, num_motion_steps); if (ob->use_motion()) { - array<DecomposedTransform> decomp(ob->motion.size()); - transform_motion_decompose(decomp.data(), ob->motion.data(), ob->motion.size()); + array<DecomposedTransform> decomp(ob->get_motion().size()); + transform_motion_decompose(decomp.data(), ob->get_motion().data(), ob->get_motion().size()); for (size_t step = 0; step < num_motion_steps; ++step) { RTCQuaternionDecomposition rtc_decomp; rtcInitQuaternionDecomposition(&rtc_decomp); @@ -534,7 +534,8 @@ void BVHEmbree::add_instance(Object *ob, int i) } } else { - rtcSetGeometryTransform(geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->tfm); + rtcSetGeometryTransform( + geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->get_tfm()); } pack.prim_index.push_back_slow(-1); @@ -558,7 +559,7 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i) if (mesh->has_motion_blur()) { attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_geometry_motion_steps = mesh->motion_steps; + num_geometry_motion_steps = mesh->get_motion_steps(); } } @@ -620,7 +621,7 @@ void BVHEmbree::set_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh, con if (mesh->has_motion_blur()) { attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_motion_steps = mesh->motion_steps; + num_motion_steps = mesh->get_motion_steps(); t_mid = (num_motion_steps - 1) / 2; if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) { assert(0); @@ -672,7 +673,7 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c if (hair->has_motion_blur()) { attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_motion_steps = hair->motion_steps; + num_motion_steps = hair->get_motion_steps(); } } @@ -689,11 +690,11 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c /* Copy the CV data to Embree */ const int t_mid = (num_motion_steps - 1) / 2; - const float *curve_radius = &hair->curve_radius[0]; + const float *curve_radius = &hair->get_curve_radius()[0]; for (int t = 0; t < num_motion_steps; ++t) { const float3 *verts; if (t == t_mid || attr_mP == NULL) { - verts = &hair->curve_keys[0]; + verts = &hair->get_curve_keys()[0]; } else { int t_ = (t > t_mid) ? (t - 1) : t; @@ -741,7 +742,7 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) if (hair->has_motion_blur()) { attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_geometry_motion_steps = hair->motion_steps; + num_geometry_motion_steps = hair->get_motion_steps(); } } @@ -826,7 +827,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) for (size_t i = 0; i < pack.prim_index.size(); ++i) { if (pack.prim_index[i] != -1) { - pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset; + pack.prim_index[i] += objects[pack.prim_object[i]]->get_geometry()->prim_offset; } } @@ -843,7 +844,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) map<Geometry *, int> geometry_map; foreach (Object *ob, objects) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); BVH *bvh = geom->bvh; if (geom->need_build_bvh(BVH_LAYOUT_EMBREE)) { @@ -873,7 +874,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) /* merge */ foreach (Object *ob, objects) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); /* We assume that if mesh doesn't need own BVH it was already included * into a top-level BVH and no packing here is needed. @@ -948,10 +949,10 @@ void BVHEmbree::refit_nodes() /* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */ unsigned geom_id = 0; foreach (Object *ob, objects) { - if (!params.top_level || (ob->is_traceable() && !ob->geometry->is_instanced())) { - Geometry *geom = ob->geometry; + if (!params.top_level || (ob->is_traceable() && !ob->get_geometry()->is_instanced())) { + Geometry *geom = ob->get_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); if (mesh->num_triangles() > 0) { RTCGeometry geom = rtcGetGeometry(scene, geom_id); @@ -959,7 +960,7 @@ void BVHEmbree::refit_nodes() rtcCommitGeometry(geom); } } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); if (hair->num_curves() > 0) { RTCGeometry geom = rtcGetGeometry(scene, geom_id + 1); diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp index f2666688123..52fc9c0a50d 100644 --- a/intern/cycles/bvh/bvh_optix.cpp +++ b/intern/cycles/bvh/bvh_optix.cpp @@ -69,7 +69,7 @@ void BVHOptiX::pack_blas() assert(geometry.size() == 1 && objects.size() == 1); // These are built per-mesh Geometry *const geom = geometry[0]; - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *const hair = static_cast<Hair *const>(geom); if (hair->num_curves() > 0) { const size_t num_curves = hair->num_curves(); @@ -80,7 +80,7 @@ void BVHOptiX::pack_blas() // 'pack.prim_time' is only used in geom_curve_intersect.h // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH - uint type = (hair->use_motion_blur && + uint type = (hair->get_use_motion_blur() && hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) ? ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON : PRIMITIVE_MOTION_CURVE_THICK) : @@ -98,7 +98,7 @@ void BVHOptiX::pack_blas() } } } - else if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + else if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *const mesh = static_cast<Mesh *const>(geom); if (mesh->num_triangles() > 0) { const size_t num_triangles = mesh->num_triangles(); @@ -107,7 +107,7 @@ void BVHOptiX::pack_blas() pack.prim_object.reserve(pack.prim_object.size() + num_triangles); uint type = PRIMITIVE_TRIANGLE; - if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) + if (mesh->get_use_motion_blur() && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) type = PRIMITIVE_MOTION_TRIANGLE; for (size_t k = 0; k < num_triangles; ++k) { @@ -119,14 +119,14 @@ void BVHOptiX::pack_blas() } // Initialize visibility to zero and later update it during top-level build - uint prev_visibility = objects[0]->visibility; - objects[0]->visibility = 0; + uint prev_visibility = objects[0]->get_visibility(); + objects[0]->set_visibility(0); // Update 'pack.prim_tri_index', 'pack.prim_tri_verts' and 'pack.prim_visibility' pack_primitives(); // Reset visibility after packing - objects[0]->visibility = prev_visibility; + objects[0]->set_visibility(prev_visibility); } void BVHOptiX::pack_tlas() @@ -170,7 +170,7 @@ void BVHOptiX::pack_tlas() int object_index = 0; // Unused for instanced geometry int object_visibility = 0; foreach (Object *ob, objects) { - if (ob->geometry == geom) { + if (ob->get_geometry() == geom) { object_visibility |= ob->visibility_for_tracing(); if (!geom->is_instanced()) { object_index = ob->get_device_index(); diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 2f1960d664e..834b07440d8 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -392,8 +392,8 @@ void BVHSpatialSplit::split_curve_primitive(const Hair *hair, Hair::Curve curve = hair->get_curve(prim_index); const int k0 = curve.first_key + segment_index; const int k1 = k0 + 1; - float3 v0 = hair->curve_keys[k0]; - float3 v1 = hair->curve_keys[k1]; + float3 v0 = hair->get_curve_keys()[k0]; + float3 v1 = hair->get_curve_keys()[k1]; if (tfm != NULL) { v0 = transform_point(tfm, v0); @@ -456,21 +456,22 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference &ref, void BVHSpatialSplit::split_object_reference( const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds) { - Geometry *geom = object->geometry; + Geometry *geom = object->get_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 (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) { - split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds); + split_triangle_primitive( + mesh, &object->get_tfm(), tri_idx, dim, pos, left_bounds, right_bounds); } } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); for (int curve_idx = 0; curve_idx < hair->num_curves(); ++curve_idx) { Hair::Curve curve = hair->get_curve(curve_idx); for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) { split_curve_primitive( - hair, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds); + hair, &object->get_tfm(), curve_idx, segment_idx, dim, pos, left_bounds, right_bounds); } } } @@ -491,11 +492,11 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder, const Object *ob = builder.objects[ref.prim_object()]; if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { - Mesh *mesh = static_cast<Mesh *>(ob->geometry); + Mesh *mesh = static_cast<Mesh *>(ob->get_geometry()); split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds); } else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) { - Hair *hair = static_cast<Hair *>(ob->geometry); + Hair *hair = static_cast<Hair *>(ob->get_geometry()); split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds); } else { diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp index c969b361643..38e55307848 100644 --- a/intern/cycles/bvh/bvh_unaligned.cpp +++ b/intern/cycles/bvh/bvh_unaligned.cpp @@ -72,10 +72,10 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) { const int curve_index = ref.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); - const Hair *hair = static_cast<const Hair *>(object->geometry); + const Hair *hair = static_cast<const Hair *>(object->get_geometry()); const Hair::Curve &curve = hair->get_curve(curve_index); const int key = curve.first_key + segment; - const float3 v1 = hair->curve_keys[key], v2 = hair->curve_keys[key + 1]; + const float3 v1 = hair->get_curve_keys()[key], v2 = hair->get_curve_keys()[key + 1]; float length; const float3 axis = normalize_len(v2 - v1, &length); if (length > 1e-6f) { @@ -98,10 +98,10 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim, if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) { const int curve_index = prim.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); - const Hair *hair = static_cast<const Hair *>(object->geometry); + const Hair *hair = static_cast<const Hair *>(object->get_geometry()); const Hair::Curve &curve = hair->get_curve(curve_index); curve.bounds_grow( - segment, &hair->curve_keys[0], &hair->curve_radius[0], aligned_space, bounds); + segment, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], aligned_space, bounds); } else { bounds = prim.bounds().transformed(&aligned_space); diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp index 5558354d03c..95234845f98 100644 --- a/intern/cycles/device/device_optix.cpp +++ b/intern/cycles/device/device_optix.cpp @@ -1211,7 +1211,7 @@ class OptiXDevice : public CUDADevice { // Note: Always keep this logic in sync with bvh_optix.cpp! for (Object *ob : bvh->objects) { // Skip geometry for which acceleration structure already exists - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); if (geometry.find(geom) != geometry.end()) continue; @@ -1230,9 +1230,9 @@ class OptiXDevice : public CUDADevice { operation = OPTIX_BUILD_OPERATION_BUILD; } - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { // Build BLAS for curve primitives - Hair *const hair = static_cast<Hair *const>(ob->geometry); + Hair *const hair = static_cast<Hair *const>(ob->get_geometry()); if (hair->num_curves() == 0) { continue; } @@ -1241,8 +1241,8 @@ class OptiXDevice : public CUDADevice { size_t num_motion_steps = 1; Attribute *motion_keys = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (motion_blur && hair->use_motion_blur && motion_keys) { - num_motion_steps = hair->motion_steps; + if (motion_blur && hair->get_use_motion_blur() && motion_keys) { + num_motion_steps = hair->get_motion_steps(); } device_vector<OptixAabb> aabb_data(this, "temp_aabb_data", MEM_READ_ONLY); @@ -1262,16 +1262,19 @@ class OptiXDevice : public CUDADevice { // Get AABBs for each motion step for (size_t step = 0; step < num_motion_steps; ++step) { // The center step for motion vertices is not stored in the attribute - const float3 *keys = hair->curve_keys.data(); + const float3 *keys = hair->get_curve_keys().data(); size_t center_step = (num_motion_steps - 1) / 2; if (step != center_step) { size_t attr_offset = (step > center_step) ? step - 1 : step; // Technically this is a float4 array, but sizeof(float3) is the same as sizeof(float4) - keys = motion_keys->data_float3() + attr_offset * hair->curve_keys.size(); + keys = motion_keys->data_float3() + attr_offset * hair->get_curve_keys().size(); } for (size_t j = 0, i = 0; j < hair->num_curves(); ++j) { const Hair::Curve curve = hair->get_curve(j); +# if OPTIX_ABI_VERSION >= 36 + const array<float> &curve_radius = hair->get_curve_radius(); +# endif for (int segment = 0; segment < curve.num_segments(); ++segment, ++i) { # if OPTIX_ABI_VERSION >= 36 @@ -1284,10 +1287,8 @@ class OptiXDevice : public CUDADevice { const float4 px = make_float4(keys[ka].x, keys[k0].x, keys[k1].x, keys[kb].x); const float4 py = make_float4(keys[ka].y, keys[k0].y, keys[k1].y, keys[kb].y); const float4 pz = make_float4(keys[ka].z, keys[k0].z, keys[k1].z, keys[kb].z); - const float4 pw = make_float4(hair->curve_radius[ka], - hair->curve_radius[k0], - hair->curve_radius[k1], - hair->curve_radius[kb]); + const float4 pw = make_float4( + curve_radius[ka], curve_radius[k0], curve_radius[k1], curve_radius[kb]); // Convert Catmull-Rom data to Bezier spline static const float4 cr2bsp0 = make_float4(+7, -4, +5, -2) / 6.f; @@ -1310,7 +1311,7 @@ class OptiXDevice : public CUDADevice { # endif { BoundBox bounds = BoundBox::empty; - curve.bounds_grow(segment, keys, hair->curve_radius.data(), bounds); + curve.bounds_grow(segment, keys, hair->get_curve_radius().data(), bounds); const size_t index = step * num_segments + i; aabb_data[index].minX = bounds.min.x; @@ -1394,7 +1395,7 @@ class OptiXDevice : public CUDADevice { // Allocate memory for new BLAS and build it if (build_optix_bvh(build_input, num_motion_steps, handle, out_data, operation)) { - geometry.insert({ob->geometry, handle}); + geometry.insert({ob->get_geometry(), handle}); static_cast<BVHOptiX *>(geom->bvh)->optix_data_handle = out_data; static_cast<BVHOptiX *>(geom->bvh)->optix_handle = handle; static_cast<BVHOptiX *>(geom->bvh)->do_refit = false; @@ -1403,29 +1404,31 @@ class OptiXDevice : public CUDADevice { return false; } } - else if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + else if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { // Build BLAS for triangle primitives - Mesh *const mesh = static_cast<Mesh *const>(ob->geometry); + Mesh *const mesh = static_cast<Mesh *const>(ob->get_geometry()); if (mesh->num_triangles() == 0) { continue; } - const size_t num_verts = mesh->verts.size(); + const size_t num_verts = mesh->get_verts().size(); size_t num_motion_steps = 1; Attribute *motion_keys = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (motion_blur && mesh->use_motion_blur && motion_keys) { - num_motion_steps = mesh->motion_steps; + if (motion_blur && mesh->get_use_motion_blur() && motion_keys) { + num_motion_steps = mesh->get_motion_steps(); } device_vector<int> index_data(this, "temp_index_data", MEM_READ_ONLY); - index_data.alloc(mesh->triangles.size()); - memcpy(index_data.data(), mesh->triangles.data(), mesh->triangles.size() * sizeof(int)); + index_data.alloc(mesh->get_triangles().size()); + memcpy(index_data.data(), + mesh->get_triangles().data(), + mesh->get_triangles().size() * sizeof(int)); device_vector<float3> vertex_data(this, "temp_vertex_data", MEM_READ_ONLY); vertex_data.alloc(num_verts * num_motion_steps); for (size_t step = 0; step < num_motion_steps; ++step) { - const float3 *verts = mesh->verts.data(); + const float3 *verts = mesh->get_verts().data(); size_t center_step = (num_motion_steps - 1) / 2; // The center step for motion vertices is not stored in the attribute @@ -1468,7 +1471,7 @@ class OptiXDevice : public CUDADevice { // Allocate memory for new BLAS and build it if (build_optix_bvh(build_input, num_motion_steps, handle, out_data, operation)) { - geometry.insert({ob->geometry, handle}); + geometry.insert({ob->get_geometry(), handle}); static_cast<BVHOptiX *>(geom->bvh)->optix_data_handle = out_data; static_cast<BVHOptiX *>(geom->bvh)->optix_handle = handle; static_cast<BVHOptiX *>(geom->bvh)->do_refit = false; @@ -1493,7 +1496,7 @@ class OptiXDevice : public CUDADevice { continue; // Create separate instance for triangle/curve meshes of an object - const auto handle_it = geometry.find(ob->geometry); + const auto handle_it = geometry.find(ob->get_geometry()); if (handle_it == geometry.end()) { continue; } @@ -1523,18 +1526,19 @@ class OptiXDevice : public CUDADevice { // Have to have at least one bit in the mask, or else instance would always be culled instance.visibilityMask = 1; - if (ob->geometry->has_volume) { + if (ob->get_geometry()->has_volume) { // Volumes have a special bit set in the visibility mask so a trace can mask only volumes instance.visibilityMask |= 2; } - if (ob->geometry->type == Geometry::HAIR) { + if (ob->get_geometry()->geometry_type == Geometry::HAIR) { // Same applies to curves (so they can be skipped in local trace calls) instance.visibilityMask |= 4; # if OPTIX_ABI_VERSION >= 36 - if (motion_blur && ob->geometry->has_motion_blur() && DebugFlags().optix.curves_api && - static_cast<const Hair *>(ob->geometry)->curve_shape == CURVE_THICK) { + if (motion_blur && ob->get_geometry()->has_motion_blur() && + DebugFlags().optix.curves_api && + static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) { // Select between motion blur and non-motion blur built-in intersection module instance.sbtOffset = PG_HITD_MOTION - PG_HITD; } @@ -1543,7 +1547,7 @@ class OptiXDevice : public CUDADevice { // Insert motion traversable if object has motion if (motion_blur && ob->use_motion()) { - size_t motion_keys = max(ob->motion.size(), 2) - 2; + size_t motion_keys = max(ob->get_motion().size(), 2) - 2; size_t motion_transform_size = sizeof(OptixSRTMotionTransform) + motion_keys * sizeof(OptixSRTData); @@ -1557,16 +1561,17 @@ class OptiXDevice : public CUDADevice { OptixSRTMotionTransform &motion_transform = *reinterpret_cast<OptixSRTMotionTransform *>( new uint8_t[motion_transform_size]); motion_transform.child = handle; - motion_transform.motionOptions.numKeys = ob->motion.size(); + motion_transform.motionOptions.numKeys = ob->get_motion().size(); motion_transform.motionOptions.flags = OPTIX_MOTION_FLAG_NONE; motion_transform.motionOptions.timeBegin = 0.0f; motion_transform.motionOptions.timeEnd = 1.0f; OptixSRTData *const srt_data = motion_transform.srtData; - array<DecomposedTransform> decomp(ob->motion.size()); - transform_motion_decompose(decomp.data(), ob->motion.data(), ob->motion.size()); + array<DecomposedTransform> decomp(ob->get_motion().size()); + transform_motion_decompose( + decomp.data(), ob->get_motion().data(), ob->get_motion().size()); - for (size_t i = 0; i < ob->motion.size(); ++i) { + for (size_t i = 0; i < ob->get_motion().size(); ++i) { // Scale srt_data[i].sx = decomp[i].y.w; // scale.x.x srt_data[i].sy = decomp[i].z.w; // scale.y.y @@ -1613,9 +1618,9 @@ class OptiXDevice : public CUDADevice { else { instance.traversableHandle = handle; - if (ob->geometry->is_instanced()) { + if (ob->get_geometry()->is_instanced()) { // Set transform matrix - memcpy(instance.transform, &ob->tfm, sizeof(instance.transform)); + memcpy(instance.transform, &ob->get_tfm(), sizeof(instance.transform)); } else { // Disable instance transform if geometry already has it applied to vertex data diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index f239040ee3d..0f073ed9b63 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -52,11 +52,6 @@ Node::~Node() { } -template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket) -{ - return (T &)*(((char *)node) + socket.struct_offset); -} - #ifndef NDEBUG static bool is_socket_float3(const SocketType &socket) { @@ -387,6 +382,87 @@ void Node::copy_value(const SocketType &socket, const Node &other, const SocketT } } +void Node::set_value(const SocketType &socket, const Node &other, const SocketType &other_socket) +{ + assert(socket.type == other_socket.type); + (void)other_socket; + + if (socket.is_array()) { + switch (socket.type) { + case SocketType::BOOLEAN_ARRAY: + set(socket, get_socket_value<array<bool>>(&other, socket)); + break; + case SocketType::FLOAT_ARRAY: + set(socket, get_socket_value<array<float>>(&other, socket)); + break; + case SocketType::INT_ARRAY: + set(socket, get_socket_value<array<int>>(&other, socket)); + break; + case SocketType::COLOR_ARRAY: + case SocketType::VECTOR_ARRAY: + case SocketType::POINT_ARRAY: + case SocketType::NORMAL_ARRAY: + set(socket, get_socket_value<array<float3>>(&other, socket)); + break; + case SocketType::POINT2_ARRAY: + set(socket, get_socket_value<array<float2>>(&other, socket)); + break; + case SocketType::STRING_ARRAY: + set(socket, get_socket_value<array<ustring>>(&other, socket)); + break; + case SocketType::TRANSFORM_ARRAY: + set(socket, get_socket_value<array<Transform>>(&other, socket)); + break; + case SocketType::NODE_ARRAY: + set(socket, get_socket_value<array<Node *>>(&other, socket)); + break; + default: + assert(0); + break; + } + } + else { + switch (socket.type) { + case SocketType::BOOLEAN: + set(socket, get_socket_value<bool>(&other, socket)); + break; + case SocketType::FLOAT: + set(socket, get_socket_value<float>(&other, socket)); + break; + case SocketType::INT: + set(socket, get_socket_value<int>(&other, socket)); + break; + case SocketType::UINT: + set(socket, get_socket_value<uint>(&other, socket)); + break; + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::POINT: + case SocketType::NORMAL: + set(socket, get_socket_value<float3>(&other, socket)); + break; + case SocketType::POINT2: + set(socket, get_socket_value<float2>(&other, socket)); + break; + case SocketType::STRING: + set(socket, get_socket_value<ustring>(&other, socket)); + break; + case SocketType::ENUM: + set(socket, get_socket_value<int>(&other, socket)); + break; + case SocketType::TRANSFORM: + set(socket, get_socket_value<Transform>(&other, socket)); + break; + case SocketType::NODE: + set(socket, get_socket_value<Node *>(&other, socket)); + break; + default: + assert(0); + break; + } + } +} + template<typename T> static bool is_array_equal(const Node *node, const Node *other, const SocketType &socket) { diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index 16bd5e4358a..2fc9a1e0281 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -29,6 +29,66 @@ struct Node; struct NodeType; struct Transform; +/* Note: in the following macros we use "type const &" instead of "const type &" + * to avoid issues when pasting a pointer type. */ +#define NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) \ + const SocketType *get_##name##_socket() const \ + { \ + static const SocketType *socket = type->find_input(ustring(string_name)); \ + return socket; \ + } \ + bool name##_is_modified() const \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return socket_is_modified(*socket); \ + } \ + void tag_##name##_modified() \ + { \ + const SocketType *socket = get_##name##_socket(); \ + socket_modified |= socket->modified_flag_bit; \ + } \ + type_ const &get_##name() const \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return get_socket_value<type_>(this, *socket); \ + } + +#define NODE_SOCKET_API_BASE(type_, name, string_name) \ + protected: \ + type_ name; \ +\ + public: \ + NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) + +#define NODE_SOCKET_API(type_, name) \ + NODE_SOCKET_API_BASE(type_, name, #name) \ + void set_##name(type_ value) \ + { \ + const SocketType *socket = get_##name##_socket(); \ + this->set(*socket, value); \ + } + +#define NODE_SOCKET_API_ARRAY(type_, name) \ + NODE_SOCKET_API_BASE(type_, name, #name) \ + void set_##name(type_ &value) \ + { \ + const SocketType *socket = get_##name##_socket(); \ + this->set(*socket, value); \ + } \ + type_ &get_##name() \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return get_socket_value<type_>(this, *socket); \ + } + +#define NODE_SOCKET_API_STRUCT_MEMBER(type_, name, member) \ + NODE_SOCKET_API_BASE_METHODS(type_, name##_##member, #name "." #member) \ + void set_##name##_##member(type_ value) \ + { \ + const SocketType *socket = get_##name##_##member##_socket(); \ + this->set(*socket, value); \ + } + /* Node */ struct NodeOwner { @@ -88,6 +148,7 @@ struct Node { void set_default_value(const SocketType &input); bool equals_value(const Node &other, const SocketType &input) const; void copy_value(const SocketType &input, const Node &other, const SocketType &other_input); + void set_value(const SocketType &input, const Node &other, const SocketType &other_input); /* equals */ bool equals(const Node &other) const; @@ -119,6 +180,11 @@ struct Node { protected: const NodeOwner *owner; + template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket) + { + return (T &)*(((char *)node) + socket.struct_offset); + } + SocketModifiedFlags socket_modified; template<typename T> void set_if_different(const SocketType &input, T value); diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 05f3d619989..b478aae9ae2 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -167,62 +167,62 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const size = 1; break; case ATTR_ELEMENT_VERTEX: - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); - size = mesh->verts.size() + mesh->num_ngons; + size = mesh->get_verts().size() + mesh->get_num_ngons(); if (prim == ATTR_PRIM_SUBD) { - size -= mesh->num_subd_verts; + size -= mesh->get_num_subd_verts(); } } break; case ATTR_ELEMENT_VERTEX_MOTION: - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); - size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1); + size = (mesh->get_verts().size() + mesh->get_num_ngons()) * (mesh->get_motion_steps() - 1); if (prim == ATTR_PRIM_SUBD) { - size -= mesh->num_subd_verts * (mesh->motion_steps - 1); + size -= mesh->get_num_subd_verts() * (mesh->get_motion_steps() - 1); } } break; case ATTR_ELEMENT_FACE: - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); if (prim == ATTR_PRIM_GEOMETRY) { size = mesh->num_triangles(); } else { - size = mesh->subd_faces.size() + mesh->num_ngons; + size = mesh->get_num_subd_faces() + mesh->get_num_ngons(); } } break; case ATTR_ELEMENT_CORNER: case ATTR_ELEMENT_CORNER_BYTE: - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); if (prim == ATTR_PRIM_GEOMETRY) { size = mesh->num_triangles() * 3; } else { - size = mesh->subd_face_corners.size() + mesh->num_ngons; + size = mesh->get_subd_face_corners().size() + mesh->get_num_ngons(); } } break; case ATTR_ELEMENT_CURVE: - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); size = hair->num_curves(); } break; case ATTR_ELEMENT_CURVE_KEY: - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); - size = hair->curve_keys.size(); + size = hair->get_curve_keys().size(); } break; case ATTR_ELEMENT_CURVE_KEY_MOTION: - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); - size = hair->curve_keys.size() * (hair->motion_steps - 1); + size = hair->get_curve_keys().size() * (hair->get_motion_steps() - 1); } break; default: @@ -445,7 +445,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) if (name == ustring()) name = Attribute::standard_name(std); - if (geometry->type == Geometry::MESH) { + if (geometry->geometry_type == Geometry::MESH) { switch (std) { case ATTR_STD_VERTEX_NORMAL: attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX); @@ -496,7 +496,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) break; } } - else if (geometry->type == Geometry::VOLUME) { + else if (geometry->geometry_type == Geometry::VOLUME) { switch (std) { case ATTR_STD_VERTEX_NORMAL: attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX); @@ -521,7 +521,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) break; } } - else if (geometry->type == Geometry::HAIR) { + else if (geometry->geometry_type == Geometry::HAIR) { switch (std) { case ATTR_STD_UV: attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE); diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp index d2463454522..7bdcb1578c3 100644 --- a/intern/cycles/render/background.cpp +++ b/intern/cycles/render/background.cpp @@ -54,7 +54,6 @@ NODE_DEFINE(Background) Background::Background() : Node(node_type) { - need_update = true; shader = NULL; } @@ -64,7 +63,7 @@ Background::~Background() void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -102,7 +101,7 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene else kbackground->volume_shader = SHADER_NONE; - kbackground->volume_step_size = volume_step_size * scene->integrator->volume_step_rate; + kbackground->volume_step_size = volume_step_size * scene->integrator->get_volume_step_rate(); /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */ if (bg_shader->graph->nodes.size() <= 1) { @@ -122,22 +121,17 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA; } - need_update = false; + clear_modified(); } void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/) { } -bool Background::modified(const Background &background) -{ - return !Node::equals(background); -} - void Background::tag_update(Scene *scene) { scene->integrator->tag_update(scene); - need_update = true; + tag_modified(); } Shader *Background::get_shader(const Scene *scene) diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h index c2ca1f75179..e89ffbc2445 100644 --- a/intern/cycles/render/background.h +++ b/intern/cycles/render/background.h @@ -32,22 +32,20 @@ class Background : public Node { public: NODE_DECLARE - float ao_factor; - float ao_distance; + NODE_SOCKET_API(float, ao_factor) + NODE_SOCKET_API(float, ao_distance) - bool use_shader; - bool use_ao; + NODE_SOCKET_API(bool, use_shader) + NODE_SOCKET_API(bool, use_ao) - uint visibility; - Shader *shader; + NODE_SOCKET_API(uint, visibility) + NODE_SOCKET_API(Shader *, shader) - bool transparent; - bool transparent_glass; - float transparent_roughness_threshold; + NODE_SOCKET_API(bool, transparent) + NODE_SOCKET_API(bool, transparent_glass) + NODE_SOCKET_API(float, transparent_roughness_threshold) - float volume_step_size; - - bool need_update; + NODE_SOCKET_API(float, volume_step_size) Background(); ~Background(); @@ -55,7 +53,6 @@ class Background : public Node { void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene); - bool modified(const Background &background); void tag_update(Scene *scene); Shader *get_shader(const Scene *scene); diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index 05f52159671..439ebdedb8e 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -33,10 +33,11 @@ static int aa_samples(Scene *scene, Object *object, ShaderEvalType type) } else if (type == SHADER_EVAL_NORMAL) { /* Only antialias normal if mesh has bump mapping. */ - if (object->geometry) { - foreach (Shader *shader, object->geometry->used_shaders) { + if (object->get_geometry()) { + foreach (Node *node, object->get_geometry()->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_bump) { - return scene->integrator->aa_samples; + return scene->integrator->get_aa_samples(); } } } @@ -44,7 +45,7 @@ static int aa_samples(Scene *scene, Object *object, ShaderEvalType type) return 1; } else { - return scene->integrator->aa_samples; + return scene->integrator->get_aa_samples(); } } @@ -112,7 +113,7 @@ void BakeManager::set(Scene *scene, } /* create device and update scene */ - scene->film->tag_update(scene); + scene->film->tag_modified(); scene->integrator->tag_update(scene); need_update = true; @@ -140,8 +141,8 @@ void BakeManager::device_update(Device * /*device*/, int object_index = 0; foreach (Object *object, scene->objects) { - const Geometry *geom = object->geometry; - if (object->name == object_name && geom->type == Geometry::MESH) { + const Geometry *geom = object->get_geometry(); + if (object->name == object_name && geom->geometry_type == Geometry::MESH) { kbake->object_index = object_index; kbake->tri_offset = geom->prim_offset; kintegrator->aa_samples = aa_samples(scene, object, type); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 0f2befae320..92cf712d32a 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -98,7 +98,7 @@ NODE_DEFINE(Camera) type_enum.insert("perspective", CAMERA_PERSPECTIVE); type_enum.insert("orthograph", CAMERA_ORTHOGRAPHIC); type_enum.insert("panorama", CAMERA_PANORAMA); - SOCKET_ENUM(type, "Type", type_enum, CAMERA_PERSPECTIVE); + SOCKET_ENUM(camera_type, "Type", type_enum, CAMERA_PERSPECTIVE); static NodeEnum panorama_type_enum; panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR); @@ -148,8 +148,18 @@ NODE_DEFINE(Camera) SOCKET_FLOAT(border.bottom, "Border Bottom", 0); SOCKET_FLOAT(border.top, "Border Top", 0); + SOCKET_FLOAT(viewport_camera_border.left, "Viewport Border Left", 0); + SOCKET_FLOAT(viewport_camera_border.right, "Viewport Border Right", 0); + SOCKET_FLOAT(viewport_camera_border.bottom, "Viewport Border Bottom", 0); + SOCKET_FLOAT(viewport_camera_border.top, "Viewport Border Top", 0); + SOCKET_FLOAT(offscreen_dicing_scale, "Offscreen Dicing Scale", 1.0f); + SOCKET_INT(full_width, "Full Width", 1024); + SOCKET_INT(full_height, "Full Height", 512); + + SOCKET_BOOLEAN(use_perspective_motion, "Use Perspective Motion", false); + return type; } @@ -182,7 +192,6 @@ Camera::Camera() : Node(node_type) dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); - need_update = true; need_device_update = true; need_flags_update = true; previous_need_motion = -1; @@ -196,7 +205,7 @@ Camera::~Camera() void Camera::compute_auto_viewplane() { - if (type == CAMERA_PANORAMA) { + if (camera_type == CAMERA_PANORAMA) { viewplane.left = 0.0f; viewplane.right = 1.0f; viewplane.bottom = 0.0f; @@ -230,7 +239,7 @@ void Camera::update(Scene *scene) need_device_update = true; } - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -257,9 +266,9 @@ void Camera::update(Scene *scene) /* screen to camera */ ProjectionTransform cameratoscreen; - if (type == CAMERA_PERSPECTIVE) + if (camera_type == CAMERA_PERSPECTIVE) cameratoscreen = projection_perspective(fov, nearclip, farclip); - else if (type == CAMERA_ORTHOGRAPHIC) + else if (camera_type == CAMERA_ORTHOGRAPHIC) cameratoscreen = projection_orthographic(nearclip, farclip); else cameratoscreen = projection_identity(); @@ -284,13 +293,13 @@ void Camera::update(Scene *scene) worldtoraster = ndctoraster * worldtondc; /* differentials */ - if (type == CAMERA_ORTHOGRAPHIC) { + if (camera_type == CAMERA_ORTHOGRAPHIC) { dx = transform_perspective_direction(&rastertocamera, make_float3(1, 0, 0)); dy = transform_perspective_direction(&rastertocamera, make_float3(0, 1, 0)); full_dx = transform_perspective_direction(&full_rastertocamera, make_float3(1, 0, 0)); full_dy = transform_perspective_direction(&full_rastertocamera, make_float3(0, 1, 0)); } - else if (type == CAMERA_PERSPECTIVE) { + else if (camera_type == CAMERA_PERSPECTIVE) { dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) - transform_perspective(&rastertocamera, make_float3(0, 0, 0)); dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) - @@ -310,7 +319,7 @@ void Camera::update(Scene *scene) full_dx = transform_direction(&cameratoworld, full_dx); full_dy = transform_direction(&cameratoworld, full_dy); - if (type == CAMERA_PERSPECTIVE) { + if (camera_type == CAMERA_PERSPECTIVE) { float3 v = transform_perspective(&full_rastertocamera, make_float3(full_width, full_height, 1.0f)); frustum_right_normal = normalize(make_float3(v.z, 0.0f, -v.x)); @@ -348,7 +357,7 @@ void Camera::update(Scene *scene) if (need_motion == Scene::MOTION_PASS) { /* TODO(sergey): Support perspective (zoom, fov) motion. */ - if (type == CAMERA_PANORAMA) { + if (camera_type == CAMERA_PANORAMA) { if (have_motion) { kcam->motion_pass_pre = transform_inverse(motion[0]); kcam->motion_pass_post = transform_inverse(motion[motion.size() - 1]); @@ -377,7 +386,7 @@ void Camera::update(Scene *scene) } /* TODO(sergey): Support other types of camera. */ - if (use_perspective_motion && type == CAMERA_PERSPECTIVE) { + if (use_perspective_motion && camera_type == CAMERA_PERSPECTIVE) { /* TODO(sergey): Move to an utility function and de-duplicate with * calculation above. */ @@ -402,7 +411,7 @@ void Camera::update(Scene *scene) kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime : -1.0f; /* type */ - kcam->type = type; + kcam->type = camera_type; /* anamorphic lens bokeh */ kcam->inv_aperture_ratio = 1.0f / aperture_ratio; @@ -464,7 +473,7 @@ void Camera::update(Scene *scene) kcam->rolling_shutter_duration = rolling_shutter_duration; /* Set further update flags */ - need_update = false; + clear_modified(); need_device_update = true; need_flags_update = true; previous_need_motion = need_motion; @@ -527,7 +536,7 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen [&](const blocked_range<size_t> &r) { for (size_t i = r.begin(); i != r.end(); i++) { Object *object = scene->objects[i]; - if (object->geometry->has_volume && + if (object->get_geometry()->has_volume && viewplane_boundbox.intersects(object->bounds)) { /* TODO(sergey): Consider adding more grained check. */ VLOG(1) << "Detected camera inside volume."; @@ -553,25 +562,10 @@ void Camera::device_free(Device * /*device*/, DeviceScene *dscene, Scene *scene) dscene->camera_motion.free(); } -bool Camera::modified(const Camera &cam) -{ - return !Node::equals(cam); -} - -bool Camera::motion_modified(const Camera &cam) -{ - return !((motion == cam.motion) && (use_perspective_motion == cam.use_perspective_motion)); -} - -void Camera::tag_update() -{ - need_update = true; -} - float3 Camera::transform_raster_to_world(float raster_x, float raster_y) { float3 D, P; - if (type == CAMERA_PERSPECTIVE) { + if (camera_type == CAMERA_PERSPECTIVE) { D = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); float3 Pclip = normalize(D); P = make_float3(0.0f, 0.0f, 0.0f); @@ -584,7 +578,7 @@ float3 Camera::transform_raster_to_world(float raster_x, float raster_y) */ P += nearclip * D / Pclip.z; } - else if (type == CAMERA_ORTHOGRAPHIC) { + else if (camera_type == CAMERA_ORTHOGRAPHIC) { D = make_float3(0.0f, 0.0f, 1.0f); /* TODO(sergey): Aperture support? */ P = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); @@ -603,7 +597,7 @@ BoundBox Camera::viewplane_bounds_get() * checks we need in a more clear and smart fashion? */ BoundBox bounds = BoundBox::empty; - if (type == CAMERA_PANORAMA) { + if (camera_type == CAMERA_PANORAMA) { if (use_spherical_stereo == false) { bounds.grow(make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w)); } @@ -628,7 +622,7 @@ BoundBox Camera::viewplane_bounds_get() bounds.grow(transform_raster_to_world(0.0f, (float)height)); bounds.grow(transform_raster_to_world((float)width, (float)height)); bounds.grow(transform_raster_to_world((float)width, 0.0f)); - if (type == CAMERA_PERSPECTIVE) { + if (camera_type == CAMERA_PERSPECTIVE) { /* Center point has the most distance in local Z axis, * use it to construct bounding box/ */ @@ -642,7 +636,7 @@ float Camera::world_to_raster_size(float3 P) { float res = 1.0f; - if (type == CAMERA_ORTHOGRAPHIC) { + if (camera_type == CAMERA_ORTHOGRAPHIC) { res = min(len(full_dx), len(full_dy)); if (offscreen_dicing_scale > 1.0f) { @@ -668,7 +662,7 @@ float Camera::world_to_raster_size(float3 P) } } } - else if (type == CAMERA_PERSPECTIVE) { + else if (camera_type == CAMERA_PERSPECTIVE) { /* Calculate as if point is directly ahead of the camera. */ float3 raster = make_float3(0.5f * full_width, 0.5f * full_height, 0.0f); float3 Pcamera = transform_perspective(&full_rastertocamera, raster); @@ -743,7 +737,7 @@ float Camera::world_to_raster_size(float3 P) } } } - else if (type == CAMERA_PANORAMA) { + else if (camera_type == CAMERA_PANORAMA) { float3 D = transform_point(&worldtocamera, P); float dist = len(D); @@ -794,6 +788,16 @@ bool Camera::use_motion() const return motion.size() > 1; } +void Camera::set_screen_size_and_resolution(int width_, int height_, int resolution_) +{ + if (width_ != width || height_ != height || resolution_ != resolution) { + width = width_; + height = height_; + resolution = resolution_; + tag_modified(); + } +} + float Camera::motion_time(int step) const { return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f; diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 21dad5eea3b..7970381f338 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -73,78 +73,92 @@ class Camera : public Node { }; /* motion blur */ - float shuttertime; - MotionPosition motion_position; - array<float> shutter_curve; + NODE_SOCKET_API(float, shuttertime) + NODE_SOCKET_API(MotionPosition, motion_position) + NODE_SOCKET_API_ARRAY(array<float>, shutter_curve) size_t shutter_table_offset; /* ** Rolling shutter effect. ** */ /* Defines rolling shutter effect type. */ - RollingShutterType rolling_shutter_type; + NODE_SOCKET_API(RollingShutterType, rolling_shutter_type) /* Specifies exposure time of scanlines when using * rolling shutter effect. */ - float rolling_shutter_duration; + NODE_SOCKET_API(float, rolling_shutter_duration) /* depth of field */ - float focaldistance; - float aperturesize; - uint blades; - float bladesrotation; + NODE_SOCKET_API(float, focaldistance) + NODE_SOCKET_API(float, aperturesize) + NODE_SOCKET_API(uint, blades) + NODE_SOCKET_API(float, bladesrotation) /* type */ - CameraType type; - float fov; + NODE_SOCKET_API(CameraType, camera_type) + NODE_SOCKET_API(float, fov) /* panorama */ - PanoramaType panorama_type; - float fisheye_fov; - float fisheye_lens; - float latitude_min; - float latitude_max; - float longitude_min; - float longitude_max; + NODE_SOCKET_API(PanoramaType, panorama_type) + NODE_SOCKET_API(float, fisheye_fov) + NODE_SOCKET_API(float, fisheye_lens) + NODE_SOCKET_API(float, latitude_min) + NODE_SOCKET_API(float, latitude_max) + NODE_SOCKET_API(float, longitude_min) + NODE_SOCKET_API(float, longitude_max) /* panorama stereo */ - StereoEye stereo_eye; - bool use_spherical_stereo; - float interocular_distance; - float convergence_distance; - bool use_pole_merge; - float pole_merge_angle_from; - float pole_merge_angle_to; + NODE_SOCKET_API(StereoEye, stereo_eye) + NODE_SOCKET_API(bool, use_spherical_stereo) + NODE_SOCKET_API(float, interocular_distance) + NODE_SOCKET_API(float, convergence_distance) + NODE_SOCKET_API(bool, use_pole_merge) + NODE_SOCKET_API(float, pole_merge_angle_from) + NODE_SOCKET_API(float, pole_merge_angle_to) /* anamorphic lens bokeh */ - float aperture_ratio; + NODE_SOCKET_API(float, aperture_ratio) /* sensor */ - float sensorwidth; - float sensorheight; + NODE_SOCKET_API(float, sensorwidth) + NODE_SOCKET_API(float, sensorheight) /* clipping */ - float nearclip; - float farclip; + NODE_SOCKET_API(float, nearclip) + NODE_SOCKET_API(float, farclip) /* screen */ - int width, height; - int resolution; BoundBox2D viewplane; + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, left) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, right) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, bottom) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, top) + /* width and height change during preview, so we need these for calculating dice rates. */ - int full_width, full_height; + NODE_SOCKET_API(int, full_width) + NODE_SOCKET_API(int, full_height) /* controls how fast the dicing rate falls off for geometry out side of view */ - float offscreen_dicing_scale; + NODE_SOCKET_API(float, offscreen_dicing_scale) /* border */ BoundBox2D border; + NODE_SOCKET_API_STRUCT_MEMBER(float, border, left) + NODE_SOCKET_API_STRUCT_MEMBER(float, border, right) + NODE_SOCKET_API_STRUCT_MEMBER(float, border, bottom) + NODE_SOCKET_API_STRUCT_MEMBER(float, border, top) + BoundBox2D viewport_camera_border; + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, left) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, right) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, bottom) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, top) /* transformation */ - Transform matrix; + NODE_SOCKET_API(Transform, matrix) /* motion */ - array<Transform> motion; - bool use_perspective_motion; - float fov_pre, fov_post; + NODE_SOCKET_API_ARRAY(array<Transform>, motion) + NODE_SOCKET_API(bool, use_perspective_motion) + NODE_SOCKET_API(float, fov_pre) + NODE_SOCKET_API(float, fov_post) /* computed camera parameters */ ProjectionTransform screentoworld; @@ -174,7 +188,6 @@ class Camera : public Node { float3 frustum_bottom_normal; /* update */ - bool need_update; bool need_device_update; bool need_flags_update; int previous_need_motion; @@ -183,6 +196,12 @@ class Camera : public Node { KernelCamera kernel_camera; array<DecomposedTransform> kernel_camera_motion; + private: + int width; + int height; + int resolution; + + public: /* functions */ Camera(); ~Camera(); @@ -195,10 +214,6 @@ class Camera : public Node { void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene, Scene *scene); - bool modified(const Camera &cam); - bool motion_modified(const Camera &cam); - void tag_update(); - /* Public utility functions. */ BoundBox viewplane_bounds_get(); @@ -210,6 +225,8 @@ class Camera : public Node { int motion_step(float time) const; bool use_motion() const; + void set_screen_size_and_resolution(int width_, int height_, int resolution_); + private: /* Private utility functions. */ float3 transform_raster_to_world(float raster_x, float raster_y); diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index e4c1e452bd5..5c3778f6ae5 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -40,10 +40,8 @@ static bool compare_pass_order(const Pass &a, const Pass &b) return (a.components > b.components); } -NODE_DEFINE(Pass) +static NodeEnum *get_pass_type_enum() { - NodeType *type = NodeType::add("pass", create); - static NodeEnum pass_type_enum; pass_type_enum.insert("combined", PASS_COMBINED); pass_type_enum.insert("depth", PASS_DEPTH); @@ -84,7 +82,15 @@ NODE_DEFINE(Pass) pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE); pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL); - SOCKET_ENUM(type, "Type", pass_type_enum, PASS_COMBINED); + return &pass_type_enum; +} + +NODE_DEFINE(Pass) +{ + NodeType *type = NodeType::add("pass", create); + + NodeEnum *pass_type_enum = get_pass_type_enum(); + SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED); SOCKET_STRING(name, "Name", ustring()); return type; @@ -383,6 +389,21 @@ NODE_DEFINE(Film) SOCKET_INT(denoising_flags, "Denoising Flags", 0); SOCKET_BOOLEAN(use_adaptive_sampling, "Use Adaptive Sampling", false); + SOCKET_BOOLEAN(use_light_visibility, "Use Light Visibility", false); + + NodeEnum *pass_type_enum = get_pass_type_enum(); + SOCKET_ENUM(display_pass, "Display Pass", *pass_type_enum, PASS_COMBINED); + + static NodeEnum cryptomatte_passes_enum; + cryptomatte_passes_enum.insert("none", CRYPT_NONE); + cryptomatte_passes_enum.insert("object", CRYPT_OBJECT); + cryptomatte_passes_enum.insert("material", CRYPT_MATERIAL); + cryptomatte_passes_enum.insert("asset", CRYPT_ASSET); + cryptomatte_passes_enum.insert("accurate", CRYPT_ACCURATE); + SOCKET_ENUM(cryptomatte_passes, "Cryptomatte Passes", cryptomatte_passes_enum, CRYPT_NONE); + + SOCKET_INT(cryptomatte_depth, "Cryptomatte Depth", 0); + return type; } @@ -392,8 +413,6 @@ Film::Film() : Node(node_type) filter_table_offset = TABLE_OFFSET_INVALID; cryptomatte_passes = CRYPT_NONE; display_pass = PASS_COMBINED; - - need_update = true; } Film::~Film() @@ -407,7 +426,7 @@ void Film::add_default(Scene *scene) void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -658,7 +677,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) denoising_data_offset = kfilm->pass_denoising_data; denoising_clean_offset = kfilm->pass_denoising_clean; - need_update = false; + clear_modified(); } void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *scene) @@ -666,11 +685,6 @@ void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *sce scene->lookup_tables->remove_table(&filter_table_offset); } -bool Film::modified(const Film &film) -{ - return !Node::equals(film); -} - void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes) { if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) { @@ -691,11 +705,6 @@ void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool upd } } -void Film::tag_update(Scene * /*scene*/) -{ - need_update = true; -} - int Film::get_aov_offset(Scene *scene, string name, bool &is_color) { int num_color = 0, num_value = 0; @@ -719,4 +728,24 @@ int Film::get_aov_offset(Scene *scene, string name, bool &is_color) return -1; } +int Film::get_pass_stride() const +{ + return pass_stride; +} + +int Film::get_denoising_data_offset() const +{ + return denoising_data_offset; +} + +int Film::get_denoising_clean_offset() const +{ + return denoising_clean_offset; +} + +size_t Film::get_filter_table_offset() const +{ + return filter_table_offset; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h index 961058c008e..462a7275491 100644 --- a/intern/cycles/render/film.h +++ b/intern/cycles/render/film.h @@ -60,34 +60,35 @@ class Film : public Node { public: NODE_DECLARE - float exposure; - bool denoising_data_pass; - bool denoising_clean_pass; - bool denoising_prefiltered_pass; - int denoising_flags; - float pass_alpha_threshold; - - PassType display_pass; - int pass_stride; - int denoising_data_offset; - int denoising_clean_offset; + NODE_SOCKET_API(float, exposure) + NODE_SOCKET_API(bool, denoising_data_pass) + NODE_SOCKET_API(bool, denoising_clean_pass) + NODE_SOCKET_API(bool, denoising_prefiltered_pass) + NODE_SOCKET_API(int, denoising_flags) + NODE_SOCKET_API(float, pass_alpha_threshold) - FilterType filter_type; - float filter_width; - size_t filter_table_offset; + NODE_SOCKET_API(PassType, display_pass) - float mist_start; - float mist_depth; - float mist_falloff; + NODE_SOCKET_API(FilterType, filter_type) + NODE_SOCKET_API(float, filter_width) - bool use_light_visibility; - CryptomatteType cryptomatte_passes; - int cryptomatte_depth; + NODE_SOCKET_API(float, mist_start) + NODE_SOCKET_API(float, mist_depth) + NODE_SOCKET_API(float, mist_falloff) - bool use_adaptive_sampling; + NODE_SOCKET_API(bool, use_light_visibility) + NODE_SOCKET_API(CryptomatteType, cryptomatte_passes) + NODE_SOCKET_API(int, cryptomatte_depth) - bool need_update; + NODE_SOCKET_API(bool, use_adaptive_sampling) + private: + int pass_stride; + int denoising_data_offset; + int denoising_clean_offset; + size_t filter_table_offset; + + public: Film(); ~Film(); @@ -97,11 +98,14 @@ class Film : public Node { void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene, Scene *scene); - bool modified(const Film &film); void tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes = true); - void tag_update(Scene *scene); int get_aov_offset(Scene *scene, string name, bool &is_color); + + int get_pass_stride() const; + int get_denoising_data_offset() const; + int get_denoising_clean_offset() const; + size_t get_filter_table_offset() const; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index 7b410a0c5ea..a63fc620c69 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -52,14 +52,14 @@ NODE_ABSTRACT_DEFINE(Geometry) SOCKET_UINT(motion_steps, "Motion Steps", 3); SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false); + SOCKET_NODE_ARRAY(used_shaders, "Shaders", &Shader::node_type); return type; } Geometry::Geometry(const NodeType *node_type, const Type type) - : Node(node_type), type(type), attributes(this, ATTR_PRIM_GEOMETRY) + : Node(node_type), geometry_type(type), attributes(this, ATTR_PRIM_GEOMETRY) { - need_update = true; need_update_rebuild = false; transform_applied = false; @@ -99,9 +99,11 @@ bool Geometry::need_attribute(Scene *scene, AttributeStandard std) if (scene->need_global_attribute(std)) return true; - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); if (shader->attributes.find(std)) return true; + } return false; } @@ -111,9 +113,11 @@ bool Geometry::need_attribute(Scene * /*scene*/, ustring name) if (name == ustring()) return false; - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); if (shader->attributes.find(name)) return true; + } return false; } @@ -122,8 +126,10 @@ AttributeRequestSet Geometry::needed_attributes() { AttributeRequestSet result; - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); result.add(shader->attributes); + } return result; } @@ -171,8 +177,9 @@ bool Geometry::is_instanced() const bool Geometry::has_true_displacement() const { - foreach (Shader *shader, used_shaders) { - if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) { + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); + if (shader->has_displacement && shader->get_displacement_method() != DISPLACE_BUMP) { return true; } } @@ -198,7 +205,7 @@ void Geometry::compute_bvh( msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total); Object object; - object.geometry = this; + object.set_geometry(this); vector<Geometry *> geometry; geometry.push_back(this); @@ -232,7 +239,7 @@ void Geometry::compute_bvh( } } - need_update = false; + clear_modified(); need_update_rebuild = false; } @@ -254,16 +261,18 @@ bool Geometry::has_voxel_attributes() const void Geometry::tag_update(Scene *scene, bool rebuild) { - need_update = true; + tag_modified(); if (rebuild) { need_update_rebuild = true; scene->light_manager->need_update = true; } else { - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_surface_emission) scene->light_manager->need_update = true; + } } scene->geometry_manager->need_update = true; @@ -433,9 +442,9 @@ static void emit_attribute_mapping( emit_attribute_map_entry(attr_map, index, id, req.type, req.desc); - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->subd_faces.size()) { + if (mesh->get_num_subd_faces()) { emit_attribute_map_entry(attr_map, index + 1, id, req.subd_type, req.subd_desc); } } @@ -547,19 +556,19 @@ static void update_attribute_element_size(Geometry *geom, } } -static void update_attribute_element_offset(Geometry *geom, - device_vector<float> &attr_float, - size_t &attr_float_offset, - device_vector<float2> &attr_float2, - size_t &attr_float2_offset, - device_vector<float4> &attr_float3, - size_t &attr_float3_offset, - device_vector<uchar4> &attr_uchar4, - size_t &attr_uchar4_offset, - Attribute *mattr, - AttributePrimitive prim, - TypeDesc &type, - AttributeDescriptor &desc) +void GeometryManager::update_attribute_element_offset(Geometry *geom, + device_vector<float> &attr_float, + size_t &attr_float_offset, + device_vector<float2> &attr_float2, + size_t &attr_float2_offset, + device_vector<float4> &attr_float3, + size_t &attr_float3_offset, + device_vector<uchar4> &attr_uchar4, + size_t &attr_uchar4_offset, + Attribute *mattr, + AttributePrimitive prim, + TypeDesc &type, + AttributeDescriptor &desc) { if (mattr) { /* store element and type */ @@ -631,7 +640,7 @@ static void update_attribute_element_offset(Geometry *geom, /* mesh vertex/curve index is global, not per object, so we sneak * a correction for that in here */ - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK && desc.flags & ATTR_SUBDIVIDED) { @@ -655,7 +664,7 @@ static void update_attribute_element_offset(Geometry *geom, offset -= mesh->corner_offset; } } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); if (element == ATTR_ELEMENT_CURVE) offset -= hair->prim_offset; @@ -690,7 +699,8 @@ void GeometryManager::device_update_attributes(Device *device, geom->index = i; scene->need_global_attributes(geom_attributes[i]); - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); geom_attributes[i].add(shader->attributes); } } @@ -754,7 +764,7 @@ void GeometryManager::device_update_attributes(Device *device, &attr_float3_size, &attr_uchar4_size); - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); Attribute *subd_attr = mesh->subd_attributes.find(req); @@ -816,7 +826,7 @@ void GeometryManager::device_update_attributes(Device *device, req.type, req.desc); - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); Attribute *subd_attr = mesh->subd_attributes.find(req); @@ -919,7 +929,7 @@ void GeometryManager::mesh_calc_offset(Scene *scene) size_t optix_prim_size = 0; foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); mesh->vert_offset = vert_size; @@ -932,8 +942,8 @@ void GeometryManager::mesh_calc_offset(Scene *scene) vert_size += mesh->verts.size(); tri_size += mesh->num_triangles(); - if (mesh->subd_faces.size()) { - Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; + if (mesh->get_num_subd_faces()) { + Mesh::SubdFace last = mesh->get_subd_face(mesh->get_num_subd_faces() - 1); patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; /* patch tables are stored in same array so include them in patch_size */ @@ -943,19 +953,19 @@ void GeometryManager::mesh_calc_offset(Scene *scene) } } - face_size += mesh->subd_faces.size(); + face_size += mesh->get_num_subd_faces(); corner_size += mesh->subd_face_corners.size(); mesh->optix_prim_offset = optix_prim_size; optix_prim_size += mesh->num_triangles(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); hair->curvekey_offset = curve_key_size; hair->prim_offset = curve_size; - curve_key_size += hair->curve_keys.size(); + curve_key_size += hair->get_curve_keys().size(); curve_size += hair->num_curves(); hair->optix_prim_offset = optix_prim_size; @@ -977,14 +987,14 @@ void GeometryManager::device_update_mesh( size_t patch_size = 0; foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); vert_size += mesh->verts.size(); tri_size += mesh->num_triangles(); - if (mesh->subd_faces.size()) { - Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; + if (mesh->get_num_subd_faces()) { + Mesh::SubdFace last = mesh->get_subd_face(mesh->get_num_subd_faces() - 1); patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; /* patch tables are stored in same array so include them in patch_size */ @@ -994,10 +1004,10 @@ void GeometryManager::device_update_mesh( } } } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); - curve_key_size += hair->curve_keys.size(); + curve_key_size += hair->get_curve_keys().size(); curve_size += hair->num_curves(); } } @@ -1011,7 +1021,7 @@ void GeometryManager::device_update_mesh( * really use same semantic of arrays. */ foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); for (size_t i = 0; i < mesh->num_triangles(); ++i) { tri_prim_index[i + mesh->prim_offset] = 3 * (i + mesh->prim_offset); @@ -1039,7 +1049,7 @@ void GeometryManager::device_update_mesh( float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]); mesh->pack_normals(&vnormal[mesh->vert_offset]); @@ -1071,7 +1081,7 @@ void GeometryManager::device_update_mesh( float4 *curves = dscene->curves.alloc(curve_size); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::HAIR) { + if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); hair->pack_curves(scene, &curve_keys[hair->curvekey_offset], @@ -1092,7 +1102,7 @@ void GeometryManager::device_update_mesh( uint *patch_data = dscene->patches.alloc(patch_size); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); mesh->pack_patches(&patch_data[mesh->patch_offset], mesh->vert_offset, @@ -1115,7 +1125,7 @@ void GeometryManager::device_update_mesh( if (for_displacement) { float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); for (size_t i = 0; i < mesh->num_triangles(); ++i) { Mesh::Triangle t = mesh->get_triangle(i); @@ -1242,7 +1252,8 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro foreach (Geometry *geom, scene->geometry) { geom->has_volume = false; - foreach (const Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_volume) { geom->has_volume = true; } @@ -1254,7 +1265,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro /* Re-create volume mesh if we will rebuild or refit the BVH. Note we * should only do it in that case, otherwise the BVH and mesh can go * out of sync. */ - if (geom->need_update && geom->type == Geometry::VOLUME) { + if (geom->is_modified() && geom->geometry_type == Geometry::VOLUME) { /* Create volume meshes if there is voxel data. */ if (!volume_images_updated) { progress.set_status("Updating Meshes Volume Bounds"); @@ -1266,7 +1277,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro create_volume_mesh(volume, progress); } - if (geom->type == Geometry::HAIR) { + if (geom->is_hair()) { /* Set curve shape, still a global scene setting for now. */ Hair *hair = static_cast<Hair *>(geom); hair->curve_shape = scene->params.hair_shape; @@ -1285,9 +1296,10 @@ void GeometryManager::device_update_displacement_images(Device *device, ImageManager *image_manager = scene->image_manager; set<int> bump_images; foreach (Geometry *geom, scene->geometry) { - if (geom->need_update) { - foreach (Shader *shader, geom->used_shaders) { - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + if (geom->is_modified()) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { continue; } foreach (ShaderNode *node, shader->graph->nodes) { @@ -1321,7 +1333,7 @@ void GeometryManager::device_update_volume_images(Device *device, Scene *scene, set<int> volume_images; foreach (Geometry *geom, scene->geometry) { - if (!geom->need_update) { + if (!geom->is_modified()) { continue; } @@ -1370,12 +1382,14 @@ void GeometryManager::device_update(Device *device, }); foreach (Geometry *geom, scene->geometry) { - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->need_update_geometry) - geom->need_update = true; + geom->tag_modified(); } - if (geom->need_update && (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME)) { + if (geom->is_modified() && + (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) { Mesh *mesh = static_cast<Mesh *>(geom); /* Update normals. */ @@ -1387,8 +1401,7 @@ void GeometryManager::device_update(Device *device, } /* Test if we need tessellation. */ - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && - mesh->subd_params) { + if (mesh->need_tesselation()) { total_tess_needed++; } @@ -1413,17 +1426,18 @@ void GeometryManager::device_update(Device *device, }); Camera *dicing_camera = scene->dicing_camera; + dicing_camera->set_screen_size_and_resolution( + dicing_camera->get_full_width(), dicing_camera->get_full_height(), 1); dicing_camera->update(scene); size_t i = 0; foreach (Geometry *geom, scene->geometry) { - if (!(geom->need_update && geom->type == Geometry::MESH)) { + if (!(geom->is_modified() && geom->is_mesh())) { continue; } Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && - mesh->subd_params) { + if (mesh->need_tesselation()) { string msg = "Tessellating "; if (mesh->name == "") msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed); @@ -1500,8 +1514,8 @@ void GeometryManager::device_update(Device *device, }); foreach (Geometry *geom, scene->geometry) { - if (geom->need_update) { - if (geom->type == Geometry::MESH) { + if (geom->is_modified()) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); if (displace(device, dscene, scene, mesh, progress)) { displacement_done = true; @@ -1543,7 +1557,7 @@ void GeometryManager::device_update(Device *device, size_t i = 0; foreach (Geometry *geom, scene->geometry) { - if (geom->need_update) { + if (geom->is_modified()) { pool.push(function_bind( &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh)); if (geom->need_build_bvh(bvh_layout)) { diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h index 6d4364a6454..1c101540464 100644 --- a/intern/cycles/render/geometry.h +++ b/intern/cycles/render/geometry.h @@ -56,13 +56,13 @@ class Geometry : public Node { VOLUME, }; - Type type; + Type geometry_type; /* Attributes */ AttributeSet attributes; /* Shaders */ - vector<Shader *> used_shaders; + NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders) /* Transform */ BoundBox bounds; @@ -71,8 +71,8 @@ class Geometry : public Node { Transform transform_normal; /* Motion Blur */ - uint motion_steps; - bool use_motion_blur; + NODE_SOCKET_API(uint, motion_steps) + NODE_SOCKET_API(bool, use_motion_blur) /* Maximum number of motion steps supported (due to Embree). */ static const uint MAX_MOTION_STEPS = 129; @@ -88,7 +88,6 @@ class Geometry : public Node { bool has_surface_bssrdf; /* Set in the device_update_flags(). */ /* Update Flags */ - bool need_update; bool need_update_rebuild; /* Index into scene->geometry (only valid during update) */ @@ -143,6 +142,16 @@ class Geometry : public Node { bool has_motion_blur() const; bool has_voxel_attributes() const; + bool is_mesh() const + { + return geometry_type == MESH; + } + + bool is_hair() const + { + return geometry_type == HAIR; + } + /* Updates */ void tag_update(Scene *scene, bool rebuild); }; @@ -206,6 +215,21 @@ class GeometryManager { void device_update_displacement_images(Device *device, Scene *scene, Progress &progress); void device_update_volume_images(Device *device, Scene *scene, Progress &progress); + + private: + static void update_attribute_element_offset(Geometry *geom, + device_vector<float> &attr_float, + size_t &attr_float_offset, + device_vector<float2> &attr_float2, + size_t &attr_float2_offset, + device_vector<float4> &attr_float3, + size_t &attr_float3_offset, + device_vector<uchar4> &attr_uchar4, + size_t &attr_uchar4_offset, + Attribute *mattr, + AttributePrimitive prim, + TypeDesc &type, + AttributeDescriptor &desc); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 485d6167ee3..1de48aa8b0d 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -273,8 +273,8 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) if (to->type() == SocketType::CLOSURE) { EmissionNode *emission = create_node<EmissionNode>(); - emission->color = make_float3(1.0f, 1.0f, 1.0f); - emission->strength = 1.0f; + emission->set_color(make_float3(1.0f, 1.0f, 1.0f)); + emission->set_strength(1.0f); convert = add(emission); /* Connect float inputs to Strength to save an additional Falue->Color conversion. */ if (from->type() == SocketType::FLOAT) { @@ -586,7 +586,7 @@ void ShaderGraph::constant_fold(Scene *scene) */ if (has_displacement && !output()->input("Displacement")->link) { ColorNode *value = (ColorNode *)add(create_node<ColorNode>()); - value->value = output()->displacement; + value->set_value(output()->get_displacement()); connect(value->output("Color"), output()->input("Displacement")); } @@ -1003,8 +1003,8 @@ void ShaderGraph::bump_from_displacement(bool use_object_space) /* add bump node and connect copied graphs to it */ BumpNode *bump = (BumpNode *)add(create_node<BumpNode>()); - bump->use_object_space = use_object_space; - bump->distance = 1.0f; + bump->set_use_object_space(use_object_space); + bump->set_distance(1.0f); ShaderOutput *out = displacement_in->link; ShaderOutput *out_center = nodes_center[out->parent]->output(out->name()); @@ -1016,9 +1016,9 @@ void ShaderGraph::bump_from_displacement(bool use_object_space) VectorMathNode *dot_dx = (VectorMathNode *)add(create_node<VectorMathNode>()); VectorMathNode *dot_dy = (VectorMathNode *)add(create_node<VectorMathNode>()); - dot_center->type = NODE_VECTOR_MATH_DOT_PRODUCT; - dot_dx->type = NODE_VECTOR_MATH_DOT_PRODUCT; - dot_dy->type = NODE_VECTOR_MATH_DOT_PRODUCT; + dot_center->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT); + dot_dx->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT); + dot_dy->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT); GeometryNode *geom = (GeometryNode *)add(create_node<GeometryNode>()); connect(geom->output("Normal"), dot_center->input("Vector2")); @@ -1072,7 +1072,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if (fin->link) connect(fin->link, fac_in); else - mix_node->fac = node->get_float(fin->socket_type); + mix_node->set_fac(node->get_float(fin->socket_type)); if (weight_out) connect(weight_out, weight_in); @@ -1107,12 +1107,12 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if (weight_in->link) connect(weight_in->link, math_node->input("Value1")); else - math_node->value1 = weight_value; + math_node->set_value1(weight_value); if (weight_out) connect(weight_out, math_node->input("Value2")); else - math_node->value2 = 1.0f; + math_node->set_value2(1.0f); weight_out = math_node->output("Value"); if (weight_in->link) diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp index 3853604f78a..d67bd209142 100644 --- a/intern/cycles/render/hair.cpp +++ b/intern/cycles/render/hair.cpp @@ -337,12 +337,18 @@ void Hair::add_curve_key(float3 co, float radius) { curve_keys.push_back_reserved(co); curve_radius.push_back_reserved(radius); + + tag_curve_keys_modified(); + tag_curve_radius_modified(); } void Hair::add_curve(int first_key, int shader) { curve_first_key.push_back_reserved(first_key); curve_shader.push_back_reserved(shader); + + tag_curve_first_key_modified(); + tag_curve_shader_modified(); } void Hair::copy_center_to_motion_step(const int motion_step) @@ -474,8 +480,9 @@ void Hair::pack_curves(Scene *scene, for (size_t i = 0; i < curve_num; i++) { Curve curve = get_curve(i); int shader_id = curve_shader[i]; - Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] : - scene->default_surface; + Shader *shader = (shader_id < used_shaders.size()) ? + static_cast<Shader *>(used_shaders[shader_id]) : + scene->default_surface; shader_id = scene->shader_manager->get_shader_id(shader, false); curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset), diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h index bb6fa7fa4d8..32c5b00e879 100644 --- a/intern/cycles/render/hair.h +++ b/intern/cycles/render/hair.h @@ -89,10 +89,10 @@ class Hair : public Geometry { float4 r_keys[4]) const; }; - array<float3> curve_keys; - array<float> curve_radius; - array<int> curve_first_key; - array<int> curve_shader; + NODE_SOCKET_API(array<float3>, curve_keys) + NODE_SOCKET_API(array<float>, curve_radius) + NODE_SOCKET_API(array<int>, curve_first_key) + NODE_SOCKET_API(array<int>, curve_shader) /* BVH */ size_t curvekey_offset; diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index e50e70c8591..3e6ff289c85 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -381,7 +381,7 @@ ImageHandle ImageManager::add_image(const string &filename, const ImageParams &p ImageHandle ImageManager::add_image(const string &filename, const ImageParams ¶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 49a737f5b1f..11c8e240afd 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -132,11 +132,58 @@ NODE_DEFINE(Mesh) SOCKET_INT_ARRAY(shader, "Shader", array<int>()); SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>()); + SOCKET_INT_ARRAY(triangle_patch, "Triangle Patch", array<int>()); + SOCKET_POINT2_ARRAY(vert_patch_uv, "Patch UVs", array<float2>()); + + static NodeEnum subdivision_type_enum; + subdivision_type_enum.insert("none", SUBDIVISION_NONE); + subdivision_type_enum.insert("linear", SUBDIVISION_LINEAR); + subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK); + SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE); + + SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>()); + SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>()); + SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>()); + SOCKET_INT_ARRAY(subd_start_corner, "Subdivision Face Start Corner", array<int>()); + SOCKET_INT_ARRAY(subd_num_corners, "Subdivision Face Corner Count", array<int>()); + SOCKET_INT_ARRAY(subd_shader, "Subdivision Face Shader", array<int>()); + SOCKET_BOOLEAN_ARRAY(subd_smooth, "Subdivision Face Smooth", array<bool>()); + SOCKET_INT_ARRAY(subd_ptex_offset, "Subdivision Face PTex Offset", array<int>()); + SOCKET_INT(num_ngons, "NGons Number", 0); + + /* Subdivisions parameters */ + SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 0.0f) + SOCKET_INT(subd_max_level, "Subdivision Dicing Rate", 0); + SOCKET_TRANSFORM(subd_objecttoworld, "Subdivision Object Transform", transform_identity()); + return type; } -Mesh::Mesh(const NodeType *node_type_, Type geom_type_) - : Geometry(node_type_, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD) +SubdParams *Mesh::get_subd_params() +{ + if (subdivision_type == SubdivisionType::SUBDIVISION_NONE) { + return nullptr; + } + + if (!subd_params) { + subd_params = new SubdParams(this); + } + + subd_params->dicing_rate = subd_dicing_rate; + subd_params->max_level = subd_max_level; + subd_params->objecttoworld = subd_objecttoworld; + + return subd_params; +} + +bool Mesh::need_tesselation() +{ + return get_subd_params() && (verts_is_modified() || subd_dicing_rate_is_modified() || + subd_objecttoworld_is_modified() || subd_max_level_is_modified()); +} + +Mesh::Mesh(const NodeType *node_type, Type geom_type_) + : Geometry(node_type, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD) { vert_offset = 0; @@ -145,6 +192,7 @@ Mesh::Mesh(const NodeType *node_type_, Type geom_type_) corner_offset = 0; num_subd_verts = 0; + num_subd_faces = 0; num_ngons = 0; @@ -171,7 +219,7 @@ void Mesh::resize_mesh(int numverts, int numtris) shader.resize(numtris); smooth.resize(numtris); - if (subd_faces.size()) { + if (get_num_subd_faces()) { triangle_patch.resize(numtris); vert_patch_uv.resize(numverts); } @@ -187,7 +235,7 @@ void Mesh::reserve_mesh(int numverts, int numtris) shader.reserve(numtris); smooth.reserve(numtris); - if (subd_faces.size()) { + if (get_num_subd_faces()) { triangle_patch.reserve(numtris); vert_patch_uv.reserve(numverts); } @@ -197,22 +245,38 @@ void Mesh::reserve_mesh(int numverts, int numtris) void Mesh::resize_subd_faces(int numfaces, int num_ngons_, int numcorners) { - subd_faces.resize(numfaces); + subd_start_corner.resize(numfaces); + subd_num_corners.resize(numfaces); + subd_shader.resize(numfaces); + subd_smooth.resize(numfaces); + subd_ptex_offset.resize(numfaces); subd_face_corners.resize(numcorners); num_ngons = num_ngons_; + num_subd_faces = numfaces; subd_attributes.resize(); } void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners) { - subd_faces.reserve(numfaces); + subd_start_corner.reserve(numfaces); + subd_num_corners.reserve(numfaces); + subd_shader.reserve(numfaces); + subd_smooth.reserve(numfaces); + subd_ptex_offset.reserve(numfaces); subd_face_corners.reserve(numcorners); num_ngons = num_ngons_; + num_subd_faces = numfaces; subd_attributes.resize(true); } +void Mesh::reserve_subd_creases(size_t num_creases) +{ + subd_creases_edge.reserve(num_creases * 2); + subd_creases_weight.reserve(num_creases); +} + void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data) { Geometry::clear(preserve_shaders); @@ -226,12 +290,18 @@ void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data) triangle_patch.clear(); vert_patch_uv.clear(); - subd_faces.clear(); + subd_start_corner.clear(); + subd_num_corners.clear(); + subd_shader.clear(); + subd_smooth.clear(); + subd_ptex_offset.clear(); subd_face_corners.clear(); num_subd_verts = 0; + num_subd_faces = 0; - subd_creases.clear(); + subd_creases_edge.clear(); + subd_creases_weight.clear(); subd_attributes.clear(); attributes.clear(preserve_voxel_data); @@ -239,6 +309,8 @@ void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data) vert_to_stitching_key_map.clear(); vert_stitching_map.clear(); + subdivision_type = SubdivisionType::SUBDIVISION_NONE; + delete patch_table; patch_table = NULL; } @@ -251,18 +323,22 @@ void Mesh::clear(bool preserve_shaders) void Mesh::add_vertex(float3 P) { verts.push_back_reserved(P); + tag_verts_modified(); - if (subd_faces.size()) { + if (get_num_subd_faces()) { vert_patch_uv.push_back_reserved(make_float2(0.0f, 0.0f)); + tag_vert_patch_uv_modified(); } } void Mesh::add_vertex_slow(float3 P) { verts.push_back_slow(P); + tag_verts_modified(); - if (subd_faces.size()) { + if (get_num_subd_faces()) { vert_patch_uv.push_back_slow(make_float2(0.0f, 0.0f)); + tag_vert_patch_uv_modified(); } } @@ -274,8 +350,13 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) shader.push_back_reserved(shader_); smooth.push_back_reserved(smooth_); - if (subd_faces.size()) { + tag_triangles_modified(); + tag_shader_modified(); + tag_smooth_modified(); + + if (get_num_subd_faces()) { triangle_patch.push_back_reserved(-1); + tag_triangle_patch_modified(); } } @@ -288,14 +369,47 @@ void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth } int ptex_offset = 0; - - if (subd_faces.size()) { - SubdFace &s = subd_faces[subd_faces.size() - 1]; + // cannot use get_num_subd_faces here as it holds the total number of subd_faces, but we do not + // have the total amount of data yet + if (subd_shader.size()) { + SubdFace s = get_subd_face(subd_shader.size() - 1); ptex_offset = s.ptex_offset + s.num_ptex_faces(); } - SubdFace face = {start_corner, num_corners, shader_, smooth_, ptex_offset}; - subd_faces.push_back_reserved(face); + subd_start_corner.push_back_reserved(start_corner); + subd_num_corners.push_back_reserved(num_corners); + subd_shader.push_back_reserved(shader_); + subd_smooth.push_back_reserved(smooth_); + subd_ptex_offset.push_back_reserved(ptex_offset); + + tag_subd_face_corners_modified(); + tag_subd_start_corner_modified(); + tag_subd_num_corners_modified(); + tag_subd_shader_modified(); + tag_subd_smooth_modified(); + tag_subd_ptex_offset_modified(); +} + +Mesh::SubdFace Mesh::get_subd_face(size_t index) const +{ + Mesh::SubdFace s; + s.shader = subd_shader[index]; + s.num_corners = subd_num_corners[index]; + s.smooth = subd_smooth[index]; + s.ptex_offset = subd_ptex_offset[index]; + s.start_corner = subd_start_corner[index]; + return s; +} + +void Mesh::add_crease(int v0, int v1, float weight) +{ + subd_creases_edge.push_back_slow(v0); + subd_creases_edge.push_back_slow(v1); + subd_creases_weight.push_back_slow(weight); + + tag_subd_creases_edge_modified(); + tag_subd_creases_edge_modified(); + tag_subd_creases_weight_modified(); } void Mesh::copy_center_to_motion_step(const int motion_step) @@ -505,7 +619,7 @@ void Mesh::add_vertex_normals() } /* subd vertex normals */ - if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && subd_faces.size()) { + if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && get_num_subd_faces()) { /* get attributes */ Attribute *attr_vN = subd_attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *vN = attr_vN->data_float3(); @@ -513,8 +627,8 @@ void Mesh::add_vertex_normals() /* compute vertex normals */ memset(vN, 0, verts.size() * sizeof(float3)); - for (size_t i = 0; i < subd_faces.size(); i++) { - SubdFace &face = subd_faces[i]; + for (size_t i = 0; i < get_num_subd_faces(); i++) { + SubdFace face = get_subd_face(i); float3 fN = face.normal(this); for (size_t j = 0; j < face.num_corners; j++) { @@ -574,8 +688,9 @@ void Mesh::pack_shaders(Scene *scene, uint *tri_shader) if (shader_ptr[i] != last_shader || last_smooth != smooth[i]) { last_shader = shader_ptr[i]; last_smooth = smooth[i]; - Shader *shader = (last_shader < used_shaders.size()) ? used_shaders[last_shader] : - scene->default_surface; + Shader *shader = (last_shader < used_shaders.size()) ? + static_cast<Shader *>(used_shaders[last_shader]) : + scene->default_surface; shader_id = scene->shader_manager->get_shader_id(shader, last_smooth); } @@ -616,7 +731,7 @@ void Mesh::pack_verts(const vector<uint> &tri_prim_index, { size_t verts_size = verts.size(); - if (verts_size && subd_faces.size()) { + if (verts_size && get_num_subd_faces()) { float2 *vert_patch_uv_ptr = vert_patch_uv.data(); for (size_t i = 0; i < verts_size; i++) { @@ -633,17 +748,17 @@ void Mesh::pack_verts(const vector<uint> &tri_prim_index, t.v[2] + vert_offset, tri_prim_index[i + tri_offset]); - tri_patch[i] = (!subd_faces.size()) ? -1 : (triangle_patch[i] * 8 + patch_offset); + tri_patch[i] = (!get_num_subd_faces()) ? -1 : (triangle_patch[i] * 8 + patch_offset); } } void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset) { - size_t num_faces = subd_faces.size(); + size_t num_faces = get_num_subd_faces(); int ngons = 0; for (size_t f = 0; f < num_faces; f++) { - SubdFace face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { int c[4]; diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index b03b826cd9f..6630dcd8a35 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -118,36 +118,57 @@ class Mesh : public Geometry { float crease; }; + SubdEdgeCrease get_subd_crease(size_t i) const + { + SubdEdgeCrease s; + s.v[0] = subd_creases_edge[i * 2]; + s.v[1] = subd_creases_edge[i * 2 + 1]; + s.crease = subd_creases_weight[i]; + return s; + } + + bool need_tesselation(); + enum SubdivisionType { SUBDIVISION_NONE, SUBDIVISION_LINEAR, SUBDIVISION_CATMULL_CLARK, }; - SubdivisionType subdivision_type; + NODE_SOCKET_API(SubdivisionType, subdivision_type) /* Mesh Data */ - array<int> triangles; - array<float3> verts; - array<int> shader; - array<bool> smooth; + NODE_SOCKET_API_ARRAY(array<int>, triangles) + NODE_SOCKET_API_ARRAY(array<float3>, verts) + NODE_SOCKET_API_ARRAY(array<int>, shader) + NODE_SOCKET_API_ARRAY(array<bool>, smooth) /* used for storing patch info for subd triangles, only allocated if there are patches */ - array<int> triangle_patch; /* must be < 0 for non subd triangles */ - array<float2> vert_patch_uv; + NODE_SOCKET_API_ARRAY(array<int>, triangle_patch) /* must be < 0 for non subd triangles */ + NODE_SOCKET_API_ARRAY(array<float2>, vert_patch_uv) + + /* SubdFaces */ + NODE_SOCKET_API_ARRAY(array<int>, subd_start_corner) + NODE_SOCKET_API_ARRAY(array<int>, subd_num_corners) + NODE_SOCKET_API_ARRAY(array<int>, subd_shader) + NODE_SOCKET_API_ARRAY(array<bool>, subd_smooth) + NODE_SOCKET_API_ARRAY(array<int>, subd_ptex_offset) - array<SubdFace> subd_faces; - array<int> subd_face_corners; - int num_ngons; + NODE_SOCKET_API_ARRAY(array<int>, subd_face_corners) + NODE_SOCKET_API(int, num_ngons) - array<SubdEdgeCrease> subd_creases; + NODE_SOCKET_API_ARRAY(array<int>, subd_creases_edge) + NODE_SOCKET_API_ARRAY(array<float>, subd_creases_weight) - SubdParams *subd_params; + /* Subdivisions parameters */ + NODE_SOCKET_API(float, subd_dicing_rate) + NODE_SOCKET_API(int, subd_max_level) + NODE_SOCKET_API(Transform, subd_objecttoworld) AttributeSet subd_attributes; + private: PackedPatchTable *patch_table; - /* BVH */ size_t vert_offset; @@ -157,13 +178,22 @@ class Mesh : public Geometry { size_t corner_offset; size_t num_subd_verts; + size_t num_subd_faces; - private: unordered_map<int, int> vert_to_stitching_key_map; /* real vert index -> stitching index */ unordered_multimap<int, int> vert_stitching_map; /* stitching index -> multiple real vert indices */ + + friend class BVH; + friend class BVHBuild; + friend class BVHEmbree; + friend class BVHSpatialSplit; friend class DiagSplit; + friend class EdgeDice; friend class GeometryManager; + friend class ObjectManager; + + SubdParams *subd_params = nullptr; public: /* Functions */ @@ -174,11 +204,13 @@ class Mesh : public Geometry { void reserve_mesh(int numverts, int numfaces); void resize_subd_faces(int numfaces, int num_ngons, int numcorners); void reserve_subd_faces(int numfaces, int num_ngons, int numcorners); + void reserve_subd_creases(size_t num_creases); void clear(bool preserve_shaders = false) override; void add_vertex(float3 P); void add_vertex_slow(float3 P); void add_triangle(int v0, int v1, int v2, int shader, bool smooth); void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_); + void add_crease(int v0, int v1, float weight); void copy_center_to_motion_step(const int motion_step); @@ -202,6 +234,25 @@ class Mesh : public Geometry { void tessellate(DiagSplit *split); + SubdFace get_subd_face(size_t index) const; + + SubdParams *get_subd_params(); + + size_t get_num_subd_faces() const + { + return num_subd_faces; + } + + void set_num_subd_faces(size_t num_subd_faces_) + { + num_subd_faces = num_subd_faces_; + } + + size_t get_num_subd_verts() + { + return num_subd_verts; + } + protected: void clear(bool preserve_shaders, bool preserve_voxel_data); }; diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index 467810f9273..b4fb5dcdea2 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -58,7 +58,7 @@ bool GeometryManager::displace( size_t object_index = OBJECT_NONE; for (size_t i = 0; i < scene->objects.size(); i++) { - if (scene->objects[i]->geometry == mesh) { + if (scene->objects[i]->get_geometry() == mesh) { object_index = i; break; } @@ -76,10 +76,10 @@ bool GeometryManager::displace( Mesh::Triangle t = mesh->get_triangle(i); int shader_index = mesh->shader[i]; Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + static_cast<Shader *>(mesh->used_shaders[shader_index]) : scene->default_surface; - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { continue; } @@ -160,10 +160,10 @@ bool GeometryManager::displace( Mesh::Triangle t = mesh->get_triangle(i); int shader_index = mesh->shader[i]; Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + static_cast<Shader *>(mesh->used_shaders[shader_index]) : scene->default_surface; - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { continue; } @@ -227,8 +227,9 @@ bool GeometryManager::displace( bool need_recompute_vertex_normals = false; - foreach (Shader *shader, mesh->used_shaders) { - if (shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) { + foreach (Node *node, mesh->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (shader->has_displacement && shader->get_displacement_method() == DISPLACE_TRUE) { need_recompute_vertex_normals = true; break; } @@ -241,11 +242,11 @@ bool GeometryManager::displace( for (size_t i = 0; i < num_triangles; i++) { int shader_index = mesh->shader[i]; Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + static_cast<Shader *>(mesh->used_shaders[shader_index]) : scene->default_surface; tri_has_true_disp[i] = shader->has_displacement && - shader->displacement_method == DISPLACE_TRUE; + shader->get_displacement_method() == DISPLACE_TRUE; } /* static vertex normals */ diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp index 3d72b2fab91..7408ee2dbdf 100644 --- a/intern/cycles/render/mesh_subdivision.cpp +++ b/intern/cycles/render/mesh_subdivision.cpp @@ -46,13 +46,11 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner, ccl::Mesh const &mesh) { - setNumBaseVertices(refiner, mesh.verts.size()); - setNumBaseFaces(refiner, mesh.subd_faces.size()); + setNumBaseVertices(refiner, mesh.get_verts().size()); + setNumBaseFaces(refiner, mesh.get_num_subd_faces()); - const ccl::Mesh::SubdFace *face = mesh.subd_faces.data(); - - for (int i = 0; i < mesh.subd_faces.size(); i++, face++) { - setNumBaseFaceVertices(refiner, i, face->num_corners); + for (int i = 0; i < mesh.get_num_subd_faces(); i++) { + setNumBaseFaceVertices(refiner, i, mesh.get_subd_num_corners()[i]); } return true; @@ -62,14 +60,17 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner, ccl::Mesh const &mesh) { - const ccl::Mesh::SubdFace *face = mesh.subd_faces.data(); + const ccl::array<int> &subd_face_corners = mesh.get_subd_face_corners(); + const ccl::array<int> &subd_start_corner = mesh.get_subd_start_corner(); + const ccl::array<int> &subd_num_corners = mesh.get_subd_num_corners(); - for (int i = 0; i < mesh.subd_faces.size(); i++, face++) { + for (int i = 0; i < mesh.get_num_subd_faces(); i++) { IndexArray face_verts = getBaseFaceVertices(refiner, i); - int *corner = &mesh.subd_face_corners[face->start_corner]; + int start_corner = subd_start_corner[i]; + int *corner = &subd_face_corners[start_corner]; - for (int j = 0; j < face->num_corners; j++, corner++) { + for (int j = 0; j < subd_num_corners[i]; j++, corner++) { face_verts[j] = *corner; } } @@ -81,17 +82,18 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner, ccl::Mesh const &mesh) { - const ccl::Mesh::SubdEdgeCrease *crease = mesh.subd_creases.data(); + size_t num_creases = mesh.get_subd_creases_weight().size(); - for (int i = 0; i < mesh.subd_creases.size(); i++, crease++) { - Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]); + for (int i = 0; i < num_creases; i++) { + ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i); + Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]); if (edge != INDEX_INVALID) { - setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f); + setBaseEdgeSharpness(refiner, edge, crease.crease * 10.0f); } } - for (int i = 0; i < mesh.verts.size(); i++) { + for (int i = 0; i < mesh.get_verts().size(); i++) { ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i); if (vert_edges.size() == 2) { @@ -203,8 +205,8 @@ class OsdData { int num_local_points = patch_table->GetNumLocalPoints(); verts.resize(num_refiner_verts + num_local_points); - for (int i = 0; i < mesh->verts.size(); i++) { - verts[i].value = mesh->verts[i]; + for (int i = 0; i < mesh->get_verts().size(); i++) { + verts[i].value = mesh->get_verts()[i]; } OsdValue<float3> *src = verts.data(); @@ -278,16 +280,17 @@ class OsdData { { /* loop over all edges to find longest in screen space */ const Far::TopologyLevel &level = refiner->GetLevel(0); - Transform objecttoworld = mesh->subd_params->objecttoworld; - Camera *cam = mesh->subd_params->camera; + const SubdParams *subd_params = mesh->get_subd_params(); + Transform objecttoworld = subd_params->objecttoworld; + Camera *cam = subd_params->camera; float longest_edge = 0.0f; for (size_t i = 0; i < level.GetNumEdges(); i++) { Far::ConstIndexArray verts = level.GetEdgeVertices(i); - float3 a = mesh->verts[verts[0]]; - float3 b = mesh->verts[verts[1]]; + float3 a = mesh->get_verts()[verts[0]]; + float3 b = mesh->get_verts()[verts[1]]; float edge_len; @@ -305,7 +308,7 @@ class OsdData { } /* calculate isolation level */ - int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f); + int isolation = (int)(log2f(max(longest_edge / subd_params->dicing_rate, 1.0f)) + 1.0f); return min(isolation, 10); } @@ -368,12 +371,16 @@ struct OsdPatch : Patch { void Mesh::tessellate(DiagSplit *split) { + /* reset the number of subdivision vertices, in case the Mesh was not cleared + * between calls or data updates */ + num_subd_verts = 0; + #ifdef WITH_OPENSUBDIV OsdData osd_data; bool need_packed_patch_table = false; if (subdivision_type == SUBDIVISION_CATMULL_CLARK) { - if (subd_faces.size()) { + if (get_num_subd_faces()) { osd_data.build_from_mesh(this); } } @@ -391,7 +398,7 @@ void Mesh::tessellate(DiagSplit *split) } } - int num_faces = subd_faces.size(); + int num_faces = get_num_subd_faces(); Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL); float3 *vN = (attr_vN) ? attr_vN->data_float3() : NULL; @@ -399,7 +406,7 @@ void Mesh::tessellate(DiagSplit *split) /* count patches */ int num_patches = 0; for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { num_patches++; @@ -416,7 +423,7 @@ void Mesh::tessellate(DiagSplit *split) OsdPatch *patch = osd_patches.data(); for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { patch->patch_index = face.ptex_offset; @@ -444,7 +451,7 @@ void Mesh::tessellate(DiagSplit *split) LinearQuadPatch *patch = linear_patches.data(); for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { float3 *hull = patch->hull; @@ -542,7 +549,7 @@ void Mesh::tessellate(DiagSplit *split) /* keep subdivision for corner attributes disabled for now */ attr.flags &= ~ATTR_SUBDIVIDED; } - else if (subd_faces.size()) { + else if (get_num_subd_faces()) { osd_data.subdivide_attribute(attr); need_packed_patch_table = true; @@ -558,7 +565,7 @@ void Mesh::tessellate(DiagSplit *split) switch (attr.element) { case ATTR_ELEMENT_VERTEX: { for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (!face.is_quad()) { char *center = data + (verts.size() - num_subd_verts + ngons) * stride; @@ -581,7 +588,7 @@ void Mesh::tessellate(DiagSplit *split) } break; case ATTR_ELEMENT_CORNER: { for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (!face.is_quad()) { char *center = data + (subd_face_corners.size() + ngons) * stride; @@ -600,7 +607,7 @@ void Mesh::tessellate(DiagSplit *split) } break; case ATTR_ELEMENT_CORNER_BYTE: { for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (!face.is_quad()) { uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 500496dc738..43dff896db7 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -247,6 +247,9 @@ NODE_DEFINE(ImageTextureNode) SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f); + SOCKET_INT_ARRAY(tiles, "Tiles", array<int>()); + SOCKET_BOOLEAN(animated, "Animated", false); + SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV); SOCKET_OUT_COLOR(color, "Color"); @@ -259,7 +262,7 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type) { colorspace = u_colorspace_raw; animated = false; - tiles.push_back(1001); + tiles.push_back_slow(1001); } ShaderNode *ImageTextureNode::clone(ShaderGraph *graph) const @@ -286,7 +289,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) * 1001 tile, so there's no point in loading any others. */ if (projection == NODE_IMAGE_PROJ_BOX) { tiles.clear(); - tiles.push_back(1001); + tiles.push_back_slow(1001); return; } @@ -308,7 +311,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) ShaderNode *node = vector_in->link->parent; if (node->type == UVMapNode::node_type) { UVMapNode *uvmap = (UVMapNode *)node; - attribute = uvmap->attribute; + attribute = uvmap->get_attribute(); } else if (node->type == TextureCoordinateNode::node_type) { if (vector_in->link != node->output("UV")) { @@ -325,20 +328,21 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) * be to have a cache in each mesh that is indexed by attribute. * Additionally, building a graph-to-meshes list once could help. */ foreach (Geometry *geom, scene->geometry) { - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->graph == graph) { geom->get_uv_tiles(attribute, used_tiles); } } } - ccl::vector<int> new_tiles; + array<int> new_tiles; foreach (int tile, tiles) { if (used_tiles.count(tile)) { - new_tiles.push_back(tile); + new_tiles.push_back_slow(tile); } } - tiles.swap(new_tiles); + tiles.steal_data(new_tiles); } void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -511,6 +515,8 @@ NODE_DEFINE(EnvironmentTextureNode) projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL); SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR); + SOCKET_BOOLEAN(animated, "Animated", false); + SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION); SOCKET_OUT_COLOR(color, "Color"); @@ -790,7 +796,7 @@ NODE_DEFINE(SkyTextureNode) type_enum.insert("preetham", NODE_SKY_PREETHAM); type_enum.insert("hosek_wilkie", NODE_SKY_HOSEK); type_enum.insert("nishita_improved", NODE_SKY_NISHITA); - SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NISHITA); + SOCKET_ENUM(sky_type, "Type", type_enum, NODE_SKY_NISHITA); SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f)); SOCKET_FLOAT(turbidity, "Turbidity", 2.2f); @@ -823,11 +829,11 @@ void SkyTextureNode::compile(SVMCompiler &compiler) ShaderOutput *color_out = output("Color"); SunSky sunsky; - if (type == NODE_SKY_PREETHAM) + if (sky_type == NODE_SKY_PREETHAM) sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity); - else if (type == NODE_SKY_HOSEK) + else if (sky_type == NODE_SKY_HOSEK) sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo); - else if (type == NODE_SKY_NISHITA) { + else if (sky_type == NODE_SKY_NISHITA) { /* Clamp altitude to reasonable values. * Below 1m causes numerical issues and above 60km is space. */ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f); @@ -860,9 +866,9 @@ void SkyTextureNode::compile(SVMCompiler &compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.stack_assign(color_out); - compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), type); + compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_type); /* nishita doesn't need this data */ - if (type != NODE_SKY_NISHITA) { + if (sky_type != NODE_SKY_NISHITA) { compiler.add_node(__float_as_uint(sunsky.phi), __float_as_uint(sunsky.theta), __float_as_uint(sunsky.radiance_x), @@ -919,11 +925,11 @@ void SkyTextureNode::compile(OSLCompiler &compiler) tex_mapping.compile(compiler); SunSky sunsky; - if (type == NODE_SKY_PREETHAM) + if (sky_type == NODE_SKY_PREETHAM) sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity); - else if (type == NODE_SKY_HOSEK) + else if (sky_type == NODE_SKY_HOSEK) sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo); - else if (type == NODE_SKY_NISHITA) { + else if (sky_type == NODE_SKY_NISHITA) { /* Clamp altitude to reasonable values. * Below 1m causes numerical issues and above 60km is space. */ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f); @@ -963,7 +969,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler) compiler.parameter_array("config_z", sunsky.config_z, 9); compiler.parameter_array("nishita_data", sunsky.nishita_data, 10); /* nishita texture */ - if (type == NODE_SKY_NISHITA) { + if (sky_type == NODE_SKY_NISHITA) { compiler.parameter_texture("filename", handle.svm_slot()); } compiler.add(this, "node_sky_texture"); @@ -985,7 +991,7 @@ NODE_DEFINE(GradientTextureNode) type_enum.insert("radial", NODE_BLEND_RADIAL); type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE); type_enum.insert("spherical", NODE_BLEND_SPHERICAL); - SOCKET_ENUM(type, "Type", type_enum, NODE_BLEND_LINEAR); + SOCKET_ENUM(gradient_type, "Type", type_enum, NODE_BLEND_LINEAR); SOCKET_IN_POINT( vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); @@ -1009,7 +1015,7 @@ void GradientTextureNode::compile(SVMCompiler &compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_GRADIENT, - compiler.encode_uchar4(type, + compiler.encode_uchar4(gradient_type, vector_offset, compiler.stack_assign_if_linked(fac_out), compiler.stack_assign_if_linked(color_out))); @@ -1369,7 +1375,7 @@ NODE_DEFINE(MusgraveTextureNode) type_enum.insert("hybrid_multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL); type_enum.insert("ridged_multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL); type_enum.insert("hetero_terrain", NODE_MUSGRAVE_HETERO_TERRAIN); - SOCKET_ENUM(type, "Type", type_enum, NODE_MUSGRAVE_FBM); + SOCKET_ENUM(musgrave_type, "Type", type_enum, NODE_MUSGRAVE_FBM); SOCKET_IN_POINT( vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); @@ -1414,7 +1420,7 @@ void MusgraveTextureNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_TEX_MUSGRAVE, - compiler.encode_uchar4(type, dimensions, vector_stack_offset, w_stack_offset), + compiler.encode_uchar4(musgrave_type, dimensions, vector_stack_offset, w_stack_offset), compiler.encode_uchar4(scale_stack_offset, detail_stack_offset, dimension_stack_offset, @@ -1447,7 +1453,7 @@ NODE_DEFINE(WaveTextureNode) static NodeEnum type_enum; type_enum.insert("bands", NODE_WAVE_BANDS); type_enum.insert("rings", NODE_WAVE_RINGS); - SOCKET_ENUM(type, "Type", type_enum, NODE_WAVE_BANDS); + SOCKET_ENUM(wave_type, "Type", type_enum, NODE_WAVE_BANDS); static NodeEnum bands_direction_enum; bands_direction_enum.insert("x", NODE_WAVE_BANDS_DIRECTION_X); @@ -1504,7 +1510,7 @@ void WaveTextureNode::compile(SVMCompiler &compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_WAVE, - compiler.encode_uchar4(type, bands_direction, rings_direction, profile), + compiler.encode_uchar4(wave_type, bands_direction, rings_direction, profile), compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(scale_in), compiler.stack_assign_if_linked(distortion_in)), @@ -1926,7 +1932,7 @@ NODE_DEFINE(MappingNode) type_enum.insert("texture", NODE_MAPPING_TYPE_TEXTURE); type_enum.insert("vector", NODE_MAPPING_TYPE_VECTOR); type_enum.insert("normal", NODE_MAPPING_TYPE_NORMAL); - SOCKET_ENUM(type, "Type", type_enum, NODE_MAPPING_TYPE_POINT); + SOCKET_ENUM(mapping_type, "Type", type_enum, NODE_MAPPING_TYPE_POINT); SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_POINT(location, "Location", make_float3(0.0f, 0.0f, 0.0f)); @@ -1945,11 +1951,11 @@ MappingNode::MappingNode() : ShaderNode(node_type) void MappingNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - float3 result = svm_mapping((NodeMappingType)type, vector, location, rotation, scale); + float3 result = svm_mapping((NodeMappingType)mapping_type, vector, location, rotation, scale); folder.make_constant(result); } else { - folder.fold_mapping((NodeMappingType)type); + folder.fold_mapping((NodeMappingType)mapping_type); } } @@ -1969,7 +1975,7 @@ void MappingNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_MAPPING, - type, + mapping_type, compiler.encode_uchar4( vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset), result_stack_offset); @@ -2385,7 +2391,7 @@ void GlossyBsdfNode::simplify_settings(Scene *scene) } Integrator *integrator = scene->integrator; ShaderInput *roughness_input = input("Roughness"); - if (integrator->filter_glossy == 0.0f) { + if (integrator->get_filter_glossy() == 0.0f) { /* Fallback to Sharp closure for Roughness close to 0. * Note: Keep the epsilon in sync with kernel! */ @@ -2478,7 +2484,7 @@ void GlassBsdfNode::simplify_settings(Scene *scene) } Integrator *integrator = scene->integrator; ShaderInput *roughness_input = input("Roughness"); - if (integrator->filter_glossy == 0.0f) { + if (integrator->get_filter_glossy() == 0.0f) { /* Fallback to Sharp closure for Roughness close to 0. * Note: Keep the epsilon in sync with kernel! */ @@ -2571,7 +2577,7 @@ void RefractionBsdfNode::simplify_settings(Scene *scene) } Integrator *integrator = scene->integrator; ShaderInput *roughness_input = input("Roughness"); - if (integrator->filter_glossy == 0.0f) { + if (integrator->get_filter_glossy() == 0.0f) { /* Fallback to Sharp closure for Roughness close to 0. * Note: Keep the epsilon in sync with kernel! */ @@ -4481,7 +4487,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *color_out = output("Color"); if (!color_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "color"; + attr->set_attribute(ustring("color")); graph->add(attr); graph->relink(color_out, attr->output("Color")); } @@ -4489,7 +4495,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *density_out = output("Density"); if (!density_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "density"; + attr->set_attribute(ustring("density")); graph->add(attr); graph->relink(density_out, attr->output("Fac")); } @@ -4497,7 +4503,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *flame_out = output("Flame"); if (!flame_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "flame"; + attr->set_attribute(ustring("flame")); graph->add(attr); graph->relink(flame_out, attr->output("Fac")); } @@ -4505,7 +4511,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *temperature_out = output("Temperature"); if (!temperature_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "temperature"; + attr->set_attribute(ustring("temperature")); graph->add(attr); graph->relink(temperature_out, attr->output("Fac")); } @@ -4882,7 +4888,7 @@ NODE_DEFINE(MixNode) type_enum.insert("color", NODE_MIX_COLOR); type_enum.insert("soft_light", NODE_MIX_SOFT); type_enum.insert("linear_light", NODE_MIX_LINEAR); - SOCKET_ENUM(type, "Type", type_enum, NODE_MIX_BLEND); + SOCKET_ENUM(mix_type, "Type", type_enum, NODE_MIX_BLEND); SOCKET_BOOLEAN(use_clamp, "Use Clamp", false); @@ -4910,7 +4916,7 @@ void MixNode::compile(SVMCompiler &compiler) compiler.stack_assign(fac_in), compiler.stack_assign(color1_in), compiler.stack_assign(color2_in)); - compiler.add_node(NODE_MIX, type, compiler.stack_assign(color_out)); + compiler.add_node(NODE_MIX, mix_type, compiler.stack_assign(color_out)); if (use_clamp) { compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out)); @@ -4928,10 +4934,10 @@ void MixNode::compile(OSLCompiler &compiler) void MixNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp); + folder.make_constant_clamp(svm_mix(mix_type, fac, color1, color2), use_clamp); } else { - folder.fold_mix(type, use_clamp); + folder.fold_mix(mix_type, use_clamp); } } @@ -5761,7 +5767,7 @@ NODE_DEFINE(MapRangeNode) type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED); type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP); type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP); - SOCKET_ENUM(type, "Type", type_enum, NODE_MAP_RANGE_LINEAR); + SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR); SOCKET_IN_FLOAT(value, "Value", 1.0f); SOCKET_IN_FLOAT(from_min, "From Min", 0.0f); @@ -5786,7 +5792,7 @@ void MapRangeNode::expand(ShaderGraph *graph) ShaderOutput *result_out = output("Result"); if (!result_out->links.empty()) { ClampNode *clamp_node = graph->create_node<ClampNode>(); - clamp_node->type = NODE_CLAMP_RANGE; + clamp_node->set_clamp_type(NODE_CLAMP_RANGE); graph->add(clamp_node); graph->relink(result_out, clamp_node->output("Result")); graph->connect(result_out, clamp_node->input("Value")); @@ -5794,13 +5800,13 @@ void MapRangeNode::expand(ShaderGraph *graph) graph->connect(input("To Min")->link, clamp_node->input("Min")); } else { - clamp_node->min = to_min; + clamp_node->set_min(to_min); } if (input("To Max")->link) { graph->connect(input("To Max")->link, clamp_node->input("Max")); } else { - clamp_node->max = to_max; + clamp_node->set_max(to_max); } } } @@ -5829,7 +5835,7 @@ void MapRangeNode::compile(SVMCompiler &compiler) value_stack_offset, compiler.encode_uchar4( from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset), - compiler.encode_uchar4(type, steps_stack_offset, result_stack_offset)); + compiler.encode_uchar4(range_type, steps_stack_offset, result_stack_offset)); compiler.add_node(__float_as_int(from_min), __float_as_int(from_max), @@ -5853,7 +5859,7 @@ NODE_DEFINE(ClampNode) static NodeEnum type_enum; type_enum.insert("minmax", NODE_CLAMP_MINMAX); type_enum.insert("range", NODE_CLAMP_RANGE); - SOCKET_ENUM(type, "Type", type_enum, NODE_CLAMP_MINMAX); + SOCKET_ENUM(clamp_type, "Type", type_enum, NODE_CLAMP_MINMAX); SOCKET_IN_FLOAT(value, "Value", 1.0f); SOCKET_IN_FLOAT(min, "Min", 0.0f); @@ -5871,7 +5877,7 @@ ClampNode::ClampNode() : ShaderNode(node_type) void ClampNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - if (type == NODE_CLAMP_RANGE && (min > max)) { + if (clamp_type == NODE_CLAMP_RANGE && (min > max)) { folder.make_constant(clamp(value, max, min)); } else { @@ -5894,7 +5900,7 @@ void ClampNode::compile(SVMCompiler &compiler) compiler.add_node(NODE_CLAMP, value_stack_offset, - compiler.encode_uchar4(min_stack_offset, max_stack_offset, type), + compiler.encode_uchar4(min_stack_offset, max_stack_offset, clamp_type), result_stack_offset); compiler.add_node(__float_as_int(min), __float_as_int(max)); } @@ -6004,7 +6010,7 @@ NODE_DEFINE(MathNode) type_enum.insert("smoothmin", NODE_MATH_SMOOTH_MIN); type_enum.insert("smoothmax", NODE_MATH_SMOOTH_MAX); type_enum.insert("compare", NODE_MATH_COMPARE); - SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD); + SOCKET_ENUM(math_type, "Type", type_enum, NODE_MATH_ADD); SOCKET_BOOLEAN(use_clamp, "Use Clamp", false); @@ -6027,9 +6033,9 @@ void MathNode::expand(ShaderGraph *graph) ShaderOutput *result_out = output("Value"); if (!result_out->links.empty()) { ClampNode *clamp_node = graph->create_node<ClampNode>(); - clamp_node->type = NODE_CLAMP_MINMAX; - clamp_node->min = 0.0f; - clamp_node->max = 1.0f; + clamp_node->set_clamp_type(NODE_CLAMP_MINMAX); + clamp_node->set_min(0.0f); + clamp_node->set_max(1.0f); graph->add(clamp_node); graph->relink(result_out, clamp_node->output("Result")); graph->connect(result_out, clamp_node->input("Value")); @@ -6040,10 +6046,10 @@ void MathNode::expand(ShaderGraph *graph) void MathNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - folder.make_constant(svm_math(type, value1, value2, value3)); + folder.make_constant(svm_math(math_type, value1, value2, value3)); } else { - folder.fold_math(type); + folder.fold_math(math_type); } } @@ -6061,7 +6067,7 @@ void MathNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_MATH, - type, + math_type, compiler.encode_uchar4(value1_stack_offset, value2_stack_offset, value3_stack_offset), value_stack_offset); } @@ -6107,7 +6113,7 @@ NODE_DEFINE(VectorMathNode) type_enum.insert("sine", NODE_VECTOR_MATH_SINE); type_enum.insert("cosine", NODE_VECTOR_MATH_COSINE); type_enum.insert("tangent", NODE_VECTOR_MATH_TANGENT); - SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD); + SOCKET_ENUM(math_type, "Type", type_enum, NODE_VECTOR_MATH_ADD); SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f)); @@ -6130,7 +6136,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder) float3 vector = make_float3(0.0f, 0.0f, 0.0f); if (folder.all_inputs_constant()) { - svm_vector_math(&value, &vector, type, vector1, vector2, vector3, scale); + svm_vector_math(&value, &vector, math_type, vector1, vector2, vector3, scale); if (folder.output == output("Value")) { folder.make_constant(value); } @@ -6139,7 +6145,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder) } } else { - folder.fold_vector_math(type); + folder.fold_vector_math(math_type); } } @@ -6158,12 +6164,12 @@ void VectorMathNode::compile(SVMCompiler &compiler) int vector_stack_offset = compiler.stack_assign_if_linked(vector_out); /* 3 Vector Operators */ - if (type == NODE_VECTOR_MATH_WRAP) { + if (math_type == NODE_VECTOR_MATH_WRAP) { ShaderInput *vector3_in = input("Vector3"); int vector3_stack_offset = compiler.stack_assign(vector3_in); compiler.add_node( NODE_VECTOR_MATH, - type, + math_type, compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); compiler.add_node(vector3_stack_offset); @@ -6171,7 +6177,7 @@ void VectorMathNode::compile(SVMCompiler &compiler) else { compiler.add_node( NODE_VECTOR_MATH, - type, + math_type, compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); } @@ -6195,7 +6201,7 @@ NODE_DEFINE(VectorRotateNode) type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y); type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z); type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ); - SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS); + SOCKET_ENUM(rotate_type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS); SOCKET_BOOLEAN(invert, "Invert", false); @@ -6222,14 +6228,15 @@ void VectorRotateNode::compile(SVMCompiler &compiler) ShaderInput *angle_in = input("Angle"); ShaderOutput *vector_out = output("Vector"); - compiler.add_node( - NODE_VECTOR_ROTATE, - compiler.encode_uchar4( - type, compiler.stack_assign(vector_in), compiler.stack_assign(rotation_in), invert), - compiler.encode_uchar4(compiler.stack_assign(center_in), - compiler.stack_assign(axis_in), - compiler.stack_assign(angle_in)), - compiler.stack_assign(vector_out)); + compiler.add_node(NODE_VECTOR_ROTATE, + compiler.encode_uchar4(rotate_type, + compiler.stack_assign(vector_in), + compiler.stack_assign(rotation_in), + invert), + compiler.encode_uchar4(compiler.stack_assign(center_in), + compiler.stack_assign(axis_in), + compiler.stack_assign(angle_in)), + compiler.stack_assign(vector_out)); } void VectorRotateNode::compile(OSLCompiler &compiler) @@ -6249,7 +6256,7 @@ NODE_DEFINE(VectorTransformNode) type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR); type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT); type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL); - SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR); + SOCKET_ENUM(transform_type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR); static NodeEnum space_enum; space_enum.insert("world", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD); @@ -6275,7 +6282,7 @@ void VectorTransformNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_VECTOR_TRANSFORM, - compiler.encode_uchar4(type, convert_from, convert_to), + compiler.encode_uchar4(transform_type, convert_from, convert_to), compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out))); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 62dd9d843a8..4d51b4fccaf 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -70,6 +70,17 @@ class TextureNode : public ShaderNode { { } TextureMapping tex_mapping; + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, translation) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, rotation) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, scale) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, min) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, max) + NODE_SOCKET_API_STRUCT_MEMBER(bool, tex_mapping, use_minmax) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Type, tex_mapping, type) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, x_mapping) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, y_mapping) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, z_mapping) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Projection, tex_mapping, projection) }; /* Any node which uses image manager's slot should be a subclass of this one. */ @@ -108,16 +119,16 @@ class ImageTextureNode : public ImageSlotTextureNode { ImageParams image_params() const; /* Parameters. */ - ustring filename; - ustring colorspace; - ImageAlphaType alpha_type; - NodeImageProjection projection; - InterpolationType interpolation; - ExtensionType extension; - float projection_blend; - bool animated; - float3 vector; - ccl::vector<int> tiles; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(ustring, colorspace) + NODE_SOCKET_API(ImageAlphaType, alpha_type) + NODE_SOCKET_API(NodeImageProjection, projection) + NODE_SOCKET_API(InterpolationType, interpolation) + NODE_SOCKET_API(ExtensionType, extension) + NODE_SOCKET_API(float, projection_blend) + NODE_SOCKET_API(bool, animated) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(array<int>, tiles) protected: void cull_tiles(Scene *scene, ShaderGraph *graph); @@ -146,13 +157,13 @@ class EnvironmentTextureNode : public ImageSlotTextureNode { ImageParams image_params() const; /* Parameters. */ - ustring filename; - ustring colorspace; - ImageAlphaType alpha_type; - NodeEnvironmentProjection projection; - InterpolationType interpolation; - bool animated; - float3 vector; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(ustring, colorspace) + NODE_SOCKET_API(ImageAlphaType, alpha_type) + NODE_SOCKET_API(NodeEnvironmentProjection, projection) + NODE_SOCKET_API(InterpolationType, interpolation) + NODE_SOCKET_API(bool, animated) + NODE_SOCKET_API(float3, vector) }; class SkyTextureNode : public TextureNode { @@ -164,20 +175,20 @@ class SkyTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - NodeSkyType type; - float3 sun_direction; - float turbidity; - float ground_albedo; - bool sun_disc; - float sun_size; - float sun_intensity; - float sun_elevation; - float sun_rotation; - float altitude; - float air_density; - float dust_density; - float ozone_density; - float3 vector; + NODE_SOCKET_API(NodeSkyType, sky_type) + NODE_SOCKET_API(float3, sun_direction) + NODE_SOCKET_API(float, turbidity) + NODE_SOCKET_API(float, ground_albedo) + NODE_SOCKET_API(bool, sun_disc) + NODE_SOCKET_API(float, sun_size) + NODE_SOCKET_API(float, sun_intensity) + NODE_SOCKET_API(float, sun_elevation) + NODE_SOCKET_API(float, sun_rotation) + NODE_SOCKET_API(float, altitude) + NODE_SOCKET_API(float, air_density) + NODE_SOCKET_API(float, dust_density) + NODE_SOCKET_API(float, ozone_density) + NODE_SOCKET_API(float3, vector) ImageHandle handle; float get_sun_size() @@ -191,10 +202,10 @@ class OutputNode : public ShaderNode { public: SHADER_NODE_CLASS(OutputNode) - void *surface; - void *volume; - float3 displacement; - float3 normal; + NODE_SOCKET_API(Node *, surface) + NODE_SOCKET_API(Node *, volume) + NODE_SOCKET_API(float3, displacement) + NODE_SOCKET_API(float3, normal) /* Don't allow output node de-duplication. */ virtual bool equals(const ShaderNode & /*other*/) @@ -208,10 +219,10 @@ class OutputAOVNode : public ShaderNode { SHADER_NODE_CLASS(OutputAOVNode) virtual void simplify_settings(Scene *scene); - float value; - float3 color; + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float3, color) - ustring name; + NODE_SOCKET_API(ustring, name) virtual int get_group() { @@ -237,17 +248,21 @@ class GradientTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - NodeGradientType type; - float3 vector; + NODE_SOCKET_API(NodeGradientType, gradient_type) + NODE_SOCKET_API(float3, vector) }; class NoiseTextureNode : public TextureNode { public: SHADER_NODE_CLASS(NoiseTextureNode) - int dimensions; - float w, scale, detail, roughness, distortion; - float3 vector; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(float, w) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, detail) + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, distortion) + NODE_SOCKET_API(float3, vector) }; class VoronoiTextureNode : public TextureNode { @@ -271,11 +286,15 @@ class VoronoiTextureNode : public TextureNode { return result; } - int dimensions; - NodeVoronoiDistanceMetric metric; - NodeVoronoiFeature feature; - float w, scale, exponent, smoothness, randomness; - float3 vector; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(NodeVoronoiDistanceMetric, metric) + NODE_SOCKET_API(NodeVoronoiFeature, feature) + NODE_SOCKET_API(float, w) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, exponent) + NODE_SOCKET_API(float, smoothness) + NODE_SOCKET_API(float, randomness) + NODE_SOCKET_API(float3, vector) }; class MusgraveTextureNode : public TextureNode { @@ -287,10 +306,16 @@ class MusgraveTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - int dimensions; - NodeMusgraveType type; - float w, scale, detail, dimension, lacunarity, offset, gain; - float3 vector; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(NodeMusgraveType, musgrave_type) + NODE_SOCKET_API(float, w) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, detail) + NODE_SOCKET_API(float, dimension) + NODE_SOCKET_API(float, lacunarity) + NODE_SOCKET_API(float, offset) + NODE_SOCKET_API(float, gain) + NODE_SOCKET_API(float3, vector) }; class WaveTextureNode : public TextureNode { @@ -302,13 +327,18 @@ class WaveTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - NodeWaveType type; - NodeWaveBandsDirection bands_direction; - NodeWaveRingsDirection rings_direction; - NodeWaveProfile profile; + NODE_SOCKET_API(NodeWaveType, wave_type) + NODE_SOCKET_API(NodeWaveBandsDirection, bands_direction) + NODE_SOCKET_API(NodeWaveRingsDirection, rings_direction) + NODE_SOCKET_API(NodeWaveProfile, profile) - float scale, distortion, detail, detail_scale, detail_roughness, phase; - float3 vector; + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, distortion) + NODE_SOCKET_API(float, detail) + NODE_SOCKET_API(float, detail_scale) + NODE_SOCKET_API(float, detail_roughness) + NODE_SOCKET_API(float, phase) + NODE_SOCKET_API(float3, vector) }; class MagicTextureNode : public TextureNode { @@ -320,17 +350,20 @@ class MagicTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - int depth; - float3 vector; - float scale, distortion; + NODE_SOCKET_API(int, depth) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, distortion) }; class CheckerTextureNode : public TextureNode { public: SHADER_NODE_CLASS(CheckerTextureNode) - float3 vector, color1, color2; - float scale; + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float3, color1) + NODE_SOCKET_API(float3, color2) + NODE_SOCKET_API(float, scale) virtual int get_group() { @@ -342,12 +375,21 @@ class BrickTextureNode : public TextureNode { public: SHADER_NODE_CLASS(BrickTextureNode) - float offset, squash; - int offset_frequency, squash_frequency; - - float3 color1, color2, mortar; - float scale, mortar_size, mortar_smooth, bias, brick_width, row_height; - float3 vector; + NODE_SOCKET_API(float, offset) + NODE_SOCKET_API(float, squash) + NODE_SOCKET_API(int, offset_frequency) + NODE_SOCKET_API(int, squash_frequency) + + NODE_SOCKET_API(float3, color1) + NODE_SOCKET_API(float3, color2) + NODE_SOCKET_API(float3, mortar) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, mortar_size) + NODE_SOCKET_API(float, mortar_smooth) + NODE_SOCKET_API(float, bias) + NODE_SOCKET_API(float, brick_width) + NODE_SOCKET_API(float, row_height) + NODE_SOCKET_API(float3, vector) virtual int get_group() { @@ -377,11 +419,11 @@ class PointDensityTextureNode : public ShaderNode { } /* Parameters. */ - ustring filename; - NodeTexVoxelSpace space; - InterpolationType interpolation; - Transform tfm; - float3 vector; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(NodeTexVoxelSpace, space) + NODE_SOCKET_API(InterpolationType, interpolation) + NODE_SOCKET_API(Transform, tfm) + NODE_SOCKET_API(float3, vector) /* Runtime. */ ImageHandle handle; @@ -406,11 +448,11 @@ class IESLightNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - ustring filename; - ustring ies; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(ustring, ies) - float strength; - float3 vector; + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float3, vector) private: LightManager *light_manager; @@ -427,9 +469,9 @@ class WhiteNoiseTextureNode : public ShaderNode { return NODE_GROUP_LEVEL_2; } - int dimensions; - float3 vector; - float w; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float, w) }; class MappingNode : public ShaderNode { @@ -441,8 +483,11 @@ class MappingNode : public ShaderNode { } void constant_fold(const ConstantFolder &folder); - float3 vector, location, rotation, scale; - NodeMappingType type; + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float3, location) + NODE_SOCKET_API(float3, rotation) + NODE_SOCKET_API(float3, scale) + NODE_SOCKET_API(NodeMappingType, mapping_type) }; class RGBToBWNode : public ShaderNode { @@ -450,7 +495,7 @@ class RGBToBWNode : public ShaderNode { SHADER_NODE_CLASS(RGBToBWNode) void constant_fold(const ConstantFolder &folder); - float3 color; + NODE_SOCKET_API(float3, color) }; class ConvertNode : public ShaderNode { @@ -460,6 +505,7 @@ class ConvertNode : public ShaderNode { void constant_fold(const ConstantFolder &folder); + private: SocketType::Type from, to; union { @@ -472,7 +518,6 @@ class ConvertNode : public ShaderNode { }; ustring value_string; - private: static const int MAX_TYPE = 12; static bool register_types(); static Node *create(const NodeType *type); @@ -500,6 +545,7 @@ class BsdfBaseNode : public ShaderNode { return false; } + protected: ClosureType closure; }; @@ -514,18 +560,20 @@ class BsdfNode : public BsdfBaseNode { ShaderInput *param3 = NULL, ShaderInput *param4 = NULL); - float3 color; - float3 normal; - float surface_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, surface_mix_weight) }; class AnisotropicBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(AnisotropicBsdfNode) - float3 tangent; - float roughness, anisotropy, rotation; - ClosureType distribution; + NODE_SOCKET_API(float3, tangent) + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, anisotropy) + NODE_SOCKET_API(float, rotation) + NODE_SOCKET_API(ClosureType, distribution) ClosureType get_closure_type() { @@ -542,7 +590,7 @@ class DiffuseBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(DiffuseBsdfNode) - float roughness; + NODE_SOCKET_API(float, roughness) }; /* Disney principled BRDF */ @@ -570,19 +618,37 @@ class PrincipledBsdfNode : public BsdfBaseNode { ShaderInput *anisotropic_rotation, ShaderInput *transmission_roughness); - float3 base_color; - float3 subsurface_color, subsurface_radius; - float metallic, subsurface, specular, roughness, specular_tint, anisotropic, sheen, sheen_tint, - clearcoat, clearcoat_roughness, ior, transmission, anisotropic_rotation, - transmission_roughness; - float3 normal, clearcoat_normal, tangent; - float surface_mix_weight; - ClosureType distribution, distribution_orig; - ClosureType subsurface_method; - float3 emission; - float emission_strength; - float alpha; + NODE_SOCKET_API(float3, base_color) + NODE_SOCKET_API(float3, subsurface_color) + NODE_SOCKET_API(float3, subsurface_radius) + NODE_SOCKET_API(float, metallic) + NODE_SOCKET_API(float, subsurface) + NODE_SOCKET_API(float, specular) + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, specular_tint) + NODE_SOCKET_API(float, anisotropic) + NODE_SOCKET_API(float, sheen) + NODE_SOCKET_API(float, sheen_tint) + NODE_SOCKET_API(float, clearcoat) + NODE_SOCKET_API(float, clearcoat_roughness) + NODE_SOCKET_API(float, ior) + NODE_SOCKET_API(float, transmission) + NODE_SOCKET_API(float, anisotropic_rotation) + NODE_SOCKET_API(float, transmission_roughness) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float3, clearcoat_normal) + NODE_SOCKET_API(float3, tangent) + NODE_SOCKET_API(float, surface_mix_weight) + NODE_SOCKET_API(ClosureType, distribution) + NODE_SOCKET_API(ClosureType, subsurface_method) + NODE_SOCKET_API(float3, emission) + NODE_SOCKET_API(float, emission_strength) + NODE_SOCKET_API(float, alpha) + private: + ClosureType distribution_orig; + + public: bool has_integrator_dependency(); void attributes(Shader *shader, AttributeRequestSet *attributes); bool has_attribute_dependency() @@ -610,7 +676,7 @@ class VelvetBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(VelvetBsdfNode) - float sigma; + NODE_SOCKET_API(float, sigma) }; class GlossyBsdfNode : public BsdfNode { @@ -624,8 +690,12 @@ class GlossyBsdfNode : public BsdfNode { return distribution; } - float roughness, roughness_orig; - ClosureType distribution, distribution_orig; + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(ClosureType, distribution) + + private: + float roughness_orig; + ClosureType distribution_orig; }; class GlassBsdfNode : public BsdfNode { @@ -639,8 +709,13 @@ class GlassBsdfNode : public BsdfNode { return distribution; } - float roughness, roughness_orig, IOR; - ClosureType distribution, distribution_orig; + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, IOR) + NODE_SOCKET_API(ClosureType, distribution) + + private: + float roughness_orig; + ClosureType distribution_orig; }; class RefractionBsdfNode : public BsdfNode { @@ -654,16 +729,22 @@ class RefractionBsdfNode : public BsdfNode { return distribution; } - float roughness, roughness_orig, IOR; - ClosureType distribution, distribution_orig; + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, IOR) + NODE_SOCKET_API(ClosureType, distribution) + + private: + float roughness_orig; + ClosureType distribution_orig; }; class ToonBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(ToonBsdfNode) - float smooth, size; - ClosureType component; + NODE_SOCKET_API(float, smooth) + NODE_SOCKET_API(float, size) + NODE_SOCKET_API(ClosureType, component) }; class SubsurfaceScatteringNode : public BsdfNode { @@ -679,11 +760,11 @@ class SubsurfaceScatteringNode : public BsdfNode { return falloff; } - float scale; - float3 radius; - float sharpness; - float texture_blur; - ClosureType falloff; + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float3, radius) + NODE_SOCKET_API(float, sharpness) + NODE_SOCKET_API(float, texture_blur) + NODE_SOCKET_API(ClosureType, falloff) }; class EmissionNode : public ShaderNode { @@ -700,9 +781,9 @@ class EmissionNode : public ShaderNode { return true; } - float3 color; - float strength; - float surface_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, surface_mix_weight) }; class BackgroundNode : public ShaderNode { @@ -710,9 +791,9 @@ class BackgroundNode : public ShaderNode { SHADER_NODE_CLASS(BackgroundNode) void constant_fold(const ConstantFolder &folder); - float3 color; - float strength; - float surface_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, surface_mix_weight) }; class HoldoutNode : public ShaderNode { @@ -727,8 +808,8 @@ class HoldoutNode : public ShaderNode { return CLOSURE_HOLDOUT_ID; } - float surface_mix_weight; - float volume_mix_weight; + NODE_SOCKET_API(float, surface_mix_weight) + NODE_SOCKET_API(float, volume_mix_weight) }; class AmbientOcclusionNode : public ShaderNode { @@ -748,13 +829,13 @@ class AmbientOcclusionNode : public ShaderNode { return true; } - float3 color; - float distance; - float3 normal; - int samples; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, distance) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(int, samples) - bool only_local; - bool inside; + NODE_SOCKET_API(bool, only_local) + NODE_SOCKET_API(bool, inside) }; class VolumeNode : public ShaderNode { @@ -780,11 +861,14 @@ class VolumeNode : public ShaderNode { return true; } - float3 color; - float density; - float volume_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, density) + NODE_SOCKET_API(float, volume_mix_weight) + + protected: ClosureType closure; + public: virtual bool equals(const ShaderNode & /*other*/) { /* TODO(sergey): With some care Volume nodes can be de-duplicated. */ @@ -801,7 +885,7 @@ class ScatterVolumeNode : public VolumeNode { public: SHADER_NODE_CLASS(ScatterVolumeNode) - float anisotropy; + NODE_SOCKET_API(float, anisotropy) }; class PrincipledVolumeNode : public VolumeNode { @@ -813,17 +897,17 @@ class PrincipledVolumeNode : public VolumeNode { return true; } - ustring density_attribute; - ustring color_attribute; - ustring temperature_attribute; + NODE_SOCKET_API(ustring, density_attribute) + NODE_SOCKET_API(ustring, color_attribute) + NODE_SOCKET_API(ustring, temperature_attribute) - float anisotropy; - float3 absorption_color; - float emission_strength; - float3 emission_color; - float blackbody_intensity; - float3 blackbody_tint; - float temperature; + NODE_SOCKET_API(float, anisotropy) + NODE_SOCKET_API(float3, absorption_color) + NODE_SOCKET_API(float, emission_strength) + NODE_SOCKET_API(float3, emission_color) + NODE_SOCKET_API(float, blackbody_intensity) + NODE_SOCKET_API(float3, blackbody_tint) + NODE_SOCKET_API(float, temperature) }; /* Interface between the I/O sockets and the SVM/OSL backend. */ @@ -833,36 +917,36 @@ class PrincipledHairBsdfNode : public BsdfBaseNode { void attributes(Shader *shader, AttributeRequestSet *attributes); /* Longitudinal roughness. */ - float roughness; + NODE_SOCKET_API(float, roughness) /* Azimuthal roughness. */ - float radial_roughness; + NODE_SOCKET_API(float, radial_roughness) /* Randomization factor for roughnesses. */ - float random_roughness; + NODE_SOCKET_API(float, random_roughness) /* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */ - float coat; + NODE_SOCKET_API(float, coat) /* Index of reflection. */ - float ior; + NODE_SOCKET_API(float, ior) /* Cuticle tilt angle. */ - float offset; + NODE_SOCKET_API(float, offset) /* Direct coloring's color. */ - float3 color; + NODE_SOCKET_API(float3, color) /* Melanin concentration. */ - float melanin; + NODE_SOCKET_API(float, melanin) /* Melanin redness ratio. */ - float melanin_redness; + NODE_SOCKET_API(float, melanin_redness) /* Dye color. */ - float3 tint; + NODE_SOCKET_API(float3, tint) /* Randomization factor for melanin quantities. */ - float random_color; + NODE_SOCKET_API(float, random_color) /* Absorption coefficient (unfiltered). */ - float3 absorption_coefficient; + NODE_SOCKET_API(float3, absorption_coefficient) - float3 normal; - float surface_mix_weight; + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, surface_mix_weight) /* If linked, here will be the given random number. */ - float random; + NODE_SOCKET_API(float, random) /* Selected coloring parametrization. */ - NodePrincipledHairParametrization parametrization; + NODE_SOCKET_API(NodePrincipledHairParametrization, parametrization) }; class HairBsdfNode : public BsdfNode { @@ -873,11 +957,11 @@ class HairBsdfNode : public BsdfNode { return component; } - ClosureType component; - float offset; - float roughness_u; - float roughness_v; - float3 tangent; + NODE_SOCKET_API(ClosureType, component) + NODE_SOCKET_API(float, offset) + NODE_SOCKET_API(float, roughness_u) + NODE_SOCKET_API(float, roughness_v) + NODE_SOCKET_API(float3, tangent) }; class GeometryNode : public ShaderNode { @@ -894,7 +978,7 @@ class GeometryNode : public ShaderNode { } int get_group(); - float3 normal_osl; + NODE_SOCKET_API(float3, normal_osl) }; class TextureCoordinateNode : public ShaderNode { @@ -910,10 +994,10 @@ class TextureCoordinateNode : public ShaderNode { return true; } - float3 normal_osl; - bool from_dupli; - bool use_transform; - Transform ob_tfm; + NODE_SOCKET_API(float3, normal_osl) + NODE_SOCKET_API(bool, from_dupli) + NODE_SOCKET_API(bool, use_transform) + NODE_SOCKET_API(Transform, ob_tfm) }; class UVMapNode : public ShaderNode { @@ -933,8 +1017,8 @@ class UVMapNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - ustring attribute; - bool from_dupli; + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(bool, from_dupli) }; class LightPathNode : public ShaderNode { @@ -958,8 +1042,8 @@ class LightFalloffNode : public ShaderNode { return NODE_GROUP_LEVEL_2; } - float strength; - float smooth; + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, smooth) }; class ObjectInfoNode : public ShaderNode { @@ -1036,7 +1120,7 @@ class VertexColorNode : public ShaderNode { return true; } - ustring layer_name; + NODE_SOCKET_API(ustring, layer_name) }; class ValueNode : public ShaderNode { @@ -1045,7 +1129,7 @@ class ValueNode : public ShaderNode { void constant_fold(const ConstantFolder &folder); - float value; + NODE_SOCKET_API(float, value) }; class ColorNode : public ShaderNode { @@ -1054,7 +1138,7 @@ class ColorNode : public ShaderNode { void constant_fold(const ConstantFolder &folder); - float3 value; + NODE_SOCKET_API(float3, value) }; class AddClosureNode : public ShaderNode { @@ -1068,15 +1152,15 @@ class MixClosureNode : public ShaderNode { SHADER_NODE_CLASS(MixClosureNode) void constant_fold(const ConstantFolder &folder); - float fac; + NODE_SOCKET_API(float, fac) }; class MixClosureWeightNode : public ShaderNode { public: SHADER_NODE_CLASS(MixClosureWeightNode) - float weight; - float fac; + NODE_SOCKET_API(float, weight) + NODE_SOCKET_API(float, fac) }; class InvertNode : public ShaderNode { @@ -1088,8 +1172,8 @@ class InvertNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float fac; - float3 color; + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float3, color) }; class MixNode : public ShaderNode { @@ -1102,11 +1186,11 @@ class MixNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeMix type; - bool use_clamp; - float3 color1; - float3 color2; - float fac; + NODE_SOCKET_API(NodeMix, mix_type) + NODE_SOCKET_API(bool, use_clamp) + NODE_SOCKET_API(float3, color1) + NODE_SOCKET_API(float3, color2) + NODE_SOCKET_API(float, fac) }; class CombineRGBNode : public ShaderNode { @@ -1118,7 +1202,9 @@ class CombineRGBNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float r, g, b; + NODE_SOCKET_API(float, r) + NODE_SOCKET_API(float, g) + NODE_SOCKET_API(float, b) }; class CombineHSVNode : public ShaderNode { @@ -1130,7 +1216,9 @@ class CombineHSVNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float h, s, v; + NODE_SOCKET_API(float, h) + NODE_SOCKET_API(float, s) + NODE_SOCKET_API(float, v) }; class CombineXYZNode : public ShaderNode { @@ -1142,7 +1230,9 @@ class CombineXYZNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float x, y, z; + NODE_SOCKET_API(float, x) + NODE_SOCKET_API(float, y) + NODE_SOCKET_API(float, z) }; class GammaNode : public ShaderNode { @@ -1154,8 +1244,8 @@ class GammaNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 color; - float gamma; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, gamma) }; class BrightContrastNode : public ShaderNode { @@ -1167,9 +1257,9 @@ class BrightContrastNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 color; - float bright; - float contrast; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, bright) + NODE_SOCKET_API(float, contrast) }; class SeparateRGBNode : public ShaderNode { @@ -1181,7 +1271,7 @@ class SeparateRGBNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float3 color; + NODE_SOCKET_API(float3, color) }; class SeparateHSVNode : public ShaderNode { @@ -1193,7 +1283,7 @@ class SeparateHSVNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float3 color; + NODE_SOCKET_API(float3, color) }; class SeparateXYZNode : public ShaderNode { @@ -1205,18 +1295,18 @@ class SeparateXYZNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float3 vector; + NODE_SOCKET_API(float3, vector) }; class HSVNode : public ShaderNode { public: SHADER_NODE_CLASS(HSVNode) - float hue; - float saturation; - float value; - float fac; - float3 color; + NODE_SOCKET_API(float, hue) + NODE_SOCKET_API(float, saturation) + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float3, color) }; class AttributeNode : public ShaderNode { @@ -1232,7 +1322,7 @@ class AttributeNode : public ShaderNode { return true; } - ustring attribute; + NODE_SOCKET_API(ustring, attribute) }; class CameraNode : public ShaderNode { @@ -1260,8 +1350,8 @@ class FresnelNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 normal; - float IOR; + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, IOR) }; class LayerWeightNode : public ShaderNode { @@ -1276,8 +1366,8 @@ class LayerWeightNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 normal; - float blend; + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, blend) }; class WireframeNode : public ShaderNode { @@ -1292,8 +1382,8 @@ class WireframeNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float size; - bool use_pixel_size; + NODE_SOCKET_API(float, size) + NODE_SOCKET_API(bool, use_pixel_size) }; class WavelengthNode : public ShaderNode { @@ -1304,7 +1394,7 @@ class WavelengthNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float wavelength; + NODE_SOCKET_API(float, wavelength) }; class BlackbodyNode : public ShaderNode { @@ -1316,7 +1406,7 @@ class BlackbodyNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float temperature; + NODE_SOCKET_API(float, temperature) }; class MapRangeNode : public ShaderNode { @@ -1328,9 +1418,14 @@ class MapRangeNode : public ShaderNode { } void expand(ShaderGraph *graph); - float value, from_min, from_max, to_min, to_max, steps; - NodeMapRangeType type; - bool clamp; + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float, from_min) + NODE_SOCKET_API(float, from_max) + NODE_SOCKET_API(float, to_min) + NODE_SOCKET_API(float, to_max) + NODE_SOCKET_API(float, steps) + NODE_SOCKET_API(NodeMapRangeType, range_type) + NODE_SOCKET_API(bool, clamp) }; class ClampNode : public ShaderNode { @@ -1341,8 +1436,10 @@ class ClampNode : public ShaderNode { { return NODE_GROUP_LEVEL_3; } - float value, min, max; - NodeClampType type; + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float, min) + NODE_SOCKET_API(float, max) + NODE_SOCKET_API(NodeClampType, clamp_type) }; class MathNode : public ShaderNode { @@ -1355,11 +1452,11 @@ class MathNode : public ShaderNode { void expand(ShaderGraph *graph); void constant_fold(const ConstantFolder &folder); - float value1; - float value2; - float value3; - NodeMathType type; - bool use_clamp; + NODE_SOCKET_API(float, value1) + NODE_SOCKET_API(float, value2) + NODE_SOCKET_API(float, value3) + NODE_SOCKET_API(NodeMathType, math_type) + NODE_SOCKET_API(bool, use_clamp) }; class NormalNode : public ShaderNode { @@ -1370,8 +1467,8 @@ class NormalNode : public ShaderNode { return NODE_GROUP_LEVEL_2; } - float3 direction; - float3 normal; + NODE_SOCKET_API(float3, direction) + NODE_SOCKET_API(float3, normal) }; class VectorMathNode : public ShaderNode { @@ -1383,11 +1480,11 @@ class VectorMathNode : public ShaderNode { } void constant_fold(const ConstantFolder &folder); - float3 vector1; - float3 vector2; - float3 vector3; - float scale; - NodeVectorMathType type; + NODE_SOCKET_API(float3, vector1) + NODE_SOCKET_API(float3, vector2) + NODE_SOCKET_API(float3, vector3) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(NodeVectorMathType, math_type) }; class VectorRotateNode : public ShaderNode { @@ -1398,13 +1495,13 @@ class VectorRotateNode : public ShaderNode { { return NODE_GROUP_LEVEL_3; } - NodeVectorRotateType type; - bool invert; - float3 vector; - float3 center; - float3 axis; - float angle; - float3 rotation; + NODE_SOCKET_API(NodeVectorRotateType, rotate_type) + NODE_SOCKET_API(bool, invert) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float3, center) + NODE_SOCKET_API(float3, axis) + NODE_SOCKET_API(float, angle) + NODE_SOCKET_API(float3, rotation) }; class VectorTransformNode : public ShaderNode { @@ -1416,10 +1513,10 @@ class VectorTransformNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeVectorTransformType type; - NodeVectorTransformConvertSpace convert_from; - NodeVectorTransformConvertSpace convert_to; - float3 vector; + NODE_SOCKET_API(NodeVectorTransformType, transform_type) + NODE_SOCKET_API(NodeVectorTransformConvertSpace, convert_from) + NODE_SOCKET_API(NodeVectorTransformConvertSpace, convert_to) + NODE_SOCKET_API(float3, vector) }; class BumpNode : public ShaderNode { @@ -1435,15 +1532,15 @@ class BumpNode : public ShaderNode { return NODE_FEATURE_BUMP; } - bool invert; - bool use_object_space; - float height; - float sample_center; - float sample_x; - float sample_y; - float3 normal; - float strength; - float distance; + NODE_SOCKET_API(bool, invert) + NODE_SOCKET_API(bool, use_object_space) + NODE_SOCKET_API(float, height) + NODE_SOCKET_API(float, sample_center) + NODE_SOCKET_API(float, sample_x) + NODE_SOCKET_API(float, sample_y) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, distance) }; class CurvesNode : public ShaderNode { @@ -1456,9 +1553,11 @@ class CurvesNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - array<float3> curves; - float min_x, max_x, fac; - float3 value; + NODE_SOCKET_API(array<float3>, curves) + NODE_SOCKET_API(float, min_x) + NODE_SOCKET_API(float, max_x) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float3, value) protected: using ShaderNode::constant_fold; @@ -1488,16 +1587,16 @@ class RGBRampNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - array<float3> ramp; - array<float> ramp_alpha; - float fac; - bool interpolate; + NODE_SOCKET_API(array<float3>, ramp) + NODE_SOCKET_API(array<float>, ramp_alpha) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(bool, interpolate) }; class SetNormalNode : public ShaderNode { public: SHADER_NODE_CLASS(SetNormalNode) - float3 direction; + NODE_SOCKET_API(float3, direction) }; class OSLNode : public ShaderNode { @@ -1549,11 +1648,11 @@ class NormalMapNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeNormalMapSpace space; - ustring attribute; - float strength; - float3 color; - float3 normal_osl; + NODE_SOCKET_API(NodeNormalMapSpace, space) + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float3, normal_osl) }; class TangentNode : public ShaderNode { @@ -1573,10 +1672,10 @@ class TangentNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeTangentDirectionType direction_type; - NodeTangentAxis axis; - ustring attribute; - float3 normal_osl; + NODE_SOCKET_API(NodeTangentDirectionType, direction_type) + NODE_SOCKET_API(NodeTangentAxis, axis) + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(float3, normal_osl) }; class BevelNode : public ShaderNode { @@ -1595,9 +1694,9 @@ class BevelNode : public ShaderNode { return true; } - float radius; - float3 normal; - int samples; + NODE_SOCKET_API(float, radius) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(int, samples) }; class DisplacementNode : public ShaderNode { @@ -1609,11 +1708,11 @@ class DisplacementNode : public ShaderNode { return NODE_FEATURE_BUMP; } - NodeNormalMapSpace space; - float height; - float midlevel; - float scale; - float3 normal; + NODE_SOCKET_API(NodeNormalMapSpace, space) + NODE_SOCKET_API(float, height) + NODE_SOCKET_API(float, midlevel) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float3, normal) }; class VectorDisplacementNode : public ShaderNode { @@ -1630,11 +1729,11 @@ class VectorDisplacementNode : public ShaderNode { return NODE_FEATURE_BUMP; } - NodeNormalMapSpace space; - ustring attribute; - float3 vector; - float midlevel; - float scale; + NODE_SOCKET_API(NodeNormalMapSpace, space) + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float, midlevel) + NODE_SOCKET_API(float, scale) }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 96c5fcd4fcb..105e968c265 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -104,9 +104,13 @@ NODE_DEFINE(Object) SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f)); SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>()); SOCKET_FLOAT(shadow_terminator_offset, "Terminator Offset", 0.0f); + SOCKET_STRING(asset_name, "Asset Name", ustring()); SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false); + SOCKET_NODE(particle_system, "Particle System", &ParticleSystem::node_type); + SOCKET_INT(particle_index, "Particle Index", 0); + return type; } @@ -213,10 +217,11 @@ void Object::tag_update(Scene *scene) { if (geometry) { if (geometry->transform_applied) - geometry->need_update = true; + geometry->tag_modified(); - foreach (Shader *shader, geometry->used_shaders) { - if (shader->use_mis && shader->has_surface_emission) + foreach (Node *node, geometry->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (shader->get_use_mis() && shader->has_surface_emission) scene->light_manager->need_update = true; } } @@ -273,7 +278,7 @@ uint Object::visibility_for_tracing() const float Object::compute_volume_step_size() const { - if (geometry->type != Geometry::MESH && geometry->type != Geometry::VOLUME) { + if (geometry->geometry_type != Geometry::MESH && geometry->geometry_type != Geometry::VOLUME) { return FLT_MAX; } @@ -286,11 +291,12 @@ float Object::compute_volume_step_size() const /* Compute step rate from shaders. */ float step_rate = FLT_MAX; - foreach (Shader *shader, mesh->used_shaders) { + foreach (Node *node, mesh->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_volume) { - if ((shader->heterogeneous_volume && shader->has_volume_spatial_varying) || + if ((shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) || (shader->has_volume_attribute_dependency)) { - step_rate = fminf(shader->volume_step_rate, step_rate); + step_rate = fminf(shader->get_volume_step_rate(), step_rate); } } } @@ -302,7 +308,7 @@ float Object::compute_volume_step_size() const /* Compute step size from voxel grids. */ float step_size = FLT_MAX; - if (geometry->type == Geometry::VOLUME) { + if (geometry->geometry_type == Geometry::VOLUME) { Volume *volume = static_cast<Volume *>(geometry); foreach (Attribute &attr, volume->attributes.attributes) { @@ -314,7 +320,7 @@ float Object::compute_volume_step_size() const } /* User specified step size. */ - float voxel_step_size = volume->step_size; + float voxel_step_size = volume->get_step_size(); if (voxel_step_size == 0.0f) { /* Auto detect step size. */ @@ -328,7 +334,7 @@ float Object::compute_volume_step_size() const } voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size))); } - else if (volume->object_space) { + else if (volume->get_object_space()) { /* User specified step size in object space. */ float3 size = make_float3(voxel_step_size, voxel_step_size, voxel_step_size); voxel_step_size = min3(fabs(transform_direction(&tfm, size))); @@ -372,14 +378,15 @@ static float object_surface_area(UpdateObjectTransformState *state, const Transform &tfm, Geometry *geom) { - if (geom->type != Geometry::MESH && geom->type != Geometry::VOLUME) { + if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) { return 0.0f; } Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->has_volume || geom->type == Geometry::VOLUME) { + if (mesh->has_volume || geom->geometry_type == Geometry::VOLUME) { /* Volume density automatically adjust to object scale. */ - if (geom->type == Geometry::VOLUME && static_cast<Volume *>(geom)->object_space) { + if (geom->geometry_type == Geometry::VOLUME && + static_cast<Volume *>(geom)->get_object_space()) { const float3 unit = normalize(make_float3(1.0f, 1.0f, 1.0f)); return 1.0f / len(transform_direction(&tfm, unit)); } @@ -411,9 +418,9 @@ static float object_surface_area(UpdateObjectTransformState *state, size_t num_triangles = mesh->num_triangles(); for (size_t j = 0; j < num_triangles; j++) { Mesh::Triangle t = mesh->get_triangle(j); - float3 p1 = mesh->verts[t.v[0]]; - float3 p2 = mesh->verts[t.v[1]]; - float3 p3 = mesh->verts[t.v[2]]; + float3 p1 = mesh->get_verts()[t.v[0]]; + float3 p2 = mesh->get_verts()[t.v[1]]; + float3 p3 = mesh->get_verts()[t.v[2]]; surface_area += triangle_area(p1, p2, p3); } @@ -432,9 +439,9 @@ static float object_surface_area(UpdateObjectTransformState *state, size_t num_triangles = mesh->num_triangles(); for (size_t j = 0; j < num_triangles; j++) { Mesh::Triangle t = mesh->get_triangle(j); - float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]); - float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]); - float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]); + float3 p1 = transform_point(&tfm, mesh->get_verts()[t.v[0]]); + float3 p2 = transform_point(&tfm, mesh->get_verts()[t.v[1]]); + float3 p3 = transform_point(&tfm, mesh->get_verts()[t.v[2]]); surface_area += triangle_area(p1, p2, p3); } @@ -473,11 +480,11 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.particle_index = particle_index; kobject.motion_offset = 0; - if (geom->use_motion_blur) { + if (geom->get_use_motion_blur()) { state->have_motion = true; } - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { /* TODO: why only mesh? */ Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) { @@ -528,14 +535,16 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.dupli_generated[0] = ob->dupli_generated[0]; kobject.dupli_generated[1] = ob->dupli_generated[1]; kobject.dupli_generated[2] = ob->dupli_generated[2]; - kobject.numkeys = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom)->curve_keys.size() : - 0; + kobject.numkeys = (geom->geometry_type == Geometry::HAIR) ? + static_cast<Hair *>(geom)->get_curve_keys().size() : + 0; kobject.dupli_uv[0] = ob->dupli_uv[0]; kobject.dupli_uv[1] = ob->dupli_uv[1]; - int totalsteps = geom->motion_steps; + int totalsteps = geom->get_motion_steps(); kobject.numsteps = (totalsteps - 1) / 2; - kobject.numverts = (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) ? - static_cast<Mesh *>(geom)->verts.size() : + kobject.numverts = (geom->geometry_type == Geometry::MESH || + geom->geometry_type == Geometry::VOLUME) ? + static_cast<Mesh *>(geom)->get_verts().size() : 0; kobject.patch_map_offset = 0; kobject.attribute_map_offset = 0; @@ -553,7 +562,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s state->object_volume_step[ob->index] = FLT_MAX; /* Have curves. */ - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { state->have_curves = true; } } @@ -688,6 +697,10 @@ void ObjectManager::device_update(Device *device, progress.set_status("Updating Objects", "Applying Static Transformations"); apply_static_transforms(dscene, scene, progress); } + + foreach (Object *object, scene->objects) { + object->clear_modified(); + } } void ObjectManager::device_update_flags( @@ -787,7 +800,7 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc foreach (Object *object, scene->objects) { Geometry *geom = object->geometry; - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->patch_table) { uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() - @@ -865,11 +878,11 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P bool apply = (geometry_users[geom] == 1) && !geom->has_surface_bssrdf && !geom->has_true_displacement(); - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); - apply = apply && mesh->subdivision_type == Mesh::SUBDIVISION_NONE; + apply = apply && mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE; } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { /* Can't apply non-uniform scale to curves, this can't be represented by * control points and radius alone. */ float scale; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index dfd9790313b..76c9c30abb0 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -18,6 +18,11 @@ #define __OBJECT_H__ #include "graph/node.h" + +/* included as Object::set_particle_system defined through NODE_SOCKET_API does + * not select the right Node::set overload as it does not know that ParticleSystem + * is a Node */ +#include "render/particles.h" #include "render/scene.h" #include "util/util_array.h" @@ -46,26 +51,26 @@ class Object : public Node { public: NODE_DECLARE - Geometry *geometry; - Transform tfm; + NODE_SOCKET_API(Geometry *, geometry) + NODE_SOCKET_API(Transform, tfm) BoundBox bounds; - uint random_id; - int pass_id; - float3 color; - ustring asset_name; + NODE_SOCKET_API(uint, random_id) + NODE_SOCKET_API(int, pass_id) + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(ustring, asset_name) vector<ParamValue> attributes; - uint visibility; - array<Transform> motion; - bool hide_on_missing_motion; - bool use_holdout; - bool is_shadow_catcher; - float shadow_terminator_offset; - - float3 dupli_generated; - float2 dupli_uv; - - ParticleSystem *particle_system; - int particle_index; + NODE_SOCKET_API(uint, visibility) + NODE_SOCKET_API_ARRAY(array<Transform>, motion) + NODE_SOCKET_API(bool, hide_on_missing_motion) + NODE_SOCKET_API(bool, use_holdout) + NODE_SOCKET_API(bool, is_shadow_catcher) + NODE_SOCKET_API(float, shadow_terminator_offset) + + NODE_SOCKET_API(float3, dupli_generated) + NODE_SOCKET_API(float2, dupli_uv) + + NODE_SOCKET_API(ParticleSystem *, particle_system); + NODE_SOCKET_API(int, particle_index); Object(); ~Object(); diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 0c2b2cf27e9..bea2c534bd1 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -131,7 +131,7 @@ void OSLShaderManager::device_update(Device *device, compiler.background = (shader == background_shader); compiler.compile(og, shader); - if (shader->use_mis && shader->has_surface_emission) + if (shader->get_use_mis() && shader->has_surface_emission) scene->light_manager->need_update = true; } @@ -145,7 +145,7 @@ void OSLShaderManager::device_update(Device *device, og->use = true; foreach (Shader *shader, scene->shaders) - shader->need_update = false; + shader->clear_modified(); need_update = false; @@ -1120,18 +1120,18 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph void OSLCompiler::compile(OSLGlobals *og, Shader *shader) { - if (shader->need_update) { + if (shader->is_modified()) { ShaderGraph *graph = shader->graph; ShaderNode *output = (graph) ? graph->output() : NULL; - bool has_bump = (shader->displacement_method != DISPLACE_TRUE) && + bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) && output->input("Surface")->link && output->input("Displacement")->link; /* finalize */ shader->graph->finalize(scene, has_bump, shader->has_integrator_dependency, - shader->displacement_method == DISPLACE_BOTH); + shader->get_displacement_method() == DISPLACE_BOTH); current_shader = shader; diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 3fb6c9620e6..98c256a43b5 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -339,7 +339,7 @@ void Scene::device_update(Device *device_, Progress &progress) Scene::MotionType Scene::need_motion() { - if (integrator->motion_blur) + if (integrator->get_motion_blur()) return MOTION_BLUR; else if (Pass::contains(passes, PASS_MOTION)) return MOTION_PASS; @@ -352,7 +352,7 @@ float Scene::motion_shutter_time() if (need_motion() == Scene::MOTION_PASS) return 2.0f; else - return camera->shuttertime; + return camera->get_shuttertime(); } bool Scene::need_global_attribute(AttributeStandard std) @@ -376,20 +376,21 @@ void Scene::need_global_attributes(AttributeRequestSet &attributes) bool Scene::need_update() { - return (need_reset() || film->need_update); + return (need_reset() || film->is_modified()); } bool Scene::need_data_update() { - return (background->need_update || image_manager->need_update || object_manager->need_update || + return (background->is_modified() || image_manager->need_update || object_manager->need_update || geometry_manager->need_update || light_manager->need_update || - lookup_tables->need_update || integrator->need_update || shader_manager->need_update || - particle_system_manager->need_update || bake_manager->need_update || film->need_update); + lookup_tables->need_update || integrator->is_modified() || shader_manager->need_update || + particle_system_manager->need_update || bake_manager->need_update || + film->is_modified()); } bool Scene::need_reset() { - return need_data_update() || camera->need_update; + return need_data_update() || camera->is_modified(); } void Scene::reset() @@ -398,9 +399,9 @@ void Scene::reset() shader_manager->add_default(this); /* ensure all objects are updated */ - camera->tag_update(); - dicing_camera->tag_update(); - film->tag_update(this); + camera->tag_modified(); + dicing_camera->tag_modified(); + film->tag_modified(); background->tag_update(this); integrator->tag_update(this); object_manager->tag_update(this); @@ -442,24 +443,24 @@ DeviceRequestedFeatures Scene::get_requested_device_features() requested_features.use_object_motion = false; requested_features.use_camera_motion = use_motion && camera->use_motion(); foreach (Object *object, objects) { - Geometry *geom = object->geometry; + Geometry *geom = object->get_geometry(); if (use_motion) { - requested_features.use_object_motion |= object->use_motion() | geom->use_motion_blur; - requested_features.use_camera_motion |= geom->use_motion_blur; + requested_features.use_object_motion |= object->use_motion() | geom->get_use_motion_blur(); + requested_features.use_camera_motion |= geom->get_use_motion_blur(); } - if (object->is_shadow_catcher) { + if (object->get_is_shadow_catcher()) { requested_features.use_shadow_tricks = true; } - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); #ifdef WITH_OPENSUBDIV - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) { requested_features.use_patch_evaluation = true; } #endif requested_features.use_true_displacement |= mesh->has_true_displacement(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { requested_features.use_hair = true; } } @@ -467,8 +468,9 @@ DeviceRequestedFeatures Scene::get_requested_device_features() requested_features.use_background_light = light_manager->has_background_light(this); requested_features.use_baking = bake_manager->get_baking(); - requested_features.use_integrator_branched = (integrator->method == Integrator::BRANCHED_PATH); - if (film->denoising_data_pass) { + requested_features.use_integrator_branched = (integrator->get_method() == + Integrator::BRANCHED_PATH); + if (film->get_denoising_data_pass()) { requested_features.use_denoising = true; requested_features.use_shadow_tricks = true; } diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 3e12e183771..a60542259f6 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -1008,23 +1008,19 @@ bool Session::update_scene() int height = tile_manager.state.buffer.full_height; int resolution = tile_manager.state.resolution_divider; - if (width != cam->width || height != cam->height || resolution != cam->resolution) { - cam->width = width; - cam->height = height; - cam->resolution = resolution; - cam->tag_update(); - } + cam->set_screen_size_and_resolution(width, height, resolution); /* number of samples is needed by multi jittered * sampling pattern and by baking */ Integrator *integrator = scene->integrator; BakeManager *bake_manager = scene->bake_manager; - if (integrator->sampling_pattern != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) { + if (integrator->get_sampling_pattern() != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) { int aa_samples = tile_manager.num_samples; - if (aa_samples != integrator->aa_samples) { - integrator->aa_samples = aa_samples; + integrator->set_aa_samples(aa_samples); + + if (integrator->is_modified()) { integrator->tag_update(scene); } } @@ -1118,7 +1114,7 @@ bool Session::render_need_denoise(bool &delayed) /* Viewport render. */ /* It can happen that denoising was already enabled, but the scene still needs an update. */ - if (scene->film->need_update || !scene->film->denoising_data_offset) { + if (scene->film->is_modified() || !scene->film->get_denoising_data_offset()) { return false; } @@ -1163,9 +1159,10 @@ void Session::render(bool need_denoise) task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2); task.get_tile_stolen = function_bind(&Session::get_tile_stolen, this); task.need_finish_queue = params.progressive_refine; - task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH; + task.integrator_branched = scene->integrator->get_method() == Integrator::BRANCHED_PATH; - task.adaptive_sampling.use = (scene->integrator->sampling_pattern == SAMPLING_PATTERN_PMJ) && + task.adaptive_sampling.use = (scene->integrator->get_sampling_pattern() == + SAMPLING_PATTERN_PMJ) && scene->dscene.data.film.pass_adaptive_aux_buffer; task.adaptive_sampling.min_samples = scene->dscene.data.integrator.adaptive_min_samples; task.adaptive_sampling.adaptive_step = scene->dscene.data.integrator.adaptive_step; @@ -1176,10 +1173,10 @@ void Session::render(bool need_denoise) if (need_denoise) { task.denoising = params.denoising; - task.pass_stride = scene->film->pass_stride; + task.pass_stride = scene->film->get_pass_stride(); task.target_pass_stride = task.pass_stride; - task.pass_denoising_data = scene->film->denoising_data_offset; - task.pass_denoising_clean = scene->film->denoising_clean_offset; + task.pass_denoising_data = scene->film->get_denoising_data_offset(); + task.pass_denoising_clean = scene->film->get_denoising_clean_offset(); task.denoising_from_render = true; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 135d0dc962b..cf49dedc426 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -187,6 +187,8 @@ NODE_DEFINE(Shader) displacement_method_enum.insert("both", DISPLACE_BOTH); SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP); + SOCKET_INT(pass_id, "Pass ID", 0); + return type; } @@ -216,7 +218,6 @@ Shader::Shader() : Node(node_type) id = -1; used = false; - need_update = true; need_update_geometry = true; } @@ -250,7 +251,7 @@ bool Shader::is_constant_emission(float3 *emission) return false; } - *emission = node->color * node->strength; + *emission = node->get_color() * node->get_strength(); } else if (surf->link->parent->type == BackgroundNode::node_type) { BackgroundNode *node = (BackgroundNode *)surf->link->parent; @@ -262,7 +263,7 @@ bool Shader::is_constant_emission(float3 *emission) return false; } - *emission = node->color * node->strength; + *emission = node->get_color() * node->get_strength(); } else { return false; @@ -306,7 +307,7 @@ void Shader::set_graph(ShaderGraph *graph_) void Shader::tag_update(Scene *scene) { /* update tag */ - need_update = true; + tag_modified(); scene->shader_manager->need_update = true; /* if the shader previously was emissive, update light distribution, @@ -369,7 +370,7 @@ void Shader::tag_used(Scene *scene) /* if an unused shader suddenly gets used somewhere, it needs to be * recompiled because it was skipped for compilation before */ if (!used) { - need_update = true; + tag_modified(); scene->shader_manager->need_update = true; } } @@ -493,16 +494,18 @@ void ShaderManager::update_shaders_used(Scene *scene) scene->default_background->used = true; scene->default_empty->used = true; - if (scene->background->shader) - scene->background->shader->used = true; + if (scene->background->get_shader()) + scene->background->get_shader()->used = true; foreach (Geometry *geom, scene->geometry) - foreach (Shader *shader, geom->used_shaders) + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); shader->used = true; + } foreach (Light *light, scene->lights) - if (light->shader) - light->shader->used = true; + if (light->get_shader()) + const_cast<Shader *>(light->get_shader())->used = true; } void ShaderManager::device_update_common(Device *device, @@ -522,9 +525,9 @@ void ShaderManager::device_update_common(Device *device, foreach (Shader *shader, scene->shaders) { uint flag = 0; - if (shader->use_mis) + if (shader->get_use_mis()) flag |= SD_USE_MIS; - if (shader->has_surface_transparent && shader->use_transparent_shadow) + if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) flag |= SD_HAS_TRANSPARENT_SHADOW; if (shader->has_volume) { flag |= SD_HAS_VOLUME; @@ -539,7 +542,7 @@ void ShaderManager::device_update_common(Device *device, if (shader->has_volume_connected && !shader->has_surface) flag |= SD_HAS_ONLY_VOLUME; if (shader->has_volume) { - if (shader->heterogeneous_volume && shader->has_volume_spatial_varying) + if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) flag |= SD_HETEROGENEOUS_VOLUME; } if (shader->has_volume_attribute_dependency) @@ -547,16 +550,16 @@ void ShaderManager::device_update_common(Device *device, if (shader->has_bssrdf_bump) flag |= SD_HAS_BSSRDF_BUMP; if (device->info.has_volume_decoupled) { - if (shader->volume_sampling_method == VOLUME_SAMPLING_EQUIANGULAR) + if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR) flag |= SD_VOLUME_EQUIANGULAR; - if (shader->volume_sampling_method == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) + if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) flag |= SD_VOLUME_MIS; } - if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) + if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) flag |= SD_VOLUME_CUBIC; if (shader->has_bump) flag |= SD_HAS_BUMP; - if (shader->displacement_method != DISPLACE_BUMP) + if (shader->get_displacement_method() != DISPLACE_BUMP) flag |= SD_HAS_DISPLACEMENT; /* constant emission check */ @@ -568,7 +571,7 @@ void ShaderManager::device_update_common(Device *device, /* regular shader */ kshader->flags = flag; - kshader->pass_id = shader->pass_id; + kshader->pass_id = shader->get_pass_id(); kshader->constant_emission[0] = constant_emission.x; kshader->constant_emission[1] = constant_emission.y; kshader->constant_emission[2] = constant_emission.z; @@ -625,7 +628,7 @@ void ShaderManager::add_default(Scene *scene) ShaderGraph *graph = new ShaderGraph(); DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>(); - diffuse->color = make_float3(0.8f, 0.8f, 0.8f); + diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f)); graph->add(diffuse); graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface")); @@ -658,8 +661,8 @@ void ShaderManager::add_default(Scene *scene) ShaderGraph *graph = new ShaderGraph(); EmissionNode *emission = graph->create_node<EmissionNode>(); - emission->color = make_float3(0.8f, 0.8f, 0.8f); - emission->strength = 0.0f; + emission->set_color(make_float3(0.8f, 0.8f, 0.8f)); + emission->set_strength(0.0f); graph->add(emission); graph->connect(emission->output("Emission"), graph->output()->input("Surface")); @@ -703,10 +706,10 @@ void ShaderManager::get_requested_graph_features(ShaderGraph *graph, requested_features->nodes_features |= node->get_feature(); if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) { BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node); - if (CLOSURE_IS_VOLUME(bsdf_node->closure)) { + if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) { requested_features->nodes_features |= NODE_FEATURE_VOLUME; } - else if (CLOSURE_IS_PRINCIPLED(bsdf_node->closure)) { + else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) { requested_features->use_principled = true; } } @@ -738,7 +741,7 @@ void ShaderManager::get_requested_features(Scene *scene, ShaderNode *output_node = shader->graph->output(); if (output_node->input("Displacement")->link != NULL) { requested_features->nodes_features |= NODE_FEATURE_BUMP; - if (shader->displacement_method == DISPLACE_BOTH) { + if (shader->get_displacement_method() == DISPLACE_BOTH) { requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE; requested_features->max_nodes_group = max(requested_features->max_nodes_group, NODE_GROUP_LEVEL_1); diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 897b0984a7e..de19048d8e1 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -81,22 +81,25 @@ class Shader : public Node { public: NODE_DECLARE - int pass_id; - /* shader graph */ ShaderGraph *graph; + NODE_SOCKET_API(int, pass_id) + /* sampling */ - bool use_mis; - bool use_transparent_shadow; - bool heterogeneous_volume; - VolumeSampling volume_sampling_method; - int volume_interpolation_method; - float volume_step_rate; + NODE_SOCKET_API(bool, use_mis) + NODE_SOCKET_API(bool, use_transparent_shadow) + NODE_SOCKET_API(bool, heterogeneous_volume) + NODE_SOCKET_API(VolumeSampling, volume_sampling_method) + NODE_SOCKET_API(int, volume_interpolation_method) + NODE_SOCKET_API(float, volume_step_rate) + + /* displacement */ + NODE_SOCKET_API(DisplacementMethod, displacement_method) + float prev_volume_step_rate; /* synchronization */ - bool need_update; bool need_update_geometry; /* If the shader has only volume components, the surface is assumed to @@ -122,9 +125,6 @@ class Shader : public Node { bool has_volume_attribute_dependency; bool has_integrator_dependency; - /* displacement */ - DisplacementMethod displacement_method; - /* requested mesh attributes */ AttributeRequestSet attributes; diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index d66744d06be..b2bc17aec19 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -123,8 +123,8 @@ void SVMShaderManager::device_update(Device *device, for (int i = 0; i < num_shaders; i++) { Shader *shader = scene->shaders[i]; - shader->need_update = false; - if (shader->use_mis && shader->has_surface_emission) { + shader->clear_modified(); + if (shader->get_use_mis() && shader->has_surface_emission) { scene->light_manager->need_update = true; } @@ -749,7 +749,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty /* for the bump shader we need add a node to store the shader state */ bool need_bump_state = (type == SHADER_TYPE_BUMP) && - (shader->displacement_method == DISPLACE_BOTH); + (shader->get_displacement_method() == DISPLACE_BOTH); int bump_state_offset = SVM_STACK_INVALID; if (need_bump_state) { bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE); @@ -840,7 +840,7 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum const double time_start = time_dt(); - bool has_bump = (shader->displacement_method != DISPLACE_TRUE) && + bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) && output->input("Surface")->link && output->input("Displacement")->link; /* finalize */ @@ -849,7 +849,7 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum shader->graph->finalize(scene, has_bump, shader->has_integrator_dependency, - shader->displacement_method == DISPLACE_BOTH); + shader->get_displacement_method() == DISPLACE_BOTH); } current_shader = shader; diff --git a/intern/cycles/render/volume.cpp b/intern/cycles/render/volume.cpp index 6d5e9126955..4d9bf1df5cb 100644 --- a/intern/cycles/render/volume.cpp +++ b/intern/cycles/render/volume.cpp @@ -518,20 +518,20 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) if (image_memory->data_elements == 1) { grid = openvdb_grid_from_device_texture<openvdb::FloatGrid>( - image_memory, volume->clipping, handle.metadata().transform_3d); + image_memory, volume->get_clipping(), handle.metadata().transform_3d); } else if (image_memory->data_elements == 3) { grid = openvdb_grid_from_device_texture<openvdb::Vec3fGrid>( - image_memory, volume->clipping, handle.metadata().transform_3d); + image_memory, volume->get_clipping(), handle.metadata().transform_3d); } else if (image_memory->data_elements == 4) { grid = openvdb_grid_from_device_texture<openvdb::Vec4fGrid>( - image_memory, volume->clipping, handle.metadata().transform_3d); + image_memory, volume->get_clipping(), handle.metadata().transform_3d); } } if (grid) { - builder.add_grid(grid, do_clipping, volume->clipping); + builder.add_grid(grid, do_clipping, volume->get_clipping()); } } #endif @@ -544,17 +544,19 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) Shader *volume_shader = NULL; int pad_size = 0; - foreach (Shader *shader, volume->used_shaders) { + foreach (Node *node, volume->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (!shader->has_volume) { continue; } volume_shader = shader; - if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) { + if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_LINEAR) { pad_size = max(1, pad_size); } - else if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) { + else if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) { pad_size = max(2, pad_size); } @@ -582,8 +584,8 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) volume->clear(); volume->reserve_mesh(vertices.size(), indices.size() / 3); - volume->used_shaders.push_back(volume_shader); - volume->need_update = true; + volume->used_shaders.push_back_slow(volume_shader); + volume->tag_modified(); volume->need_update_rebuild = true; for (size_t i = 0; i < vertices.size(); ++i) { diff --git a/intern/cycles/render/volume.h b/intern/cycles/render/volume.h index 21568e8e852..2e9703bf7ed 100644 --- a/intern/cycles/render/volume.h +++ b/intern/cycles/render/volume.h @@ -28,9 +28,9 @@ class Volume : public Mesh { Volume(); - float clipping; - float step_size; - bool object_space; + NODE_SOCKET_API(float, clipping) + NODE_SOCKET_API(float, step_size) + NODE_SOCKET_API(bool, object_space) virtual void clear(bool preserve_shaders = false) override; }; diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index 91c7f4bea05..4efdb98aa0f 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -42,11 +42,11 @@ void EdgeDice::reserve(int num_verts, int num_triangles) { Mesh *mesh = params.mesh; - vert_offset = mesh->verts.size(); + vert_offset = mesh->get_verts().size(); tri_offset = mesh->num_triangles(); - mesh->resize_mesh(mesh->verts.size() + num_verts, mesh->num_triangles()); - mesh->reserve_mesh(mesh->verts.size() + num_verts, mesh->num_triangles() + num_triangles); + mesh->resize_mesh(mesh->get_verts().size() + num_verts, mesh->num_triangles()); + mesh->reserve_mesh(mesh->get_verts().size() + num_verts, mesh->num_triangles() + num_triangles); Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp index 1a8c182510c..928f5bf2ed7 100644 --- a/intern/cycles/subd/subd_split.cpp +++ b/intern/cycles/subd/subd_split.cpp @@ -341,8 +341,8 @@ void DiagSplit::split_patches(Patch *patches, size_t patches_byte_stride) { int patch_index = 0; - for (int f = 0; f < params.mesh->subd_faces.size(); f++) { - Mesh::SubdFace &face = params.mesh->subd_faces[f]; + for (int f = 0; f < params.mesh->get_num_subd_faces(); f++) { + Mesh::SubdFace face = params.mesh->get_subd_face(f); Patch *patch = (Patch *)(((char *)patches) + patch_index * patches_byte_stride); @@ -372,8 +372,8 @@ static Edge *create_edge_from_corner(DiagSplit *split, int v0, int v1) { - int a = mesh->subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]; - int b = mesh->subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]; + int a = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 0, face.num_corners)]; + int b = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 1, face.num_corners)]; reversed = !(b < a); @@ -443,8 +443,8 @@ static Edge *create_split_edge_from_corner(DiagSplit *split, { Edge *edge = split->alloc_edge(); - int a = mesh->subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]; - int b = mesh->subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]; + int a = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 0, face.num_corners)]; + int b = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 1, face.num_corners)]; if (b < a) { edge->stitch_edge_key = {b, a}; diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp index 4639fc6d0dd..3eaec982d09 100644 --- a/intern/cycles/test/render_graph_finalize_test.cpp +++ b/intern/cycles/test/render_graph_finalize_test.cpp @@ -64,9 +64,11 @@ template<typename T> class ShaderNodeBuilder { return *this; } - template<typename T2, typename V> ShaderNodeBuilder &set(V T2::*pfield, V value) + template<typename V> ShaderNodeBuilder &set_param(const string &input_name, V value) { - static_cast<T *>(node_)->*pfield = value; + const SocketType *input_socket = node_->type->find_input(ustring(input_name.c_str())); + EXPECT_NE((void *)NULL, input_socket); + node_->set(*input_socket, value); return *this; } @@ -121,8 +123,8 @@ class ShaderGraphBuilder { /* Common input/output boilerplate. */ ShaderGraphBuilder &add_attribute(const string &name) { - return (*this).add_node(ShaderNodeBuilder<AttributeNode>(*graph_, name) - .set(&AttributeNode::attribute, ustring(name))); + return (*this).add_node( + ShaderNodeBuilder<AttributeNode>(*graph_, name).set_param("attribute", ustring(name))); } ShaderGraphBuilder &output_closure(const string &from) @@ -210,12 +212,12 @@ TEST_F(RenderGraph, deduplicate_deep) builder.add_node(ShaderNodeBuilder<GeometryNode>(graph, "Geometry1")) .add_node(ShaderNodeBuilder<GeometryNode>(graph, "Geometry2")) - .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value1").set(&ValueNode::value, 0.8f)) - .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value2").set(&ValueNode::value, 0.8f)) + .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value1").set_param("value", 0.8f)) + .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value2").set_param("value", 0.8f)) .add_node(ShaderNodeBuilder<NoiseTextureNode>(graph, "Noise1")) .add_node(ShaderNodeBuilder<NoiseTextureNode>(graph, "Noise2")) .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_BLEND) + .set_param("mix_type", NODE_MIX_BLEND) .set("Fac", 0.5f)) .add_connection("Geometry1::Parametric", "Noise1::Vector") .add_connection("Value1::Value", "Noise1::Scale") @@ -422,8 +424,8 @@ TEST_F(RenderGraph, constant_fold_mix_add) builder .add_node(ShaderNodeBuilder<MixNode>(graph, "MixAdd") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", false) .set("Fac", 0.8f) .set("Color1", make_float3(0.3f, 0.5f, 0.7f)) .set("Color2", make_float3(0.4f, 0.8f, 0.9f))) @@ -443,8 +445,8 @@ TEST_F(RenderGraph, constant_fold_mix_add_clamp) builder .add_node(ShaderNodeBuilder<MixNode>(graph, "MixAdd") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 0.8f) .set("Color1", make_float3(0.3f, 0.5f, 0.7f)) .set("Color2", make_float3(0.4f, 0.8f, 0.9f))) @@ -465,8 +467,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_dodge_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_DODGE) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_DODGE) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -487,8 +489,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_light_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_LIGHT) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_LIGHT) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -509,8 +511,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_burn_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_BURN) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_BURN) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -531,8 +533,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend_clamped_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", true) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -557,22 +559,22 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend) .add_attribute("Attribute2") /* choose left */ .add_node(ShaderNodeBuilder<MixNode>(graph, "MixBlend1") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "MixBlend1::Color1") .add_connection("Attribute2::Color", "MixBlend1::Color2") /* choose right */ .add_node(ShaderNodeBuilder<MixNode>(graph, "MixBlend2") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", false) .set("Fac", 1.0f)) .add_connection("Attribute1::Color", "MixBlend2::Color2") .add_connection("Attribute2::Color", "MixBlend2::Color1") /* both inputs folded to Attribute1 */ .add_node(ShaderNodeBuilder<MixNode>(graph, "MixBlend3") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, false)) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", false)) .add_connection("Attribute1::Fac", "MixBlend3::Fac") .add_connection("MixBlend1::Color", "MixBlend3::Color1") .add_connection("MixBlend2::Color", "MixBlend3::Color2") @@ -592,8 +594,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_bad) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_SUB) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_SUB) + .set_param("use_clamp", true) .set("Fac", 0.5f)) .add_connection("Attribute::Color", "Mix::Color1") .add_connection("Attribute::Color", "Mix::Color2") @@ -613,8 +615,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_1) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_SUB) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_SUB) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Attribute::Color", "Mix::Color1") .add_connection("Attribute::Color", "Mix::Color2") @@ -635,12 +637,12 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, .add_attribute("Attribute") /* constant on the left */ .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_Cx_Fx") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color1", constval)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_Cx_F1") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color1", constval) .set("Fac", 1.0f)) .add_connection("Attribute::Fac", "Mix_Cx_Fx::Fac") @@ -648,12 +650,12 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, .add_connection("Attribute::Color", "Mix_Cx_F1::Color2") /* constant on the right */ .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_xC_Fx") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color2", constval)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_xC_F1") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color2", constval) .set("Fac", 1.0f)) .add_connection("Attribute::Fac", "Mix_xC_Fx::Fac") @@ -661,16 +663,16 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, .add_connection("Attribute::Color", "Mix_xC_F1::Color1") /* results of actual tests simply added up to connect to output */ .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Out12") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Out34") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Out1234") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Mix_Cx_Fx::Color", "Out12::Color1") .add_connection("Mix_Cx_F1::Color", "Out12::Color2") @@ -898,8 +900,8 @@ TEST_F(RenderGraph, constant_fold_gamma_part_0) .add_connection("Attribute::Color", "Gamma_xC::Color") /* output sum */ .add_node(ShaderNodeBuilder<MixNode>(graph, "Out") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Gamma_Cx::Color", "Out::Color1") .add_connection("Gamma_xC::Color", "Out::Color2") @@ -928,8 +930,8 @@ TEST_F(RenderGraph, constant_fold_gamma_part_1) .add_connection("Attribute::Color", "Gamma_xC::Color") /* output sum */ .add_node(ShaderNodeBuilder<MixNode>(graph, "Out") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Gamma_Cx::Color", "Out::Color1") .add_connection("Gamma_xC::Color", "Out::Color2") @@ -988,8 +990,8 @@ TEST_F(RenderGraph, constant_fold_math) builder .add_node(ShaderNodeBuilder<MathNode>(graph, "Math") - .set(&MathNode::type, NODE_MATH_ADD) - .set(&MathNode::use_clamp, false) + .set_param("math_type", NODE_MATH_ADD) + .set_param("use_clamp", false) .set("Value1", 0.7f) .set("Value2", 0.9f)) .output_value("Math::Value"); @@ -1007,8 +1009,8 @@ TEST_F(RenderGraph, constant_fold_math_clamp) builder .add_node(ShaderNodeBuilder<MathNode>(graph, "Math") - .set(&MathNode::type, NODE_MATH_ADD) - .set(&MathNode::use_clamp, true) + .set_param("math_type", NODE_MATH_ADD) + .set_param("use_clamp", true) .set("Value1", 0.7f) .set("Value2", 0.9f)) .output_value("Math::Value"); @@ -1028,20 +1030,20 @@ static void build_math_partial_test_graph(ShaderGraphBuilder &builder, .add_attribute("Attribute") /* constant on the left */ .add_node(ShaderNodeBuilder<MathNode>(builder.graph(), "Math_Cx") - .set(&MathNode::type, type) - .set(&MathNode::use_clamp, false) + .set_param("math_type", type) + .set_param("use_clamp", false) .set("Value1", constval)) .add_connection("Attribute::Fac", "Math_Cx::Value2") /* constant on the right */ .add_node(ShaderNodeBuilder<MathNode>(builder.graph(), "Math_xC") - .set(&MathNode::type, type) - .set(&MathNode::use_clamp, false) + .set_param("math_type", type) + .set_param("use_clamp", false) .set("Value2", constval)) .add_connection("Attribute::Fac", "Math_xC::Value1") /* output sum */ .add_node(ShaderNodeBuilder<MathNode>(builder.graph(), "Out") - .set(&MathNode::type, NODE_MATH_ADD) - .set(&MathNode::use_clamp, true)) + .set_param("math_type", NODE_MATH_ADD) + .set_param("use_clamp", true)) .add_connection("Math_Cx::Value", "Out::Value1") .add_connection("Math_xC::Value", "Out::Value2") .output_value("Out::Value"); @@ -1178,7 +1180,7 @@ TEST_F(RenderGraph, constant_fold_vector_math) builder .add_node(ShaderNodeBuilder<VectorMathNode>(graph, "VectorMath") - .set(&VectorMathNode::type, NODE_VECTOR_MATH_SUBTRACT) + .set_param("math_type", NODE_VECTOR_MATH_SUBTRACT) .set("Vector1", make_float3(1.3f, 0.5f, 0.7f)) .set("Vector2", make_float3(-1.7f, 0.5f, 0.7f))) .output_color("VectorMath::Vector"); @@ -1198,17 +1200,17 @@ static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder, .add_attribute("Attribute") /* constant on the left */ .add_node(ShaderNodeBuilder<VectorMathNode>(builder.graph(), "Math_Cx") - .set(&VectorMathNode::type, type) + .set_param("math_type", type) .set("Vector1", constval)) .add_connection("Attribute::Vector", "Math_Cx::Vector2") /* constant on the right */ .add_node(ShaderNodeBuilder<VectorMathNode>(builder.graph(), "Math_xC") - .set(&VectorMathNode::type, type) + .set_param("math_type", type) .set("Vector2", constval)) .add_connection("Attribute::Vector", "Math_xC::Vector1") /* output sum */ .add_node(ShaderNodeBuilder<VectorMathNode>(builder.graph(), "Out") - .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD)) + .set_param("math_type", NODE_VECTOR_MATH_ADD)) .add_connection("Math_Cx::Vector", "Out::Vector1") .add_connection("Math_xC::Vector", "Out::Vector2") .output_color("Out::Vector"); @@ -1312,9 +1314,9 @@ TEST_F(RenderGraph, constant_fold_rgb_curves) builder .add_node(ShaderNodeBuilder<RGBCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.5f) .set("Color", make_float3(0.3f, 0.5f, 0.7f))) .output_color("Curves::Color"); @@ -1336,9 +1338,9 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<RGBCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.0f)) .add_connection("Attribute::Color", "Curves::Color") .output_color("Curves::Color"); @@ -1360,9 +1362,9 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0_const) builder .add_node(ShaderNodeBuilder<RGBCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.0f) .set("Color", make_float3(0.3f, 0.5f, 0.7f))) .output_color("Curves::Color"); @@ -1384,9 +1386,9 @@ TEST_F(RenderGraph, constant_fold_vector_curves) builder .add_node(ShaderNodeBuilder<VectorCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.5f) .set("Vector", make_float3(0.3f, 0.5f, 0.7f))) .output_color("Curves::Vector"); @@ -1408,9 +1410,9 @@ TEST_F(RenderGraph, constant_fold_vector_curves_fac_0) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<VectorCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.0f)) .add_connection("Attribute::Vector", "Curves::Vector") .output_color("Curves::Vector"); @@ -1435,11 +1437,11 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp) builder .add_node(ShaderNodeBuilder<RGBRampNode>(graph, "Ramp") - .set(&RGBRampNode::ramp, curve) - .set(&RGBRampNode::ramp_alpha, alpha) - .set(&RGBRampNode::interpolate, true) + .set_param("ramp", curve) + .set_param("ramp_alpha", alpha) + .set_param("interpolate", true) .set("Fac", 0.56f)) - .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set(&MixNode::type, NODE_MIX_ADD)) + .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set_param("mix_type", NODE_MIX_ADD)) .add_connection("Ramp::Color", "Mix::Color1") .add_connection("Ramp::Alpha", "Mix::Color2") .output_color("Mix::Color"); @@ -1464,11 +1466,11 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp_flat) builder .add_node(ShaderNodeBuilder<RGBRampNode>(graph, "Ramp") - .set(&RGBRampNode::ramp, curve) - .set(&RGBRampNode::ramp_alpha, alpha) - .set(&RGBRampNode::interpolate, false) + .set_param("ramp", curve) + .set_param("ramp_alpha", alpha) + .set_param("interpolate", false) .set("Fac", 0.56f)) - .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set(&MixNode::type, NODE_MIX_ADD)) + .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set_param("mix_type", NODE_MIX_ADD)) .add_connection("Ramp::Color", "Mix::Color1") .add_connection("Ramp::Alpha", "Mix::Color2") .output_color("Mix::Color"); @@ -1510,7 +1512,7 @@ TEST_F(RenderGraph, constant_fold_convert_color_vector_color) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<VectorMathNode>(graph, "VecAdd") - .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD) + .set_param("math_type", NODE_VECTOR_MATH_ADD) .set("Vector2", make_float3(0, 0, 0))) .add_connection("Attribute::Color", "VecAdd::Vector1") .output_color("VecAdd::Vector"); @@ -1531,7 +1533,7 @@ TEST_F(RenderGraph, constant_fold_convert_color_float_color) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<MathNode>(graph, "MathAdd") - .set(&MathNode::type, NODE_MATH_ADD) + .set_param("math_type", NODE_MATH_ADD) .set("Value2", 0.0f)) .add_connection("Attribute::Color", "MathAdd::Value1") .output_color("MathAdd::Value"); diff --git a/intern/cycles/util/util_array.h b/intern/cycles/util/util_array.h index db80ab474e0..ea481787018 100644 --- a/intern/cycles/util/util_array.h +++ b/intern/cycles/util/util_array.h @@ -213,6 +213,26 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra return data_[i]; } + T *begin() + { + return data_; + } + + const T *begin() const + { + return data_; + } + + T *end() + { + return data_ + datasize_; + } + + const T *end() const + { + return data_ + datasize_; + } + void reserve(size_t newcapacity) { if (newcapacity > capacity_) { |