Freestyle integration into Blender

December 29, 2010

Weekly updates December 6-26

Filed under: Update — The dev team @ 1:50 AM

The last three weeks were mainly spent for bug fixes and consolidation of the Freestyle renderer.

  • A bug in stroke rendering with round/square caps was fixed.  A freeze of the program was caused by a stroke having two vertices that reside (exactly or almost) at  the same position in the 3D space.
  • The Parameter Editor mode was improved so that it accepts quote symbols within the names of scene render layers and linesets.
  • Incorrect vertex normals in the case of smooth surfaces were fixed.  Many thanks to Stéphane for his careful code review and bug report!
  • Compilation errors with CMake on Linux were fixed by a patch from Écrivain through the BA Freestyle thread.  Thanks!

In addition, the Freestyle Python API has been slightly extended by wrappers of the following Operators class methods in the C++ layer:

  • getViewEdgeFromIndex(index): Returns a ViewEdge object in the current set of ViewEdges (0 <= index < Operators.getViewEdgesSize()).
  • getChainFromIndex(index): Returns a Chain object in the current set of Chains (0 <= index < Operators.getChainsSize()).
  • getStrokeFromIndex(index): Returns a Stroke object in the current set of Strokes (0 <= index < Operators.getStrokesSize()).

When you want to iterate over all objects in the current set of ViewEdges, Chains, or Strokes (for instance, in order to find the minimum and maximum Z depths, or sum up the lengths of all strokes), these API functions give a procedural programming way of accessing the objects, instead of relying on implicit side-effects of declarative rules (such as predicates and shaders).


December 5, 2010

Weekly update November 29-December 5

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

Since the last blog update, the dev team was working on bug fixes, addition of new features, and consolidation of existing functionalities.

A compilation issue with MinGW32 was fixed thanks to a report from Dazzle, and a bug in Distance from Object modifiers due to a recent change in the trunk about matrix-vector multiplication was fixed based on a .blend file provided by Jonathan Hudson.  We really appreciate the user feedback, which helps the dev team to improve the software.

In the meantime, the Parameter Editor mode was extended with two new feature edge selection options.  One is the “Selection by Group” option and the other is the “Selection by Image Border” option, both in part of linesets in the Parameter Editor mode, as shown in the screenshot below.

The Selection by Group option allows you to select feature edges based on a group of objects (defined through the Groups tab in the Object buttons).  For each lineset, you can specify one group of objects.  The group-based feature edge selection is either inclusive or exclusive.  If inclusive, feature edges are selected when they belong to some object in the group; otherwise, those feature edges not belonging to any object in the group are selected.  When no group is specified, feature edges are selected from all objects in object layers enabled in a render layer.  In the past, render layers were the only way to apply different line styles to different objects in the same scene.  This required the use of the compositor and thus a more and less complicated workflow.  The group-based feature edge selection is intended to address this difficulty, making object-specific line stylization much easier.  The image below is a result using this new feature.  A group of objects comprising a lily in the middle was defined, based on which white lines were drawn.  A different line style was applied to lines of two lilies in the left and right using a separate object group.

The Selection by Image Border option is used to select feature edges within the border of the image being rendered.  The border is defined either by the frame size or a border region (specified by the Shift-B key in a 3D View window).  When you work on a big scene with a lot of objects outside the viewing frustum, enabling this option leads to less memory consumption and possibly shorter rendering time.

Finally, the data flow within the Freestyle renderer was revised with the aim of reducing the amount of memory consumption.  Rendering of a 3D scene in Freestyle involves several data structures holding different representations of the scene and strokes generated from the scene.  The data processing in Freestyle is summarized as follows:

  1. First of all, mesh data are imported from the 3D scene and stored in a tree-based data structure.
  2. The mesh data are transformed into a data structure called winged edges and stored in a 3D grid structure for efficient spatial search.
  3. The winged edges are used for view map calculation, and a separate view map data structure is constructed.
  4. The view map is fed to stroke generation by means of style modules (it is noted that the Parameter Editor mode is implemented as a built-in style module).
  5. Generated strokes are converted into Blender mesh data for stroke rendering.

Previously, all the data structures were kept until the end of the entire rendering process.  This makes sense in the original, stand-alone Freestyle program, in which the view map, for instance, can be reused for applying different style modules one after another.  This is not the case in Freestyle for Blender, where the view map is recalculated for each render.  Therefore, the memory resources allocated for the data structures should be released soon after they become unnecessary even in the middle of the rendering process.  For this reason, memory usage improvements were made with regard to the aforementioned data structures.  The improvements were verified by a test scene (generated using a modified version of “Arc” in Structure Synth) consisting of 34968 vertices and 52452 faces.  The left image below is a rendering result.  Using a 64-bit Windows machine, memory consumption in the latest revision 33485 was compared with that in revision 33434 without the memory-related updates.  The right image below shows the amount of allocated memory (in the vertical axis) throughout the rendering time (in the horizontal axis).  The maximum amount of allocated memory in the older revision was about 2.138 GB, which reduced to 1.439 GB through the memory usage optimization as well as the Selection by Image Border option.


Experiments with several other test scenes showed that the extent of memory usage reduction depends on scenes.  We hope the reported updates will allow branch users to render big scenes without an out-of-memory crash.

Blog at