less copy protection, more size visualization
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 

124 рядки
3.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. import bmesh
  8. def get_bounds(objects):
  9. xl = []
  10. yl = []
  11. zl = []
  12. for obj in objects:
  13. for bounds in obj.bound_box:
  14. v = obj.matrix_world @ Vector(bounds)
  15. xl += [v[0] for c in obj.bound_box]
  16. yl += [v[1] for c in obj.bound_box]
  17. zl += [v[2] for c in obj.bound_box]
  18. return (
  19. Vector([min(xl), min(yl), min(zl)]),
  20. Vector([max(xl), max(yl), max(zl)])
  21. )
  22. GROUP_NAME = "Billboards"
  23. GROUP_KIND = "buildings"
  24. path_info = pathlib.Path(bpy.data.filepath).parent.joinpath("macrovision-directory.txt")
  25. config_path = pathlib.Path(open(path_info).read())
  26. json_path = config_path.joinpath("config.json")
  27. config = json.load(open(json_path.resolve(), encoding="utf-8"))
  28. parent_workdir = config["work-directory"]
  29. workdir = pathlib.Path(parent_workdir).joinpath(GROUP_NAME)
  30. c = bpy.data.objects["cam"]
  31. c.data.type = "ORTHO"
  32. bpy.data.scenes["Scene"].render.resolution_x = 1000
  33. bpy.data.scenes["Scene"].render.resolution_y = 1000
  34. bpy.data.scenes["Scene"].render.film_transparent = True
  35. bpy.data.scenes["Scene"].view_settings.view_transform = "Raw"
  36. bpy.data.worlds["World"].node_tree.nodes["Background"].inputs[1].default_value = 0
  37. collections = bpy.data.collections["Macrovision"].children
  38. all_data = {}
  39. all_data["name"] = GROUP_NAME
  40. all_data["kind"] = GROUP_KIND
  41. all_data["forms"] = []
  42. VOLUME = False
  43. os.makedirs(workdir, exist_ok=True)
  44. VIEW_DATA = {
  45. "Front": [0, 1, 2, "Front"],
  46. "Angled": [0.5, 1, 2, "Angled"],
  47. "Side": [1, 1, 2, "Side"],
  48. "Back": [2, 1, 2, "Back"],
  49. "Top": [0, 0, 1, "Top"]
  50. }
  51. for coll in collections:
  52. coll.hide_render = True
  53. for coll in collections:
  54. coll.hide_render = False
  55. bpy.ops.object.select_all(action='DESELECT')
  56. for obj in coll.objects:
  57. obj.select_set(True)
  58. data = {}
  59. data["name"] = coll.name
  60. data["views"] = []
  61. bound_min, bound_max = get_bounds(coll.objects)
  62. dimensions = bound_max - bound_min
  63. size = max(dimensions)
  64. global_bbox_center = 0.5 * (bound_min + bound_max)
  65. view_list = []
  66. if "Views" in coll:
  67. for view in coll["Views"].split(","):
  68. view_list.append(VIEW_DATA[view])
  69. else:
  70. view_list = [VIEW_DATA["Front"]]
  71. for angles in view_list:
  72. c.location = global_bbox_center
  73. largest = size
  74. c.data.ortho_scale = largest * 1.2
  75. if angles[0] % 1 != 0:
  76. c.data.ortho_scale *= sqrt(2)
  77. c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2])
  78. rot = c.rotation_euler.to_matrix()
  79. rot.invert()
  80. c.location = c.location + Vector([0, 0, largest * 2]) @ rot
  81. c.data.clip_start = largest / 4
  82. c.data.clip_end = largest * 4
  83. data["views"].append({
  84. "name": angles[3],
  85. "height": dimensions[angles[2]]
  86. })
  87. #s.rotation_euler = c.rotation_euler
  88. filename = f"{coll.name}-{angles[3]}.png"
  89. bpy.context.scene.render.filepath = workdir.joinpath(filename).resolve().__str__()
  90. bpy.ops.render.render(write_still = True)
  91. all_data["forms"].append(data)
  92. coll.hide_render = True
  93. with open(workdir.joinpath("data.json"), "w") as file:
  94. json.dump(all_data, file)