diff options
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/addon/osl.py | 6 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 51 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 51 | ||||
-rw-r--r-- | intern/cycles/blender/addon/version_update.py | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 372 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 32 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 29 |
9 files changed, 355 insertions, 203 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/osl.py b/intern/cycles/blender/addon/osl.py index f4aaaab5eab..19f2ecc9d1a 100644 --- a/intern/cycles/blender/addon/osl.py +++ b/intern/cycles/blender/addon/osl.py @@ -41,6 +41,8 @@ def update_script_node(node, report): import shutil import tempfile + oso_file_remove = False + if node.mode == 'EXTERNAL': # compile external script file script_path = bpy.path.abspath(node.filepath, library=node.id_data.library) @@ -49,7 +51,6 @@ def update_script_node(node, report): if script_ext == ".oso": # it's a .oso file, no need to compile ok, oso_path = True, script_path - oso_file_remove = False elif script_ext == ".osl": # compile .osl file ok, oso_path = osl_compile(script_path, report) @@ -65,7 +66,6 @@ def update_script_node(node, report): elif os.path.dirname(node.filepath) == "": # module in search path oso_path = node.filepath - oso_file_remove = False ok = True else: # unknown @@ -88,12 +88,10 @@ def update_script_node(node, report): osl_file.close() ok, oso_path = osl_compile(osl_file.name, report) - oso_file_remove = False os.remove(osl_file.name) else: # compile text datablock from disk directly ok, oso_path = osl_compile(osl_path, report) - oso_file_remove = False if ok: # read bytecode diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 0b3dd552f62..8e82eac2b59 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"), @@ -781,6 +775,13 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup): default='LINEAR', ) + cls.displacement_method = EnumProperty( + name="Displacement Method", + description="Method to use for the displacement", + items=enum_displacement_methods, + default='BUMP', + ) + @classmethod def unregister(cls): del bpy.types.Material.cycles @@ -958,25 +959,6 @@ class CyclesMeshSettings(bpy.types.PropertyGroup): type=cls, ) - cls.displacement_method = EnumProperty( - name="Displacement Method", - description="Method to use for the displacement", - 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): del bpy.types.Mesh.cycles @@ -984,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", @@ -1020,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 @@ -1136,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) @@ -1147,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 6656beb4478..52872d2b83f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -674,48 +674,6 @@ class Cycles_PT_context_material(CyclesButtonsPanel, Panel): split.separator() -class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel): - bl_label = "Displacement" - bl_context = "data" - - @classmethod - def poll(cls, context): - if CyclesButtonsPanel.poll(context): - if context.mesh or context.curve or context.meta_ball: - if context.scene.cycles.feature_set == 'EXPERIMENTAL': - return True - - return False - - def draw(self, context): - layout = self.layout - - mesh = context.mesh - curve = context.curve - mball = context.meta_ball - - if mesh: - cdata = mesh.cycles - elif curve: - cdata = curve.cycles - elif mball: - cdata = mball.cycles - - split = layout.split() - - col = split.column() - sub = col.column(align=True) - 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" @@ -895,7 +853,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) @@ -1115,7 +1073,7 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel): world = context.world cworld = world.cycles - cscene = context.scene.cycles + # cscene = context.scene.cycles split = layout.split() @@ -1227,6 +1185,11 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel): col.prop(cmat, "sample_as_light", text="Multiple Importance") col.prop(cmat, "use_transparent_shadow") + if context.scene.cycles.feature_set == 'EXPERIMENTAL': + col.separator() + col.label(text="Displacement:") + col.prop(cmat, "displacement_method", text="") + col = split.column() col.label(text="Volume:") sub = col.column() 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_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index ec11a893b5a..5d63aaa1415 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,45 @@ 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, + bool subdivide_uvs) { - 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); + + if(subdivide_uvs) { + attr->flags |= ATTR_SUBDIVIDED; + } + + 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 +527,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,30 +596,45 @@ 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, + bool subdivide_uvs=true) { /* 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(); + } } /* allocate memory */ mesh->reserve_mesh(numverts, numtris); + mesh->reserve_subd_faces(numfaces, numngons, numcorners); /* create vertex coordinates and normals */ 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) @@ -564,7 +643,8 @@ 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); + attr->flags |= ATTR_SUBDIVIDED; float3 loc, size; mesh_texture_space(b_mesh, loc, size); @@ -577,67 +657,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; - 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; + 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->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; + /* 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->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; + mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); } + + nverts[fi] = n; } - else - mesh->add_triangle(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; - nverts[fi] = n; + 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; + } + } + } + + /* 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, subdivide_uvs); /* for volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can @@ -657,16 +773,44 @@ 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); + BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]); + bool subdivide_uvs = subsurf_mod.use_subsurf_uv(); + + create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs); + + /* export creases */ + size_t num_creases = 0; + BL::Mesh::edges_iterator e; + + for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { + if(e->crease() != 0.0f) { + num_creases++; + } + } + + mesh->subd_creases.resize(num_creases); - SubdParams sdparams(mesh, 0, true, false); - sdparams.dicing_rate = max(0.1f, RNA_float_get(cmesh, "dicing_rate") * dicing_rate); + Mesh::SubdEdgeCrease* crease = mesh->subd_creases.data(); + for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { + if(e->crease() != 0.0f) { + crease->v[0] = e->vertices()[0]; + crease->v[1] = e->vertices()[1]; + crease->crease = e->crease(); + + crease++; + } + } + + /* set subd params */ + 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(); @@ -675,7 +819,7 @@ static void create_subd_mesh(Scene *scene, /* tesselate */ DiagSplit dsplit(sdparams); - basemesh.tessellate(&dsplit); + mesh->tessellate(&dsplit); } /* Sync */ @@ -793,8 +937,6 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, mesh_synced.insert(mesh); /* create derived mesh */ - PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles"); - array<int> oldtriangle = mesh->triangles; /* compares curve_keys rather than strands in order to handle quick hair @@ -817,20 +959,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) { @@ -843,21 +1006,6 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, } mesh->geometry_flags = requested_geometry_flags; - /* displacement method */ - if(cmesh.data) { - const int method = get_enum(cmesh, - "displacement_method", - Mesh::DISPLACE_NUM_METHODS, - Mesh::DISPLACE_BUMP); - - if(method == 0 || !experimental) - mesh->displacement_method = Mesh::DISPLACE_BUMP; - else if(method == 1) - mesh->displacement_method = Mesh::DISPLACE_TRUE; - else - mesh->displacement_method = Mesh::DISPLACE_BOTH; - } - /* fluid motion */ sync_mesh_fluid_motion(b_ob, scene, mesh); @@ -957,7 +1105,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob, 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) { diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 22a0b3988c8..f305e8e17cc 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -253,8 +253,18 @@ static bool object_boundbox_clip(Scene *scene, boundbox[3 * i + 1], boundbox[3 * i + 2]); p = transform_point(&tfm, p); - p = transform_perspective(&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; } bb_min = min(bb_min, p); @@ -319,16 +329,18 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, /* object transformation */ if(tfm != object->tfm) { VLOG(1) << "Object " << b_ob.name() << " motion detected."; - if(motion_time == -1.0f) { - object->motion.pre = tfm; - object->use_motion = true; - } - else if(motion_time == 1.0f) { - object->motion.post = tfm; + if(motion_time == -1.0f || motion_time == 1.0f) { object->use_motion = true; } } + if(motion_time == -1.0f) { + object->motion.pre = tfm; + } + else if(motion_time == 1.0f) { + object->motion.post = tfm; + } + /* mesh deformation */ if(object->mesh) sync_mesh_motion(b_ob, object, motion_time); @@ -385,8 +397,8 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, object->name = b_ob.name().c_str(); object->pass_id = b_ob.pass_index(); object->tfm = tfm; - object->motion.pre = tfm; - object->motion.post = tfm; + object->motion.pre = transform_empty(); + object->motion.post = transform_empty(); object->use_motion = false; /* motion blur */ diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 64559804ccb..534bc6cc897 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -64,6 +64,14 @@ static VolumeInterpolation get_volume_interpolation(PointerRNA& ptr) VOLUME_INTERPOLATION_LINEAR); } +static DisplacementMethod get_displacement_method(PointerRNA& ptr) +{ + return (DisplacementMethod)get_enum(ptr, + "displacement_method", + DISPLACE_NUM_METHODS, + DISPLACE_BUMP); +} + static int validate_enum_value(int value, int num_values, int default_value) { if(value >= num_values) { @@ -837,8 +845,10 @@ static ShaderNode *add_node(Scene *scene, } } - if(node) + if(node) { + node->name = b_node.name(); graph->add(node); + } return node; } @@ -1180,6 +1190,7 @@ void BlenderSync::sync_materials(bool update_all) shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume"); shader->volume_sampling_method = get_volume_sampling(cmat); shader->volume_interpolation_method = get_volume_interpolation(cmat); + shader->displacement_method = (experimental) ? get_displacement_method(cmat) : DISPLACE_BUMP; shader->set_graph(graph); shader->tag_update(scene); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 188d23d0c59..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; } |