RCG: data base names

This commit is contained in:
brothermechanic 2024-04-10 10:25:50 +03:00
parent 0ecf214e26
commit 8aeb802ec8
No known key found for this signature in database
GPG key ID: 9C59EF9503ACD106
4 changed files with 77 additions and 93 deletions

View file

@ -28,10 +28,8 @@ sys.path.append('/nix/store/ip49yhfl2l8gphylj4i43kdpq5qnq93i-bpy-4.1.0/lib/pytho
sys.path.append('/media/disk/robossembler/project/collab/150-cg-render-assets/rcg_pipeline') sys.path.append('/media/disk/robossembler/project/collab/150-cg-render-assets/rcg_pipeline')
sys.path.append('/nix/store/x1rqfn240xn6m6p6077gxfqxdxxj1cmc-python3.11-numpy-1.26.4/lib/python3.11/site-packages') sys.path.append('/nix/store/x1rqfn240xn6m6p6077gxfqxdxxj1cmc-python3.11-numpy-1.26.4/lib/python3.11/site-packages')
import rcg_pipeline import rcg_pipeline
project_dir = '/path/to/<my_freecad_project>' project_dir = '/path/to/<my_project_dir>'
parts_tree_path = '/path/to/<my_assembly>_tree_version.json'
libs_data_path = '/path/to/<my_freecad_project>_libs_data.json'
rcg_pipeline.libs.generate_libs_database(project_dir) rcg_pipeline.libs.generate_libs_database(project_dir)
rcg_pipeline.render_asset.build_render_asset(parts_tree_path, libs_data_path, project_dir) rcg_pipeline.render_asset.build_render_assets(project_dir)
``` ```

View file

@ -42,7 +42,6 @@ __license__ = 'GPL-3'
#__all__ = ['libs', 'render_asset', 'rcg_full_pipeline'] #__all__ = ['libs', 'render_asset', 'rcg_full_pipeline']
import logging import logging
import os
from . import libs from . import libs
from . import render_asset from . import render_asset
@ -55,13 +54,9 @@ def rcg_full_pipeline(project_dir):
''' '''
''' '''
# 1 generate libs # 1 generate libs
libs_data_path = libs.generate_libs_database(project_dir) libs.generate_libs_database(project_dir)
# 2 build render assets # 2 build render assets
parts_tree_names = [ render_asset.build_render_assets(project_dir)
data for data in os.listdir(project_dir)
if data.endswith('tree_version.json')]
for parts_tree_name in parts_tree_names:
parts_tree_path = os.path.join(project_dir, parts_tree_name)
render_asset.build_render_asset(parts_tree_path, libs_data_path, project_dir)
return True return True

View file

@ -52,16 +52,9 @@ logger = logging.getLogger(__name__)
def generate_libs_database(project_dir): def generate_libs_database(project_dir):
''' Generate Blender LIBS database from PARTs database. ''' ''' Generate Blender LIBS database from PARTs database. '''
parts_data_name = [ parts_data_path = os.path.join(project_dir, 'parts.json')
data for data in os.listdir(project_dir) if not os.path.exists(parts_data_path):
if data.endswith('_parts_data.json')] raise Exception('No parts database found! Check %s directory' % project_dir)
if len(parts_data_name) != 1:
raise Exception(
'No database! Only single supported! Check %s directory' % project_dir)
parts_data_path = os.path.join(project_dir, parts_data_name[0])
data_name = parts_data_name[0].split('_parts_data.json')[0]
with open(parts_data_path, encoding='utf-8') as data: with open(parts_data_path, encoding='utf-8') as data:
parts_data = json.load(data) parts_data = json.load(data)
@ -200,7 +193,7 @@ def generate_libs_database(project_dir):
) )
# write db file # write db file
libs_data_path = os.path.join(project_dir, data_name + '_libs_data.json') libs_data_path = os.path.join(project_dir, 'libs.json')
with open(libs_data_path, 'w', encoding='utf-8') as libs_data_file: with open(libs_data_path, 'w', encoding='utf-8') as libs_data_file:
json.dump(libs_data, libs_data_file, ensure_ascii=False, indent=4) json.dump(libs_data, libs_data_file, ensure_ascii=False, indent=4)
logger.info('Database saved successfully to %s!', libs_data_path) logger.info('Database saved successfully to %s!', libs_data_path)

View file

@ -65,74 +65,64 @@ def assembly_builder(item, libs_data, libs_data_dir, collection=None, parent=Non
''' '''
if not collection: if not collection:
collection = bpy.context.scene.collection collection = bpy.context.scene.collection
item_obj = None item_obj = None
if item['type'] == 'LOCATOR': if item['type'] == 'LOCATOR':
item_obj = bpy.data.objects.new(item['name'], None) item_obj = bpy.data.objects.new(item['name'], None)
item_obj.empty_display_type = 'CUBE' item_obj.empty_display_type = 'CUBE'
item_obj.empty_display_size = 0.01 item_obj.empty_display_size = 0.01
collection.objects.link(item_obj) collection.objects.link(item_obj)
elif item['type'] == 'LCS': elif item['type'] == 'LCS':
item_obj = bpy.data.objects.new(item['name'], None) item_obj = bpy.data.objects.new(item['name'], None)
item_obj.empty_display_type = 'ARROWS' item_obj.empty_display_type = 'ARROWS'
item_obj.empty_display_size = round(random.uniform(0.05, 0.15), 3) item_obj.empty_display_size = round(random.uniform(0.05, 0.15), 3)
item_obj.show_in_front = True item_obj.show_in_front = True
collection.objects.link(item_obj) collection.objects.link(item_obj)
elif item['type'] == 'PART': elif item['type'] == 'PART':
# link clones item_data = [
if item.get('base_name'): data for data in libs_data
item_data = [ if data['type'] == 'OBJECT'
data for data in libs_data if data['name'] == item['base_name']]
if data['type'] == 'OBJECT' if not item_data:
if data['name'] == item['base_name']] logger.error('No %s in database!', item['base_name'])
if not item_data: return False
logger.error('No %s in database!', item['name']) # if there is local base_named object in scene -> rename it
return False local_obj = None
# if there is local base_named object in scene -> rename it # for clones
if item['base_name'] != item['name']:
local_obj = [ local_obj = [
loc for loc in bpy.data.objects loc for loc in bpy.data.objects
if loc.name == item['base_name'] if loc.name == item['base_name']
if not loc.library] if not loc.library]
if local_obj: if local_obj:
local_obj[0].name += '_loc' local_obj[0].name += '_loc'
item_file_path = os.path.join(libs_data_dir, item_data[0]['path']) item_file_path = os.path.join(libs_data_dir, item_data[0]['path'])
# TODO already linked # TODO already linked
bpy.ops.wm.link( bpy.ops.wm.link(
filepath=item_file_path, filepath=item_file_path,
directory=os.path.join(item_file_path, 'Collection'), directory=os.path.join(item_file_path, 'Collection'),
filename=item['base_name'], filename=item['base_name'],
relative_path=True, relative_path=True,
do_reuse_local_id=True, do_reuse_local_id=True,
active_collection=True, active_collection=True,
) )
item_obj = bpy.data.objects[item['base_name']] item_obj = bpy.data.objects[item['base_name']]
# for clones
if item['base_name'] != item['name']:
item_obj.name = item['name'] item_obj.name = item['name']
# rename local back # rename local back
if local_obj: if local_obj:
local_obj[0].name = item['base_name'] local_obj[0].name = item['base_name']
# link unical
else:
item_data = [
data for data in libs_data
if data['type'] == 'OBJECT'
if data['name'] == item['name']]
if not item_data:
logger.error('No %s in database!', item['name'])
return False
item_file_path = os.path.join(libs_data_dir, item_data[0]['path'])
bpy.ops.wm.link(
filepath=item_file_path,
directory=os.path.join(item_file_path, 'Collection'),
filename=item['name'],
relative_path=True,
do_reuse_local_id=True,
active_collection=True,
)
item_obj = bpy.data.objects[item['name']]
item_obj.empty_display_type = 'PLAIN_AXES' item_obj.empty_display_type = 'PLAIN_AXES'
item_obj.empty_display_size = 0.01 item_obj.empty_display_size = 0.01
else: else:
logger.error('Unknown object type %s of %s', item['type'], item['name']) logger.error('Unknown object type %s of %s', item['type'], item['name'])
return False return False
item_obj.location = Vector(item['pose'][0]['loc_xyz']) * 0.001 item_obj.location = Vector(item['pose'][0]['loc_xyz']) * 0.001
item_obj.rotation_mode = 'QUATERNION' item_obj.rotation_mode = 'QUATERNION'
item_obj.rotation_quaternion = [ item_obj.rotation_quaternion = [
@ -197,42 +187,50 @@ def assembly_rebuilder():
return default_origin return default_origin
def build_render_asset(parts_tree_path, libs_data_path, project_dir): def build_render_assets(project_dir):
''' '''
''' '''
# start from stratch libs_data_path = os.path.join(project_dir, 'libs.json')
bpy.ops.wm.read_homefile() if not os.path.exists(libs_data_path):
remove_collections_with_objects() raise Exception('No libs database found! Check %s directory' % project_dir)
cleanup_orphan_data()
with open(parts_tree_path, encoding='utf-8') as data:
parts_tree_item = json.load(data)
with open(libs_data_path, encoding='utf-8') as data: with open(libs_data_path, encoding='utf-8') as data:
libs_data = json.load(data) libs_data = json.load(data)
trees_path = os.path.join(project_dir, 'trees.json')
if not os.path.exists(trees_path):
raise Exception('No trees database found! Check %s directory' % project_dir)
with open(trees_path, encoding='utf-8') as data:
tree_item_list = json.load(data)
# create redner collection for tree_item in tree_item_list:
render_collection = bpy.data.collections.new(parts_tree_item['name']) # start from stratch
bpy.context.scene.collection.children.link(render_collection) bpy.ops.wm.read_homefile()
active_collection = recursive_layer_collection( remove_collections_with_objects()
bpy.context.view_layer.layer_collection, cleanup_orphan_data()
render_collection.name)
bpy.context.view_layer.active_layer_collection = active_collection
# build original hierarchy # create redner collection
assembly_builder(parts_tree_item, libs_data, project_dir, render_collection) render_collection = bpy.data.collections.new(tree_item['name'])
# rebuild to LCS hierarchy bpy.context.scene.collection.children.link(render_collection)
assembly_rebuilder() active_collection = recursive_layer_collection(
bpy.context.view_layer.layer_collection,
render_collection.name)
bpy.context.view_layer.active_layer_collection = active_collection
# render assets dir # build original hierarchy
render_assets_dir = os.path.join(project_dir, 'assets', 'render') assembly_builder(tree_item, libs_data, project_dir, render_collection)
if os.path.exists(render_assets_dir): # rebuild to LCS hierarchy
shutil.rmtree(render_assets_dir) assembly_rebuilder()
os.makedirs(render_assets_dir)
else:
os.makedirs(render_assets_dir)
blend_path = os.path.join(render_assets_dir, parts_tree_item['name'] + '.blend') # render assets dir
bpy.ops.wm.save_as_mainfile(filepath=blend_path) render_assets_dir = os.path.join(project_dir, 'assets', 'render')
logger.info('Render asset %s generated!', parts_tree_item['name']) if os.path.exists(render_assets_dir):
shutil.rmtree(render_assets_dir)
os.makedirs(render_assets_dir)
else:
os.makedirs(render_assets_dir)
return blend_path blend_path = os.path.join(render_assets_dir, tree_item['name'] + '.blend')
bpy.ops.wm.save_as_mainfile(filepath=blend_path)
logger.info('Render asset %s generated!', tree_item['name'])
logger.info('%s Render Assets was generated!', len(tree_item_list))
return render_assets_dir