Cycles microdisplacement: move subdivision options to subsurf modifier
authorMai Lavelle <mai.lavelle@gmail.com>
Sat, 16 Jul 2016 23:56:45 +0000 (19:56 -0400)
committerMai Lavelle <mai.lavelle@gmail.com>
Fri, 29 Jul 2016 07:37:55 +0000 (03:37 -0400)
Subdivision options can now be found in the subsurf modifier. The modifier must
be the last in the stack or the options will be unavailable. Catmull-Clark
subdivision is still unavailable and will fallback to linear subdivision instead

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2109

intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_util.h
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h
release/scripts/startup/bl_ui/properties_data_modifier.py

index 0b3dd552f62a31363a8308c7f5c7fa84b3ba4085..79b77516ae71277fc5aef06c297afcccbbc37894 100644 (file)
@@ -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"),
@@ -964,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):
@@ -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,20 @@ 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 +1130,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 +1142,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)
index 6656beb4478ea4228788a984c5185ac8e0dcd0e5..58c30a2d15a4172f638e7e68b45ce1406a867667 100644 (file)
@@ -708,14 +708,6 @@ class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel):
         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"
index 0744bbf1a0a51843f7c34e653f6f1d3e6997d1cc..a8f006f46239b01dc29f43f8d75461d78c29b178 100644 (file)
@@ -774,7 +774,10 @@ static void create_subd_mesh(Scene *scene,
        create_mesh(scene, mesh, b_mesh, used_shaders, true);
 
        SubdParams sdparams(mesh);
-       sdparams.dicing_rate = max(0.1f, RNA_float_get(cmesh, "dicing_rate") * dicing_rate);
+
+       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();
@@ -925,12 +928,32 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
                        b_ob.update_from_editmode();
 
                bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
-               bool subdivision = experimental && cmesh.data && RNA_enum_get(&cmesh, "subdivision_type");
-               BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed, subdivision);
+
+               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(subdivision)
+                               if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
                                        create_subd_mesh(scene, mesh, b_ob, b_mesh, &cmesh, used_shaders,
                                                         dicing_rate, max_subdivisions);
                                else
@@ -939,7 +962,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
                                create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
                        }
 
-                       if(render_layer.use_hair && !subdivision)
+                       if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
                                sync_curves(mesh, b_mesh, b_ob, false);
 
                        if(can_free_caches) {
index 34405c3ea1affb32b2f5d9beff1631ebe59e0f73..d5dbaba094b87e9225105c7fb6fd063666453e2d 100644 (file)
@@ -48,7 +48,29 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
                                       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();
index 8d7c8fa9adbb1f1b7be4e1f56de9366ab6ba0e55..9692e684c0a959268920f28e55a3da660158ecb2 100644 (file)
@@ -175,6 +175,8 @@ Mesh::Mesh()
        has_surface_bssrdf = false;
 
        num_ngons = 0;
+
+       subdivision_type = SUBDIVISION_NONE;
 }
 
 Mesh::~Mesh()
index adb639201ce61850dbb2cbd8f758e6c143207ab4..c9ae9aab8889db215a5f704b2b922be32d91cdbc 100644 (file)
@@ -119,6 +119,14 @@ public:
                DISPLACE_NUM_METHODS,
        };
 
+       enum SubdivisionType {
+               SUBDIVISION_NONE,
+               SUBDIVISION_LINEAR,
+               SUBDIVISION_CATMULL_CLARK,
+       };
+
+       SubdivisionType subdivision_type;
+
        /* Mesh Data */
        enum GeometryFlags {
                GEOMETRY_NONE      = 0,
index c6bb6ccf05f4ef405282b4b6aa3f5765d0f6c13c..6f53ae6e11878168269a9d9d07c73ae67be7eaf5 100644 (file)
@@ -879,9 +879,21 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
 
         split = layout.split()
         col = split.column()
-        col.label(text="Subdivisions:")
-        col.prop(md, "levels", text="View")
-        col.prop(md, "render_levels", text="Render")
+
+        engine = bpy.context.scene.render.engine
+        if engine == "CYCLES" and md == ob.modifiers[-1] and bpy.context.scene.cycles.feature_set == "EXPERIMENTAL":
+            col.label(text="Preview:")
+            col.prop(md, "levels", text="Levels")
+            col.label(text="Render:")
+            col.prop(ob.cycles, "use_adaptive_subdivision", text="Adaptive")
+            if ob.cycles.use_adaptive_subdivision:
+                col.prop(ob.cycles, "dicing_rate")
+            else:
+                col.prop(md, "render_levels", text="Levels")
+        else:
+            col.label(text="Subdivisions:")
+            col.prop(md, "levels", text="View")
+            col.prop(md, "render_levels", text="Render")
 
         col = split.column()
         col.label(text="Options:")