Selaa lähdekoodia

Write a script to generate silhouettes from models

This one doesn't require autotracing the lines, which should make
for better results.
master
Fen Dweller 4 vuotta sitten
vanhempi
commit
3d824183ba
1 muutettua tiedostoa jossa 100 lisäystä ja 0 poistoa
  1. +100
    -0
      scripts/blender-freestyle.py

+ 100
- 0
scripts/blender-freestyle.py Näytä tiedosto

@@ -0,0 +1,100 @@
import bpy
from mathutils import Vector, Euler
from math import pi
import json
import os
import subprocess
import xml.etree.ElementTree as ET

c = bpy.data.objects["cam"]

selected = bpy.context.selected_objects[0]

bpy.ops.object.transform_apply( rotation = True )

data = {}

b = selected

FRONT = [0, 1, 2, "Front"]
SIDE = [1, 1, 2, "Side"]
TOP = [0, 0, 1, "Top"]
ANGLED = [0.5, 1, 2, "Angled"]

sides = [FRONT, SIDE, TOP, ANGLED]

path = "/tmp/macrovision/"

media_path = "/home/crux/furry/macrovision/media/"
media_folder = "buildings/Houses/"

os.makedirs(path, exist_ok=True)
os.makedirs(os.path.join(media_path, media_folder), exist_ok=True)


ns = {"svg": "http://www.w3.org/2000/svg"}
ET.register_namespace("", ns["svg"])

TEMPLATE = """
{{
name: "{0}",
sides: {{
{1}
}}
}}"""

VIEW_TEMPLATE = ' "{0}": {{ height: math.unit({1}, "meters") }}'

for angles in sides:
local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector())
global_bbox_center = b.matrix_world @ local_bbox_center
c.location = global_bbox_center
c.data.ortho_scale = max(b.dimensions) * 1.1
c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2])
rot = c.rotation_euler.to_matrix()
rot.invert()
c.location = c.location + Vector([0, 0, 100]) @ rot
data[angles[3]] = b.dimensions[angles[2]]
output_path = os.path.join(path, f"{b.name}-{angles[3]}")
bpy.context.scene.render.filepath = output_path

svg_path = output_path + "0001.svg"

bpy.ops.render.render(write_still = True)
os.rename(svg_path, output_path + ".svg")

subprocess.check_output([
"potrace",
"-b",
"svg",
output_path + ".bmp",
"-o",
output_path + "-fill.svg"
])

line_xml = ET.parse(output_path + ".svg")
fill_xml = ET.parse(output_path + "-fill.svg")
lines = line_xml.find("./svg:g", namespaces=ns)

fill_xml.find("svg:g[@fill='#000000']", namespaces=ns).attrib["fill"] = "#1a1a1a"

fill_xml.iter().__next__().append(lines)

fill_xml.write(output_path + "-combined.svg")

subprocess.Popen([
"inkscape",
"--without-gui",
"--export-plain-svg=" + os.path.join(media_path, media_folder, f"{b.name}-{angles[3]}.svg"),
"--export-area-drawing",
output_path + "-combined.svg"
])

fill_xml.write(os.path.join(media_path, media_folder, f"{b.name}-{angles[3]}.svg"))

lines = []
for key, value in data.items():
lines.append(VIEW_TEMPLATE.format(key, value))

print(TEMPLATE.format(b.name, ",\n".join(lines)))

Loading…
Peruuta
Tallenna