3D to 2D Conversion

Building an SVG exporter

Folkert de Vries  -  December 17th 2014

  • CompSci and O&O thesis project
  • Blender
  • Worked extensively with Tamito Kajiyama and Campbell Barton
  • Brussels

Context

The goal

Build an exporter that converts results from the Freestyle render engine to an SVG format

Table of Contents

  • SVG format
  • Freestyle render engine
  • Process of edge-based rendering
  • The final product

SVG

Scalable Vector Graphics

SVG is an image format that is scalable & resolution-independent​
SVG is supported on the web and animatable

Scale without degrading quality

Freestyle

.

Freestyle

Freestyle is an edge-based non-photorealic rendering engine

made by prosopoblend

made by @reigulli

made by @tomo_

made by @lightbwk

Freestyle's rendering process

scene

render result

stylization

viewmap

Stylization

for sv in stroke:
    sv.attribute.color = (1, 0, 0)
it = stroke.strokeVerticesBegin()
while it.isEnd() == 0:
    it.object.attribute.color = (1, 0, 0)
    it.increment()

Stroke Shaders

Freestyle's stroke shaders apply a series of manipulations to every stroke vertex

class MyShader(StrokeShader):
    def __init__(self, *args):
        #initialize all the stuff
        Strokeshader.__init__(self)

    def shade(self, stroke):
        # give every stroke vertex a red color
        for sv in stroke:
            sv.attribute.color = (1, 0, 0)

Process of the exporter

  • get the location of all points in a stroke
  • convert them to valid SVG
  • write them to a file
@staticmethod
def pathgen(stroke, path, height, split_at_invisible, 
            f=lambda v: not v.attribute.visible):
    """Generator that creates SVG paths (as strings) 
       from the current stroke """
    it = iter(stroke)
    # start first path
    yield path
    for v in it:
        x, y = v.point
        yield '{:.3f}, {:.3f} '.format(x, height - y)
        if split_at_invisible and v.attribute.visible == False:
            # end current and start new path; 
            yield '" />' + path
            # fast-forward till the next visible vertex
            it = dropwhile(f, it)
            # yield next visible vertex           
            svert = next(it, None)
            if svert is None:
                break
            x, y = svert.point 
            yield '{:.3f}, {:.3f} '.format(x, height - y)
    # close current path
    yield '" />'

Final product

A working integrated SVG export for Freestyle in Blender

Conclusion

  • work with other people
  • have an international view
  • contribute to open-source

 

PWS thesis presentation

By folkert de vries

PWS thesis presentation

  • 135