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

146 行
4.3 KiB

  1. import bpy
  2. from mathutils import Vector, Euler
  3. from math import pi, sqrt
  4. import json
  5. import os
  6. import pathlib
  7. VIEW_DATA = {
  8. "Front": [0, 1, 2, "Front"],
  9. "Angled": [0.25, 1, 2, "Angled"],
  10. "Corner": [0.5, 1, 2, "Corner"],
  11. "Side": [1, 1, 2, "Side"],
  12. "Back Angled": [1.5, 1, 2, "Back Angled"],
  13. "Back": [2, 1, 2, "Back"],
  14. "Top": [0, 0, 1, "Top"],
  15. "Bottom": [0, 2, 1, "Bottom"],
  16. "Bottom Flipped": [2, 2, 1, "Bottom Flipped"],
  17. }
  18. def get_bounds(objects):
  19. xl = []
  20. yl = []
  21. zl = []
  22. for obj in objects:
  23. if not obj.hide_render:
  24. for bounds in obj.bound_box:
  25. v = obj.matrix_world @ Vector(bounds)
  26. xl += [v[0] for c in obj.bound_box]
  27. yl += [v[1] for c in obj.bound_box]
  28. zl += [v[2] for c in obj.bound_box]
  29. return (
  30. Vector([min(xl), min(yl), min(zl)]),
  31. Vector([max(xl), max(yl), max(zl)])
  32. )
  33. path_info = pathlib.Path(bpy.data.filepath).parent.joinpath("macrovision-directory.txt")
  34. config_path = pathlib.Path(open(path_info).read().strip())
  35. json_path = config_path.joinpath("config.json")
  36. config = json.load(open(json_path.resolve(), encoding="utf-8"))
  37. parent_workdir = config["work-directory"]
  38. c = bpy.data.objects["cam"]
  39. lineart = bpy.data.objects["lineart"]
  40. c.data.type = "ORTHO"
  41. bpy.data.scenes["Scene"].render.resolution_x = 2000
  42. bpy.data.scenes["Scene"].render.resolution_y = 2000
  43. bpy.data.scenes["Scene"].render.film_transparent = True
  44. bpy.data.scenes["Scene"].view_settings.view_transform = "Raw"
  45. bpy.data.worlds["World"].node_tree.nodes["Background"].inputs[1].default_value = 0
  46. mv = bpy.data.collections["Macrovision"]
  47. collections = mv.children
  48. all_data = {}
  49. all_data["name"] = mv["MVName"]
  50. all_data["kind"] = mv["MVKind"]
  51. all_data["forms"] = []
  52. default_views = []
  53. for view in mv["MVViews"].split(","):
  54. default_views.append(VIEW_DATA[view.strip()])
  55. if "MVViewLabels" in mv:
  56. for pair in mv["MVViewLabels"].split(","):
  57. key, val = pair.split(":")
  58. VIEW_DATA[key.strip()][3] = val.strip()
  59. workdir = pathlib.Path(parent_workdir).joinpath(all_data["name"])
  60. os.makedirs(workdir, exist_ok=True)
  61. for coll in collections:
  62. coll.hide_render = True
  63. for coll in collections:
  64. coll.hide_render = False
  65. bpy.ops.object.select_all(action='DESELECT')
  66. for obj in coll.objects:
  67. obj.select_set(True)
  68. data = {}
  69. data["name"] = coll.name
  70. data["views"] = []
  71. bound_min, bound_max = get_bounds(coll.objects)
  72. dimensions = bound_max - bound_min
  73. size = max(dimensions)
  74. global_bbox_center = 0.5 * (bound_min + bound_max)
  75. view_list = []
  76. if "Views" in coll:
  77. for view in coll["Views"].split(","):
  78. view_list.append(VIEW_DATA[view])
  79. else:
  80. view_list = default_views
  81. for angles in view_list:
  82. c.location = global_bbox_center
  83. c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2])
  84. print(list(bound_min) + list(bound_max))
  85. _, c.data.ortho_scale = c.camera_fit_coords(bpy.context.evaluated_depsgraph_get(), list(bound_min) + list(bound_max))
  86. c.location = Vector([c.location[0], c.location[1], c.location[2]])
  87. c.data.ortho_scale *= 1.2
  88. rot = c.rotation_euler.to_matrix()
  89. rot.invert()
  90. c.location += Vector([0, 0, size * 2]) @ rot
  91. c.data.clip_start = size / 4
  92. c.data.clip_end = size * 8
  93. data["views"].append({
  94. "name": angles[3],
  95. "height": dimensions[angles[2]]
  96. })
  97. if "Volume" in coll:
  98. data["views"][-1]["volume"] = coll["Volume"]
  99. if "Mass" in coll:
  100. data["views"][-1]["mass"] = coll["Mass"]
  101. lineart.hide_render = False
  102. filename = f"{coll.name}-{angles[3]}.png"
  103. bpy.context.scene.render.filepath = workdir.joinpath(filename).resolve().__str__()
  104. bpy.ops.render.render(write_still = True)
  105. lineart.hide_render = True
  106. filename = f"{coll.name}-{angles[3]}-noline.png"
  107. bpy.context.scene.render.filepath = workdir.joinpath(filename).resolve().__str__()
  108. bpy.ops.render.render(write_still = True)
  109. all_data["forms"].append(data)
  110. coll.hide_render = True
  111. with open(workdir.joinpath("data.json"), "w") as file:
  112. json.dump(all_data, file)