def freestyle_to_gpencil_strokes(strokes, frame, lineset, options): # draw_mode='3DSPACE', color_extraction='BASE'):
    mat = bpy.context.scene.camera.matrix_local.copy()

    # pick the active palette or create a default one
    grease_pencil = bpy.context.scene.grease_pencil
    palette = grease_pencil.palettes.active or grease_pencil.palettes.new("GP_Palette")

    # can we tag the colors the script adds, to remove them when they are not used? 
    cache = { color_to_hex(color.color) : color for color in palette.colors } 

    # keep track of which colors are used (to remove unused ones)
    used = []

    for fstroke in strokes:

        # the color object can be "owned", so use Color to clone it
        if options.color_extraction:
            if options.color_extraction_mode == 'FIRST':
                base_color = Color(fstroke[0].attribute.color)
            elif options.color_extraction_mode == 'FINAL':
                base_color = Color(fstroke[-1].attribute.color)
            else:
                base_color = Color(lineset.linestyle.color)

        # color has to be frozen (immutable) for it to be stored
        base_color.freeze()

        colorname = get_colorname(palette.colors, base_color, palette).name

        # append the current color, so it is kept
        used.append(colorname)

        gpstroke = frame.strokes.new(colorname=colorname)
        gpstroke.draw_mode = options.draw_mode
        gpstroke.points.add(count=len(fstroke), pressure=1, strength=1)

        # the max width gets pressure 1.0. Smaller widths get a pressure 0 <= x < 1 
        base_width = functools.reduce(max, (sum(svert.attribute.thickness) for svert in fstroke), lineset.linestyle.thickness)

        # set the default (pressure == 1) width for the gpstroke
        gpstroke.line_width = base_width

        if options.draw_mode == '3DSPACE':
            for svert, point in zip (fstroke, gpstroke.points):
                point.co = mat * svert.point_3d
                # print(point.co, svert.point_3d)

                if options.thickness_extraction:
                    point.pressure = sum(svert.attribute.thickness) / max(1e-6, base_width)

                if options.alpha_extraction:
                    point.strength = svert.attribute.alpha

        elif options.draw_mode == 'SCREEN':
            width, height = render_dimensions(bpy.context.scene)
            for svert, point in zip (fstroke, gpstroke.points):
                x, y = svert.point
                point.co = Vector((abs(x / width), abs(y / height), 0.0)) * 100

                if options.thickness_extraction:
                    point.pressure = sum(svert.attribute.thickness) / max(1e-6, base_width)

                if options.alpha_extraction:
                    point.strength = svert.attribute.alpha

        else:
            raise NotImplementedError()
def freestyle_to_gpencil_strokes(
        strokes, frame, lineset,
        options):  # draw_mode='3DSPACE', color_extraction='BASE'):
    mat = bpy.context.scene.camera.matrix_local.copy()

    # pick the active palette or create a default one
    grease_pencil = bpy.context.scene.grease_pencil
    palette = grease_pencil.palettes.active or grease_pencil.palettes.new(
        "GP_Palette")

    # can we tag the colors the script adds, to remove them when they are not used?
    cache = {color_to_hex(color.color): color for color in palette.colors}

    # keep track of which colors are used (to remove unused ones)
    used = []

    for fstroke in strokes:

        # the color object can be "owned", so use Color to clone it
        if options.color_extraction:
            if options.color_extraction_mode == 'FIRST':
                base_color = Color(fstroke[0].attribute.color)
            elif options.color_extraction_mode == 'FINAL':
                base_color = Color(fstroke[-1].attribute.color)
            else:
                base_color = Color(lineset.linestyle.color)

        # color has to be frozen (immutable) for it to be stored
        base_color.freeze()

        colorname = get_colorname(palette.colors, base_color, palette).name

        # append the current color, so it is kept
        used.append(colorname)

        gpstroke = frame.strokes.new(colorname=colorname)
        gpstroke.draw_mode = options.draw_mode
        gpstroke.points.add(count=len(fstroke), pressure=1, strength=1)

        # the max width gets pressure 1.0. Smaller widths get a pressure 0 <= x < 1
        base_width = functools.reduce(max, (sum(svert.attribute.thickness)
                                            for svert in fstroke),
                                      lineset.linestyle.thickness)

        # set the default (pressure == 1) width for the gpstroke
        gpstroke.line_width = base_width

        if options.draw_mode == '3DSPACE':
            for svert, point in zip(fstroke, gpstroke.points):
                point.co = mat * svert.point_3d
                # print(point.co, svert.point_3d)

                if options.thickness_extraction:
                    point.pressure = sum(svert.attribute.thickness) / max(
                        1e-6, base_width)

                if options.alpha_extraction:
                    point.strength = svert.attribute.alpha

        elif options.draw_mode == 'SCREEN':
            width, height = render_dimensions(bpy.context.scene)
            for svert, point in zip(fstroke, gpstroke.points):
                x, y = svert.point
                point.co = Vector((abs(x / width), abs(y / height), 0.0)) * 100

                if options.thickness_extraction:
                    point.pressure = sum(svert.attribute.thickness) / max(
                        1e-6, base_width)

                if options.alpha_extraction:
                    point.strength = svert.attribute.alpha

        else:
            raise NotImplementedError()