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

145 行
3.9 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. FRONT_CORNER = [0.5, 1, 2, "Front Corner"]
  15. SIDE = [1, 1, 2, "Side"]
  16. BACK_CORNER = [1.5, 1, 2, "Back Corner"]
  17. BACK = [2, 1, 2, "Back"]
  18. BOTTOM = [0, 2, 1, "Bottom"]
  19. TOP = [0, 0, 1, "Top"]
  20. sides = [FRONT, FRONT_CORNER, SIDE, BACK_CORNER, BACK, BOTTOM, TOP]
  21. path = "/tmp/macrovision/"
  22. media_path = "/home/crux/furry/macrovision/media/"
  23. media_folder = "clothing/Boots/"
  24. os.makedirs(path, exist_ok=True)
  25. os.makedirs(os.path.join(media_path, media_folder), exist_ok=True)
  26. ns = {"svg": "http://www.w3.org/2000/svg"}
  27. ET.register_namespace("", ns["svg"])
  28. TEMPLATE = """
  29. {{
  30. name: "{0}",
  31. sides: {{
  32. {1}
  33. }}
  34. }}"""
  35. VIEW_TEMPLATE = ' "{0}": {{ height: math.unit({1}, "meters") }}'
  36. for angles in sides:
  37. local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector())
  38. global_bbox_center = b.matrix_world @ local_bbox_center
  39. c.location = global_bbox_center
  40. c.data.ortho_scale = max(b.dimensions) * 1.1
  41. c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2])
  42. rot = c.rotation_euler.to_matrix()
  43. rot.invert()
  44. c.location = c.location + Vector([0, 0, 100]) @ rot
  45. data[angles[3]] = b.dimensions[angles[2]]
  46. output_path = os.path.join(path, f"{b.name}-{angles[3]}")
  47. bpy.context.scene.render.filepath = output_path
  48. svg_path = output_path + "0001.svg"
  49. bpy.ops.render.render(write_still = True)
  50. os.rename(svg_path, output_path + ".svg")
  51. subprocess.check_output([
  52. "potrace",
  53. "-b",
  54. "svg",
  55. output_path + ".bmp",
  56. "-o",
  57. output_path + "-fill.svg"
  58. ])
  59. line_xml = ET.parse(output_path + ".svg")
  60. fill_xml = ET.parse(output_path + "-fill.svg")
  61. style = None
  62. for elem in line_xml.findall(".//svg:path", namespaces=ns):
  63. if style is None:
  64. style = {}
  65. for key in elem.attrib:
  66. if not key == "d":
  67. style[key] = elem.attrib[key]
  68. for key in style:
  69. del elem.attrib[key]
  70. parts = elem.attrib["d"].strip().split(" ")
  71. if len(parts) > 6 and parts[1] == parts[3] == parts[5] and parts[2] == parts[4] == parts[6]:
  72. elem.attrib["DELETEME"] = True
  73. while True:
  74. child = line_xml.find(".//svg:path[@DELETEME]", namespaces=ns)
  75. parent = line_xml.find(".//svg:path[@DELETEME]...", namespaces=ns)
  76. print(parent, child)
  77. if parent is None:
  78. break
  79. parent.remove(child)
  80. for key in style:
  81. line_xml.find("./svg:g", namespaces=ns).attrib[key] = style[key]
  82. line_xml.write(output_path + "-cleaned.svg")
  83. subprocess.check_output([
  84. "inkscape",
  85. output_path + "-cleaned.svg",
  86. "--batch-process",
  87. "--actions=EditSelectAll;SelectionSimplify;FileSave",
  88. ])
  89. optimized = ET.parse(output_path + "-cleaned.svg")
  90. lines = optimized.find("./svg:g", namespaces=ns)
  91. fill_xml.find("svg:g[@fill='#000000']", namespaces=ns).attrib["fill"] = "#1a1a1a"
  92. fill_xml.iter().__next__().append(lines)
  93. fill_xml.write(output_path + "-combined.svg")
  94. subprocess.check_output([
  95. "inkscape",
  96. "--batch-process",
  97. "--export-plain-svg=" + output_path + "-prepared.svg",
  98. "--export-area-drawing",
  99. output_path + "-combined.svg"
  100. ])
  101. subprocess.check_output([
  102. "svgo",
  103. output_path + "-prepared.svg",
  104. "-o",
  105. os.path.join(media_path, media_folder, f"{b.name}-{angles[3]}.svg")
  106. ])
  107. lines = []
  108. for key, value in data.items():
  109. lines.append(VIEW_TEMPLATE.format(key, value))
  110. print(TEMPLATE.format(b.name, ",\n".join(lines)))