diff options
Diffstat (limited to 'intern')
131 files changed, 2983 insertions, 2518 deletions
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index dc0c4f68898..9f967a4bde9 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -31,6 +31,7 @@ #include "mesh.h" #include "nodes.h" #include "object.h" +#include "osl.h" #include "shader.h" #include "scene.h" @@ -214,25 +215,7 @@ static bool xml_equal_string(pugi::xml_node node, const char *name, const char * return false; } -static bool xml_read_enum(ustring *str, ShaderEnum& enm, pugi::xml_node node, const char *name) -{ - pugi::xml_attribute attr = node.attribute(name); - - if(attr) { - ustring ustr(attr.value()); - - if(enm.exists(ustr)) { - *str = ustr; - return true; - } - else - fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", ustr.c_str(), name); - } - - return false; -} - -static bool xml_read_enum_value(int *value, ShaderEnum& enm, pugi::xml_node node, const char *name) +static bool xml_read_enum_value(int *value, NodeEnum& enm, pugi::xml_node node, const char *name) { pugi::xml_attribute attr = node.attribute(name); @@ -250,77 +233,16 @@ static bool xml_read_enum_value(int *value, ShaderEnum& enm, pugi::xml_node node return false; } -static ShaderSocketType xml_read_socket_type(pugi::xml_node node, const char *name) -{ - pugi::xml_attribute attr = node.attribute(name); - - if(attr) { - string value = attr.value(); - if(string_iequals(value, "float")) - return SHADER_SOCKET_FLOAT; - else if(string_iequals(value, "int")) - return SHADER_SOCKET_INT; - else if(string_iequals(value, "color")) - return SHADER_SOCKET_COLOR; - else if(string_iequals(value, "vector")) - return SHADER_SOCKET_VECTOR; - else if(string_iequals(value, "point")) - return SHADER_SOCKET_POINT; - else if(string_iequals(value, "normal")) - return SHADER_SOCKET_NORMAL; - else if(string_iequals(value, "closure color")) - return SHADER_SOCKET_CLOSURE; - else if(string_iequals(value, "string")) - return SHADER_SOCKET_STRING; - else - fprintf(stderr, "Unknown shader socket type \"%s\" for attribute \"%s\".\n", value.c_str(), name); - } - - return SHADER_SOCKET_UNDEFINED; -} - /* Camera */ -static void xml_read_camera(const XMLReadState& state, pugi::xml_node node) +static void xml_read_camera(XMLReadState& state, pugi::xml_node node) { Camera *cam = state.scene->camera; xml_read_int(&cam->width, node, "width"); xml_read_int(&cam->height, node, "height"); - if(xml_read_float(&cam->fov, node, "fov")) - cam->fov = DEG2RADF(cam->fov); - - xml_read_float(&cam->nearclip, node, "nearclip"); - xml_read_float(&cam->farclip, node, "farclip"); - xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop - xml_read_float(&cam->focaldistance, node, "focaldistance"); - xml_read_float(&cam->shuttertime, node, "shuttertime"); - xml_read_float(&cam->aperture_ratio, node, "aperture_ratio"); - - if(xml_equal_string(node, "type", "orthographic")) - cam->type = CAMERA_ORTHOGRAPHIC; - else if(xml_equal_string(node, "type", "perspective")) - cam->type = CAMERA_PERSPECTIVE; - else if(xml_equal_string(node, "type", "panorama")) - cam->type = CAMERA_PANORAMA; - - if(xml_equal_string(node, "panorama_type", "equirectangular")) - cam->panorama_type = PANORAMA_EQUIRECTANGULAR; - else if(xml_equal_string(node, "panorama_type", "fisheye_equidistant")) - cam->panorama_type = PANORAMA_FISHEYE_EQUIDISTANT; - else if(xml_equal_string(node, "panorama_type", "fisheye_equisolid")) - cam->panorama_type = PANORAMA_FISHEYE_EQUISOLID; - - xml_read_float(&cam->fisheye_fov, node, "fisheye_fov"); - xml_read_float(&cam->fisheye_lens, node, "fisheye_lens"); - - xml_read_bool(&cam->use_spherical_stereo, node, "use_spherical_stereo"); - xml_read_float(&cam->interocular_distance, node, "interocular_distance"); - xml_read_float(&cam->convergence_distance, node, "convergence_distance"); - - xml_read_float(&cam->sensorwidth, node, "sensorwidth"); - xml_read_float(&cam->sensorheight, node, "sensorheight"); + xml_read_node(state, cam, node); cam->matrix = state.tfm; @@ -345,6 +267,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml { xml_read_node(state, shader, graph_node); + ShaderManager *manager = state.scene->shader_manager; ShaderGraph *graph = new ShaderGraph(); map<string, ShaderNode*> nodemap; @@ -364,8 +287,8 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml xml_read_string(&img->filename, node, "src"); img->filename = path_join(state.base, img->filename); - xml_read_enum(&img->color_space, ImageTextureNode::color_space_enum, node, "color_space"); - xml_read_enum(&img->projection, ImageTextureNode::projection_enum, node, "projection"); + xml_read_enum_value((int*)&img->color_space, ImageTextureNode::color_space_enum, node, "color_space"); + xml_read_enum_value((int*)&img->projection, ImageTextureNode::projection_enum, node, "projection"); xml_read_float(&img->projection_blend, node, "projection_blend"); /* ToDo: Interpolation */ @@ -378,56 +301,40 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml xml_read_string(&env->filename, node, "src"); env->filename = path_join(state.base, env->filename); - xml_read_enum(&env->color_space, EnvironmentTextureNode::color_space_enum, node, "color_space"); - xml_read_enum(&env->projection, EnvironmentTextureNode::projection_enum, node, "projection"); + xml_read_enum_value((int*)&env->color_space, EnvironmentTextureNode::color_space_enum, node, "color_space"); + xml_read_enum_value((int*)&env->projection, EnvironmentTextureNode::projection_enum, node, "projection"); snode = env; } +#ifdef WITH_OSL else if(string_iequals(node.name(), "osl_shader")) { - OSLScriptNode *osl = new OSLScriptNode(); + if(manager->use_osl()) { + std::string filepath; - /* Source */ - xml_read_string(&osl->filepath, node, "src"); - if(path_is_relative(osl->filepath)) { - osl->filepath = path_join(state.base, osl->filepath); - } + if(xml_read_string(&filepath, node, "src")) { + if(path_is_relative(filepath)) { + filepath = path_join(state.base, filepath); + } - /* Generate inputs/outputs from node sockets - * - * Note: ShaderInput/ShaderOutput store shallow string copies only! - * So we register them as ustring to ensure the pointer stays valid. */ - /* read input values */ - for(pugi::xml_node param = node.first_child(); param; param = param.next_sibling()) { - if(string_iequals(param.name(), "input")) { - string name; - if(!xml_read_string(&name, param, "name")) - continue; - - ShaderSocketType type = xml_read_socket_type(param, "type"); - if(type == SHADER_SOCKET_UNDEFINED) - continue; - - osl->add_input(ustring(name).c_str(), type); + snode = ((OSLShaderManager*)manager)->osl_node(filepath); + + if(!snode) { + fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str()); + } } - else if(string_iequals(param.name(), "output")) { - string name; - if(!xml_read_string(&name, param, "name")) - continue; - - ShaderSocketType type = xml_read_socket_type(param, "type"); - if(type == SHADER_SOCKET_UNDEFINED) - continue; - - osl->add_output(ustring(name).c_str(), type); + else { + fprintf(stderr, "OSL node missing \"src\" attribute.\n"); } } - - snode = osl; + else { + fprintf(stderr, "OSL node without using --shadingsys osl.\n"); + } } +#endif else if(string_iequals(node.name(), "sky_texture")) { SkyTextureNode *sky = new SkyTextureNode(); - xml_read_enum(&sky->type, SkyTextureNode::type_enum, node, "type"); + xml_read_enum_value((int*)&sky->type, SkyTextureNode::type_enum, node, "type"); xml_read_float3(&sky->sun_direction, node, "sun_direction"); xml_read_float(&sky->turbidity, node, "turbidity"); xml_read_float(&sky->ground_albedo, node, "ground_albedo"); @@ -452,17 +359,17 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml } else if(string_iequals(node.name(), "gradient_texture")) { GradientTextureNode *blend = new GradientTextureNode(); - xml_read_enum(&blend->type, GradientTextureNode::type_enum, node, "type"); + xml_read_enum_value((int*)&blend->type, GradientTextureNode::type_enum, node, "type"); snode = blend; } else if(string_iequals(node.name(), "voronoi_texture")) { VoronoiTextureNode *voronoi = new VoronoiTextureNode(); - xml_read_enum(&voronoi->coloring, VoronoiTextureNode::coloring_enum, node, "coloring"); + xml_read_enum_value((int*)&voronoi->coloring, VoronoiTextureNode::coloring_enum, node, "coloring"); snode = voronoi; } else if(string_iequals(node.name(), "musgrave_texture")) { MusgraveTextureNode *musgrave = new MusgraveTextureNode(); - xml_read_enum(&musgrave->type, MusgraveTextureNode::type_enum, node, "type"); + xml_read_enum_value((int*)&musgrave->type, MusgraveTextureNode::type_enum, node, "type"); snode = musgrave; } else if(string_iequals(node.name(), "magic_texture")) { @@ -472,8 +379,8 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml } else if(string_iequals(node.name(), "wave_texture")) { WaveTextureNode *wave = new WaveTextureNode(); - xml_read_enum(&wave->type, WaveTextureNode::type_enum, node, "type"); - xml_read_enum(&wave->profile, WaveTextureNode::profile_enum, node, "profile"); + xml_read_enum_value((int*)&wave->type, WaveTextureNode::type_enum, node, "type"); + xml_read_enum_value((int*)&wave->profile, WaveTextureNode::profile_enum, node, "profile"); snode = wave; } else if(string_iequals(node.name(), "normal")) { @@ -508,7 +415,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml } else if(string_iequals(node.name(), "anisotropic_bsdf")) { AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode(); - xml_read_enum(&aniso->distribution, AnisotropicBsdfNode::distribution_enum, node, "distribution"); + xml_read_enum_value((int*)&aniso->distribution, AnisotropicBsdfNode::distribution_enum, node, "distribution"); snode = aniso; } else if(string_iequals(node.name(), "diffuse_bsdf")) { @@ -525,27 +432,27 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml } else if(string_iequals(node.name(), "toon_bsdf")) { ToonBsdfNode *toon = new ToonBsdfNode(); - xml_read_enum(&toon->component, ToonBsdfNode::component_enum, node, "component"); + xml_read_enum_value((int*)&toon->component, ToonBsdfNode::component_enum, node, "component"); snode = toon; } else if(string_iequals(node.name(), "glossy_bsdf")) { GlossyBsdfNode *glossy = new GlossyBsdfNode(); - xml_read_enum(&glossy->distribution, GlossyBsdfNode::distribution_enum, node, "distribution"); + xml_read_enum_value((int*)&glossy->distribution, GlossyBsdfNode::distribution_enum, node, "distribution"); snode = glossy; } else if(string_iequals(node.name(), "glass_bsdf")) { GlassBsdfNode *diel = new GlassBsdfNode(); - xml_read_enum(&diel->distribution, GlassBsdfNode::distribution_enum, node, "distribution"); + xml_read_enum_value((int*)&diel->distribution, GlassBsdfNode::distribution_enum, node, "distribution"); snode = diel; } else if(string_iequals(node.name(), "refraction_bsdf")) { RefractionBsdfNode *diel = new RefractionBsdfNode(); - xml_read_enum(&diel->distribution, RefractionBsdfNode::distribution_enum, node, "distribution"); + xml_read_enum_value((int*)&diel->distribution, RefractionBsdfNode::distribution_enum, node, "distribution"); snode = diel; } else if(string_iequals(node.name(), "hair_bsdf")) { HairBsdfNode *hair = new HairBsdfNode(); - xml_read_enum(&hair->component, HairBsdfNode::component_enum, node, "component"); + xml_read_enum_value((int*)&hair->component, HairBsdfNode::component_enum, node, "component"); snode = hair; } else if(string_iequals(node.name(), "emission")) { @@ -623,7 +530,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml else if(string_iequals(node.name(), "mix")) { /* ToDo: Tag Mix case for optimization */ MixNode *mix = new MixNode(); - xml_read_enum(&mix->type, MixNode::type_enum, node, "type"); + xml_read_enum_value((int*)&mix->type, MixNode::type_enum, node, "type"); xml_read_bool(&mix->use_clamp, node, "use_clamp"); snode = mix; } @@ -687,32 +594,32 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml else if(string_iequals(node.name(), "normal_map")) { NormalMapNode *nmap = new NormalMapNode; xml_read_ustring(&nmap->attribute, node, "attribute"); - xml_read_enum(&nmap->space, NormalMapNode::space_enum, node, "space"); + xml_read_enum_value((int*)&nmap->space, NormalMapNode::space_enum, node, "space"); snode = nmap; } else if(string_iequals(node.name(), "tangent")) { TangentNode *tangent = new TangentNode; xml_read_ustring(&tangent->attribute, node, "attribute"); - xml_read_enum(&tangent->direction_type, TangentNode::direction_type_enum, node, "direction_type"); - xml_read_enum(&tangent->axis, TangentNode::axis_enum, node, "axis"); + xml_read_enum_value((int*)&tangent->direction_type, TangentNode::direction_type_enum, node, "direction_type"); + xml_read_enum_value((int*)&tangent->axis, TangentNode::axis_enum, node, "axis"); snode = tangent; } else if(string_iequals(node.name(), "math")) { MathNode *math = new MathNode(); - xml_read_enum(&math->type, MathNode::type_enum, node, "type"); + xml_read_enum_value((int*)&math->type, MathNode::type_enum, node, "type"); xml_read_bool(&math->use_clamp, node, "use_clamp"); snode = math; } else if(string_iequals(node.name(), "vector_math")) { VectorMathNode *vmath = new VectorMathNode(); - xml_read_enum(&vmath->type, VectorMathNode::type_enum, node, "type"); + xml_read_enum_value((int*)&vmath->type, VectorMathNode::type_enum, node, "type"); snode = vmath; } else if(string_iequals(node.name(), "vector_transform")) { VectorTransformNode *vtransform = new VectorTransformNode(); - xml_read_enum(&vtransform->type, VectorTransformNode::type_enum, node, "type"); - xml_read_enum(&vtransform->convert_from, VectorTransformNode::convert_space_enum, node, "convert_from"); - xml_read_enum(&vtransform->convert_to, VectorTransformNode::convert_space_enum, node, "convert_to"); + xml_read_enum_value((int*)&vtransform->type, VectorTransformNode::type_enum, node, "type"); + xml_read_enum_value((int*)&vtransform->convert_from, VectorTransformNode::convert_space_enum, node, "convert_from"); + xml_read_enum_value((int*)&vtransform->convert_to, VectorTransformNode::convert_space_enum, node, "convert_to"); snode = vtransform; } else if(string_iequals(node.name(), "connect")) { @@ -731,7 +638,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml ShaderNode *fromnode = nodemap[from_tokens[0]]; foreach(ShaderOutput *out, fromnode->outputs) - if(string_iequals(xml_socket_name(out->name), from_tokens[1])) + if(string_iequals(xml_socket_name(out->name().c_str()), from_tokens[1])) output = out; if(!output) @@ -744,7 +651,7 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml ShaderNode *tonode = nodemap[to_tokens[0]]; foreach(ShaderInput *in, tonode->inputs) - if(string_iequals(xml_socket_name(in->name), to_tokens[1])) + if(string_iequals(xml_socket_name(in->name().c_str()), to_tokens[1])) input = in; if(!input) @@ -776,20 +683,20 @@ static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml /* read input values */ for(pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) { foreach(ShaderInput *in, snode->inputs) { - if(string_iequals(in->name, attr.name())) { - switch(in->type) { - case SHADER_SOCKET_FLOAT: - case SHADER_SOCKET_INT: - xml_read_float(&in->value.x, node, attr.name()); + if(string_iequals(in->name().c_str(), attr.name())) { + switch(in->type()) { + case SocketType::FLOAT: + case SocketType::INT: + xml_read_float(&in->value_float(), node, attr.name()); break; - case SHADER_SOCKET_COLOR: - case SHADER_SOCKET_VECTOR: - case SHADER_SOCKET_POINT: - case SHADER_SOCKET_NORMAL: - xml_read_float3(&in->value, node, attr.name()); + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::POINT: + case SocketType::NORMAL: + xml_read_float3(&in->value(), node, attr.name()); break; - case SHADER_SOCKET_STRING: - xml_read_ustring( &in->value_string, node, attr.name() ); + case SocketType::STRING: + xml_read_ustring( &in->value_string(), node, attr.name() ); break; default: break; @@ -908,6 +815,11 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node) /* create vertices */ mesh->verts = P; + size_t num_triangles = 0; + for(size_t i = 0; i < nverts.size(); i++) + num_triangles += nverts[i]-2; + mesh->reserve_mesh(mesh->verts.size(), num_triangles); + /* create triangles */ int index_offset = 0; @@ -936,9 +848,9 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node) index_offset = 0; for(size_t i = 0; i < nverts.size(); i++) { for(int j = 0; j < nverts[i]-2; j++) { - int v0 = verts[index_offset]; - int v1 = verts[index_offset + j + 1]; - int v2 = verts[index_offset + j + 2]; + int v0 = index_offset; + int v1 = index_offset + j + 1; + int v2 = index_offset + j + 2; assert(v0*2+1 < (int)UV.size()); assert(v1*2+1 < (int)UV.size()); diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index eed86a6e65a..140862721a8 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -359,7 +359,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Distance between volume shader samples when rendering the volume " "(lower values give more accurate and detailed results, but also increased render time)", default=0.1, - min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0 + min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0, precision=4 ) cls.volume_max_steps = IntProperty( diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 023841a7a17..0961c349fc3 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -76,9 +76,8 @@ def use_cuda(context): def use_branched_path(context): cscene = context.scene.cycles - device_type = context.user_preferences.system.compute_device_type - return (cscene.progressive == 'BRANCHED_PATH' and device_type != 'OPENCL') + return (cscene.progressive == 'BRANCHED_PATH' and not use_opencl(context)) def use_sample_all_lights(context): @@ -704,7 +703,7 @@ class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel): col = split.column() sub = col.column(align=True) - sub.label(text="Displacment:") + sub.label(text="Displacement:") sub.prop(cdata, "displacement_method", text="") col = split.column() diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 9dec489ce33..f02fc553908 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -37,7 +37,7 @@ struct BlenderCamera { float lens; float shuttertime; Camera::MotionPosition motion_position; - float shutter_curve[RAMP_TABLE_SIZE]; + array<float> shutter_curve; Camera::RollingShutterType rolling_shutter_type; float rolling_shutter_duration; @@ -108,10 +108,6 @@ static void blender_camera_init(BlenderCamera *bcam, /* render resolution */ bcam->full_width = render_resolution_x(b_render); bcam->full_height = render_resolution_y(b_render); - - /* pixel aspect */ - bcam->pixelaspect.x = b_render.pixel_aspect_x(); - bcam->pixelaspect.y = b_render.pixel_aspect_y(); } static float blender_camera_focal_distance(BL::RenderEngine& b_engine, @@ -464,7 +460,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->rolling_shutter_type = bcam->rolling_shutter_type; cam->rolling_shutter_duration = bcam->rolling_shutter_duration; - memcpy(cam->shutter_curve, bcam->shutter_curve, sizeof(cam->shutter_curve)); + cam->shutter_curve = bcam->shutter_curve; /* border */ cam->border = bcam->border; @@ -563,6 +559,10 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render, float aspectratio, sensor_size; blender_camera_init(&bcam, b_render); + /* TODO(sergey): Consider making it a part of blender_camera_init(). */ + bcam.pixelaspect.x = b_render.pixel_aspect_x(); + bcam.pixelaspect.y = b_render.pixel_aspect_y(); + blender_camera_from_object(&bcam, b_engine, b_ob); blender_camera_viewplane(&bcam, width, height, diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 64f1b66405e..378ae67f0c7 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -156,16 +156,16 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles"); - CData->psys_firstcurve.push_back(curvenum); - CData->psys_curvenum.push_back(totcurves); - CData->psys_shader.push_back(shader); + CData->psys_firstcurve.push_back_slow(curvenum); + CData->psys_curvenum.push_back_slow(totcurves); + CData->psys_shader.push_back_slow(shader); float radius = get_float(cpsys, "radius_scale") * 0.5f; - CData->psys_rootradius.push_back(radius * get_float(cpsys, "root_width")); - CData->psys_tipradius.push_back(radius * get_float(cpsys, "tip_width")); - CData->psys_shape.push_back(get_float(cpsys, "shape")); - CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip")); + CData->psys_rootradius.push_back_slow(radius * get_float(cpsys, "root_width")); + CData->psys_tipradius.push_back_slow(radius * get_float(cpsys, "tip_width")); + CData->psys_shape.push_back_slow(get_float(cpsys, "shape")); + CData->psys_closetip.push_back_slow(get_boolean(cpsys, "use_closetip")); int pa_no = 0; if(!(b_part.child_type() == 0) && totchild != 0) @@ -180,7 +180,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par for(; pa_no < totparts+totchild; pa_no++) { int keynum = 0; - CData->curve_firstkey.push_back(keyno); + CData->curve_firstkey.push_back_slow(keyno); float curve_length = 0.0f; float3 pcKey; @@ -195,15 +195,15 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par continue; curve_length += step_length; } - CData->curvekey_co.push_back(cKey); - CData->curvekey_time.push_back(curve_length); + CData->curvekey_co.push_back_slow(cKey); + CData->curvekey_time.push_back_slow(curve_length); pcKey = cKey; keynum++; } keyno += keynum; - CData->curve_keynum.push_back(keynum); - CData->curve_length.push_back(curve_length); + CData->curve_keynum.push_back_slow(keynum); + CData->curve_length.push_back_slow(curve_length); curvenum++; } } @@ -255,7 +255,7 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti float3 uv = make_float3(0.0f, 0.0f, 0.0f); if(b_mesh->tessface_uv_textures.length()) b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x); - CData->curve_uv.push_back(uv); + CData->curve_uv.push_back_slow(uv); if(pa_no < totparts && b_pa != b_psys.particles.end()) ++b_pa; @@ -309,7 +309,7 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par float3 vcol = make_float3(0.0f, 0.0f, 0.0f); if(b_mesh->tessface_vertex_colors.length()) b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x); - CData->curve_vcol.push_back(vcol); + CData->curve_vcol.push_back_slow(vcol); if(pa_no < totparts && b_pa != b_psys.particles.end()) ++b_pa; @@ -351,10 +351,7 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, } } - mesh->verts.reserve(mesh->verts.size() + numverts); - mesh->triangles.reserve(mesh->triangles.size() + numtris); - mesh->shader.reserve(mesh->shader.size() + numtris); - mesh->smooth.reserve(mesh->smooth.size() + numtris); + mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris); /* actually export */ for(int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) { @@ -374,8 +371,8 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, xbasis = normalize(cross(RotCam - ickey_loc, v1)); float3 ickey_loc_shfl = ickey_loc - radius * xbasis; float3 ickey_loc_shfr = ickey_loc + radius * xbasis; - mesh->verts.push_back(ickey_loc_shfl); - mesh->verts.push_back(ickey_loc_shfr); + mesh->add_vertex(ickey_loc_shfl); + mesh->add_vertex(ickey_loc_shfr); vertexindex += 2; for(int curvekey = CData->curve_firstkey[curve] + 1; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { @@ -401,8 +398,8 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, xbasis = normalize(cross(RotCam - ickey_loc, v1)); float3 ickey_loc_shfl = ickey_loc - radius * xbasis; float3 ickey_loc_shfr = ickey_loc + radius * xbasis; - mesh->verts.push_back(ickey_loc_shfl); - mesh->verts.push_back(ickey_loc_shfr); + mesh->add_vertex(ickey_loc_shfl); + mesh->add_vertex(ickey_loc_shfr); mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], true); mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], true); vertexindex += 2; @@ -410,7 +407,6 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, } } - mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0); mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); mesh->attributes.remove(ATTR_STD_FACE_NORMAL); mesh->add_face_normals(); @@ -437,10 +433,7 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resol } } - mesh->verts.reserve(mesh->verts.size() + numverts); - mesh->triangles.reserve(mesh->triangles.size() + numtris); - mesh->shader.reserve(mesh->shader.size() + numtris); - mesh->smooth.reserve(mesh->smooth.size() + numtris); + mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris); /* actually export */ for(int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) { @@ -529,7 +522,7 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resol float angle = M_2PI_F / (float)resolution; for(int section = 0; section < resolution; section++) { float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + sinf(angle * section) * ybasis); - mesh->verts.push_back(ickey_loc_shf); + mesh->add_vertex(ickey_loc_shf); } if(subv != 0) { @@ -546,7 +539,6 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resol } } - mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0); mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); mesh->attributes.remove(ATTR_STD_FACE_NORMAL); mesh->add_face_normals(); @@ -561,7 +553,7 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) int num_keys = 0; int num_curves = 0; - if(!(mesh->curves.empty() && mesh->curve_keys.empty())) + if(mesh->num_curves()) return; Attribute *attr_intercept = NULL; @@ -584,8 +576,7 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) VLOG(1) << "Exporting curve segments for mesh " << mesh->name; } - mesh->curve_keys.reserve(mesh->curve_keys.size() + num_keys); - mesh->curves.reserve(mesh->curves.size() + num_curves); + mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys); num_keys = 0; num_curves = 0; @@ -613,18 +604,16 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) num_curve_keys++; } - mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]); + mesh->add_curve(num_keys, CData->psys_shader[sys]); num_keys += num_curve_keys; num_curves++; } } /* check allocation */ - if((mesh->curve_keys.size() != num_keys) || (mesh->curves.size() != num_curves)) { + if((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) { VLOG(1) << "Allocation failed, clearing data"; - mesh->curve_keys.clear(); - mesh->curves.clear(); - mesh->curve_attributes.clear(); + mesh->clear(); } } @@ -667,13 +656,16 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) radius = 0.0f; + /* curve motion keys store both position and radius in float4 */ mP[i] = float3_to_float4(ickey_loc); mP[i].w = radius; /* 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 */ - if(len_squared(mP[i] - mesh->curve_keys[i]) > 1e-5f*1e-5f) + float4 curve_key = float3_to_float4(mesh->curve_keys[i]); + curve_key.w = mesh->curve_radius[i]; + if(len_squared(mP[i] - curve_key) > 1e-5f*1e-5f) have_motion = true; } @@ -697,8 +689,10 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int for(int step = 0; step < time_index; step++) { float4 *mP = attr_mP->data_float4() + step*numkeys; - for(int key = 0; key < numkeys; key++) - mP[key] = mesh->curve_keys[key]; + for(int key = 0; key < numkeys; key++) { + mP[key] = float3_to_float4(mesh->curve_keys[key]); + mP[key].w = mesh->curve_radius[key]; + } } } } @@ -872,7 +866,9 @@ void BlenderSync::sync_curves(Mesh *mesh, if(!motion) { /* Clear stored curve data */ mesh->curve_keys.clear(); - mesh->curves.clear(); + mesh->curve_radius.clear(); + mesh->curve_first_key.clear(); + mesh->curve_shader.clear(); mesh->curve_attributes.clear(); } @@ -889,7 +885,7 @@ void BlenderSync::sync_curves(Mesh *mesh, int triangle_method = scene->curve_system_manager->triangle_method; int resolution = scene->curve_system_manager->resolution; size_t vert_num = mesh->verts.size(); - size_t tri_num = mesh->triangles.size(); + size_t tri_num = mesh->num_triangles(); int used_res = 1; /* extract particle hair data - should be combined with connecting to mesh later*/ @@ -950,11 +946,10 @@ void BlenderSync::sync_curves(Mesh *mesh, else { Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED); float3 *generated = attr_generated->data_float3(); - size_t i = 0; - foreach(Mesh::Curve& curve, mesh->curves) { - float3 co = float4_to_float3(mesh->curve_keys[curve.first_key]); - generated[i++] = co*size - loc; + for(size_t i = 0; i < mesh->num_curves(); i++) { + float3 co = mesh->curve_keys[mesh->get_curve(i).first_key]; + generated[i] = co*size - loc; } } } diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 4a0ad79f3ae..80db51148e6 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -548,13 +548,12 @@ static void create_mesh(Scene *scene, numtris += (vi[3] == 0)? 1: 2; } - /* reserve memory */ - mesh->reserve(numverts, numtris, 0, 0); + /* allocate memory */ + mesh->reserve_mesh(numverts, numtris); /* create vertex coordinates and normals */ - int i = 0; - for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) - mesh->verts[i] = get_float3(v->co()); + for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) + mesh->add_vertex(get_float3(v->co())); Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); @@ -583,7 +582,7 @@ static void create_mesh(Scene *scene, /* create faces */ vector<int> nverts(numfaces); vector<int> face_flags(numfaces, FACE_FLAG_NONE); - int fi = 0, ti = 0; + int fi = 0; for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) { int4 vi = get_int4(f->vertices_raw()); @@ -618,18 +617,18 @@ static void create_mesh(Scene *scene, is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) { // TODO(mai): order here is probably wrong - mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth, true); - mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth, true); + mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth, true); + mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth, true); face_flags[fi] |= FACE_FLAG_DIVIDE_24; } else { - mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth, true); - mesh->set_triangle(ti++, vi[0], vi[2], vi[3], shader, smooth, true); + mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth, true); + mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth, true); face_flags[fi] |= FACE_FLAG_DIVIDE_13; } } else - mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth, false); + mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth, false); nverts[fi] = n; } @@ -759,11 +758,12 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, /* create derived mesh */ PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles"); - vector<Mesh::Triangle> oldtriangle = mesh->triangles; + array<int> oldtriangle = mesh->triangles; /* compares curve_keys rather than strands in order to handle quick hair * adjustments in dynamic BVH - other methods could probably do this better*/ - vector<float4> oldcurve_keys = mesh->curve_keys; + array<float3> oldcurve_keys = mesh->curve_keys; + array<float> oldcurve_radius = mesh->curve_radius; mesh->clear(); mesh->used_shaders = used_shaders; @@ -827,14 +827,21 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, if(oldtriangle.size() != mesh->triangles.size()) rebuild = true; else if(oldtriangle.size()) { - if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0) + if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(int)*oldtriangle.size()) != 0) rebuild = true; } if(oldcurve_keys.size() != mesh->curve_keys.size()) rebuild = true; else if(oldcurve_keys.size()) { - if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float4)*oldcurve_keys.size()) != 0) + if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float3)*oldcurve_keys.size()) != 0) + rebuild = true; + } + + if(oldcurve_radius.size() != mesh->curve_radius.size()) + rebuild = true; + else if(oldcurve_radius.size()) { + if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0) rebuild = true; } @@ -931,8 +938,8 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if(attr_mP) { - float4 *keys = &mesh->curve_keys[0]; - memcpy(attr_mP->data_float4() + time_index*numkeys, keys, sizeof(float4)*numkeys); + float3 *keys = &mesh->curve_keys[0]; + memcpy(attr_mP->data_float3() + time_index*numkeys, keys, sizeof(float3)*numkeys); } } diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index d1e702cfdc2..b9876cd604f 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -76,7 +76,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object& b_ob, pa.velocity = get_float3(b_pa.velocity()); pa.angular_velocity = get_float3(b_pa.angular_velocity()); - psys->particles.push_back(pa); + psys->particles.push_back_slow(pa); if(object->particle_index != psys->particles.size() - 1) scene->object_manager->tag_update(scene); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index a56c2e75e4e..7a13641a312 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -127,82 +127,57 @@ static float3 get_node_output_vector(BL::Node& b_node, const string& name) return make_float3(value[0], value[1], value[2]); } -static ShaderSocketType convert_socket_type(BL::NodeSocket& b_socket) +static SocketType::Type convert_socket_type(BL::NodeSocket& b_socket) { switch(b_socket.type()) { case BL::NodeSocket::type_VALUE: - return SHADER_SOCKET_FLOAT; + return SocketType::FLOAT; case BL::NodeSocket::type_INT: - return SHADER_SOCKET_INT; + return SocketType::INT; case BL::NodeSocket::type_VECTOR: - return SHADER_SOCKET_VECTOR; + return SocketType::VECTOR; case BL::NodeSocket::type_RGBA: - return SHADER_SOCKET_COLOR; + return SocketType::COLOR; case BL::NodeSocket::type_STRING: - return SHADER_SOCKET_STRING; + return SocketType::STRING; case BL::NodeSocket::type_SHADER: - return SHADER_SOCKET_CLOSURE; + return SocketType::CLOSURE; default: - return SHADER_SOCKET_UNDEFINED; + return SocketType::UNDEFINED; } } -#ifdef WITH_OSL -static ShaderSocketType convert_osl_socket_type(OSL::OSLQuery& query, - BL::NodeSocket& b_socket) -{ - ShaderSocketType socket_type = convert_socket_type(b_socket); - if(socket_type == SHADER_SOCKET_VECTOR) { - /* TODO(sergey): Do we need compatible_name() here? */ - const OSL::OSLQuery::Parameter *param = query.getparam(b_socket.name()); - assert(param != NULL); - if(param != NULL) { - if(param->type.vecsemantics == TypeDesc::POINT) { - socket_type = SHADER_SOCKET_POINT; - } - else if(param->type.vecsemantics == TypeDesc::NORMAL) { - socket_type = SHADER_SOCKET_NORMAL; - } - } - } - - return socket_type; -} -#endif /* WITH_OSL */ - static void set_default_value(ShaderInput *input, BL::NodeSocket& b_sock, BL::BlendData& b_data, BL::ID& b_id) { /* copy values for non linked inputs */ - switch(input->type) { - case SHADER_SOCKET_FLOAT: { + switch(input->type()) { + case SocketType::FLOAT: { input->set(get_float(b_sock.ptr, "default_value")); break; } - case SHADER_SOCKET_INT: { - input->set((float)get_int(b_sock.ptr, "default_value")); + case SocketType::INT: { + input->set(get_int(b_sock.ptr, "default_value")); break; } - case SHADER_SOCKET_COLOR: { + case SocketType::COLOR: { input->set(float4_to_float3(get_float4(b_sock.ptr, "default_value"))); break; } - case SHADER_SOCKET_NORMAL: - case SHADER_SOCKET_POINT: - case SHADER_SOCKET_VECTOR: { + case SocketType::NORMAL: + case SocketType::POINT: + case SocketType::VECTOR: { input->set(get_float3(b_sock.ptr, "default_value")); break; } - case SHADER_SOCKET_STRING: { + case SocketType::STRING: { input->set((ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value"))); break; } - - case SHADER_SOCKET_CLOSURE: - case SHADER_SOCKET_UNDEFINED: + default: break; } } @@ -315,7 +290,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeMixRGB)) { BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = new MixNode(); - mix->type = MixNode::type_enum[b_mix_node.blend_type()]; + mix->type = (NodeMix)b_mix_node.blend_type(); mix->use_clamp = b_mix_node.use_clamp(); node = mix; } @@ -341,27 +316,27 @@ static ShaderNode *add_node(Scene *scene, node = new HSVNode(); } else if(b_node.is_a(&RNA_ShaderNodeRGBToBW)) { - node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT); + node = new RGBToBWNode(); } else if(b_node.is_a(&RNA_ShaderNodeMath)) { BL::ShaderNodeMath b_math_node(b_node); MathNode *math = new MathNode(); - math->type = MathNode::type_enum[b_math_node.operation()]; + math->type = (NodeMath)b_math_node.operation(); math->use_clamp = b_math_node.use_clamp(); node = math; } else if(b_node.is_a(&RNA_ShaderNodeVectorMath)) { BL::ShaderNodeVectorMath b_vector_math_node(b_node); VectorMathNode *vmath = new VectorMathNode(); - vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()]; + vmath->type = (NodeVectorMath)b_vector_math_node.operation(); node = vmath; } else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = new VectorTransformNode(); - vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.vector_type()]; - vtransform->convert_from = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_from()]; - vtransform->convert_to = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_to()]; + 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(); node = vtransform; } else if(b_node.is_a(&RNA_ShaderNodeNormal)) { @@ -410,13 +385,13 @@ static ShaderNode *add_node(Scene *scene, switch(b_aniso_node.distribution()) { case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: - aniso->distribution = ustring("Beckmann"); + aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID; break; case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: - aniso->distribution = ustring("GGX"); + aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID; break; case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: - aniso->distribution = ustring("Ashikhmin-Shirley"); + aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID; break; } @@ -432,13 +407,13 @@ static ShaderNode *add_node(Scene *scene, switch(b_subsurface_node.falloff()) { case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC: - subsurface->closure = CLOSURE_BSSRDF_CUBIC_ID; + subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID; break; case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN: - subsurface->closure = CLOSURE_BSSRDF_GAUSSIAN_ID; + subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID; break; case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY: - subsurface->closure = CLOSURE_BSSRDF_BURLEY_ID; + subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID; break; } @@ -450,16 +425,16 @@ static ShaderNode *add_node(Scene *scene, switch(b_glossy_node.distribution()) { case BL::ShaderNodeBsdfGlossy::distribution_SHARP: - glossy->distribution = ustring("Sharp"); + glossy->distribution = CLOSURE_BSDF_REFLECTION_ID; break; case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: - glossy->distribution = ustring("Beckmann"); + glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; break; case BL::ShaderNodeBsdfGlossy::distribution_GGX: - glossy->distribution = ustring("GGX"); + glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; break; case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY: - glossy->distribution = ustring("Ashikhmin-Shirley"); + glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID; break; } node = glossy; @@ -469,13 +444,13 @@ static ShaderNode *add_node(Scene *scene, GlassBsdfNode *glass = new GlassBsdfNode(); switch(b_glass_node.distribution()) { case BL::ShaderNodeBsdfGlass::distribution_SHARP: - glass->distribution = ustring("Sharp"); + glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID; break; case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: - glass->distribution = ustring("Beckmann"); + glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID; break; case BL::ShaderNodeBsdfGlass::distribution_GGX: - glass->distribution = ustring("GGX"); + glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; break; } node = glass; @@ -485,13 +460,13 @@ static ShaderNode *add_node(Scene *scene, RefractionBsdfNode *refraction = new RefractionBsdfNode(); switch(b_refraction_node.distribution()) { case BL::ShaderNodeBsdfRefraction::distribution_SHARP: - refraction->distribution = ustring("Sharp"); + refraction->distribution = CLOSURE_BSDF_REFRACTION_ID; break; case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN: - refraction->distribution = ustring("Beckmann"); + refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; break; case BL::ShaderNodeBsdfRefraction::distribution_GGX: - refraction->distribution = ustring("GGX"); + refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; break; } node = refraction; @@ -501,10 +476,10 @@ static ShaderNode *add_node(Scene *scene, ToonBsdfNode *toon = new ToonBsdfNode(); switch(b_toon_node.component()) { case BL::ShaderNodeBsdfToon::component_DIFFUSE: - toon->component = ustring("Diffuse"); + toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID; break; case BL::ShaderNodeBsdfToon::component_GLOSSY: - toon->component = ustring("Glossy"); + toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID; break; } node = toon; @@ -514,10 +489,10 @@ static ShaderNode *add_node(Scene *scene, HairBsdfNode *hair = new HairBsdfNode(); switch(b_hair_node.component()) { case BL::ShaderNodeBsdfHair::component_Reflection: - hair->component = ustring("Reflection"); + hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID; break; case BL::ShaderNodeBsdfHair::component_Transmission: - hair->component = ustring("Transmission"); + hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID; break; } node = hair; @@ -584,62 +559,17 @@ static ShaderNode *add_node(Scene *scene, if(scene->shader_manager->use_osl()) { /* create script node */ BL::ShaderNodeScript b_script_node(b_node); - OSLScriptNode *script_node = new OSLScriptNode(); OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager; string bytecode_hash = b_script_node.bytecode_hash(); - /* Gather additional information from the shader, such as - * input/output type info needed for proper node construction. - */ - OSL::OSLQuery query; - string absolute_filepath; - - if(!bytecode_hash.empty()) { - query.open_bytecode(b_script_node.bytecode()); - } - else { - absolute_filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath()); - OSLShaderManager::osl_query(query, absolute_filepath); - } - /* TODO(sergey): Add proper query info error parsing. */ - - /* Generate inputs/outputs from node sockets - * - * Note: the node sockets are generated from OSL parameters, - * so the names match those of the corresponding parameters exactly. - * - * Note 2: ShaderInput/ShaderOutput store shallow string copies only! - * So we register them as ustring to ensure the pointer stays valid. */ - BL::Node::inputs_iterator b_input; - - for(b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) { - ShaderInput *input = script_node->add_input(ustring(b_input->name()).c_str(), - convert_osl_socket_type(query, *b_input)); - set_default_value(input, *b_input, b_data, b_ntree); - } - - BL::Node::outputs_iterator b_output; - - for(b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) { - script_node->add_output(ustring(b_output->name()).c_str(), - convert_osl_socket_type(query, *b_output)); - } - - /* load bytecode or filepath */ if(!bytecode_hash.empty()) { - /* loaded bytecode if not already done */ - if(!manager->shader_test_loaded(bytecode_hash)) - manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode()); - - script_node->bytecode_hash = bytecode_hash; + node = manager->osl_node("", bytecode_hash, b_script_node.bytecode()); } else { - /* set filepath */ - script_node->filepath = absolute_filepath; + string absolute_filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath()); + node = manager->osl_node(absolute_filepath, ""); } - - node = script_node; } #else (void)b_data; @@ -692,8 +622,8 @@ static ShaderNode *add_node(Scene *scene, get_image_extension(b_image_node)); } } - image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()]; - image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()]; + image->color_space = (NodeImageColorSpace)b_image_node.color_space(); + image->projection = (NodeImageProjection)b_image_node.projection(); image->interpolation = get_image_interpolation(b_image_node); image->extension = get_image_extension(b_image_node); image->projection_blend = b_image_node.projection_blend(); @@ -738,9 +668,9 @@ static ShaderNode *add_node(Scene *scene, EXTENSION_REPEAT); } } - env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; + env->color_space = (NodeImageColorSpace)b_env_node.color_space(); env->interpolation = get_image_interpolation(b_env_node); - env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()]; + env->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); node = env; @@ -748,7 +678,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeTexGradient)) { BL::ShaderNodeTexGradient b_gradient_node(b_node); GradientTextureNode *gradient = new GradientTextureNode(); - gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()]; + 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); node = gradient; @@ -756,7 +686,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeTexVoronoi)) { BL::ShaderNodeTexVoronoi b_voronoi_node(b_node); VoronoiTextureNode *voronoi = new VoronoiTextureNode(); - voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()]; + voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring(); BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping()); get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping); node = voronoi; @@ -772,8 +702,8 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeTexWave)) { BL::ShaderNodeTexWave b_wave_node(b_node); WaveTextureNode *wave = new WaveTextureNode(); - wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()]; - wave->profile = WaveTextureNode::profile_enum[(int)b_wave_node.wave_profile()]; + wave->type = (NodeWaveType)b_wave_node.wave_type(); + wave->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); node = wave; @@ -806,7 +736,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeTexMusgrave)) { BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); MusgraveTextureNode *musgrave = new MusgraveTextureNode(); - musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()]; + musgrave->type = (NodeMusgraveType)b_musgrave_node.musgrave_type(); BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping()); get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping); node = musgrave; @@ -824,7 +754,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeTexSky)) { BL::ShaderNodeTexSky b_sky_node(b_node); SkyTextureNode *sky = new SkyTextureNode(); - sky->type = SkyTextureNode::type_enum[(int)b_sky_node.sky_type()]; + 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(); @@ -835,15 +765,15 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeNormalMap)) { BL::ShaderNodeNormalMap b_normal_map_node(b_node); NormalMapNode *nmap = new NormalMapNode(); - nmap->space = NormalMapNode::space_enum[(int)b_normal_map_node.space()]; + nmap->space = (NodeNormalMapSpace)b_normal_map_node.space(); nmap->attribute = b_normal_map_node.uv_map(); node = nmap; } else if(b_node.is_a(&RNA_ShaderNodeTangent)) { BL::ShaderNodeTangent b_tangent_node(b_node); TangentNode *tangent = new TangentNode(); - tangent->direction_type = TangentNode::direction_type_enum[(int)b_tangent_node.direction_type()]; - tangent->axis = TangentNode::axis_enum[(int)b_tangent_node.axis()]; + tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type(); + tangent->axis = (NodeTangentAxis)b_tangent_node.axis(); tangent->attribute = b_tangent_node.uv_map(); node = tangent; } @@ -858,8 +788,7 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeTexPointDensity b_point_density_node(b_node); PointDensityTextureNode *point_density = new PointDensityTextureNode(); point_density->filename = b_point_density_node.name(); - point_density->space = - PointDensityTextureNode::space_enum[(int)b_point_density_node.space()]; + point_density->space = (NodeTexVoxelSpace)b_point_density_node.space(); point_density->interpolation = get_image_interpolation(b_point_density_node); point_density->builtin_data = b_point_density_node.ptr.data; @@ -1020,7 +949,7 @@ static void add_nodes(Scene *scene, BL::Node::internal_links_iterator b_link; for(b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end(); ++b_link) { BL::NodeSocket to_socket(b_link->to_socket()); - ShaderSocketType to_socket_type = convert_socket_type(to_socket); + SocketType::Type to_socket_type = convert_socket_type(to_socket); ConvertNode *proxy = new ConvertNode(to_socket_type, to_socket_type, true); input_map[b_link->from_socket().ptr.data] = proxy->inputs[0]; @@ -1043,7 +972,7 @@ static void add_nodes(Scene *scene, * so that links have something to connect to and assert won't fail. */ for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) { - ShaderSocketType input_type = convert_socket_type(*b_input); + SocketType::Type input_type = convert_socket_type(*b_input); ConvertNode *proxy = new ConvertNode(input_type, input_type, true); graph->add(proxy); @@ -1055,7 +984,7 @@ static void add_nodes(Scene *scene, set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree); } for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) { - ShaderSocketType output_type = convert_socket_type(*b_output); + SocketType::Type output_type = convert_socket_type(*b_output); ConvertNode *proxy = new ConvertNode(output_type, output_type, true); graph->add(proxy); @@ -1227,7 +1156,7 @@ void BlenderSync::sync_materials(bool update_all) ShaderNode *closure, *out; closure = graph->add(new DiffuseBsdfNode()); - closure->input("Color")->value = get_float3(b_mat->diffuse_color()); + closure->input("Color")->set(get_float3(b_mat->diffuse_color())); out = graph->output(); graph->connect(closure->output("BSDF"), out->input("Surface")); @@ -1276,7 +1205,7 @@ void BlenderSync::sync_world(bool update_all) ShaderNode *closure, *out; closure = graph->add(new BackgroundNode()); - closure->input("Color")->value = get_float3(b_world.horizon_color()); + closure->input("Color")->set(get_float3(b_world.horizon_color())); out = graph->output(); graph->connect(closure->output("Background"), out->input("Surface")); @@ -1369,8 +1298,8 @@ void BlenderSync::sync_lamps(bool update_all) } closure = graph->add(new EmissionNode()); - closure->input("Color")->value = get_float3(b_lamp->color()); - closure->input("Strength")->value.x = strength; + closure->input("Color")->set(get_float3(b_lamp->color())); + closure->input("Strength")->set(strength); out = graph->output(); graph->connect(closure->output("Emission"), out->input("Surface")); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index e23d8bf4e2d..2510cebcdc0 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -98,11 +98,12 @@ static inline void curvemapping_minmax(/*const*/ BL::CurveMapping& cumap, } static inline void curvemapping_to_array(BL::CurveMapping& cumap, - float *data, + array<float>& data, int size) { cumap.update(); BL::CurveMap curve = cumap.curves[0]; + data.resize(size); for(int i = 0; i < size; i++) { float t = (float)i/(float)(size-1); data[i] = curve.evaluate(t); diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 5c474c8c3e9..fa2b9ae7279 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -128,11 +128,11 @@ void BVH::pack_triangle(int idx, float4 storage[3]) const Mesh *mesh = objects[tob]->mesh; int tidx = pack.prim_index[idx]; - const int *vidx = mesh->triangles[tidx].v; + Mesh::Triangle t = mesh->get_triangle(tidx); const float3* vpos = &mesh->verts[0]; - float3 v0 = vpos[vidx[0]]; - float3 v1 = vpos[vidx[1]]; - float3 v2 = vpos[vidx[2]]; + float3 v0 = vpos[t.v[0]]; + float3 v1 = vpos[t.v[1]]; + float3 v2 = vpos[t.v[2]]; storage[0] = float3_to_float4(v0); storage[1] = float3_to_float4(v1); @@ -506,10 +506,10 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* curves */ int str_offset = (params.top_level)? mesh->curve_offset: 0; - const Mesh::Curve& curve = mesh->curves[pidx - str_offset]; + Mesh::Curve curve = mesh->get_curve(pidx - str_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); - curve.bounds_grow(k, &mesh->curve_keys[0], bbox); + curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox); visibility |= PATH_RAY_CURVE; @@ -520,17 +520,17 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility if(attr) { size_t mesh_size = mesh->curve_keys.size(); size_t steps = mesh->motion_steps - 1; - float4 *key_steps = attr->data_float4(); + float3 *key_steps = attr->data_float3(); for(size_t i = 0; i < steps; i++) - curve.bounds_grow(k, key_steps + i*mesh_size, bbox); + curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox); } } } else { /* triangles */ int tri_offset = (params.top_level)? mesh->tri_offset: 0; - const Mesh::Triangle& triangle = mesh->triangles[pidx - tri_offset]; + Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset); const float3 *vpos = &mesh->verts[0]; triangle.bounds_grow(vpos, bbox); @@ -770,10 +770,10 @@ void QBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ int str_offset = (params.top_level)? mesh->curve_offset: 0; - const Mesh::Curve& curve = mesh->curves[pidx - str_offset]; + Mesh::Curve curve = mesh->get_curve(pidx - str_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); - curve.bounds_grow(k, &mesh->curve_keys[0], bbox); + curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox); visibility |= PATH_RAY_CURVE; @@ -784,17 +784,17 @@ void QBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) if(attr) { size_t mesh_size = mesh->curve_keys.size(); size_t steps = mesh->motion_steps - 1; - float4 *key_steps = attr->data_float4(); + float3 *key_steps = attr->data_float3(); for(size_t i = 0; i < steps; i++) - curve.bounds_grow(k, key_steps + i*mesh_size, bbox); + curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox); } } } else { /* Triangles. */ int tri_offset = (params.top_level)? mesh->tri_offset: 0; - const Mesh::Triangle& triangle = mesh->triangles[pidx - tri_offset]; + Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset); const float3 *vpos = &mesh->verts[0]; triangle.bounds_grow(vpos, bbox); diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 76a1bfa2bfe..d00de007b2d 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -117,8 +117,9 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, if(mesh->has_motion_blur()) attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - for(uint j = 0; j < mesh->triangles.size(); j++) { - Mesh::Triangle t = mesh->triangles[j]; + size_t num_triangles = mesh->num_triangles(); + for(uint j = 0; j < num_triangles; j++) { + Mesh::Triangle t = mesh->get_triangle(j); BoundBox bounds = BoundBox::empty; PrimitiveType type = PRIMITIVE_TRIANGLE; @@ -148,22 +149,23 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, if(mesh->has_motion_blur()) curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - for(uint j = 0; j < mesh->curves.size(); j++) { - Mesh::Curve curve = mesh->curves[j]; + size_t num_curves = mesh->num_curves(); + for(uint j = 0; j < num_curves; j++) { + Mesh::Curve curve = mesh->get_curve(j); PrimitiveType type = PRIMITIVE_CURVE; for(int k = 0; k < curve.num_keys - 1; k++) { BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &mesh->curve_keys[0], bounds); + curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bounds); /* motion curve */ if(curve_attr_mP) { size_t mesh_size = mesh->curve_keys.size(); size_t steps = mesh->motion_steps - 1; - float4 *key_steps = curve_attr_mP->data_float4(); + float3 *key_steps = curve_attr_mP->data_float3(); for(size_t i = 0; i < steps; i++) - curve.bounds_grow(k, key_steps + i*mesh_size, bounds); + curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bounds); type = PRIMITIVE_MOTION_CURVE; } @@ -188,10 +190,10 @@ void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob static size_t count_curve_segments(Mesh *mesh) { - size_t num = 0, num_curves = mesh->curves.size(); + size_t num = 0, num_curves = mesh->num_curves(); for(size_t i = 0; i < num_curves; i++) - num += mesh->curves[i].num_keys - 1; + num += mesh->get_curve(i).num_keys - 1; return num; } @@ -203,15 +205,18 @@ void BVHBuild::add_references(BVHRange& root) foreach(Object *ob, objects) { if(params.top_level) { + if(!ob->is_traceable()) { + continue; + } if(!ob->mesh->is_instanced()) { - num_alloc_references += ob->mesh->triangles.size(); + num_alloc_references += ob->mesh->num_triangles(); num_alloc_references += count_curve_segments(ob->mesh); } else num_alloc_references++; } else { - num_alloc_references += ob->mesh->triangles.size(); + num_alloc_references += ob->mesh->num_triangles(); num_alloc_references += count_curve_segments(ob->mesh); } } @@ -224,6 +229,9 @@ void BVHBuild::add_references(BVHRange& root) foreach(Object *ob, objects) { if(params.top_level) { + if(!ob->is_traceable()) { + continue; + } if(!ob->mesh->is_instanced()) add_reference_mesh(bounds, center, ob->mesh, i); else @@ -326,11 +334,11 @@ BVHNode* BVHBuild::run() VLOG(1) << "BVH build statistics:\n" << " Build time: " << time_dt() - build_start_time << "\n" << " Total number of nodes: " - << rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT) << "\n" + << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT)) << "\n" << " Number of inner nodes: " - << rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT) << "\n" + << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT)) << "\n" << " Number of leaf nodes: " - << rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT) << "\n" + << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT)) << "\n" << " Allocation slop factor: " << ((prim_type.capacity() != 0) ? (float)prim_type.size() / prim_type.capacity() diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 8084975565e..bf68b41021f 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -292,13 +292,13 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, BoundBox& left_bounds, BoundBox& right_bounds) { - const int *inds = mesh->triangles[prim_index].v; + Mesh::Triangle t = mesh->get_triangle(prim_index); const float3 *verts = &mesh->verts[0]; - float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]]; + float3 v1 = tfm ? transform_point(tfm, verts[t.v[2]]) : verts[t.v[2]]; for(int i = 0; i < 3; i++) { float3 v0 = v1; - int vindex = inds[i]; + int vindex = t.v[i]; v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex]; float v0p = v0[dim]; float v1p = v1[dim]; @@ -329,12 +329,11 @@ void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, BoundBox& right_bounds) { /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ - const int k0 = mesh->curves[prim_index].first_key + segment_index; + Mesh::Curve curve = mesh->get_curve(prim_index); + const int k0 = curve.first_key + segment_index; const int k1 = k0 + 1; - const float4& key0 = mesh->curve_keys[k0]; - const float4& key1 = mesh->curve_keys[k1]; - float3 v0 = float4_to_float3(key0); - float3 v1 = float4_to_float3(key1); + float3 v0 = mesh->curve_keys[k0]; + float3 v1 = mesh->curve_keys[k1]; if(tfm != NULL) { v0 = transform_point(tfm, v0); @@ -405,7 +404,7 @@ void BVHSpatialSplit::split_object_reference(const Object *object, BoundBox& right_bounds) { Mesh *mesh = object->mesh; - for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) { + for(int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) { split_triangle_primitive(mesh, &object->tfm, tri_idx, @@ -414,8 +413,8 @@ void BVHSpatialSplit::split_object_reference(const Object *object, left_bounds, right_bounds); } - for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) { - Mesh::Curve &curve = mesh->curves[curve_idx]; + for(int curve_idx = 0; curve_idx < mesh->num_curves(); ++curve_idx) { + Mesh::Curve curve = mesh->get_curve(curve_idx); for(int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 275ee028eb4..aed86d8d853 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -155,7 +155,9 @@ public: InterpolationType interpolation, ExtensionType extension) { - VLOG(1) << "Texture allocate: " << name << ", " << mem.memory_size() << " bytes."; + VLOG(1) << "Texture allocate: " << name << ", " + << string_human_readable_number(mem.memory_size()) << " bytes. (" + << string_human_readable_size(mem.memory_size()) << ")"; kernel_tex_copy(&kernel_globals, name, mem.data_pointer, diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 9a78d055580..2d404918a38 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -493,7 +493,9 @@ public: InterpolationType interpolation, ExtensionType extension) { - VLOG(1) << "Texture allocate: " << name << ", " << mem.memory_size() << " bytes."; + VLOG(1) << "Texture allocate: " << name << ", " + << string_human_readable_number(mem.memory_size()) << " bytes. (" + << string_human_readable_size(mem.memory_size()) << ")"; /* Check if we are on sm_30 or above. * We use arrays and bindles textures for storage there */ @@ -1366,6 +1368,7 @@ void device_cuda_info(vector<DeviceInfo>& devices) /* if device has a kernel timeout, assume it is used for display */ if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) { + info.description += " (Display)"; info.display_device = true; display_devices.push_back(info); } diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index 434d0085d39..c4f8d9e16e0 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -175,7 +175,9 @@ public: interpolation, ExtensionType extension) { - VLOG(1) << "Texture allocate: " << name << ", " << mem.memory_size() << " bytes."; + VLOG(1) << "Texture allocate: " << name << ", " + << string_human_readable_number(mem.memory_size()) << " bytes. (" + << string_human_readable_size(mem.memory_size()) << ")"; foreach(SubDevice& sub, devices) { mem.device_pointer = 0; diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp index cf4a05de8fc..3eb5ad2d2db 100644 --- a/intern/cycles/device/device_network.cpp +++ b/intern/cycles/device/device_network.cpp @@ -168,7 +168,9 @@ public: InterpolationType interpolation, ExtensionType extension) { - VLOG(1) << "Texture allocate: " << name << ", " << mem.memory_size() << " bytes."; + VLOG(1) << "Texture allocate: " << name << ", " + << string_human_readable_number(mem.memory_size()) << " bytes. (" + << string_human_readable_size(mem.memory_size()) << ")"; thread_scoped_lock lock(rpc_lock); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 1b4e5421b5a..afe21c49730 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -1187,7 +1187,9 @@ public: InterpolationType /*interpolation*/, ExtensionType /*extension*/) { - VLOG(1) << "Texture allocate: " << name << ", " << mem.memory_size() << " bytes."; + VLOG(1) << "Texture allocate: " << name << ", " + << string_human_readable_number(mem.memory_size()) << " bytes. (" + << string_human_readable_size(mem.memory_size()) << ")"; mem_alloc(mem, MEM_READ_ONLY); mem_copy_to(mem); assert(mem_map.find(name) == mem_map.end()); @@ -1222,18 +1224,28 @@ public: CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &workgroup_size, NULL); clGetDeviceInfo(cdDevice, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t)*3, max_work_items, NULL); - - /* try to divide evenly over 2 dimensions */ + + /* Try to divide evenly over 2 dimensions. */ size_t sqrt_workgroup_size = max((size_t)sqrt((double)workgroup_size), 1); size_t local_size[2] = {sqrt_workgroup_size, sqrt_workgroup_size}; - /* some implementations have max size 1 on 2nd dimension */ + /* Some implementations have max size 1 on 2nd dimension. */ if(local_size[1] > max_work_items[1]) { local_size[0] = workgroup_size/max_work_items[1]; local_size[1] = max_work_items[1]; } - size_t global_size[2] = {global_size_round_up(local_size[0], w), global_size_round_up(local_size[1], h)}; + size_t global_size[2] = {global_size_round_up(local_size[0], w), + global_size_round_up(local_size[1], h)}; + + /* Vertical size of 1 is coming from bake/shade kernels where we should + * not round anything up because otherwise we'll either be doing too + * much work per pixel (if we don't check global ID on Y axis) or will + * be checking for global ID to always have Y of 0. + */ + if (h == 1) { + global_size[h] = 1; + } /* run kernel */ opencl_assert(clEnqueueNDRangeKernel(cqCommandQueue, kernel, 2, NULL, global_size, NULL, 0, NULL, NULL)); @@ -1318,48 +1330,49 @@ public: else kernel = ckShaderKernel; - for(int sample = 0; sample < task.num_samples; sample++) { - - if(task.get_cancel()) - break; - - cl_int d_sample = sample; - - cl_uint start_arg_index = - kernel_set_args(kernel, - 0, - d_data, - d_input, - d_output); + cl_uint start_arg_index = + kernel_set_args(kernel, + 0, + d_data, + d_input, + d_output); - if(task.shader_eval_type < SHADER_EVAL_BAKE) { - start_arg_index += kernel_set_args(kernel, - start_arg_index, - d_output_luma); - } + if(task.shader_eval_type < SHADER_EVAL_BAKE) { + start_arg_index += kernel_set_args(kernel, + start_arg_index, + d_output_luma); + } #define KERNEL_TEX(type, ttype, name) \ - set_kernel_arg_mem(kernel, &start_arg_index, #name); + set_kernel_arg_mem(kernel, &start_arg_index, #name); #include "kernel_textures.h" #undef KERNEL_TEX + start_arg_index += kernel_set_args(kernel, + start_arg_index, + d_shader_eval_type); + if(task.shader_eval_type >= SHADER_EVAL_BAKE) { start_arg_index += kernel_set_args(kernel, start_arg_index, - d_shader_eval_type); - if(task.shader_eval_type >= SHADER_EVAL_BAKE) { - start_arg_index += kernel_set_args(kernel, - start_arg_index, - d_shader_filter); - } - start_arg_index += kernel_set_args(kernel, - start_arg_index, - d_shader_x, - d_shader_w, - d_offset, - d_sample); + d_shader_filter); + } + start_arg_index += kernel_set_args(kernel, + start_arg_index, + d_shader_x, + d_shader_w, + d_offset); + + for(int sample = 0; sample < task.num_samples; sample++) { + + if(task.get_cancel()) + break; + + kernel_set_args(kernel, start_arg_index, sample); enqueue_kernel(kernel, task.shader_w, 1); + clFinish(cqCommandQueue); + task.update_progress(NULL); } } diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index d482577b73b..941a66741c5 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -36,12 +36,8 @@ Node::Node(const NodeType *type_, ustring name_) } /* initialize default values */ - typedef unordered_map<ustring, SocketType, ustringHash> map_type; - foreach(const map_type::value_type& it, type->inputs) { - const SocketType& socket = it.second; - const void *src = socket.default_value; - void *dst = ((char*)this) + socket.struct_offset; - memcpy(dst, src, socket.size()); + foreach(const SocketType& socket, type->inputs) { + set_default_value(socket); } } @@ -104,6 +100,11 @@ void Node::set(const SocketType& input, float3 value) get_socket_value<float3>(this, input) = value; } +void Node::set(const SocketType& input, const char *value) +{ + set(input, ustring(value)); +} + void Node::set(const SocketType& input, ustring value) { if(input.type == SocketType::STRING) { @@ -292,7 +293,8 @@ const array<Node*>& Node::get_node_array(const SocketType& input) const return get_socket_value<array<Node*> >(this, input); } -/* default values */ +/* generic value operations */ + bool Node::has_default_value(const SocketType& input) const { const void *src = input.default_value; @@ -300,6 +302,48 @@ bool Node::has_default_value(const SocketType& input) const return memcmp(dst, src, input.size()) == 0; } +void Node::set_default_value(const SocketType& socket) +{ + const void *src = socket.default_value; + void *dst = ((char*)this) + socket.struct_offset; + memcpy(dst, src, socket.size()); +} + +template<typename T> +static void copy_array(const Node *node, const SocketType& socket, const Node *other, const SocketType& other_socket) +{ + const array<T>* src = (const array<T>*)(((char*)other) + other_socket.struct_offset); + array<T>* dst = (array<T>*)(((char*)node) + socket.struct_offset); + *dst = *src; +} + +void Node::copy_value(const SocketType& socket, const Node& other, const SocketType& other_socket) +{ + assert(socket.type == other_socket.type); + + if(socket.is_array()) { + switch(socket.type) { + case SocketType::BOOLEAN_ARRAY: copy_array<bool>(this, socket, &other, other_socket); break; + case SocketType::FLOAT_ARRAY: copy_array<float>(this, socket, &other, other_socket); break; + case SocketType::INT_ARRAY: copy_array<int>(this, socket, &other, other_socket); break; + case SocketType::COLOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break; + case SocketType::VECTOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break; + case SocketType::POINT_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break; + case SocketType::NORMAL_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break; + case SocketType::POINT2_ARRAY: copy_array<float2>(this, socket, &other, other_socket); break; + case SocketType::STRING_ARRAY: copy_array<ustring>(this, socket, &other, other_socket); break; + case SocketType::TRANSFORM_ARRAY: copy_array<Transform>(this, socket, &other, other_socket); break; + case SocketType::NODE_ARRAY: copy_array<void*>(this, socket, &other, other_socket); break; + default: assert(0); break; + } + } + else { + const void *src = ((char*)&other) + other_socket.struct_offset; + void *dst = ((char*)this) + socket.struct_offset; + memcpy(dst, src, socket.size()); + } +} + template<typename T> static bool is_array_equal(const Node *node, const Node *other, const SocketType& socket) { @@ -308,48 +352,43 @@ static bool is_array_equal(const Node *node, const Node *other, const SocketType return *a == *b; } -/* modified */ -bool Node::modified(const Node& other) +bool Node::equals_value(const Node& other, const SocketType& socket) const +{ + if(socket.is_array()) { + switch(socket.type) { + case SocketType::BOOLEAN_ARRAY: return is_array_equal<bool>(this, &other, socket); + case SocketType::FLOAT_ARRAY: return is_array_equal<float>(this, &other, socket); + case SocketType::INT_ARRAY: return is_array_equal<int>(this, &other, socket); + case SocketType::COLOR_ARRAY: return is_array_equal<float3>(this, &other, socket); + case SocketType::VECTOR_ARRAY: return is_array_equal<float3>(this, &other, socket); + case SocketType::POINT_ARRAY: return is_array_equal<float3>(this, &other, socket); + case SocketType::NORMAL_ARRAY: return is_array_equal<float3>(this, &other, socket); + case SocketType::POINT2_ARRAY: return is_array_equal<float2>(this, &other, socket); + case SocketType::STRING_ARRAY: return is_array_equal<ustring>(this, &other, socket); + case SocketType::TRANSFORM_ARRAY: return is_array_equal<Transform>(this, &other, socket); + case SocketType::NODE_ARRAY: return is_array_equal<void*>(this, &other, socket); + default: assert(0); return true; + } + } + else { + const void *a = ((char*)this) + socket.struct_offset; + const void *b = ((char*)&other) + socket.struct_offset; + return (memcmp(a, b, socket.size()) == 0); + } +} + +/* equals */ + +bool Node::equals(const Node& other) const { assert(type == other.type); - typedef unordered_map<ustring, SocketType, ustringHash> map_type; - foreach(const map_type::value_type& it, type->inputs) { - const SocketType& socket = it.second; - - if(socket.is_array()) { - bool equal = true; - - switch(socket.type) - { - case SocketType::BOOLEAN_ARRAY: equal = is_array_equal<bool>(this, &other, socket); break; - case SocketType::FLOAT_ARRAY: equal = is_array_equal<float>(this, &other, socket); break; - case SocketType::INT_ARRAY: equal = is_array_equal<int>(this, &other, socket); break; - case SocketType::COLOR_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break; - case SocketType::VECTOR_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break; - case SocketType::POINT_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break; - case SocketType::NORMAL_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break; - case SocketType::POINT2_ARRAY: equal = is_array_equal<float2>(this, &other, socket); break; - case SocketType::STRING_ARRAY: equal = is_array_equal<ustring>(this, &other, socket); break; - case SocketType::TRANSFORM_ARRAY: equal = is_array_equal<Transform>(this, &other, socket); break; - case SocketType::NODE_ARRAY: equal = is_array_equal<void*>(this, &other, socket); break; - default: assert(0); break; - } - - if(!equal) { - return true; - } - } - else { - const void *a = ((char*)this) + socket.struct_offset; - const void *b = ((char*)&other) + socket.struct_offset; - if(memcmp(a, b, socket.size()) != 0) { - return true; - } - } + foreach(const SocketType& socket, type->inputs) { + if(!equals_value(other, socket)) + return false; } - return false; + return true; } CCL_NAMESPACE_END diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index 33971fa714a..bb84f982fb3 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -41,6 +41,7 @@ struct Node void set(const SocketType& input, float value); void set(const SocketType& input, float2 value); void set(const SocketType& input, float3 value); + void set(const SocketType& input, const char *value); void set(const SocketType& input, ustring value); void set(const SocketType& input, const Transform& value); void set(const SocketType& input, Node *value); @@ -76,11 +77,14 @@ struct Node const array<Transform>& get_transform_array(const SocketType& input) const; const array<Node*>& get_node_array(const SocketType& input) const; - /* default values */ + /* generic values operations */ bool has_default_value(const SocketType& input) const; + 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); - /* modified */ - bool modified(const Node& other); + /* equals */ + bool equals(const Node& other) const; ustring name; const NodeType *type; diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp index dc879655d7f..7f68ae9c7c7 100644 --- a/intern/cycles/graph/node_type.cpp +++ b/intern/cycles/graph/node_type.cpp @@ -114,9 +114,15 @@ ustring SocketType::type_name(Type type) return names[(int)type]; } +bool SocketType::is_float3(Type type) +{ + return (type == COLOR || type == VECTOR || type == POINT || type == NORMAL); +} + /* Node Type */ -NodeType::NodeType() +NodeType::NodeType(Type type_) +: type(type_) { } @@ -137,7 +143,7 @@ void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type ty socket.enum_values = enum_values; socket.node_type = node_type; socket.flags = flags | extra_flags; - inputs[name] = socket; + inputs.push_back(socket); } void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type type) @@ -151,7 +157,29 @@ void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type t socket.enum_values = NULL; socket.node_type = NULL; socket.flags = SocketType::LINKABLE; - outputs[name] = socket; + outputs.push_back(socket); +} + +const SocketType *NodeType::find_input(ustring name) const +{ + foreach(const SocketType& socket, inputs) { + if(socket.name == name) { + return &socket; + } + } + + return NULL; +} + +const SocketType *NodeType::find_output(ustring name) const +{ + foreach(const SocketType& socket, outputs) { + if(socket.name == name) { + return &socket; + } + } + + return NULL; } /* Node Type Registry */ @@ -162,7 +190,7 @@ unordered_map<ustring, NodeType, ustringHash>& NodeType::types() return _types; } -NodeType *NodeType::add(const char *name_, CreateFunc create_) +NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_) { ustring name(name_); @@ -172,7 +200,7 @@ NodeType *NodeType::add(const char *name_, CreateFunc create_) return NULL; } - types()[name] = NodeType(); + types()[name] = NodeType(type_); NodeType *type = &types()[name]; type->name = name; diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h index 82ddd29da33..20816f634cd 100644 --- a/intern/cycles/graph/node_type.h +++ b/intern/cycles/graph/node_type.h @@ -21,6 +21,7 @@ #include "util_map.h" #include "util_param.h" #include "util_string.h" +#include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -94,13 +95,19 @@ struct SocketType static size_t max_size(); static ustring type_name(Type type); static void *zero_default_value(); + static bool is_float3(Type type); }; /* Node Type */ struct NodeType { - explicit NodeType(); + enum Type { + NONE, + SHADER + }; + + explicit NodeType(Type type = NONE); ~NodeType(); void register_input(ustring name, ustring ui_name, SocketType::Type type, @@ -110,15 +117,18 @@ struct NodeType int flags = 0, int extra_flags = 0); void register_output(ustring name, ustring ui_name, SocketType::Type type); + const SocketType *find_input(ustring name) const; + const SocketType *find_output(ustring name) const; + typedef Node *(*CreateFunc)(const NodeType *type); - typedef unordered_map<ustring, SocketType, ustringHash> SocketMap; ustring name; - SocketMap inputs; - SocketMap outputs; + Type type; + std::vector<SocketType> inputs; + std::vector<SocketType> outputs; CreateFunc create; - static NodeType *add(const char *name, CreateFunc create); + static NodeType *add(const char *name, CreateFunc create, Type type = NONE); static const NodeType *find(ustring name); static unordered_map<ustring, NodeType, ustringHash>& types(); }; diff --git a/intern/cycles/graph/node_xml.cpp b/intern/cycles/graph/node_xml.cpp index fe06a243998..022de7cf32a 100644 --- a/intern/cycles/graph/node_xml.cpp +++ b/intern/cycles/graph/node_xml.cpp @@ -58,9 +58,7 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node) node->name = ustring(name_attr.value()); } - foreach(const NodeType::SocketMap::value_type& it, node->type->inputs) { - const SocketType& socket = it.second; - + foreach(const SocketType& socket, node->type->inputs) { if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) { continue; } @@ -117,8 +115,9 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node) array<int> value; value.resize(tokens.size()); - for(size_t i = 0; i < value.size(); i++) + for(size_t i = 0; i < value.size(); i++) { value[i] = (int)atoi(attr.value()); + } node->set(socket, value); break; } @@ -127,7 +126,7 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node) case SocketType::POINT: case SocketType::NORMAL: { - array<float> value; + array<float3> value; xml_read_float_array<3>(value, attr); if(value.size() == 1) { node->set(socket, value[0]); @@ -161,11 +160,21 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node) break; } case SocketType::STRING: - case SocketType::ENUM: { node->set(socket, attr.value()); break; } + case SocketType::ENUM: + { + ustring value(attr.value()); + if(socket.enum_values->exists(value)) { + node->set(socket, value); + } + else { + fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", value.c_str(), socket.name.c_str()); + } + break; + } case SocketType::STRING_ARRAY: { vector<string> tokens; @@ -173,8 +182,9 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node) array<ustring> value; value.resize(tokens.size()); - for(size_t i = 0; i < value.size(); i++) + for(size_t i = 0; i < value.size(); i++) { value[i] = ustring(tokens[i]); + } node->set(socket, value); break; } @@ -245,9 +255,7 @@ pugi::xml_node xml_write_node(Node *node, pugi::xml_node xml_root) xml_node.append_attribute("name") = node->name.c_str(); - foreach(const NodeType::SocketMap::value_type& it, node->type->inputs) { - const SocketType& socket = it.second; - + foreach(const SocketType& socket, node->type->inputs) { if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) { continue; } diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 7c2fc1e4b14..61c484df094 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -234,6 +234,7 @@ if(WITH_CYCLES_CUDA_BINARIES) OUTPUT ${cuda_cubin} COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} + ${CUDA_NVCC_FLAGS} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h index 9eadc97386c..d0eedd3396a 100644 --- a/intern/cycles/kernel/geom/geom_bvh.h +++ b/intern/cycles/kernel/geom/geom_bvh.h @@ -48,6 +48,28 @@ CCL_NAMESPACE_BEGIN #define BVH_FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0) +/* Debugging heleprs */ +#ifdef __KERNEL_DEBUG__ +# define BVH_DEBUG_INIT() \ + do { \ + isect->num_traversal_steps = 0; \ + isect->num_traversed_instances = 0; \ + } while(0) +# define BVH_DEBUG_NEXT_STEP() \ + do { \ + ++isect->num_traversal_steps; \ + } while(0) +# define BVH_DEBUG_NEXT_INSTANCE() \ + do { \ + ++isect->num_traversed_instances; \ + } while(0) +#else /* __KERNEL_DEBUG__ */ +# define BVH_DEBUG_INIT() +# define BVH_DEBUG_NEXT_STEP() +# define BVH_DEBUG_NEXT_INSTANCE() +#endif /* __KERNEL_DEBUG__ */ + + /* Common QBVH functions. */ #ifdef __QBVH__ # include "geom_qbvh.h" diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h index 8560612addc..ae919ef3f86 100644 --- a/intern/cycles/kernel/geom/geom_bvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h @@ -74,10 +74,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, isect->prim = PRIM_NONE; isect->object = OBJECT_NONE; -#if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps = 0; - isect->num_traversed_instances = 0; -#endif + BVH_DEBUG_INIT(); #if defined(__KERNEL_SSE2__) const shuffle_swap_t shuf_identity = shuffle_swap_identity(); @@ -241,10 +238,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, --stackPtr; } } - -#if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -#endif + BVH_DEBUG_NEXT_STEP(); } /* if node is leaf, fetch triangle list */ @@ -266,9 +260,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, switch(type & PRIMITIVE_ALL) { case PRIMITIVE_TRIANGLE: { for(; primAddr < primAddr2; primAddr++) { -#if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -#endif + BVH_DEBUG_NEXT_STEP(); kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); if(triangle_intersect(kg, &isect_precalc, isect, P, visibility, object, primAddr)) { /* shadow ray early termination */ @@ -287,9 +279,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, #if BVH_FEATURE(BVH_MOTION) case PRIMITIVE_MOTION_TRIANGLE: { for(; primAddr < primAddr2; primAddr++) { -# if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -# endif + BVH_DEBUG_NEXT_STEP(); kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); if(motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr)) { /* shadow ray early termination */ @@ -310,9 +300,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, case PRIMITIVE_CURVE: case PRIMITIVE_MOTION_CURVE: { for(; primAddr < primAddr2; primAddr++) { -# if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -# endif + BVH_DEBUG_NEXT_STEP(); kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); bool hit; if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) @@ -364,9 +352,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, nodeAddr = kernel_tex_fetch(__object_node, object); -# if defined(__KERNEL_DEBUG__) - isect->num_traversed_instances++; -# endif + BVH_DEBUG_NEXT_INSTANCE(); } } #endif /* FEATURE(BVH_INSTANCING) */ diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h index ce3bbbdf957..738d08ac6fc 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h @@ -78,10 +78,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, isect->prim = PRIM_NONE; isect->object = OBJECT_NONE; -#if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps = 0; - isect->num_traversed_instances = 0; -#endif + BVH_DEBUG_INIT(); ssef tnear(0.0f), tfar(ray->t); sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z)); @@ -120,9 +117,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, int traverseChild; ssef dist; -#if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -#endif + BVH_DEBUG_NEXT_STEP(); #if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH) if(difl != 0.0f) { @@ -295,9 +290,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, switch(type & PRIMITIVE_ALL) { case PRIMITIVE_TRIANGLE: { for(; primAddr < primAddr2; primAddr++) { -#if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -#endif + BVH_DEBUG_NEXT_STEP(); kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); if(triangle_intersect(kg, &isect_precalc, isect, P, visibility, object, primAddr)) { tfar = ssef(isect->t); @@ -311,9 +304,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, #if BVH_FEATURE(BVH_MOTION) case PRIMITIVE_MOTION_TRIANGLE: { for(; primAddr < primAddr2; primAddr++) { -# if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -# endif + BVH_DEBUG_NEXT_STEP(); kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); if(motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr)) { tfar = ssef(isect->t); @@ -329,9 +320,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, case PRIMITIVE_CURVE: case PRIMITIVE_MOTION_CURVE: { for(; primAddr < primAddr2; primAddr++) { -# if defined(__KERNEL_DEBUG__) - isect->num_traversal_steps++; -# endif + BVH_DEBUG_NEXT_STEP(); kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); bool hit; if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) @@ -381,9 +370,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, nodeAddr = kernel_tex_fetch(__object_node, object); -# if defined(__KERNEL_DEBUG__) - isect->num_traversed_instances++; -# endif + BVH_DEBUG_NEXT_INSTANCE(); } } #endif /* FEATURE(BVH_INSTANCING) */ diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index d2957ad5474..b6dfc769012 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -159,16 +159,11 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility) #endif { -#ifdef __KERNEL_GPU__ - float4 a = tri_b - tri_a, b = tri_c - tri_a; - if(len_squared(make_float3(a.y*b.z - a.z*b.y, - a.z*b.x - a.x*b.z, - a.x*b.y - a.y*b.x)) == 0.0f) - { +#ifdef __KERNEL_CUDA__ + if(A == B && B == C) { return false; } #endif - /* Normalize U, V, W, and T. */ const float inv_det = 1.0f / det; isect->prim = triAddr; diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index 392cff9c281..8d05befe1d4 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -30,6 +30,9 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian Ray ray; float3 throughput = make_float3(1.0f, 1.0f, 1.0f); + /* emission and indirect shader data memory used by various functions */ + ShaderData emission_sd, indirect_sd; + ray.P = sd->P + sd->Ng; ray.D = -sd->Ng; ray.t = FLT_MAX; @@ -41,7 +44,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian path_radiance_init(&L_sample, kernel_data.film.use_light_pass); /* init path state */ - path_state_init(kg, &state, &rng, sample, NULL); + path_state_init(kg, &emission_sd, &state, &rng, sample, NULL); /* evaluate surface shader */ float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF); @@ -56,7 +59,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian /* sample ambient occlusion */ if(pass_filter & BAKE_FILTER_AO) { - kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput); + kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, &rng, throughput); } /* sample emission */ @@ -75,6 +78,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian kernel_path_subsurface_init_indirect(&ss_indirect); if(kernel_path_subsurface_scatter(kg, sd, + &emission_sd, &L_sample, &state, &rng, @@ -90,6 +94,8 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian &L_sample, &throughput); kernel_path_indirect(kg, + &indirect_sd, + &emission_sd, &rng, &ray, throughput, @@ -105,14 +111,14 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian /* sample light and BSDF */ if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) { - kernel_path_surface_connect_light(kg, &rng, sd, throughput, &state, &L_sample); + kernel_path_surface_connect_light(kg, &rng, sd, &emission_sd, throughput, &state, &L_sample); if(kernel_path_surface_bounce(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) { #ifdef __LAMP_MIS__ state.ray_t = 0.0f; #endif /* compute indirect light */ - kernel_path_indirect(kg, &rng, &ray, throughput, 1, &state, &L_sample); + kernel_path_indirect(kg, &indirect_sd, &emission_sd, &rng, &ray, throughput, 1, &state, &L_sample); /* sum and reset indirect light pass variables for the next samples */ path_radiance_sum_indirect(&L_sample); @@ -126,7 +132,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian /* sample ambient occlusion */ if(pass_filter & BAKE_FILTER_AO) { - kernel_branched_path_ao(kg, sd, &L_sample, &state, &rng, throughput); + kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, &rng, throughput); } /* sample emission */ @@ -139,7 +145,8 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian /* sample subsurface scattering */ if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) { /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */ - kernel_branched_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, throughput); + kernel_branched_path_subsurface_scatter(kg, sd, &indirect_sd, + &emission_sd, &L_sample, &state, &rng, &ray, throughput); } #endif @@ -150,13 +157,13 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian if(kernel_data.integrator.use_direct_light) { int all = kernel_data.integrator.sample_all_lights_direct; kernel_branched_path_surface_connect_light(kg, &rng, - sd, &state, throughput, 1.0f, &L_sample, all); + sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all); } #endif /* indirect light */ kernel_branched_path_surface_indirect_light(kg, &rng, - sd, throughput, 1.0f, &state, &L_sample); + sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample); } } #endif @@ -475,12 +482,10 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, } /* write output */ - float output_fac = is_aa_pass(type)? 1.0f/num_samples: 1.0f; + const float output_fac = is_aa_pass(type)? 1.0f/num_samples: 1.0f; + const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac; - if(sample == 0) - output[i] = make_float4(out.x, out.y, out.z, 1.0f) * output_fac; - else - output[i] += make_float4(out.x, out.y, out.z, 1.0f) * output_fac; + output[i] = (sample == 0)? scaled_result: output[i] + scaled_result; } #endif /* __BAKING__ */ diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 5cf52f9d176..4de8e0f698a 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -18,6 +18,7 @@ CCL_NAMESPACE_BEGIN /* Direction Emission */ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, + ShaderData *emission_sd, LightSample *ls, ccl_addr_space PathState *state, float3 I, @@ -26,12 +27,6 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float time) { /* setup shading at emitter */ -#ifdef __SPLIT_KERNEL__ - ShaderData *sd = kg->sd_input; -#else - ShaderData sd_object; - ShaderData *sd = &sd_object; -#endif float3 eval; #ifdef __BACKGROUND_MIS__ @@ -46,28 +41,28 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, ray.dP = differential3_zero(); ray.dD = dI; - shader_setup_from_background(kg, sd, &ray); + shader_setup_from_background(kg, emission_sd, &ray); path_state_modify_bounce(state, true); - eval = shader_eval_background(kg, sd, state, 0, SHADER_CONTEXT_EMISSION); + eval = shader_eval_background(kg, emission_sd, state, 0, SHADER_CONTEXT_EMISSION); path_state_modify_bounce(state, false); } else #endif { - shader_setup_from_sample(kg, sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time); + shader_setup_from_sample(kg, emission_sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time); - ls->Ng = ccl_fetch(sd, Ng); + ls->Ng = ccl_fetch(emission_sd, Ng); /* no path flag, we're evaluating this for all closures. that's weak but * we'd have to do multiple evaluations otherwise */ path_state_modify_bounce(state, true); - shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_EMISSION); + shader_eval_surface(kg, emission_sd, state, 0.0f, 0, SHADER_CONTEXT_EMISSION); path_state_modify_bounce(state, false); /* evaluate emissive closure */ - if(ccl_fetch(sd, flag) & SD_EMISSION) - eval = shader_emissive_eval(kg, sd); + if(ccl_fetch(emission_sd, flag) & SD_EMISSION) + eval = shader_emissive_eval(kg, emission_sd); else eval = make_float3(0.0f, 0.0f, 0.0f); } @@ -79,6 +74,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, + ShaderData *emission_sd, LightSample *ls, ccl_addr_space PathState *state, Ray *ray, @@ -94,6 +90,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, /* evaluate closure */ float3 light_eval = direct_emissive_eval(kg, + emission_sd, ls, state, -ls->D, @@ -198,6 +195,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader /* Indirect Lamp Emission */ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, + ShaderData *emission_sd, ccl_addr_space PathState *state, Ray *ray, float3 *emission) @@ -225,6 +223,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, #endif float3 L = direct_emissive_eval(kg, + emission_sd, &ls, state, -ray->D, @@ -238,7 +237,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray volume_ray = *ray; volume_ray.t = ls.t; float3 volume_tp = make_float3(1.0f, 1.0f, 1.0f); - kernel_volume_shadow(kg, state, &volume_ray, &volume_tp); + kernel_volume_shadow(kg, emission_sd, state, &volume_ray, &volume_tp); L *= volume_tp; } #endif @@ -260,6 +259,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, /* Indirect Background */ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, + ShaderData *emission_sd, ccl_addr_space PathState *state, ccl_addr_space Ray *ray) { @@ -280,19 +280,14 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, /* evaluate background closure */ # ifdef __SPLIT_KERNEL__ Ray priv_ray = *ray; - shader_setup_from_background(kg, kg->sd_input, &priv_ray); - - path_state_modify_bounce(state, true); - float3 L = shader_eval_background(kg, kg->sd_input, state, state->flag, SHADER_CONTEXT_EMISSION); - path_state_modify_bounce(state, false); + shader_setup_from_background(kg, emission_sd, &priv_ray); # else - ShaderData sd; - shader_setup_from_background(kg, &sd, ray); + shader_setup_from_background(kg, emission_sd, ray); +# endif path_state_modify_bounce(state, true); - float3 L = shader_eval_background(kg, &sd, state, state->flag, SHADER_CONTEXT_EMISSION); + float3 L = shader_eval_background(kg, emission_sd, state, state->flag, SHADER_CONTEXT_EMISSION); path_state_modify_bounce(state, false); -# endif #ifdef __BACKGROUND_MIS__ /* check if background light exists or if we should skip pdf */ diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h index 7e6cdf93fb9..e06c68f2fc9 100644 --- a/intern/cycles/kernel/kernel_globals.h +++ b/intern/cycles/kernel/kernel_globals.h @@ -35,10 +35,10 @@ struct Intersection; struct VolumeStep; typedef struct KernelGlobals { - texture_image_uchar4 texture_byte4_images[TEX_NUM_BYTE4_IMAGES_CPU]; - texture_image_float4 texture_float4_images[TEX_NUM_FLOAT4_IMAGES_CPU]; - texture_image_float texture_float_images[TEX_NUM_FLOAT_IMAGES_CPU]; - texture_image_uchar texture_byte_images[TEX_NUM_BYTE_IMAGES_CPU]; + texture_image_uchar4 texture_byte4_images[TEX_NUM_BYTE4_CPU]; + texture_image_float4 texture_float4_images[TEX_NUM_FLOAT4_CPU]; + texture_image_float texture_float_images[TEX_NUM_FLOAT_CPU]; + texture_image_uchar texture_byte_images[TEX_NUM_BYTE_CPU]; # define KERNEL_TEX(type, ttype, name) ttype name; # define KERNEL_IMAGE_TEX(type, ttype, name) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 675eacfc5ee..736a884f819 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -291,24 +291,13 @@ ccl_device float background_portal_pdf(KernelGlobals *kg, } num_possible++; - float t = -(dot(P, dir) - dot(lightpos, dir)) / dot(direction, dir); - if(t <= 1e-4f) { - /* Either behind the portal or too close. */ - continue; - } - float4 data1 = kernel_tex_fetch(__light_data, (p + kernel_data.integrator.portal_offset)*LIGHT_SIZE + 1); float4 data2 = kernel_tex_fetch(__light_data, (p + kernel_data.integrator.portal_offset)*LIGHT_SIZE + 2); float3 axisu = make_float3(data1.y, data1.z, data1.w); float3 axisv = make_float3(data2.y, data2.z, data2.w); - float3 hit = P + t*direction; - float3 inplane = hit - lightpos; - /* Skip if the the ray doesn't pass through portal. */ - if(fabsf(dot(inplane, axisu) / dot(axisu, axisu)) > 0.5f) - continue; - if(fabsf(dot(inplane, axisv) / dot(axisv, axisv)) > 0.5f) + if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL)) continue; portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false); @@ -729,8 +718,8 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float3 light_P = make_float3(data0.y, data0.z, data0.w); - if(!ray_quad_intersect(P, D, t, - light_P, axisu, axisv, &ls->P, &ls->t)) + if(!ray_quad_intersect(P, D, 0.0f, t, + light_P, axisu, axisv, Ng, &ls->P, &ls->t)) { return false; } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index c136c85df59..0dded397ffa 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -53,6 +53,8 @@ CCL_NAMESPACE_BEGIN ccl_device void kernel_path_indirect(KernelGlobals *kg, + ShaderData *sd, + ShaderData *emission_sd, RNG *rng, Ray *ray, float3 throughput, @@ -87,7 +89,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* intersect with lamp */ float3 emission; - if(indirect_lamp_emission(kg, state, &light_ray, &emission)) { + if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission)) { path_radiance_accum_emission(L, throughput, emission, @@ -115,15 +117,14 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(decoupled) { /* cache steps along volume for repeated sampling */ VolumeSegment volume_segment; - ShaderData volume_sd; shader_setup_from_volume(kg, - &volume_sd, + sd, &volume_ray); kernel_volume_decoupled_record(kg, state, &volume_ray, - &volume_sd, + sd, &volume_segment, heterogeneous); @@ -146,7 +147,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* direct light sampling */ kernel_branched_path_volume_connect_light(kg, rng, - &volume_sd, + sd, + emission_sd, throughput, state, L, @@ -163,7 +165,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, result = kernel_volume_decoupled_scatter(kg, state, &volume_ray, - &volume_sd, + sd, &throughput, rphase, rscatter, @@ -178,7 +180,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(result == VOLUME_PATH_SCATTERED) { if(kernel_path_volume_bounce(kg, rng, - &volume_sd, + sd, &throughput, state, L, @@ -198,16 +200,16 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, # endif { /* integrate along volume segment with distance sampling */ - ShaderData volume_sd; VolumeIntegrateResult result = kernel_volume_integrate( - kg, state, &volume_sd, &volume_ray, L, &throughput, rng, heterogeneous); + kg, state, sd, &volume_ray, L, &throughput, rng, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ kernel_path_volume_connect_light(kg, rng, - &volume_sd, + sd, + emission_sd, throughput, state, L); @@ -215,7 +217,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* indirect light bounce */ if(kernel_path_volume_bounce(kg, rng, - &volume_sd, + sd, &throughput, state, L, @@ -235,7 +237,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(!hit) { #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, state, ray); + float3 L_background = indirect_background(kg, emission_sd, state, ray); path_radiance_accum_background(L, throughput, L_background, @@ -246,15 +248,14 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, } /* setup shading */ - ShaderData sd; shader_setup_from_ray(kg, - &sd, + sd, &isect, ray); float rbsdf = path_state_rng_1D_for_decision(kg, rng, state, PRNG_BSDF); - shader_eval_surface(kg, &sd, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); + shader_eval_surface(kg, sd, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); #ifdef __BRANCHED_PATH__ - shader_merge_closures(&sd); + shader_merge_closures(sd); #endif /* blurring of bsdf after bounces, for rays that have a small likelihood @@ -264,15 +265,15 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(blur_pdf < 1.0f) { float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; - shader_bsdf_blur(kg, &sd, blur_roughness); + shader_bsdf_blur(kg, sd, blur_roughness); } } #ifdef __EMISSION__ /* emission */ - if(sd.flag & SD_EMISSION) { + if(sd->flag & SD_EMISSION) { float3 emission = indirect_primitive_emission(kg, - &sd, + sd, isect.t, state->flag, state->ray_pdf); @@ -302,33 +303,33 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ - if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { + if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) { float bsdf_u, bsdf_v; path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; - float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); + float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N); float3 ao_D; float ao_pdf; float3 ao_alpha = make_float3(0.0f, 0.0f, 0.0f); sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); - if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { + if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { Ray light_ray; float3 ao_shadow; - light_ray.P = ray_offset(sd.P, sd.Ng); + light_ray.P = ray_offset(sd->P, sd->Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; # ifdef __OBJECT_MOTION__ - light_ray.time = sd.time; + light_ray.time = sd->time; # endif - light_ray.dP = sd.dP; + light_ray.dP = sd->dP; light_ray.dD = differential3_zero(); - if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) { path_radiance_accum_ao(L, throughput, ao_alpha, @@ -343,9 +344,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #ifdef __SUBSURFACE__ /* bssrdf scatter to a different location on the same object, replacing * the closures with a diffuse BSDF */ - if(sd.flag & SD_BSSRDF) { + if(sd->flag & SD_BSSRDF) { float bssrdf_probability; - ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability); + ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability); /* modify throughput for picking bssrdf or bsdf */ throughput *= bssrdf_probability; @@ -361,7 +362,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); subsurface_scatter_step(kg, - &sd, + sd, state, state->flag, sc, @@ -377,7 +378,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, int all = kernel_data.integrator.sample_all_lights_indirect; kernel_branched_path_surface_connect_light(kg, rng, - &sd, + sd, + emission_sd, state, throughput, 1.0f, @@ -386,13 +388,14 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, } #endif - if(!kernel_path_surface_bounce(kg, rng, &sd, &throughput, state, L, ray)) + if(!kernel_path_surface_bounce(kg, rng, sd, &throughput, state, L, ray)) break; } } ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, + ShaderData *emission_sd, PathRadiance *L, PathState *state, RNG *rng, @@ -425,7 +428,7 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, light_ray.dP = ccl_fetch(sd, dP); light_ray.dD = differential3_zero(); - if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state->bounce); } } @@ -435,6 +438,7 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, ccl_device bool kernel_path_subsurface_scatter( KernelGlobals *kg, ShaderData *sd, + ShaderData *emission_sd, PathRadiance *L, PathState *state, RNG *rng, @@ -503,7 +507,7 @@ ccl_device bool kernel_path_subsurface_scatter( hit_L->direct_throughput = L->direct_throughput; path_radiance_copy_indirect(hit_L, L); - kernel_path_surface_connect_light(kg, rng, sd, *hit_tp, state, hit_L); + kernel_path_surface_connect_light(kg, rng, sd, emission_sd, *hit_tp, state, hit_L); if(kernel_path_surface_bounce(kg, rng, @@ -526,6 +530,7 @@ ccl_device bool kernel_path_subsurface_scatter( kernel_volume_stack_update_for_subsurface( kg, + emission_sd, &volume_ray, hit_state->volume_stack); } @@ -604,8 +609,13 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, path_radiance_init(&L, kernel_data.film.use_light_pass); + /* shader data memory used for both volumes and surfaces, saves stack space */ + ShaderData sd; + /* shader data used by emission, shadows, volume stacks */ + ShaderData emission_sd; + PathState state; - path_state_init(kg, &state, rng, sample, &ray); + path_state_init(kg, &emission_sd, &state, rng, sample, &ray); #ifdef __KERNEL_DEBUG__ DebugData debug_data; @@ -669,7 +679,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, /* intersect with lamp */ float3 emission; - if(indirect_lamp_emission(kg, &state, &light_ray, &emission)) + if(indirect_lamp_emission(kg, &emission_sd, &state, &light_ray, &emission)) path_radiance_accum_emission(&L, throughput, emission, state.bounce); } #endif @@ -689,11 +699,10 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, if(decoupled) { /* cache steps along volume for repeated sampling */ VolumeSegment volume_segment; - ShaderData volume_sd; - shader_setup_from_volume(kg, &volume_sd, &volume_ray); + shader_setup_from_volume(kg, &sd, &volume_ray); kernel_volume_decoupled_record(kg, &state, - &volume_ray, &volume_sd, &volume_segment, heterogeneous); + &volume_ray, &sd, &volume_segment, heterogeneous); volume_segment.sampling_method = sampling_method; @@ -708,8 +717,9 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, int all = false; /* direct light sampling */ - kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, - throughput, &state, &L, all, &volume_ray, &volume_segment); + kernel_branched_path_volume_connect_light(kg, rng, &sd, + &emission_sd, throughput, &state, &L, all, + &volume_ray, &volume_segment); /* indirect sample. if we use distance sampling and take just * one sample for direct and indirect light, we could share @@ -718,7 +728,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE); result = kernel_volume_decoupled_scatter(kg, - &state, &volume_ray, &volume_sd, &throughput, + &state, &volume_ray, &sd, &throughput, rphase, rscatter, &volume_segment, NULL, true); } @@ -726,7 +736,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, kernel_volume_decoupled_free(kg, &volume_segment); if(result == VOLUME_PATH_SCATTERED) { - if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray)) + if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, &L, &ray)) continue; else break; @@ -739,17 +749,16 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, # endif { /* integrate along volume segment with distance sampling */ - ShaderData volume_sd; VolumeIntegrateResult result = kernel_volume_integrate( - kg, &state, &volume_sd, &volume_ray, &L, &throughput, rng, heterogeneous); + kg, &state, &sd, &volume_ray, &L, &throughput, rng, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L); + kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, &L); /* indirect light bounce */ - if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray)) + if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, &L, &ray)) continue; else break; @@ -772,7 +781,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, &state, &ray); + float3 L_background = indirect_background(kg, &emission_sd, &state, &ray); path_radiance_accum_background(&L, throughput, L_background, state.bounce); #endif @@ -780,7 +789,6 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, } /* setup shading */ - ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, &ray); float rbsdf = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_BSDF); shader_eval_surface(kg, &sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); @@ -848,7 +856,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - kernel_path_ao(kg, &sd, &L, &state, rng, throughput); + kernel_path_ao(kg, &sd, &emission_sd, &L, &state, rng, throughput); } #endif @@ -858,6 +866,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, if(sd.flag & SD_BSSRDF) { if(kernel_path_subsurface_scatter(kg, &sd, + &emission_sd, &L, &state, rng, @@ -871,7 +880,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #endif /* __SUBSURFACE__ */ /* direct lighting */ - kernel_path_surface_connect_light(kg, rng, &sd, throughput, &state, &L); + kernel_path_surface_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, &L); /* compute direct lighting and next bounce */ if(!kernel_path_surface_bounce(kg, rng, &sd, &throughput, &state, &L, &ray)) diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 13ae4cf669b..fdba1a7b025 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -18,7 +18,13 @@ CCL_NAMESPACE_BEGIN #ifdef __BRANCHED_PATH__ -ccl_device void kernel_branched_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, float3 throughput) +ccl_device void kernel_branched_path_ao(KernelGlobals *kg, + ShaderData *sd, + ShaderData *emission_sd, + PathRadiance *L, + PathState *state, + RNG *rng, + float3 throughput) { int num_samples = kernel_data.integrator.ao_samples; float num_samples_inv = 1.0f/num_samples; @@ -49,7 +55,7 @@ ccl_device void kernel_branched_path_ao(KernelGlobals *kg, ShaderData *sd, PathR light_ray.dP = ccl_fetch(sd, dP); light_ray.dD = differential3_zero(); - if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) path_radiance_accum_ao(L, throughput*num_samples_inv, ao_alpha, ao_bsdf, ao_shadow, state->bounce); } } @@ -58,8 +64,8 @@ ccl_device void kernel_branched_path_ao(KernelGlobals *kg, ShaderData *sd, PathR /* bounce off surface and integrate indirect light */ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg, - RNG *rng, ShaderData *sd, float3 throughput, float num_samples_adjust, - PathState *state, PathRadiance *L) + RNG *rng, ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd, + float3 throughput, float num_samples_adjust, PathState *state, PathRadiance *L) { for(int i = 0; i < ccl_fetch(sd, num_closure); i++) { const ShaderClosure *sc = &ccl_fetch(sd, closure)[i]; @@ -106,6 +112,8 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba } kernel_path_indirect(kg, + indirect_sd, + emission_sd, rng, &bsdf_ray, tp*num_samples_inv, @@ -124,6 +132,8 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba #ifdef __SUBSURFACE__ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, + ShaderData *indirect_sd, + ShaderData *emission_sd, PathRadiance *L, PathState *state, RNG *rng, @@ -186,6 +196,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, kernel_volume_stack_update_for_subsurface( kg, + emission_sd, &volume_ray, hit_state.volume_stack); } @@ -199,6 +210,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, kg, rng, &bssrdf_sd, + emission_sd, &hit_state, throughput, num_samples_inv, @@ -212,6 +224,8 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, kg, rng, &bssrdf_sd, + indirect_sd, + emission_sd, throughput, num_samples_inv, &hit_state, @@ -231,8 +245,13 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in path_radiance_init(&L, kernel_data.film.use_light_pass); + /* shader data memory used for both volumes and surfaces, saves stack space */ + ShaderData sd; + /* shader data used by emission, shadows, volume stacks, indirect path */ + ShaderData emission_sd, indirect_sd; + PathState state; - path_state_init(kg, &state, rng, sample, &ray); + path_state_init(kg, &emission_sd, &state, rng, sample, &ray); #ifdef __KERNEL_DEBUG__ DebugData debug_data; @@ -287,11 +306,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in /* cache steps along volume for repeated sampling */ VolumeSegment volume_segment; - ShaderData volume_sd; - shader_setup_from_volume(kg, &volume_sd, &volume_ray); + shader_setup_from_volume(kg, &sd, &volume_ray); kernel_volume_decoupled_record(kg, &state, - &volume_ray, &volume_sd, &volume_segment, heterogeneous); + &volume_ray, &sd, &volume_segment, heterogeneous); /* direct light sampling */ if(volume_segment.closure_flag & SD_SCATTER) { @@ -299,8 +317,9 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in int all = kernel_data.integrator.sample_all_lights_direct; - kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, - throughput, &state, &L, all, &volume_ray, &volume_segment); + kernel_branched_path_volume_connect_light(kg, rng, &sd, + &emission_sd, throughput, &state, &L, all, + &volume_ray, &volume_segment); /* indirect light sampling */ int num_samples = kernel_data.integrator.volume_samples; @@ -326,20 +345,22 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in float rscatter = path_state_rng_1D_for_decision(kg, &tmp_rng, &ps, PRNG_SCATTER_DISTANCE); VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, - &ps, &pray, &volume_sd, &tp, rphase, rscatter, &volume_segment, NULL, false); + &ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false); (void)result; kernel_assert(result == VOLUME_PATH_SCATTERED); if(kernel_path_volume_bounce(kg, rng, - &volume_sd, + &sd, &tp, &ps, &L, &pray)) { kernel_path_indirect(kg, + &indirect_sd, + &emission_sd, rng, &pray, tp*num_samples_inv, @@ -373,30 +394,31 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in for(int j = 0; j < num_samples; j++) { PathState ps = state; Ray pray = ray; - ShaderData volume_sd; float3 tp = throughput * num_samples_inv; /* branch RNG state */ path_state_branch(&ps, j, num_samples); VolumeIntegrateResult result = kernel_volume_integrate( - kg, &ps, &volume_sd, &volume_ray, &L, &tp, rng, heterogeneous); + kg, &ps, &sd, &volume_ray, &L, &tp, rng, heterogeneous); #ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* todo: support equiangular, MIS and all light sampling. * alternatively get decoupled ray marching working on the GPU */ - kernel_path_volume_connect_light(kg, rng, &volume_sd, tp, &state, &L); + kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, tp, &state, &L); if(kernel_path_volume_bounce(kg, rng, - &volume_sd, + &sd, &tp, &ps, &L, &pray)) { kernel_path_indirect(kg, + &indirect_sd, + &emission_sd, rng, &pray, tp, @@ -414,7 +436,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in } /* todo: avoid this calculation using decoupled ray marching */ - kernel_volume_shadow(kg, &state, &volume_ray, &throughput); + kernel_volume_shadow(kg, &emission_sd, &state, &volume_ray, &throughput); #endif } #endif @@ -432,7 +454,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, &state, &ray); + float3 L_background = indirect_background(kg, &emission_sd, &state, &ray); path_radiance_accum_background(&L, throughput, L_background, state.bounce); #endif @@ -440,7 +462,6 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in } /* setup shading */ - ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, &ray); shader_eval_surface(kg, &sd, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN); shader_merge_closures(&sd); @@ -499,15 +520,15 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - kernel_branched_path_ao(kg, &sd, &L, &state, rng, throughput); + kernel_branched_path_ao(kg, &sd, &emission_sd, &L, &state, rng, throughput); } #endif #ifdef __SUBSURFACE__ /* bssrdf scatter to a different location on the same object */ if(sd.flag & SD_BSSRDF) { - kernel_branched_path_subsurface_scatter(kg, &sd, &L, &state, - rng, &ray, throughput); + kernel_branched_path_subsurface_scatter(kg, &sd, &indirect_sd, &emission_sd, + &L, &state, rng, &ray, throughput); } #endif @@ -519,13 +540,13 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in if(kernel_data.integrator.use_direct_light) { int all = kernel_data.integrator.sample_all_lights_direct; kernel_branched_path_surface_connect_light(kg, rng, - &sd, &hit_state, throughput, 1.0f, &L, all); + &sd, &emission_sd, &hit_state, throughput, 1.0f, &L, all); } #endif /* indirect light */ kernel_branched_path_surface_indirect_light(kg, rng, - &sd, throughput, 1.0f, &hit_state, &L); + &sd, &indirect_sd, &emission_sd, throughput, 1.0f, &hit_state, &L); /* continue in case of transparency */ throughput *= shader_bsdf_transparency(kg, &sd); diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h index ef3765f7d89..e0e35d792ab 100644 --- a/intern/cycles/kernel/kernel_path_state.h +++ b/intern/cycles/kernel/kernel_path_state.h @@ -16,7 +16,12 @@ CCL_NAMESPACE_BEGIN -ccl_device_inline void path_state_init(KernelGlobals *kg, ccl_addr_space PathState *state, ccl_addr_space RNG *rng, int sample, ccl_addr_space Ray *ray) +ccl_device_inline void path_state_init(KernelGlobals *kg, + ShaderData *stack_sd, + ccl_addr_space PathState *state, + ccl_addr_space RNG *rng, + int sample, + ccl_addr_space Ray *ray) { state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP; @@ -41,7 +46,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg, ccl_addr_space PathSta if(kernel_data.integrator.use_volumes) { /* initialize volume stack with volume we are inside of */ - kernel_volume_stack_init(kg, ray, state->volume_stack); + kernel_volume_stack_init(kg, stack_sd, ray, state->volume_stack); /* seed RNG for cases where we can't use stratified samples */ state->rng_congruential = lcg_init(*rng + sample*0x51633e2d); } diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index 1818c4fd2da..74b1ae0ca32 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -20,7 +20,8 @@ CCL_NAMESPACE_BEGIN /* branched path tracing: connect path directly to position on one or more lights and add it to L */ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RNG *rng, - ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, int sample_all_lights) + ShaderData *sd, ShaderData *emission_sd, PathState *state, float3 throughput, + float num_samples_adjust, PathRadiance *L, int sample_all_lights) { #ifdef __EMISSION__ /* sample illumination from lights to find path contribution */ @@ -55,11 +56,11 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal LightSample ls; lamp_light_sample(kg, i, light_u, light_v, ccl_fetch(sd, P), &ls); - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); } @@ -87,11 +88,11 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal LightSample ls; light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls); - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); } @@ -109,11 +110,11 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls); /* sample random light */ - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, state->bounce, is_lamp); } @@ -184,7 +185,8 @@ ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng, #ifndef __SPLIT_KERNEL__ /* path tracing: connect path directly to position on a light and add it to L */ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ccl_addr_space RNG *rng, - ShaderData *sd, float3 throughput, ccl_addr_space PathState *state, PathRadiance *L) + ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state, + PathRadiance *L) { #ifdef __EMISSION__ if(!(kernel_data.integrator.use_direct_light && (ccl_fetch(sd, flag) & SD_BSDF_HAS_EVAL))) @@ -206,11 +208,11 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ccl_ LightSample ls; light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls); - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); } diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h index 9eb8b240b88..e45522a4641 100644 --- a/intern/cycles/kernel/kernel_path_volume.h +++ b/intern/cycles/kernel/kernel_path_volume.h @@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN #ifdef __VOLUME_SCATTER__ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng, - ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L) + ShaderData *sd, ShaderData *emission_sd, float3 throughput, PathState *state, PathRadiance *L) { #ifdef __EMISSION__ if(!kernel_data.integrator.use_direct_light) @@ -44,11 +44,11 @@ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng, if(ls.pdf == 0.0f) return; - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); } @@ -106,7 +106,7 @@ bool kernel_path_volume_bounce(KernelGlobals *kg, RNG *rng, } ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG *rng, - ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L, + ShaderData *sd, ShaderData *emission_sd, float3 throughput, PathState *state, PathRadiance *L, bool sample_all_lights, Ray *ray, const VolumeSegment *segment) { #ifdef __EMISSION__ @@ -160,11 +160,11 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG if(ls.pdf == 0.0f) continue; - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); } @@ -211,11 +211,11 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG if(ls.pdf == 0.0f) continue; - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); } @@ -251,11 +251,11 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG return; /* sample random light */ - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; - if(!shadow_blocked(kg, state, &light_ray, &shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { /* accumulate */ path_radiance_accum_light(L, tp, &L_light, shadow, 1.0f, state->bounce, is_lamp); } diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h index 504ac2e40bc..1abbbb2ddad 100644 --- a/intern/cycles/kernel/kernel_shadow.h +++ b/intern/cycles/kernel/kernel_shadow.h @@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN #define STACK_MAX_HITS 64 -ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, float3 *shadow) +ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *shadow_sd, PathState *state, Ray *ray, float3 *shadow) { *shadow = make_float3(1.0f, 1.0f, 1.0f); @@ -107,39 +107,36 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray * if(ps.volume_stack[0].shader != SHADER_NONE) { Ray segment_ray = *ray; segment_ray.t = isect->t; - kernel_volume_shadow(kg, &ps, &segment_ray, &throughput); + kernel_volume_shadow(kg, shadow_sd, &ps, &segment_ray, &throughput); } #endif /* setup shader data at surface */ - ShaderData sd; - shader_setup_from_ray(kg, &sd, isect, ray); + shader_setup_from_ray(kg, shadow_sd, isect, ray); /* attenuation from transparent surface */ - if(!(sd.flag & SD_HAS_ONLY_VOLUME)) { + if(!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) { path_state_modify_bounce(state, true); - shader_eval_surface(kg, &sd, state, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); + shader_eval_surface(kg, shadow_sd, state, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); path_state_modify_bounce(state, false); - throughput *= shader_bsdf_transparency(kg, &sd); + throughput *= shader_bsdf_transparency(kg, shadow_sd); } /* stop if all light is blocked */ if(is_zero(throughput)) { /* free dynamic storage */ - if(hits != hits_stack) - free(hits); return true; } /* move ray forward */ - ray->P = sd.P; + ray->P = shadow_sd->P; if(ray->t != FLT_MAX) ray->D = normalize_len(Pend - ray->P, &ray->t); #ifdef __VOLUME__ /* exit/enter volume */ - kernel_volume_stack_enter_exit(kg, &sd, ps.volume_stack); + kernel_volume_stack_enter_exit(kg, shadow_sd, ps.volume_stack); #endif bounce++; @@ -148,7 +145,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray * #ifdef __VOLUME__ /* attenuation for last line segment towards light */ if(ps.volume_stack[0].shader != SHADER_NONE) - kernel_volume_shadow(kg, &ps, ray, &throughput); + kernel_volume_shadow(kg, shadow_sd, &ps, ray, &throughput); #endif *shadow = throughput; @@ -164,7 +161,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray * #ifdef __VOLUME__ if(!blocked && state->volume_stack[0].shader != SHADER_NONE) { /* apply attenuation from current volume shader */ - kernel_volume_shadow(kg, state, ray, shadow); + kernel_volume_shadow(kg, shadow_sd, state, ray, shadow); } #endif @@ -184,6 +181,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray * * one extra ray cast for the cases were we do want transparency. */ ccl_device_noinline bool shadow_blocked(KernelGlobals *kg, + ShaderData *shadow_sd, ccl_addr_space PathState *state, ccl_addr_space Ray *ray_input, float3 *shadow) @@ -228,7 +226,7 @@ ccl_device_noinline bool shadow_blocked(KernelGlobals *kg, #ifdef __VOLUME__ /* attenuation for last line segment towards light */ if(ps.volume_stack[0].shader != SHADER_NONE) - kernel_volume_shadow(kg, &ps, ray, &throughput); + kernel_volume_shadow(kg, shadow_sd, &ps, ray, &throughput); #endif *shadow *= throughput; @@ -244,39 +242,33 @@ ccl_device_noinline bool shadow_blocked(KernelGlobals *kg, if(ps.volume_stack[0].shader != SHADER_NONE) { Ray segment_ray = *ray; segment_ray.t = isect->t; - kernel_volume_shadow(kg, &ps, &segment_ray, &throughput); + kernel_volume_shadow(kg, shadow_sd, &ps, &segment_ray, &throughput); } #endif /* setup shader data at surface */ -#ifdef __SPLIT_KERNEL__ - ShaderData *sd = kg->sd_input; -#else - ShaderData sd_object; - ShaderData *sd = &sd_object; -#endif - shader_setup_from_ray(kg, sd, isect, ray); + shader_setup_from_ray(kg, shadow_sd, isect, ray); /* attenuation from transparent surface */ - if(!(ccl_fetch(sd, flag) & SD_HAS_ONLY_VOLUME)) { + if(!(ccl_fetch(shadow_sd, flag) & SD_HAS_ONLY_VOLUME)) { path_state_modify_bounce(state, true); - shader_eval_surface(kg, sd, state, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); + shader_eval_surface(kg, shadow_sd, state, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); path_state_modify_bounce(state, false); - throughput *= shader_bsdf_transparency(kg, sd); + throughput *= shader_bsdf_transparency(kg, shadow_sd); } if(is_zero(throughput)) return true; /* move ray forward */ - ray->P = ray_offset(ccl_fetch(sd, P), -ccl_fetch(sd, Ng)); + ray->P = ray_offset(ccl_fetch(shadow_sd, P), -ccl_fetch(shadow_sd, Ng)); if(ray->t != FLT_MAX) ray->D = normalize_len(Pend - ray->P, &ray->t); #ifdef __VOLUME__ /* exit/enter volume */ - kernel_volume_stack_enter_exit(kg, sd, ps.volume_stack); + kernel_volume_stack_enter_exit(kg, shadow_sd, ps.volume_stack); #endif bounce++; @@ -286,7 +278,7 @@ ccl_device_noinline bool shadow_blocked(KernelGlobals *kg, #ifdef __VOLUME__ else if(!blocked && state->volume_stack[0].shader != SHADER_NONE) { /* apply attenuation from current volume shader */ - kernel_volume_shadow(kg, state, ray, shadow); + kernel_volume_shadow(kg, shadow_sd, state, ray, shadow); } #endif #endif diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index ba50d180acf..1ffcfb94a15 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -121,9 +121,7 @@ CCL_NAMESPACE_BEGIN # define __OBJECT_MOTION__ # define __HAIR__ # define __BAKING__ -# ifdef __KERNEL_EXPERIMENTAL__ -# define __TRANSPARENT_SHADOWS__ -# endif +# define __TRANSPARENT_SHADOWS__ # endif /* __KERNEL_OPENCL_AMD__ */ # ifdef __KERNEL_OPENCL_INTEL_CPU__ diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 30a978f6c9e..0e313b8e88c 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -219,15 +219,14 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState /* get the volume attenuation over line segment defined by ray, with the * assumption that there are no surfaces blocking light between the endpoints */ -ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg, PathState *state, Ray *ray, float3 *throughput) +ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg, ShaderData *shadow_sd, PathState *state, Ray *ray, float3 *throughput) { - ShaderData sd; - shader_setup_from_volume(kg, &sd, ray); + shader_setup_from_volume(kg, shadow_sd, ray); if(volume_stack_is_heterogeneous(kg, state->volume_stack)) - kernel_volume_shadow_heterogeneous(kg, state, ray, &sd, throughput); + kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput); else - kernel_volume_shadow_homogeneous(kg, state, ray, &sd, throughput); + kernel_volume_shadow_homogeneous(kg, state, ray, shadow_sd, throughput); } /* Equi-angular sampling as in: @@ -1000,6 +999,7 @@ ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg, bool heterogeneou * is inside of. */ ccl_device void kernel_volume_stack_init(KernelGlobals *kg, + ShaderData *stack_sd, Ray *ray, VolumeStack *stack) { @@ -1040,28 +1040,27 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg, qsort(hits, num_hits, sizeof(Intersection), intersections_compare); for(uint hit = 0; hit < num_hits; ++hit, ++isect) { - ShaderData sd; - shader_setup_from_ray(kg, &sd, isect, &volume_ray); - if(sd.flag & SD_BACKFACING) { + shader_setup_from_ray(kg, stack_sd, isect, &volume_ray); + if(stack_sd->flag & SD_BACKFACING) { bool need_add = true; for(int i = 0; i < enclosed_index && need_add; ++i) { /* If ray exited the volume and never entered to that volume * it means that camera is inside such a volume. */ - if(enclosed_volumes[i] == sd.object) { + if(enclosed_volumes[i] == stack_sd->object) { need_add = false; } } for(int i = 0; i < stack_index && need_add; ++i) { /* Don't add intersections twice. */ - if(stack[i].object == sd.object) { + if(stack[i].object == stack_sd->object) { need_add = false; break; } } if(need_add) { - stack[stack_index].object = sd.object; - stack[stack_index].shader = sd.shader; + stack[stack_index].object = stack_sd->object; + stack[stack_index].shader = stack_sd->shader; ++stack_index; } } @@ -1069,7 +1068,7 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg, /* If ray from camera enters the volume, this volume shouldn't * be added to the stack on exit. */ - enclosed_volumes[enclosed_index++] = sd.object; + enclosed_volumes[enclosed_index++] = stack_sd->object; } } } @@ -1086,9 +1085,8 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg, break; } - ShaderData sd; - shader_setup_from_ray(kg, &sd, &isect, &volume_ray); - if(sd.flag & SD_BACKFACING) { + shader_setup_from_ray(kg, stack_sd, &isect, &volume_ray); + if(stack_sd->flag & SD_BACKFACING) { /* If ray exited the volume and never entered to that volume * it means that camera is inside such a volume. */ @@ -1097,20 +1095,20 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg, /* If ray exited the volume and never entered to that volume * it means that camera is inside such a volume. */ - if(enclosed_volumes[i] == sd.object) { + if(enclosed_volumes[i] == stack_sd->object) { need_add = false; } } for(int i = 0; i < stack_index && need_add; ++i) { /* Don't add intersections twice. */ - if(stack[i].object == sd.object) { + if(stack[i].object == stack_sd->object) { need_add = false; break; } } if(need_add) { - stack[stack_index].object = sd.object; - stack[stack_index].shader = sd.shader; + stack[stack_index].object = stack_sd->object; + stack[stack_index].shader = stack_sd->shader; ++stack_index; } } @@ -1118,11 +1116,11 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg, /* If ray from camera enters the volume, this volume shouldn't * be added to the stack on exit. */ - enclosed_volumes[enclosed_index++] = sd.object; + enclosed_volumes[enclosed_index++] = stack_sd->object; } /* Move ray forward. */ - volume_ray.P = ray_offset(sd.P, -sd.Ng); + volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); ++step; } #endif @@ -1190,6 +1188,7 @@ ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd #ifdef __SUBSURFACE__ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg, + ShaderData *stack_sd, Ray *ray, VolumeStack *stack) { @@ -1210,27 +1209,28 @@ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg, qsort(hits, num_hits, sizeof(Intersection), intersections_compare); for(uint hit = 0; hit < num_hits; ++hit, ++isect) { - ShaderData sd; - shader_setup_from_ray(kg, &sd, isect, &volume_ray); - kernel_volume_stack_enter_exit(kg, &sd, stack); + shader_setup_from_ray(kg, stack_sd, isect, &volume_ray); + kernel_volume_stack_enter_exit(kg, stack_sd, stack); } } # else Intersection isect; int step = 0; + float3 Pend = ray->P + ray->D*ray->t; while(step < 2 * VOLUME_STACK_SIZE && scene_intersect_volume(kg, &volume_ray, &isect, PATH_RAY_ALL_VISIBILITY)) { - ShaderData sd; - shader_setup_from_ray(kg, &sd, &isect, &volume_ray); - kernel_volume_stack_enter_exit(kg, &sd, stack); + shader_setup_from_ray(kg, stack_sd, &isect, &volume_ray); + kernel_volume_stack_enter_exit(kg, stack_sd, stack); /* Move ray forward. */ - volume_ray.P = ray_offset(sd.P, -sd.Ng); - volume_ray.t -= sd.ray_length; + volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng); + if(volume_ray.t != FLT_MAX) { + volume_ray.D = normalize_len(Pend - volume_ray.P, &volume_ray.t); + } ++step; } # endif diff --git a/intern/cycles/kernel/kernels/cpu/kernel.cpp b/intern/cycles/kernel/kernels/cpu/kernel.cpp index 365ce891354..d8a83f69685 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel.cpp +++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp @@ -95,7 +95,7 @@ void kernel_tex_copy(KernelGlobals *kg, int id = atoi(name + strlen("__tex_image_float4_")); int array_index = id; - if(array_index >= 0 && array_index < TEX_NUM_FLOAT4_IMAGES_CPU) { + if(array_index >= 0 && array_index < TEX_NUM_FLOAT4_CPU) { tex = &kg->texture_float4_images[array_index]; } @@ -109,9 +109,9 @@ void kernel_tex_copy(KernelGlobals *kg, else if(strstr(name, "__tex_image_float")) { texture_image_float *tex = NULL; int id = atoi(name + strlen("__tex_image_float_")); - int array_index = id - TEX_IMAGE_FLOAT_START_CPU; + int array_index = id - TEX_START_FLOAT_CPU; - if(array_index >= 0 && array_index < TEX_NUM_FLOAT_IMAGES_CPU) { + if(array_index >= 0 && array_index < TEX_NUM_FLOAT_CPU) { tex = &kg->texture_float_images[array_index]; } @@ -125,9 +125,9 @@ void kernel_tex_copy(KernelGlobals *kg, else if(strstr(name, "__tex_image_byte4")) { texture_image_uchar4 *tex = NULL; int id = atoi(name + strlen("__tex_image_byte4_")); - int array_index = id - TEX_IMAGE_BYTE4_START_CPU; + int array_index = id - TEX_START_BYTE4_CPU; - if(array_index >= 0 && array_index < TEX_NUM_BYTE4_IMAGES_CPU) { + if(array_index >= 0 && array_index < TEX_NUM_BYTE4_CPU) { tex = &kg->texture_byte4_images[array_index]; } @@ -141,9 +141,9 @@ void kernel_tex_copy(KernelGlobals *kg, else if(strstr(name, "__tex_image_byte")) { texture_image_uchar *tex = NULL; int id = atoi(name + strlen("__tex_image_byte_")); - int array_index = id - TEX_IMAGE_BYTE_START_CPU; + int array_index = id - TEX_START_BYTE_CPU; - if(array_index >= 0 && array_index < TEX_NUM_BYTE_IMAGES_CPU) { + if(array_index >= 0 && array_index < TEX_NUM_BYTE_CPU) { tex = &kg->texture_byte_images[array_index]; } diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h index 4807f96a0df..b10861ab857 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h +++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h @@ -23,24 +23,24 @@ CCL_NAMESPACE_BEGIN ccl_device float4 kernel_tex_image_interp_impl(KernelGlobals *kg, int tex, float x, float y) { - if(tex >= TEX_IMAGE_BYTE_START_CPU) - return kg->texture_byte_images[tex - TEX_IMAGE_BYTE_START_CPU].interp(x, y); - else if(tex >= TEX_IMAGE_FLOAT_START_CPU) - return kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp(x, y); - else if(tex >= TEX_IMAGE_BYTE4_START_CPU) - return kg->texture_byte4_images[tex - TEX_IMAGE_BYTE4_START_CPU].interp(x, y); + if(tex >= TEX_START_BYTE_CPU) + return kg->texture_byte_images[tex - TEX_START_BYTE_CPU].interp(x, y); + else if(tex >= TEX_START_FLOAT_CPU) + return kg->texture_float_images[tex - TEX_START_FLOAT_CPU].interp(x, y); + else if(tex >= TEX_START_BYTE4_CPU) + return kg->texture_byte4_images[tex - TEX_START_BYTE4_CPU].interp(x, y); else return kg->texture_float4_images[tex].interp(x, y); } ccl_device float4 kernel_tex_image_interp_3d_impl(KernelGlobals *kg, int tex, float x, float y, float z) { - if(tex >= TEX_IMAGE_BYTE_START_CPU) - return kg->texture_byte_images[tex - TEX_IMAGE_BYTE_START_CPU].interp_3d(x, y, z); - else if(tex >= TEX_IMAGE_FLOAT_START_CPU) - return kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp_3d(x, y, z); - else if(tex >= TEX_IMAGE_BYTE4_START_CPU) - return kg->texture_byte4_images[tex - TEX_IMAGE_BYTE4_START_CPU].interp_3d(x, y, z); + if(tex >= TEX_START_BYTE_CPU) + return kg->texture_byte_images[tex - TEX_START_BYTE_CPU].interp_3d(x, y, z); + else if(tex >= TEX_START_FLOAT_CPU) + return kg->texture_float_images[tex - TEX_START_FLOAT_CPU].interp_3d(x, y, z); + else if(tex >= TEX_START_BYTE4_CPU) + return kg->texture_byte4_images[tex - TEX_START_BYTE4_CPU].interp_3d(x, y, z); else return kg->texture_float4_images[tex].interp_3d(x, y, z); @@ -48,12 +48,12 @@ ccl_device float4 kernel_tex_image_interp_3d_impl(KernelGlobals *kg, int tex, fl ccl_device float4 kernel_tex_image_interp_3d_ex_impl(KernelGlobals *kg, int tex, float x, float y, float z, int interpolation) { - if(tex >= TEX_IMAGE_BYTE_START_CPU) - return kg->texture_byte_images[tex - TEX_IMAGE_BYTE_START_CPU].interp_3d_ex(x, y, z, interpolation); - else if(tex >= TEX_IMAGE_FLOAT_START_CPU) - return kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp_3d_ex(x, y, z, interpolation); - else if(tex >= TEX_IMAGE_BYTE4_START_CPU) - return kg->texture_byte4_images[tex - TEX_IMAGE_BYTE4_START_CPU].interp_3d_ex(x, y, z, interpolation); + if(tex >= TEX_START_BYTE_CPU) + return kg->texture_byte_images[tex - TEX_START_BYTE_CPU].interp_3d_ex(x, y, z, interpolation); + else if(tex >= TEX_START_FLOAT_CPU) + return kg->texture_float_images[tex - TEX_START_FLOAT_CPU].interp_3d_ex(x, y, z, interpolation); + else if(tex >= TEX_START_BYTE4_CPU) + return kg->texture_byte4_images[tex - TEX_START_BYTE4_CPU].interp_3d_ex(x, y, z, interpolation); else return kg->texture_float4_images[tex].interp_3d_ex(x, y, z, interpolation); } diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl index 35e01178ba8..d5e0a7d4c8c 100644 --- a/intern/cycles/kernel/shaders/node_brick_texture.osl +++ b/intern/cycles/kernel/shaders/node_brick_texture.osl @@ -59,10 +59,10 @@ float brick(point p, float mortar_size, float bias, shader node_brick_texture( int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - float Offset = 0.5, - int OffsetFrequency = 2, - float Squash = 1.0, - int SquashFrequency = 1, + float offset = 0.5, + int offset_frequency = 2, + float squash = 1.0, + int squash_frequency = 1, point Vector = P, color Color1 = 0.2, color Color2 = 0.8, @@ -84,7 +84,7 @@ shader node_brick_texture( color Col = Color1; Fac = brick(p * Scale, MortarSize, Bias, BrickWidth, RowHeight, - Offset, OffsetFrequency, Squash, SquashFrequency, tint); + offset, offset_frequency, squash, squash_frequency, tint); if (Fac != 1.0) { float facm = 1.0 - tint; diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl index 44074317f42..e95a17f6fa1 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_color.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl @@ -17,18 +17,18 @@ #include "stdosl.h" shader node_convert_from_color( - color Color = 0.0, - output string String = "", - output float Val = 0.0, - output int ValInt = 0, - output vector Vector = vector(0.0, 0.0, 0.0), - output point Point = point(0.0, 0.0, 0.0), - output normal Normal = normal(0.0, 0.0, 0.0)) + color value_color = 0.0, + output string value_string = "", + output float value_float = 0.0, + output int value_int = 0, + output vector value_vector = vector(0.0, 0.0, 0.0), + output point value_point = point(0.0, 0.0, 0.0), + output normal value_normal = normal(0.0, 0.0, 0.0)) { - Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722; - ValInt = (int)(Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722); - Vector = vector(Color[0], Color[1], Color[2]); - Point = point(Color[0], Color[1], Color[2]); - Normal = normal(Color[0], Color[1], Color[2]); + value_float = value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722; + value_int = (int)(value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722); + value_vector = vector(value_color[0], value_color[1], value_color[2]); + value_point = point(value_color[0], value_color[1], value_color[2]); + value_normal = normal(value_color[0], value_color[1], value_color[2]); } diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl index fc5c79c4c64..a5c2e3b26ad 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_float.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl @@ -17,18 +17,18 @@ #include "stdosl.h" shader node_convert_from_float( - float Val = 0.0, - output string String = "", - output int ValInt = 0, - output color Color = 0.0, - output vector Vector = vector(0.0, 0.0, 0.0), - output point Point = point(0.0, 0.0, 0.0), - output normal Normal = normal(0.0, 0.0, 0.0)) + float value_float = 0.0, + output string value_string = "", + output int value_int = 0, + output color value_color = 0.0, + output vector value_vector = vector(0.0, 0.0, 0.0), + output point value_point = point(0.0, 0.0, 0.0), + output normal value_normal = normal(0.0, 0.0, 0.0)) { - ValInt = (int)Val; - Color = color(Val, Val, Val); - Vector = vector(Val, Val, Val); - Point = point(Val, Val, Val); - Normal = normal(Val, Val, Val); + value_int = (int)value_float; + value_color = color(value_float, value_float, value_float); + value_vector = vector(value_float, value_float, value_float); + value_point = point(value_float, value_float, value_float); + value_normal = normal(value_float, value_float, value_float); } diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl index 3c3785ebc0d..0e6ae711210 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_int.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl @@ -17,19 +17,19 @@ #include "stdosl.h" shader node_convert_from_int( - int ValInt = 0, - output string String = "", - output float Val = 0.0, - output color Color = 0.0, - output vector Vector = vector(0.0, 0.0, 0.0), - output point Point = point(0.0, 0.0, 0.0), - output normal Normal = normal(0.0, 0.0, 0.0)) + int value_int = 0, + output string value_string = "", + output float value_float = 0.0, + output color value_color = 0.0, + output vector value_vector = vector(0.0, 0.0, 0.0), + output point value_point = point(0.0, 0.0, 0.0), + output normal value_normal = normal(0.0, 0.0, 0.0)) { - float f = (float)ValInt; - Val = f; - Color = color(f, f, f); - Vector = vector(f, f, f); - Point = point(f, f, f); - Normal = normal(f, f, f); + float f = (float)value_int; + value_float = f; + value_color = color(f, f, f); + value_vector = vector(f, f, f); + value_point = point(f, f, f); + value_normal = normal(f, f, f); } diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl index 8ecc56ac8ce..7fffa7f6169 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl @@ -17,18 +17,18 @@ #include "stdosl.h" shader node_convert_from_normal( - normal Normal = normal(0.0, 0.0, 0.0), - output string String = "", - output float Val = 0.0, - output int ValInt = 0, - output vector Vector = vector(0.0, 0.0, 0.0), - output color Color = 0.0, - output point Point = point(0.0, 0.0, 0.0)) + normal value_normal = normal(0.0, 0.0, 0.0), + output string value_string = "", + output float value_float = 0.0, + output int value_int = 0, + output vector value_vector = vector(0.0, 0.0, 0.0), + output color value_color = 0.0, + output point value_point = point(0.0, 0.0, 0.0)) { - Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0); - ValInt = (int)((Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0)); - Vector = vector(Normal[0], Normal[1], Normal[2]); - Color = color(Normal[0], Normal[1], Normal[2]); - Point = point(Normal[0], Normal[1], Normal[2]); + value_float = (value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0); + value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0)); + value_vector = vector(value_normal[0], value_normal[1], value_normal[2]); + value_color = color(value_normal[0], value_normal[1], value_normal[2]); + value_point = point(value_normal[0], value_normal[1], value_normal[2]); } diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl index e5913b7a1e4..9e4930296bb 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_point.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl @@ -17,18 +17,18 @@ #include "stdosl.h" shader node_convert_from_point( - point Point = point(0.0, 0.0, 0.0), - output string String = "", - output float Val = 0.0, - output int ValInt = 0, - output vector Vector = vector(0.0, 0.0, 0.0), - output color Color = 0.0, - output normal Normal = normal(0.0, 0.0, 0.0)) + point value_point = point(0.0, 0.0, 0.0), + output string value_string = "", + output float value_float = 0.0, + output int value_int = 0, + output vector value_vector = vector(0.0, 0.0, 0.0), + output color value_color = 0.0, + output normal value_normal = normal(0.0, 0.0, 0.0)) { - Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0); - ValInt = (int)((Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0)); - Vector = vector(Point[0], Point[1], Point[2]); - Color = color(Point[0], Point[1], Point[2]); - Normal = normal(Point[0], Point[1], Point[2]); + value_float = (value_point[0] + value_point[1] + value_point[2]) * (1.0 / 3.0); + value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0)); + value_vector = vector(value_point[0], value_point[1], value_point[2]); + value_color = color(value_point[0], value_point[1], value_point[2]); + value_normal = normal(value_point[0], value_point[1], value_point[2]); } diff --git a/intern/cycles/kernel/shaders/node_convert_from_string.osl b/intern/cycles/kernel/shaders/node_convert_from_string.osl index 0466734277b..cbc6653eada 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_string.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_string.osl @@ -17,13 +17,13 @@ #include "stdosl.h" shader node_convert_from_string( - string String = "", - output color Color = color(0.0, 0.0, 0.0), - output float Val = 0.0, - output int ValInt = 0, - output vector Vector = vector(0.0, 0.0, 0.0), - output point Point = point(0.0, 0.0, 0.0), - output normal Normal = normal(0.0, 0.0, 0.0)) + string value_string = "", + output color value_color = color(0.0, 0.0, 0.0), + output float value_float = 0.0, + output int value_int = 0, + output vector value_vector = vector(0.0, 0.0, 0.0), + output point value_point = point(0.0, 0.0, 0.0), + output normal value_normal = normal(0.0, 0.0, 0.0)) { } diff --git a/intern/cycles/kernel/shaders/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl index 79c5cb04550..8bdca469b90 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_vector.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl @@ -17,18 +17,18 @@ #include "stdosl.h" shader node_convert_from_vector( - vector Vector = vector(0.0, 0.0, 0.0), - output string String = "", - output float Val = 0.0, - output int ValInt = 0, - output color Color = color(0.0, 0.0, 0.0), - output point Point = point(0.0, 0.0, 0.0), - output normal Normal = normal(0.0, 0.0, 0.0)) + vector value_vector = vector(0.0, 0.0, 0.0), + output string value_string = "", + output float value_float = 0.0, + output int value_int = 0, + output color value_color = color(0.0, 0.0, 0.0), + output point value_point = point(0.0, 0.0, 0.0), + output normal value_normal = normal(0.0, 0.0, 0.0)) { - Val = (Vector[0] + Vector[1] + Vector[2]) * (1.0 / 3.0); - ValInt = (int)((Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0)); - Color = color(Vector[0], Vector[1], Vector[2]); - Point = point(Vector[0], Vector[1], Vector[2]); - Normal = normal(Vector[0], Vector[1], Vector[2]); + value_float = (value_vector[0] + value_vector[1] + value_vector[2]) * (1.0 / 3.0); + value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0)); + value_color = color(value_vector[0], value_vector[1], value_vector[2]); + value_point = point(value_vector[0], value_vector[1], value_vector[2]); + value_normal = normal(value_vector[0], value_vector[1], value_vector[2]); } diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl index 52b49688ab3..69e2ee54bdf 100644 --- a/intern/cycles/kernel/shaders/node_gradient_texture.osl +++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl @@ -63,7 +63,7 @@ float gradient(point p, string type) shader node_gradient_texture( int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - string Type = "Linear", + string type = "Linear", point Vector = P, output float Fac = 0.0, output color Color = 0.0) @@ -73,7 +73,7 @@ shader node_gradient_texture( if (use_mapping) p = transform(mapping, p); - Fac = gradient(p, Type); + Fac = gradient(p, type); Color = color(Fac, Fac, Fac); } diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl index d3a347b70db..d09174ff5d3 100644 --- a/intern/cycles/kernel/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/shaders/node_image_texture.osl @@ -62,9 +62,9 @@ color image_texture_lookup(string filename, int use_alpha, int is_float, string interpolation, - string wrap) + string extension) { - color rgb = (color)texture(filename, u, 1.0 - v, "wrap", wrap, "interp", interpolation, "alpha", Alpha); + color rgb = (color)texture(filename, u, 1.0 - v, "wrap", extension, "interp", interpolation, "alpha", Alpha); if (use_alpha) { rgb = color_unpremultiply(rgb, Alpha); diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl index 55992e3494c..8d6af391e04 100644 --- a/intern/cycles/kernel/shaders/node_magic_texture.osl +++ b/intern/cycles/kernel/shaders/node_magic_texture.osl @@ -93,7 +93,7 @@ color magic(point p, int n, float distortion) shader node_magic_texture( int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - int Depth = 2, + int depth = 2, float Distortion = 5.0, float Scale = 5.0, point Vector = P, @@ -105,7 +105,7 @@ shader node_magic_texture( if (use_mapping) p = transform(mapping, p); - Color = magic(p * Scale, Depth, Distortion); + Color = magic(p * Scale, depth, Distortion); Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0); } diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl index 7eef97fd7e8..85eac0b97a6 100644 --- a/intern/cycles/kernel/shaders/node_math.osl +++ b/intern/cycles/kernel/shaders/node_math.osl @@ -50,7 +50,7 @@ float safe_log(float a, float b) shader node_math( string type = "Add", - int Clamp = 0, + int use_clamp = 0, float Value1 = 0.0, float Value2 = 0.0, output float Value = 0.0) @@ -96,7 +96,7 @@ shader node_math( else if (type == "Absolute") Value = fabs(Value1); - if (Clamp) + if (use_clamp) Value = clamp(Value, 0.0, 1.0); } diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl index 9ef58e4cbba..4a66748ed6a 100644 --- a/intern/cycles/kernel/shaders/node_mix.osl +++ b/intern/cycles/kernel/shaders/node_mix.osl @@ -278,7 +278,7 @@ color node_mix_clamp(color col) shader node_mix( string type = "Mix", - int Clamp = 0, + int use_clamp = 0, float Fac = 0.5, color Color1 = 0.0, color Color2 = 0.0, @@ -323,7 +323,7 @@ shader node_mix( if (type == "Linear Light") Color = node_mix_linear(t, Color1, Color2); - if (Clamp) + if (use_clamp) Color = node_mix_clamp(Color); } diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl index 4f95dec910a..2f9f62bcfe8 100644 --- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl +++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl @@ -187,7 +187,7 @@ float noise_musgrave_ridged_multi_fractal(point p, float H, float lacunarity, shader node_musgrave_texture( int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - string Type = "fBM", + string type = "fBM", float Dimension = 2.0, float Lacunarity = 1.0, float Detail = 2.0, @@ -210,15 +210,15 @@ shader node_musgrave_texture( p = p * Scale; - if (Type == "Multifractal") + if (type == "Multifractal") Fac = intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves); - else if (Type == "fBM") + else if (type == "fBM") Fac = intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves); - else if (Type == "Hybrid Multifractal") + else if (type == "Hybrid Multifractal") Fac = intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, Offset, Gain); - else if (Type == "Ridged Multifractal") + else if (type == "Ridged Multifractal") Fac = intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, Offset, Gain); - else if (Type == "Hetero Terrain") + else if (type == "Hetero Terrain") Fac = intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, Offset); Color = color(Fac, Fac, Fac); diff --git a/intern/cycles/kernel/shaders/node_normal.osl b/intern/cycles/kernel/shaders/node_normal.osl index 2d04978fc72..7307971eddd 100644 --- a/intern/cycles/kernel/shaders/node_normal.osl +++ b/intern/cycles/kernel/shaders/node_normal.osl @@ -17,12 +17,12 @@ #include "stdosl.h" shader node_normal( - normal Direction = normal(0.0, 0.0, 0.0), + normal direction = normal(0.0, 0.0, 0.0), normal NormalIn = normal(0.0, 0.0, 0.0), output normal NormalOut = normal(0.0, 0.0, 0.0), output float Dot = 1.0) { - NormalOut = normalize(Direction); + NormalOut = normalize(direction); Dot = dot(NormalOut, normalize(NormalIn)); } diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl index 2ab6b6778b7..c0ae74d6b33 100644 --- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl +++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl @@ -20,7 +20,7 @@ shader node_rgb_ramp( color ramp_color[] = {0.0}, float ramp_alpha[] = {0.0}, - int ramp_interpolate = 1, + int interpolate = 1, float Fac = 0.0, output color Color = 0.0, @@ -38,7 +38,7 @@ shader node_rgb_ramp( Color = ramp_color[i]; Alpha = ramp_alpha[i]; - if (ramp_interpolate && t > 0.0) { + if (interpolate && t > 0.0) { Color = (1.0 - t) * Color + t * ramp_color[i + 1]; Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1]; } diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl index a67333c5d4e..1877c7e595f 100644 --- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl +++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl @@ -22,13 +22,13 @@ shader node_subsurface_scattering( vector Radius = vector(0.1, 0.1, 0.1), float TextureBlur = 0.0, float Sharpness = 0.0, - string Falloff = "Cubic", + string falloff = "Cubic", normal Normal = N, output closure color BSSRDF = 0) { - if (Falloff == "Gaussian") + if (falloff == "Gaussian") BSSRDF = Color * bssrdf_gaussian(Normal, Scale * Radius, TextureBlur); - else if (Falloff == "Cubic") + else if (falloff == "Cubic") BSSRDF = Color * bssrdf_cubic(Normal, Scale * Radius, TextureBlur, Sharpness); else BSSRDF = Color * bssrdf_burley(Normal, Scale * Radius, TextureBlur, Color); diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl index 29e143ae207..bacdd593c7c 100644 --- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl +++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl @@ -22,7 +22,7 @@ shader node_voronoi_texture( int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - string Coloring = "Intensity", + string coloring = "Intensity", float Scale = 5.0, point Vector = P, output float Fac = 0.0, @@ -40,7 +40,7 @@ shader node_voronoi_texture( voronoi(p * Scale, 1.0, da, pa); /* Colored output */ - if (Coloring == "Intensity") { + if (coloring == "Intensity") { Fac = fabs(da[0]); Color = color(Fac); } diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl index 59f61d3b46a..a07742faefc 100644 --- a/intern/cycles/kernel/shaders/node_wave_texture.osl +++ b/intern/cycles/kernel/shaders/node_wave_texture.osl @@ -48,8 +48,8 @@ float wave(point p, string type, string profile, float detail, float distortion, shader node_wave_texture( int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - string Type = "Bands", - string Profile = "Sine", + string type = "Bands", + string profile = "Sine", float Scale = 5.0, float Distortion = 0.0, float Detail = 2.0, @@ -63,7 +63,7 @@ shader node_wave_texture( if (use_mapping) p = transform(mapping, p); - Fac = wave(p * Scale, Type, Profile, Detail, Distortion, DetailScale); + Fac = wave(p * Scale, type, profile, Detail, Distortion, DetailScale); Color = Fac; } diff --git a/intern/cycles/kernel/split/kernel_background_buffer_update.h b/intern/cycles/kernel/split/kernel_background_buffer_update.h index 3d12a3dd993..f42d0a985bb 100644 --- a/intern/cycles/kernel/split/kernel_background_buffer_update.h +++ b/intern/cycles/kernel/split/kernel_background_buffer_update.h @@ -157,7 +157,7 @@ ccl_device char kernel_background_buffer_update( if(IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) { #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, state, ray); + float3 L_background = indirect_background(kg, kg->sd_input, state, ray); path_radiance_accum_background(L, (*throughput), L_background, state->bounce); #endif ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER); @@ -226,7 +226,7 @@ ccl_device char kernel_background_buffer_update( *throughput = make_float3(1.0f, 1.0f, 1.0f); *L_transparent = 0.0f; path_radiance_init(L, kernel_data.film.use_light_pass); - path_state_init(kg, state, rng, sample, ray); + path_state_init(kg, kg->sd_input, state, rng, sample, ray); #ifdef __KERNEL_DEBUG__ debug_data_init(debug_data); #endif diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h index 9891391a3a3..e3dbc43757e 100644 --- a/intern/cycles/kernel/split/kernel_data_init.h +++ b/intern/cycles/kernel/split/kernel_data_init.h @@ -207,6 +207,7 @@ ccl_device void kernel_data_init( L_transparent_coop[ray_index] = 0.0f; path_radiance_init(&PathRadiance_coop[ray_index], kernel_data.film.use_light_pass); path_state_init(kg, + kg->sd_input, &PathState_coop[ray_index], &rng_coop[ray_index], my_sample, diff --git a/intern/cycles/kernel/split/kernel_direct_lighting.h b/intern/cycles/kernel/split/kernel_direct_lighting.h index c7a2aa6426c..ebe91097496 100644 --- a/intern/cycles/kernel/split/kernel_direct_lighting.h +++ b/intern/cycles/kernel/split/kernel_direct_lighting.h @@ -88,7 +88,7 @@ ccl_device char kernel_direct_lighting( BsdfEval L_light; bool is_lamp; - if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, sd, kg->sd_input, &ls, state, &light_ray, &L_light, &is_lamp)) { /* Write intermediate data to global memory to access from * the next kernel. */ diff --git a/intern/cycles/kernel/split/kernel_lamp_emission.h b/intern/cycles/kernel/split/kernel_lamp_emission.h index dc3b4b34d4e..3bd0e361078 100644 --- a/intern/cycles/kernel/split/kernel_lamp_emission.h +++ b/intern/cycles/kernel/split/kernel_lamp_emission.h @@ -74,7 +74,7 @@ ccl_device void kernel_lamp_emission( /* intersect with lamp */ float3 emission; - if(indirect_lamp_emission(kg, state, &light_ray, &emission)) { + if(indirect_lamp_emission(kg, kg->sd_input, state, &light_ray, &emission)) { path_radiance_accum_emission(L, throughput, emission, state->bounce); } } diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked.h b/intern/cycles/kernel/split/kernel_shadow_blocked.h index 0c989861eef..6153af47f96 100644 --- a/intern/cycles/kernel/split/kernel_shadow_blocked.h +++ b/intern/cycles/kernel/split/kernel_shadow_blocked.h @@ -71,6 +71,7 @@ ccl_device void kernel_shadow_blocked( float3 shadow; update_path_radiance = !(shadow_blocked(kg, + kg->sd_input, state, light_ray_global, &shadow)); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 88397005b49..65512a0105c 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -365,8 +365,12 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * } break; } - case CLOSURE_BSDF_DIFFUSE_TOON_ID: - case CLOSURE_BSDF_GLOSSY_TOON_ID: { + case CLOSURE_BSDF_GLOSSY_TOON_ID: +#ifdef __CAUSTICS_TRICKS__ + if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) + break; +#endif + case CLOSURE_BSDF_DIFFUSE_TOON_ID: { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 92d2b36bbb1..3d9ab405849 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -18,15 +18,15 @@ CCL_NAMESPACE_BEGIN /* Float4 textures on various devices. */ #if defined(__KERNEL_CPU__) -# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_IMAGES_CPU +# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_CPU #elif defined(__KERNEL_CUDA__) # if __CUDA_ARCH__ < 300 -# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_IMAGES_CUDA +# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_CUDA # else -# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER +# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_CUDA_KEPLER # endif #else -# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_IMAGES_OPENCL +# define TEX_NUM_FLOAT4_IMAGES TEX_NUM_FLOAT4_OPENCL #endif #ifdef __KERNEL_OPENCL__ diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 8c69c589ebb..e57d22b1b13 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -343,6 +343,11 @@ typedef enum NodeNormalMapSpace { NODE_NORMAL_MAP_BLENDER_WORLD, } NodeNormalMapSpace; +typedef enum NodeImageColorSpace { + NODE_COLOR_SPACE_NONE = 0, + NODE_COLOR_SPACE_COLOR = 1, +} NodeImageColorSpace; + typedef enum NodeImageProjection { NODE_IMAGE_PROJ_FLAT = 0, NODE_IMAGE_PROJ_BOX = 1, @@ -350,6 +355,11 @@ typedef enum NodeImageProjection { NODE_IMAGE_PROJ_TUBE = 3, } NodeImageProjection; +typedef enum NodeEnvironmentProjection { + NODE_ENVIRONMENT_EQUIRECTANGULAR = 0, + NODE_ENVIRONMENT_MIRROR_BALL = 1, +} NodeEnvironmentProjection; + typedef enum NodeBumpOffset { NODE_BUMP_OFFSET_CENTER, NODE_BUMP_OFFSET_DX, @@ -370,6 +380,9 @@ typedef enum ShaderType { /* Closure */ typedef enum ClosureType { + /* Special type, flags generic node as a non-BSDF. */ + CLOSURE_NONE_ID, + CLOSURE_BSDF_ID, /* Diffuse */ diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index b7de83d89c1..71a3cba6811 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -51,13 +51,13 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_) type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix); } -void Attribute::reserve(int numverts, int numtris, int numsteps, int numcurves, int numkeys, bool resize) +void Attribute::resize(int numverts, int numtris, int numsteps, int numcurves, int numkeys, bool reserve_only) { - if(resize) { - buffer.resize(buffer_size(numverts, numtris, numsteps, numcurves, numkeys), 0); + if(reserve_only) { + buffer.reserve(buffer_size(numverts, numtris, numsteps, numcurves, numkeys)); } else { - buffer.reserve(buffer_size(numverts, numtris, numsteps, numcurves, numkeys)); + buffer.resize(buffer_size(numverts, numtris, numsteps, numcurves, numkeys), 0); } } @@ -263,7 +263,7 @@ AttributeSet::~AttributeSet() { } -Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element, bool resize) +Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element) { Attribute *attr = find(name); @@ -291,9 +291,9 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme /* this is weak .. */ if(triangle_mesh) - attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), triangle_mesh->motion_steps, 0, 0, resize); + attr->resize(triangle_mesh->verts.size(), triangle_mesh->num_triangles(), triangle_mesh->motion_steps, 0, 0, false); if(curve_mesh) - attr->reserve(0, 0, curve_mesh->motion_steps, curve_mesh->curves.size(), curve_mesh->curve_keys.size(), resize); + attr->resize(0, 0, curve_mesh->motion_steps, curve_mesh->num_curves(), curve_mesh->curve_keys.size(), false); return attr; } @@ -448,13 +448,13 @@ Attribute *AttributeSet::find(AttributeRequest& req) return find(req.std); } -void AttributeSet::reserve() +void AttributeSet::resize(bool reserve_only) { foreach(Attribute& attr, attributes) { if(triangle_mesh) - attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), triangle_mesh->motion_steps, 0, 0, true); + attr.resize(triangle_mesh->verts.size(), triangle_mesh->num_triangles(), triangle_mesh->motion_steps, 0, 0, reserve_only); if(curve_mesh) - attr.reserve(0, 0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size(), true); + attr.resize(0, 0, 0, curve_mesh->num_curves(), curve_mesh->curve_keys.size(), reserve_only); } } diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index 01102d22aaa..41b3626afd3 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -58,7 +58,7 @@ public: Attribute() {} ~Attribute(); void set(ustring name, TypeDesc type, AttributeElement element); - void reserve(int numverts, int numfaces, int numsteps, int numcurves, int numkeys, bool resize); + void resize(int numverts, int numfaces, int numsteps, int numcurves, int numkeys, bool reserve_only); size_t data_sizeof() const; size_t element_size(int numverts, int numfaces, int numsteps, int numcurves, int numkeys) const; @@ -104,7 +104,7 @@ public: AttributeSet(); ~AttributeSet(); - Attribute *add(ustring name, TypeDesc type, AttributeElement element, bool resize = true); + Attribute *add(ustring name, TypeDesc type, AttributeElement element); Attribute *find(ustring name) const; void remove(ustring name); @@ -114,7 +114,7 @@ public: Attribute *find(AttributeRequest& req); - void reserve(); + void resize(bool reserve_only = false); void clear(); }; diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp index 6f8d1d1d461..20536b74e87 100644 --- a/intern/cycles/render/background.cpp +++ b/intern/cycles/render/background.cpp @@ -116,6 +116,11 @@ 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); diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h index 843655b00a1..8029c6a9e80 100644 --- a/intern/cycles/render/background.h +++ b/intern/cycles/render/background.h @@ -50,6 +50,7 @@ public: 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); }; diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index 5bf5e5113ef..13310a61761 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -177,7 +177,7 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre device->mem_alloc(d_input, MEM_READ_ONLY); device->mem_copy_to(d_input); - device->mem_alloc(d_output, MEM_WRITE_ONLY); + device->mem_alloc(d_output, MEM_READ_WRITE); DeviceTask task(DeviceTask::SHADER); task.shader_input = d_input.device_pointer; diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index d992cac5312..2310798be2e 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -30,70 +30,126 @@ CCL_NAMESPACE_BEGIN static float shutter_curve_eval(float x, - float shutter_curve[RAMP_TABLE_SIZE]) + array<float>& shutter_curve) { - x *= RAMP_TABLE_SIZE; + if (shutter_curve.size() == 0) + return 1.0f; + + x *= shutter_curve.size(); int index = (int)x; float frac = x - index; - if(index < RAMP_TABLE_SIZE - 1) { + if(index < shutter_curve.size() - 1) { return lerp(shutter_curve[index], shutter_curve[index + 1], frac); } else { - return shutter_curve[RAMP_TABLE_SIZE - 1]; + return shutter_curve[shutter_curve.size() - 1]; } } +NODE_DEFINE(Camera) +{ + NodeType* type = NodeType::add("camera", create); + + SOCKET_FLOAT(shuttertime, "Shutter Time", 1.0f); + + static NodeEnum motion_position_enum; + motion_position_enum.insert("start", MOTION_POSITION_START); + motion_position_enum.insert("center", MOTION_POSITION_CENTER); + motion_position_enum.insert("end", MOTION_POSITION_END); + SOCKET_ENUM(motion_position, "Motion Position", motion_position_enum, MOTION_POSITION_CENTER); + + static NodeEnum rolling_shutter_type_enum; + rolling_shutter_type_enum.insert("none", ROLLING_SHUTTER_NONE); + rolling_shutter_type_enum.insert("top", ROLLING_SHUTTER_TOP); + SOCKET_ENUM(rolling_shutter_type, "Rolling Shutter Type", rolling_shutter_type_enum, ROLLING_SHUTTER_NONE); + SOCKET_FLOAT(rolling_shutter_duration, "Rolling Shutter Duration", 0.1f); + + SOCKET_FLOAT_ARRAY(shutter_curve, "Shutter Curve", array<float>()); + + SOCKET_FLOAT(aperturesize, "Aperture Size", 0.0f); + SOCKET_FLOAT(focaldistance, "Focal Distance", 10.0f); + SOCKET_INT(blades, "Blades", 0); + SOCKET_FLOAT(bladesrotation, "Blades Rotation", 0.0f); + + SOCKET_TRANSFORM(matrix, "Matrix", transform_identity()); + + SOCKET_FLOAT(aperture_ratio, "Aperture Ratio", 1.0f); + + static NodeEnum type_enum; + 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); + + static NodeEnum panorama_type_enum; + panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR); + panorama_type_enum.insert("mirrorball", PANORAMA_MIRRORBALL); + panorama_type_enum.insert("fisheye_equidistant", PANORAMA_FISHEYE_EQUIDISTANT); + panorama_type_enum.insert("fisheye_equisolid", PANORAMA_FISHEYE_EQUISOLID); + SOCKET_ENUM(panorama_type, "Panorama Type", panorama_type_enum, PANORAMA_EQUIRECTANGULAR); + + SOCKET_FLOAT(fisheye_fov, "Fisheye FOV", M_PI_F); + SOCKET_FLOAT(fisheye_lens, "Fisheye Lens", 10.5f); + SOCKET_FLOAT(latitude_min, "Latitude Min", -M_PI_2_F); + SOCKET_FLOAT(latitude_max, "Latitude Max", M_PI_2_F); + SOCKET_FLOAT(longitude_min, "Longitude Min", -M_PI_F); + SOCKET_FLOAT(longitude_max, "Longitude Max", M_PI_F); + SOCKET_FLOAT(fov, "FOV", M_PI_4_F); + SOCKET_FLOAT(fov_pre, "FOV Pre", M_PI_4_F); + SOCKET_FLOAT(fov_post, "FOV Post", M_PI_4_F); + + static NodeEnum stereo_eye_enum; + stereo_eye_enum.insert("none", STEREO_NONE); + stereo_eye_enum.insert("left", STEREO_LEFT); + stereo_eye_enum.insert("right", STEREO_RIGHT); + SOCKET_ENUM(stereo_eye, "Stereo Eye", stereo_eye_enum, STEREO_NONE); + + SOCKET_FLOAT(interocular_distance, "Interocular Distance", 0.065f); + SOCKET_FLOAT(convergence_distance, "Convergence Distance", 30.0f * 0.065f); + + SOCKET_BOOLEAN(use_pole_merge, "Use Pole Merge", false); + SOCKET_FLOAT(pole_merge_angle_from, "Pole Merge Angle From", 60.0f * M_PI_F / 180.0f); + SOCKET_FLOAT(pole_merge_angle_to, "Pole Merge Angle To", 75.0f * M_PI_F / 180.0f); + + SOCKET_FLOAT(sensorwidth, "Sensor Width", 0.036f); + SOCKET_FLOAT(sensorheight, "Sensor Height", 0.024f); + + SOCKET_FLOAT(nearclip, "Near Clip", 1e-5f); + SOCKET_FLOAT(farclip, "Far Clip", 1e5f); + + SOCKET_FLOAT(viewplane.left, "Viewplane Left", 0); + SOCKET_FLOAT(viewplane.right, "Viewplane Right", 0); + SOCKET_FLOAT(viewplane.bottom, "Viewplane Bottom", 0); + SOCKET_FLOAT(viewplane.top, "Viewplane Top", 0); + + SOCKET_FLOAT(border.left, "Border Left", 0); + SOCKET_FLOAT(border.right, "Border Right", 0); + SOCKET_FLOAT(border.bottom, "Border Bottom", 0); + SOCKET_FLOAT(border.top, "Border Top", 0); + + return type; +} + Camera::Camera() +: Node(node_type) { - shuttertime = 1.0f; - motion_position = MOTION_POSITION_CENTER; shutter_table_offset = TABLE_OFFSET_INVALID; - aperturesize = 0.0f; - focaldistance = 10.0f; - blades = 0; - bladesrotation = 0.0f; - - matrix = transform_identity(); + width = 1024; + height = 512; + resolution = 1; motion.pre = transform_identity(); motion.post = transform_identity(); use_motion = false; use_perspective_motion = false; - aperture_ratio = 1.0f; - - type = CAMERA_PERSPECTIVE; - panorama_type = PANORAMA_EQUIRECTANGULAR; - fisheye_fov = M_PI_F; - fisheye_lens = 10.5f; - latitude_min = -M_PI_2_F; - latitude_max = M_PI_2_F; - longitude_min = -M_PI_F; - longitude_max = M_PI_F; - fov = M_PI_4_F; - fov_pre = fov_post = fov; - stereo_eye = STEREO_NONE; - interocular_distance = 0.065f; - convergence_distance = 30.0f * 0.065f; - use_pole_merge = false; - pole_merge_angle_from = 60.0f * M_PI_F / 180.0f; - pole_merge_angle_to = 75.0f * M_PI_F / 180.0f; - - sensorwidth = 0.036f; - sensorheight = 0.024f; - - nearclip = 1e-5f; - farclip = 1e5f; - - width = 1024; - height = 512; - resolution = 1; + shutter_curve.resize(RAMP_TABLE_SIZE); + for(int i = 0; i < shutter_curve.size(); ++i) { + shutter_curve[i] = 1.0f; + } - viewplane.left = -((float)width/(float)height); - viewplane.right = (float)width/(float)height; - viewplane.bottom = -1.0f; - viewplane.top = 1.0f; + compute_auto_viewplane(); screentoworld = transform_identity(); rastertoworld = transform_identity(); @@ -109,16 +165,6 @@ Camera::Camera() need_device_update = true; need_flags_update = true; previous_need_motion = -1; - - /* Initialize shutter curve. */ - const int num_shutter_points = sizeof(shutter_curve) / sizeof(*shutter_curve); - for(int i = 0; i < num_shutter_points; ++i) { - shutter_curve[i] = 1.0f; - } - - /* Initialize rolling shutter effect. */ - rolling_shutter_type = ROLLING_SHUTTER_NONE; - rolling_shutter_duration = 0.1f; } Camera::~Camera() @@ -438,38 +484,14 @@ void Camera::device_free(Device * /*device*/, bool Camera::modified(const Camera& cam) { - return !((shuttertime == cam.shuttertime) && - (aperturesize == cam.aperturesize) && - (blades == cam.blades) && - (bladesrotation == cam.bladesrotation) && - (focaldistance == cam.focaldistance) && - (type == cam.type) && - (fov == cam.fov) && - (nearclip == cam.nearclip) && - (farclip == cam.farclip) && - (sensorwidth == cam.sensorwidth) && - (sensorheight == cam.sensorheight) && - // modified for progressive render - // (width == cam.width) && - // (height == cam.height) && - (viewplane == cam.viewplane) && - (border == cam.border) && - (matrix == cam.matrix) && - (aperture_ratio == cam.aperture_ratio) && - (panorama_type == cam.panorama_type) && - (fisheye_fov == cam.fisheye_fov) && - (fisheye_lens == cam.fisheye_lens) && - (latitude_min == cam.latitude_min) && - (latitude_max == cam.latitude_max) && - (longitude_min == cam.longitude_min) && - (longitude_max == cam.longitude_max) && - (stereo_eye == cam.stereo_eye)); + return !Node::equals(cam); } bool Camera::motion_modified(const Camera& cam) { return !((motion == cam.motion) && - (use_motion == cam.use_motion)); + (use_motion == cam.use_motion) && + (use_perspective_motion == cam.use_perspective_motion)); } void Camera::tag_update() diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 57b9960e70b..141ef9cccef 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -19,6 +19,8 @@ #include "kernel_types.h" +#include "node.h" + #include "util_boundbox.h" #include "util_transform.h" #include "util_types.h" @@ -35,8 +37,10 @@ class Scene; * Renderman, and Blender after remapping. */ -class Camera { +class Camera : public Node { public: + NODE_DECLARE; + /* Specifies an offset for the shutter's time interval. */ enum MotionPosition { /* Shutter opens at the current frame. */ @@ -69,7 +73,7 @@ public: /* motion blur */ float shuttertime; MotionPosition motion_position; - float shutter_curve[RAMP_TABLE_SIZE]; + array<float> shutter_curve; size_t shutter_table_offset; /* ** Rolling shutter effect. ** */ diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h index 3d9b4e1f347..e41967eebf5 100644 --- a/intern/cycles/render/curves.h +++ b/intern/cycles/render/curves.h @@ -63,23 +63,23 @@ public: ParticleCurveData(); ~ParticleCurveData(); - vector<int> psys_firstcurve; - vector<int> psys_curvenum; - vector<int> psys_shader; - - vector<float> psys_rootradius; - vector<float> psys_tipradius; - vector<float> psys_shape; - vector<bool> psys_closetip; - - vector<int> curve_firstkey; - vector<int> curve_keynum; - vector<float> curve_length; - vector<float3> curve_uv; - vector<float3> curve_vcol; - - vector<float3> curvekey_co; - vector<float> curvekey_time; + array<int> psys_firstcurve; + array<int> psys_curvenum; + array<int> psys_shader; + + array<float> psys_rootradius; + array<float> psys_tipradius; + array<float> psys_shape; + array<bool> psys_closetip; + + array<int> curve_firstkey; + array<int> curve_keynum; + array<float> curve_length; + array<float3> curve_uv; + array<float3> curve_vcol; + + array<float3> curvekey_co; + array<float> curvekey_time; }; /* HairSystem Manager */ diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 12dce6ad999..e10a938e1eb 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -465,7 +465,7 @@ void Film::device_free(Device * /*device*/, bool Film::modified(const Film& film) { - return Node::modified(film) || !Pass::equals(passes, film.passes); + return !Node::equals(film) || !Pass::equals(passes, film.passes); } void Film::tag_passes_update(Scene *scene, const array<Pass>& passes_) diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 15c89cc4b51..29c0eec9b97 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -66,7 +66,7 @@ bool check_node_inputs_equals(const ShaderNode *node_a, *input_b = node_b->inputs[i]; if(input_a->link == NULL && input_b->link == NULL) { /* Unconnected inputs are expected to have the same value. */ - if(input_a->value != input_b->value) { + if(input_a->value() != input_b->value()) { return false; } } @@ -90,23 +90,22 @@ bool check_node_inputs_equals(const ShaderNode *node_a, /* Input and Output */ -ShaderInput::ShaderInput(ShaderNode *parent_, const char *name_, ShaderSocketType type_) +ShaderInput::ShaderInput(ShaderNode *parent_, const char *name, SocketType::Type type) { parent = parent_; - name = name_; - type = type_; + name_ = name; + type_ = type; link = NULL; - value = make_float3(0.0f, 0.0f, 0.0f); + value_ = make_float3(0.0f, 0.0f, 0.0f); stack_offset = SVM_STACK_INVALID; - default_value = NONE; - usage = USE_ALL; + flags_ = 0; } -ShaderOutput::ShaderOutput(ShaderNode *parent_, const char *name_, ShaderSocketType type_) +ShaderOutput::ShaderOutput(ShaderNode *parent_, const char *name, SocketType::Type type) { parent = parent_; - name = name_; - type = type_; + name_ = name; + type_ = type; stack_offset = SVM_STACK_INVALID; } @@ -132,7 +131,7 @@ ShaderNode::~ShaderNode() ShaderInput *ShaderNode::input(const char *name) { foreach(ShaderInput *socket, inputs) { - if(strcmp(socket->name, name) == 0) + if(socket->name() == name) return socket; } @@ -142,39 +141,50 @@ ShaderInput *ShaderNode::input(const char *name) ShaderOutput *ShaderNode::output(const char *name) { foreach(ShaderOutput *socket, outputs) - if(strcmp(socket->name, name) == 0) + if(socket->name() == name) return socket; return NULL; } -ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value, int usage) +ShaderInput *ShaderNode::input(ustring name) { - ShaderInput *input = new ShaderInput(this, name, type); - input->value.x = value; - input->usage = usage; - inputs.push_back(input); - return input; + foreach(ShaderInput *socket, inputs) { + if(socket->name() == name) + return socket; + } + + return NULL; +} + +ShaderOutput *ShaderNode::output(ustring name) +{ + foreach(ShaderOutput *socket, outputs) + if(socket->name() == name) + return socket; + + return NULL; } -ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value, int usage) +ShaderInput *ShaderNode::add_input(const char *name, SocketType::Type type, float value, int flags) { ShaderInput *input = new ShaderInput(this, name, type); - input->value = value; - input->usage = usage; + input->value_.x = value; + input->flags_ = flags; inputs.push_back(input); return input; } -ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage) +ShaderInput *ShaderNode::add_input(const char *name, SocketType::Type type, float3 value, int flags) { - ShaderInput *input = add_input(name, type); - input->default_value = value; - input->usage = usage; + ShaderInput *input = new ShaderInput(this, name, type); + input->value_ = value; + input->flags_ = flags; + inputs.push_back(input); return input; } -ShaderOutput *ShaderNode::add_output(const char *name, ShaderSocketType type) +ShaderOutput *ShaderNode::add_output(const char *name, SocketType::Type type) { ShaderOutput *output = new ShaderOutput(this, name, type); outputs.push_back(output); @@ -185,13 +195,13 @@ void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes) { foreach(ShaderInput *input, inputs) { if(!input->link) { - if(input->default_value == ShaderInput::TEXTURE_GENERATED) { + if(input->flags() & SocketType::LINK_TEXTURE_GENERATED) { if(shader->has_surface) attributes->add(ATTR_STD_GENERATED); if(shader->has_volume) attributes->add(ATTR_STD_GENERATED_TRANSFORM); } - else if(input->default_value == ShaderInput::TEXTURE_UV) { + else if(input->flags() & SocketType::LINK_TEXTURE_UV) { if(shader->has_surface) attributes->add(ATTR_STD_UV); } @@ -256,18 +266,18 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) return; } - if(from->type != to->type) { + if(from->type() != to->type()) { /* for closures we can't do automatic conversion */ - if(from->type == SHADER_SOCKET_CLOSURE || to->type == SHADER_SOCKET_CLOSURE) { + if(from->type() == SocketType::CLOSURE || to->type() == SocketType::CLOSURE) { fprintf(stderr, "Cycles shader graph connect: can only connect closure to closure " "(%s.%s to %s.%s).\n", - from->parent->name.c_str(), from->name, - to->parent->name.c_str(), to->name); + from->parent->name.c_str(), from->name().c_str(), + to->parent->name.c_str(), to->name().c_str()); return; } /* add automatic conversion node in case of type mismatch */ - ShaderNode *convert = add(new ConvertNode(from->type, to->type, true)); + ShaderNode *convert = add(new ConvertNode(from->type(), to->type(), true)); connect(from, convert->inputs[0]); connect(convert->outputs[0], to); @@ -401,8 +411,8 @@ void ShaderGraph::copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap) /* find new input and output */ ShaderNode *nfrom = nnodemap[input->link->parent]; ShaderNode *nto = nnodemap[input->parent]; - ShaderOutput *noutput = nfrom->output(input->link->name); - ShaderInput *ninput = nto->input(input->name); + ShaderOutput *noutput = nfrom->output(input->link->name()); + ShaderInput *ninput = nto->input(input->name()); /* connect */ connect(noutput, ninput); @@ -447,10 +457,10 @@ void ShaderGraph::remove_proxy_nodes() vector<ShaderInput*> links = tonode->outputs[0]->links; foreach(ShaderInput *autoin, links) { - if(autoin->default_value == ShaderInput::NONE) - all_links_removed = false; - else + if(autoin->flags() & SocketType::DEFAULT_LINK_MASK) disconnect(autoin); + else + all_links_removed = false; } if(all_links_removed) @@ -460,8 +470,8 @@ void ShaderGraph::remove_proxy_nodes() disconnect(to); /* transfer the default input value to the target socket */ - to->set(input->value); - to->set(input->value_string); + to->set(input->value()); + to->set(input->value_string()); } } @@ -527,14 +537,13 @@ void ShaderGraph::constant_fold() } } /* Optimize current node. */ - float3 optimized_value = make_float3(0.0f, 0.0f, 0.0f); - if(node->constant_fold(this, output, &optimized_value)) { - /* Apply optimized value to connected sockets. */ + if(node->constant_fold(this, output, output->links[0])) { + /* Apply optimized value to other connected sockets and disconnect. */ vector<ShaderInput*> links(output->links); - foreach(ShaderInput *input, links) { - /* Assign value and disconnect the optimizedinput. */ - input->value = optimized_value; - disconnect(input); + for(size_t i = 0; i < links.size(); i++) { + if(i > 0) + links[i]->set(links[0]->value()); + disconnect(links[i]); } } } @@ -706,38 +715,38 @@ void ShaderGraph::default_inputs(bool do_osl) foreach(ShaderNode *node, nodes) { foreach(ShaderInput *input, node->inputs) { - if(!input->link && ((input->usage & ShaderInput::USE_SVM) || do_osl)) { - if(input->default_value == ShaderInput::TEXTURE_GENERATED) { + if(!input->link && (!(input->flags() & SocketType::OSL_INTERNAL) || do_osl)) { + if(input->flags() & SocketType::LINK_TEXTURE_GENERATED) { if(!texco) texco = new TextureCoordinateNode(); connect(texco->output("Generated"), input); } - else if(input->default_value == ShaderInput::TEXTURE_UV) { + else if(input->flags() & SocketType::LINK_TEXTURE_UV) { if(!texco) texco = new TextureCoordinateNode(); connect(texco->output("UV"), input); } - else if(input->default_value == ShaderInput::INCOMING) { + else if(input->flags() & SocketType::LINK_INCOMING) { if(!geom) geom = new GeometryNode(); connect(geom->output("Incoming"), input); } - else if(input->default_value == ShaderInput::NORMAL) { + else if(input->flags() & SocketType::LINK_NORMAL) { if(!geom) geom = new GeometryNode(); connect(geom->output("Normal"), input); } - else if(input->default_value == ShaderInput::POSITION) { + else if(input->flags() & SocketType::LINK_POSITION) { if(!geom) geom = new GeometryNode(); connect(geom->output("Position"), input); } - else if(input->default_value == ShaderInput::TANGENT) { + else if(input->flags() & SocketType::LINK_TANGENT) { if(!geom) geom = new GeometryNode(); @@ -785,8 +794,8 @@ void ShaderGraph::refine_bump_nodes() pair.second->bump = SHADER_BUMP_DY; ShaderOutput *out = bump_input->link; - ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name); - ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name); + ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name()); + ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name()); connect(out_dx, node->input("SampleX")); connect(out_dy, node->input("SampleY")); @@ -860,9 +869,9 @@ void ShaderGraph::bump_from_displacement() ShaderNode *bump = add(new BumpNode()); ShaderOutput *out = displacement_in->link; - ShaderOutput *out_center = nodes_center[out->parent]->output(out->name); - ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name); - ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name); + ShaderOutput *out_center = nodes_center[out->parent]->output(out->name()); + ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name()); + ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name()); connect(out_center, bump->input("SampleCenter")); connect(out_dx, bump->input("SampleX")); @@ -882,7 +891,7 @@ void ShaderGraph::bump_from_displacement() continue; } foreach(ShaderInput *input, node->inputs) { - if(!input->link && input->default_value == ShaderInput::NORMAL) + if(!input->link && (input->flags() & SocketType::LINK_NORMAL)) connect(set_normal->output("Normal"), input); } } @@ -925,7 +934,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if(fin->link) connect(fin->link, fac_in); else - fac_in->value = fin->value; + fac_in->set(fin->value_float()); if(weight_out) connect(weight_out, weight_in); @@ -952,7 +961,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight return; /* already has a weight connected to it? add weights */ - if(weight_in->link || weight_in->value.x != 0.0f) { + if(weight_in->link || weight_in->value_float() != 0.0f) { ShaderNode *math_node = add(new MathNode()); ShaderInput *value1_in = math_node->input("Value1"); ShaderInput *value2_in = math_node->input("Value2"); @@ -960,12 +969,12 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if(weight_in->link) connect(weight_in->link, value1_in); else - value1_in->value = weight_in->value; + value1_in->set(weight_in->value_float()); if(weight_out) connect(weight_out, value2_in); else - value2_in->value.x = 1.0f; + value2_in->set(1.0f); weight_out = math_node->output("Value"); if(weight_in->link) @@ -976,7 +985,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if(weight_out) connect(weight_out, weight_in); else - weight_in->value.x += 1.0f; + weight_in->set(weight_in->value_float() + 1.0f); } } @@ -984,17 +993,18 @@ int ShaderGraph::get_num_closures() { int num_closures = 0; foreach(ShaderNode *node, nodes) { - if(node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) { - BsdfNode *bsdf_node = static_cast<BsdfNode*>(node); - /* TODO(sergey): Make it more generic approach, maybe some utility - * macros like CLOSURE_IS_FOO()? - */ - if(CLOSURE_IS_BSSRDF(bsdf_node->closure)) - num_closures = num_closures + 3; - else if(CLOSURE_IS_GLASS(bsdf_node->closure)) - num_closures = num_closures + 2; - else - num_closures = num_closures + 1; + ClosureType closure_type = node->get_closure_type(); + if(closure_type == CLOSURE_NONE_ID) { + continue; + } + else if(CLOSURE_IS_BSSRDF(closure_type)) { + num_closures += 3; + } + else if(CLOSURE_IS_GLASS(closure_type)) { + num_closures += 2; + } + else { + ++num_closures; } } return num_closures; @@ -1023,7 +1033,7 @@ void ShaderGraph::dump_graph(const char *filename) if(socket != node->inputs[0]) { fprintf(fd, "|"); } - fprintf(fd, "<IN_%p>%s", socket, socket->name); + fprintf(fd, "<IN_%p>%s", socket, socket->name().c_str()); } fprintf(fd, "}|"); } @@ -1043,7 +1053,7 @@ void ShaderGraph::dump_graph(const char *filename) if(socket != node->outputs[0]) { fprintf(fd, "|"); } - fprintf(fd, "<OUT_%p>%s", socket, socket->name); + fprintf(fd, "<OUT_%p>%s", socket, socket->name().c_str()); } fprintf(fd, "}"); } @@ -1057,7 +1067,7 @@ void ShaderGraph::dump_graph(const char *filename) "// CONNECTION: OUT_%p->IN_%p (%s:%s)\n", output, input, - output->name, input->name); + output->name().c_str(), input->name().c_str()); fprintf(fd, "\"%p\":\"OUT_%p\":e -> \"%p\":\"IN_%p\":w [label=\"\"]\n", output->parent, diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index b1ebdbfd51d..882e495df20 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -17,6 +17,8 @@ #ifndef __GRAPH_H__ #define __GRAPH_H__ +#include "node.h" + #include "kernel_types.h" #include "util_list.h" @@ -39,23 +41,6 @@ class SVMCompiler; class OSLCompiler; class OutputNode; -/* Socket Type - * - * Data type for inputs and outputs */ - -enum ShaderSocketType { - SHADER_SOCKET_UNDEFINED, - - SHADER_SOCKET_FLOAT, - SHADER_SOCKET_INT, - SHADER_SOCKET_COLOR, - SHADER_SOCKET_VECTOR, - SHADER_SOCKET_POINT, - SHADER_SOCKET_NORMAL, - SHADER_SOCKET_CLOSURE, - SHADER_SOCKET_STRING -}; - /* Bump * * For bump mapping, a node may be evaluated multiple times, using different @@ -86,30 +71,6 @@ enum ShaderNodeSpecialType { SHADER_SPECIAL_TYPE_BUMP, }; -/* Enum - * - * Utility class for enum values. */ - -class ShaderEnum { -public: - bool empty() const { return left.empty(); } - void insert(const char *x, int y) { - left[ustring(x)] = y; - right[y] = ustring(x); - } - - bool exists(ustring x) { return left.find(x) != left.end(); } - bool exists(int y) { return right.find(y) != right.end(); } - - int operator[](const char *x) { return left[ustring(x)]; } - int operator[](ustring x) { return left[x]; } - ustring operator[](int y) { return right[y]; } - -protected: - map<ustring, int> left; - map<int, ustring> right; -}; - /* Input * * Input socket for a shader node. May be linked to an output or not. If not @@ -118,39 +79,32 @@ protected: class ShaderInput { public: - enum DefaultValue { - TEXTURE_GENERATED, - TEXTURE_UV, - INCOMING, - NORMAL, - POSITION, - TANGENT, - NONE - }; - - enum Usage { - USE_SVM = 1, - USE_OSL = 2, - USE_ALL = USE_SVM|USE_OSL - }; - - ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type); - void set(const float3& v) { value = v; } - void set(float f) { value = make_float3(f, 0, 0); } - void set(const ustring v) { value_string = v; } - - const char *name; - ShaderSocketType type; + ShaderInput(ShaderNode *parent, const char *name, SocketType::Type type); + + ustring name() { return name_; } + int flags() { return flags_; } + SocketType::Type type() { return type_; } + + void set(float f) { value_.x = f; } + void set(float3 f) { value_ = f; } + void set(int i) { value_.x = (float)i; } + void set(ustring s) { value_string_ = s; } + + float3& value() { return value_; } + float& value_float() { return value_.x; } + ustring& value_string() { return value_string_; } + + ustring name_; + SocketType::Type type_; ShaderNode *parent; ShaderOutput *link; - DefaultValue default_value; - float3 value; - ustring value_string; + float3 value_; + ustring value_string_; int stack_offset; /* for SVM compiler */ - int usage; + int flags_; }; /* Output @@ -159,12 +113,15 @@ public: class ShaderOutput { public: - ShaderOutput(ShaderNode *parent, const char *name, ShaderSocketType type); + ShaderOutput(ShaderNode *parent, const char *name, SocketType::Type type); - const char *name; - ShaderNode *parent; - ShaderSocketType type; + ustring name() { return name_; } + SocketType::Type type() { return type_; } + ustring name_; + SocketType::Type type_; + + ShaderNode *parent; vector<ShaderInput*> links; int stack_offset; /* for SVM compiler */ @@ -182,11 +139,12 @@ public: ShaderInput *input(const char *name); ShaderOutput *output(const char *name); + ShaderInput *input(ustring name); + ShaderOutput *output(ustring name); - ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL); - ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL); - ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL); - ShaderOutput *add_output(const char *name, ShaderSocketType type); + ShaderInput *add_input(const char *name, SocketType::Type type, float value=0.0f, int flags=0); + ShaderInput *add_input(const char *name, SocketType::Type type, float3 value, int flags=0); + ShaderOutput *add_output(const char *name, SocketType::Type type); virtual ShaderNode *clone() const = 0; virtual void attributes(Shader *shader, AttributeRequestSet *attributes); @@ -195,7 +153,7 @@ public: /* ** Node optimization ** */ /* Check whether the node can be replaced with single constant. */ - virtual bool constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, float3 * /*optimized_value*/) { return false; } + virtual bool constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, ShaderInput * /*optimized*/) { return false; } /* Simplify settings used by artists to the ones which are simpler to * evaluate in the kernel but keep the final result unchanged. @@ -237,6 +195,9 @@ public: */ virtual int get_feature() { return bump == SHADER_BUMP_NONE ? 0 : NODE_FEATURE_BUMP; } + /* Get closure ID to which the node compiles into. */ + virtual ClosureType get_closure_type() { return CLOSURE_NONE_ID; } + /* Check whether settings of the node equals to another one. * * This is mainly used to check whether two nodes can be merged diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 150c742fd24..71dc85f5f03 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -36,59 +36,58 @@ ImageManager::ImageManager(const DeviceInfo& info) osl_texture_system = NULL; animation_frame = 0; - /* Set image limits */ + /* In case of multiple devices used we need to know type of an actual + * compute device. + * + * NOTE: We assume that all the devices are same type, otherwise we'll + * be screwed on so many levels.. + */ + DeviceType device_type = info.type; + if (device_type == DEVICE_MULTI) { + device_type = info.multi_devices[0].type; + } - /* CPU */ - if(info.type == DEVICE_CPU) { - tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CPU; - tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CPU; - tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CPU; - tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_CPU; - tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CPU; - tex_image_float_start = TEX_IMAGE_FLOAT_START_CPU; - tex_image_byte_start = TEX_IMAGE_BYTE_START_CPU; + /* Set image limits */ +#define SET_TEX_IMAGES_LIMITS(ARCH) \ + { \ + tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_ ## ARCH; \ + tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_ ## ARCH; \ + tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_ ## ARCH; \ + tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_ ## ARCH; \ + tex_start_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_START_FLOAT4_ ## ARCH; \ + tex_start_images[IMAGE_DATA_TYPE_BYTE4] = TEX_START_BYTE4_ ## ARCH; \ + tex_start_images[IMAGE_DATA_TYPE_FLOAT] = TEX_START_FLOAT_ ## ARCH; \ + tex_start_images[IMAGE_DATA_TYPE_BYTE] = TEX_START_BYTE_ ## ARCH; \ } - /* CUDA (Fermi) */ - else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && !info.has_bindless_textures) { - tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CUDA; - tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CUDA; - tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CUDA; - tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_CUDA; - tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CUDA; - tex_image_float_start = TEX_IMAGE_FLOAT_START_CUDA; - tex_image_byte_start = TEX_IMAGE_BYTE_START_CUDA; + + if(device_type == DEVICE_CPU) { + SET_TEX_IMAGES_LIMITS(CPU); } - /* CUDA (Kepler and above) */ - else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.has_bindless_textures) { - tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CUDA_KEPLER; - tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER; - tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CUDA_KEPLER; - tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_CUDA_KEPLER; - tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CUDA_KEPLER; - tex_image_float_start = TEX_IMAGE_FLOAT_START_CUDA_KEPLER; - tex_image_byte_start = TEX_IMAGE_BYTE_START_CUDA_KEPLER; + else if(device_type == DEVICE_CUDA) { + if(info.has_bindless_textures) { + SET_TEX_IMAGES_LIMITS(CUDA_KEPLER); + } + else { + SET_TEX_IMAGES_LIMITS(CUDA); + } } - /* OpenCL */ - else if(info.pack_images) { - tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_OPENCL; - tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_OPENCL; - tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_OPENCL; - tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_OPENCL; - tex_image_byte4_start = TEX_IMAGE_BYTE4_START_OPENCL; - tex_image_float_start = TEX_IMAGE_FLOAT_START_OPENCL; - tex_image_byte_start = TEX_IMAGE_BYTE_START_OPENCL; + else if(device_type == DEVICE_OPENCL) { + SET_TEX_IMAGES_LIMITS(OPENCL); } - /* Should never happen */ else { - tex_num_images[IMAGE_DATA_TYPE_BYTE4] = 0; + /* Should not happen. */ tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = 0; + tex_num_images[IMAGE_DATA_TYPE_BYTE4] = 0; tex_num_images[IMAGE_DATA_TYPE_FLOAT] = 0; tex_num_images[IMAGE_DATA_TYPE_BYTE] = 0; - tex_image_byte4_start = 0; - tex_image_float_start = 0; - tex_image_byte_start = 0; + tex_start_images[IMAGE_DATA_TYPE_FLOAT4] = 0; + tex_start_images[IMAGE_DATA_TYPE_BYTE4] = 0; + tex_start_images[IMAGE_DATA_TYPE_FLOAT] = 0; + tex_start_images[IMAGE_DATA_TYPE_BYTE] = 0; assert(0); } + +#undef SET_TEX_IMAGES_LIMITS } ImageManager::~ImageManager() @@ -207,34 +206,20 @@ ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filen * to device ones and vice versa. */ int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type) { - if(type == IMAGE_DATA_TYPE_BYTE4) - return slot + tex_image_byte4_start; - else if(type == IMAGE_DATA_TYPE_FLOAT) - return slot + tex_image_float_start; - else if(type == IMAGE_DATA_TYPE_BYTE) - return slot + tex_image_byte_start; - else - return slot; + return slot + tex_start_images[type]; } int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type) { - if(flat_slot >= tex_image_byte_start) { - *type = IMAGE_DATA_TYPE_BYTE; - return flat_slot - tex_image_byte_start; - } - else if(flat_slot >= tex_image_float_start) { - *type = IMAGE_DATA_TYPE_FLOAT; - return flat_slot - tex_image_float_start; - } - else if(flat_slot >= tex_image_byte4_start) { - *type = IMAGE_DATA_TYPE_BYTE4; - return flat_slot - tex_image_byte4_start; - } - else { - *type = IMAGE_DATA_TYPE_FLOAT4; - return flat_slot; + for(int i = IMAGE_DATA_NUM_TYPES - 1; i >= 0; i--) { + if(flat_slot >= tex_start_images[i]) { + *type = (ImageDataType)i; + return flat_slot - tex_start_images[i]; + } } + + /* Should not happen. */ + return flat_slot; } string ImageManager::name_from_type(int type) @@ -280,7 +265,7 @@ int ImageManager::add_image(const string& filename, if(type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4) is_float = true; - /* No single channel textures on Fermi GPUs, use available slots */ + /* No single channel textures on CUDA (Fermi) and OpenCL, use available slots */ if(type == IMAGE_DATA_TYPE_FLOAT && tex_num_images[type] == 0) type = IMAGE_DATA_TYPE_FLOAT4; if(type == IMAGE_DATA_TYPE_BYTE && tex_num_images[type] == 0) @@ -460,7 +445,8 @@ bool ImageManager::file_load_image_generic(Image *img, ImageInput **in, int &wid return true; } -bool ImageManager::file_load_byte4_image(Image *img, device_vector<uchar4>& tex_img) +template<typename T> +bool ImageManager::file_load_byte_image(Image *img, ImageDataType type, device_vector<T>& tex_img) { ImageInput *in = NULL; int width, height, depth, components; @@ -498,92 +484,59 @@ bool ImageManager::file_load_byte4_image(Image *img, device_vector<uchar4>& tex_ builtin_image_pixels_cb(img->filename, img->builtin_data, pixels); } - size_t num_pixels = ((size_t)width) * height * depth; - if(cmyk) { - /* CMYK */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; - pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; - pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; - pixels[i*4+3] = 255; - } - } - else if(components == 2) { - /* grayscale + alpha */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = pixels[i*2+1]; - pixels[i*4+2] = pixels[i*2+0]; - pixels[i*4+1] = pixels[i*2+0]; - pixels[i*4+0] = pixels[i*2+0]; + /* Check if we actually have a byte4 slot, in case components == 1, but device + * doesn't support single channel textures. */ + if(type == IMAGE_DATA_TYPE_BYTE4) { + size_t num_pixels = ((size_t)width) * height * depth; + if(cmyk) { + /* CMYK */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; + pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; + pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; + pixels[i*4+3] = 255; + } } - } - else if(components == 3) { - /* RGB */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; - pixels[i*4+2] = pixels[i*3+2]; - pixels[i*4+1] = pixels[i*3+1]; - pixels[i*4+0] = pixels[i*3+0]; + else if(components == 2) { + /* grayscale + alpha */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = pixels[i*2+1]; + pixels[i*4+2] = pixels[i*2+0]; + pixels[i*4+1] = pixels[i*2+0]; + pixels[i*4+0] = pixels[i*2+0]; + } } - } - else if(components == 1) { - /* grayscale */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; - pixels[i*4+2] = pixels[i]; - pixels[i*4+1] = pixels[i]; - pixels[i*4+0] = pixels[i]; + else if(components == 3) { + /* RGB */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + pixels[i*4+2] = pixels[i*3+2]; + pixels[i*4+1] = pixels[i*3+1]; + pixels[i*4+0] = pixels[i*3+0]; + } } - } - - if(img->use_alpha == false) { - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; + else if(components == 1) { + /* grayscale */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + pixels[i*4+2] = pixels[i]; + pixels[i*4+1] = pixels[i]; + pixels[i*4+0] = pixels[i]; + } } - } - - return true; -} - -bool ImageManager::file_load_byte_image(Image *img, device_vector<uchar>& tex_img) -{ - ImageInput *in = NULL; - int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read BW pixels */ - uchar *pixels = (uchar*)tex_img.resize(width, height, depth); - if(pixels == NULL) { - return false; - } - - if(in) { - if(depth <= 1) { - int scanlinesize = width*components*sizeof(uchar); - in->read_image(TypeDesc::UINT8, - (uchar*)pixels + (((size_t)height)-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); - } - else { - in->read_image(TypeDesc::UINT8, (uchar*)pixels); + if(img->use_alpha == false) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + } } - - in->close(); - delete in; - } - else { - builtin_image_pixels_cb(img->filename, img->builtin_data, pixels); } return true; } -bool ImageManager::file_load_float4_image(Image *img, device_vector<float4>& tex_img) +template<typename T> +bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_vector<T>& tex_img) { ImageInput *in = NULL; int width, height, depth, components; @@ -641,88 +594,52 @@ bool ImageManager::file_load_float4_image(Image *img, device_vector<float4>& tex builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); } - size_t num_pixels = ((size_t)width) * height * depth; - if(cmyk) { - /* CMYK */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; - pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; - pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; - pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; - } - } - else if(components == 2) { - /* grayscale + alpha */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = pixels[i*2+1]; - pixels[i*4+2] = pixels[i*2+0]; - pixels[i*4+1] = pixels[i*2+0]; - pixels[i*4+0] = pixels[i*2+0]; + /* Check if we actually have a float4 slot, in case components == 1, but device + * doesn't support single channel textures. */ + if(type == IMAGE_DATA_TYPE_FLOAT4) { + size_t num_pixels = ((size_t)width) * height * depth; + if(cmyk) { + /* CMYK */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; + pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; + pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; + } } - } - else if(components == 3) { - /* RGB */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 1.0f; - pixels[i*4+2] = pixels[i*3+2]; - pixels[i*4+1] = pixels[i*3+1]; - pixels[i*4+0] = pixels[i*3+0]; + else if(components == 2) { + /* grayscale + alpha */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = pixels[i*2+1]; + pixels[i*4+2] = pixels[i*2+0]; + pixels[i*4+1] = pixels[i*2+0]; + pixels[i*4+0] = pixels[i*2+0]; + } } - } - else if(components == 1) { - /* grayscale */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 1.0f; - pixels[i*4+2] = pixels[i]; - pixels[i*4+1] = pixels[i]; - pixels[i*4+0] = pixels[i]; + else if(components == 3) { + /* RGB */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 1.0f; + pixels[i*4+2] = pixels[i*3+2]; + pixels[i*4+1] = pixels[i*3+1]; + pixels[i*4+0] = pixels[i*3+0]; + } } - } - - if(img->use_alpha == false) { - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 1.0f; + else if(components == 1) { + /* grayscale */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 1.0f; + pixels[i*4+2] = pixels[i]; + pixels[i*4+1] = pixels[i]; + pixels[i*4+0] = pixels[i]; + } } - } - - return true; -} - -bool ImageManager::file_load_float_image(Image *img, device_vector<float>& tex_img) -{ - ImageInput *in = NULL; - int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read BW pixels */ - float *pixels = (float*)tex_img.resize(width, height, depth); - if(pixels == NULL) { - return false; - } - if(in) { - float *readpixels = pixels; - - if(depth <= 1) { - int scanlinesize = width*components*sizeof(float); - - in->read_image(TypeDesc::FLOAT, - (uchar*)readpixels + (height-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); - } - else { - in->read_image(TypeDesc::FLOAT, (uchar*)readpixels); + if(img->use_alpha == false) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 1.0f; + } } - - in->close(); - delete in; - } - else { - builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); } return true; @@ -760,7 +677,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_float4_image(img, tex_img)) { + if(!file_load_float_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); @@ -786,7 +703,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_float_image(img, tex_img)) { + if(!file_load_float_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); @@ -809,7 +726,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_byte4_image(img, tex_img)) { + if(!file_load_byte_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); @@ -835,7 +752,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_byte_image(img, tex_img)) { + if(!file_load_byte_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 53f739cd356..8735133fd91 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -96,9 +96,8 @@ public: private: int tex_num_images[IMAGE_DATA_NUM_TYPES]; - int tex_image_byte4_start; - int tex_image_float_start; - int tex_image_byte_start; + int tex_start_images[IMAGE_DATA_NUM_TYPES]; + thread_mutex device_mutex; int animation_frame; @@ -107,10 +106,12 @@ private: bool pack_images; bool file_load_image_generic(Image *img, ImageInput **in, int &width, int &height, int &depth, int &components); - bool file_load_byte4_image(Image *img, device_vector<uchar4>& tex_img); - bool file_load_byte_image(Image *img, device_vector<uchar>& tex_img); - bool file_load_float4_image(Image *img, device_vector<float4>& tex_img); - bool file_load_float_image(Image *img, device_vector<float>& tex_img); + + template<typename T> + bool file_load_byte_image(Image *img, ImageDataType type, device_vector<T>& tex_img); + + template<typename T> + bool file_load_float_image(Image *img, ImageDataType type, device_vector<T>& tex_img); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 41e2571dc24..2a10eb474a4 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -204,6 +204,11 @@ void Integrator::device_free(Device *device, DeviceScene *dscene) dscene->sobol_directions.clear(); } +bool Integrator::modified(const Integrator& integrator) +{ + return !Node::equals(integrator); +} + void Integrator::tag_update(Scene *scene) { foreach(Shader *shader, scene->shaders) { diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index a5cfb0c7863..39eaaf246d4 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -86,6 +86,7 @@ public: 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 c20bf6b5e9e..9ef35820254 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -247,7 +247,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen /* count triangles */ if(have_emission) { - for(size_t i = 0; i < mesh->triangles.size(); i++) { + 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] : scene->default_surface; @@ -319,7 +320,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen use_light_visibility = true; } - for(size_t i = 0; i < mesh->triangles.size(); i++) { + 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] : scene->default_surface; @@ -331,7 +333,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen distribution[offset].w = __int_as_float(object_id); offset++; - Mesh::Triangle t = mesh->triangles[i]; + Mesh::Triangle t = mesh->get_triangle(i); float3 p1 = mesh->verts[t.v[0]]; float3 p2 = mesh->verts[t.v[1]]; float3 p3 = mesh->verts[t.v[2]]; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index de1533c26af..e25155630bd 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -51,14 +51,14 @@ void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox& bounds) const /* Curve */ -void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const +void Mesh::Curve::bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const { float3 P[4]; - P[0] = float4_to_float3(curve_keys[max(first_key + k - 1,first_key)]); - P[1] = float4_to_float3(curve_keys[first_key + k]); - P[2] = float4_to_float3(curve_keys[first_key + k + 1]); - P[3] = float4_to_float3(curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]); + P[0] = curve_keys[max(first_key + k - 1,first_key)]; + P[1] = curve_keys[first_key + k]; + P[2] = curve_keys[first_key + k + 1]; + P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]; float3 lower; float3 upper; @@ -67,7 +67,7 @@ void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& b curvebounds(&lower.y, &upper.y, P, 1); curvebounds(&lower.z, &upper.z, P, 2); - float mr = max(curve_keys[first_key + k].w, curve_keys[first_key + k + 1].w); + float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]); bounds.grow(lower, mr); bounds.grow(upper, mr); @@ -75,19 +75,42 @@ void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& b /* Mesh */ +NODE_DEFINE(Mesh) +{ + NodeType* type = NodeType::add("mesh", create); + + static NodeEnum displacement_method_enum; + displacement_method_enum.insert("bump", DISPLACE_BUMP); + displacement_method_enum.insert("true", DISPLACE_TRUE); + displacement_method_enum.insert("both", DISPLACE_BOTH); + SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP); + + SOCKET_INT(motion_steps, "Motion Steps", 3); + SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false); + + SOCKET_INT_ARRAY(triangles, "Triangles", array<int>()); + SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>()); + SOCKET_INT_ARRAY(shader, "Shader", array<int>()); + SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>()); + + SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array<float3>()); + SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array<float>()); + SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array<int>()); + SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array<int>()); + + return type; +} + Mesh::Mesh() +: Node(node_type) { need_update = true; need_update_rebuild = false; transform_applied = false; transform_negative_scaled = false; transform_normal = transform_identity(); - displacement_method = DISPLACE_BUMP; bounds = BoundBox::empty; - motion_steps = 3; - use_motion_blur = false; - bvh = NULL; tri_offset = 0; @@ -99,6 +122,8 @@ Mesh::Mesh() attributes.triangle_mesh = this; curve_attributes.curve_mesh = this; + geometry_flags = GEOMETRY_NONE; + has_volume = false; has_surface_bssrdf = false; } @@ -108,21 +133,49 @@ Mesh::~Mesh() delete bvh; } -void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys) +void Mesh::resize_mesh(int numverts, int numtris) { - /* reserve space to add verts and triangles later */ verts.resize(numverts); - triangles.resize(numtris); + triangles.resize(numtris * 3); shader.resize(numtris); smooth.resize(numtris); forms_quad.resize(numtris); - curve_keys.resize(numcurvekeys); - curves.resize(numcurves); + attributes.resize(); +} + +void Mesh::reserve_mesh(int numverts, int numtris) +{ + /* reserve space to add verts and triangles later */ + verts.reserve(numverts); + triangles.reserve(numtris * 3); + shader.reserve(numtris); + smooth.reserve(numtris); + + forms_quad.reserve(numtris); - attributes.reserve(); - curve_attributes.reserve(); + attributes.resize(true); +} + +void Mesh::resize_curves(int numcurves, int numkeys) +{ + curve_keys.resize(numkeys); + curve_radius.resize(numkeys); + curve_first_key.resize(numcurves); + curve_shader.resize(numcurves); + + curve_attributes.resize(); +} + +void Mesh::reserve_curves(int numcurves, int numkeys) +{ + curve_keys.reserve(numkeys); + curve_radius.reserve(numkeys); + curve_first_key.reserve(numcurves); + curve_shader.reserve(numcurves); + + curve_attributes.resize(true); } void Mesh::clear() @@ -136,7 +189,9 @@ void Mesh::clear() forms_quad.clear(); curve_keys.clear(); - curves.clear(); + curve_radius.clear(); + curve_first_key.clear(); + curve_shader.clear(); attributes.clear(); curve_attributes.clear(); @@ -151,7 +206,7 @@ void Mesh::clear() int Mesh::split_vertex(int vertex) { /* copy vertex location and vertex attributes */ - verts.push_back(verts[vertex]); + add_vertex_slow(verts[vertex]); foreach(Attribute& attr, attributes.attributes) { if(attr.element == ATTR_ELEMENT_VERTEX) { @@ -164,48 +219,36 @@ int Mesh::split_vertex(int vertex) return verts.size() - 1; } -void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_, bool forms_quad_) +void Mesh::add_vertex(float3 P) { - Triangle tri; - tri.v[0] = v0; - tri.v[1] = v1; - tri.v[2] = v2; - - triangles[i] = tri; - shader[i] = shader_; - smooth[i] = smooth_; - forms_quad[i] = forms_quad_; + verts.push_back_reserved(P); +} + +void Mesh::add_vertex_slow(float3 P) +{ + verts.push_back_slow(P); } void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_, bool forms_quad_) { - Triangle tri; - tri.v[0] = v0; - tri.v[1] = v1; - tri.v[2] = v2; - - triangles.push_back(tri); - shader.push_back(shader_); - smooth.push_back(smooth_); - forms_quad.push_back(forms_quad_); + triangles.push_back_reserved(v0); + triangles.push_back_reserved(v1); + triangles.push_back_reserved(v2); + shader.push_back_reserved(shader_); + smooth.push_back_reserved(smooth_); + forms_quad.push_back_reserved(forms_quad_); } void Mesh::add_curve_key(float3 co, float radius) { - float4 key = float3_to_float4(co); - key.w = radius; - - curve_keys.push_back(key); + curve_keys.push_back_reserved(co); + curve_radius.push_back_reserved(radius); } -void Mesh::add_curve(int first_key, int num_keys, int shader) +void Mesh::add_curve(int first_key, int shader) { - Curve curve; - curve.first_key = first_key; - curve.num_keys = num_keys; - curve.shader = shader; - - curves.push_back(curve); + curve_first_key.push_back_reserved(first_key); + curve_shader.push_back_reserved(shader); } void Mesh::compute_bounds() @@ -219,7 +262,7 @@ void Mesh::compute_bounds() bnds.grow(verts[i]); for(size_t i = 0; i < curve_keys_size; i++) - bnds.grow(float4_to_float3(curve_keys[i]), curve_keys[i].w); + bnds.grow(curve_keys[i], curve_radius[i]); Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if(use_motion_blur && attr) { @@ -247,7 +290,7 @@ void Mesh::compute_bounds() bnds.grow_safe(verts[i]); for(size_t i = 0; i < curve_keys_size; i++) - bnds.grow_safe(float4_to_float3(curve_keys[i]), curve_keys[i].w); + bnds.grow_safe(curve_keys[i], curve_radius[i]); if(use_motion_blur && attr) { size_t steps_size = verts.size() * (motion_steps - 1); @@ -285,7 +328,7 @@ static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts) float normlen = len(norm); if(normlen == 0.0f) - return make_float3(0.0f, 0.0f, 0.0f); + return make_float3(1.0f, 0.0f, 0.0f); return norm / normlen; } @@ -301,15 +344,14 @@ void Mesh::add_face_normals() float3 *fN = attr_fN->data_float3(); /* compute face normals */ - size_t triangles_size = triangles.size(); + size_t triangles_size = num_triangles(); bool flip = transform_negative_scaled; if(triangles_size) { float3 *verts_ptr = &verts[0]; - Triangle *triangles_ptr = &triangles[0]; for(size_t i = 0; i < triangles_size; i++) { - fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr); + fN[i] = compute_face_normal(get_triangle(i), verts_ptr); if(flip) fN[i] = -fN[i]; @@ -329,7 +371,7 @@ void Mesh::add_vertex_normals() { bool flip = transform_negative_scaled; size_t verts_size = verts.size(); - size_t triangles_size = triangles.size(); + size_t triangles_size = num_triangles(); /* static vertex normals */ if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) { @@ -344,11 +386,10 @@ void Mesh::add_vertex_normals() memset(vN, 0, verts.size()*sizeof(float3)); if(triangles_size) { - Triangle *triangles_ptr = &triangles[0]; for(size_t i = 0; i < triangles_size; i++) for(size_t j = 0; j < 3; j++) - vN[triangles_ptr[i].v[j]] += fN[i]; + vN[get_triangle(i).v[j]] += fN[i]; } for(size_t i = 0; i < verts_size; i++) { @@ -374,12 +415,10 @@ void Mesh::add_vertex_normals() memset(mN, 0, verts.size()*sizeof(float3)); if(triangles_size) { - Triangle *triangles_ptr = &triangles[0]; - for(size_t i = 0; i < triangles_size; i++) { for(size_t j = 0; j < 3; j++) { - float3 fN = compute_face_normal(triangles_ptr[i], mP); - mN[triangles_ptr[i].v[j]] += fN; + float3 fN = compute_face_normal(get_triangle(i), mP); + mN[get_triangle(i).v[j]] += fN; } } } @@ -402,8 +441,8 @@ void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal) uint last_shader = -1; bool last_smooth = false; - size_t triangles_size = triangles.size(); - uint *shader_ptr = (shader.size())? &shader[0]: NULL; + size_t triangles_size = num_triangles(); + int *shader_ptr = (shader.size())? &shader[0]: NULL; bool do_transform = transform_applied; Transform ntfm = transform_normal; @@ -446,13 +485,11 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset) } } - size_t triangles_size = triangles.size(); + size_t triangles_size = num_triangles(); if(triangles_size) { - Triangle *triangles_ptr = &triangles[0]; - for(size_t i = 0; i < triangles_size; i++) { - Triangle t = triangles_ptr[i]; + Triangle t = get_triangle(i); tri_vindex[i] = make_float4( __int_as_float(t.v[0] + vert_offset), @@ -466,27 +503,25 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset) void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset) { size_t curve_keys_size = curve_keys.size(); - float4 *keys_ptr = NULL; /* pack curve keys */ if(curve_keys_size) { - keys_ptr = &curve_keys[0]; + float3 *keys_ptr = &curve_keys[0]; + float *radius_ptr = &curve_radius[0]; for(size_t i = 0; i < curve_keys_size; i++) - curve_key_co[i] = keys_ptr[i]; + curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]); } /* pack curve segments */ - size_t curve_num = curves.size(); + size_t curve_num = num_curves(); if(curve_num) { - Curve *curve_ptr = &curves[0]; - int shader_id = 0; - for(size_t i = 0; i < curve_num; i++) { - Curve curve = curve_ptr[i]; - Shader *shader = (curve.shader < used_shaders.size()) ? - used_shaders[curve.shader] : scene->default_surface; + 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_id = scene->shader_manager->get_shader_id(shader, this, false); curve_data[i] = make_float4( @@ -732,7 +767,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce else id = scene->shader_manager->get_attribute_id(req.std); - if(mesh->triangles.size()) { + if(mesh->num_triangles()) { attr_map[index].x = id; attr_map[index].y = req.triangle_element; attr_map[index].z = as_uint(req.triangle_offset); @@ -747,7 +782,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce index++; - if(mesh->curves.size()) { + if(mesh->num_curves()) { attr_map[index].x = id; attr_map[index].y = req.curve_element; attr_map[index].z = as_uint(req.curve_offset); @@ -793,9 +828,9 @@ static void update_attribute_element_size(Mesh *mesh, if(mattr) { size_t size = mattr->element_size( mesh->verts.size(), - mesh->triangles.size(), + mesh->num_triangles(), mesh->motion_steps, - mesh->curves.size(), + mesh->num_curves(), mesh->curve_keys.size()); if(mattr->element == ATTR_ELEMENT_VOXEL) { @@ -836,9 +871,9 @@ static void update_attribute_element_offset(Mesh *mesh, /* store attribute data in arrays */ size_t size = mattr->element_size( mesh->verts.size(), - mesh->triangles.size(), + mesh->num_triangles(), mesh->motion_steps, - mesh->curves.size(), + mesh->num_curves(), mesh->curve_keys.size()); if(mattr->element == ATTR_ELEMENT_VOXEL) { @@ -1052,10 +1087,10 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene mesh->curve_offset = curve_size; vert_size += mesh->verts.size(); - tri_size += mesh->triangles.size(); + tri_size += mesh->num_triangles(); curve_key_size += mesh->curve_keys.size(); - curve_size += mesh->curves.size(); + curve_size += mesh->num_curves(); } if(tri_size != 0) { @@ -1450,7 +1485,7 @@ bool Mesh::need_attribute(Scene * /*scene*/, ustring name) void Mesh::tessellate(DiagSplit *split) { - int num_faces = triangles.size(); + int num_faces = num_triangles(); add_face_normals(); add_vertex_normals(); @@ -1465,16 +1500,17 @@ void Mesh::tessellate(DiagSplit *split) if(!forms_quad[f]) { /* triangle */ LinearTrianglePatch patch; + Triangle triangle = get_triangle(f); float3 *hull = patch.hull; float3 *normals = patch.normals; for(int i = 0; i < 3; i++) { - hull[i] = verts[triangles[f].v[i]]; + hull[i] = verts[triangle.v[i]]; } if(smooth[f]) { for(int i = 0; i < 3; i++) { - normals[i] = vN[triangles[f].v[i]]; + normals[i] = vN[triangle.v[i]]; } } else { @@ -1488,19 +1524,21 @@ void Mesh::tessellate(DiagSplit *split) else { /* quad */ LinearQuadPatch patch; + Triangle triangle0 = get_triangle(f); + Triangle triangle1 = get_triangle(f+1); float3 *hull = patch.hull; float3 *normals = patch.normals; - hull[0] = verts[triangles[f ].v[0]]; - hull[1] = verts[triangles[f ].v[1]]; - hull[3] = verts[triangles[f ].v[2]]; - hull[2] = verts[triangles[f+1].v[2]]; + hull[0] = verts[triangle0.v[0]]; + hull[1] = verts[triangle0.v[1]]; + hull[3] = verts[triangle0.v[2]]; + hull[2] = verts[triangle1.v[2]]; if(smooth[f]) { - normals[0] = vN[triangles[f ].v[0]]; - normals[1] = vN[triangles[f ].v[1]]; - normals[3] = vN[triangles[f ].v[2]]; - normals[2] = vN[triangles[f+1].v[2]]; + normals[0] = vN[triangle0.v[0]]; + normals[1] = vN[triangle0.v[1]]; + normals[3] = vN[triangle0.v[2]]; + normals[2] = vN[triangle1.v[2]]; } else { for(int i = 0; i < 4; i++) { diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index 557b664bff3..edad6d32f00 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -18,6 +18,7 @@ #define __MESH_H__ #include "attribute.h" +#include "node.h" #include "shader.h" #include "util_boundbox.h" @@ -42,8 +43,10 @@ class DiagSplit; /* Mesh */ -class Mesh { +class Mesh : public Node { public: + NODE_DECLARE; + /* Mesh Triangle */ struct Triangle { int v[3]; @@ -51,17 +54,41 @@ public: void bounds_grow(const float3 *verts, BoundBox& bounds) const; }; + Triangle get_triangle(size_t i) const + { + Triangle tri = {{triangles[i*3 + 0], triangles[i*3 + 1], triangles[i*3 + 2]}}; + return tri; + } + + size_t num_triangles() const + { + return triangles.size() / 3; + } + /* Mesh Curve */ struct Curve { int first_key; int num_keys; - uint shader; int num_segments() { return num_keys - 1; } - void bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const; + void bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const; }; + Curve get_curve(size_t i) const + { + int first = curve_first_key[i]; + int next_first = (i+1 < curve_first_key.size()) ? curve_first_key[i+1] : curve_keys.size(); + + Curve curve = {first, next_first - first}; + return curve; + } + + size_t num_curves() const + { + return curve_first_key.size(); + } + /* Displacement */ enum DisplacementMethod { DISPLACE_BUMP = 0, @@ -71,8 +98,6 @@ public: DISPLACE_NUM_METHODS, }; - ustring name; - /* Mesh Data */ enum GeometryFlags { GEOMETRY_NONE = 0, @@ -82,17 +107,19 @@ public: int geometry_flags; /* used to distinguish meshes with no verts and meshed for which geometry is not created */ - vector<float3> verts; - vector<Triangle> triangles; - vector<uint> shader; - vector<bool> smooth; - vector<bool> forms_quad; /* used to tell if triangle is part of a quad patch */ + array<int> triangles; + array<float3> verts; + array<int> shader; + array<bool> smooth; + array<bool> forms_quad; /* used to tell if triangle is part of a quad patch */ bool has_volume; /* Set in the device_update_flags(). */ bool has_surface_bssrdf; /* Set in the device_update_flags(). */ - vector<float4> curve_keys; /* co + radius */ - vector<Curve> curves; + array<float3> curve_keys; + array<float> curve_radius; + array<int> curve_first_key; + array<int> curve_shader; vector<Shader*> used_shaders; AttributeSet attributes; @@ -123,12 +150,16 @@ public: Mesh(); ~Mesh(); - void reserve(int numverts, int numfaces, int numcurves, int numcurvekeys); + void resize_mesh(int numverts, int numfaces); + void reserve_mesh(int numverts, int numfaces); + void resize_curves(int numcurves, int numkeys); + void reserve_curves(int numcurves, int numkeys); void clear(); - void set_triangle(int i, int v0, int v1, int v2, int shader, bool smooth, bool forms_quad = false); + void add_vertex(float3 P); + void add_vertex_slow(float3 P); void add_triangle(int v0, int v1, int v2, int shader, bool smooth, bool forms_quad = false); void add_curve_key(float3 loc, float radius); - void add_curve(int first_key, int num_keys, int shader); + void add_curve(int first_key, int shader); int split_vertex(int vertex); void compute_bounds(); diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index d19bf2084d7..95f46ff02a2 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -60,8 +60,9 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me uint4 *d_input_data = d_input.resize(num_verts); size_t d_input_size = 0; - for(size_t i = 0; i < mesh->triangles.size(); i++) { - Mesh::Triangle t = mesh->triangles[i]; + size_t num_triangles = mesh->num_triangles(); + for(size_t i = 0; i < num_triangles; i++) { + 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] : scene->default_surface; @@ -146,8 +147,8 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me float4 *offset = (float4*)d_output.data_pointer; Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - for(size_t i = 0; i < mesh->triangles.size(); i++) { - Mesh::Triangle t = mesh->triangles[i]; + for(size_t i = 0; i < num_triangles; i++) { + 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] : scene->default_surface; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 998d9cf31dd..df0fee63113 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -30,9 +30,9 @@ CCL_NAMESPACE_BEGIN /* Texture Mapping */ -static ShaderEnum texture_mapping_type_init() +static NodeEnum texture_mapping_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Point", TextureMapping::POINT); enm.insert("Texture", TextureMapping::TEXTURE); @@ -42,9 +42,9 @@ static ShaderEnum texture_mapping_type_init() return enm; } -static ShaderEnum texture_mapping_mapping_init() +static NodeEnum texture_mapping_mapping_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("None", TextureMapping::NONE); enm.insert("X", TextureMapping::X); @@ -54,9 +54,9 @@ static ShaderEnum texture_mapping_mapping_init() return enm; } -static ShaderEnum texture_mapping_projection_init() +static NodeEnum texture_mapping_projection_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Flat", TextureMapping::FLAT); enm.insert("Cube", TextureMapping::CUBE); @@ -66,9 +66,9 @@ static ShaderEnum texture_mapping_projection_init() return enm; } -ShaderEnum TextureMapping::type_enum = texture_mapping_type_init(); -ShaderEnum TextureMapping::mapping_enum = texture_mapping_mapping_init(); -ShaderEnum TextureMapping::projection_enum = texture_mapping_projection_init(); +NodeEnum TextureMapping::type_enum = texture_mapping_type_init(); +NodeEnum TextureMapping::mapping_enum = texture_mapping_mapping_init(); +NodeEnum TextureMapping::projection_enum = texture_mapping_projection_init(); TextureMapping::TextureMapping() { @@ -193,7 +193,7 @@ int TextureMapping::compile_begin(SVMCompiler& compiler, ShaderInput *vector_in) { if(!skip()) { int offset_in = compiler.stack_assign(vector_in); - int offset_out = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + int offset_out = compiler.stack_find_offset(SocketType::VECTOR); compile(compiler, offset_in, offset_out); @@ -206,7 +206,7 @@ int TextureMapping::compile_begin(SVMCompiler& compiler, ShaderInput *vector_in) void TextureMapping::compile_end(SVMCompiler& compiler, ShaderInput *vector_in, int vector_offset) { if(!skip()) { - compiler.stack_clear_offset(vector_in->type, vector_offset); + compiler.stack_clear_offset(vector_in->type(), vector_offset); } } @@ -222,9 +222,9 @@ void TextureMapping::compile(OSLCompiler &compiler) /* Image Texture */ -static ShaderEnum color_space_init() +static NodeEnum color_space_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("None", 0); enm.insert("Color", 1); @@ -232,9 +232,9 @@ static ShaderEnum color_space_init() return enm; } -static ShaderEnum image_projection_init() +static NodeEnum image_projection_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Flat", NODE_IMAGE_PROJ_FLAT); enm.insert("Box", NODE_IMAGE_PROJ_BOX); @@ -259,8 +259,8 @@ static const char* get_osl_interpolation_parameter(InterpolationType interpolati } } -ShaderEnum ImageTextureNode::color_space_enum = color_space_init(); -ShaderEnum ImageTextureNode::projection_enum = image_projection_init(); +NodeEnum ImageTextureNode::color_space_enum = color_space_init(); +NodeEnum ImageTextureNode::projection_enum = image_projection_init(); ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode("image_texture") @@ -272,16 +272,16 @@ ImageTextureNode::ImageTextureNode() use_alpha = true; filename = ""; builtin_data = NULL; - color_space = ustring("Color"); - projection = ustring("Flat"); + color_space = NODE_COLOR_SPACE_COLOR; + projection = NODE_IMAGE_PROJ_FLAT; interpolation = INTERPOLATION_LINEAR; extension = EXTENSION_REPEAT; projection_blend = 0.0f; animated = false; - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_UV); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Alpha", SHADER_SOCKET_FLOAT); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV); + add_output("Color", SocketType::COLOR); + add_output("Alpha", SocketType::FLOAT); } ImageTextureNode::~ImageTextureNode() @@ -341,10 +341,10 @@ void ImageTextureNode::compile(SVMCompiler& compiler) } if(slot != -1) { - int srgb = (is_linear || color_space != "Color")? 0: 1; + int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1; int vector_offset = tex_mapping.compile_begin(compiler, vector_in); - if(projection != "Box") { + if(projection != NODE_IMAGE_PROJ_BOX) { compiler.add_node(NODE_TEX_IMAGE, slot, compiler.encode_uchar4( @@ -352,7 +352,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), srgb), - projection_enum[projection]); + projection); } else { compiler.add_node(NODE_TEX_IMAGE_BOX, @@ -421,7 +421,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler) */ compiler.parameter("filename", string_printf("@%d", slot).c_str()); } - if(is_linear || color_space != "Color") + if(is_linear || color_space != NODE_COLOR_SPACE_COLOR) compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); @@ -433,14 +433,14 @@ void ImageTextureNode::compile(OSLCompiler& compiler) switch(extension) { case EXTENSION_EXTEND: - compiler.parameter("wrap", "clamp"); + compiler.parameter("extension", "clamp"); break; case EXTENSION_CLIP: - compiler.parameter("wrap", "black"); + compiler.parameter("extension", "black"); break; case EXTENSION_REPEAT: default: - compiler.parameter("wrap", "periodic"); + compiler.parameter("extension", "periodic"); break; } @@ -449,9 +449,9 @@ void ImageTextureNode::compile(OSLCompiler& compiler) /* Environment Texture */ -static ShaderEnum env_projection_init() +static NodeEnum env_projection_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Equirectangular", 0); enm.insert("Mirror Ball", 1); @@ -459,8 +459,8 @@ static ShaderEnum env_projection_init() return enm; } -ShaderEnum EnvironmentTextureNode::color_space_enum = color_space_init(); -ShaderEnum EnvironmentTextureNode::projection_enum = env_projection_init(); +NodeEnum EnvironmentTextureNode::color_space_enum = color_space_init(); +NodeEnum EnvironmentTextureNode::projection_enum = env_projection_init(); EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode("environment_texture") @@ -472,14 +472,14 @@ EnvironmentTextureNode::EnvironmentTextureNode() use_alpha = true; filename = ""; builtin_data = NULL; - color_space = ustring("Color"); + color_space = NODE_COLOR_SPACE_COLOR; interpolation = INTERPOLATION_LINEAR; - projection = ustring("Equirectangular"); + projection = NODE_ENVIRONMENT_EQUIRECTANGULAR; animated = false; - add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Alpha", SHADER_SOCKET_FLOAT); + add_input("Vector", SocketType::VECTOR, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION); + add_output("Color", SocketType::COLOR); + add_output("Alpha", SocketType::FLOAT); } EnvironmentTextureNode::~EnvironmentTextureNode() @@ -537,7 +537,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) } if(slot != -1) { - int srgb = (is_linear || color_space != "Color")? 0: 1; + int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1; int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_ENVIRONMENT, @@ -547,7 +547,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), srgb), - projection_enum[projection]); + projection); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -602,8 +602,8 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) else { compiler.parameter("filename", string_printf("@%d", slot).c_str()); } - compiler.parameter("projection", projection); - if(is_linear || color_space != "Color") + compiler.parameter("projection", projection_enum[projection]); + if(is_linear || color_space != NODE_COLOR_SPACE_COLOR) compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); @@ -738,9 +738,9 @@ static void sky_texture_precompute_new(SunSky *sunsky, float3 dir, float turbidi arhosekskymodelstate_free(sky_state); } -static ShaderEnum sky_type_init() +static NodeEnum sky_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Preetham", NODE_SKY_OLD); enm.insert("Hosek / Wilkie", NODE_SKY_NEW); @@ -748,19 +748,19 @@ static ShaderEnum sky_type_init() return enm; } -ShaderEnum SkyTextureNode::type_enum = sky_type_init(); +NodeEnum SkyTextureNode::type_enum = sky_type_init(); SkyTextureNode::SkyTextureNode() : TextureNode("sky_texture") { - type = ustring("Hosek / Wilkie"); + type = NODE_SKY_NEW; sun_direction = make_float3(0.0f, 0.0f, 1.0f); turbidity = 2.2f; ground_albedo = 0.3f; - add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Vector", SocketType::VECTOR, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION); + add_output("Color", SocketType::COLOR); } void SkyTextureNode::compile(SVMCompiler& compiler) @@ -769,15 +769,15 @@ void SkyTextureNode::compile(SVMCompiler& compiler) ShaderOutput *color_out = output("Color"); SunSky sunsky; - if(type_enum[type] == NODE_SKY_OLD) + if(type == NODE_SKY_OLD) sky_texture_precompute_old(&sunsky, sun_direction, turbidity); - else if(type_enum[type] == NODE_SKY_NEW) + else if(type == NODE_SKY_NEW) sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo); else assert(false); int vector_offset = tex_mapping.compile_begin(compiler, vector_in); - int sky_model = type_enum[type]; + int sky_model = type; compiler.stack_assign(color_out); compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_model); @@ -799,14 +799,14 @@ void SkyTextureNode::compile(OSLCompiler& compiler) SunSky sunsky; - if(type_enum[type] == NODE_SKY_OLD) + if(type == NODE_SKY_OLD) sky_texture_precompute_old(&sunsky, sun_direction, turbidity); - else if(type_enum[type] == NODE_SKY_NEW) + else if(type == NODE_SKY_NEW) sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo); else assert(false); - compiler.parameter("sky_model", type); + compiler.parameter("sky_model", type_enum[type]); compiler.parameter("theta", sunsky.theta); compiler.parameter("phi", sunsky.phi); compiler.parameter_color("radiance", make_float3(sunsky.radiance_x, sunsky.radiance_y, sunsky.radiance_z)); @@ -818,9 +818,9 @@ void SkyTextureNode::compile(OSLCompiler& compiler) /* Gradient Texture */ -static ShaderEnum gradient_type_init() +static NodeEnum gradient_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Linear", NODE_BLEND_LINEAR); enm.insert("Quadratic", NODE_BLEND_QUADRATIC); @@ -833,16 +833,16 @@ static ShaderEnum gradient_type_init() return enm; } -ShaderEnum GradientTextureNode::type_enum = gradient_type_init(); +NodeEnum GradientTextureNode::type_enum = gradient_type_init(); GradientTextureNode::GradientTextureNode() : TextureNode("gradient_texture") { - type = ustring("Linear"); + type = NODE_BLEND_LINEAR; - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void GradientTextureNode::compile(SVMCompiler& compiler) @@ -855,7 +855,7 @@ void GradientTextureNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_TEX_GRADIENT, compiler.encode_uchar4( - type_enum[type], + type, vector_offset, compiler.stack_assign_if_linked(fac_out), compiler.stack_assign_if_linked(color_out))); @@ -867,7 +867,7 @@ void GradientTextureNode::compile(OSLCompiler& compiler) { tex_mapping.compile(compiler); - compiler.parameter("Type", type); + compiler.parameter("type", type_enum[type]); compiler.add(this, "node_gradient_texture"); } @@ -876,13 +876,13 @@ void GradientTextureNode::compile(OSLCompiler& compiler) NoiseTextureNode::NoiseTextureNode() : TextureNode("noise_texture") { - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); - add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f); - add_input("Distortion", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + add_input("Scale", SocketType::FLOAT, 1.0f); + add_input("Detail", SocketType::FLOAT, 2.0f); + add_input("Distortion", SocketType::FLOAT, 0.0f); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void NoiseTextureNode::compile(SVMCompiler& compiler) @@ -906,9 +906,9 @@ void NoiseTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(fac_out))); compiler.add_node( - __float_as_int(scale_in->value.x), - __float_as_int(detail_in->value.x), - __float_as_int(distortion_in->value.x)); + __float_as_int(scale_in->value_float()), + __float_as_int(detail_in->value_float()), + __float_as_int(distortion_in->value_float())); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -922,9 +922,9 @@ void NoiseTextureNode::compile(OSLCompiler& compiler) /* Voronoi Texture */ -static ShaderEnum voronoi_coloring_init() +static NodeEnum voronoi_coloring_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Intensity", NODE_VORONOI_INTENSITY); enm.insert("Cells", NODE_VORONOI_CELLS); @@ -932,18 +932,18 @@ static ShaderEnum voronoi_coloring_init() return enm; } -ShaderEnum VoronoiTextureNode::coloring_enum = voronoi_coloring_init(); +NodeEnum VoronoiTextureNode::coloring_enum = voronoi_coloring_init(); VoronoiTextureNode::VoronoiTextureNode() : TextureNode("voronoi_texture") { - coloring = ustring("Intensity"); + coloring = NODE_VORONOI_INTENSITY; - add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); + add_input("Scale", SocketType::FLOAT, 1.0f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void VoronoiTextureNode::compile(SVMCompiler& compiler) @@ -956,13 +956,13 @@ void VoronoiTextureNode::compile(SVMCompiler& compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_VORONOI, - coloring_enum[coloring], + coloring, compiler.encode_uchar4( compiler.stack_assign_if_linked(scale_in), vector_offset, compiler.stack_assign(fac_out), compiler.stack_assign(color_out)), - __float_as_int(scale_in->value.x)); + __float_as_int(scale_in->value_float())); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -971,15 +971,15 @@ void VoronoiTextureNode::compile(OSLCompiler& compiler) { tex_mapping.compile(compiler); - compiler.parameter("Coloring", coloring); + compiler.parameter("coloring", coloring_enum[coloring]); compiler.add(this, "node_voronoi_texture"); } /* Musgrave Texture */ -static ShaderEnum musgrave_type_init() +static NodeEnum musgrave_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Multifractal", NODE_MUSGRAVE_MULTIFRACTAL); enm.insert("fBM", NODE_MUSGRAVE_FBM); @@ -990,23 +990,23 @@ static ShaderEnum musgrave_type_init() return enm; } -ShaderEnum MusgraveTextureNode::type_enum = musgrave_type_init(); +NodeEnum MusgraveTextureNode::type_enum = musgrave_type_init(); MusgraveTextureNode::MusgraveTextureNode() : TextureNode("musgrave_texture") { - type = ustring("fBM"); + type = NODE_MUSGRAVE_FBM; - add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f); - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); - add_input("Dimension", SHADER_SOCKET_FLOAT, 2.0f); - add_input("Lacunarity", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Offset", SHADER_SOCKET_FLOAT, 0.0f); - add_input("Gain", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Scale", SocketType::FLOAT, 1.0f); + add_input("Detail", SocketType::FLOAT, 2.0f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + add_input("Dimension", SocketType::FLOAT, 2.0f); + add_input("Lacunarity", SocketType::FLOAT, 1.0f); + add_input("Offset", SocketType::FLOAT, 0.0f); + add_input("Gain", SocketType::FLOAT, 1.0f); - add_output("Fac", SHADER_SOCKET_FLOAT); - add_output("Color", SHADER_SOCKET_COLOR); + add_output("Fac", SocketType::FLOAT); + add_output("Color", SocketType::COLOR); } void MusgraveTextureNode::compile(SVMCompiler& compiler) @@ -1025,7 +1025,7 @@ void MusgraveTextureNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_TEX_MUSGRAVE, compiler.encode_uchar4( - type_enum[type], + type, vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(fac_out)), @@ -1037,12 +1037,12 @@ void MusgraveTextureNode::compile(SVMCompiler& compiler) compiler.encode_uchar4( compiler.stack_assign_if_linked(gain_in), compiler.stack_assign_if_linked(scale_in))); - compiler.add_node(__float_as_int(dimension_in->value.x), - __float_as_int(lacunarity_in->value.x), - __float_as_int(detail_in->value.x), - __float_as_int(offset_in->value.x)); - compiler.add_node(__float_as_int(gain_in->value.x), - __float_as_int(scale_in->value.x)); + compiler.add_node(__float_as_int(dimension_in->value_float()), + __float_as_int(lacunarity_in->value_float()), + __float_as_int(detail_in->value_float()), + __float_as_int(offset_in->value_float())); + compiler.add_node(__float_as_int(gain_in->value_float()), + __float_as_int(scale_in->value_float())); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -1051,16 +1051,16 @@ void MusgraveTextureNode::compile(OSLCompiler& compiler) { tex_mapping.compile(compiler); - compiler.parameter("Type", type); + compiler.parameter("type", type_enum[type]); compiler.add(this, "node_musgrave_texture"); } /* Wave Texture */ -static ShaderEnum wave_type_init() +static NodeEnum wave_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Bands", NODE_WAVE_BANDS); enm.insert("Rings", NODE_WAVE_RINGS); @@ -1068,9 +1068,9 @@ static ShaderEnum wave_type_init() return enm; } -static ShaderEnum wave_profile_init() +static NodeEnum wave_profile_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Sine", NODE_WAVE_PROFILE_SIN); enm.insert("Saw", NODE_WAVE_PROFILE_SAW); @@ -1078,23 +1078,23 @@ static ShaderEnum wave_profile_init() return enm; } -ShaderEnum WaveTextureNode::type_enum = wave_type_init(); -ShaderEnum WaveTextureNode::profile_enum = wave_profile_init(); +NodeEnum WaveTextureNode::type_enum = wave_type_init(); +NodeEnum WaveTextureNode::profile_enum = wave_profile_init(); WaveTextureNode::WaveTextureNode() : TextureNode("wave_texture") { - type = ustring("Bands"); - profile = ustring("Sine"); + type = NODE_WAVE_BANDS; + profile = NODE_WAVE_PROFILE_SIN; - add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Distortion", SHADER_SOCKET_FLOAT, 0.0f); - add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f); - add_input("Detail Scale", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); + add_input("Scale", SocketType::FLOAT, 1.0f); + add_input("Distortion", SocketType::FLOAT, 0.0f); + add_input("Detail", SocketType::FLOAT, 2.0f); + add_input("Detail Scale", SocketType::FLOAT, 1.0f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void WaveTextureNode::compile(SVMCompiler& compiler) @@ -1111,7 +1111,7 @@ void WaveTextureNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_TEX_WAVE, compiler.encode_uchar4( - type_enum[type], + type, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(fac_out), compiler.stack_assign_if_linked(dscale_in)), @@ -1120,13 +1120,13 @@ void WaveTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(scale_in), compiler.stack_assign_if_linked(detail_in), compiler.stack_assign_if_linked(distortion_in)), - profile_enum[profile]); + profile); compiler.add_node( - __float_as_int(scale_in->value.x), - __float_as_int(detail_in->value.x), - __float_as_int(distortion_in->value.x), - __float_as_int(dscale_in->value.x)); + __float_as_int(scale_in->value_float()), + __float_as_int(detail_in->value_float()), + __float_as_int(distortion_in->value_float()), + __float_as_int(dscale_in->value_float())); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -1135,8 +1135,8 @@ void WaveTextureNode::compile(OSLCompiler& compiler) { tex_mapping.compile(compiler); - compiler.parameter("Type", type); - compiler.parameter("Profile", profile); + compiler.parameter("type", type_enum[type]); + compiler.parameter("profile", profile_enum[profile]); compiler.add(this, "node_wave_texture"); } @@ -1148,12 +1148,12 @@ MagicTextureNode::MagicTextureNode() { depth = 2; - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); - add_input("Scale", SHADER_SOCKET_FLOAT, 5.0f); - add_input("Distortion", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + add_input("Scale", SocketType::FLOAT, 5.0f); + add_input("Distortion", SocketType::FLOAT, 1.0f); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void MagicTextureNode::compile(SVMCompiler& compiler) @@ -1176,8 +1176,8 @@ void MagicTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(scale_in), compiler.stack_assign_if_linked(distortion_in))); compiler.add_node( - __float_as_int(scale_in->value.x), - __float_as_int(distortion_in->value.x)); + __float_as_int(scale_in->value_float()), + __float_as_int(distortion_in->value_float())); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -1186,7 +1186,7 @@ void MagicTextureNode::compile(OSLCompiler& compiler) { tex_mapping.compile(compiler); - compiler.parameter("Depth", depth); + compiler.parameter("depth", depth); compiler.add(this, "node_magic_texture"); } @@ -1195,13 +1195,13 @@ void MagicTextureNode::compile(OSLCompiler& compiler) CheckerTextureNode::CheckerTextureNode() : TextureNode("checker_texture") { - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); - add_input("Color1", SHADER_SOCKET_COLOR); - add_input("Color2", SHADER_SOCKET_COLOR); - add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + add_input("Color1", SocketType::COLOR); + add_input("Color2", SocketType::COLOR); + add_input("Scale", SocketType::FLOAT, 1.0f); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void CheckerTextureNode::compile(SVMCompiler& compiler) @@ -1225,7 +1225,7 @@ void CheckerTextureNode::compile(SVMCompiler& compiler) compiler.encode_uchar4( compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(fac_out)), - __float_as_int(scale_in->value.x)); + __float_as_int(scale_in->value_float())); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -1247,18 +1247,18 @@ BrickTextureNode::BrickTextureNode() squash = 1.0f; squash_frequency = 2; - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); - add_input("Color1", SHADER_SOCKET_COLOR); - add_input("Color2", SHADER_SOCKET_COLOR); - add_input("Mortar", SHADER_SOCKET_COLOR); - add_input("Scale", SHADER_SOCKET_FLOAT, 5.0f); - add_input("Mortar Size", SHADER_SOCKET_FLOAT, 0.02f); - add_input("Bias", SHADER_SOCKET_FLOAT, 0.0f); - add_input("Brick Width", SHADER_SOCKET_FLOAT, 0.5f); - add_input("Row Height", SHADER_SOCKET_FLOAT, 0.25f); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + add_input("Color1", SocketType::COLOR); + add_input("Color2", SocketType::COLOR); + add_input("Mortar", SocketType::COLOR); + add_input("Scale", SocketType::FLOAT, 5.0f); + add_input("Mortar Size", SocketType::FLOAT, 0.02f); + add_input("Bias", SocketType::FLOAT, 0.0f); + add_input("Brick Width", SocketType::FLOAT, 0.5f); + add_input("Row Height", SocketType::FLOAT, 0.25f); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Fac", SocketType::FLOAT); } void BrickTextureNode::compile(SVMCompiler& compiler) @@ -1295,12 +1295,12 @@ void BrickTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(fac_out))); compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency), - __float_as_int(scale_in->value.x), - __float_as_int(mortar_size_in->value.x), - __float_as_int(bias_in->value.x)); + __float_as_int(scale_in->value_float()), + __float_as_int(mortar_size_in->value_float()), + __float_as_int(bias_in->value_float())); - compiler.add_node(__float_as_int(brick_width_in->value.x), - __float_as_int(row_height_in->value.x), + compiler.add_node(__float_as_int(brick_width_in->value_float()), + __float_as_int(row_height_in->value_float()), __float_as_int(offset), __float_as_int(squash)); @@ -1311,18 +1311,18 @@ void BrickTextureNode::compile(OSLCompiler& compiler) { tex_mapping.compile(compiler); - compiler.parameter("Offset", offset); - compiler.parameter("OffsetFrequency", offset_frequency); - compiler.parameter("Squash", squash); - compiler.parameter("SquashFrequency", squash_frequency); + compiler.parameter("offset", offset); + compiler.parameter("offset_frequency", offset_frequency); + compiler.parameter("squash", squash); + compiler.parameter("squash_frequency", squash_frequency); compiler.add(this, "node_brick_texture"); } /* Point Density Texture */ -static ShaderEnum point_density_space_init() +static NodeEnum point_density_space_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Object", NODE_TEX_VOXEL_SPACE_OBJECT); enm.insert("World", NODE_TEX_VOXEL_SPACE_WORLD); @@ -1330,7 +1330,7 @@ static ShaderEnum point_density_space_init() return enm; } -ShaderEnum PointDensityTextureNode::space_enum = point_density_space_init(); +NodeEnum PointDensityTextureNode::space_enum = point_density_space_init(); PointDensityTextureNode::PointDensityTextureNode() : ShaderNode("point_density") @@ -1338,15 +1338,15 @@ PointDensityTextureNode::PointDensityTextureNode() image_manager = NULL; slot = -1; filename = ""; - space = ustring("Object"); + space = NODE_TEX_VOXEL_SPACE_OBJECT; builtin_data = NULL; interpolation = INTERPOLATION_LINEAR; tfm = transform_identity(); - add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::POSITION); - add_output("Density", SHADER_SOCKET_FLOAT); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Vector", SocketType::POINT, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION); + add_output("Density", SocketType::FLOAT); + add_output("Color", SocketType::COLOR); } PointDensityTextureNode::~PointDensityTextureNode() @@ -1405,8 +1405,8 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler) compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign_if_linked(density_out), compiler.stack_assign_if_linked(color_out), - space_enum[space])); - if(space == "World") { + space)); + if(space == NODE_TEX_VOXEL_SPACE_WORLD) { compiler.add_node(tfm.x); compiler.add_node(tfm.y); compiler.add_node(tfm.z); @@ -1453,7 +1453,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler) if(slot != -1) { compiler.parameter("filename", string_printf("@%d", slot).c_str()); } - if(space == "World") { + if(space == NODE_TEX_VOXEL_SPACE_WORLD) { compiler.parameter("mapping", transform_transpose(tfm)); compiler.parameter("use_mapping", 1); } @@ -1481,9 +1481,9 @@ NormalNode::NormalNode() { direction = make_float3(0.0f, 0.0f, 1.0f); - add_input("Normal", SHADER_SOCKET_NORMAL); - add_output("Normal", SHADER_SOCKET_NORMAL); - add_output("Dot", SHADER_SOCKET_FLOAT); + add_input("Normal", SocketType::NORMAL); + add_output("Normal", SocketType::NORMAL); + add_output("Dot", SocketType::FLOAT); } void NormalNode::compile(SVMCompiler& compiler) @@ -1504,7 +1504,7 @@ void NormalNode::compile(SVMCompiler& compiler) void NormalNode::compile(OSLCompiler& compiler) { - compiler.parameter_normal("Direction", direction); + compiler.parameter_normal("direction", direction); compiler.add(this, "node_normal"); } @@ -1513,8 +1513,8 @@ void NormalNode::compile(OSLCompiler& compiler) MappingNode::MappingNode() : ShaderNode("mapping") { - add_input("Vector", SHADER_SOCKET_POINT); - add_output("Vector", SHADER_SOCKET_POINT); + add_input("Vector", SocketType::POINT); + add_output("Vector", SocketType::POINT); } void MappingNode::compile(SVMCompiler& compiler) @@ -1536,9 +1536,41 @@ void MappingNode::compile(OSLCompiler& compiler) compiler.add(this, "node_mapping"); } +/* RGBToBW */ + +RGBToBWNode::RGBToBWNode() +: ShaderNode("rgb_to_bw") +{ + add_input("Color", SocketType::COLOR); + add_output("Val", SocketType::FLOAT); +} + +bool RGBToBWNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *optimized) +{ + if(inputs[0]->link == NULL) { + optimized->set(linear_rgb_to_gray(inputs[0]->value())); + return true; + } + + return false; +} + +void RGBToBWNode::compile(SVMCompiler& compiler) +{ + compiler.add_node(NODE_CONVERT, + NODE_CONVERT_CF, + compiler.stack_assign(inputs[0]), + compiler.stack_assign(outputs[0])); +} + +void RGBToBWNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_convert_from_color"); +} + /* Convert */ -ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_, bool autoconvert) +ConvertNode::ConvertNode(SocketType::Type from_, SocketType::Type to_, bool autoconvert) : ShaderNode("convert") { from = from_; @@ -1551,92 +1583,72 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_, bool auto special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT; } - if(from == SHADER_SOCKET_FLOAT) - add_input("Val", SHADER_SOCKET_FLOAT); - else if(from == SHADER_SOCKET_INT) - add_input("ValInt", SHADER_SOCKET_INT); - else if(from == SHADER_SOCKET_COLOR) - add_input("Color", SHADER_SOCKET_COLOR); - else if(from == SHADER_SOCKET_VECTOR) - add_input("Vector", SHADER_SOCKET_VECTOR); - else if(from == SHADER_SOCKET_POINT) - add_input("Point", SHADER_SOCKET_POINT); - else if(from == SHADER_SOCKET_NORMAL) - add_input("Normal", SHADER_SOCKET_NORMAL); - else if(from == SHADER_SOCKET_STRING) - add_input("String", SHADER_SOCKET_STRING); - else if(from == SHADER_SOCKET_CLOSURE) - add_input("Closure", SHADER_SOCKET_CLOSURE); + if(from == SocketType::FLOAT) + add_input("value_float", SocketType::FLOAT); + else if(from == SocketType::INT) + add_input("value_int", SocketType::INT); + else if(from == SocketType::COLOR) + add_input("value_color", SocketType::COLOR); + else if(from == SocketType::VECTOR) + add_input("value_vector", SocketType::VECTOR); + else if(from == SocketType::POINT) + add_input("value_point", SocketType::POINT); + else if(from == SocketType::NORMAL) + add_input("value_normal", SocketType::NORMAL); + else if(from == SocketType::STRING) + add_input("value_string", SocketType::STRING); + else if(from == SocketType::CLOSURE) + add_input("value_closure", SocketType::CLOSURE); else assert(0); - if(to == SHADER_SOCKET_FLOAT) - add_output("Val", SHADER_SOCKET_FLOAT); - else if(to == SHADER_SOCKET_INT) - add_output("ValInt", SHADER_SOCKET_INT); - else if(to == SHADER_SOCKET_COLOR) - add_output("Color", SHADER_SOCKET_COLOR); - else if(to == SHADER_SOCKET_VECTOR) - add_output("Vector", SHADER_SOCKET_VECTOR); - else if(to == SHADER_SOCKET_POINT) - add_output("Point", SHADER_SOCKET_POINT); - else if(to == SHADER_SOCKET_NORMAL) - add_output("Normal", SHADER_SOCKET_NORMAL); - else if(to == SHADER_SOCKET_STRING) - add_output("String", SHADER_SOCKET_STRING); - else if(to == SHADER_SOCKET_CLOSURE) - add_output("Closure", SHADER_SOCKET_CLOSURE); + if(to == SocketType::FLOAT) + add_output("value_float", SocketType::FLOAT); + else if(to == SocketType::INT) + add_output("value_int", SocketType::INT); + else if(to == SocketType::COLOR) + add_output("value_color", SocketType::COLOR); + else if(to == SocketType::VECTOR) + add_output("value_vector", SocketType::VECTOR); + else if(to == SocketType::POINT) + add_output("value_point", SocketType::POINT); + else if(to == SocketType::NORMAL) + add_output("value_normal", SocketType::NORMAL); + else if(to == SocketType::STRING) + add_output("value_string", SocketType::STRING); + else if(to == SocketType::CLOSURE) + add_output("value_closure", SocketType::CLOSURE); else assert(0); } -bool ConvertNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - float3 *optimized_value) +bool ConvertNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *optimized) { ShaderInput *in = inputs[0]; - float3 value = in->value; + float3 value = in->value(); /* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */ if(in->link == NULL) { - if(from == SHADER_SOCKET_FLOAT) { - if(to == SHADER_SOCKET_INT) - /* float to int */ - return false; - else - /* float to float3 */ - *optimized_value = make_float3(value.x, value.x, value.x); - } - else if(from == SHADER_SOCKET_INT) { - if(to == SHADER_SOCKET_FLOAT) - /* int to float */ - return false; - else - /* int to vector/point/normal */ - return false; - } - else if(to == SHADER_SOCKET_FLOAT) { - if(from == SHADER_SOCKET_COLOR) - /* color to float */ - optimized_value->x = linear_rgb_to_gray(value); - else - /* vector/point/normal to float */ - optimized_value->x = average(value); - } - else if(to == SHADER_SOCKET_INT) { - if(from == SHADER_SOCKET_COLOR) - /* color to int */ - return false; - else - /* vector/point/normal to int */ - return false; + if(from == SocketType::FLOAT) { + if(SocketType::is_float3(to)) { + optimized->set(make_float3(value.x, value.x, value.x)); + return true; + } } - else { - *optimized_value = value; + else if(SocketType::is_float3(from)) { + if(to == SocketType::FLOAT) { + if(from == SocketType::COLOR) + optimized->set(linear_rgb_to_gray(value)); + else + optimized->set(average(value)); + return true; + } + else if(SocketType::is_float3(to)) { + optimized->set(value); + return true; + } } - - return true; } return false; @@ -1650,32 +1662,32 @@ void ConvertNode::compile(SVMCompiler& compiler) ShaderInput *in = inputs[0]; ShaderOutput *out = outputs[0]; - if(from == SHADER_SOCKET_FLOAT) { - if(to == SHADER_SOCKET_INT) + if(from == SocketType::FLOAT) { + if(to == SocketType::INT) /* float to int */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out)); else /* float to float3 */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out)); } - else if(from == SHADER_SOCKET_INT) { - if(to == SHADER_SOCKET_FLOAT) + else if(from == SocketType::INT) { + if(to == SocketType::FLOAT) /* int to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out)); else /* int to vector/point/normal */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out)); } - else if(to == SHADER_SOCKET_FLOAT) { - if(from == SHADER_SOCKET_COLOR) + else if(to == SocketType::FLOAT) { + if(from == SocketType::COLOR) /* color to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out)); else /* vector/point/normal to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out)); } - else if(to == SHADER_SOCKET_INT) { - if(from == SHADER_SOCKET_COLOR) + else if(to == SocketType::INT) { + if(from == SocketType::COLOR) /* color to int */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out)); else @@ -1691,7 +1703,7 @@ void ConvertNode::compile(SVMCompiler& compiler) else { /* set 0,0,0 value */ compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out)); - compiler.add_node(NODE_VALUE_V, in->value); + compiler.add_node(NODE_VALUE_V, in->value()); } } } @@ -1701,17 +1713,17 @@ void ConvertNode::compile(OSLCompiler& compiler) /* constant folding should eliminate proxy nodes */ assert(from != to); - if(from == SHADER_SOCKET_FLOAT) + if(from == SocketType::FLOAT) compiler.add(this, "node_convert_from_float"); - else if(from == SHADER_SOCKET_INT) + else if(from == SocketType::INT) compiler.add(this, "node_convert_from_int"); - else if(from == SHADER_SOCKET_COLOR) + else if(from == SocketType::COLOR) compiler.add(this, "node_convert_from_color"); - else if(from == SHADER_SOCKET_VECTOR) + else if(from == SocketType::VECTOR) compiler.add(this, "node_convert_from_vector"); - else if(from == SHADER_SOCKET_POINT) + else if(from == SocketType::POINT) compiler.add(this, "node_convert_from_point"); - else if(from == SHADER_SOCKET_NORMAL) + else if(from == SocketType::NORMAL) compiler.add(this, "node_convert_from_normal"); else assert(0); @@ -1724,17 +1736,17 @@ BsdfNode::BsdfNode(bool scattering_) { special_type = SHADER_SPECIAL_TYPE_CLOSURE; - add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); - add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("Color", SocketType::COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_input("Normal", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL); + add_input("SurfaceMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); if(scattering) { closure = CLOSURE_BSSRDF_CUBIC_ID; - add_output("BSSRDF", SHADER_SOCKET_CLOSURE); + add_output("BSSRDF", SocketType::CLOSURE); } else { closure = CLOSURE_BSDF_DIFFUSE_ID; - add_output("BSDF", SHADER_SOCKET_CLOSURE); + add_output("BSDF", SocketType::CLOSURE); } } @@ -1747,7 +1759,7 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * if(color_in->link) compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); else - compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value); + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value()); int normal_offset = compiler.stack_assign_if_linked(normal_in); int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) : SVM_STACK_INVALID; @@ -1759,8 +1771,8 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID, (param2)? compiler.stack_assign(param2): SVM_STACK_INVALID, compiler.closure_mix_weight_offset()), - __float_as_int((param1)? param1->value.x: 0.0f), - __float_as_int((param2)? param2->value.x: 0.0f)); + __float_as_int((param1)? param1->value_float(): 0.0f), + __float_as_int((param2)? param2->value_float(): 0.0f)); compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset); } @@ -1777,9 +1789,9 @@ void BsdfNode::compile(OSLCompiler& /*compiler*/) /* Anisotropic BSDF Closure */ -static ShaderEnum aniso_distribution_init() +static NodeEnum aniso_distribution_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID); enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID); @@ -1788,18 +1800,18 @@ static ShaderEnum aniso_distribution_init() return enm; } -ShaderEnum AnisotropicBsdfNode::distribution_enum = aniso_distribution_init(); +NodeEnum AnisotropicBsdfNode::distribution_enum = aniso_distribution_init(); AnisotropicBsdfNode::AnisotropicBsdfNode() { closure = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID; - distribution = ustring("GGX"); + distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID; - add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); + add_input("Tangent", SocketType::VECTOR, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT); - add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f); - add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.5f); - add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Roughness", SocketType::FLOAT, 0.2f); + add_input("Anisotropy", SocketType::FLOAT, 0.5f); + add_input("Rotation", SocketType::FLOAT, 0.0f); } void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -1816,22 +1828,22 @@ void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attrib void AnisotropicBsdfNode::compile(SVMCompiler& compiler) { - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation")); } void AnisotropicBsdfNode::compile(OSLCompiler& compiler) { - compiler.parameter("distribution", distribution); + compiler.parameter("distribution", distribution_enum[distribution]); compiler.add(this, "node_anisotropic_bsdf"); } /* Glossy BSDF Closure */ -static ShaderEnum glossy_distribution_init() +static NodeEnum glossy_distribution_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Sharp", CLOSURE_BSDF_REFLECTION_ID); enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID); @@ -1841,20 +1853,20 @@ static ShaderEnum glossy_distribution_init() return enm; } -ShaderEnum GlossyBsdfNode::distribution_enum = glossy_distribution_init(); +NodeEnum GlossyBsdfNode::distribution_enum = glossy_distribution_init(); GlossyBsdfNode::GlossyBsdfNode() { closure = CLOSURE_BSDF_MICROFACET_GGX_ID; - distribution = ustring("GGX"); - distribution_orig = ustring(""); + distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; + distribution_orig = NBUILTIN_CLOSURES; - add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f); + add_input("Roughness", SocketType::FLOAT, 0.2f); } void GlossyBsdfNode::simplify_settings(Scene *scene) { - if(distribution_orig == "") { + if(distribution_orig == NBUILTIN_CLOSURES) { distribution_orig = distribution; } Integrator *integrator = scene->integrator; @@ -1863,26 +1875,26 @@ void GlossyBsdfNode::simplify_settings(Scene *scene) * Note: Keep the epsilon in sync with kernel! */ ShaderInput *roughness_input = input("Roughness"); - if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { - distribution = ustring("Sharp"); + if(!roughness_input->link && roughness_input->value_float() <= 1e-4f) { + distribution = CLOSURE_BSDF_REFLECTION_ID; } } else { /* Rollback to original distribution when filter glossy is used. */ distribution = distribution_orig; } - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; } bool GlossyBsdfNode::has_integrator_dependency() { ShaderInput *roughness_input = input("Roughness"); - return !roughness_input->link && roughness_input->value.x <= 1e-4f; + return !roughness_input->link && roughness_input->value_float() <= 1e-4f; } void GlossyBsdfNode::compile(SVMCompiler& compiler) { - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; if(closure == CLOSURE_BSDF_REFLECTION_ID) BsdfNode::compile(compiler, NULL, NULL); @@ -1892,15 +1904,15 @@ void GlossyBsdfNode::compile(SVMCompiler& compiler) void GlossyBsdfNode::compile(OSLCompiler& compiler) { - compiler.parameter("distribution", distribution); + compiler.parameter("distribution", distribution_enum[distribution]); compiler.add(this, "node_glossy_bsdf"); } /* Glass BSDF Closure */ -static ShaderEnum glass_distribution_init() +static NodeEnum glass_distribution_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Sharp", CLOSURE_BSDF_SHARP_GLASS_ID); enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); @@ -1909,21 +1921,21 @@ static ShaderEnum glass_distribution_init() return enm; } -ShaderEnum GlassBsdfNode::distribution_enum = glass_distribution_init(); +NodeEnum GlassBsdfNode::distribution_enum = glass_distribution_init(); GlassBsdfNode::GlassBsdfNode() { closure = CLOSURE_BSDF_SHARP_GLASS_ID; - distribution = ustring("Sharp"); - distribution_orig = ustring(""); + distribution = CLOSURE_BSDF_SHARP_GLASS_ID; + distribution_orig = NBUILTIN_CLOSURES; - add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f); - add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f); + add_input("Roughness", SocketType::FLOAT, 0.0f); + add_input("IOR", SocketType::FLOAT, 0.3f); } void GlassBsdfNode::simplify_settings(Scene *scene) { - if(distribution_orig == "") { + if(distribution_orig == NBUILTIN_CLOSURES) { distribution_orig = distribution; } Integrator *integrator = scene->integrator; @@ -1932,26 +1944,26 @@ void GlassBsdfNode::simplify_settings(Scene *scene) * Note: Keep the epsilon in sync with kernel! */ ShaderInput *roughness_input = input("Roughness"); - if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { - distribution = ustring("Sharp"); + if(!roughness_input->link && roughness_input->value_float() <= 1e-4f) { + distribution = CLOSURE_BSDF_SHARP_GLASS_ID; } } else { /* Rollback to original distribution when filter glossy is used. */ distribution = distribution_orig; } - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; } bool GlassBsdfNode::has_integrator_dependency() { ShaderInput *roughness_input = input("Roughness"); - return !roughness_input->link && roughness_input->value.x <= 1e-4f; + return !roughness_input->link && roughness_input->value_float() <= 1e-4f; } void GlassBsdfNode::compile(SVMCompiler& compiler) { - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; if(closure == CLOSURE_BSDF_SHARP_GLASS_ID) BsdfNode::compile(compiler, NULL, input("IOR")); @@ -1961,15 +1973,15 @@ void GlassBsdfNode::compile(SVMCompiler& compiler) void GlassBsdfNode::compile(OSLCompiler& compiler) { - compiler.parameter("distribution", distribution); + compiler.parameter("distribution", distribution_enum[distribution]); compiler.add(this, "node_glass_bsdf"); } /* Refraction BSDF Closure */ -static ShaderEnum refraction_distribution_init() +static NodeEnum refraction_distribution_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID); enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); @@ -1978,21 +1990,21 @@ static ShaderEnum refraction_distribution_init() return enm; } -ShaderEnum RefractionBsdfNode::distribution_enum = refraction_distribution_init(); +NodeEnum RefractionBsdfNode::distribution_enum = refraction_distribution_init(); RefractionBsdfNode::RefractionBsdfNode() { closure = CLOSURE_BSDF_REFRACTION_ID; - distribution = ustring("Sharp"); - distribution_orig = ustring(""); + distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + distribution_orig = NBUILTIN_CLOSURES; - add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f); - add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f); + add_input("Roughness", SocketType::FLOAT, 0.0f); + add_input("IOR", SocketType::FLOAT, 0.3f); } void RefractionBsdfNode::simplify_settings(Scene *scene) { - if(distribution_orig == "") { + if(distribution_orig == NBUILTIN_CLOSURES) { distribution_orig = distribution; } Integrator *integrator = scene->integrator; @@ -2001,26 +2013,26 @@ void RefractionBsdfNode::simplify_settings(Scene *scene) * Note: Keep the epsilon in sync with kernel! */ ShaderInput *roughness_input = input("Roughness"); - if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { - distribution = ustring("Sharp"); + if(!roughness_input->link && roughness_input->value_float() <= 1e-4f) { + distribution = CLOSURE_BSDF_REFRACTION_ID; } } else { /* Rollback to original distribution when filter glossy is used. */ distribution = distribution_orig; } - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; } bool RefractionBsdfNode::has_integrator_dependency() { ShaderInput *roughness_input = input("Roughness"); - return !roughness_input->link && roughness_input->value.x <= 1e-4f; + return !roughness_input->link && roughness_input->value_float() <= 1e-4f; } void RefractionBsdfNode::compile(SVMCompiler& compiler) { - closure = (ClosureType)distribution_enum[distribution]; + closure = distribution; if(closure == CLOSURE_BSDF_REFRACTION_ID) BsdfNode::compile(compiler, NULL, input("IOR")); @@ -2030,15 +2042,15 @@ void RefractionBsdfNode::compile(SVMCompiler& compiler) void RefractionBsdfNode::compile(OSLCompiler& compiler) { - compiler.parameter("distribution", distribution); + compiler.parameter("distribution", distribution_enum[distribution]); compiler.add(this, "node_refraction_bsdf"); } /* Toon BSDF Closure */ -static ShaderEnum toon_component_init() +static NodeEnum toon_component_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Diffuse", CLOSURE_BSDF_DIFFUSE_TOON_ID); enm.insert("Glossy", CLOSURE_BSDF_GLOSSY_TOON_ID); @@ -2046,27 +2058,27 @@ static ShaderEnum toon_component_init() return enm; } -ShaderEnum ToonBsdfNode::component_enum = toon_component_init(); +NodeEnum ToonBsdfNode::component_enum = toon_component_init(); ToonBsdfNode::ToonBsdfNode() { closure = CLOSURE_BSDF_DIFFUSE_TOON_ID; - component = ustring("Diffuse"); + component = CLOSURE_BSDF_DIFFUSE_TOON_ID; - add_input("Size", SHADER_SOCKET_FLOAT, 0.5f); - add_input("Smooth", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Size", SocketType::FLOAT, 0.5f); + add_input("Smooth", SocketType::FLOAT, 0.0f); } void ToonBsdfNode::compile(SVMCompiler& compiler) { - closure = (ClosureType)component_enum[component]; + closure = component; BsdfNode::compile(compiler, input("Size"), input("Smooth")); } void ToonBsdfNode::compile(OSLCompiler& compiler) { - compiler.parameter("component", component); + compiler.parameter("component", component_enum[component]); compiler.add(this, "node_toon_bsdf"); } @@ -2076,7 +2088,7 @@ VelvetBsdfNode::VelvetBsdfNode() { closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID; - add_input("Sigma", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Sigma", SocketType::FLOAT, 1.0f); } void VelvetBsdfNode::compile(SVMCompiler& compiler) @@ -2094,7 +2106,7 @@ void VelvetBsdfNode::compile(OSLCompiler& compiler) DiffuseBsdfNode::DiffuseBsdfNode() { closure = CLOSURE_BSDF_DIFFUSE_ID; - add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Roughness", SocketType::FLOAT, 0.0f); } void DiffuseBsdfNode::compile(SVMCompiler& compiler) @@ -2144,9 +2156,9 @@ void TransparentBsdfNode::compile(OSLCompiler& compiler) /* Subsurface Scattering Closure */ -static ShaderEnum subsurface_falloff_init() +static NodeEnum subsurface_falloff_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Cubic", CLOSURE_BSSRDF_CUBIC_ID); enm.insert("Gaussian", CLOSURE_BSSRDF_GAUSSIAN_ID); @@ -2155,28 +2167,29 @@ static ShaderEnum subsurface_falloff_init() return enm; } -ShaderEnum SubsurfaceScatteringNode::falloff_enum = subsurface_falloff_init(); +NodeEnum SubsurfaceScatteringNode::falloff_enum = subsurface_falloff_init(); SubsurfaceScatteringNode::SubsurfaceScatteringNode() : BsdfNode(true) { name = "subsurface_scattering"; - closure = CLOSURE_BSSRDF_CUBIC_ID; + falloff = CLOSURE_BSSRDF_CUBIC_ID; - add_input("Scale", SHADER_SOCKET_FLOAT, 0.01f); - add_input("Radius", SHADER_SOCKET_VECTOR, make_float3(0.1f, 0.1f, 0.1f)); - add_input("Sharpness", SHADER_SOCKET_FLOAT, 0.0f); - add_input("Texture Blur", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Scale", SocketType::FLOAT, 0.01f); + add_input("Radius", SocketType::VECTOR, make_float3(0.1f, 0.1f, 0.1f)); + add_input("Sharpness", SocketType::FLOAT, 0.0f); + add_input("Texture Blur", SocketType::FLOAT, 1.0f); } void SubsurfaceScatteringNode::compile(SVMCompiler& compiler) { + closure = falloff; BsdfNode::compile(compiler, input("Scale"), input("Texture Blur"), input("Radius"), input("Sharpness")); } void SubsurfaceScatteringNode::compile(OSLCompiler& compiler) { - compiler.parameter("Falloff", falloff_enum[closure]); + compiler.parameter("falloff", falloff_enum[closure]); compiler.add(this, "node_subsurface_scattering"); } @@ -2192,11 +2205,11 @@ bool SubsurfaceScatteringNode::has_bssrdf_bump() EmissionNode::EmissionNode() : ShaderNode("emission") { - add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Strength", SHADER_SOCKET_FLOAT, 10.0f); - add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("Color", SocketType::COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_input("Strength", SocketType::FLOAT, 10.0f); + add_input("SurfaceMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); - add_output("Emission", SHADER_SOCKET_CLOSURE); + add_output("Emission", SocketType::CLOSURE); } void EmissionNode::compile(SVMCompiler& compiler) @@ -2210,7 +2223,7 @@ void EmissionNode::compile(SVMCompiler& compiler) compiler.stack_assign(strength_in)); } else - compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value * strength_in->value.x); + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value() * strength_in->value_float()); compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset()); } @@ -2220,13 +2233,13 @@ void EmissionNode::compile(OSLCompiler& compiler) compiler.add(this, "node_emission"); } -bool EmissionNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, float3 * /*optimized_value*/) +bool EmissionNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *) { ShaderInput *color_in = input("Color"); ShaderInput *strength_in = input("Strength"); - return ((!color_in->link && color_in->value == make_float3(0.0f, 0.0f, 0.0f)) || - (!strength_in->link && strength_in->value.x == 0.0f)); + return ((!color_in->link && color_in->value() == make_float3(0.0f, 0.0f, 0.0f)) || + (!strength_in->link && strength_in->value_float() == 0.0f)); } /* Background Closure */ @@ -2234,11 +2247,11 @@ bool EmissionNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socke BackgroundNode::BackgroundNode() : ShaderNode("background") { - add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); - add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("Color", SocketType::COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_input("Strength", SocketType::FLOAT, 1.0f); + add_input("SurfaceMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); - add_output("Background", SHADER_SOCKET_CLOSURE); + add_output("Background", SocketType::CLOSURE); } void BackgroundNode::compile(SVMCompiler& compiler) @@ -2252,7 +2265,7 @@ void BackgroundNode::compile(SVMCompiler& compiler) compiler.stack_assign(strength_in)); } else - compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value*strength_in->value.x); + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value()*strength_in->value_float()); compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset()); } @@ -2262,13 +2275,13 @@ void BackgroundNode::compile(OSLCompiler& compiler) compiler.add(this, "node_background"); } -bool BackgroundNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, float3 * /*optimized_value*/) +bool BackgroundNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *) { ShaderInput *color_in = input("Color"); ShaderInput *strength_in = input("Strength"); - return ((!color_in->link && color_in->value == make_float3(0.0f, 0.0f, 0.0f)) || - (!strength_in->link && strength_in->value.x == 0.0f)); + return ((!color_in->link && color_in->value() == make_float3(0.0f, 0.0f, 0.0f)) || + (!strength_in->link && strength_in->value_float() == 0.0f)); } /* Holdout Closure */ @@ -2276,10 +2289,10 @@ bool BackgroundNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*soc HoldoutNode::HoldoutNode() : ShaderNode("holdout") { - add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); - add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("SurfaceMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); + add_input("VolumeMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); - add_output("Holdout", SHADER_SOCKET_CLOSURE); + add_output("Holdout", SocketType::CLOSURE); } void HoldoutNode::compile(SVMCompiler& compiler) @@ -2300,11 +2313,11 @@ void HoldoutNode::compile(OSLCompiler& compiler) AmbientOcclusionNode::AmbientOcclusionNode() : ShaderNode("ambient_occlusion") { - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("NormalIn", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_input("Color", SocketType::COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_input("SurfaceMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); - add_output("AO", SHADER_SOCKET_CLOSURE); + add_output("AO", SocketType::CLOSURE); } void AmbientOcclusionNode::compile(SVMCompiler& compiler) @@ -2314,7 +2327,7 @@ void AmbientOcclusionNode::compile(SVMCompiler& compiler) if(color_in->link) compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); else - compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value); + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value()); compiler.add_node(NODE_CLOSURE_AMBIENT_OCCLUSION, compiler.closure_mix_weight_offset()); } @@ -2331,11 +2344,11 @@ VolumeNode::VolumeNode() { closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID; - add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Density", SHADER_SOCKET_FLOAT, 1.0f); - add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("Color", SocketType::COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_input("Density", SocketType::FLOAT, 1.0f); + add_input("VolumeMixWeight", SocketType::FLOAT, 0.0f, SocketType::SVM_INTERNAL); - add_output("Volume", SHADER_SOCKET_CLOSURE); + add_output("Volume", SocketType::CLOSURE); } void VolumeNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2) @@ -2345,15 +2358,15 @@ void VolumeNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput if(color_in->link) compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); else - compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value); + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value()); compiler.add_node(NODE_CLOSURE_VOLUME, compiler.encode_uchar4(closure, (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID, (param2)? compiler.stack_assign(param2): SVM_STACK_INVALID, compiler.closure_mix_weight_offset()), - __float_as_int((param1)? param1->value.x: 0.0f), - __float_as_int((param2)? param2->value.x: 0.0f)); + __float_as_int((param1)? param1->value_float(): 0.0f), + __float_as_int((param2)? param2->value_float(): 0.0f)); } void VolumeNode::compile(SVMCompiler& compiler) @@ -2389,7 +2402,7 @@ ScatterVolumeNode::ScatterVolumeNode() { closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID; - add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Anisotropy", SocketType::FLOAT, 0.0f); } void ScatterVolumeNode::compile(SVMCompiler& compiler) @@ -2404,9 +2417,9 @@ void ScatterVolumeNode::compile(OSLCompiler& compiler) /* Hair BSDF Closure */ -static ShaderEnum hair_component_init() +static NodeEnum hair_component_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Reflection", CLOSURE_BSDF_HAIR_REFLECTION_ID); enm.insert("Transmission", CLOSURE_BSDF_HAIR_TRANSMISSION_ID); @@ -2414,29 +2427,29 @@ static ShaderEnum hair_component_init() return enm; } -ShaderEnum HairBsdfNode::component_enum = hair_component_init(); +NodeEnum HairBsdfNode::component_enum = hair_component_init(); HairBsdfNode::HairBsdfNode() { closure = CLOSURE_BSDF_HAIR_REFLECTION_ID; - component = ustring("Reflection"); + component = CLOSURE_BSDF_HAIR_REFLECTION_ID; - add_input("Offset", SHADER_SOCKET_FLOAT); - add_input("RoughnessU", SHADER_SOCKET_FLOAT); - add_input("RoughnessV", SHADER_SOCKET_FLOAT); - add_input("Tangent", SHADER_SOCKET_VECTOR); + add_input("Offset", SocketType::FLOAT); + add_input("RoughnessU", SocketType::FLOAT); + add_input("RoughnessV", SocketType::FLOAT); + add_input("Tangent", SocketType::VECTOR); } void HairBsdfNode::compile(SVMCompiler& compiler) { - closure = (ClosureType)component_enum[component]; + closure = component; BsdfNode::compile(compiler, input("RoughnessU"), input("RoughnessV"), input("Offset")); } void HairBsdfNode::compile(OSLCompiler& compiler) { - compiler.parameter("component", component); + compiler.parameter("component", component_enum[component]); compiler.add(this, "node_hair_bsdf"); } @@ -2448,15 +2461,15 @@ GeometryNode::GeometryNode() { special_type = SHADER_SPECIAL_TYPE_GEOMETRY; - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_output("Position", SHADER_SOCKET_POINT); - add_output("Normal", SHADER_SOCKET_NORMAL); - add_output("Tangent", SHADER_SOCKET_NORMAL); - add_output("True Normal", SHADER_SOCKET_NORMAL); - add_output("Incoming", SHADER_SOCKET_VECTOR); - add_output("Parametric", SHADER_SOCKET_POINT); - add_output("Backfacing", SHADER_SOCKET_FLOAT); - add_output("Pointiness", SHADER_SOCKET_FLOAT); + add_input("NormalIn", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_output("Position", SocketType::POINT); + add_output("Normal", SocketType::NORMAL); + add_output("Tangent", SocketType::NORMAL); + add_output("True Normal", SocketType::NORMAL); + add_output("Incoming", SocketType::VECTOR); + add_output("Parametric", SocketType::POINT); + add_output("Backfacing", SocketType::FLOAT); + add_output("Pointiness", SocketType::FLOAT); } void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -2554,14 +2567,14 @@ void GeometryNode::compile(OSLCompiler& compiler) TextureCoordinateNode::TextureCoordinateNode() : ShaderNode("texture_coordinate") { - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_output("Generated", SHADER_SOCKET_POINT); - add_output("Normal", SHADER_SOCKET_NORMAL); - add_output("UV", SHADER_SOCKET_POINT); - add_output("Object", SHADER_SOCKET_POINT); - add_output("Camera", SHADER_SOCKET_POINT); - add_output("Window", SHADER_SOCKET_POINT); - add_output("Reflection", SHADER_SOCKET_NORMAL); + add_input("NormalIn", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_output("Generated", SocketType::POINT); + add_output("Normal", SocketType::NORMAL); + add_output("UV", SocketType::POINT); + add_output("Object", SocketType::POINT); + add_output("Camera", SocketType::POINT); + add_output("Window", SocketType::POINT); + add_output("Reflection", SocketType::NORMAL); from_dupli = false; use_transform = false; @@ -2704,7 +2717,7 @@ UVMapNode::UVMapNode() attribute = ""; from_dupli = false; - add_output("UV", SHADER_SOCKET_POINT); + add_output("UV", SocketType::POINT); } void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -2773,18 +2786,18 @@ void UVMapNode::compile(OSLCompiler& compiler) LightPathNode::LightPathNode() : ShaderNode("light_path") { - add_output("Is Camera Ray", SHADER_SOCKET_FLOAT); - add_output("Is Shadow Ray", SHADER_SOCKET_FLOAT); - add_output("Is Diffuse Ray", SHADER_SOCKET_FLOAT); - add_output("Is Glossy Ray", SHADER_SOCKET_FLOAT); - add_output("Is Singular Ray", SHADER_SOCKET_FLOAT); - add_output("Is Reflection Ray", SHADER_SOCKET_FLOAT); - add_output("Is Transmission Ray", SHADER_SOCKET_FLOAT); - add_output("Is Volume Scatter Ray", SHADER_SOCKET_FLOAT); - add_output("Ray Length", SHADER_SOCKET_FLOAT); - add_output("Ray Depth", SHADER_SOCKET_FLOAT); - add_output("Transparent Depth", SHADER_SOCKET_FLOAT); - add_output("Transmission Depth", SHADER_SOCKET_FLOAT); + add_output("Is Camera Ray", SocketType::FLOAT); + add_output("Is Shadow Ray", SocketType::FLOAT); + add_output("Is Diffuse Ray", SocketType::FLOAT); + add_output("Is Glossy Ray", SocketType::FLOAT); + add_output("Is Singular Ray", SocketType::FLOAT); + add_output("Is Reflection Ray", SocketType::FLOAT); + add_output("Is Transmission Ray", SocketType::FLOAT); + add_output("Is Volume Scatter Ray", SocketType::FLOAT); + add_output("Ray Length", SocketType::FLOAT); + add_output("Ray Depth", SocketType::FLOAT); + add_output("Transparent Depth", SocketType::FLOAT); + add_output("Transmission Depth", SocketType::FLOAT); } void LightPathNode::compile(SVMCompiler& compiler) @@ -2863,11 +2876,11 @@ void LightPathNode::compile(OSLCompiler& compiler) LightFalloffNode::LightFalloffNode() : ShaderNode("light_fallof") { - add_input("Strength", SHADER_SOCKET_FLOAT, 100.0f); - add_input("Smooth", SHADER_SOCKET_FLOAT, 0.0f); - add_output("Quadratic", SHADER_SOCKET_FLOAT); - add_output("Linear", SHADER_SOCKET_FLOAT); - add_output("Constant", SHADER_SOCKET_FLOAT); + add_input("Strength", SocketType::FLOAT, 100.0f); + add_input("Smooth", SocketType::FLOAT, 0.0f); + add_output("Quadratic", SocketType::FLOAT); + add_output("Linear", SocketType::FLOAT); + add_output("Constant", SocketType::FLOAT); } void LightFalloffNode::compile(SVMCompiler& compiler) @@ -2913,10 +2926,10 @@ void LightFalloffNode::compile(OSLCompiler& compiler) ObjectInfoNode::ObjectInfoNode() : ShaderNode("object_info") { - add_output("Location", SHADER_SOCKET_VECTOR); - add_output("Object Index", SHADER_SOCKET_FLOAT); - add_output("Material Index", SHADER_SOCKET_FLOAT); - add_output("Random", SHADER_SOCKET_FLOAT); + add_output("Location", SocketType::VECTOR); + add_output("Object Index", SocketType::FLOAT); + add_output("Material Index", SocketType::FLOAT); + add_output("Random", SocketType::FLOAT); } void ObjectInfoNode::compile(SVMCompiler& compiler) @@ -2952,16 +2965,16 @@ void ObjectInfoNode::compile(OSLCompiler& compiler) ParticleInfoNode::ParticleInfoNode() : ShaderNode("particle_info") { - add_output("Index", SHADER_SOCKET_FLOAT); - add_output("Age", SHADER_SOCKET_FLOAT); - add_output("Lifetime", SHADER_SOCKET_FLOAT); - add_output("Location", SHADER_SOCKET_POINT); + add_output("Index", SocketType::FLOAT); + add_output("Age", SocketType::FLOAT); + add_output("Lifetime", SocketType::FLOAT); + add_output("Location", SocketType::POINT); #if 0 /* not yet supported */ add_output("Rotation", SHADER_SOCKET_QUATERNION); #endif - add_output("Size", SHADER_SOCKET_FLOAT); - add_output("Velocity", SHADER_SOCKET_VECTOR); - add_output("Angular Velocity", SHADER_SOCKET_VECTOR); + add_output("Size", SocketType::FLOAT); + add_output("Velocity", SocketType::VECTOR); + add_output("Angular Velocity", SocketType::VECTOR); } void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -3046,12 +3059,12 @@ void ParticleInfoNode::compile(OSLCompiler& compiler) HairInfoNode::HairInfoNode() : ShaderNode("hair_info") { - add_output("Is Strand", SHADER_SOCKET_FLOAT); - add_output("Intercept", SHADER_SOCKET_FLOAT); - add_output("Thickness", SHADER_SOCKET_FLOAT); - add_output("Tangent Normal", SHADER_SOCKET_NORMAL); + add_output("Is Strand", SocketType::FLOAT); + add_output("Intercept", SocketType::FLOAT); + add_output("Thickness", SocketType::FLOAT); + add_output("Tangent Normal", SocketType::NORMAL); /*output for minimum hair width transparency - deactivated*/ - /*add_output("Fade", SHADER_SOCKET_FLOAT);*/ + /*add_output("Fade", SocketType::FLOAT);*/ } void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -3110,13 +3123,12 @@ ValueNode::ValueNode() { value = 0.0f; - add_output("Value", SHADER_SOCKET_FLOAT); + add_output("Value", SocketType::FLOAT); } -bool ValueNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, - float3 *optimized_value) +bool ValueNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *optimized) { - *optimized_value = make_float3(value, value, value); + optimized->set(value); return true; } @@ -3140,13 +3152,12 @@ ColorNode::ColorNode() { value = make_float3(0.0f, 0.0f, 0.0f); - add_output("Color", SHADER_SOCKET_COLOR); + add_output("Color", SocketType::COLOR); } -bool ColorNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, - float3 *optimized_value) +bool ColorNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *optimized) { - *optimized_value = value; + optimized->set(value); return true; } @@ -3174,9 +3185,9 @@ AddClosureNode::AddClosureNode() { special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE; - add_input("Closure1", SHADER_SOCKET_CLOSURE); - add_input("Closure2", SHADER_SOCKET_CLOSURE); - add_output("Closure", SHADER_SOCKET_CLOSURE); + add_input("Closure1", SocketType::CLOSURE); + add_input("Closure2", SocketType::CLOSURE); + add_output("Closure", SocketType::CLOSURE); } void AddClosureNode::compile(SVMCompiler& /*compiler*/) @@ -3196,10 +3207,10 @@ MixClosureNode::MixClosureNode() { special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE; - add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f); - add_input("Closure1", SHADER_SOCKET_CLOSURE); - add_input("Closure2", SHADER_SOCKET_CLOSURE); - add_output("Closure", SHADER_SOCKET_CLOSURE); + add_input("Fac", SocketType::FLOAT, 0.5f); + add_input("Closure1", SocketType::CLOSURE); + add_input("Closure2", SocketType::CLOSURE); + add_output("Closure", SocketType::CLOSURE); } void MixClosureNode::compile(SVMCompiler& /*compiler*/) @@ -3212,7 +3223,7 @@ void MixClosureNode::compile(OSLCompiler& compiler) compiler.add(this, "node_mix_closure"); } -bool MixClosureNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/, float3 * /*optimized_value*/) +bool MixClosureNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *) { ShaderInput *fac_in = input("Fac"); ShaderInput *closure1_in = input("Closure1"); @@ -3229,12 +3240,12 @@ bool MixClosureNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/ /* check for closure links and make sure factor link is disconnected */ if(closure1_in->link && closure2_in->link && !fac_in->link) { /* factor 0.0 */ - if(fac_in->value.x == 0.0f) { + if(fac_in->value_float() == 0.0f) { graph->relink(this, closure_out, closure1_in->link); return true; } /* factor 1.0 */ - else if(fac_in->value.x == 1.0f) { + else if(fac_in->value_float() == 1.0f) { graph->relink(this, closure_out, closure2_in->link); return true; } @@ -3248,10 +3259,10 @@ bool MixClosureNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/ MixClosureWeightNode::MixClosureWeightNode() : ShaderNode("mix_closure_weight") { - add_input("Weight", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f); - add_output("Weight1", SHADER_SOCKET_FLOAT); - add_output("Weight2", SHADER_SOCKET_FLOAT); + add_input("Weight", SocketType::FLOAT, 1.0f); + add_input("Fac", SocketType::FLOAT, 1.0f); + add_output("Weight1", SocketType::FLOAT); + add_output("Weight2", SocketType::FLOAT); } void MixClosureWeightNode::compile(SVMCompiler& compiler) @@ -3279,9 +3290,9 @@ void MixClosureWeightNode::compile(OSLCompiler& /*compiler*/) InvertNode::InvertNode() : ShaderNode("invert") { - add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Color", SHADER_SOCKET_COLOR); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Fac", SocketType::FLOAT, 1.0f); + add_input("Color", SocketType::COLOR); + add_output("Color", SocketType::COLOR); } void InvertNode::compile(SVMCompiler& compiler) @@ -3306,19 +3317,19 @@ void InvertNode::compile(OSLCompiler& compiler) MixNode::MixNode() : ShaderNode("mix") { - type = ustring("Mix"); + type = NODE_MIX_BLEND; use_clamp = false; - add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f); - add_input("Color1", SHADER_SOCKET_COLOR); - add_input("Color2", SHADER_SOCKET_COLOR); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Fac", SocketType::FLOAT, 0.5f); + add_input("Color1", SocketType::COLOR); + add_input("Color2", SocketType::COLOR); + add_output("Color", SocketType::COLOR); } -static ShaderEnum mix_type_init() +static NodeEnum mix_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Mix", NODE_MIX_BLEND); enm.insert("Add", NODE_MIX_ADD); @@ -3342,7 +3353,7 @@ static ShaderEnum mix_type_init() return enm; } -ShaderEnum MixNode::type_enum = mix_type_init(); +NodeEnum MixNode::type_enum = mix_type_init(); void MixNode::compile(SVMCompiler& compiler) { @@ -3355,7 +3366,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_enum[type], compiler.stack_assign(color_out)); + compiler.add_node(NODE_MIX, type, compiler.stack_assign(color_out)); if(use_clamp) { compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out)); @@ -3365,14 +3376,14 @@ void MixNode::compile(SVMCompiler& compiler) void MixNode::compile(OSLCompiler& compiler) { - compiler.parameter("type", type); - compiler.parameter("Clamp", use_clamp); + compiler.parameter("type", type_enum[type]); + compiler.parameter("use_clamp", use_clamp); compiler.add(this, "node_mix"); } -bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/, float3 * optimized_value) +bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *optimized) { - if(type != ustring("Mix")) { + if(type != NODE_MIX_BLEND) { return false; } @@ -3390,19 +3401,19 @@ bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/, float /* remove unused mix color input when factor is 0.0 or 1.0 */ if(!fac_in->link) { /* factor 0.0 */ - if(fac_in->value.x == 0.0f) { + if(fac_in->value_float() == 0.0f) { if(color1_in->link) graph->relink(this, color_out, color1_in->link); else - *optimized_value = color1_in->value; + optimized->set(color1_in->value()); return true; } /* factor 1.0 */ - else if(fac_in->value.x == 1.0f) { + else if(fac_in->value_float() == 1.0f) { if(color2_in->link) graph->relink(this, color_out, color2_in->link); else - *optimized_value = color2_in->value; + optimized->set(color2_in->value()); return true; } } @@ -3414,10 +3425,10 @@ bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/, float CombineRGBNode::CombineRGBNode() : ShaderNode("combine_rgb") { - add_input("R", SHADER_SOCKET_FLOAT); - add_input("G", SHADER_SOCKET_FLOAT); - add_input("B", SHADER_SOCKET_FLOAT); - add_output("Image", SHADER_SOCKET_COLOR); + add_input("R", SocketType::FLOAT); + add_input("G", SocketType::FLOAT); + add_input("B", SocketType::FLOAT); + add_output("Image", SocketType::COLOR); } void CombineRGBNode::compile(SVMCompiler& compiler) @@ -3449,10 +3460,10 @@ void CombineRGBNode::compile(OSLCompiler& compiler) CombineXYZNode::CombineXYZNode() : ShaderNode("combine_xyz") { - add_input("X", SHADER_SOCKET_FLOAT); - add_input("Y", SHADER_SOCKET_FLOAT); - add_input("Z", SHADER_SOCKET_FLOAT); - add_output("Vector", SHADER_SOCKET_VECTOR); + add_input("X", SocketType::FLOAT); + add_input("Y", SocketType::FLOAT); + add_input("Z", SocketType::FLOAT); + add_output("Vector", SocketType::VECTOR); } void CombineXYZNode::compile(SVMCompiler& compiler) @@ -3484,10 +3495,10 @@ void CombineXYZNode::compile(OSLCompiler& compiler) CombineHSVNode::CombineHSVNode() : ShaderNode("combine_hsv") { - add_input("H", SHADER_SOCKET_FLOAT); - add_input("S", SHADER_SOCKET_FLOAT); - add_input("V", SHADER_SOCKET_FLOAT); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("H", SocketType::FLOAT); + add_input("S", SocketType::FLOAT); + add_input("V", SocketType::FLOAT); + add_output("Color", SocketType::COLOR); } void CombineHSVNode::compile(SVMCompiler& compiler) @@ -3514,20 +3525,20 @@ void CombineHSVNode::compile(OSLCompiler& compiler) GammaNode::GammaNode() : ShaderNode("gamma") { - add_input("Color", SHADER_SOCKET_COLOR); - add_input("Gamma", SHADER_SOCKET_FLOAT); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Color", SocketType::COLOR); + add_input("Gamma", SocketType::FLOAT); + add_output("Color", SocketType::COLOR); } -bool GammaNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput *socket, float3 *optimized_value) +bool GammaNode::constant_fold(ShaderGraph *, ShaderOutput *socket, ShaderInput *optimized) { ShaderInput *color_in = input("Color"); ShaderInput *gamma_in = input("Gamma"); if(socket == output("Color")) { if(color_in->link == NULL && gamma_in->link == NULL) { - *optimized_value = svm_math_gamma_color(color_in->value, - gamma_in->value.x); + optimized->set(svm_math_gamma_color(color_in->value(), + gamma_in->value_float())); return true; } } @@ -3556,10 +3567,10 @@ void GammaNode::compile(OSLCompiler& compiler) BrightContrastNode::BrightContrastNode() : ShaderNode("brightness") { - add_input("Color", SHADER_SOCKET_COLOR); - add_input("Bright", SHADER_SOCKET_FLOAT); - add_input("Contrast", SHADER_SOCKET_FLOAT); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Color", SocketType::COLOR); + add_input("Bright", SocketType::FLOAT); + add_input("Contrast", SocketType::FLOAT); + add_output("Color", SocketType::COLOR); } void BrightContrastNode::compile(SVMCompiler& compiler) @@ -3586,10 +3597,10 @@ void BrightContrastNode::compile(OSLCompiler& compiler) SeparateRGBNode::SeparateRGBNode() : ShaderNode("separate_rgb") { - add_input("Image", SHADER_SOCKET_COLOR); - add_output("R", SHADER_SOCKET_FLOAT); - add_output("G", SHADER_SOCKET_FLOAT); - add_output("B", SHADER_SOCKET_FLOAT); + add_input("Image", SocketType::COLOR); + add_output("R", SocketType::FLOAT); + add_output("G", SocketType::FLOAT); + add_output("B", SocketType::FLOAT); } void SeparateRGBNode::compile(SVMCompiler& compiler) @@ -3621,10 +3632,10 @@ void SeparateRGBNode::compile(OSLCompiler& compiler) SeparateXYZNode::SeparateXYZNode() : ShaderNode("separate_xyz") { - add_input("Vector", SHADER_SOCKET_VECTOR); - add_output("X", SHADER_SOCKET_FLOAT); - add_output("Y", SHADER_SOCKET_FLOAT); - add_output("Z", SHADER_SOCKET_FLOAT); + add_input("Vector", SocketType::VECTOR); + add_output("X", SocketType::FLOAT); + add_output("Y", SocketType::FLOAT); + add_output("Z", SocketType::FLOAT); } void SeparateXYZNode::compile(SVMCompiler& compiler) @@ -3656,10 +3667,10 @@ void SeparateXYZNode::compile(OSLCompiler& compiler) SeparateHSVNode::SeparateHSVNode() : ShaderNode("separate_hsv") { - add_input("Color", SHADER_SOCKET_COLOR); - add_output("H", SHADER_SOCKET_FLOAT); - add_output("S", SHADER_SOCKET_FLOAT); - add_output("V", SHADER_SOCKET_FLOAT); + add_input("Color", SocketType::COLOR); + add_output("H", SocketType::FLOAT); + add_output("S", SocketType::FLOAT); + add_output("V", SocketType::FLOAT); } void SeparateHSVNode::compile(SVMCompiler& compiler) @@ -3686,12 +3697,12 @@ void SeparateHSVNode::compile(OSLCompiler& compiler) HSVNode::HSVNode() : ShaderNode("hsv") { - add_input("Hue", SHADER_SOCKET_FLOAT); - add_input("Saturation", SHADER_SOCKET_FLOAT); - add_input("Value", SHADER_SOCKET_FLOAT); - add_input("Fac", SHADER_SOCKET_FLOAT); - add_input("Color", SHADER_SOCKET_COLOR); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Hue", SocketType::FLOAT); + add_input("Saturation", SocketType::FLOAT); + add_input("Value", SocketType::FLOAT); + add_input("Fac", SocketType::FLOAT); + add_input("Color", SocketType::COLOR); + add_output("Color", SocketType::COLOR); } void HSVNode::compile(SVMCompiler& compiler) @@ -3726,9 +3737,9 @@ AttributeNode::AttributeNode() { attribute = ""; - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Vector", SHADER_SOCKET_VECTOR); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Vector", SocketType::VECTOR); + add_output("Fac", SocketType::FLOAT); } void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -3807,9 +3818,9 @@ void AttributeNode::compile(OSLCompiler& compiler) CameraNode::CameraNode() : ShaderNode("camera") { - add_output("View Vector", SHADER_SOCKET_VECTOR); - add_output("View Z Depth", SHADER_SOCKET_FLOAT); - add_output("View Distance", SHADER_SOCKET_FLOAT); + add_output("View Vector", SocketType::VECTOR); + add_output("View Z Depth", SocketType::FLOAT); + add_output("View Distance", SocketType::FLOAT); } void CameraNode::compile(SVMCompiler& compiler) @@ -3834,9 +3845,9 @@ void CameraNode::compile(OSLCompiler& compiler) FresnelNode::FresnelNode() : ShaderNode("fresnel") { - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_input("Normal", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_input("IOR", SocketType::FLOAT, 1.45f); + add_output("Fac", SocketType::FLOAT); } void FresnelNode::compile(SVMCompiler& compiler) @@ -3847,7 +3858,7 @@ void FresnelNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_FRESNEL, compiler.stack_assign(IOR_in), - __float_as_int(IOR_in->value.x), + __float_as_int(IOR_in->value_float()), compiler.encode_uchar4( compiler.stack_assign_if_linked(normal_in), compiler.stack_assign(fac_out))); @@ -3863,11 +3874,11 @@ void FresnelNode::compile(OSLCompiler& compiler) LayerWeightNode::LayerWeightNode() : ShaderNode("layer_weight") { - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_input("Blend", SHADER_SOCKET_FLOAT, 0.5f); + add_input("Normal", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_input("Blend", SocketType::FLOAT, 0.5f); - add_output("Fresnel", SHADER_SOCKET_FLOAT); - add_output("Facing", SHADER_SOCKET_FLOAT); + add_output("Fresnel", SocketType::FLOAT); + add_output("Facing", SocketType::FLOAT); } void LayerWeightNode::compile(SVMCompiler& compiler) @@ -3880,7 +3891,7 @@ void LayerWeightNode::compile(SVMCompiler& compiler) if(!fresnel_out->links.empty()) { compiler.add_node(NODE_LAYER_WEIGHT, compiler.stack_assign_if_linked(blend_in), - __float_as_int(blend_in->value.x), + __float_as_int(blend_in->value_float()), compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL, compiler.stack_assign_if_linked(normal_in), compiler.stack_assign(fresnel_out))); @@ -3889,7 +3900,7 @@ void LayerWeightNode::compile(SVMCompiler& compiler) if(!facing_out->links.empty()) { compiler.add_node(NODE_LAYER_WEIGHT, compiler.stack_assign_if_linked(blend_in), - __float_as_int(blend_in->value.x), + __float_as_int(blend_in->value_float()), compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING, compiler.stack_assign_if_linked(normal_in), compiler.stack_assign(facing_out))); @@ -3906,8 +3917,8 @@ void LayerWeightNode::compile(OSLCompiler& compiler) WireframeNode::WireframeNode() : ShaderNode("wireframe") { - add_input("Size", SHADER_SOCKET_FLOAT, 0.01f); - add_output("Fac", SHADER_SOCKET_FLOAT); + add_input("Size", SocketType::FLOAT, 0.01f); + add_output("Fac", SocketType::FLOAT); use_pixel_size = false; } @@ -3951,8 +3962,8 @@ void WireframeNode::compile(OSLCompiler& compiler) WavelengthNode::WavelengthNode() : ShaderNode("wavelength") { - add_input("Wavelength", SHADER_SOCKET_FLOAT, 500.0f); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Wavelength", SocketType::FLOAT, 500.0f); + add_output("Color", SocketType::COLOR); } void WavelengthNode::compile(SVMCompiler& compiler) @@ -3975,17 +3986,17 @@ void WavelengthNode::compile(OSLCompiler& compiler) BlackbodyNode::BlackbodyNode() : ShaderNode("blackbody") { - add_input("Temperature", SHADER_SOCKET_FLOAT, 1200.0f); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Temperature", SocketType::FLOAT, 1200.0f); + add_output("Color", SocketType::COLOR); } -bool BlackbodyNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput *socket, float3 *optimized_value) +bool BlackbodyNode::constant_fold(ShaderGraph *, ShaderOutput *socket, ShaderInput *optimized) { ShaderInput *temperature_in = input("Temperature"); if(socket == output("Color")) { if(temperature_in->link == NULL) { - *optimized_value = svm_math_blackbody_color(temperature_in->value.x); + optimized->set(svm_math_blackbody_color(temperature_in->value_float())); return true; } } @@ -4015,10 +4026,10 @@ OutputNode::OutputNode() { special_type = SHADER_SPECIAL_TYPE_OUTPUT; - add_input("Surface", SHADER_SOCKET_CLOSURE); - add_input("Volume", SHADER_SOCKET_CLOSURE); - add_input("Displacement", SHADER_SOCKET_FLOAT); - add_input("Normal", SHADER_SOCKET_NORMAL); + add_input("Surface", SocketType::CLOSURE); + add_input("Volume", SocketType::CLOSURE); + add_input("Displacement", SocketType::FLOAT); + add_input("Normal", SocketType::NORMAL); } void OutputNode::compile(SVMCompiler& compiler) @@ -4047,18 +4058,18 @@ void OutputNode::compile(OSLCompiler& compiler) MathNode::MathNode() : ShaderNode("math") { - type = ustring("Add"); + type = NODE_MATH_ADD; use_clamp = false; - add_input("Value1", SHADER_SOCKET_FLOAT); - add_input("Value2", SHADER_SOCKET_FLOAT); - add_output("Value", SHADER_SOCKET_FLOAT); + add_input("Value1", SocketType::FLOAT); + add_input("Value2", SocketType::FLOAT); + add_output("Value", SocketType::FLOAT); } -static ShaderEnum math_type_init() +static NodeEnum math_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Add", NODE_MATH_ADD); enm.insert("Subtract", NODE_MATH_SUBTRACT); @@ -4083,23 +4094,25 @@ static ShaderEnum math_type_init() return enm; } -ShaderEnum MathNode::type_enum = math_type_init(); +NodeEnum MathNode::type_enum = math_type_init(); -bool MathNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput *socket, float3 *optimized_value) +bool MathNode::constant_fold(ShaderGraph *, ShaderOutput *socket, ShaderInput *optimized) { ShaderInput *value1_in = input("Value1"); ShaderInput *value2_in = input("Value2"); if(socket == output("Value")) { if(value1_in->link == NULL && value2_in->link == NULL) { - optimized_value->x = svm_math((NodeMath)type_enum[type], - value1_in->value.x, - value2_in->value.x); + float value = svm_math(type, + value1_in->value_float(), + value2_in->value_float()); if(use_clamp) { - optimized_value->x = saturate(optimized_value->x); + value = saturate(value); } + optimized->set(value); + return true; } } @@ -4113,10 +4126,7 @@ void MathNode::compile(SVMCompiler& compiler) ShaderInput *value2_in = input("Value2"); ShaderOutput *value_out = output("Value"); - compiler.add_node(NODE_MATH, - type_enum[type], - compiler.stack_assign(value1_in), - compiler.stack_assign(value2_in)); + compiler.add_node(NODE_MATH, type, compiler.stack_assign(value1_in), compiler.stack_assign(value2_in)); compiler.add_node(NODE_MATH, compiler.stack_assign(value_out)); if(use_clamp) { @@ -4127,8 +4137,8 @@ void MathNode::compile(SVMCompiler& compiler) void MathNode::compile(OSLCompiler& compiler) { - compiler.parameter("type", type); - compiler.parameter("Clamp", use_clamp); + compiler.parameter("type", type_enum[type]); + compiler.parameter("use_clamp", use_clamp); compiler.add(this, "node_math"); } @@ -4137,17 +4147,17 @@ void MathNode::compile(OSLCompiler& compiler) VectorMathNode::VectorMathNode() : ShaderNode("vector_math") { - type = ustring("Add"); + type = NODE_VECTOR_MATH_ADD; - add_input("Vector1", SHADER_SOCKET_VECTOR); - add_input("Vector2", SHADER_SOCKET_VECTOR); - add_output("Value", SHADER_SOCKET_FLOAT); - add_output("Vector", SHADER_SOCKET_VECTOR); + add_input("Vector1", SocketType::VECTOR); + add_input("Vector2", SocketType::VECTOR); + add_output("Value", SocketType::FLOAT); + add_output("Vector", SocketType::VECTOR); } -static ShaderEnum vector_math_type_init() +static NodeEnum vector_math_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Add", NODE_VECTOR_MATH_ADD); enm.insert("Subtract", NODE_VECTOR_MATH_SUBTRACT); @@ -4159,9 +4169,9 @@ static ShaderEnum vector_math_type_init() return enm; } -ShaderEnum VectorMathNode::type_enum = vector_math_type_init(); +NodeEnum VectorMathNode::type_enum = vector_math_type_init(); -bool VectorMathNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput *socket, float3 *optimized_value) +bool VectorMathNode::constant_fold(ShaderGraph *, ShaderOutput *socket, ShaderInput *optimized) { ShaderInput *vector1_in = input("Vector1"); ShaderInput *vector2_in = input("Vector2"); @@ -4172,16 +4182,16 @@ bool VectorMathNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput *socket if(vector1_in->link == NULL && vector2_in->link == NULL) { svm_vector_math(&value, &vector, - (NodeVectorMath)type_enum[type], - vector1_in->value, - vector2_in->value); + type, + vector1_in->value(), + vector2_in->value()); if(socket == output("Value")) { - optimized_value->x = value; + optimized->set(value); return true; } else if(socket == output("Vector")) { - *optimized_value = vector; + optimized->set(vector); return true; } } @@ -4197,7 +4207,7 @@ void VectorMathNode::compile(SVMCompiler& compiler) ShaderOutput *vector_out = output("Vector"); compiler.add_node(NODE_VECTOR_MATH, - type_enum[type], + type, compiler.stack_assign(vector1_in), compiler.stack_assign(vector2_in)); compiler.add_node(NODE_VECTOR_MATH, @@ -4207,7 +4217,7 @@ void VectorMathNode::compile(SVMCompiler& compiler) void VectorMathNode::compile(OSLCompiler& compiler) { - compiler.parameter("type", type); + compiler.parameter("type", type_enum[type]); compiler.add(this, "node_vector_math"); } @@ -4216,17 +4226,17 @@ void VectorMathNode::compile(OSLCompiler& compiler) VectorTransformNode::VectorTransformNode() : ShaderNode("vector_transform") { - type = ustring("Vector"); - convert_from = ustring("world"); - convert_to = ustring("object"); + type = NODE_VECTOR_TRANSFORM_TYPE_VECTOR; + convert_from = NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD; + convert_to = NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT; - add_input("Vector", SHADER_SOCKET_VECTOR); - add_output("Vector", SHADER_SOCKET_VECTOR); + add_input("Vector", SocketType::VECTOR); + add_output("Vector", SocketType::VECTOR); } -static ShaderEnum vector_transform_type_init() +static NodeEnum vector_transform_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR); enm.insert("Point", NODE_VECTOR_TRANSFORM_TYPE_POINT); @@ -4235,9 +4245,9 @@ static ShaderEnum vector_transform_type_init() return enm; } -static ShaderEnum vector_transform_convert_space_init() +static NodeEnum vector_transform_convert_space_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("world", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD); enm.insert("object", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT); @@ -4246,8 +4256,8 @@ static ShaderEnum vector_transform_convert_space_init() return enm; } -ShaderEnum VectorTransformNode::type_enum = vector_transform_type_init(); -ShaderEnum VectorTransformNode::convert_space_enum = vector_transform_convert_space_init(); +NodeEnum VectorTransformNode::type_enum = vector_transform_type_init(); +NodeEnum VectorTransformNode::convert_space_enum = vector_transform_convert_space_init(); void VectorTransformNode::compile(SVMCompiler& compiler) { @@ -4255,18 +4265,16 @@ void VectorTransformNode::compile(SVMCompiler& compiler) ShaderOutput *vector_out = output("Vector"); compiler.add_node(NODE_VECTOR_TRANSFORM, - compiler.encode_uchar4(type_enum[type], - convert_space_enum[convert_from], - convert_space_enum[convert_to]), + compiler.encode_uchar4(type, convert_from, convert_to), compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out))); } void VectorTransformNode::compile(OSLCompiler& compiler) { - compiler.parameter("type", type); - compiler.parameter("convert_from", convert_from); - compiler.parameter("convert_to", convert_to); + compiler.parameter("type", type_enum[type]); + compiler.parameter("convert_from", convert_space_enum[convert_from]); + compiler.parameter("convert_to", convert_space_enum[convert_to]); compiler.add(this, "node_vector_transform"); } @@ -4281,16 +4289,16 @@ BumpNode::BumpNode() /* this input is used by the user, but after graph transform it is no longer * used and moved to sampler center/x/y instead */ - add_input("Height", SHADER_SOCKET_FLOAT); + add_input("Height", SocketType::FLOAT); - add_input("SampleCenter", SHADER_SOCKET_FLOAT); - add_input("SampleX", SHADER_SOCKET_FLOAT); - add_input("SampleY", SHADER_SOCKET_FLOAT); - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); - add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Distance", SHADER_SOCKET_FLOAT, 0.1f); + add_input("SampleCenter", SocketType::FLOAT); + add_input("SampleX", SocketType::FLOAT); + add_input("SampleY", SocketType::FLOAT); + add_input("Normal", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL); + add_input("Strength", SocketType::FLOAT, 1.0f); + add_input("Distance", SocketType::FLOAT, 0.1f); - add_output("Normal", SHADER_SOCKET_NORMAL); + add_output("Normal", SocketType::NORMAL); } void BumpNode::compile(SVMCompiler& compiler) @@ -4323,9 +4331,7 @@ void BumpNode::compile(OSLCompiler& compiler) compiler.add(this, "node_bump"); } -bool BumpNode::constant_fold(ShaderGraph *graph, - ShaderOutput * /*socket*/, - float3 * /*optimized_value*/) +bool BumpNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *) { ShaderInput *height_in = input("Height"); ShaderInput *normal_in = input("Normal"); @@ -4352,9 +4358,9 @@ bool BumpNode::constant_fold(ShaderGraph *graph, RGBCurvesNode::RGBCurvesNode() : ShaderNode("rgb_curves") { - add_input("Fac", SHADER_SOCKET_FLOAT); - add_input("Color", SHADER_SOCKET_COLOR); - add_output("Color", SHADER_SOCKET_COLOR); + add_input("Fac", SocketType::FLOAT); + add_input("Color", SocketType::COLOR); + add_output("Color", SocketType::COLOR); min_x = 0.0f; max_x = 1.0f; @@ -4397,9 +4403,9 @@ void RGBCurvesNode::compile(OSLCompiler& compiler) VectorCurvesNode::VectorCurvesNode() : ShaderNode("vector_curves") { - add_input("Fac", SHADER_SOCKET_FLOAT); - add_input("Vector", SHADER_SOCKET_VECTOR); - add_output("Vector", SHADER_SOCKET_VECTOR); + add_input("Fac", SocketType::FLOAT); + add_input("Vector", SocketType::VECTOR); + add_output("Vector", SocketType::VECTOR); min_x = 0.0f; max_x = 1.0f; @@ -4442,9 +4448,9 @@ void VectorCurvesNode::compile(OSLCompiler& compiler) RGBRampNode::RGBRampNode() : ShaderNode("rgb_ramp") { - add_input("Fac", SHADER_SOCKET_FLOAT); - add_output("Color", SHADER_SOCKET_COLOR); - add_output("Alpha", SHADER_SOCKET_FLOAT); + add_input("Fac", SocketType::FLOAT); + add_output("Color", SocketType::COLOR); + add_output("Alpha", SocketType::FLOAT); interpolate = true; } @@ -4477,7 +4483,7 @@ void RGBRampNode::compile(OSLCompiler& compiler) compiler.parameter_color_array("ramp_color", ramp); compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size()); - compiler.parameter("ramp_interpolate", interpolate); + compiler.parameter("interpolate", interpolate); compiler.add(this, "node_rgb_ramp"); } @@ -4487,8 +4493,8 @@ void RGBRampNode::compile(OSLCompiler& compiler) SetNormalNode::SetNormalNode() : ShaderNode("set_normal") { - add_input("Direction", SHADER_SOCKET_VECTOR); - add_output("Normal", SHADER_SOCKET_NORMAL); + add_input("Direction", SocketType::VECTOR); + add_output("Normal", SocketType::NORMAL); } void SetNormalNode::compile(SVMCompiler& compiler) @@ -4506,20 +4512,29 @@ void SetNormalNode::compile(OSLCompiler& compiler) compiler.add(this, "node_set_normal"); } -/* OSLScriptNode */ +/* OSLNode */ -OSLScriptNode::OSLScriptNode() -: ShaderNode("osl_script") +OSLNode::OSLNode() +: ShaderNode("osl_shader") { special_type = SHADER_SPECIAL_TYPE_SCRIPT; } -void OSLScriptNode::compile(SVMCompiler& /*compiler*/) +OSLNode::~OSLNode() +{ +} + +OSLNode* OSLNode::create(size_t) +{ + return new OSLNode(); +} + +void OSLNode::compile(SVMCompiler&) { /* doesn't work for SVM, obviously ... */ } -void OSLScriptNode::compile(OSLCompiler& compiler) +void OSLNode::compile(OSLCompiler& compiler) { if(!filepath.empty()) compiler.add(this, filepath.c_str(), true); @@ -4529,9 +4544,9 @@ void OSLScriptNode::compile(OSLCompiler& compiler) /* Normal Map */ -static ShaderEnum normal_map_space_init() +static NodeEnum normal_map_space_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Tangent", NODE_NORMAL_MAP_TANGENT); enm.insert("Object", NODE_NORMAL_MAP_OBJECT); @@ -4542,24 +4557,24 @@ static ShaderEnum normal_map_space_init() return enm; } -ShaderEnum NormalMapNode::space_enum = normal_map_space_init(); +NodeEnum NormalMapNode::space_enum = normal_map_space_init(); NormalMapNode::NormalMapNode() : ShaderNode("normal_map") { - space = ustring("Tangent"); + space = NODE_NORMAL_MAP_TANGENT; attribute = ustring(""); - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); - add_input("Color", SHADER_SOCKET_COLOR); + add_input("NormalIn", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_input("Strength", SocketType::FLOAT, 1.0f); + add_input("Color", SocketType::COLOR); - add_output("Normal", SHADER_SOCKET_NORMAL); + add_output("Normal", SocketType::NORMAL); } void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(shader->has_surface && space == ustring("Tangent")) { + if(shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) { if(attribute == ustring("")) { attributes->add(ATTR_STD_UV_TANGENT); attributes->add(ATTR_STD_UV_TANGENT_SIGN); @@ -4582,7 +4597,7 @@ void NormalMapNode::compile(SVMCompiler& compiler) ShaderOutput *normal_out = output("Normal"); int attr = 0, attr_sign = 0; - if(space == ustring("Tangent")) { + if(space == NODE_NORMAL_MAP_TANGENT) { if(attribute == ustring("")) { attr = compiler.attribute(ATTR_STD_UV_TANGENT); attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN); @@ -4598,13 +4613,13 @@ void NormalMapNode::compile(SVMCompiler& compiler) compiler.stack_assign(color_in), compiler.stack_assign(strength_in), compiler.stack_assign(normal_out), - space_enum[space]), + space), attr, attr_sign); } void NormalMapNode::compile(OSLCompiler& compiler) { - if(space == ustring("Tangent")) { + if(space == NODE_NORMAL_MAP_TANGENT) { if(attribute == ustring("")) { compiler.parameter("attr_name", ustring("geom:tangent")); compiler.parameter("attr_sign_name", ustring("geom:tangent_sign")); @@ -4615,16 +4630,16 @@ void NormalMapNode::compile(OSLCompiler& compiler) } } - compiler.parameter("space", space); + compiler.parameter("space", space_enum[space]); compiler.add(this, "node_normal_map"); } /* Tangent */ -static ShaderEnum tangent_direction_type_init() +static NodeEnum tangent_direction_type_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("Radial", NODE_TANGENT_RADIAL); enm.insert("UV Map", NODE_TANGENT_UVMAP); @@ -4632,9 +4647,9 @@ static ShaderEnum tangent_direction_type_init() return enm; } -static ShaderEnum tangent_axis_init() +static NodeEnum tangent_axis_init() { - ShaderEnum enm; + NodeEnum enm; enm.insert("X", NODE_TANGENT_AXIS_X); enm.insert("Y", NODE_TANGENT_AXIS_Y); @@ -4643,24 +4658,24 @@ static ShaderEnum tangent_axis_init() return enm; } -ShaderEnum TangentNode::direction_type_enum = tangent_direction_type_init(); -ShaderEnum TangentNode::axis_enum = tangent_axis_init(); +NodeEnum TangentNode::direction_type_enum = tangent_direction_type_init(); +NodeEnum TangentNode::axis_enum = tangent_axis_init(); TangentNode::TangentNode() : ShaderNode("tangent") { - direction_type = ustring("Radial"); - axis = ustring("X"); + direction_type = NODE_TANGENT_RADIAL; + axis = NODE_TANGENT_AXIS_X; attribute = ustring(""); - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); - add_output("Tangent", SHADER_SOCKET_NORMAL); + add_input("NormalIn", SocketType::NORMAL, make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); + add_output("Tangent", SocketType::NORMAL); } void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes) { if(shader->has_surface) { - if(direction_type == ustring("UV Map")) { + if(direction_type == NODE_TANGENT_UVMAP) { if(attribute == ustring("")) attributes->add(ATTR_STD_UV_TANGENT); else @@ -4678,7 +4693,7 @@ void TangentNode::compile(SVMCompiler& compiler) ShaderOutput *tangent_out = output("Tangent"); int attr; - if(direction_type == ustring("UV Map")) { + if(direction_type == NODE_TANGENT_UVMAP) { if(attribute == ustring("")) attr = compiler.attribute(ATTR_STD_UV_TANGENT); else @@ -4690,21 +4705,21 @@ void TangentNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_TANGENT, compiler.encode_uchar4( compiler.stack_assign(tangent_out), - direction_type_enum[direction_type], - axis_enum[axis]), attr); + direction_type, + axis), attr); } void TangentNode::compile(OSLCompiler& compiler) { - if(direction_type == ustring("UV Map")) { + if(direction_type == NODE_TANGENT_UVMAP) { if(attribute == ustring("")) compiler.parameter("attr_name", ustring("geom:tangent")); else compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str())); } - compiler.parameter("direction_type", direction_type); - compiler.parameter("axis", axis); + compiler.parameter("direction_type", direction_type_enum[direction_type]); + compiler.parameter("axis", axis_enum[axis]); compiler.add(this, "node_tangent"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 40fda070ec4..8b17e455f7a 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -49,15 +49,15 @@ public: enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 }; Type type; - static ShaderEnum type_enum; + static NodeEnum type_enum; enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 }; Mapping x_mapping, y_mapping, z_mapping; - static ShaderEnum mapping_enum; + static NodeEnum mapping_enum; enum Projection { FLAT, CUBE, TUBE, SPHERE }; Projection projection; - static ShaderEnum projection_enum; + static NodeEnum projection_enum; bool equals(const TextureMapping& other) { return translation == other.translation && @@ -109,15 +109,15 @@ public: bool use_alpha; string filename; void *builtin_data; - ustring color_space; - ustring projection; + NodeImageColorSpace color_space; + NodeImageProjection projection; InterpolationType interpolation; ExtensionType extension; float projection_blend; bool animated; - static ShaderEnum color_space_enum; - static ShaderEnum projection_enum; + static NodeEnum color_space_enum; + static NodeEnum projection_enum; virtual bool equals(const ShaderNode *other) { const ImageTextureNode *image_node = (const ImageTextureNode*)other; @@ -148,13 +148,13 @@ public: bool use_alpha; string filename; void *builtin_data; - ustring color_space; - ustring projection; + NodeImageColorSpace color_space; + NodeEnvironmentProjection projection; InterpolationType interpolation; bool animated; - static ShaderEnum color_space_enum; - static ShaderEnum projection_enum; + static NodeEnum color_space_enum; + static NodeEnum projection_enum; virtual bool equals(const ShaderNode *other) { const EnvironmentTextureNode *env_node = (const EnvironmentTextureNode*)other; @@ -175,12 +175,12 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_2; } + NodeSkyType type; float3 sun_direction; float turbidity; float ground_albedo; - ustring type; - static ShaderEnum type_enum; + static NodeEnum type_enum; virtual bool equals(const ShaderNode *other) { const SkyTextureNode *sky_node = (const SkyTextureNode*)other; @@ -206,8 +206,8 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_2; } - ustring type; - static ShaderEnum type_enum; + NodeGradientType type; + static NodeEnum type_enum; virtual bool equals(const ShaderNode *other) { const GradientTextureNode *gradient_node = (const GradientTextureNode*)other; @@ -227,9 +227,8 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_2; } - ustring coloring; - - static ShaderEnum coloring_enum; + NodeVoronoiColoring coloring; + static NodeEnum coloring_enum; virtual bool equals(const ShaderNode *other) { const VoronoiTextureNode *voronoi_node = (const VoronoiTextureNode*)other; @@ -244,9 +243,8 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_2; } - ustring type; - - static ShaderEnum type_enum; + NodeMusgraveType type; + static NodeEnum type_enum; virtual bool equals(const ShaderNode *other) { const MusgraveTextureNode *musgrave_node = (const MusgraveTextureNode*)other; @@ -261,10 +259,10 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_2; } - ustring type; - ustring profile; - static ShaderEnum type_enum; - static ShaderEnum profile_enum; + NodeWaveType type; + NodeWaveProfile profile; + static NodeEnum type_enum; + static NodeEnum profile_enum; virtual bool equals(const ShaderNode *other) { const WaveTextureNode *wave_node = (const WaveTextureNode*)other; @@ -329,13 +327,13 @@ public: ImageManager *image_manager; int slot; string filename; - ustring space; + NodeTexVoxelSpace space; void *builtin_data; InterpolationType interpolation; Transform tfm; - static ShaderEnum space_enum; + static NodeEnum space_enum; virtual bool equals(const ShaderNode *other) { const PointDensityTextureNode *point_dendity_node = (const PointDensityTextureNode*)other; @@ -362,14 +360,21 @@ public: } }; +class RGBToBWNode : public ShaderNode { +public: + SHADER_NODE_CLASS(RGBToBWNode) + + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); +}; + class ConvertNode : public ShaderNode { public: - ConvertNode(ShaderSocketType from, ShaderSocketType to, bool autoconvert = false); + ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false); SHADER_NODE_BASE_CLASS(ConvertNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); - ShaderSocketType from, to; + SocketType::Type from, to; virtual bool equals(const ShaderNode *other) { @@ -387,6 +392,7 @@ public: bool has_spatial_varying() { return true; } void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL); + virtual ClosureType get_closure_type() { return closure; } ClosureType closure; bool scattering; @@ -402,8 +408,8 @@ class AnisotropicBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(AnisotropicBsdfNode) - ustring distribution; - static ShaderEnum distribution_enum; + ClosureType distribution; + static NodeEnum distribution_enum; void attributes(Shader *shader, AttributeRequestSet *attributes); }; @@ -437,8 +443,8 @@ public: void simplify_settings(Scene *scene); bool has_integrator_dependency(); - ustring distribution, distribution_orig; - static ShaderEnum distribution_enum; + ClosureType distribution, distribution_orig; + static NodeEnum distribution_enum; }; class GlassBsdfNode : public BsdfNode { @@ -448,8 +454,8 @@ public: void simplify_settings(Scene *scene); bool has_integrator_dependency(); - ustring distribution, distribution_orig; - static ShaderEnum distribution_enum; + ClosureType distribution, distribution_orig; + static NodeEnum distribution_enum; }; class RefractionBsdfNode : public BsdfNode { @@ -459,16 +465,16 @@ public: void simplify_settings(Scene *scene); bool has_integrator_dependency(); - ustring distribution, distribution_orig; - static ShaderEnum distribution_enum; + ClosureType distribution, distribution_orig; + static NodeEnum distribution_enum; }; class ToonBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(ToonBsdfNode) - ustring component; - static ShaderEnum component_enum; + ClosureType component; + static NodeEnum component_enum; }; class SubsurfaceScatteringNode : public BsdfNode { @@ -477,13 +483,15 @@ public: bool has_surface_bssrdf() { return true; } bool has_bssrdf_bump(); - static ShaderEnum falloff_enum; + ClosureType falloff; + static NodeEnum falloff_enum; }; class EmissionNode : public ShaderNode { public: SHADER_NODE_CLASS(EmissionNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; } bool has_surface_emission() { return true; } }; @@ -491,13 +499,15 @@ public: class BackgroundNode : public ShaderNode { public: SHADER_NODE_CLASS(BackgroundNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + virtual ClosureType get_closure_type() { return CLOSURE_BACKGROUND_ID; } }; class HoldoutNode : public ShaderNode { public: SHADER_NODE_CLASS(HoldoutNode) virtual int get_group() { return NODE_GROUP_LEVEL_1; } + virtual ClosureType get_closure_type() { return CLOSURE_HOLDOUT_ID; } }; class AmbientOcclusionNode : public ShaderNode { @@ -506,6 +516,7 @@ public: bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_1; } + virtual ClosureType get_closure_type() { return CLOSURE_AMBIENT_OCCLUSION_ID; } }; class VolumeNode : public ShaderNode { @@ -514,6 +525,10 @@ public: void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2); virtual int get_group() { return NODE_GROUP_LEVEL_1; } + virtual int get_feature() { + return ShaderNode::get_feature() | NODE_FEATURE_VOLUME; + } + virtual ClosureType get_closure_type() { return closure; } ClosureType closure; @@ -538,8 +553,8 @@ class HairBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(HairBsdfNode) - ustring component; - static ShaderEnum component_enum; + ClosureType component; + static NodeEnum component_enum; }; @@ -630,7 +645,7 @@ class ValueNode : public ShaderNode { public: SHADER_NODE_CLASS(ValueNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); float value; @@ -645,7 +660,7 @@ class ColorNode : public ShaderNode { public: SHADER_NODE_CLASS(ColorNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); float3 value; @@ -664,7 +679,7 @@ public: class MixClosureNode : public ShaderNode { public: SHADER_NODE_CLASS(MixClosureNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); }; class MixClosureWeightNode : public ShaderNode { @@ -682,14 +697,14 @@ public: class MixNode : public ShaderNode { public: SHADER_NODE_CLASS(MixNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); virtual int get_group() { return NODE_GROUP_LEVEL_3; } bool use_clamp; - ustring type; - static ShaderEnum type_enum; + NodeMix type; + static NodeEnum type_enum; virtual bool equals(const ShaderNode *other) { @@ -725,7 +740,7 @@ class GammaNode : public ShaderNode { public: SHADER_NODE_CLASS(GammaNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); virtual int get_group() { return NODE_GROUP_LEVEL_1; } }; @@ -816,7 +831,7 @@ public: class BlackbodyNode : public ShaderNode { public: SHADER_NODE_CLASS(BlackbodyNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); virtual int get_group() { return NODE_GROUP_LEVEL_3; } }; @@ -825,12 +840,12 @@ class MathNode : public ShaderNode { public: SHADER_NODE_CLASS(MathNode) virtual int get_group() { return NODE_GROUP_LEVEL_1; } - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); bool use_clamp; - ustring type; - static ShaderEnum type_enum; + NodeMath type; + static NodeEnum type_enum; virtual bool equals(const ShaderNode *other) { @@ -860,14 +875,14 @@ class VectorMathNode : public ShaderNode { public: SHADER_NODE_CLASS(VectorMathNode) virtual int get_group() { return NODE_GROUP_LEVEL_1; } - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); - ustring type; - static ShaderEnum type_enum; + NodeVectorMath type; + static NodeEnum type_enum; virtual bool equals(const ShaderNode *other) { - const MathNode *math_node = (const MathNode*)other; + const VectorMathNode *math_node = (const VectorMathNode*)other; return ShaderNode::equals(other) && type == math_node->type; } @@ -879,12 +894,12 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_3; } - ustring type; - ustring convert_from; - ustring convert_to; + NodeVectorTransformType type; + NodeVectorTransformConvertSpace convert_from; + NodeVectorTransformConvertSpace convert_to; - static ShaderEnum type_enum; - static ShaderEnum convert_space_enum; + static NodeEnum type_enum; + static NodeEnum convert_space_enum; virtual bool equals(const ShaderNode *other) { const VectorTransformNode *vector_transform_node = (const VectorTransformNode*)other; @@ -898,7 +913,7 @@ public: class BumpNode : public ShaderNode { public: SHADER_NODE_CLASS(BumpNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value); + bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); bool has_spatial_varying() { return true; } virtual int get_feature() { return NODE_FEATURE_BUMP; @@ -950,17 +965,22 @@ public: SHADER_NODE_CLASS(SetNormalNode) }; -class OSLScriptNode : public ShaderNode { +class OSLNode : public ShaderNode { public: - SHADER_NODE_CLASS(OSLScriptNode) + static OSLNode *create(size_t num_inputs); + ~OSLNode(); + + SHADER_NODE_BASE_CLASS(OSLNode) /* ideally we could beter detect this, but we can't query this now */ bool has_spatial_varying() { return true; } + virtual bool equals(const ShaderNode * /*other*/) { return false; } string filepath; string bytecode_hash; - virtual bool equals(const ShaderNode * /*other*/) { return false; } +private: + OSLNode(); }; class NormalMapNode : public ShaderNode { @@ -970,8 +990,8 @@ public: bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_3; } - ustring space; - static ShaderEnum space_enum; + NodeNormalMapSpace space; + static NodeEnum space_enum; ustring attribute; @@ -991,11 +1011,10 @@ public: bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_3; } - ustring direction_type; - static ShaderEnum direction_type_enum; - - ustring axis; - static ShaderEnum axis_enum; + NodeTangentDirectionType direction_type; + NodeTangentAxis axis; + static NodeEnum direction_type_enum; + static NodeEnum axis_enum; ustring attribute; diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index e2fe0bd72a1..644e581bf4b 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -33,14 +33,25 @@ CCL_NAMESPACE_BEGIN /* Object */ +NODE_DEFINE(Object) +{ + NodeType* type = NodeType::add("object", create); + + SOCKET_NODE(mesh, "Mesh", &Mesh::node_type); + SOCKET_TRANSFORM(tfm, "Transform", transform_identity()); + SOCKET_INT(visibility, "Visibility", ~0); + SOCKET_INT(random_id, "Random ID", 0); + SOCKET_INT(pass_id, "Pass ID", 0); + SOCKET_BOOLEAN(use_holdout, "Use Holdout", false); + SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f)); + SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f)); + + return type; +} + Object::Object() +: Node(node_type) { - name = ""; - mesh = NULL; - tfm = transform_identity(); - visibility = ~0; - random_id = 0; - pass_id = 0; particle_system = NULL; particle_index = 0; bounds = BoundBox::empty; @@ -48,9 +59,6 @@ Object::Object() motion.mid = transform_identity(); motion.post = transform_identity(); use_motion = false; - use_holdout = false; - dupli_generated = make_float3(0.0f, 0.0f, 0.0f); - dupli_uv = make_float2(0.0f, 0.0f); } Object::~Object() @@ -137,12 +145,12 @@ void Object::apply_transform(bool apply_to_motion) /* apply transform to curve keys */ for(size_t i = 0; i < mesh->curve_keys.size(); i++) { - float3 co = transform_point(&tfm, float4_to_float3(mesh->curve_keys[i])); - float radius = mesh->curve_keys[i].w * scalar; + float3 co = transform_point(&tfm, mesh->curve_keys[i]); + float radius = mesh->curve_radius[i] * scalar; /* scale for curve radius is only correct for uniform scale */ - mesh->curve_keys[i] = float3_to_float4(co); - mesh->curve_keys[i].w = radius; + mesh->curve_keys[i] = co; + mesh->curve_radius[i] = radius; } if(apply_to_motion) { @@ -217,6 +225,16 @@ vector<float> Object::motion_times() return times; } +bool Object::is_traceable() +{ + /* Mesh itself can be empty,can skip all such objects. */ + if (bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) { + return false; + } + /* TODO(sergey): Check for mesh vertices/curves. visibility flags. */ + return true; +} + /* Object Manager */ ObjectManager::ObjectManager() @@ -269,7 +287,9 @@ void ObjectManager::device_update_object_transform(UpdateObejctTransformState *s state->surface_area_lock.unlock(); if(it == state->surface_area_map.end()) { - foreach(Mesh::Triangle& t, mesh->triangles) { + 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]]; @@ -288,7 +308,9 @@ void ObjectManager::device_update_object_transform(UpdateObejctTransformState *s surface_area *= uniform_scale; } else { - foreach(Mesh::Triangle& t, mesh->triangles) { + 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]]); @@ -360,7 +382,7 @@ void ObjectManager::device_update_object_transform(UpdateObejctTransformState *s state->object_flag[object_index] = flag; /* Have curves. */ - if(mesh->curves.size()) { + if(mesh->num_curves()) { state->have_curves = true; } } diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index c2a79ca8dc4..7ab73f3c91a 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -17,6 +17,7 @@ #ifndef __OBJECT_H__ #define __OBJECT_H__ +#include "node.h" #include "scene.h" #include "util_boundbox.h" @@ -37,12 +38,13 @@ struct Transform; /* Object */ -class Object { +class Object : public Node { public: + NODE_DECLARE; + Mesh *mesh; Transform tfm; BoundBox bounds; - ustring name; uint random_id; int pass_id; vector<ParamValue> attributes; @@ -66,6 +68,11 @@ public: void apply_transform(bool apply_to_motion); vector<float> motion_times(); + + /* Check whether object is traceable and it worth adding it to + * kernel scene. + */ + bool is_traceable(); }; /* Object Manager */ diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 3d14965b4ca..1cfe3fb38e2 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -394,16 +394,143 @@ const char *OSLShaderManager::shader_load_bytecode(const string& hash, const str { ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str()); - /* this is a bit weak, but works */ OSLShaderInfo info; + + if(!info.query.open_bytecode(bytecode)) { + fprintf(stderr, "OSL query error: %s\n", info.query.geterror().c_str()); + } + + /* this is a bit weak, but works */ info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos); info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos); info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos); + loaded_shaders[hash] = info; return loaded_shaders.find(hash)->first.c_str(); } +OSLNode *OSLShaderManager::osl_node(const std::string& filepath, + const std::string& bytecode_hash, + const std::string& bytecode) +{ + /* create query */ + const char *hash; + + if(!filepath.empty()) { + hash = shader_load_filepath(filepath); + } + else { + hash = shader_test_loaded(bytecode_hash); + if(!hash) + hash = shader_load_bytecode(bytecode_hash, bytecode); + } + + if(!hash) { + return NULL; + } + + OSLShaderInfo *info = shader_loaded_info(hash); + + /* count number of inputs */ + size_t num_inputs = 0; + + for(int i = 0; i < info->query.nparams(); i++) { + const OSL::OSLQuery::Parameter *param = info->query.getparam(i); + + /* skip unsupported types */ + if(param->varlenarray || param->isstruct || param->type.arraylen > 1) + continue; + + if(!param->isoutput) + num_inputs++; + } + + /* create node */ + OSLNode *node = OSLNode::create(num_inputs); + + /* add new sockets from parameters */ + set<void*> used_sockets; + + for(int i = 0; i < info->query.nparams(); i++) { + const OSL::OSLQuery::Parameter *param = info->query.getparam(i); + + /* skip unsupported types */ + if(param->varlenarray || param->isstruct || param->type.arraylen > 1) + continue; + + SocketType::Type socket_type; + + if(param->isclosure) { + socket_type = SocketType::CLOSURE; + } + else if(param->type.vecsemantics != TypeDesc::NOSEMANTICS) { + if(param->type.vecsemantics == TypeDesc::COLOR) + socket_type = SocketType::COLOR; + else if(param->type.vecsemantics == TypeDesc::POINT) + socket_type = SocketType::POINT; + else if(param->type.vecsemantics == TypeDesc::VECTOR) + socket_type = SocketType::VECTOR; + else if(param->type.vecsemantics == TypeDesc::NORMAL) + socket_type = SocketType::NORMAL; + else + continue; + + if(!param->isoutput && param->validdefault) { + node->add_input(param->name.c_str(), socket_type, make_float3(param->fdefault[0], param->fdefault[1], param->fdefault[2])); + continue; + } + } + else if(param->type.aggregate == TypeDesc::SCALAR) { + if(param->type.basetype == TypeDesc::INT) { + socket_type = SocketType::INT; + + if(!param->isoutput && param->validdefault) { + node->add_input(param->name.c_str(), socket_type, (float)param->idefault[0]); + continue; + } + } + else if(param->type.basetype == TypeDesc::FLOAT) { + socket_type = SocketType::FLOAT; + + if(!param->isoutput && param->validdefault) { + node->add_input(param->name.c_str(), socket_type, param->fdefault[0]); + continue; + } + } + else if(param->type.basetype == TypeDesc::STRING) { + socket_type = SocketType::STRING; + + if(!param->isoutput && param->validdefault) { + node->add_input(param->name.c_str(), socket_type); + continue; + } + } + else + continue; + } + else + continue; + + if(param->isoutput) { + node->add_output(param->name.c_str(), socket_type); + } + else { + node->add_input(param->name.c_str(), socket_type); + } + } + + /* set bytcode hash or filepath */ + if(!bytecode_hash.empty()) { + node->bytecode_hash = bytecode_hash; + } + else { + node->filepath = filepath; + } + + return node; +} + /* Graph Compiler */ OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_, ImageManager *image_manager_) @@ -427,7 +554,7 @@ string OSLCompiler::id(ShaderNode *node) string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input) { - string sname(input->name); + string sname(input->name().string()); size_t i; /* strip whitespace */ @@ -436,7 +563,7 @@ string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input) /* if output exists with the same name, add "In" suffix */ foreach(ShaderOutput *output, node->outputs) { - if(strcmp(input->name, output->name)==0) { + if(input->name() == output->name()) { sname += "In"; break; } @@ -447,7 +574,7 @@ string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input) string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output) { - string sname(output->name); + string sname(output->name().string()); size_t i; /* strip whitespace */ @@ -456,7 +583,7 @@ string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output) /* if input exists with the same name, add "Out" suffix */ foreach(ShaderInput *input, node->inputs) { - if(strcmp(input->name, output->name)==0) { + if(input->name() == output->name()) { sname += "Out"; break; } @@ -470,21 +597,21 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) /* exception for output node, only one input is actually used * depending on the current shader type */ - if(!(input->usage & ShaderInput::USE_OSL)) + if(input->flags() & SocketType::SVM_INTERNAL) return true; if(node->special_type == SHADER_SPECIAL_TYPE_OUTPUT) { - if(strcmp(input->name, "Surface") == 0 && current_type != SHADER_TYPE_SURFACE) + if(input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE) return true; - if(strcmp(input->name, "Volume") == 0 && current_type != SHADER_TYPE_VOLUME) + if(input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME) return true; - if(strcmp(input->name, "Displacement") == 0 && current_type != SHADER_TYPE_DISPLACEMENT) + if(input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT) return true; - if(strcmp(input->name, "Normal") == 0) + if(input->name() == "Normal") return true; } else if(node->special_type == SHADER_SPECIAL_TYPE_BUMP) { - if(strcmp(input->name, "Height") == 0) + if(input->name() == "Height") return true; } else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->special_type == SHADER_SPECIAL_TYPE_BUMP) @@ -512,34 +639,35 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) if(node_skip_input(node, input)) continue; /* already has default value assigned */ - else if(input->default_value != ShaderInput::NONE) + else if(input->flags() & SocketType::DEFAULT_LINK_MASK) continue; string param_name = compatible_name(node, input); - switch(input->type) { - case SHADER_SOCKET_COLOR: - parameter_color(param_name.c_str(), input->value); + switch(input->type()) { + case SocketType::COLOR: + parameter_color(param_name.c_str(), input->value()); break; - case SHADER_SOCKET_POINT: - parameter_point(param_name.c_str(), input->value); + case SocketType::POINT: + parameter_point(param_name.c_str(), input->value()); break; - case SHADER_SOCKET_VECTOR: - parameter_vector(param_name.c_str(), input->value); + case SocketType::VECTOR: + parameter_vector(param_name.c_str(), input->value()); break; - case SHADER_SOCKET_NORMAL: - parameter_normal(param_name.c_str(), input->value); + case SocketType::NORMAL: + parameter_normal(param_name.c_str(), input->value()); break; - case SHADER_SOCKET_FLOAT: - parameter(param_name.c_str(), input->value.x); + case SocketType::FLOAT: + parameter(param_name.c_str(), input->value_float()); break; - case SHADER_SOCKET_INT: - parameter(param_name.c_str(), (int)input->value.x); + case SocketType::INT: + parameter(param_name.c_str(), (int)input->value_float()); break; - case SHADER_SOCKET_STRING: - parameter(param_name.c_str(), input->value_string); + case SocketType::STRING: + parameter(param_name.c_str(), input->value_string()); break; - case SHADER_SOCKET_CLOSURE: - case SHADER_SOCKET_UNDEFINED: + case SocketType::CLOSURE: + case SocketType::UNDEFINED: + default: break; } } diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h index 110897ff300..13b9d6307f9 100644 --- a/intern/cycles/render/osl.h +++ b/intern/cycles/render/osl.h @@ -22,6 +22,7 @@ #include "util_thread.h" #include "graph.h" +#include "nodes.h" #include "shader.h" #ifdef WITH_OSL @@ -54,6 +55,7 @@ struct OSLShaderInfo { has_surface_bssrdf(false) {} + OSL::OSLQuery query; bool has_surface_emission; bool has_surface_transparent; bool has_surface_bssrdf; @@ -83,6 +85,11 @@ public: const char *shader_load_filepath(string filepath); OSLShaderInfo *shader_loaded_info(const string& hash); + /* create OSL node using OSLQuery */ + OSLNode *osl_node(const std::string& filepath, + const std::string& bytecode_hash = "", + const std::string& bytecode = ""); + protected: void texture_system_init(); void texture_system_free(); diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp index 50726bb4574..1a35d60fb4b 100644 --- a/intern/cycles/render/particles.cpp +++ b/intern/cycles/render/particles.cpp @@ -58,8 +58,8 @@ void ParticleSystemManager::device_update_particles(Device *device, DeviceScene * adds one dummy particle at the beginning to avoid invalid lookups, * in case a shader uses particle info without actual particle data. */ int num_particles = 1; - foreach(ParticleSystem *psys, scene->particle_systems) - num_particles += psys->particles.size(); + for(size_t j = 0; j < scene->particle_systems.size(); j++) + num_particles += scene->particle_systems[j]->particles.size(); float4 *particles = dscene->particles.resize(PARTICLE_SIZE*num_particles); @@ -71,9 +71,12 @@ void ParticleSystemManager::device_update_particles(Device *device, DeviceScene particles[4] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); int i = 1; - foreach(ParticleSystem *psys, scene->particle_systems) { - foreach(Particle &pa, psys->particles) { + for(size_t j = 0; j < scene->particle_systems.size(); j++) { + ParticleSystem *psys = scene->particle_systems[j]; + + for(size_t k = 0; k < psys->particles.size(); k++) { /* pack in texture */ + Particle& pa = psys->particles[k]; int offset = i*PARTICLE_SIZE; particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size); diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h index bf2b6b77015..2509e27b44b 100644 --- a/intern/cycles/render/particles.h +++ b/intern/cycles/render/particles.h @@ -47,7 +47,7 @@ public: void tag_update(Scene *scene); - vector<Particle> particles; + array<Particle> particles; }; /* ParticleSystem Manager */ diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index b0052c30af4..e8367e1eb36 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -242,9 +242,14 @@ void Scene::device_update(Device *device_, Progress& progress) } if(print_stats) { + size_t mem_used = util_guarded_get_mem_used(); + size_t mem_peak = util_guarded_get_mem_peak(); + VLOG(1) << "System memory statistics after full device sync:\n" - << " Usage: " << util_guarded_get_mem_used() << "\n" - << " Peak: " << util_guarded_get_mem_peak(); + << " Usage: " << string_human_readable_number(mem_used) + << " (" << string_human_readable_size(mem_used) << ")\n" + << " Peak: " << string_human_readable_number(mem_peak) + << " (" << string_human_readable_size(mem_peak) << ")"; } } diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 33c03d40f27..b34d6127118 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -109,10 +109,10 @@ public: device_vector<uint> sobol_directions; /* cpu images */ - device_vector<uchar4> tex_byte4_image[TEX_NUM_BYTE4_IMAGES_CPU]; - device_vector<float4> tex_float4_image[TEX_NUM_FLOAT4_IMAGES_CPU]; - device_vector<float> tex_float_image[TEX_NUM_FLOAT_IMAGES_CPU]; - device_vector<uchar> tex_byte_image[TEX_NUM_BYTE_IMAGES_CPU]; + device_vector<uchar4> tex_byte4_image[TEX_NUM_BYTE4_CPU]; + device_vector<float4> tex_float4_image[TEX_NUM_FLOAT4_CPU]; + device_vector<float> tex_float_image[TEX_NUM_FLOAT_CPU]; + device_vector<uchar> tex_byte_image[TEX_NUM_BYTE_CPU]; /* opencl images */ device_vector<uchar4> tex_image_byte4_packed; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 63037311889..1cd76ff2b39 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -610,17 +610,17 @@ DeviceRequestedFeatures Session::get_requested_device_features() /* TODO(sergey): Consider moving this to the Scene level. */ DeviceRequestedFeatures requested_features; requested_features.experimental = params.experimental; + + requested_features.max_closure = get_max_closure_count(); + scene->shader_manager->get_requested_features( + scene, + &requested_features); if(!params.background) { + /* Avoid too much re-compilations for viewport render. */ requested_features.max_closure = 64; requested_features.max_nodes_group = NODE_GROUP_LEVEL_MAX; requested_features.nodes_features = NODE_FEATURE_ALL; } - else { - requested_features.max_closure = get_max_closure_count(); - scene->shader_manager->get_requested_features( - scene, - &requested_features); - } /* This features are not being tweaked as often as shaders, * so could be done selective magic for the viewport as well. @@ -630,7 +630,7 @@ DeviceRequestedFeatures Session::get_requested_device_features() requested_features.use_camera_motion = scene->camera->use_motion; foreach(Object *object, scene->objects) { Mesh *mesh = object->mesh; - if(mesh->curves.size() > 0) { + if(mesh->num_curves()) { requested_features.use_hair = true; } requested_features.use_object_motion |= object->use_motion | mesh->use_motion_blur; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 635024d7bdf..708eeef3b50 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -456,7 +456,7 @@ void ShaderManager::add_default(Scene *scene) ShaderGraph *graph = new ShaderGraph(); closure = graph->add(new DiffuseBsdfNode()); - closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f); + closure->input("Color")->set(make_float3(0.8f, 0.8f, 0.8f)); out = graph->output(); graph->connect(closure->output("BSDF"), out->input("Surface")); @@ -473,8 +473,8 @@ void ShaderManager::add_default(Scene *scene) ShaderGraph *graph = new ShaderGraph(); closure = graph->add(new EmissionNode()); - closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f); - closure->input("Strength")->value.x = 0.0f; + closure->input("Color")->set(make_float3(0.8f, 0.8f, 0.8f)); + closure->input("Strength")->set(0.0f); out = graph->output(); graph->connect(closure->output("Emission"), out->input("Surface")); diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 4c97a5ad792..d54afd1ba6f 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -120,22 +120,22 @@ SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_man compile_failed = false; } -int SVMCompiler::stack_size(ShaderSocketType type) +int SVMCompiler::stack_size(SocketType::Type type) { int size = 0; switch(type) { - case SHADER_SOCKET_FLOAT: - case SHADER_SOCKET_INT: + case SocketType::FLOAT: + case SocketType::INT: size = 1; break; - case SHADER_SOCKET_COLOR: - case SHADER_SOCKET_VECTOR: - case SHADER_SOCKET_NORMAL: - case SHADER_SOCKET_POINT: + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::NORMAL: + case SocketType::POINT: size = 3; break; - case SHADER_SOCKET_CLOSURE: + case SocketType::CLOSURE: size = 0; break; default: @@ -146,7 +146,7 @@ int SVMCompiler::stack_size(ShaderSocketType type) return size; } -int SVMCompiler::stack_find_offset(ShaderSocketType type) +int SVMCompiler::stack_find_offset(SocketType::Type type) { int size = stack_size(type); int offset = -1; @@ -175,7 +175,7 @@ int SVMCompiler::stack_find_offset(ShaderSocketType type) return 0; } -void SVMCompiler::stack_clear_offset(ShaderSocketType type, int offset) +void SVMCompiler::stack_clear_offset(SocketType::Type type, int offset) { int size = stack_size(type); @@ -193,22 +193,22 @@ int SVMCompiler::stack_assign(ShaderInput *input) } else { /* not linked to output -> add nodes to load default value */ - input->stack_offset = stack_find_offset(input->type); + input->stack_offset = stack_find_offset(input->type()); - if(input->type == SHADER_SOCKET_FLOAT) { - add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset); + if(input->type() == SocketType::FLOAT) { + add_node(NODE_VALUE_F, __float_as_int(input->value_float()), input->stack_offset); } - else if(input->type == SHADER_SOCKET_INT) { - add_node(NODE_VALUE_F, (int)input->value.x, input->stack_offset); + else if(input->type() == SocketType::INT) { + add_node(NODE_VALUE_F, (int)input->value_float(), input->stack_offset); } - else if(input->type == SHADER_SOCKET_VECTOR || - input->type == SHADER_SOCKET_NORMAL || - input->type == SHADER_SOCKET_POINT || - input->type == SHADER_SOCKET_COLOR) + else if(input->type() == SocketType::VECTOR || + input->type() == SocketType::NORMAL || + input->type() == SocketType::POINT || + input->type() == SocketType::COLOR) { add_node(NODE_VALUE_V, input->stack_offset); - add_node(NODE_VALUE_V, input->value); + add_node(NODE_VALUE_V, input->value()); } else /* should not get called for closure */ assert(0); @@ -222,7 +222,7 @@ int SVMCompiler::stack_assign(ShaderOutput *output) { /* if no stack offset assigned yet, find one */ if(output->stack_offset == SVM_STACK_INVALID) - output->stack_offset = stack_find_offset(output->type); + output->stack_offset = stack_find_offset(output->type()); return output->stack_offset; } @@ -247,11 +247,11 @@ void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output) { if(output->stack_offset == SVM_STACK_INVALID) { assert(input->link); - assert(stack_size(output->type) == stack_size(input->link->type)); + assert(stack_size(output->type()) == stack_size(input->link->type())); output->stack_offset = input->link->stack_offset; - int size = stack_size(output->type); + int size = stack_size(output->type()); for(int i = 0; i < size; i++) active_stack.users[output->stack_offset + i]++; @@ -279,7 +279,7 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet& done) all_done = false; if(all_done) { - stack_clear_offset(output->type, output->stack_offset); + stack_clear_offset(output->type(), output->stack_offset); output->stack_offset = SVM_STACK_INVALID; foreach(ShaderInput *in, output->links) @@ -293,7 +293,7 @@ void SVMCompiler::stack_clear_temporary(ShaderNode *node) { foreach(ShaderInput *input, node->inputs) { if(!input->link && input->stack_offset != SVM_STACK_INVALID) { - stack_clear_offset(input->type, input->stack_offset); + stack_clear_offset(input->type(), input->stack_offset); input->stack_offset = SVM_STACK_INVALID; } } @@ -446,7 +446,7 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight"; ShaderInput *weight_in = node->input(weight_name); - if(weight_in && (weight_in->link || weight_in->value.x != 1.0f)) + if(weight_in && (weight_in->link || weight_in->value_float() != 1.0f)) mix_weight_offset = stack_assign(weight_in); else mix_weight_offset = SVM_STACK_INVALID; @@ -479,7 +479,7 @@ void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node, } else { foreach(ShaderInput *in, node->inputs) { - if(in->type == SHADER_SOCKET_CLOSURE && in->link) + if(in->type() == SocketType::CLOSURE && in->link) generated_shared_closure_nodes(root_node, in->link->parent, state, diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index dbf1b1de947..e14d57d7601 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -99,8 +99,8 @@ public: int stack_assign(ShaderInput *input); int stack_assign_if_linked(ShaderInput *input); int stack_assign_if_linked(ShaderOutput *output); - int stack_find_offset(ShaderSocketType type); - void stack_clear_offset(ShaderSocketType type, int offset); + int stack_find_offset(SocketType::Type type); + void stack_clear_offset(SocketType::Type type, int offset); void stack_link(ShaderInput *input, ShaderOutput *output); void add_node(ShaderNodeType type, int a = 0, int b = 0, int c = 0); @@ -172,7 +172,7 @@ protected: }; void stack_clear_temporary(ShaderNode *node); - int stack_size(ShaderSocketType type); + int stack_size(SocketType::Type type); void stack_clear_users(ShaderNode *node, ShaderNodeSet& done); bool node_skip_input(ShaderNode *node, ShaderInput *input); diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index a5dfcd21ceb..7c74f21950e 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -41,14 +41,14 @@ EdgeDice::EdgeDice(const SubdParams& params_) } } -void EdgeDice::reserve(int num_verts, int num_tris) +void EdgeDice::reserve(int num_verts) { Mesh *mesh = params.mesh; vert_offset = mesh->verts.size(); - tri_offset = mesh->triangles.size(); + tri_offset = mesh->num_triangles(); - mesh->reserve(vert_offset + num_verts, tri_offset + num_tris, 0, 0); + mesh->resize_mesh(vert_offset + num_verts, tri_offset); Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); @@ -69,7 +69,7 @@ int EdgeDice::add_vert(Patch *patch, float2 uv) if(params.ptex) { Attribute *attr_ptex_uv = params.mesh->attributes.add(ATTR_STD_PTEX_UV); - params.mesh->attributes.reserve(); + params.mesh->attributes.resize(); float3 *ptex_uv = attr_ptex_uv->data_float3(); ptex_uv[vert_offset] = make_float3(uv.x, uv.y, 0.0f); @@ -80,11 +80,17 @@ int EdgeDice::add_vert(Patch *patch, float2 uv) void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2) { - params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth, false); + Mesh *mesh = params.mesh; + + /* todo: optimize so we can reserve in advance, this is like push_back_slow() */ + if(mesh->triangles.size() == mesh->triangles.capacity()) + mesh->reserve_mesh(mesh->verts.size(), size_t(max(mesh->num_triangles() + 1, 1) * 1.2)); + + mesh->add_triangle(v0, v1, v2, params.shader, params.smooth, false); if(params.ptex) { Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID); - params.mesh->attributes.reserve(); + params.mesh->attributes.resize(); float *ptex_face_id = attr_ptex_face_id->data_float(); ptex_face_id[tri_offset] = (float)patch->ptex_face_id(); @@ -141,8 +147,7 @@ void QuadDice::reserve(EdgeFactors& ef, int Mu, int Mv) { /* XXX need to make this also work for edge factor 0 and 1 */ int num_verts = (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1) + (Mu - 1)*(Mv - 1); - int num_tris = 0; - EdgeDice::reserve(num_verts, num_tris); + EdgeDice::reserve(num_verts); } float2 QuadDice::map_uv(SubPatch& sub, float u, float v) @@ -352,7 +357,7 @@ void TriangleDice::reserve(EdgeFactors& ef, int M) if(!(M & 1)) num_verts++; - EdgeDice::reserve(num_verts, 0); + EdgeDice::reserve(num_verts); } float2 TriangleDice::map_uv(SubPatch& sub, float2 uv) diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h index 49f786e949e..85bd0ea28f0 100644 --- a/intern/cycles/subd/subd_dice.h +++ b/intern/cycles/subd/subd_dice.h @@ -72,7 +72,7 @@ public: explicit EdgeDice(const SubdParams& params); - void reserve(int num_verts, int num_tris); + void reserve(int num_verts); int add_vert(Patch *patch, float2 uv); void add_triangle(Patch *patch, int v0, int v1, int v2); diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index cceec8d444c..e6140b3ed09 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -19,8 +19,10 @@ set(SRC util_simd.cpp util_system.cpp util_task.cpp + util_thread.cpp util_time.cpp util_transform.cpp + util_windows.cpp ) if(NOT CYCLES_STANDALONE_REPOSITORY) diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 32924f9a8c2..53944ec1cc4 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1479,21 +1479,25 @@ ccl_device bool ray_triangle_intersect_uv( return true; } -ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, - float3 quad_P, float3 quad_u, float3 quad_v, +ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_mint, float ray_maxt, + float3 quad_P, float3 quad_u, float3 quad_v, float3 quad_n, float3 *isect_P, float *isect_t) { - float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; - float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; - float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f; - float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f; + float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n); + if(t < ray_mint || t > ray_maxt) + return false; - if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t)) - return true; - else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t)) - return true; - - return false; + float3 hit = ray_P + t*ray_D; + float3 inplane = hit - quad_P; + if(fabsf(dot(inplane, quad_u) / dot(quad_u, quad_u)) > 0.5f) + return false; + if(fabsf(dot(inplane, quad_v) / dot(quad_v, quad_v)) > 0.5f) + return false; + + if(isect_P) *isect_P = hit; + if(isect_t) *isect_t = t; + + return true; } /* projections */ diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp index b3a8c6d7c2e..e16a83d56d0 100644 --- a/intern/cycles/util/util_string.cpp +++ b/intern/cycles/util/util_string.cpp @@ -239,5 +239,45 @@ string string_to_ansi(const string& str) #endif /* _WIN32 */ +string string_human_readable_size(size_t size) +{ + static const char suffixes[] = "BKMGTPEZY"; + + const char* suffix = suffixes; + size_t r = 0; + + while(size >= 1024) { + r = size % 1024; + size /= 1024; + suffix++; + } + + if(*suffix != 'B') + return string_printf("%.2f%c", double(size*1024+r)/1024.0, *suffix); + else + return string_printf("%zu", size); +} + +string string_human_readable_number(size_t num) +{ + /* add thousands separators */ + char buf[32]; + + char* p = buf+31; + *p = '\0'; + + int i = -1; + while(num) { + if(++i && i % 3 == 0) + *(--p) = ','; + + *(--p) = '0' + (num % 10); + + num /= 10; + } + + return p; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h index c4b51bda432..d3b5248c380 100644 --- a/intern/cycles/util/util_string.h +++ b/intern/cycles/util/util_string.h @@ -62,6 +62,11 @@ string string_from_wstring(const wstring& path); string string_to_ansi(const string& str); #endif +/* Make a string from a size in bytes in human readable form */ +string string_human_readable_size(size_t size); +/* Make a string from a unitless quantity in human readable form */ +string string_human_readable_number(size_t num); + CCL_NAMESPACE_END #endif /* __UTIL_STRING_H__ */ diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index 4ff0ee91d73..d5fac9a0e34 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -15,7 +15,9 @@ */ #include "util_system.h" + #include "util_debug.h" +#include "util_logging.h" #include "util_types.h" #include "util_string.h" @@ -33,28 +35,56 @@ CCL_NAMESPACE_BEGIN -int system_cpu_thread_count() +int system_cpu_group_count() { - static uint count = 0; - - if(count > 0) - return count; +#ifdef _WIN32 + util_windows_init_numa_groups(); + return GetActiveProcessorGroupCount(); +#else + /* TODO(sergey): Need to adopt for other platforms. */ + return 1; +#endif +} +int system_cpu_group_thread_count(int group) +{ + /* TODO(sergey): Need make other platforms aware of groups. */ #ifdef _WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - count = (uint)info.dwNumberOfProcessors; + util_windows_init_numa_groups(); + return GetActiveProcessorCount(group); #elif defined(__APPLE__) + (void)group; + int count; size_t len = sizeof(count); int mib[2] = { CTL_HW, HW_NCPU }; - sysctl(mib, 2, &count, &len, NULL, 0); + return count; #else - count = (uint)sysconf(_SC_NPROCESSORS_ONLN); + (void)group; + return sysconf(_SC_NPROCESSORS_ONLN); #endif +} + +int system_cpu_thread_count() +{ + static uint count = 0; - if(count < 1) + if(count > 0) { + return count; + } + + int max_group = system_cpu_group_count(); + VLOG(1) << "Detected " << max_group << " CPU groups."; + for(int group = 0; group < max_group; ++group) { + int num_threads = system_cpu_group_thread_count(group); + VLOG(1) << "Group " << group + << " has " << num_threads << " threads."; + count += num_threads; + } + + if(count < 1) { count = 1; + } return count; } diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h index 4e7e00f85fd..557aab6cbae 100644 --- a/intern/cycles/util/util_system.h +++ b/intern/cycles/util/util_system.h @@ -21,7 +21,15 @@ CCL_NAMESPACE_BEGIN +/* Get number of available CPU groups. */ +int system_cpu_group_count(); + +/* Get number of threads/processors in the specified group. */ +int system_cpu_group_thread_count(int group); + +/* Get total number of threads in all groups. */ int system_cpu_thread_count(); + string system_cpu_brand_string(); int system_cpu_bits(); bool system_cpu_support_sse2(); diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp index d86aa8a4a46..352ba81c95a 100644 --- a/intern/cycles/util/util_task.cpp +++ b/intern/cycles/util/util_task.cpp @@ -16,6 +16,7 @@ #include "util_debug.h" #include "util_foreach.h" +#include "util_logging.h" #include "util_system.h" #include "util_task.h" #include "util_time.h" @@ -198,12 +199,30 @@ void TaskScheduler::init(int num_threads) /* automatic number of threads */ num_threads = system_cpu_thread_count(); } + VLOG(1) << "Creating pool of " << num_threads << " threads."; /* launch threads that will be waiting for work */ threads.resize(num_threads); - for(size_t i = 0; i < threads.size(); i++) - threads[i] = new thread(function_bind(&TaskScheduler::thread_run, i + 1)); + int num_groups = system_cpu_group_count(); + int thread_index = 0; + for(int group = 0; group < num_groups; ++group) { + /* NOTE: That's not really efficient from threading point of view, + * but it is simple to read and it doesn't make sense to use more + * user-specified threads than logical threads anyway. + */ + int num_group_threads = (group == num_groups - 1) + ? (threads.size() - thread_index) + : system_cpu_group_thread_count(group); + for(int group_thread = 0; + group_thread < num_group_threads && thread_index < threads.size(); + ++group_thread, ++thread_index) + { + threads[thread_index] = new thread(function_bind(&TaskScheduler::thread_run, + thread_index + 1), + group); + } + } } users++; diff --git a/intern/cycles/util/util_texture.h b/intern/cycles/util/util_texture.h index 6da47858133..e00edc046f7 100644 --- a/intern/cycles/util/util_texture.h +++ b/intern/cycles/util/util_texture.h @@ -19,43 +19,47 @@ CCL_NAMESPACE_BEGIN -/* Texture limits on various devices. */ +/* Texture limits on devices. */ /* CPU */ -#define TEX_NUM_BYTE4_IMAGES_CPU 1024 -#define TEX_NUM_FLOAT4_IMAGES_CPU 1024 -#define TEX_NUM_FLOAT_IMAGES_CPU 1024 -#define TEX_NUM_BYTE_IMAGES_CPU 1024 -#define TEX_IMAGE_BYTE4_START_CPU TEX_NUM_FLOAT4_IMAGES_CPU -#define TEX_IMAGE_FLOAT_START_CPU (TEX_NUM_FLOAT4_IMAGES_CPU + TEX_NUM_BYTE4_IMAGES_CPU) -#define TEX_IMAGE_BYTE_START_CPU (TEX_NUM_FLOAT4_IMAGES_CPU + TEX_NUM_BYTE4_IMAGES_CPU + TEX_NUM_BYTE_IMAGES_CPU) +#define TEX_NUM_FLOAT4_CPU 1024 +#define TEX_NUM_BYTE4_CPU 1024 +#define TEX_NUM_FLOAT_CPU 1024 +#define TEX_NUM_BYTE_CPU 1024 +#define TEX_START_FLOAT4_CPU 0 +#define TEX_START_BYTE4_CPU TEX_NUM_FLOAT4_CPU +#define TEX_START_FLOAT_CPU (TEX_NUM_FLOAT4_CPU + TEX_NUM_BYTE4_CPU) +#define TEX_START_BYTE_CPU (TEX_NUM_FLOAT4_CPU + TEX_NUM_BYTE4_CPU + TEX_NUM_BYTE_CPU) -/* CUDA (Fermi) */ -#define TEX_NUM_BYTE4_IMAGES_CUDA 88 -#define TEX_NUM_FLOAT4_IMAGES_CUDA 5 -#define TEX_NUM_FLOAT_IMAGES_CUDA 0 -#define TEX_NUM_BYTE_IMAGES_CUDA 0 -#define TEX_IMAGE_BYTE4_START_CUDA TEX_NUM_FLOAT4_IMAGES_CUDA -#define TEX_IMAGE_FLOAT_START_CUDA (TEX_NUM_FLOAT4_IMAGES_CUDA + TEX_NUM_BYTE4_IMAGES_CUDA) -#define TEX_IMAGE_BYTE_START_CUDA (TEX_NUM_FLOAT4_IMAGES_CUDA + TEX_NUM_BYTE4_IMAGES_CUDA + TEX_NUM_BYTE_IMAGES_CUDA) +/* CUDA (Geforce 4xx and 5xx) */ +#define TEX_NUM_FLOAT4_CUDA 5 +#define TEX_NUM_BYTE4_CUDA 88 +#define TEX_NUM_FLOAT_CUDA 0 +#define TEX_NUM_BYTE_CUDA 0 +#define TEX_START_FLOAT4_CUDA 0 +#define TEX_START_BYTE4_CUDA TEX_NUM_FLOAT4_CUDA +#define TEX_START_FLOAT_CUDA (TEX_NUM_FLOAT4_CUDA + TEX_NUM_BYTE4_CUDA) +#define TEX_START_BYTE_CUDA (TEX_NUM_FLOAT4_CUDA + TEX_NUM_BYTE4_CUDA + TEX_NUM_BYTE_CUDA) -/* CUDA (KEPLER and above) */ -#define TEX_NUM_BYTE4_IMAGES_CUDA_KEPLER 1024 -#define TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER 1024 -#define TEX_NUM_FLOAT_IMAGES_CUDA_KEPLER 1024 -#define TEX_NUM_BYTE_IMAGES_CUDA_KEPLER 1024 -#define TEX_IMAGE_BYTE4_START_CUDA_KEPLER TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER -#define TEX_IMAGE_FLOAT_START_CUDA_KEPLER (TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER + TEX_NUM_BYTE4_IMAGES_CUDA_KEPLER) -#define TEX_IMAGE_BYTE_START_CUDA_KEPLER (TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER + TEX_NUM_BYTE4_IMAGES_CUDA_KEPLER + TEX_NUM_BYTE_IMAGES_CUDA_KEPLER) +/* CUDA (Kepler, Geforce 6xx and above) */ +#define TEX_NUM_FLOAT4_CUDA_KEPLER 1024 +#define TEX_NUM_BYTE4_CUDA_KEPLER 1024 +#define TEX_NUM_FLOAT_CUDA_KEPLER 1024 +#define TEX_NUM_BYTE_CUDA_KEPLER 1024 +#define TEX_START_FLOAT4_CUDA_KEPLER 0 +#define TEX_START_BYTE4_CUDA_KEPLER TEX_NUM_FLOAT4_CUDA_KEPLER +#define TEX_START_FLOAT_CUDA_KEPLER (TEX_NUM_FLOAT4_CUDA_KEPLER + TEX_NUM_BYTE4_CUDA_KEPLER) +#define TEX_START_BYTE_CUDA_KEPLER (TEX_NUM_FLOAT4_CUDA_KEPLER + TEX_NUM_BYTE4_CUDA_KEPLER + TEX_NUM_BYTE_CUDA_KEPLER) /* OpenCL */ -#define TEX_NUM_BYTE4_IMAGES_OPENCL 1024 -#define TEX_NUM_FLOAT4_IMAGES_OPENCL 1024 -#define TEX_NUM_FLOAT_IMAGES_OPENCL 0 -#define TEX_NUM_BYTE_IMAGES_OPENCL 0 -#define TEX_IMAGE_BYTE4_START_OPENCL TEX_NUM_FLOAT4_IMAGES_OPENCL -#define TEX_IMAGE_FLOAT_START_OPENCL (TEX_NUM_FLOAT4_IMAGES_OPENCL + TEX_NUM_BYTE4_IMAGES_OPENCL) -#define TEX_IMAGE_BYTE_START_OPENCL (TEX_NUM_FLOAT4_IMAGES_OPENCL + TEX_NUM_BYTE4_IMAGES_OPENCL + TEX_NUM_BYTE_IMAGES_OPENCL) +#define TEX_NUM_FLOAT4_OPENCL 1024 +#define TEX_NUM_BYTE4_OPENCL 1024 +#define TEX_NUM_FLOAT_OPENCL 0 +#define TEX_NUM_BYTE_OPENCL 0 +#define TEX_START_FLOAT4_OPENCL 0 +#define TEX_START_BYTE4_OPENCL TEX_NUM_FLOAT4_OPENCL +#define TEX_START_FLOAT_OPENCL (TEX_NUM_FLOAT4_OPENCL + TEX_NUM_BYTE4_OPENCL) +#define TEX_START_BYTE_OPENCL (TEX_NUM_FLOAT4_OPENCL + TEX_NUM_BYTE4_OPENCL + TEX_NUM_BYTE_OPENCL) /* Color to use when textures are not found. */ diff --git a/intern/cycles/util/util_thread.cpp b/intern/cycles/util/util_thread.cpp new file mode 100644 index 00000000000..3db8b4bd197 --- /dev/null +++ b/intern/cycles/util/util_thread.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "util_thread.h" + +#include "util_system.h" +#include "util_windows.h" + +CCL_NAMESPACE_BEGIN + +thread::thread(function<void(void)> run_cb, int group) + : run_cb_(run_cb), + joined_(false), + group_(group) +{ + pthread_create(&pthread_id_, NULL, run, (void*)this); +} + +thread::~thread() +{ + if(!joined_) { + join(); + } +} + +void *thread::run(void *arg) +{ + thread *self = (thread*)(arg); + if(self->group_ != -1) { +#ifdef _WIN32 + HANDLE thread_handle = GetCurrentThread(); + GROUP_AFFINITY group_affinity = { 0 }; + int num_threads = system_cpu_group_thread_count(self->group_); + group_affinity.Group = self->group_; + group_affinity.Mask = (num_threads == 64) + ? -1 + : (1ull << num_threads) - 1; + if(SetThreadGroupAffinity(thread_handle, &group_affinity, NULL) == 0) { + fprintf(stderr, "Error setting thread affinity.\n"); + } +#endif + } + self->run_cb_(); + return NULL; +} + +bool thread::join() +{ + joined_ = true; + return pthread_join(pthread_id_, NULL) == 0; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 59575f31c13..427c633d2ce 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -52,37 +52,17 @@ typedef boost::condition_variable thread_condition_variable; class thread { public: - thread(function<void(void)> run_cb_) + thread(function<void(void)> run_cb, int group = -1); + ~thread(); - { - joined = false; - run_cb = run_cb_; - - pthread_create(&pthread_id, NULL, run, (void*)this); - } - - ~thread() - { - if(!joined) - join(); - } - - static void *run(void *arg) - { - ((thread*)arg)->run_cb(); - return NULL; - } - - bool join() - { - joined = true; - return pthread_join(pthread_id, NULL) == 0; - } + static void *run(void *arg); + bool join(); protected: - function<void(void)> run_cb; - pthread_t pthread_id; - bool joined; + function<void(void)> run_cb_; + pthread_t pthread_id_; + bool joined_; + int group_; }; /* Own wrapper around pthread's spin lock to make it's use easier. */ diff --git a/intern/cycles/util/util_windows.cpp b/intern/cycles/util/util_windows.cpp new file mode 100644 index 00000000000..ee5b3fd73c0 --- /dev/null +++ b/intern/cycles/util/util_windows.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "util_windows.h" + +#ifdef _WIN32 + +CCL_NAMESPACE_BEGIN + +#ifdef _M_X64 +# include <VersionHelpers.h> +#endif + +#if _WIN32_WINNT < 0x0601 +tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; +tGetActiveProcessorCount *GetActiveProcessorCount; +tSetThreadGroupAffinity *SetThreadGroupAffinity; +#endif + +static WORD GetActiveProcessorGroupCount_stub() +{ + return 1; +} + +static DWORD GetActiveProcessorCount_stub(WORD /*GroupNumber*/) +{ + SYSTEM_INFO info; + GetSystemInfo(&info); + return info.dwNumberOfProcessors; +} + +static BOOL SetThreadGroupAffinity_stub( + HANDLE /*hThread*/, + const GROUP_AFFINITY * /*GroupAffinity*/, + PGROUP_AFFINITY /*PreviousGroupAffinity*/) +{ + return TRUE; +} + +static bool supports_numa() +{ +#ifndef _M_X64 + return false; +#else + return IsWindows7OrGreater(); +#endif +} + +void util_windows_init_numa_groups() +{ + static bool initialized = false; + if(initialized) { + return; + } + initialized = true; +#if _WIN32_WINNT < 0x0601 + if(!supports_numa()) { + /* Use stubs on platforms which doesn't have rean NUMA/Groups. */ + GetActiveProcessorGroupCount = GetActiveProcessorGroupCount_stub; + GetActiveProcessorCount = GetActiveProcessorCount_stub; + SetThreadGroupAffinity = SetThreadGroupAffinity_stub; + return; + } + HMODULE kernel = GetModuleHandleA("kernel32.dll"); +# define READ_SYMBOL(sym) sym = (t##sym*)GetProcAddress(kernel, #sym) + READ_SYMBOL(GetActiveProcessorGroupCount); + READ_SYMBOL(GetActiveProcessorCount); + READ_SYMBOL(SetThreadGroupAffinity); +# undef READ_SUMBOL +#endif +} + +CCL_NAMESPACE_END + +#endif /* _WIN32 */ diff --git a/intern/cycles/util/util_windows.h b/intern/cycles/util/util_windows.h index f67e34d0f31..ac61d5348c3 100644 --- a/intern/cycles/util/util_windows.h +++ b/intern/cycles/util/util_windows.h @@ -31,6 +31,25 @@ #include <windows.h> +CCL_NAMESPACE_BEGIN + +#if _WIN32_WINNT < 0x0601 +typedef WORD tGetActiveProcessorGroupCount(); +typedef DWORD tGetActiveProcessorCount(WORD GroupNumber); +typedef BOOL tSetThreadGroupAffinity(HANDLE hThread, + const GROUP_AFFINITY *GroupAffinity, + PGROUP_AFFINITY PreviousGroupAffinity); + +extern tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; +extern tGetActiveProcessorCount *GetActiveProcessorCount; +extern tSetThreadGroupAffinity *SetThreadGroupAffinity; +#endif + +/* Make sure NUMA and processor groups API is initialized. */ +void util_windows_init_numa_groups(); + +CCL_NAMESPACE_END + #endif /* WIN32 */ #endif /* __UTIL_WINDOWS_H__ */ diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp index d80a638818c..39627fac899 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.cpp +++ b/intern/ghost/intern/GHOST_ContextSDL.cpp @@ -69,7 +69,7 @@ GHOST_ContextSDL::GHOST_ContextSDL( GHOST_ContextSDL::~GHOST_ContextSDL() { if (m_context != NULL) { - if (m_window != 0 && m_context == SDL_GL_GetCurrentContext()) + if (m_window != NULL && m_context == SDL_GL_GetCurrentContext()) SDL_GL_MakeCurrent(m_window, m_context); if (m_context != s_sharedContext || s_sharedCount == 1) { diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp index fd9abce96b7..96ff79aa65a 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp @@ -75,7 +75,7 @@ HRESULT __stdcall GHOST_DropTargetWin32::QueryInterface(REFIID riid, void **ppvO return S_OK; } else { - *ppvObj = 0; + *ppvObj = NULL; return E_NOINTERFACE; } } @@ -97,8 +97,7 @@ ULONG __stdcall GHOST_DropTargetWin32::Release(void) { ULONG refs = ::InterlockedDecrement(&m_cRef); - if (refs == 0) - { + if (refs == 0) { delete this; return 0; } diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp index d7dd2b1cde1..37d5926ffc2 100644 --- a/intern/ghost/intern/GHOST_ISystem.cpp +++ b/intern/ghost/intern/GHOST_ISystem.cpp @@ -54,7 +54,7 @@ # endif #endif -GHOST_ISystem *GHOST_ISystem::m_system = 0; +GHOST_ISystem *GHOST_ISystem::m_system = NULL; GHOST_TSuccess GHOST_ISystem::createSystem() @@ -76,7 +76,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem() # endif # endif #endif - success = m_system != 0 ? GHOST_kSuccess : GHOST_kFailure; + success = m_system != NULL ? GHOST_kSuccess : GHOST_kFailure; } else { success = GHOST_kFailure; @@ -92,7 +92,7 @@ GHOST_TSuccess GHOST_ISystem::disposeSystem() GHOST_TSuccess success = GHOST_kSuccess; if (m_system) { delete m_system; - m_system = 0; + m_system = NULL; } else { success = GHOST_kFailure; diff --git a/intern/ghost/intern/GHOST_ISystemPaths.cpp b/intern/ghost/intern/GHOST_ISystemPaths.cpp index 6ebcb37ba06..93ca0bc3880 100644 --- a/intern/ghost/intern/GHOST_ISystemPaths.cpp +++ b/intern/ghost/intern/GHOST_ISystemPaths.cpp @@ -36,6 +36,9 @@ * \date May 7, 2001 */ + +#include <stdio.h> /* just for NULL */ + #include "GHOST_ISystemPaths.h" #ifdef WIN32 @@ -49,7 +52,7 @@ #endif -GHOST_ISystemPaths *GHOST_ISystemPaths::m_systemPaths = 0; +GHOST_ISystemPaths *GHOST_ISystemPaths::m_systemPaths = NULL; GHOST_TSuccess GHOST_ISystemPaths::create() @@ -65,7 +68,7 @@ GHOST_TSuccess GHOST_ISystemPaths::create() m_systemPaths = new GHOST_SystemPathsUnix(); # endif #endif - success = m_systemPaths != 0 ? GHOST_kSuccess : GHOST_kFailure; + success = m_systemPaths != NULL ? GHOST_kSuccess : GHOST_kFailure; } else { success = GHOST_kFailure; @@ -78,7 +81,7 @@ GHOST_TSuccess GHOST_ISystemPaths::dispose() GHOST_TSuccess success = GHOST_kSuccess; if (m_systemPaths) { delete m_systemPaths; - m_systemPaths = 0; + m_systemPaths = NULL; } else { success = GHOST_kFailure; diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index 27285e49e9e..f18b7911f45 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -299,6 +299,12 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ m_buttonMask = 0x07C0F137; m_hidMap = Modern3Dx_HID_map; break; + case 0xC633: + puts("ndof: using SpaceMouse Enterprise"); + m_deviceType = NDOF_SpaceMouseEnterprise; + m_buttonCount = 31; + m_hidMap = Modern3Dx_HID_map; + break; default: printf("ndof: unknown 3Dconnexion product %04hx\n", product_id); diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h index ba82f37bb2a..d3c70bbac50 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.h +++ b/intern/ghost/intern/GHOST_NDOFManager.h @@ -40,6 +40,7 @@ typedef enum { NDOF_SpaceMousePro, NDOF_SpaceMouseWireless, NDOF_SpaceMouseProWireless, + NDOF_SpaceMouseEnterprise, // older devices NDOF_SpacePilot, diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 735f15777f2..c53580818e6 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -88,7 +88,7 @@ GHOST_ITimerTask *GHOST_System::installTimer(GHOST_TUns64 delay, } else { delete timer; - timer = 0; + timer = NULL; } } return timer; @@ -328,27 +328,22 @@ GHOST_TSuccess GHOST_System::exit() if (getFullScreen()) { endFullScreen(); } - if (m_displayManager) { - delete m_displayManager; - m_displayManager = NULL; - } - if (m_windowManager) { - delete m_windowManager; - m_windowManager = NULL; - } - if (m_timerManager) { - delete m_timerManager; - m_timerManager = NULL; - } - if (m_eventManager) { - delete m_eventManager; - m_eventManager = NULL; - } + + delete m_displayManager; + m_displayManager = NULL; + + delete m_windowManager; + m_windowManager = NULL; + + delete m_timerManager; + m_timerManager = NULL; + + delete m_eventManager; + m_eventManager = NULL; + #ifdef WITH_INPUT_NDOF - if (m_ndofManager) { - delete m_ndofManager; - m_ndofManager = 0; - } + delete m_ndofManager; + m_ndofManager = NULL; #endif return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index bf44d938a47..c9855cfdf7e 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -539,7 +539,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( ) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_IWindow* window = 0; + GHOST_IWindow* window = NULL; //Get the available rect for including window contents NSRect frame = [[NSScreen mainScreen] visibleFrame]; @@ -567,7 +567,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( else { GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n"); delete window; - window = 0; + window = NULL; } [pool drain]; diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 9a11c7287ff..ed08ce02f47 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -254,7 +254,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow( else { GHOST_PRINT("GHOST_SystemWin32::createWindow(): window invalid\n"); delete window; - window = 0; + window = NULL; } return window; @@ -771,7 +771,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter } else { - event = 0; + event = NULL; } return event; } @@ -905,7 +905,7 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw) LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - GHOST_Event *event = 0; + GHOST_Event *event = NULL; bool eventHandled = false; LRESULT lResult = 0; diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 316e69400eb..25daa8ce2a7 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -302,7 +302,7 @@ createWindow(const STR_String& title, const bool exclusive, const GHOST_TEmbedderWindowID parentWindow) { - GHOST_WindowX11 *window = 0; + GHOST_WindowX11 *window = NULL; if (!m_display) return 0; @@ -325,7 +325,7 @@ createWindow(const STR_String& title, } else { delete window; - window = 0; + window = NULL; } } return window; diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 52cb9cbf54b..d778628ea37 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -106,7 +106,7 @@ public: * \return The validity of the window. */ virtual bool getValid() const { - return m_context != 0; + return m_context != NULL; } /** diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index b3fc8efbab1..00e00b6a1ea 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -663,7 +663,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() bool GHOST_WindowCocoa::getValid() const { - return GHOST_Window::getValid() && m_window != 0 && m_openGLView != 0; + return GHOST_Window::getValid() && m_window != NULL && m_openGLView != NULL; } void* GHOST_WindowCocoa::getOSWindow() const diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp index 83490cecce5..790c73deca5 100644 --- a/intern/ghost/intern/GHOST_WindowManager.cpp +++ b/intern/ghost/intern/GHOST_WindowManager.cpp @@ -110,7 +110,7 @@ bool GHOST_WindowManager::getWindowFound(const GHOST_IWindow *window) const bool GHOST_WindowManager::getFullScreen(void) const { - return m_fullScreenWindow != 0; + return m_fullScreenWindow != NULL; } @@ -140,13 +140,13 @@ GHOST_TSuccess GHOST_WindowManager::endFullScreen(void) { GHOST_TSuccess success = GHOST_kFailure; if (getFullScreen()) { - if (m_fullScreenWindow != 0) { + if (m_fullScreenWindow != NULL) { //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n"); setWindowInactive(m_fullScreenWindow); m_fullScreenWindow->endFullScreen(); delete m_fullScreenWindow; //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n"); - m_fullScreenWindow = 0; + m_fullScreenWindow = NULL; if (m_activeWindowBeforeFullScreen) { setActiveWindow(m_activeWindowBeforeFullScreen); } @@ -181,7 +181,7 @@ GHOST_IWindow *GHOST_WindowManager::getActiveWindow(void) const void GHOST_WindowManager::setWindowInactive(const GHOST_IWindow *window) { if (window == m_activeWindow) { - m_activeWindow = 0; + m_activeWindow = NULL; } } diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 4171fdc2dd8..c9bcb38ab68 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -361,8 +361,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32() if (fpWTClose) { if (m_tablet) fpWTClose(m_tablet); - if (m_tabletData) - delete m_tabletData; + delete m_tabletData; m_tabletData = NULL; } } diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl index 5921d6d9c73..853bf575582 100644 --- a/intern/opencolorio/gpu_shader_display_transform.glsl +++ b/intern/opencolorio/gpu_shader_display_transform.glsl @@ -38,7 +38,7 @@ float read_curve_mapping(int table, int index) * But is it actually correct to subtract 1 here? */ float texture_index = float(index) / float(curve_mapping_lut_size - 1); - return texture1D(curve_mapping_texture, texture_index) [table]; + return texture1D(curve_mapping_texture, texture_index)[table]; } float curvemap_calc_extend(int table, float x, vec2 first, vec2 last) diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl index 51e8ed46c34..a17dcef81c7 100644 --- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl +++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl @@ -111,7 +111,7 @@ void emit(int index, vec3 normal) outpt.v.normal = normal; /* TODO(sergey): Only uniform subdivisions atm. */ - vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1)); + vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); vec2 st = quadst[index]; INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); @@ -135,7 +135,7 @@ void emit(int index) outpt.v.normal = inpt[index].v.normal; /* TODO(sergey): Only uniform subdivisions atm. */ - vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1)); + vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); vec2 st = quadst[index]; INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); @@ -261,7 +261,7 @@ void main() #else /* USE_COLOR_MATERIAL */ vec3 varying_position = inpt.v.position.xyz; vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? - normalize(varying_position): vec3(0.0, 0.0, -1.0); + normalize(varying_position) : vec3(0.0, 0.0, -1.0); for (int i = 0; i < num_enabled_lights; i++) { /* todo: this is a slow check for disabled lights */ if (lightSource[i].specular.a == 0.0) @@ -299,7 +299,7 @@ void main() /* diffuse light */ vec3 light_diffuse = lightSource[i].diffuse.rgb; float diffuse_bsdf = max(dot(N, light_direction), 0.0); - L_diffuse += light_diffuse*diffuse_bsdf*intensity; + L_diffuse += light_diffuse * diffuse_bsdf * intensity; /* specular light */ vec3 light_specular = lightSource[i].specular.rgb; @@ -307,7 +307,7 @@ void main() float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess); - L_specular += light_specular*specular_bsdf * intensity; + L_specular += light_specular * specular_bsdf * intensity; } #endif /* USE_COLOR_MATERIAL */ |