Freestyle integration into Blender

April 9, 2014

Experimental variable line thickness shaders

Filed under: Update — The dev team @ 2:24 AM

A discussion in the bf-blender-npr mailing list turned out to be productive with new ideas and artist-driven coding experiments.  This blog article presents two experimental Python style modules for Freestyle in Blender as a result of the discussion.  The scripts have been tested with Blender 2.70.

Crease angle dependent thickness

crease_thickness_tn

Video clip: vimeo.com/91306354

This style module draws crease lines with variable line thickness depending on the angle between the two faces on both sides of each crease line segment.

from freestyle.chainingiterators import *
from freestyle.predicates import *
from freestyle.shaders import *
from freestyle.types import Operators
import math

class CreaseAngleDependentThicknessShader(StrokeShader):
    def __init__(self, angle1, angle2, thickness1, thickness2):
        StrokeShader.__init__(self)
        self.__a1 = angle1
        self.__a2 = angle2
        self.__t1 = thickness1
        self.__t2 = thickness2

    def shade(self, stroke):
        delta_a = self.__a2 - self.__a1
        delta_t = self.__t2 - self.__t1
        fac = 1 / delta_a
        for v in stroke:
            fe = v.first_svertex.get_fedge(v.second_svertex)
            if not fe.is_smooth:
                angle = math.degrees(math.acos(-fe.normal_left.dot(fe.normal_right)))
                if angle < self.__a1:
                    t = self.__t1
                elif angle > self.__a2:
                    t = self.__t2
                else:
                    t = self.__t1 + delta_t * (angle - self.__a1) * fac
                #print(angle, t)
                v.attribute.thickness = (t/2, t/2)

upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyNatureUP1D(Nature.CREASE))
Operators.select(upred)
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
shaders_list = [
    SamplingShader(5.0),
    CreaseAngleDependentThicknessShader(70, 120, 5, 0),
    ConstantColorShader(0, 0, 0),
    ]
Operators.create(TrueUP1D(), shaders_list)

Curvature dependent contour line thickness

contour_thickness_tn

Video clip: vimeo.com/91383521

This style module draws contour lines with variable line thickness as a function of radial curvatures.  In short, curvatures are a property of surface that tells you how quickly the surface bends.  With the script below, thicker contour lines are drawn when the contours lie on more quickly bending areas of the surface, while thinner lines appear in more flat areas.

from freestyle.chainingiterators import *
from freestyle.predicates import *
from freestyle.shaders import *
from freestyle.types import Operators
import math

class VariableContourThicknessShader(StrokeShader):
    def __init__(self, Kr1, Kr2, thickness1, thickness2):
        StrokeShader.__init__(self)
        self.__k1 = Kr1
        self.__k2 = Kr2
        self.__t1 = thickness1
        self.__t2 = thickness2

    def shade(self, stroke):
        delta_k = self.__k2 - self.__k1
        delta_t = self.__t2 - self.__t1
        fac = 1 / delta_k
        for v in stroke:
            c1 = v.first_svertex.curvatures
            c2 = v.second_svertex.curvatures
            if c1 is None and c2 is None:
                v.attribute.thickness = (0, 0)
                continue
            if c1 is None:
                Kr = abs(c2[4])
            elif c2 is None:
                Kr = abs(c1[4])
            else:
                Kr = abs(c1[4]) + v.t2d * (abs(c2[4]) - abs(c1[4]))
            if Kr < self.__k1:
                t = self.__t1
            elif Kr > self.__k2:
                t = self.__t2
            else:
                t = self.__t1 + delta_t * (Kr - self.__k1) * fac
            #print(Kr, t)
            v.attribute.thickness = (t/2, t/2)

upred = QuantitativeInvisibilityUP1D(0)
Operators.select(upred)
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
shaders_list = [
    #SamplingShader(1),
    VariableContourThicknessShader(0.001, 0.01, 0, 10),
    ConstantColorShader(1, 0, 0),
    ]
Operators.create(TrueUP1D(), shaders_list)

BF Development Fund project on Freestyle and NPR

Filed under: Update — The dev team @ 2:20 AM

Thanks to the sponsors of the Blender Foundation (BF) Development Fund, a full-time job position has been granted for the development of non-photorealistic (NPR) rendering capabilities in Blender.  The project duration is three months from the 1st of April, 2014.  The proposed work components include Freestyle performance improvements in terms of time and space, better artists experience in interactions with Freestyle, and more general Blender development, all in view of an extensive use of Freestyle and Blender NPR features in the production of the Gooseberry open film.  Below you will find a document summarizing the project elements foreseen in the upcoming months:

http://wiki.blender.org/index.php/User:Kjym3/DevFundProject

As a fresh restart, this blog is going to be used for posting updates on relevant activities in the newly funded project.

Interested Blender artists are kindly invited to the bf-blender-npr mailing list for discussing Freestyle and NPR topics.

Create a free website or blog at WordPress.com.