File size: 5,867 Bytes
f20b100 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
import bpy
import json
import math
import os
object_name = 'Cube'
object_to_delete = bpy.data.objects.get(object_name)
# Check if the object exists before trying to delete it
if object_to_delete is not None:
bpy.data.objects.remove(object_to_delete, do_unlink=True)
def import_glb(file_path, object_name):
bpy.ops.import_scene.gltf(filepath=file_path)
imported_object = bpy.context.view_layer.objects.active
if imported_object is not None:
imported_object.name = object_name
def import_fbx(file_path, object_name):
bpy.ops.import_scene.fbx(filepath=file_path)
for obj in bpy.context.selected_objects:
obj.name = object_name
def create_room(width, depth, height):
# Create floor
bpy.ops.mesh.primitive_plane_add(size=1, enter_editmode=False, align='WORLD', location=(0, 0, 0))
# Extrude to create walls
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0, 0, height)})
bpy.ops.object.mode_set(mode='OBJECT')
# Scale the walls to the desired dimensions
bpy.ops.transform.resize(value=(width, depth, 1))
bpy.context.active_object.location.x += width / 2
bpy.context.active_object.location.y += depth / 2
def find_files(directory, extensions):
files = {}
for root, dirs, filenames in os.walk(directory):
for filename in filenames:
if filename.endswith(extensions):
key = filename.split(".")[0]
if key not in files:
files[key] = os.path.join(root, filename)
return files
def get_highest_parent_objects():
highest_parent_objects = []
for obj in bpy.data.objects:
# Check if the object has no parent
if obj.parent is None:
highest_parent_objects.append(obj)
return highest_parent_objects
def delete_empty_objects():
# Iterate through all objects in the scene
for obj in bpy.context.scene.objects:
# Check if the object is empty (has no geometry)
print(obj.name, obj.type)
if obj.type == 'EMPTY':
bpy.context.view_layer.objects.active = obj
bpy.data.objects.remove(obj)
def select_meshes_under_empty(empty_object_name):
# Get the empty object
empty_object = bpy.data.objects.get(empty_object_name)
print(empty_object is not None)
if empty_object is not None and empty_object.type == 'EMPTY':
# Iterate through the children of the empty object
for child in empty_object.children:
# Check if the child is a mesh
if child.type == 'MESH':
# Select the mesh
child.select_set(True)
bpy.context.view_layer.objects.active = child
else:
select_meshes_under_empty(child.name)
def rescale_object(obj, scale):
# Ensure the object has a mesh data
if obj.type == 'MESH':
bbox_dimensions = obj.dimensions
scale_factors = (
scale["length"] / bbox_dimensions.x,
scale["width"] / bbox_dimensions.y,
scale["height"] / bbox_dimensions.z
)
obj.scale = scale_factors
objects_in_room = {}
file_path = "scene_graph.json"
with open(file_path, 'r') as file:
data = json.load(file)
for item in data:
if item["new_object_id"] not in ["south_wall", "north_wall", "east_wall", "west_wall", "middle of the room", "ceiling"]:
objects_in_room[item["new_object_id"]] = item
directory_path = os.path.join(os.getcwd(), "Assets")
fbx_files = find_files(directory_path, ".fbx")
glb_files = find_files(directory_path, ".glb")
for item_id, object_in_room in objects_in_room.items():
if item_id in fbx_files:
fbx_file_path = fbx_files[item_id]
import_fbx(fbx_file_path, item_id)
for item_id, object_in_room in objects_in_room.items():
if item_id in glb_files:
glb_file_path = glb_files[item_id]
import_glb(glb_file_path, item_id)
parents = get_highest_parent_objects()
empty_parents = [parent for parent in parents if parent.type == "EMPTY"]
print(empty_parents)
for empty_parent in empty_parents:
bpy.ops.object.select_all(action='DESELECT')
select_meshes_under_empty(empty_parent.name)
bpy.ops.object.join()
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS')
joined_object = bpy.context.view_layer.objects.active
if joined_object is not None:
joined_object.name = empty_parent.name + "-joined"
bpy.context.view_layer.objects.active = None
MSH_OBJS = [m for m in bpy.context.scene.objects if m.type == 'MESH']
for OBJS in MSH_OBJS:
bpy.context.view_layer.objects.active = OBJS
bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')
OBJS.location = (0.0, 0.0, 0.0)
bpy.context.view_layer.objects.active = OBJS
OBJS.select_set(True)
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS')
MSH_OBJS = [m for m in bpy.context.scene.objects if m.type == 'MESH']
for OBJS in MSH_OBJS:
item = objects_in_room[OBJS.name.split("-")[0]]
object_position = (item["position"]["x"], item["position"]["y"], item["position"]["z"]) # X, Y, and Z coordinates
object_rotation_z = (item["rotation"]["z_angle"] / 180.0) * math.pi + math.pi # Rotation angles in radians around the X, Y, and Z axes
bpy.ops.object.select_all(action='DESELECT')
OBJS.select_set(True)
OBJS.location = object_position
bpy.ops.transform.rotate(value=object_rotation_z, orient_axis='Z')
rescale_object(OBJS, item["size_in_meters"])
bpy.ops.object.select_all(action='DESELECT')
delete_empty_objects()
# TODO: Generate the room with the room dimensions
create_room(4.0, 4.0, 2.5) |