DI-PCG / scripts /generate.py
thuzhaowang's picture
fix config
5e17843
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import numpy as np
import cv2
import gin
import bpy
import gc
import logging
import argparse
from pathlib import Path
import importlib
import yaml
logging.basicConfig(
format="[%(asctime)s.%(msecs)03d] [%(module)s] [%(levelname)s] | %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO,
)
logger = logging.getLogger(__name__)
import infinigen
from infinigen.core import init, surface
from infinigen.assets.utils.decorate import read_co
from infinigen.assets.utils.misc import assign_material
from infinigen.core.util import blender as butil
from infinigen.assets.lighting import (
hdri_lighting,
holdout_lighting,
sky_lighting,
three_point_lighting,
)
from core.utils.vis_utils import colorObj, setMat_plastic
def generate(generator, params, seed, mesh_save_path, no_mod=False, no_ground=True):
print(params)
print("Generating")
# reset to default
bpy.ops.wm.read_homefile(app_template="")
butil.clear_scene()
# Suppress info messages
bpy.ops.outliner.orphans_purge()
gc.collect()
# configurate infinigen
gin.add_config_file_search_path("./configs/infinigen")
gin.parse_config_files_and_bindings(
["configs/infinigen/base.gin"],
bindings=[],
skip_unknown=True,
finalize_config=False,
)
surface.registry.initialize_from_gin()
print("Configured")
# setup the scene
scene = bpy.context.scene
scene.render.engine = "CYCLES"
scene.cycles.device = "GPU"
scene.render.film_transparent = True
bpy.context.preferences.system.scrollback = 0
bpy.context.preferences.edit.undo_steps = 0
prefs = bpy.context.preferences.addons["cycles"].preferences
for dt in prefs.get_device_types(bpy.context):
prefs.get_devices_for_type(dt[0])
bpy.context.preferences.addons["cycles"].preferences.compute_device_type = "CUDA"
use_devices = [d for d in prefs.devices if d.type == "CUDA"]
for d in prefs.devices:
d.use = False
for d in use_devices:
d.use = True
bpy.context.scene.world.node_tree.nodes["Background"].inputs[0].default_value[0:3] = (0.0, 0.0, 0.0)
print("Setup done")
# update the parameters
generator.update_params(params)
# generate the object
asset = generator.spawn_asset(seed)
generator.finalize_assets(asset)
print("Generated")
parent = asset
if asset.type == "EMPTY":
meshes = [o for o in asset.children_recursive if o.type == "MESH"]
sizes = []
for m in meshes:
co = read_co(m)
sizes.append((np.amax(co, 0) - np.amin(co, 0)).sum())
i = np.argmax(np.array(sizes))
asset = meshes[i]
if not no_mod:
if parent.animation_data is not None:
drivers = parent.animation_data.drivers.values()
for d in drivers:
parent.driver_remove(d.data_path)
co = read_co(asset)
x_min, x_max = np.amin(co, 0), np.amax(co, 0)
parent.location = -(x_min[0] + x_max[0]) / 2, -(x_min[1] + x_max[1]) / 2, 0
butil.apply_transform(parent, loc=True)
if not no_ground:
bpy.ops.mesh.primitive_grid_add(
size=5, x_subdivisions=400, y_subdivisions=400
)
plane = bpy.context.active_object
plane.location[-1] = x_min[-1]
plane.is_shadow_catcher = True
material = bpy.data.materials.new("plane")
material.use_nodes = True
material.node_tree.nodes["Principled BSDF"].inputs[0].default_value = (
0.015,
0.009,
0.003,
1,
)
assign_material(plane, material)
# dump mesh model
save_mesh_filepath = mesh_save_path
bpy.ops.export_scene.gltf(filepath=save_mesh_filepath)
print("Mesh saved in {}".format(save_mesh_filepath))
if __name__ == "__main__":
argparser = argparse.ArgumentParser()
argparser.add_argument("--config", type=str, required=True)
argparser.add_argument('--output_path', type=str, required=True)
argparser.add_argument('--params_path', type=str, required=True)
argparser.add_argument('--seed', type=int, default=0)
args = argparser.parse_args()
# load config
with open(args.config) as f:
cfg = yaml.load(f, Loader=yaml.FullLoader)
# load generators
generators_choices = ["chair", "table", "vase", "basket", "flower", "dandelion"]
factory_names = ["ChairFactory", "TableDiningFactory", "VaseFactory", "BasketBaseFactory", "FlowerFactory", "DandelionFactory"]
category = args.config.split("/")[-1].split("_")[0]
idx = generators_choices.index(category)
# load generator
module = importlib.import_module(f"core.assets.{category}")
gen = getattr(module, factory_names[idx])
generator = gen(args.seed)
# load params
params = np.load(args.params_path, allow_pickle=True).item()
generate(generator, params, args.seed, args.output_path)