Improvements of Freestyle GUI controls - Part 1.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Sun, 28 Oct 2012 16:09:51 +0000 (16:09 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Sun, 28 Oct 2012 16:09:51 +0000 (16:09 +0000)
This commit makes a set of fixes and improvements based on the results of
Freestyle branch review by Brecht.  The discussion thread is:
http://lists.blender.org/pipermail/bf-committers/2012-October/037927.html

* The Layers panel and Freestyle-related panels in the Render tab of the
Properties window were moved to the newly created Render Layers tab.
The idea is to separate per render layer rendering options into a distinct
Properties window tab, and use the existing Render tab to accommodate
per scene rendering options.

* The new Freestyle panel was added in the Render tab.  The panel header
contains a toggle button for globally enabling Freestyle, with the aim of making
Freestyle easier to find.  Those Freestyle options in the Post Processing panel
were also moved to the new panel.

* GUI code was updated so that UI controls will be greyed out (instead of
being hidden) when Freestyle is disabled.  Additional UI changes were also
made to reduce space consumption.

* The list of line sets was moved from the Freestyle panel to the Freestyle:
Line Sets panel.

* Old ray-casting algorithms were removed from the UI.  Now only two
algorithms (culled and non-culled cumulative visibility detection algorithms)
are available, and the selection is done by the new "Culling" toggle button
within the edge detection options.

14 files changed:
release/datafiles/startup.blend
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/properties_render_layer.py [new file with mode: 0644]
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/buttons_header.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
source/blender/makesdna/DNA_freestyle_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/intern/rna_linestyle.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_space.c

index 8b0e052fad83d23c6f608d89256a9054b9e9e836..dee58249bde0d68aaba0e59114408373cafd6b63 100644 (file)
Binary files a/release/datafiles/startup.blend and b/release/datafiles/startup.blend differ
index e4be84d53969ae67410a4d8e8455b77dfe18ecc9..ecae4b2d721894bdb1135290cfb50cd24fb4aa9c 100644 (file)
@@ -51,6 +51,7 @@ _modules = (
     "properties_physics_smoke",
     "properties_physics_softbody",
     "properties_render",
+    "properties_render_layer",
     "properties_scene",
     "properties_texture",
     "properties_world",
index bae0a390ff74a407fb184d1eaa1312700bc4c6e7..33ce0e07f177ff13b4369c2e934e69ddd7b73088 100644 (file)
@@ -71,660 +71,6 @@ class RENDER_PT_render(RenderButtonsPanel, Panel):
         layout.prop(rd, "display_mode", text="Display")
 
 
-class RENDER_PT_layers(RenderButtonsPanel, Panel):
-    bl_label = "Layers"
-    bl_options = {'DEFAULT_CLOSED'}
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    def draw(self, context):
-        layout = self.layout
-
-        scene = context.scene
-        rd = scene.render
-
-        row = layout.row()
-        row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
-
-        col = row.column(align=True)
-        col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
-        col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
-
-        row = layout.row()
-        rl = rd.layers.active
-        if rl:
-            row.prop(rl, "name")
-        row.prop(rd, "use_single_layer", text="", icon_only=True)
-
-        split = layout.split()
-
-        col = split.column()
-        col.prop(scene, "layers", text="Scene")
-        col.label(text="")
-        col.prop(rl, "light_override", text="Light")
-        col.prop(rl, "material_override", text="Material")
-
-        col = split.column()
-        col.prop(rl, "layers", text="Layer")
-        col.label(text="Mask Layers:")
-        col.prop(rl, "layers_zmask", text="")
-
-        layout.separator()
-        layout.label(text="Include:")
-
-        split = layout.split()
-
-        col = split.column()
-        col.prop(rl, "use_zmask")
-        row = col.row()
-        row.prop(rl, "invert_zmask", text="Negate")
-        row.active = rl.use_zmask
-        col.prop(rl, "use_all_z")
-
-        col = split.column()
-        col.prop(rl, "use_solid")
-        col.prop(rl, "use_halo")
-        col.prop(rl, "use_ztransp")
-        col.prop(rl, "use_sky")
-
-        col = split.column()
-        col.prop(rl, "use_edge_enhance")
-        col.prop(rl, "use_strand")
-        col.prop(rl, "use_freestyle")
-
-        layout.separator()
-
-        split = layout.split()
-
-        col = split.column()
-        col.label(text="Passes:")
-        col.prop(rl, "use_pass_combined")
-        col.prop(rl, "use_pass_z")
-        col.prop(rl, "use_pass_vector")
-        col.prop(rl, "use_pass_normal")
-        col.prop(rl, "use_pass_uv")
-        col.prop(rl, "use_pass_mist")
-        col.prop(rl, "use_pass_object_index")
-        col.prop(rl, "use_pass_material_index")
-        col.prop(rl, "use_pass_color")
-
-        col = split.column()
-        col.label()
-        col.prop(rl, "use_pass_diffuse")
-        row = col.row()
-        row.prop(rl, "use_pass_specular")
-        row.prop(rl, "exclude_specular", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_shadow")
-        row.prop(rl, "exclude_shadow", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_emit")
-        row.prop(rl, "exclude_emit", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_ambient_occlusion")
-        row.prop(rl, "exclude_ambient_occlusion", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_environment")
-        row.prop(rl, "exclude_environment", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_indirect")
-        row.prop(rl, "exclude_indirect", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_reflection")
-        row.prop(rl, "exclude_reflection", text="")
-        row = col.row()
-        row.prop(rl, "use_pass_refraction")
-        row.prop(rl, "exclude_refraction", text="")
-
-
-class RENDER_MT_lineset_specials(Menu):
-    bl_label = "Lineset Specials"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator("scene.freestyle_lineset_copy", icon='COPYDOWN')
-        layout.operator("scene.freestyle_lineset_paste", icon='PASTEDOWN')
-
-
-class RENDER_PT_freestyle(RenderButtonsPanel, Panel):
-    bl_label = "Freestyle"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    @classmethod
-    def poll(cls, context):
-        rd = context.scene.render
-        if rd.engine not in cls.COMPAT_ENGINES:
-            return False
-        rl = rd.layers.active
-        return rl and rl.use_freestyle
-
-    def draw(self, context):
-        layout = self.layout
-
-        rd = context.scene.render
-        rl = rd.layers.active
-        freestyle = rl.freestyle_settings
-
-        split = layout.split()
-
-        col = split.column()
-        col.prop(freestyle, "raycasting_algorithm", text="Raycasting Algorithm")
-        col.prop(freestyle, "mode", text="Control Mode")
-
-        col.label(text="Edge Detection Options:")
-        col.prop(freestyle, "use_smoothness")
-        col.prop(freestyle, "crease_angle")
-        if freestyle.mode == "SCRIPT":
-            col.prop(freestyle, "use_material_boundaries")
-            col.prop(freestyle, "use_ridges_and_valleys")
-            col.prop(freestyle, "use_suggestive_contours")
-        col.prop(freestyle, "use_advanced_options")
-        if freestyle.use_advanced_options:
-            col.prop(freestyle, "sphere_radius")
-            col.prop(freestyle, "kr_derivative_epsilon")
-
-        if freestyle.mode == "EDITOR":
-
-            lineset = freestyle.linesets.active
-
-            col.label(text="Line Sets:")
-            row = col.row()
-            rows = 2
-            if lineset:
-                rows = 5
-            row.template_list(freestyle, "linesets", freestyle.linesets, "active_index", rows=rows)
-
-            sub = row.column()
-            subsub = sub.column(align=True)
-            subsub.operator("scene.freestyle_lineset_add", icon='ZOOMIN', text="")
-            subsub.operator("scene.freestyle_lineset_remove", icon='ZOOMOUT', text="")
-            subsub.menu("RENDER_MT_lineset_specials", icon='DOWNARROW_HLT', text="")
-            if lineset:
-                sub.separator()
-                subsub = sub.column(align=True)
-                subsub.operator("scene.freestyle_lineset_move", icon='TRIA_UP', text="").direction = 'UP'
-                subsub.operator("scene.freestyle_lineset_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
-
-        else: # freestyle.mode == "SCRIPT"
-
-            col.separator()
-            col.operator("scene.freestyle_module_add")
-
-            for i, module in enumerate(freestyle.modules):
-                box = layout.box()
-                box.context_pointer_set("freestyle_module", module)
-                row = box.row(align=True)
-                row.prop(module, "use", text="")
-                row.prop(module, "module_path", text="")
-                row.operator("scene.freestyle_module_remove", icon='X', text="")
-                row.operator("scene.freestyle_module_move", icon='TRIA_UP', text="").direction = 'UP'
-                row.operator("scene.freestyle_module_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
-
-
-class RENDER_PT_freestyle_lineset(RenderButtonsPanel, Panel):
-    bl_label = "Freestyle: Line Set"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    @classmethod
-    def poll(cls, context):
-        rd = context.scene.render
-        if rd.engine not in cls.COMPAT_ENGINES:
-            return False
-        rl = rd.layers.active
-        if rl and rl.use_freestyle:
-            freestyle = rl.freestyle_settings
-            return freestyle.mode == "EDITOR" and freestyle.linesets.active
-        return False
-
-    def draw_edge_type_buttons(self, box, lineset, edge_type):
-        # property names
-        select_edge_type = "select_" + edge_type
-        exclude_edge_type = "exclude_" + edge_type
-        # draw edge type buttons
-        row = box.row(align=True)
-        row.prop(lineset, select_edge_type)
-        sub = row.column()
-        sub.prop(lineset, exclude_edge_type, text="")
-        sub.enabled = getattr(lineset, select_edge_type)
-
-    def draw(self, context):
-        layout = self.layout
-
-        rd = context.scene.render
-        rl = rd.layers.active
-        freestyle = rl.freestyle_settings
-        lineset = freestyle.linesets.active
-
-        split = layout.split()
-
-        col = split.column()
-        col.prop(lineset, "name")
-
-        col.prop(lineset, "select_by_visibility")
-        if lineset.select_by_visibility:
-            sub = col.row(align=True)
-            sub.prop(lineset, "visibility", expand=True)
-            if lineset.visibility == "RANGE":
-                sub = col.row(align=True)
-                sub.prop(lineset, "qi_start")
-                sub.prop(lineset, "qi_end")
-            col.separator() # XXX
-
-        col.prop(lineset, "select_by_edge_types")
-        if lineset.select_by_edge_types:
-            row = col.row()
-            row.prop(lineset, "edge_type_negation", expand=True)
-            row = col.row()
-            row.prop(lineset, "edge_type_combination", expand=True)
-
-            row = col.row()
-            sub = row.column()
-            self.draw_edge_type_buttons(sub, lineset, "silhouette")
-            self.draw_edge_type_buttons(sub, lineset, "border")
-            self.draw_edge_type_buttons(sub, lineset, "contour")
-            self.draw_edge_type_buttons(sub, lineset, "suggestive_contour")
-            self.draw_edge_type_buttons(sub, lineset, "ridge_valley")
-            sub = row.column()
-            self.draw_edge_type_buttons(sub, lineset, "crease")
-            self.draw_edge_type_buttons(sub, lineset, "edge_mark")
-            self.draw_edge_type_buttons(sub, lineset, "external_contour")
-            self.draw_edge_type_buttons(sub, lineset, "material_boundary")
-            col.separator() # XXX
-
-        col.prop(lineset, "select_by_face_marks")
-        if lineset.select_by_face_marks:
-            row = col.row()
-            row.prop(lineset, "face_mark_negation", expand=True)
-            row = col.row()
-            row.prop(lineset, "face_mark_condition", expand=True)
-            col.separator() # XXX
-
-        col.prop(lineset, "select_by_group")
-        if lineset.select_by_group:
-            col.prop(lineset, "group")
-            row = col.row()
-            row.prop(lineset, "group_negation", expand=True)
-            col.separator() # XXX
-
-        col.prop(lineset, "select_by_image_border")
-
-
-class RENDER_PT_freestyle_linestyle(RenderButtonsPanel, Panel):
-    bl_label = "Freestyle: Line Style"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
-
-    @classmethod
-    def poll(cls, context):
-        rd = context.scene.render
-        if rd.engine not in cls.COMPAT_ENGINES:
-            return False
-        rl = rd.layers.active
-        if rl and rl.use_freestyle:
-            freestyle = rl.freestyle_settings
-            return freestyle.mode == "EDITOR" and freestyle.linesets.active
-        return False
-
-    def draw_modifier_box_header(self, box, modifier):
-        row = box.row()
-        row.context_pointer_set("modifier", modifier)
-        if modifier.expanded:
-            icon = "TRIA_DOWN"
-        else:
-            icon = "TRIA_RIGHT"
-        row.prop(modifier, "expanded", text="", icon=icon, emboss=False)
-        row.label(text=modifier.rna_type.name)
-        row.prop(modifier, "name", text="")
-        row.prop(modifier, "use", text="")
-        row.operator("scene.freestyle_modifier_copy", icon='NONE', text="Copy")
-        sub = row.row(align=True)
-        sub.operator("scene.freestyle_modifier_move", icon='TRIA_UP', text="").direction = 'UP'
-        sub.operator("scene.freestyle_modifier_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
-        row.operator("scene.freestyle_modifier_remove", icon='X', text="")
-
-    def draw_modifier_common(self, box, modifier):
-        row = box.row()
-        row.prop(modifier, "blend", text="")
-        row.prop(modifier, "influence")
-
-    def draw_modifier_color_ramp_common(self, box, modifier, has_range):
-        box.template_color_ramp(modifier, "color_ramp", expand=True)
-        if has_range:
-            row = box.row(align=True)
-            row.prop(modifier, "range_min")
-            row.prop(modifier, "range_max")
-
-    def draw_modifier_curve_common(self, box, modifier, has_range, has_value):
-        row = box.row()
-        row.prop(modifier, "mapping", text="")
-        sub = row.column()
-        sub.prop(modifier, "invert")
-        if modifier.mapping == "CURVE":
-            sub.enabled = False
-            box.template_curve_mapping(modifier, "curve")
-        if has_range:
-            row = box.row(align=True)
-            row.prop(modifier, "range_min")
-            row.prop(modifier, "range_max")
-        if has_value:
-            row = box.row(align=True)
-            row.prop(modifier, "value_min")
-            row.prop(modifier, "value_max")
-
-    def draw_color_modifier(self, context, modifier):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        self.draw_modifier_box_header(col.box(), modifier)
-        if modifier.expanded:
-            box = col.box()
-            self.draw_modifier_common(box, modifier)
-
-            if modifier.type == "ALONG_STROKE":
-                self.draw_modifier_color_ramp_common(box, modifier, False)
-
-            elif modifier.type == "DISTANCE_FROM_OBJECT":
-                box.prop(modifier, "target")
-                self.draw_modifier_color_ramp_common(box, modifier, True)
-                prop = box.operator("scene.freestyle_fill_range_by_selection")
-                prop.type = 'COLOR'
-                prop.name = modifier.name
-
-            elif modifier.type == "DISTANCE_FROM_CAMERA":
-                self.draw_modifier_color_ramp_common(box, modifier, True)
-                prop = box.operator("scene.freestyle_fill_range_by_selection")
-                prop.type = 'COLOR'
-                prop.name = modifier.name
-
-            elif modifier.type == "MATERIAL":
-                row = box.row()
-                row.prop(modifier, "material_attr", text="")
-                sub = row.column()
-                sub.prop(modifier, "use_ramp")
-                if modifier.material_attr in ["DIFF", "SPEC"]:
-                    sub.enabled = True
-                    show_ramp = modifier.use_ramp
-                else:
-                    sub.enabled = False
-                    show_ramp = True
-                if show_ramp:
-                    self.draw_modifier_color_ramp_common(box, modifier, False)
-
-    def draw_alpha_modifier(self, context, modifier):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        self.draw_modifier_box_header(col.box(), modifier)
-        if modifier.expanded:
-            box = col.box()
-            self.draw_modifier_common(box, modifier)
-
-            if modifier.type == "ALONG_STROKE":
-                self.draw_modifier_curve_common(box, modifier, False, False)
-
-            elif modifier.type == "DISTANCE_FROM_OBJECT":
-                box.prop(modifier, "target")
-                self.draw_modifier_curve_common(box, modifier, True, False)
-                prop = box.operator("scene.freestyle_fill_range_by_selection")
-                prop.type = 'ALPHA'
-                prop.name = modifier.name
-
-            elif modifier.type == "DISTANCE_FROM_CAMERA":
-                self.draw_modifier_curve_common(box, modifier, True, False)
-                prop = box.operator("scene.freestyle_fill_range_by_selection")
-                prop.type = 'ALPHA'
-                prop.name = modifier.name
-
-            elif modifier.type == "MATERIAL":
-                box.prop(modifier, "material_attr", text="")
-                self.draw_modifier_curve_common(box, modifier, False, False)
-
-    def draw_thickness_modifier(self, context, modifier):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        self.draw_modifier_box_header(col.box(), modifier)
-        if modifier.expanded:
-            box = col.box()
-            self.draw_modifier_common(box, modifier)
-
-            if modifier.type == "ALONG_STROKE":
-                self.draw_modifier_curve_common(box, modifier, False, True)
-
-            elif modifier.type == "DISTANCE_FROM_OBJECT":
-                box.prop(modifier, "target")
-                self.draw_modifier_curve_common(box, modifier, True, True)
-                prop = box.operator("scene.freestyle_fill_range_by_selection")
-                prop.type = 'THICKNESS'
-                prop.name = modifier.name
-
-            elif modifier.type == "DISTANCE_FROM_CAMERA":
-                self.draw_modifier_curve_common(box, modifier, True, True)
-                prop = box.operator("scene.freestyle_fill_range_by_selection")
-                prop.type = 'THICKNESS'
-                prop.name = modifier.name
-
-            elif modifier.type == "MATERIAL":
-                box.prop(modifier, "material_attr", text="")
-                self.draw_modifier_curve_common(box, modifier, False, True)
-
-            elif modifier.type == "CALLIGRAPHY":
-                col = box.column()
-                col.prop(modifier, "orientation")
-                col.prop(modifier, "min_thickness")
-                col.prop(modifier, "max_thickness")
-
-    def draw_geometry_modifier(self, context, modifier):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        self.draw_modifier_box_header(col.box(), modifier)
-        if modifier.expanded:
-            box = col.box()
-
-            if modifier.type == "SAMPLING":
-                box.prop(modifier, "sampling")
-
-            elif modifier.type == "BEZIER_CURVE":
-                box.prop(modifier, "error")
-
-            elif modifier.type == "SINUS_DISPLACEMENT":
-                box.prop(modifier, "wavelength")
-                box.prop(modifier, "amplitude")
-                box.prop(modifier, "phase")
-
-            elif modifier.type == "SPATIAL_NOISE":
-                box.prop(modifier, "amplitude")
-                box.prop(modifier, "scale")
-                box.prop(modifier, "octaves")
-                sub = box.row()
-                sub.prop(modifier, "smooth")
-                sub.prop(modifier, "pure_random")
-
-            elif modifier.type == "PERLIN_NOISE_1D":
-                box.prop(modifier, "frequency")
-                box.prop(modifier, "amplitude")
-                box.prop(modifier, "octaves")
-                box.prop(modifier, "angle")
-                box.prop(modifier, "seed")
-
-            elif modifier.type == "PERLIN_NOISE_2D":
-                box.prop(modifier, "frequency")
-                box.prop(modifier, "amplitude")
-                box.prop(modifier, "octaves")
-                box.prop(modifier, "angle")
-                box.prop(modifier, "seed")
-
-            elif modifier.type == "BACKBONE_STRETCHER":
-                box.prop(modifier, "backbone_length")
-
-            elif modifier.type == "TIP_REMOVER":
-                box.prop(modifier, "tip_length")
-
-            elif modifier.type == "POLYGONIZATION":
-                box.prop(modifier, "error")
-
-            elif modifier.type == "GUIDING_LINES":
-                box.prop(modifier, "offset")
-
-            elif modifier.type == "BLUEPRINT":
-                row = box.row()
-                row.prop(modifier, "shape", expand=True)
-                box.prop(modifier, "rounds")
-                if modifier.shape in ["CIRCLES", "ELLIPSES"]:
-                    box.prop(modifier, "random_radius")
-                    box.prop(modifier, "random_center")
-                elif modifier.shape == "SQUARES":
-                    box.prop(modifier, "backbone_length")
-                    box.prop(modifier, "random_backbone")
-
-            elif modifier.type == "2D_OFFSET":
-                row = box.row(align=True)
-                row.prop(modifier, "start")
-                row.prop(modifier, "end")
-                row = box.row(align=True)
-                row.prop(modifier, "x")
-                row.prop(modifier, "y")
-
-            elif modifier.type == "2D_TRANSFORM":
-                box.prop(modifier, "pivot")
-                if modifier.pivot == "PARAM":
-                    box.prop(modifier, "pivot_u")
-                elif modifier.pivot == "ABSOLUTE":
-                    row = box.row(align=True)
-                    row.prop(modifier, "pivot_x")
-                    row.prop(modifier, "pivot_y")
-                row = box.row(align=True)
-                row.prop(modifier, "scale_x")
-                row.prop(modifier, "scale_y")
-                box.prop(modifier, "angle")
-
-    def draw(self, context):
-        layout = self.layout
-
-        rd = context.scene.render
-        rl = rd.layers.active
-        lineset = rl.freestyle_settings.linesets.active
-        linestyle = lineset.linestyle
-
-        layout.template_ID(lineset, "linestyle", new="scene.freestyle_linestyle_new")
-        row = layout.row(align=True)
-        row.prop(linestyle, "panel", expand=True)
-        if linestyle.panel == "STROKES":
-            # Chaining
-            col = layout.column()
-            col.prop(linestyle, "use_chaining", text="Chaining:")
-            sub = col.column()
-            sub.enabled = linestyle.use_chaining
-            sub.prop(linestyle, "chaining", text="")
-            if linestyle.chaining == "PLAIN":
-                sub.prop(linestyle, "same_object")
-            elif linestyle.chaining == "SKETCHY":
-                subsub = sub.row()
-                subsub.prop(linestyle, "same_object")
-                subsub.prop(linestyle, "rounds")
-            # Splitting
-            col = layout.column()
-            col.label(text="Splitting:")
-            row = col.row()
-            row.prop(linestyle, "material_boundary")
-            row = col.row()
-            sub = row.column()
-            sub.prop(linestyle, "use_min_angle", text="Min 2D Angle")
-            subsub = sub.split()
-            subsub.prop(linestyle, "min_angle", text="")
-            subsub.enabled = linestyle.use_min_angle
-            sub = row.column()
-            sub.prop(linestyle, "use_max_angle", text="Max 2D Angle")
-            subsub = sub.split()
-            subsub.prop(linestyle, "max_angle", text="")
-            subsub.enabled = linestyle.use_max_angle
-            col.prop(linestyle, "use_split_length", text="2D Length")
-            row = col.row()
-            row.prop(linestyle, "split_length", text="")
-            row.enabled = linestyle.use_split_length
-            # Selection
-            col = layout.column()
-            col.label(text="Selection:")
-            sub = col.row()
-            subcol = sub.column()
-            subcol.prop(linestyle, "use_min_length", text="Min 2D Length")
-            subsub = subcol.split()
-            subsub.prop(linestyle, "min_length", text="")
-            subsub.enabled = linestyle.use_min_length
-            subcol = sub.column()
-            subcol.prop(linestyle, "use_max_length", text="Max 2D Length")
-            subsub = subcol.split()
-            subsub.prop(linestyle, "max_length", text="")
-            subsub.enabled = linestyle.use_max_length
-            # Caps
-            col = layout.column()
-            col.label(text="Caps:")
-            row = col.row(align=True)
-            row.prop(linestyle, "caps", expand=True)
-            col = layout.column()
-            col.prop(linestyle, "use_dashed_line")
-            split = col.split()
-            split.enabled = linestyle.use_dashed_line
-            sub = split.column()
-            sub.label(text="Dash")
-            sub.prop(linestyle, "dash1", text="")
-            sub = split.column()
-            sub.label(text="Gap")
-            sub.prop(linestyle, "gap1", text="")
-            sub = split.column()
-            sub.label(text="Dash")
-            sub.prop(linestyle, "dash2", text="")
-            sub = split.column()
-            sub.label(text="Gap")
-            sub.prop(linestyle, "gap2", text="")
-            sub = split.column()
-            sub.label(text="Dash")
-            sub.prop(linestyle, "dash3", text="")
-            sub = split.column()
-            sub.label(text="Gap")
-            sub.prop(linestyle, "gap3", text="")
-        elif linestyle.panel == "COLOR":
-            col = layout.column()
-            col.label(text="Base Color:")
-            col.prop(linestyle, "color", text="")
-            col = layout.column()
-            col.label(text="Modifiers:")
-            col.operator_menu_enum("scene.freestyle_color_modifier_add", "type", text="Add Modifier")
-            for modifier in linestyle.color_modifiers:
-                self.draw_color_modifier(context, modifier)
-        elif linestyle.panel == "ALPHA":
-            col = layout.column()
-            col.label(text="Base Transparency:")
-            col.prop(linestyle, "alpha")
-            col = layout.column()
-            col.label(text="Modifiers:")
-            col.operator_menu_enum("scene.freestyle_alpha_modifier_add", "type", text="Add Modifier")
-            for modifier in linestyle.alpha_modifiers:
-                self.draw_alpha_modifier(context, modifier)
-        elif linestyle.panel == "THICKNESS":
-            col = layout.column()
-            col.label(text="Base Thickness:")
-            col.prop(linestyle, "thickness")
-            col = layout.column()
-            row = col.row()
-            row.prop(linestyle, "thickness_position", expand=True)
-            row = col.row()
-            row.prop(linestyle, "thickness_ratio")
-            row.enabled = linestyle.thickness_position == "RELATIVE"
-            col = layout.column()
-            col.label(text="Modifiers:")
-            col.operator_menu_enum("scene.freestyle_thickness_modifier_add", "type", text="Add Modifier")
-            for modifier in linestyle.thickness_modifiers:
-                self.draw_thickness_modifier(context, modifier)
-        elif linestyle.panel == "GEOMETRY":
-            col = layout.column()
-            col.label(text="Modifiers:")
-            col.operator_menu_enum("scene.freestyle_geometry_modifier_add", "type", text="Add Modifier")
-            for modifier in linestyle.geometry_modifiers:
-                self.draw_geometry_modifier(context, modifier)
-        elif linestyle.panel == "MISC":
-            pass
-
-
 class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
     bl_label = "Dimensions"
     COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -948,19 +294,29 @@ class RENDER_PT_post_processing(RenderButtonsPanel, Panel):
         sub.prop(rd, "edge_threshold", text="Threshold", slider=True)
         sub.prop(rd, "edge_color", text="")
 
-        layout.separator()
 
-        split = layout.split()
+class RENDER_PT_freestyle(RenderButtonsPanel, Panel):
+    bl_label = "Freestyle"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
 
-        col = split.column()
-        col.prop(rd, "use_freestyle", text="Freestyle")
-        sub = col.column()
-        sub.label(text="Line Thickness:")
-        sub.active = rd.use_freestyle
-        sub.row().prop(rd, "line_thickness_mode", expand=True)
-        subrow = sub.row()
-        subrow.active = (rd.line_thickness_mode == "ABSOLUTE")
-        subrow.prop(rd, "unit_line_thickness")
+    def draw_header(self, context):
+        rd = context.scene.render
+
+        self.layout.prop(rd, "use_freestyle", text="")
+
+    def draw(self, context):
+        rd = context.scene.render
+
+        layout = self.layout
+        layout.enabled = rd.use_freestyle
+
+        row = layout.row()
+        row.label(text="Line Thickness:")
+        row.prop(rd, "line_thickness_mode", expand=True)
+        row = layout.row()
+        row.enabled = (rd.line_thickness_mode == "ABSOLUTE")
+        row.prop(rd, "unit_line_thickness")
 
 
 class RENDER_PT_stamp(RenderButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
new file mode 100644 (file)
index 0000000..b8c76fe
--- /dev/null
@@ -0,0 +1,677 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Menu, Panel
+
+
+class RenderLayerButtonsPanel():
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "render_layer"
+    # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
+
+    @classmethod
+    def poll(cls, context):
+        scene = context.scene
+        return scene and (scene.render.engine in cls.COMPAT_ENGINES)
+
+
+class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
+    bl_label = "Layers"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        scene = context.scene
+        rd = scene.render
+
+        row = layout.row()
+        row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
+
+        col = row.column(align=True)
+        col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
+        col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
+
+        row = layout.row()
+        rl = rd.layers.active
+        if rl:
+            row.prop(rl, "name")
+        row.prop(rd, "use_single_layer", text="", icon_only=True)
+
+        split = layout.split()
+
+        col = split.column()
+        col.prop(scene, "layers", text="Scene")
+        col.label(text="")
+        col.prop(rl, "light_override", text="Light")
+        col.prop(rl, "material_override", text="Material")
+
+        col = split.column()
+        col.prop(rl, "layers", text="Layer")
+        col.label(text="Mask Layers:")
+        col.prop(rl, "layers_zmask", text="")
+
+        layout.separator()
+        layout.label(text="Include:")
+
+        split = layout.split()
+
+        col = split.column()
+        col.prop(rl, "use_zmask")
+        row = col.row()
+        row.prop(rl, "invert_zmask", text="Negate")
+        row.active = rl.use_zmask
+        col.prop(rl, "use_all_z")
+
+        col = split.column()
+        col.prop(rl, "use_solid")
+        col.prop(rl, "use_halo")
+        col.prop(rl, "use_ztransp")
+        col.prop(rl, "use_sky")
+
+        col = split.column()
+        col.prop(rl, "use_edge_enhance")
+        col.prop(rl, "use_strand")
+        col.prop(rl, "use_freestyle")
+
+        layout.separator()
+
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="Passes:")
+        col.prop(rl, "use_pass_combined")
+        col.prop(rl, "use_pass_z")
+        col.prop(rl, "use_pass_vector")
+        col.prop(rl, "use_pass_normal")
+        col.prop(rl, "use_pass_uv")
+        col.prop(rl, "use_pass_mist")
+        col.prop(rl, "use_pass_object_index")
+        col.prop(rl, "use_pass_material_index")
+        col.prop(rl, "use_pass_color")
+
+        col = split.column()
+        col.label()
+        col.prop(rl, "use_pass_diffuse")
+        row = col.row()
+        row.prop(rl, "use_pass_specular")
+        row.prop(rl, "exclude_specular", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_shadow")
+        row.prop(rl, "exclude_shadow", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_emit")
+        row.prop(rl, "exclude_emit", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_ambient_occlusion")
+        row.prop(rl, "exclude_ambient_occlusion", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_environment")
+        row.prop(rl, "exclude_environment", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_indirect")
+        row.prop(rl, "exclude_indirect", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_reflection")
+        row.prop(rl, "exclude_reflection", text="")
+        row = col.row()
+        row.prop(rl, "use_pass_refraction")
+        row.prop(rl, "exclude_refraction", text="")
+
+
+class RENDER_MT_lineset_specials(Menu):
+    bl_label = "Lineset Specials"
+
+    def draw(self, context):
+        layout = self.layout
+        layout.operator("scene.freestyle_lineset_copy", icon='COPYDOWN')
+        layout.operator("scene.freestyle_lineset_paste", icon='PASTEDOWN')
+
+
+class RENDERLAYER_PT_freestyle(RenderLayerButtonsPanel, Panel):
+    bl_label = "Freestyle"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw(self, context):
+        rd = context.scene.render
+        rl = rd.layers.active
+        freestyle = rl.freestyle_settings
+
+        layout = self.layout
+        layout.enabled = rl.use_freestyle
+        layout.prop(freestyle, "mode", text="Control mode")
+
+        col = layout.column()
+        col.label(text="Edge Detection Options:")
+        split = col.split()
+        sub = split.column()
+        sub.prop(freestyle, "crease_angle")
+        sub.prop(freestyle, "use_culling")
+        sub = split.column()
+        sub.prop(freestyle, "use_smoothness")
+        sub.prop(freestyle, "use_material_boundaries")
+        col.prop(freestyle, "use_advanced_options")
+        # Advanced options are hidden by default to warn new users
+        if freestyle.use_advanced_options:
+            split = col.split()
+            sub = split.column()
+            sub.enabled = freestyle.use_advanced_options
+            if freestyle.mode == "SCRIPT":
+                sub.prop(freestyle, "use_ridges_and_valleys")
+            sub.prop(freestyle, "sphere_radius")
+            sub = split.column()
+            sub.enabled = freestyle.use_advanced_options
+            if freestyle.mode == "SCRIPT":
+                sub.prop(freestyle, "use_suggestive_contours")
+            sub.prop(freestyle, "kr_derivative_epsilon")
+
+        if freestyle.mode == "SCRIPT":
+            split = layout.split()
+            split.label("Style modules:")
+            split.operator("scene.freestyle_module_add", text="Add")
+            for i, module in enumerate(freestyle.modules):
+                box = layout.box()
+                box.context_pointer_set("freestyle_module", module)
+                row = box.row(align=True)
+                row.prop(module, "use", text="")
+                row.prop(module, "module_path", text="")
+                row.operator("scene.freestyle_module_remove", icon='X', text="")
+                row.operator("scene.freestyle_module_move", icon='TRIA_UP', text="").direction = 'UP'
+                row.operator("scene.freestyle_module_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+
+
+class RENDERLAYER_PT_freestyle_lineset(RenderLayerButtonsPanel, Panel):
+    bl_label = "Freestyle: Line Set"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    @classmethod
+    def poll(cls, context):
+        rd = context.scene.render
+        if rd.engine not in cls.COMPAT_ENGINES:
+            return False
+        rl = rd.layers.active
+        return rl and rl.freestyle_settings.mode == "EDITOR"
+
+    def draw_edge_type_buttons(self, box, lineset, edge_type):
+        # property names
+        select_edge_type = "select_" + edge_type
+        exclude_edge_type = "exclude_" + edge_type
+        # draw edge type buttons
+        row = box.row(align=True)
+        row.prop(lineset, select_edge_type)
+        sub = row.column()
+        sub.prop(lineset, exclude_edge_type, text="")
+        sub.enabled = getattr(lineset, select_edge_type)
+
+    def draw(self, context):
+        rd = context.scene.render
+        rl = rd.layers.active
+        freestyle = rl.freestyle_settings
+        lineset = freestyle.linesets.active
+
+        layout = self.layout
+        layout.enabled = rl.use_freestyle
+
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="Line Sets:")
+        row = col.row()
+        rows = 2
+        if lineset:
+            rows = 5
+        row.template_list(freestyle, "linesets", freestyle.linesets, "active_index", rows=rows)
+
+        sub = row.column()
+        subsub = sub.column(align=True)
+        subsub.operator("scene.freestyle_lineset_add", icon='ZOOMIN', text="")
+        subsub.operator("scene.freestyle_lineset_remove", icon='ZOOMOUT', text="")
+        subsub.menu("RENDER_MT_lineset_specials", icon='DOWNARROW_HLT', text="")
+        if lineset:
+            sub.separator()
+            subsub = sub.column(align=True)
+            subsub.operator("scene.freestyle_lineset_move", icon='TRIA_UP', text="").direction = 'UP'
+            subsub.operator("scene.freestyle_lineset_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+
+            #col = split.column()
+            col.prop(lineset, "name")
+
+            col.prop(lineset, "select_by_visibility")
+            if lineset.select_by_visibility:
+                sub = col.row(align=True)
+                sub.prop(lineset, "visibility", expand=True)
+                if lineset.visibility == "RANGE":
+                    sub = col.row(align=True)
+                    sub.prop(lineset, "qi_start")
+                    sub.prop(lineset, "qi_end")
+                col.separator() # XXX
+
+            col.prop(lineset, "select_by_edge_types")
+            if lineset.select_by_edge_types:
+                row = col.row()
+                row.prop(lineset, "edge_type_negation", expand=True)
+                row = col.row()
+                row.prop(lineset, "edge_type_combination", expand=True)
+
+                row = col.row()
+                sub = row.column()
+                self.draw_edge_type_buttons(sub, lineset, "silhouette")
+                self.draw_edge_type_buttons(sub, lineset, "border")
+                self.draw_edge_type_buttons(sub, lineset, "contour")
+                self.draw_edge_type_buttons(sub, lineset, "suggestive_contour")
+                self.draw_edge_type_buttons(sub, lineset, "ridge_valley")
+                sub = row.column()
+                self.draw_edge_type_buttons(sub, lineset, "crease")
+                self.draw_edge_type_buttons(sub, lineset, "edge_mark")
+                self.draw_edge_type_buttons(sub, lineset, "external_contour")
+                self.draw_edge_type_buttons(sub, lineset, "material_boundary")
+                col.separator() # XXX
+
+            col.prop(lineset, "select_by_face_marks")
+            if lineset.select_by_face_marks:
+                row = col.row()
+                row.prop(lineset, "face_mark_negation", expand=True)
+                row = col.row()
+                row.prop(lineset, "face_mark_condition", expand=True)
+                col.separator() # XXX
+
+            col.prop(lineset, "select_by_group")
+            if lineset.select_by_group:
+                col.prop(lineset, "group")
+                row = col.row()
+                row.prop(lineset, "group_negation", expand=True)
+                col.separator() # XXX
+
+            col.prop(lineset, "select_by_image_border")
+
+
+class RENDERLAYER_PT_freestyle_linestyle(RenderLayerButtonsPanel, Panel):
+    bl_label = "Freestyle: Line Style"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    @classmethod
+    def poll(cls, context):
+        rd = context.scene.render
+        if rd.engine not in cls.COMPAT_ENGINES:
+            return False
+        rl = rd.layers.active
+        return rl and rl.freestyle_settings.mode == "EDITOR"
+
+    def draw_modifier_box_header(self, box, modifier):
+        row = box.row()
+        row.context_pointer_set("modifier", modifier)
+        if modifier.expanded:
+            icon = "TRIA_DOWN"
+        else:
+            icon = "TRIA_RIGHT"
+        row.prop(modifier, "expanded", text="", icon=icon, emboss=False)
+        row.label(text=modifier.rna_type.name)
+        row.prop(modifier, "name", text="")
+        row.prop(modifier, "use", text="")
+        row.operator("scene.freestyle_modifier_copy", icon='NONE', text="Copy")
+        sub = row.row(align=True)
+        sub.operator("scene.freestyle_modifier_move", icon='TRIA_UP', text="").direction = 'UP'
+        sub.operator("scene.freestyle_modifier_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+        row.operator("scene.freestyle_modifier_remove", icon='X', text="")
+
+    def draw_modifier_common(self, box, modifier):
+        row = box.row()
+        row.prop(modifier, "blend", text="")
+        row.prop(modifier, "influence")
+
+    def draw_modifier_color_ramp_common(self, box, modifier, has_range):
+        box.template_color_ramp(modifier, "color_ramp", expand=True)
+        if has_range:
+            row = box.row(align=True)
+            row.prop(modifier, "range_min")
+            row.prop(modifier, "range_max")
+
+    def draw_modifier_curve_common(self, box, modifier, has_range, has_value):
+        row = box.row()
+        row.prop(modifier, "mapping", text="")
+        sub = row.column()
+        sub.prop(modifier, "invert")
+        if modifier.mapping == "CURVE":
+            sub.enabled = False
+            box.template_curve_mapping(modifier, "curve")
+        if has_range:
+            row = box.row(align=True)
+            row.prop(modifier, "range_min")
+            row.prop(modifier, "range_max")
+        if has_value:
+            row = box.row(align=True)
+            row.prop(modifier, "value_min")
+            row.prop(modifier, "value_max")
+
+    def draw_color_modifier(self, context, modifier):
+        layout = self.layout
+
+        col = layout.column(align=True)
+        self.draw_modifier_box_header(col.box(), modifier)
+        if modifier.expanded:
+            box = col.box()
+            self.draw_modifier_common(box, modifier)
+
+            if modifier.type == "ALONG_STROKE":
+                self.draw_modifier_color_ramp_common(box, modifier, False)
+
+            elif modifier.type == "DISTANCE_FROM_OBJECT":
+                box.prop(modifier, "target")
+                self.draw_modifier_color_ramp_common(box, modifier, True)
+                prop = box.operator("scene.freestyle_fill_range_by_selection")
+                prop.type = 'COLOR'
+                prop.name = modifier.name
+
+            elif modifier.type == "DISTANCE_FROM_CAMERA":
+                self.draw_modifier_color_ramp_common(box, modifier, True)
+                prop = box.operator("scene.freestyle_fill_range_by_selection")
+                prop.type = 'COLOR'
+                prop.name = modifier.name
+
+            elif modifier.type == "MATERIAL":
+                row = box.row()
+                row.prop(modifier, "material_attr", text="")
+                sub = row.column()
+                sub.prop(modifier, "use_ramp")
+                if modifier.material_attr in ["DIFF", "SPEC"]:
+                    sub.enabled = True
+                    show_ramp = modifier.use_ramp
+                else:
+                    sub.enabled = False
+                    show_ramp = True
+                if show_ramp:
+                    self.draw_modifier_color_ramp_common(box, modifier, False)
+
+    def draw_alpha_modifier(self, context, modifier):
+        layout = self.layout
+
+        col = layout.column(align=True)
+        self.draw_modifier_box_header(col.box(), modifier)
+        if modifier.expanded:
+            box = col.box()
+            self.draw_modifier_common(box, modifier)
+
+            if modifier.type == "ALONG_STROKE":
+                self.draw_modifier_curve_common(box, modifier, False, False)
+
+            elif modifier.type == "DISTANCE_FROM_OBJECT":
+                box.prop(modifier, "target")
+                self.draw_modifier_curve_common(box, modifier, True, False)
+                prop = box.operator("scene.freestyle_fill_range_by_selection")
+                prop.type = 'ALPHA'
+                prop.name = modifier.name
+
+            elif modifier.type == "DISTANCE_FROM_CAMERA":
+                self.draw_modifier_curve_common(box, modifier, True, False)
+                prop = box.operator("scene.freestyle_fill_range_by_selection")
+                prop.type = 'ALPHA'
+                prop.name = modifier.name
+
+            elif modifier.type == "MATERIAL":
+                box.prop(modifier, "material_attr", text="")
+                self.draw_modifier_curve_common(box, modifier, False, False)
+
+    def draw_thickness_modifier(self, context, modifier):
+        layout = self.layout
+
+        col = layout.column(align=True)
+        self.draw_modifier_box_header(col.box(), modifier)
+        if modifier.expanded:
+            box = col.box()
+            self.draw_modifier_common(box, modifier)
+
+            if modifier.type == "ALONG_STROKE":
+                self.draw_modifier_curve_common(box, modifier, False, True)
+
+            elif modifier.type == "DISTANCE_FROM_OBJECT":
+                box.prop(modifier, "target")
+                self.draw_modifier_curve_common(box, modifier, True, True)
+                prop = box.operator("scene.freestyle_fill_range_by_selection")
+                prop.type = 'THICKNESS'
+                prop.name = modifier.name
+
+            elif modifier.type == "DISTANCE_FROM_CAMERA":
+                self.draw_modifier_curve_common(box, modifier, True, True)
+                prop = box.operator("scene.freestyle_fill_range_by_selection")
+                prop.type = 'THICKNESS'
+                prop.name = modifier.name
+
+            elif modifier.type == "MATERIAL":
+                box.prop(modifier, "material_attr", text="")
+                self.draw_modifier_curve_common(box, modifier, False, True)
+
+            elif modifier.type == "CALLIGRAPHY":
+                col = box.column()
+                col.prop(modifier, "orientation")
+                col.prop(modifier, "min_thickness")
+                col.prop(modifier, "max_thickness")
+
+    def draw_geometry_modifier(self, context, modifier):
+        layout = self.layout
+
+        col = layout.column(align=True)
+        self.draw_modifier_box_header(col.box(), modifier)
+        if modifier.expanded:
+            box = col.box()
+
+            if modifier.type == "SAMPLING":
+                box.prop(modifier, "sampling")
+
+            elif modifier.type == "BEZIER_CURVE":
+                box.prop(modifier, "error")
+
+            elif modifier.type == "SINUS_DISPLACEMENT":
+                box.prop(modifier, "wavelength")
+                box.prop(modifier, "amplitude")
+                box.prop(modifier, "phase")
+
+            elif modifier.type == "SPATIAL_NOISE":
+                box.prop(modifier, "amplitude")
+                box.prop(modifier, "scale")
+                box.prop(modifier, "octaves")
+                sub = box.row()
+                sub.prop(modifier, "smooth")
+                sub.prop(modifier, "pure_random")
+
+            elif modifier.type == "PERLIN_NOISE_1D":
+                box.prop(modifier, "frequency")
+                box.prop(modifier, "amplitude")
+                box.prop(modifier, "octaves")
+                box.prop(modifier, "angle")
+                box.prop(modifier, "seed")
+
+            elif modifier.type == "PERLIN_NOISE_2D":
+                box.prop(modifier, "frequency")
+                box.prop(modifier, "amplitude")
+                box.prop(modifier, "octaves")
+                box.prop(modifier, "angle")
+                box.prop(modifier, "seed")
+
+            elif modifier.type == "BACKBONE_STRETCHER":
+                box.prop(modifier, "backbone_length")
+
+            elif modifier.type == "TIP_REMOVER":
+                box.prop(modifier, "tip_length")
+
+            elif modifier.type == "POLYGONIZATION":
+                box.prop(modifier, "error")
+
+            elif modifier.type == "GUIDING_LINES":
+                box.prop(modifier, "offset")
+
+            elif modifier.type == "BLUEPRINT":
+                row = box.row()
+                row.prop(modifier, "shape", expand=True)
+                box.prop(modifier, "rounds")
+                if modifier.shape in ["CIRCLES", "ELLIPSES"]:
+                    box.prop(modifier, "random_radius")
+                    box.prop(modifier, "random_center")
+                elif modifier.shape == "SQUARES":
+                    box.prop(modifier, "backbone_length")
+                    box.prop(modifier, "random_backbone")
+
+            elif modifier.type == "2D_OFFSET":
+                row = box.row(align=True)
+                row.prop(modifier, "start")
+                row.prop(modifier, "end")
+                row = box.row(align=True)
+                row.prop(modifier, "x")
+                row.prop(modifier, "y")
+
+            elif modifier.type == "2D_TRANSFORM":
+                box.prop(modifier, "pivot")
+                if modifier.pivot == "PARAM":
+                    box.prop(modifier, "pivot_u")
+                elif modifier.pivot == "ABSOLUTE":
+                    row = box.row(align=True)
+                    row.prop(modifier, "pivot_x")
+                    row.prop(modifier, "pivot_y")
+                row = box.row(align=True)
+                row.prop(modifier, "scale_x")
+                row.prop(modifier, "scale_y")
+                box.prop(modifier, "angle")
+
+    def draw(self, context):
+        rd = context.scene.render
+        rl = rd.layers.active
+        lineset = rl.freestyle_settings.linesets.active
+
+        layout = self.layout
+        layout.enabled = rl.use_freestyle
+
+        if lineset is None:
+            return
+        linestyle = lineset.linestyle
+
+        layout.template_ID(lineset, "linestyle", new="scene.freestyle_linestyle_new")
+        row = layout.row(align=True)
+        row.prop(linestyle, "panel", expand=True)
+        if linestyle.panel == "STROKES":
+            # Chaining
+            col = layout.column()
+            col.prop(linestyle, "use_chaining", text="Chaining:")
+            sub = col.column()
+            sub.enabled = linestyle.use_chaining
+            sub.prop(linestyle, "chaining", text="")
+            if linestyle.chaining == "PLAIN":
+                sub.prop(linestyle, "same_object")
+            elif linestyle.chaining == "SKETCHY":
+                subsub = sub.row()
+                subsub.prop(linestyle, "same_object")
+                subsub.prop(linestyle, "rounds")
+            # Splitting
+            layout.label(text="Splitting:")
+            row = layout.row()
+            col = row.column()
+            sub = col.row(align=True)
+            sub.prop(linestyle, "use_min_angle", text="")
+            subsub = sub.row()
+            subsub.enabled = linestyle.use_min_angle
+            subsub.prop(linestyle, "min_angle")
+            sub = col.row(align=True)
+            sub.prop(linestyle, "use_max_angle", text="")
+            subsub = sub.row()
+            subsub.enabled = linestyle.use_max_angle
+            subsub.prop(linestyle, "max_angle")
+            col = row.column()
+            sub = col.row(align=True)
+            sub.prop(linestyle, "use_split_length", text="")
+            subsub = sub.row()
+            subsub.enabled = linestyle.use_split_length
+            subsub.prop(linestyle, "split_length", text="2D Length")
+            col.prop(linestyle, "material_boundary")
+            # Selection
+            layout.label(text="Selection:")
+            row = layout.row()
+            col = row.column()
+            sub = col.row(align=True)
+            sub.prop(linestyle, "use_min_length", text="")
+            subsub = sub.row()
+            subsub.enabled = linestyle.use_min_length
+            subsub.prop(linestyle, "min_length")
+            col = row.column()
+            sub = col.row(align=True)
+            sub.prop(linestyle, "use_max_length", text="")
+            subsub = sub.row()
+            subsub.enabled = linestyle.use_max_length
+            subsub.prop(linestyle, "max_length")
+            # Caps
+            layout.label(text="Caps:")
+
+            row = layout.row(align=True)
+            row.prop(linestyle, "caps", expand=True)
+
+            layout.prop(linestyle, "use_dashed_line")
+            row = layout.row(align=True)
+            row.enabled = linestyle.use_dashed_line
+            row.prop(linestyle, "dash1")
+            row.prop(linestyle, "gap1")
+            row.prop(linestyle, "dash2")
+            row.prop(linestyle, "gap2")
+            row.prop(linestyle, "dash3")
+            row.prop(linestyle, "gap3")
+
+        elif linestyle.panel == "COLOR":
+            col = layout.column()
+            col.label(text="Base Color:")
+            col.prop(linestyle, "color", text="")
+            col = layout.column()
+            col.label(text="Modifiers:")
+            col.operator_menu_enum("scene.freestyle_color_modifier_add", "type", text="Add Modifier")
+            for modifier in linestyle.color_modifiers:
+                self.draw_color_modifier(context, modifier)
+        elif linestyle.panel == "ALPHA":
+            col = layout.column()
+            col.label(text="Base Transparency:")
+            col.prop(linestyle, "alpha")
+            col = layout.column()
+            col.label(text="Modifiers:")
+            col.operator_menu_enum("scene.freestyle_alpha_modifier_add", "type", text="Add Modifier")
+            for modifier in linestyle.alpha_modifiers:
+                self.draw_alpha_modifier(context, modifier)
+        elif linestyle.panel == "THICKNESS":
+            col = layout.column()
+            col.label(text="Base Thickness:")
+            col.prop(linestyle, "thickness")
+            col = layout.column()
+            row = col.row()
+            row.prop(linestyle, "thickness_position", expand=True)
+            row = col.row()
+            row.prop(linestyle, "thickness_ratio")
+            row.enabled = linestyle.thickness_position == "RELATIVE"
+            col = layout.column()
+            col.label(text="Modifiers:")
+            col.operator_menu_enum("scene.freestyle_thickness_modifier_add", "type", text="Add Modifier")
+            for modifier in linestyle.thickness_modifiers:
+                self.draw_thickness_modifier(context, modifier)
+        elif linestyle.panel == "GEOMETRY":
+            col = layout.column()
+            col.label(text="Modifiers:")
+            col.operator_menu_enum("scene.freestyle_geometry_modifier_add", "type", text="Add Modifier")
+            for modifier in linestyle.geometry_modifiers:
+                self.draw_geometry_modifier(context, modifier)
+        elif linestyle.panel == "MISC":
+            pass
+
+
+if __name__ == "__main__":  # only for live edit.
+    bpy.utils.register_module(__name__)
index 97ca210c3d0a2ed5b0a495722a9b8e7fac9b88f5..dc8cf3b9116711bb77837190f38fbe3a18f562c2 100644 (file)
@@ -8348,8 +8348,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        for(srl= sce->r.layers.first; srl; srl= srl->next) {
                                if (srl->freestyleConfig.mode == 0)
                                        srl->freestyleConfig.mode= FREESTYLE_CONTROL_EDITOR_MODE;
-                               if (srl->freestyleConfig.raycasting_algorithm == 0)
-                                       srl->freestyleConfig.raycasting_algorithm= FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE;
+                               if (srl->freestyleConfig.raycasting_algorithm == FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE ||
+                                       srl->freestyleConfig.raycasting_algorithm == FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL) {
+                                       srl->freestyleConfig.raycasting_algorithm= 0; /* deprecated */
+                                       srl->freestyleConfig.flags |= FREESTYLE_CULLING;
+                               }
                        }
                }
                for(linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
index 7e232a02536bbee0147d7fa3899d05f793f2742c..e5f5a4beac632e31d297f29917664a743def78a0 100644 (file)
@@ -538,6 +538,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
        switch (mainb) {
                case BCONTEXT_SCENE:
                case BCONTEXT_RENDER:
+               case BCONTEXT_RENDER_LAYER:
                        found = buttons_context_path_scene(path);
                        break;
                case BCONTEXT_WORLD:
@@ -1032,7 +1033,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
                        name = RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL);
 
                        if (name) {
-                               if (!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE) && ptr->type == &RNA_Scene)
+                               if (!ELEM3(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE, BCONTEXT_RENDER_LAYER) && ptr->type == &RNA_Scene)
                                        uiItemLDrag(row, ptr, "", icon);  /* save some space */
                                else
                                        uiItemLDrag(row, ptr, name, icon);
index ebba7d92819fb583f20da4f320a59d350aec71a0..3c2d9ac2eee2f251bcbb24c866f70803bc186b46 100644 (file)
@@ -128,6 +128,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
        } (void)0
 
        BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, N_("Render"));
+       BUTTON_HEADER_CTX(BCONTEXT_RENDER_LAYER, ICON_RENDERLAYERS, N_("Render Layers"));
        BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, N_("Scene"));
        BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, N_("World"));
        BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, N_("Object"));
index c894c1a980bd5fec67e4c393e6d8d6fee41a053b..a24a292be06c93fb9687073f42594b6d103c82d8 100644 (file)
@@ -155,6 +155,8 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
                ED_region_panels(C, ar, vertical, "scene", sbuts->mainb);
        else if (sbuts->mainb == BCONTEXT_RENDER)
                ED_region_panels(C, ar, vertical, "render", sbuts->mainb);
+       else if (sbuts->mainb == BCONTEXT_RENDER_LAYER)
+               ED_region_panels(C, ar, vertical, "render_layer", sbuts->mainb);
        else if (sbuts->mainb == BCONTEXT_WORLD)
                ED_region_panels(C, ar, vertical, "world", sbuts->mainb);
        else if (sbuts->mainb == BCONTEXT_OBJECT)
@@ -239,6 +241,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
                        switch (wmn->data) {
                                case ND_RENDER_OPTIONS:
                                        buttons_area_redraw(sa, BCONTEXT_RENDER);
+                                       buttons_area_redraw(sa, BCONTEXT_RENDER_LAYER);
                                        break;
                                case ND_FRAME:
                                        /* any buttons area can have animated properties so redraw all */
index 5dcda3bd69c524c6f16fe9da6f6d606be4d5763c..b5e67597caa1b220c898436a1f01a13af10f1187 100644 (file)
@@ -352,7 +352,8 @@ extern "C" {
                }
                controller->setFaceSmoothness( (config->flags & FREESTYLE_FACE_SMOOTHNESS_FLAG) ? true : false);
                controller->setCreaseAngle( config->crease_angle );
-               controller->setVisibilityAlgo( config->raycasting_algorithm );
+               controller->setVisibilityAlgo( (config->flags & FREESTYLE_CULLING) ?
+                       FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE : FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE );
 
                cout << "Crease angle : " << controller->getCreaseAngle() << endl;
                cout << "Sphere radius : " << controller->getSphereRadius() << endl;
@@ -527,8 +528,6 @@ extern "C" {
                config->crease_angle = 134.43f;
 
                config->linesets.first = config->linesets.last = NULL;
-
-               config->raycasting_algorithm = FREESTYLE_ALGO_REGULAR;
        }
        
        void FRS_free_freestyle_config( SceneRenderLayer* srl )
index f6e9421fa34201c9aade608ff615ded1d0d840d0..b78ea9a13bbdae11744fbd3b5226618288f9f9da 100644 (file)
@@ -41,6 +41,7 @@ struct FreestyleLineStyle;
 #define FREESTYLE_MATERIAL_BOUNDARIES_FLAG  4
 #define FREESTYLE_FACE_SMOOTHNESS_FLAG      8
 #define FREESTYLE_ADVANCED_OPTIONS_FLAG     16
+#define FREESTYLE_CULLING                   32
 
 /* FreestyleConfig::mode */
 #define FREESTYLE_CONTROL_SCRIPT_MODE  1
@@ -120,7 +121,7 @@ typedef struct FreestyleConfig {
        ListBase modules;
        
        int mode; /* scripting, editor */
-       int raycasting_algorithm; /* regular, fast, very fast, etc. */
+       int raycasting_algorithm; /* XXX deprecated */
        int flags; /* suggestive contours, ridges/valleys, material boundaries */
        float sphere_radius;
        float dkr_epsilon;
index 2469656ecd7ffb65666dad303a4fe8aa5beefbac..9289d140b85381149848251a7a8b2ed958ccdd43 100644 (file)
@@ -180,6 +180,7 @@ typedef enum eSpaceButtons_Context {
        BCONTEXT_MODIFIER = 10,
        BCONTEXT_CONSTRAINT = 11,
        BCONTEXT_BONE_CONSTRAINT = 12,
+       BCONTEXT_RENDER_LAYER = 13,
        
        /* always as last... */
        BCONTEXT_TOT
index abb715f2471e0552f24058b6eab7145b040b8d7a..62d69ee8732b5113621d2813535ba06dcaeb1b0f 100644 (file)
@@ -1038,37 +1038,37 @@ static void rna_def_linestyle(BlenderRNA *brna)
        prop= RNA_def_property(srna, "dash1", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "dash1");
        RNA_def_property_range(prop, 0, USHRT_MAX);
-       RNA_def_property_ui_text(prop, "Dash #1", "Length of the 1st dash");
+       RNA_def_property_ui_text(prop, "Dash 1", "Length of the 1st dash");
        RNA_def_property_update(prop, NC_LINESTYLE, NULL);
 
        prop= RNA_def_property(srna, "gap1", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "gap1");
        RNA_def_property_range(prop, 0, USHRT_MAX);
-       RNA_def_property_ui_text(prop, "Gap #1", "Length of the 1st gap");
+       RNA_def_property_ui_text(prop, "Gap 1", "Length of the 1st gap");
        RNA_def_property_update(prop, NC_LINESTYLE, NULL);
 
        prop= RNA_def_property(srna, "dash2", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "dash2");
        RNA_def_property_range(prop, 0, USHRT_MAX);
-       RNA_def_property_ui_text(prop, "Dash #2", "Length of the 2nd dash");
+       RNA_def_property_ui_text(prop, "Dash 2", "Length of the 2nd dash");
        RNA_def_property_update(prop, NC_LINESTYLE, NULL);
 
        prop= RNA_def_property(srna, "gap2", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "gap2");
        RNA_def_property_range(prop, 0, USHRT_MAX);
-       RNA_def_property_ui_text(prop, "Gap #2", "Length of the 2nd gap");
+       RNA_def_property_ui_text(prop, "Gap 2", "Length of the 2nd gap");
        RNA_def_property_update(prop, NC_LINESTYLE, NULL);
 
        prop= RNA_def_property(srna, "dash3", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "dash3");
        RNA_def_property_range(prop, 0, USHRT_MAX);
-       RNA_def_property_ui_text(prop, "Dash #3", "Length of the 3rd dash");
+       RNA_def_property_ui_text(prop, "Dash 3", "Length of the 3rd dash");
        RNA_def_property_update(prop, NC_LINESTYLE, NULL);
 
        prop= RNA_def_property(srna, "gap3", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "gap3");
        RNA_def_property_range(prop, 0, USHRT_MAX);
-       RNA_def_property_ui_text(prop, "Gap #3", "Length of the 3rd gap");
+       RNA_def_property_ui_text(prop, "Gap 3", "Length of the 3rd gap");
        RNA_def_property_update(prop, NC_LINESTYLE, NULL);
 
 }
index 24f17034ea15c28306224ada6b9c3a72955bb537..e13a973334b84f97043a39c4ff0bcb2341ea6455 100644 (file)
@@ -2603,6 +2603,11 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Raycasting Algorithm", "Select the Freestyle raycasting algorithm");
        RNA_def_property_update(prop, NC_SCENE, NULL);
 
+       prop= RNA_def_property(srna, "use_culling", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_CULLING);
+       RNA_def_property_ui_text(prop, "Culling", "If enabled, out-of-view edges are ignored");
+       RNA_def_property_update(prop, NC_SCENE, NULL);
+
        prop= RNA_def_property(srna, "use_suggestive_contours", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_SUGGESTIVE_CONTOURS_FLAG);
        RNA_def_property_ui_text(prop, "Suggestive Contours", "Enable suggestive contours");
index 51fb9d413dafe8d801c080c7cda909b29069bee4..e670adb1e8762dcc194908c9f4ec851e4afb18bf 100644 (file)
@@ -1911,6 +1911,7 @@ static void rna_def_space_buttons(BlenderRNA *brna)
        static EnumPropertyItem buttons_context_items[] = {
                {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
                {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"},
+               {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render Layers"},
                {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
                {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
                {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"},