less copy protection, more size visualization
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

101 行
2.6 KiB

  1. import bpy
  2. from mathutils import Vector, Euler
  3. from math import pi
  4. import json
  5. import os
  6. import subprocess
  7. import xml.etree.ElementTree as ET
  8. c = bpy.data.objects["cam"]
  9. selected = bpy.context.selected_objects[0]
  10. bpy.ops.object.transform_apply( rotation = True )
  11. data = {}
  12. b = selected
  13. FRONT = [0, 1, 2, "Front"]
  14. SIDE = [1, 1, 2, "Side"]
  15. TOP = [0, 0, 1, "Top"]
  16. ANGLED = [0.5, 1, 2, "Angled"]
  17. sides = [FRONT, SIDE, TOP, ANGLED]
  18. path = "/tmp/macrovision/"
  19. media_path = "/home/crux/furry/macrovision/media/"
  20. media_folder = "buildings/Houses/"
  21. os.makedirs(path, exist_ok=True)
  22. os.makedirs(os.path.join(media_path, media_folder), exist_ok=True)
  23. ns = {"svg": "http://www.w3.org/2000/svg"}
  24. ET.register_namespace("", ns["svg"])
  25. TEMPLATE = """
  26. {{
  27. name: "{0}",
  28. sides: {{
  29. {1}
  30. }}
  31. }}"""
  32. VIEW_TEMPLATE = ' "{0}": {{ height: math.unit({1}, "meters") }}'
  33. for angles in sides:
  34. local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector())
  35. global_bbox_center = b.matrix_world @ local_bbox_center
  36. c.location = global_bbox_center
  37. c.data.ortho_scale = max(b.dimensions) * 1.1
  38. c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2])
  39. rot = c.rotation_euler.to_matrix()
  40. rot.invert()
  41. c.location = c.location + Vector([0, 0, 100]) @ rot
  42. data[angles[3]] = b.dimensions[angles[2]]
  43. output_path = os.path.join(path, f"{b.name}-{angles[3]}")
  44. bpy.context.scene.render.filepath = output_path
  45. svg_path = output_path + "0001.svg"
  46. bpy.ops.render.render(write_still = True)
  47. os.rename(svg_path, output_path + ".svg")
  48. subprocess.check_output([
  49. "potrace",
  50. "-b",
  51. "svg",
  52. output_path + ".bmp",
  53. "-o",
  54. output_path + "-fill.svg"
  55. ])
  56. line_xml = ET.parse(output_path + ".svg")
  57. fill_xml = ET.parse(output_path + "-fill.svg")
  58. lines = line_xml.find("./svg:g", namespaces=ns)
  59. fill_xml.find("svg:g[@fill='#000000']", namespaces=ns).attrib["fill"] = "#1a1a1a"
  60. fill_xml.iter().__next__().append(lines)
  61. fill_xml.write(output_path + "-combined.svg")
  62. subprocess.Popen([
  63. "inkscape",
  64. "--without-gui",
  65. "--export-plain-svg=" + os.path.join(media_path, media_folder, f"{b.name}-{angles[3]}.svg"),
  66. "--export-area-drawing",
  67. output_path + "-combined.svg"
  68. ])
  69. fill_xml.write(os.path.join(media_path, media_folder, f"{b.name}-{angles[3]}.svg"))
  70. lines = []
  71. for key, value in data.items():
  72. lines.append(VIEW_TEMPLATE.format(key, value))
  73. print(TEMPLATE.format(b.name, ",\n".join(lines)))