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.


May 12, 2010

Weekly update April 19-May 9

Filed under: Update — The dev team @ 12:42 AM

In the last three weeks, the Freestyle branch had only a few commits.  This slowdown of the development was partly due to a lack of spare time, because I (T.K.) was in Italy for two weeks to do a couple of jobs.  The trip to Italy was full of troubles from the beginning because of the still ongoing issue regarding the Icelandic volucanic ash clouds.  All flights reserved for the trip were canceled.  Major European railways were packed according to news reports, while a colleague of mine and I had a strict time constraint for one of the planned jobs.  Eventually we decided to go by car together from Portugal to Italy.  My colleague and I alternatively drove the car.  This was the first time I went more than 2100 km by car in two days.  As a matter of fact, I was a very new driver who got a driver’s license in last January.  This would explain my impression that the car travel was kind of thrilling.  In the end, we arrived at the destination without any major issues, and the jobs were completed in time regardless of the European airspace confusion.

Another reason of the few commits in the branch was a critical bug in the trunk.  As you know, changes in the trunk are merged into the branch once in a while.  After I came back to home, a number of changes in the trunk were merged as usual.  The bug was among the merged changes and prevented me from working on the branch.  The problem was that Blender got freezed soon after the start-up.  To my knowledge there was no problem report on the bug, suggesting that the issue was very environment-specific (I was using 64-bit Windows at that time).  It took a while to look into the issue myself.  It turned out to be a typical deadlock problem in multithread programming.  I made a problem report with a possible fix, which was kindly incorporated into the trunk by Brecht.

The commits in the Freestyle branch after the bug fix were intended to be the first step toward the completion of Freestyle Python API improvements.  More commits in this direction are anticipated in the following weeks.

Blog at