code / place_in_blender.py
MSheng-Lee's picture
Upload folder using huggingface_hub
f20b100 verified
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)