9

The Edge Split modifier doesn't give me desired results (even with angle set to 0 it looks different).

Gwen
  • 11,636
  • 14
  • 68
  • 88
Sielan
  • 133
  • 6
  • 1
    What do you mean it looks different? Can you post a screenshot comparing the two? There isn't a way to insert keyframes for Smooth/Flat shading, so edge split is your only choice. – CharlesL Jul 06 '13 at 17:49

3 Answers3

8

Animatable (custom property) toggle

import bpy

def toggle_shading(self, context=bpy.context):
    """Toggle smooth shading"""
    value = self["use_smooth"]
    if self.polygons[0].use_smooth is not value:
        for poly in self.polygons:
            poly.use_smooth = value

def frame_handler(scene):
    """Update shading on frame change"""
    for mesh in bpy.data.objects.data.meshes:
        try:
            toggle_shading(mesh)
        except KeyError:
            pass

bpy.types.Mesh.use_smooth = bpy.props.BoolProperty(
    description=toggle_shading.__doc__, update=toggle_shading)
bpy.app.handlers.frame_change_pre.append(frame_handler)
  1. Paste the script above in the Text Editor, click Register and Run Script.
    • Text block name must end with ".py" to activate the register functionality (run script on load).
  2. In the Properties Window, under Object Data, Add a custom property with Property Name use_smooth and Property Value of 0.
    • You can now animate this value the toggle smooth shading.

Added property

Aldrik
  • 9,720
  • 22
  • 56
8

I still think that edge split is the way to go:

  • Make sure edge split is the last modifier.
  • Make sure that it is smooth shaded without it.
  • Set edge split angle to zero and check the angle.
  • Add desired keyframes for the angle checkbox.

Frame One:

Frame One

Frame Six:

Frame Six

4

Let me preface this with saying that this method won't let you set key-frames with the UI, Aldrik's approach does.

My method lends itself better to a procedural approach to animation where key-framing isn't important. This script accepts a list of start-end ranges, which map to the frame numbers that should be shaded flat or smooth.

  • Hit run on this script, then start the animation render

script:

import bpy

def list_to_frames(ranges):
    k = set()
    for begin, finish in ranges:
        k = k | {i for i in range(begin, finish)}
    return k

def my_handler(scene):
    frame = scene.frame_current

    obj = bpy.data.objects[obj_name]

    # this assumes you are OK with doing a full sweep
    # and setting all to either smooth or flat.
    if not frame in frames:
        if obj.data.polygons[0].use_smooth == True:
            return
        for poly in obj.data.polygons:
            poly.use_smooth = True
    else:
        if obj.data.polygons[0].use_smooth == False:
            return
        for poly in obj.data.polygons:
            poly.use_smooth = False

frames_to_flatshade = [[20,30],[45,54]]
obj_name = 'Cube'
frames = list_to_frames(frames_to_flatshade)

bpy.app.handlers.frame_change_pre.append(my_handler)

Here's a compacted version of this script

zeffii
  • 39,634
  • 9
  • 103
  • 186