less copy protection, more size visualization
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

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