Freestyle integration into Blender

May 23, 2010

Weekly update May 10-23

Filed under: Update — The dev team @ 11:52 PM

Improvements of the Freestyle Python API as well as better integration of Freestyle into Blender were attempted in the last two weeks.

First, feature edge detection has been extended so that edges at material boundaries are detected as feature edges.  The edges at material boundaries are enabled by turning on the “Material Boundaries” option in the Layers tab of the Render buttons.  The following test render (using shows examples of edges at material boundaries.  In style modules, edges at material boundaries can be tested with pyNatureUP1D(Nature.MATERIAL_BOUNDARY).

Second, new option “Crease Angle” has been added to the Layers tab of the Render buttons, to allow users to specify an angular threshold (between 0 and 180 degrees) for crease edge detection.  An edge is considered a crease edge if the angle between two faces sharing the edge is smaller than the threshold.  The default value is 134.43 degrees for backward compatibility.  Note that a larger angle threshold leads to a larger number of crease edges and thus a larger memory consumption.  The following test render (using shows the effects of different crease angles (i.e., the default value vs. 170 degrees).

To branch users: If you have .blend files made with an old Freestyle branch build, you may notice the Crease Angle value is set to 0.  If that is the case, you need to manually set the default value (or some other appropriate value); otherwise you won’t get those crease edges that you previously had.

Finally, Freestyle’s mesh importer has been improved to make object names accessible from within style modules.  ViewShape objects in the view map, as well as SShape objects that can be retrieved by ViewShape::sshape(), now have a getName() method that returns the name of the object from which each shape is created.  For instance, visible feature edges of a specific mesh object (e.g., the default Cube) can be selected using a custom predicate as follows:

class ObjectNamesUP1D(UnaryPredicate1D):
    def __init__(self, names):
        self._names = names
    def getName(self):
        return "ObjectNamesUP1D"
    def __call__(self, viewEdge):
        return viewEdge.viewShape().getName() in self._names

upred = AndUP1D(QuantitativeInvisibilityUP1D(0),

In the meantime, the dev team was working on the long-standing issue of SWIG/C++ dependency removal.  Since the beginning of the Freestyle integration into Blender, lots of efforts have been made to eliminate the SWIG/C++ dependency from the Freestyle Python API, and the work is still ongoing.  A major obstacle here is that it seems very difficult to completely remove the C++-style iteration syntax from the Python API.  In December 2008, we implemented the Python iterator protocol in Stroke and StrokeVertexIterator as a pilot case.  Initially, allowing Python-style iteration over vertices appeared a very good idea.  After an in-depth review of the Freestyle code base (mainly written in C++), however, we found that C++-style iterators cannot be easily removed from the Python API simply because a large number of API functions (and a large amount of underlying C++ code) require them.  Eliminating the C++-style iterators will require a considerable amount of modifications to the C++ code base that is fairly stable.  Clearly, having both C++- and Python-style iterators constitutes a confusing inconsistency.  The dev team is about to conclude that it is too time-consuming and not worth trying to completely exclude the C++-style iteration syntax from the Python API.  We will further investigate this issue in the next weeks.


  1. the material boundary is great!!!

    Comment by sfepa — May 24, 2010 @ 10:29 AM

  2. Actually they both are very interesting and useful!!

    Comment by sfepa — May 24, 2010 @ 7:59 PM

  3. loving the new material boundary setting and the crease angle setting is something I’ve wanted since the beginning of the project, you’ve just made FreeStyle in blender even more awesome!!! Thank you. CAnt wait to see the next updates.

    Comment by Blenderificus — May 25, 2010 @ 5:38 AM

  4. Wow, development on this is going way fast!! Well done to all involved.

    One thing puzzles me though. Why aren’t the crease edges consistent between the 3 visible faces of the cube. Isn’t the crease angle measured in 3D space relative to it’s two faces. If this is the case each side of the cube should have the same crease edges drawn.

    Comment by Rudiger — May 25, 2010 @ 9:45 AM

  5. Rudiger, you are right, but that is also what happens. The extra lines you see are actually outlines, because the faces on the other side of the lines are hidden.

    About the two types of iterations: Would it not be acceptable to have both types, but just make sure there is a python style alternative to all the ones a user would use often?

    Comment by yoff — May 25, 2010 @ 11:20 PM

  6. may this should achive the wireframe render, with backface occluded :)

    Comment by Max Puliero — September 2, 2010 @ 2:07 AM

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at

%d bloggers like this: