diff options
author | Pascal Schoen <pascal_schoen@gmx.net> | 2016-08-03 12:42:02 +0300 |
---|---|---|
committer | Pascal Schoen <pascal_schoen@gmx.net> | 2016-08-03 12:42:02 +0300 |
commit | 81f6c06b1f53180bf32a5c11ac1fa64e2b6abf52 (patch) | |
tree | c7ad4920e48e0eb529e2064fd0d3813c29d5383b /intern/cycles/blender | |
parent | ece5a08e0d6e51a83c223ea87346134216e5b34e (diff) | |
parent | 7065022f7aa23ba13d2999e1e40162a8f480af0e (diff) |
Merge branch 'master' into cycles_disney_brdf
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 42 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 181 | ||||
-rw-r--r-- | intern/cycles/blender/addon/version_update.py | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/blender/blender_curves.cpp | 87 | ||||
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 403 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 22 | ||||
-rw-r--r-- | intern/cycles/blender/blender_particles.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 261 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 49 |
13 files changed, 593 insertions, 475 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index d4b7535b9ee..2c5365c9189 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -82,7 +82,6 @@ def init(): import bpy import _cycles import os.path - import sys # Workaround possibly buggy legacy drivers which crashes on the OpenCL # device enumeration. @@ -103,10 +102,12 @@ def init(): _cycles.init(path, user_path, bpy.app.background) _parse_command_line() + def exit(): import _cycles _cycles.exit() + def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False): import bpy import _cycles diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 140862721a8..81204eb8ae0 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -46,12 +46,6 @@ enum_displacement_methods = ( ('BOTH', "Both", "Combination of displacement and bump mapping"), ) -enum_subdivision_types = ( - ('NONE', "None", "No subdivision"), - ('LINEAR', "Linear", "Use linear subdivision"), - ('CATMULL_CLARK', "Catmull–Clark", "Use Catmull-Clark subdivision"), - ) - enum_bvh_types = ( ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"), ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"), @@ -503,6 +497,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Use BVH spatial splits: longer builder time, faster render", default=False, ) + cls.debug_use_hair_bvh = BoolProperty( + name="Use Hair BVH", + description="Use special type BVH optimized for hair (uses more ram but renders faster)", + default=True, + ) cls.tile_order = EnumProperty( name="Tile Order", description="Tile order for rendering", @@ -959,18 +958,6 @@ class CyclesMeshSettings(bpy.types.PropertyGroup): items=enum_displacement_methods, default='BUMP', ) - cls.subdivision_type = EnumProperty( - name="Subdivision Type", - description="Type of subdivision to use", - items=enum_subdivision_types, - default='NONE', - ) - cls.dicing_rate = FloatProperty( - name="Dicing Rate", - description="Multiplier for scene dicing rate", - min=0.1, max=1000.0, - default=1.0, - ) @classmethod def unregister(cls): @@ -979,11 +966,9 @@ class CyclesMeshSettings(bpy.types.PropertyGroup): del bpy.types.MetaBall.cycles -class CyclesObjectBlurSettings(bpy.types.PropertyGroup): - +class CyclesObjectSettings(bpy.types.PropertyGroup): @classmethod def register(cls): - bpy.types.Object.cycles = PointerProperty( name="Cycles Object Settings", description="Cycles object settings", @@ -1015,6 +1000,19 @@ class CyclesObjectBlurSettings(bpy.types.PropertyGroup): default=False, ) + cls.use_adaptive_subdivision = BoolProperty( + name="Use Adaptive Subdivision", + description="Use adaptive render time subdivision", + default=False, + ) + + cls.dicing_rate = FloatProperty( + name="Dicing Rate", + description="Multiplier for scene dicing rate", + min=0.1, max=1000.0, + default=1.0, + ) + @classmethod def unregister(cls): del bpy.types.Object.cycles @@ -1131,6 +1129,7 @@ def register(): bpy.utils.register_class(CyclesWorldSettings) bpy.utils.register_class(CyclesVisibilitySettings) bpy.utils.register_class(CyclesMeshSettings) + bpy.utils.register_class(CyclesObjectSettings) bpy.utils.register_class(CyclesCurveRenderSettings) bpy.utils.register_class(CyclesCurveSettings) @@ -1142,6 +1141,7 @@ def unregister(): bpy.utils.unregister_class(CyclesLampSettings) bpy.utils.unregister_class(CyclesWorldSettings) bpy.utils.unregister_class(CyclesMeshSettings) + bpy.utils.unregister_class(CyclesObjectSettings) bpy.utils.unregister_class(CyclesVisibilitySettings) bpy.utils.unregister_class(CyclesCurveRenderSettings) bpy.utils.unregister_class(CyclesCurveSettings) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 023841a7a17..42f7970769a 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): @@ -384,7 +383,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.prop(cscene, "use_progressive_refine") subsub = sub.column(align=True) - subsub.enabled = not rd.use_border subsub.prop(rd, "use_save_buffers") col = split.column(align=True) @@ -403,6 +401,7 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): col.label(text="Acceleration structure:") col.prop(cscene, "debug_use_spatial_splits") + col.prop(cscene, "debug_use_hair_bvh") class CyclesRender_PT_layer_options(CyclesButtonsPanel, Panel): @@ -460,7 +459,9 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel): col.prop(rl, "use_pass_z") col.prop(rl, "use_pass_mist") col.prop(rl, "use_pass_normal") - col.prop(rl, "use_pass_vector") + row = col.row() + row.prop(rl, "use_pass_vector") + row.active = not rd.use_motion_blur col.prop(rl, "use_pass_uv") col.prop(rl, "use_pass_object_index") col.prop(rl, "use_pass_material_index") @@ -704,17 +705,9 @@ 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() - sub = col.column(align=True) - sub.label(text="Subdivision:") - sub.prop(cdata, "subdivision_type", text="") - - if cdata.subdivision_type != 'NONE': - sub.prop(cdata, "dicing_rate") - class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel): bl_label = "Motion Blur" bl_context = "object" @@ -894,7 +887,7 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel): lamp = context.lamp clamp = lamp.cycles - cscene = context.scene.cycles + # cscene = context.scene.cycles layout.prop(lamp, "type", expand=True) @@ -1114,7 +1107,7 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel): world = context.world cworld = world.cycles - cscene = context.scene.cycles + # cscene = context.scene.cycles split = layout.split() @@ -1664,104 +1657,62 @@ def draw_pause(self, context): def get_panels(): - types = bpy.types - panels = [ - "RENDER_PT_render", - "RENDER_PT_output", - "RENDER_PT_encoding", - "RENDER_PT_dimensions", - "RENDER_PT_stamp", - "RENDER_PT_freestyle", - "RENDERLAYER_PT_layers", - "RENDERLAYER_PT_freestyle", - "RENDERLAYER_PT_freestyle_lineset", - "RENDERLAYER_PT_freestyle_linestyle", - "SCENE_PT_scene", - "SCENE_PT_color_management", - "SCENE_PT_custom_props", - "SCENE_PT_audio", - "SCENE_PT_unit", - "SCENE_PT_keying_sets", - "SCENE_PT_keying_set_paths", - "SCENE_PT_physics", - "WORLD_PT_context_world", - "WORLD_PT_custom_props", - "DATA_PT_context_mesh", - "DATA_PT_context_camera", - "DATA_PT_context_lamp", - "DATA_PT_context_speaker", - "DATA_PT_normals", - "DATA_PT_texture_space", - "DATA_PT_curve_texture_space", - "DATA_PT_mball_texture_space", - "DATA_PT_vertex_groups", - "DATA_PT_shape_keys", - "DATA_PT_uv_texture", - "DATA_PT_vertex_colors", - "DATA_PT_camera", - "DATA_PT_camera_display", - "DATA_PT_camera_stereoscopy", - "DATA_PT_camera_safe_areas", - "DATA_PT_lens", - "DATA_PT_speaker", - "DATA_PT_distance", - "DATA_PT_cone", - "DATA_PT_customdata", - "DATA_PT_custom_props_mesh", - "DATA_PT_custom_props_camera", - "DATA_PT_custom_props_lamp", - "DATA_PT_custom_props_speaker", - "DATA_PT_custom_props_arm", - "DATA_PT_custom_props_curve", - "DATA_PT_custom_props_lattice", - "DATA_PT_custom_props_metaball", - "TEXTURE_PT_preview", - "TEXTURE_PT_custom_props", - "TEXTURE_PT_clouds", - "TEXTURE_PT_wood", - "TEXTURE_PT_marble", - "TEXTURE_PT_magic", - "TEXTURE_PT_blend", - "TEXTURE_PT_stucci", - "TEXTURE_PT_image", - "TEXTURE_PT_image_sampling", - "TEXTURE_PT_image_mapping", - "TEXTURE_PT_musgrave", - "TEXTURE_PT_voronoi", - "TEXTURE_PT_distortednoise", - "TEXTURE_PT_voxeldata", - "TEXTURE_PT_pointdensity", - "TEXTURE_PT_pointdensity_turbulence", - "TEXTURE_PT_mapping", - "TEXTURE_PT_ocean", - "TEXTURE_PT_influence", - "TEXTURE_PT_colors", - "PARTICLE_PT_context_particles", - "PARTICLE_PT_custom_props", - "PARTICLE_PT_emission", - "PARTICLE_PT_hair_dynamics", - "PARTICLE_PT_cache", - "PARTICLE_PT_velocity", - "PARTICLE_PT_rotation", - "PARTICLE_PT_physics", - "SCENE_PT_rigid_body_world", - "SCENE_PT_rigid_body_cache", - "SCENE_PT_rigid_body_field_weights", - "PARTICLE_PT_boidbrain", - "PARTICLE_PT_render", - "PARTICLE_PT_draw", - "PARTICLE_PT_children", - "PARTICLE_PT_field_weights", - "PARTICLE_PT_force_fields", - "PARTICLE_PT_vertexgroups", - "MATERIAL_PT_custom_props", - "MATERIAL_PT_freestyle_line", - "BONE_PT_custom_props", - "OBJECT_PT_custom_props", - ] - - return [getattr(types, p) for p in panels if hasattr(types, p)] - + exclude_panels = { + 'DATA_PT_area', + 'DATA_PT_camera_dof', + 'DATA_PT_falloff_curve', + 'DATA_PT_lamp', + 'DATA_PT_preview', + 'DATA_PT_shadow', + 'DATA_PT_spot', + 'DATA_PT_sunsky', + 'MATERIAL_PT_context_material', + 'MATERIAL_PT_diffuse', + 'MATERIAL_PT_flare', + 'MATERIAL_PT_halo', + 'MATERIAL_PT_mirror', + 'MATERIAL_PT_options', + 'MATERIAL_PT_pipeline', + 'MATERIAL_PT_preview', + 'MATERIAL_PT_shading', + 'MATERIAL_PT_shadow', + 'MATERIAL_PT_specular', + 'MATERIAL_PT_sss', + 'MATERIAL_PT_strand', + 'MATERIAL_PT_transp', + 'MATERIAL_PT_volume_density', + 'MATERIAL_PT_volume_integration', + 'MATERIAL_PT_volume_lighting', + 'MATERIAL_PT_volume_options', + 'MATERIAL_PT_volume_shading', + 'MATERIAL_PT_volume_transp', + 'RENDERLAYER_PT_layer_options', + 'RENDERLAYER_PT_layer_passes', + 'RENDERLAYER_PT_views', + 'RENDER_PT_antialiasing', + 'RENDER_PT_bake', + 'RENDER_PT_motion_blur', + 'RENDER_PT_performance', + 'RENDER_PT_post_processing', + 'RENDER_PT_shading', + 'SCENE_PT_simplify', + 'TEXTURE_PT_context_texture', + 'WORLD_PT_ambient_occlusion', + 'WORLD_PT_environment_lighting', + 'WORLD_PT_gather', + 'WORLD_PT_indirect_lighting', + 'WORLD_PT_mist', + 'WORLD_PT_preview', + 'WORLD_PT_world' + } + + panels = [] + for panel in bpy.types.Panel.__subclasses__(): + if hasattr(panel, 'COMPAT_ENGINES') and 'BLENDER_RENDER' in panel.COMPAT_ENGINES: + if panel.__name__ not in exclude_panels: + panels.append(panel) + + return panels def register(): bpy.types.RENDER_PT_render.append(draw_device) @@ -1770,10 +1721,10 @@ def register(): for panel in get_panels(): panel.COMPAT_ENGINES.add('CYCLES') - def unregister(): bpy.types.RENDER_PT_render.remove(draw_device) bpy.types.VIEW3D_HT_header.remove(draw_pause) for panel in get_panels(): - panel.COMPAT_ENGINES.remove('CYCLES') + if 'CYCLES' in panel.COMPAT_ENGINES: + panel.COMPAT_ENGINES.remove('CYCLES') diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index 221b1437128..830723d6149 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -104,7 +104,6 @@ def vector_curve_node_remap(node): """ Remap values of vector curve node from normalized to absolute values """ - from mathutils import Vector if node.bl_idname == 'ShaderNodeVectorCurve': node.mapping.use_clip = False for curve in node.mapping.curves: 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..74fd4cb44a0 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -24,7 +24,6 @@ #include "blender_session.h" #include "blender_util.h" -#include "subd_mesh.h" #include "subd_patch.h" #include "subd_split.h" @@ -335,44 +334,71 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh& b_mesh, const vector<int>& nverts, - const vector<int>& face_flags) + const vector<int>& face_flags, + bool subdivision) { - BL::Mesh::tessface_vertex_colors_iterator l; - for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) { - if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) - continue; + if(subdivision) { + BL::Mesh::vertex_colors_iterator l; - Attribute *attr = mesh->attributes.add( - ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE); + for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) { + if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) + continue; - BL::MeshColorLayer::data_iterator c; - uchar4 *cdata = attr->data_uchar4(); - size_t i = 0; + Attribute *attr = mesh->subd_attributes.add(ustring(l->name().c_str()), + TypeDesc::TypeColor, + ATTR_ELEMENT_CORNER_BYTE); - for(l->data.begin(c); c != l->data.end(); ++c, ++i) { - int tri_a[3], tri_b[3]; - face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b); + BL::Mesh::polygons_iterator p; + uchar4 *cdata = attr->data_uchar4(); - uchar4 colors[4]; - colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1()))); - colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2()))); - colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3()))); - if(nverts[i] == 4) { - colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4()))); + for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { + int n = p->loop_total(); + for(int i = 0; i < n; i++) { + float3 color = get_float3(l->data[p->loop_start() + i].color()); + *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear(color)); + } } + } + } + else { + BL::Mesh::tessface_vertex_colors_iterator l; + for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) { + if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) + continue; + + Attribute *attr = mesh->attributes.add(ustring(l->name().c_str()), + TypeDesc::TypeColor, + ATTR_ELEMENT_CORNER_BYTE); + + BL::MeshColorLayer::data_iterator c; + uchar4 *cdata = attr->data_uchar4(); + size_t i = 0; + + for(l->data.begin(c); c != l->data.end(); ++c, ++i) { + int tri_a[3], tri_b[3]; + face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b); + + uchar4 colors[4]; + colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1()))); + colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2()))); + colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3()))); + if(nverts[i] == 4) { + colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4()))); + } - cdata[0] = colors[tri_a[0]]; - cdata[1] = colors[tri_a[1]]; - cdata[2] = colors[tri_a[2]]; + cdata[0] = colors[tri_a[0]]; + cdata[1] = colors[tri_a[1]]; + cdata[2] = colors[tri_a[2]]; - if(nverts[i] == 4) { - cdata[3] = colors[tri_b[0]]; - cdata[4] = colors[tri_b[1]]; - cdata[5] = colors[tri_b[2]]; - cdata += 6; + if(nverts[i] == 4) { + cdata[3] = colors[tri_b[0]]; + cdata[4] = colors[tri_b[1]]; + cdata[5] = colors[tri_b[2]]; + cdata += 6; + } + else + cdata += 3; } - else - cdata += 3; } } } @@ -382,9 +408,40 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh& b_mesh, const vector<int>& nverts, - const vector<int>& face_flags) + const vector<int>& face_flags, + bool subdivision) { - if(b_mesh.tessface_uv_textures.length() != 0) { + if(subdivision) { + BL::Mesh::uv_layers_iterator l; + int i = 0; + + for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) { + bool active_render = b_mesh.uv_textures[i].active_render(); + AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE; + ustring name = ustring(l->name().c_str()); + + /* UV map */ + if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { + Attribute *attr; + + if(active_render) + attr = mesh->subd_attributes.add(std, name); + else + attr = mesh->subd_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER); + + BL::Mesh::polygons_iterator p; + float3 *fdata = attr->data_float3(); + + for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { + int n = p->loop_total(); + for(int j = 0; j < n; j++) { + *(fdata++) = get_float3(l->data[p->loop_start() + j].uv()); + } + } + } + } + } + else if(b_mesh.tessface_uv_textures.length() != 0) { BL::Mesh::tessface_uv_textures_iterator l; for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { @@ -465,11 +522,13 @@ static void attr_create_uv_map(Scene *scene, /* Create vertex pointiness attributes. */ static void attr_create_pointiness(Scene *scene, Mesh *mesh, - BL::Mesh& b_mesh) + BL::Mesh& b_mesh, + bool subdivision) { if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) { const int numverts = b_mesh.vertices.length(); - Attribute *attr = mesh->attributes.add(ATTR_STD_POINTINESS); + AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes; + Attribute *attr = attributes.add(ATTR_STD_POINTINESS); float *data = attr->data_float(); int *counter = new int[numverts]; float *raw_data = new float[numverts]; @@ -532,31 +591,44 @@ static void attr_create_pointiness(Scene *scene, static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh& b_mesh, - const vector<Shader*>& used_shaders) + const vector<Shader*>& used_shaders, + bool subdivision=false) { /* count vertices and faces */ int numverts = b_mesh.vertices.length(); - int numfaces = b_mesh.tessfaces.length(); + int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length(); int numtris = 0; + int numcorners = 0; + int numngons = 0; bool use_loop_normals = b_mesh.use_auto_smooth(); BL::Mesh::vertices_iterator v; BL::Mesh::tessfaces_iterator f; + BL::Mesh::polygons_iterator p; - for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { - int4 vi = get_int4(f->vertices_raw()); - numtris += (vi[3] == 0)? 1: 2; + if(!subdivision) { + for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { + int4 vi = get_int4(f->vertices_raw()); + numtris += (vi[3] == 0)? 1: 2; + } + } + else { + for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { + numngons += (p->loop_total() == 4)? 0: 1; + numcorners += p->loop_total(); + } } - /* reserve memory */ - mesh->reserve(numverts, numtris, 0, 0); + /* allocate memory */ + mesh->reserve_mesh(numverts, numtris); + mesh->reserve_subd_faces(numfaces, numngons, numcorners); /* 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); + AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes; + Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) @@ -565,7 +637,7 @@ static void create_mesh(Scene *scene, /* create generated coordinates from undeformed coordinates */ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { - Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); + Attribute *attr = attributes.add(ATTR_STD_GENERATED); float3 loc, size; mesh_texture_space(b_mesh, loc, size); @@ -578,67 +650,103 @@ static void create_mesh(Scene *scene, } /* Create needed vertex attributes. */ - attr_create_pointiness(scene, mesh, b_mesh); + attr_create_pointiness(scene, mesh, b_mesh, subdivision); /* create faces */ vector<int> nverts(numfaces); vector<int> face_flags(numfaces, FACE_FLAG_NONE); - int fi = 0, ti = 0; - - for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) { - int4 vi = get_int4(f->vertices_raw()); - int n = (vi[3] == 0)? 3: 4; - int shader = clamp(f->material_index(), 0, used_shaders.size()-1); - bool smooth = f->use_smooth() || use_loop_normals; - - /* split vertices if normal is different - * - * note all vertex attributes must have been set here so we can split - * and copy attributes in split_vertex without remapping later */ - if(use_loop_normals) { - BL::Array<float, 12> loop_normals = f->split_normals(); - - for(int i = 0; i < n; i++) { - float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); - - if(N[vi[i]] != loop_N) { - int new_vi = mesh->split_vertex(vi[i]); - - /* set new normal and vertex index */ - N = attr_N->data_float3(); - N[new_vi] = loop_N; - vi[i] = new_vi; + int fi = 0; + + if(!subdivision) { + for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) { + int4 vi = get_int4(f->vertices_raw()); + int n = (vi[3] == 0)? 3: 4; + int shader = clamp(f->material_index(), 0, used_shaders.size()-1); + bool smooth = f->use_smooth() || use_loop_normals; + + /* split vertices if normal is different + * + * note all vertex attributes must have been set here so we can split + * and copy attributes in split_vertex without remapping later */ + if(use_loop_normals) { + BL::Array<float, 12> loop_normals = f->split_normals(); + + for(int i = 0; i < n; i++) { + float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); + + if(N[vi[i]] != loop_N) { + int new_vi = mesh->split_vertex(vi[i]); + + /* set new normal and vertex index */ + N = attr_N->data_float3(); + N[new_vi] = loop_N; + vi[i] = new_vi; + } } } - } - /* create triangles */ - if(n == 4) { - if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) || - 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); - face_flags[fi] |= FACE_FLAG_DIVIDE_24; + /* create triangles */ + if(n == 4) { + if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) || + is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) + { + mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth); + mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth); + face_flags[fi] |= FACE_FLAG_DIVIDE_24; + } + else { + mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); + mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth); + face_flags[fi] |= FACE_FLAG_DIVIDE_13; + } } 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); - face_flags[fi] |= FACE_FLAG_DIVIDE_13; + mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); } + + nverts[fi] = n; } - else - mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth, false); + } + else { + vector<int> vi; + + for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { + int n = p->loop_total(); + int shader = clamp(p->material_index(), 0, used_shaders.size()-1); + bool smooth = p->use_smooth() || use_loop_normals; + + vi.reserve(n); + for(int i = 0; i < n; i++) { + vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index(); + + /* split vertices if normal is different + * + * note all vertex attributes must have been set here so we can split + * and copy attributes in split_vertex without remapping later */ + if(use_loop_normals) { + float3 loop_N = get_float3(b_mesh.loops[p->loop_start() + i].normal()); + + if(N[vi[i]] != loop_N) { + int new_vi = mesh->split_vertex(vi[i]); + + /* set new normal and vertex index */ + N = attr_N->data_float3(); + N[new_vi] = loop_N; + vi[i] = new_vi; + } + } + } - nverts[fi] = n; + /* create subd faces */ + mesh->add_subd_face(&vi[0], n, shader, smooth); + } } /* Create all needed attributes. * The calculate functions will check whether they're needed or not. */ - attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags); - attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags); + attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision); + attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision); /* for volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can @@ -658,16 +766,17 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Object& b_ob, BL::Mesh& b_mesh, - PointerRNA *cmesh, const vector<Shader*>& used_shaders, float dicing_rate, int max_subdivisions) { - Mesh basemesh; - create_mesh(scene, &basemesh, b_mesh, used_shaders); + create_mesh(scene, mesh, b_mesh, used_shaders, true); - SubdParams sdparams(mesh, 0, true, false); - sdparams.dicing_rate = max(0.1f, RNA_float_get(cmesh, "dicing_rate") * dicing_rate); + SubdParams sdparams(mesh); + + PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); + + sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate); sdparams.max_level = max_subdivisions; scene->camera->update(); @@ -676,11 +785,48 @@ static void create_subd_mesh(Scene *scene, /* tesselate */ DiagSplit dsplit(sdparams); - basemesh.tessellate(&dsplit); + mesh->tessellate(&dsplit); } /* Sync */ +static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh) +{ + if(scene->need_motion() == Scene::MOTION_NONE) + return; + + BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob); + + if(!b_fluid_domain) + return; + + /* If the mesh has modifiers following the fluid domain we can't export motion. */ + if(b_fluid_domain.fluid_mesh_vertices.length() != mesh->verts.size()) + return; + + /* Find or add attribute */ + float3 *P = &mesh->verts[0]; + Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + + if(!attr_mP) { + attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); + } + + /* Only export previous and next frame, we don't have any in between data. */ + float motion_times[2] = {-1.0f, 1.0f}; + for (int step = 0; step < 2; step++) { + float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; + float3 *mP = attr_mP->data_float3() + step*mesh->verts.size(); + + BL::DomainFluidSettings::fluid_mesh_vertices_iterator fvi; + int i = 0; + + for(b_fluid_domain.fluid_mesh_vertices.begin(fvi); fvi != b_fluid_domain.fluid_mesh_vertices.end(); ++fvi, ++i) { + mP[i] = P[i] + get_float3(fvi->velocity()) * relative_time; + } + } +} + Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, bool object_updated, bool hide_tris) @@ -759,11 +905,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; @@ -780,20 +927,41 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, b_ob.update_from_editmode(); bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); - BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed); + + mesh->subdivision_type = Mesh::SUBDIVISION_NONE; + + PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); + + if(cobj.data && b_ob.modifiers.length() > 0 && experimental) { + BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length()-1]; + bool enabled = preview ? mod.show_viewport() : mod.show_render(); + + if(enabled && mod.type() == BL::Modifier::type_SUBSURF && RNA_int_get(&cobj, "use_adaptive_subdivision")) { + BL::SubsurfModifier subsurf(mod); + + if(subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) { + mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK; + } + else { + mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR; + } + } + } + + BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, mesh->subdivision_type); if(b_mesh) { if(render_layer.use_surfaces && !hide_tris) { - if(cmesh.data && experimental && RNA_enum_get(&cmesh, "subdivision_type")) - create_subd_mesh(scene, mesh, b_ob, b_mesh, &cmesh, used_shaders, + if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE) + create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders, dicing_rate, max_subdivisions); else - create_mesh(scene, mesh, b_mesh, used_shaders); + create_mesh(scene, mesh, b_mesh, used_shaders, false); create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current()); } - if(render_layer.use_hair) + if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE) sync_curves(mesh, b_mesh, b_ob, false); if(can_free_caches) { @@ -801,7 +969,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, } /* free derived mesh */ - b_data.meshes.remove(b_mesh); + b_data.meshes.remove(b_mesh, false); } } mesh->geometry_flags = requested_geometry_flags; @@ -821,20 +989,30 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, mesh->displacement_method = Mesh::DISPLACE_BOTH; } + /* fluid motion */ + sync_mesh_fluid_motion(b_ob, scene, mesh); + /* tag update */ bool rebuild = false; 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; } @@ -903,9 +1081,14 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, * would need a more extensive check to see which objects are animated */ BL::Mesh b_mesh(PointerRNA_NULL); + /* fluid motion is exported immediate with mesh, skip here */ + BL::DomainFluidSettings b_fluid_domain = object_fluid_domain_find(b_ob); + if (b_fluid_domain) + return; + if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { /* get derived mesh */ - b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false); + b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false, false); } if(!b_mesh) { @@ -931,8 +1114,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); } } @@ -1006,7 +1189,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, sync_curves(mesh, b_mesh, b_ob, true, time_index); /* free derived mesh */ - b_data.meshes.remove(b_mesh); + b_data.meshes.remove(b_mesh, false); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 80768c096e3..4886735a18f 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -253,11 +253,20 @@ static bool object_boundbox_clip(Scene *scene, boundbox[3 * i + 1], boundbox[3 * i + 2]); p = transform_point(&tfm, p); - p = transform_point(&worldtondc, p); - if(p.z >= -margin) { + + float4 b = make_float4(p.x, p.y, p.z, 1.0f); + float4 c = make_float4(dot(worldtondc.x, b), + dot(worldtondc.y, b), + dot(worldtondc.z, b), + dot(worldtondc.w, b)); + p = float4_to_float3(c / c.w); + if(c.z < 0.0f) { + p.x = 1.0f - p.x; + p.y = 1.0f - p.y; + } + if(c.z >= -margin) { all_behind = false; } - p /= p.z; bb_min = min(bb_min, p); bb_max = max(bb_max, p); } @@ -720,12 +729,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render, << relative_time << "."; /* fixed shutter time to get previous and next frame for motion pass */ - float shuttertime; - - if(scene->need_motion() == Scene::MOTION_PASS) - shuttertime = 2.0f; - else - shuttertime = scene->camera->shuttertime; + float shuttertime = scene->motion_shutter_time(); /* compute frame and subframe time */ float time = frame_center + frame_center_delta + relative_time * shuttertime * 0.5f; 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 d2cd9307bab..7b8317a50a7 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -127,82 +127,60 @@ 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) { + Node *node = input->parent; + const SocketType& socket = input->socket_type; + /* copy values for non linked inputs */ - switch(input->type) { - case SHADER_SOCKET_FLOAT: { - input->set(get_float(b_sock.ptr, "default_value")); + switch(input->type()) { + case SocketType::FLOAT: { + node->set(socket, 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: { + node->set(socket, get_int(b_sock.ptr, "default_value")); break; } - case SHADER_SOCKET_COLOR: { - input->set(float4_to_float3(get_float4(b_sock.ptr, "default_value"))); + case SocketType::COLOR: { + node->set(socket, float4_to_float3(get_float4(b_sock.ptr, "default_value"))); break; } - case SHADER_SOCKET_NORMAL: - case SHADER_SOCKET_POINT: - case SHADER_SOCKET_VECTOR: { - input->set(get_float3(b_sock.ptr, "default_value")); + case SocketType::NORMAL: + case SocketType::POINT: + case SocketType::VECTOR: { + node->set(socket, get_float3(b_sock.ptr, "default_value")); break; } - case SHADER_SOCKET_STRING: { - input->set((ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value"))); + case SocketType::STRING: { + node->set(socket, (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 +293,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 +319,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 +388,16 @@ 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_MULTI_GGX: + aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_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 +413,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 +431,19 @@ 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_ID; + break; + case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX: + glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; break; } node = glossy; @@ -469,13 +453,16 @@ 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; + case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX: + glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; break; } node = glass; @@ -485,13 +472,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 +488,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 +501,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; @@ -587,62 +574,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()); + node = manager->osl_node("", bytecode_hash, 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)); + string absolute_filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath()); + node = manager->osl_node(absolute_filepath, ""); } - - /* 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; - } - else { - /* set filepath */ - script_node->filepath = absolute_filepath; - } - - node = script_node; } #else (void)b_data; @@ -689,14 +631,14 @@ static ShaderNode *add_node(Scene *scene, /* TODO(sergey): Does not work properly when we change builtin type. */ if(b_image.is_updated()) { scene->image_manager->tag_reload_image( - image->filename, + image->filename.string(), image->builtin_data, get_image_interpolation(b_image_node), 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(); @@ -735,15 +677,15 @@ static ShaderNode *add_node(Scene *scene, /* TODO(sergey): Does not work properly when we change builtin type. */ if(b_image.is_updated()) { scene->image_manager->tag_reload_image( - env->filename, + env->filename.string(), env->builtin_data, get_image_interpolation(b_env_node), 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; @@ -751,7 +693,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; @@ -759,7 +701,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; @@ -775,8 +717,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; @@ -809,7 +751,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; @@ -827,7 +769,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(); @@ -838,15 +780,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; } @@ -861,8 +803,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; @@ -873,7 +814,7 @@ static ShaderNode *add_node(Scene *scene, if(true) { b_point_density_node.cache_point_density(b_scene, settings); scene->image_manager->tag_reload_image( - point_density->filename, + point_density->filename.string(), point_density->builtin_data, point_density->interpolation, EXTENSION_CLIP); @@ -1023,7 +964,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]; @@ -1046,7 +987,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); @@ -1058,7 +999,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,13 +1168,12 @@ void BlenderSync::sync_materials(bool update_all) add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree); } else { - ShaderNode *closure, *out; - - closure = graph->add(new DiffuseBsdfNode()); - closure->input("Color")->value = get_float3(b_mat->diffuse_color()); - out = graph->output(); + DiffuseBsdfNode *diffuse = new DiffuseBsdfNode(); + diffuse->color = get_float3(b_mat->diffuse_color()); + graph->add(diffuse); - graph->connect(closure->output("BSDF"), out->input("Surface")); + ShaderNode *out = graph->output(); + graph->connect(diffuse->output("BSDF"), out->input("Surface")); } /* settings */ @@ -1276,13 +1216,12 @@ void BlenderSync::sync_world(bool update_all) shader->volume_interpolation_method = get_volume_interpolation(cworld); } else if(b_world) { - ShaderNode *closure, *out; - - closure = graph->add(new BackgroundNode()); - closure->input("Color")->value = get_float3(b_world.horizon_color()); - out = graph->output(); + BackgroundNode *background = new BackgroundNode(); + background->color = get_float3(b_world.horizon_color()); + graph->add(background); - graph->connect(closure->output("Background"), out->input("Surface")); + ShaderNode *out = graph->output(); + graph->connect(background->output("Background"), out->input("Surface")); } if(b_world) { @@ -1361,7 +1300,6 @@ void BlenderSync::sync_lamps(bool update_all) add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree); } else { - ShaderNode *closure, *out; float strength = 1.0f; if(b_lamp->type() == BL::Lamp::type_POINT || @@ -1371,12 +1309,13 @@ void BlenderSync::sync_lamps(bool update_all) strength = 100.0f; } - closure = graph->add(new EmissionNode()); - closure->input("Color")->value = get_float3(b_lamp->color()); - closure->input("Strength")->value.x = strength; - out = graph->output(); + EmissionNode *emission = new EmissionNode(); + emission->color = get_float3(b_lamp->color()); + emission->strength = strength; + graph->add(emission); - graph->connect(closure->output("Emission"), out->input("Surface")); + ShaderNode *out = graph->output(); + graph->connect(emission->output("Emission"), out->input("Surface")); } shader->set_graph(graph); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 33084f1c163..e7e57b2be36 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -492,6 +492,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene, SceneParams::BVH_STATIC); params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); + params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh"); if(background && params.shadingsystem != SHADINGSYSTEM_OSL) params.persistent_data = r.use_persistent_data(); diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index d690adb5662..b8b9597914e 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -131,7 +131,9 @@ private: Transform& tfm, bool *use_portal); void sync_background_light(bool use_portal); - void sync_mesh_motion(BL::Object& b_ob, Object *object, float motion_time); + void sync_mesh_motion(BL::Object& b_ob, + Object *object, + float motion_time); void sync_camera_motion(BL::RenderSettings& b_render, BL::Object& b_ob, int width, int height, diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index e23d8bf4e2d..d5dbaba094b 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -45,14 +45,39 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data, BL::Scene& scene, bool apply_modifiers, bool render, - bool calc_undeformed) + bool calc_undeformed, + bool subdivision) { + bool subsurf_mod_show_render; + bool subsurf_mod_show_viewport; + + if(subdivision) { + BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1]; + + subsurf_mod_show_render = subsurf_mod.show_render(); + subsurf_mod_show_viewport = subsurf_mod.show_render(); + + subsurf_mod.show_render(false); + subsurf_mod.show_viewport(false); + + } + BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed); + + if(subdivision) { + BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1]; + + subsurf_mod.show_render(subsurf_mod_show_render); + subsurf_mod.show_viewport(subsurf_mod_show_viewport); + } + if((bool)me) { if(me.use_auto_smooth()) { me.calc_normals_split(); } - me.calc_tessface(true); + if(!subdivision) { + me.calc_tessface(true); + } } return me; } @@ -98,11 +123,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); @@ -518,6 +544,23 @@ static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object& b_ob) return BL::SmokeDomainSettings(PointerRNA_NULL); } +static inline BL::DomainFluidSettings object_fluid_domain_find(BL::Object b_ob) +{ + BL::Object::modifiers_iterator b_mod; + + for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) { + if(b_mod->is_a(&RNA_FluidSimulationModifier)) { + BL::FluidSimulationModifier b_fmd(*b_mod); + BL::FluidSettings fss = b_fmd.settings(); + + if(fss.type() == BL::FluidSettings::type_DOMAIN) + return (BL::DomainFluidSettings)b_fmd.settings(); + } + } + + return BL::DomainFluidSettings(PointerRNA_NULL); +} + /* ID Map * * Utility class to keep in sync with blender data. |