Cycles microdisplacement: move subdivision options to subsurf modifier
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
This commit is contained in:
@@ -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)
|
||||
|
@@ -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"
|
||||
|
@@ -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) {
|
||||
|
@@ -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();
|
||||
|
@@ -175,6 +175,8 @@ Mesh::Mesh()
|
||||
has_surface_bssrdf = false;
|
||||
|
||||
num_ngons = 0;
|
||||
|
||||
subdivision_type = SUBDIVISION_NONE;
|
||||
}
|
||||
|
||||
Mesh::~Mesh()
|
||||
|
@@ -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,
|
||||
|
@@ -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:")
|
||||
|
Reference in New Issue
Block a user