Freestyle integration into Blender

December 10, 2008

Consolidation update

Filed under: Update — The dev team @ 10:29 PM

I consolidated the code base today:

  • removed unused functions in the Controller and AppCanvas classes
  • corrected a crash when the scene is empty
  • removed AppGLWidget and all related classes (AFAIR, this was the last remaining Qt dependency)
  • added an AppView class to transfer camera information from Blender to Freestyle
  • corrected the Python interpreter so that the executed scripts are not left opened in the text editor

Let me know if the 17784 revision is unstable.

December 9, 2008

Quick update: corrected crash due to Vector render pass

Filed under: Update — The dev team @ 5:23 PM

Thanks to bupla and his test on the BA thread, I was able to correct an ‘obvious’ bug that would happen when the Vector render pass was enabled. This should correct the “Memoryblock free: attempt to free illegal pointer” message. I committed the correction to the 17764 revision; let me know if this resolves your crashes.

December 4, 2008

Oversampling and tile rendering working, consolidation ahead

Filed under: Update — The dev team @ 2:47 PM

Oversampling and tiling have been corrected and now work as expected (committed as the 17714 revision).

I corrected a little bug related to rendering. The 17721 revision correctly supports all the chosen filter settings.

To clear up some questions I found on the BA thread:

  • Freestyle is activated by toggling on the ‘Freestyle’ button in the ‘Output’ panel and the ‘FrSt’ button in the ‘Render Layers’ panel (sorry, there is no space for ‘Freestyle’ or ‘Strokes’ in the UI….). These are the only required steps to produce a render.
  • you can use Freestyle in as many render layers as you want, as well as with compositor nodes.
  • the branch is still experimental and not optimized at all for Blender: this explains the big memory footprint for even “regular” scenes and the crashes. There are many different reasons behind all of them (the original API functions not being fully implemented, remaining bugs in the internal engine,…). If you encounter a specific reproducible problem, please let me know by email.
  • in the short term, there is no plan to provide an interface to control line attributes. Freestyle is meant to be used for a whole array of styles, not just a few in particular. It wouldn’t make sense to limit the panel to particular styles. Nothing stops one from developing Python UI scripts that simplify style module usage. The final decision to include these scripts or not in the final release will be up to the Blender development team.
  • in the original Freestyle program, strokes could be be controlled on a per object basis (using the Id class, each Id determined using the user interface). Unfortunately, AFAIR, Ids are currently given incrementally when models are imported into Freestyle. That means it is very difficult to know which strokes belong to what object. Eventually, I will change it so that a stroke can also have access to the underlying object’s name, not just its Id.

As of today, I consider the second milestone “Render layer for NPR line drawing” of the original project proposal as finished. I am aware that the branch is unstable and has a whole new set of problems, particularly the inability to use textures or to retrieve the depth/color information from the original scene (which in turn means the the DensityF0D and LocalAverageDepthF0D functions cannot be used currently). Nevertheless, I consider that it is important to move on to the next phase “Decomposition of Freestyle’s algorithm into reusable functional modules”, which will integrate the view map in the render database as a render pass: this means you will be able to combine different style modules, directly in the compositor or in code with PyNodes. I also intend on optimizing the current pipeline in many ways. You should consult the project proposal for more details.

But before I move on to the next stage, I want to take a step back and consolidate the branch. The first thing I will do is write a status report. This will allow me to determine which areas of the branch need to be improved for all you brave beta users. For example, I want to finish to port the last remaining style modules. I also think it is time to work on the documentation. I am aware that writing style modules or Freestyle shaders might scare many artists eager to use Freestyle. An effort needs to be made on my part to make their job easier. I am grateful that Tamito will be there to help us in that direction. I have other ideas that I would want to work on in the short term:

  • setting up a gallery of Freestyle/Blender results: I would be grateful to all of you who could share their best works on the blog.
  • setting up a repository for style modules: this would be great for quickly visualizing style modules, while at the same time learning from others. Another solution would be contacting Blender Materials or other repositories for such a service. If anyone is interested in making it happen, let me know.

I think that’s all for today. I will inform you all when the status report is uploaded on Blender’s wiki. For now, enjoy !

December 1, 2008

Native stroke rendering

Filed under: Update — The dev team @ 9:57 PM

As of today, Blender’s internal renderer can composite Freestyle strokes on top of any other render result. That means Freestyle does not need an OpenGL context for rendering anymore: Freestyle strokes can now be visualized fullscreen or in the image editor without a crash. What a delight !

The complete list of changes for this 17671 revision is described in the commit log. The important information to remember is that:

  • the rendering is only correct (in the sense that strokes are correctly overlayed on top of models) if oversampling (OSA) is disabled and if the image is rendered in one tile (Xparts = Yparts = 1)
  • style modules using the underlying scene’s depth or color information  will NOT work.

You’ve been warned… Of course, I will work hard on correcting these vital two features in the days to come. Strokes now being integrated in the rendering pipeline, you do have enough room to experiment with your own style modules.

Here are simple results for this revision (the right column presents the strokes produced by the renderer);

Support for Python's native iterator protocol

Filed under: Update — The dev team @ 12:20 PM

As a preliminary first step towards full support for Python’s native iterator protocol in Freestyle, Stroke and StrokeVertexIterator (used in the shade() method of a StrokeShader implementation) have been improved to adhere to the iterator protocol as follows:

  • Stroke object has __len__() and __getitem__() methods so that subscript can be used, like stroke[0] and stroke[-1].
  • stroke.StrokeVerticesBegin() and stroke.StrokeVerticesEnd() return iterable objects (having next() method).
  • “for v in stroke.StrokeVerticesBegin()” is equivalent to “for v in stroke”.

The conventional C++/SWIG-based syntax is still usable, so programmers can choose a preferable syntax.

Simple iteration

C++/SWIG-based syntax:

    it = stroke.StrokeVerticesBegin()
    while it.isEnd() == 0:
        v = it.getObject()

New syntax #1:

    for v in stroke:

New syntax #2:

    for v in stroke.strokeVerticesBegin():

The strokeVerticesBegin() method takes an optional argument for resampling (the default value is 0, which means no resampling).  The second syntax is useful when the optional argument is specified.

Reverse iteration

C++/SWIG-based syntax:

    it = stroke.StrokeVerticesEnd()
    while it.isBegin() == 0:
        v = it.getObject()

New syntax:

    for v in stroke.StrokeVerticesEnd():

Getting the first StrokeVertex

C++/SWIG-based syntax:

    it = stroke.StrokeVerticesBegin()
        v = it.getObject()

New syntax:

    v = stroke[0]

Getting the last StrokeVertex

C++/SWIG-based syntax:

    it = stroke.StrokeVerticesEnd()
        v = it.getObject()

New syntax:

    v = stroke[-1]

Getting the number of vertices

C++/SWIG-based syntax:

    n = stroke.StrokeVerticeSize()

New syntax:

    n = len(stroke)

Removing vertices during iteration

There are needs to remove some vertices during iteration.  However, the following code will not work, since the removal of vertices may confuse the iteration.

Incorrect code:

    for vertex in stroke:
        if some condition holds:

If an API were designed so as to make this work, stroke.__iter__() would always have to return a copy of the sequence of vertices, which would be expensive in many cases where the removal of vertices is not necessary.

So, a compromised API design has been taken as follows:

  • stroke.__iter__() returns a reference to the sequence of vertices.
  • when removal of vertices is necessary, programmers must create a copy of the stroke explicitly before starting iteration over the vertices.

Correct code #1:

    for vertex in Stroke(stroke):
        if some condition holds:

Correct code #2:

    for vertex in list(stroke):
        if some condition holds:

Create a free website or blog at