cg: update pipeline to lcs property 2 WIP
This commit is contained in:
parent
6c7e8c46d6
commit
bce317a554
6 changed files with 120 additions and 102 deletions
|
@ -36,12 +36,10 @@ scene_scale = 0.001
|
||||||
blackbody_mat_name = 'Robossembler_Black_Body'
|
blackbody_mat_name = 'Robossembler_Black_Body'
|
||||||
|
|
||||||
|
|
||||||
def json_to_blend(js_data, **cg_config):
|
def json_to_blend(js_data):
|
||||||
''' Reads JSON data and creates Blender scene '''
|
''' Reads JSON data and creates Blender scene '''
|
||||||
lcs_collection = bpy.data.collections.new(cg_config['lcs_col_name'])
|
render_collection = bpy.data.collections.new('Render')
|
||||||
bpy.context.scene.collection.children.link(lcs_collection)
|
bpy.context.scene.collection.children.link(render_collection)
|
||||||
parts_collection = bpy.data.collections.new(cg_config['parts_col_name'])
|
|
||||||
bpy.context.scene.collection.children.link(parts_collection)
|
|
||||||
|
|
||||||
fc_file = list(js_data.keys())[0]
|
fc_file = list(js_data.keys())[0]
|
||||||
|
|
||||||
|
@ -52,7 +50,7 @@ def json_to_blend(js_data, **cg_config):
|
||||||
|
|
||||||
if js_data[fc_file][js_obj]['type'] == 'LCS':
|
if js_data[fc_file][js_obj]['type'] == 'LCS':
|
||||||
if not js_data[fc_file][js_obj].get('Robossembler_SocketFlow'):
|
if not js_data[fc_file][js_obj].get('Robossembler_SocketFlow'):
|
||||||
#if not js_obj.endswith(cg_config['lcs_inlet']) and not js_obj.endswith(cg_config['lcs_outlet']):
|
# TODO test
|
||||||
logger.info('LCS %s is not defined!', js_obj)
|
logger.info('LCS %s is not defined!', js_obj)
|
||||||
continue
|
continue
|
||||||
bobj = bpy.data.objects.new(js_obj, None)
|
bobj = bpy.data.objects.new(js_obj, None)
|
||||||
|
@ -63,7 +61,7 @@ def json_to_blend(js_data, **cg_config):
|
||||||
if 'Robossembler' not in attr:
|
if 'Robossembler' not in attr:
|
||||||
continue
|
continue
|
||||||
bobj[attr] = js_data[fc_file][js_obj][attr]
|
bobj[attr] = js_data[fc_file][js_obj][attr]
|
||||||
lcs_collection.objects.link(bobj)
|
render_collection.objects.link(bobj)
|
||||||
imported_objects['objs_lcs'].append(bobj.name)
|
imported_objects['objs_lcs'].append(bobj.name)
|
||||||
|
|
||||||
elif js_data[fc_file][js_obj]['type'] == 'PART':
|
elif js_data[fc_file][js_obj]['type'] == 'PART':
|
||||||
|
@ -77,7 +75,7 @@ def json_to_blend(js_data, **cg_config):
|
||||||
bmesh.from_pydata(verts, edges, faces)
|
bmesh.from_pydata(verts, edges, faces)
|
||||||
bmesh.update()
|
bmesh.update()
|
||||||
bobj = bpy.data.objects.new(js_obj, bmesh)
|
bobj = bpy.data.objects.new(js_obj, bmesh)
|
||||||
parts_collection.objects.link(bobj)
|
render_collection.objects.link(bobj)
|
||||||
|
|
||||||
if bobj:
|
if bobj:
|
||||||
fc_placement(bobj,
|
fc_placement(bobj,
|
||||||
|
@ -92,7 +90,7 @@ def json_to_blend(js_data, **cg_config):
|
||||||
hierarchy_objs = hierarchy_list(
|
hierarchy_objs = hierarchy_list(
|
||||||
bobj, js_data[fc_file][js_obj]['hierarchy'], scene_scale)
|
bobj, js_data[fc_file][js_obj]['hierarchy'], scene_scale)
|
||||||
for hierarchy_obj in hierarchy_objs:
|
for hierarchy_obj in hierarchy_objs:
|
||||||
parts_collection.objects.link(hierarchy_obj)
|
render_collection.objects.link(hierarchy_obj)
|
||||||
imported_objects['objs_hierarchy'].append(hierarchy_obj.name)
|
imported_objects['objs_hierarchy'].append(hierarchy_obj.name)
|
||||||
|
|
||||||
# one material for the whole object
|
# one material for the whole object
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
DESCRIPTION.
|
DESCRIPTION.
|
||||||
Generte object from collection of objects.
|
Generte object from collection of objects.
|
||||||
'''
|
'''
|
||||||
|
# DEPRECATED
|
||||||
__version__ = '0.1'
|
__version__ = '0.1'
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
'''
|
'''
|
||||||
DESCRIPTION.
|
DESCRIPTION.
|
||||||
Basic mesh processing for asset pipeline.
|
Mesh processing for original tesselated assets for render.
|
||||||
'''
|
'''
|
||||||
__version__ = '0.2'
|
__version__ = '0.3'
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import bpy
|
import bpy
|
||||||
|
@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def setup_meshes(obj_names, cleanup=False, sharpness=False, shading=False):
|
def setup_meshes(obj_names, cleanup=False, sharpness=False, shading=False):
|
||||||
''' Setup raw meshes list after importing '''
|
''' Setup raw meshes list after importing '''
|
||||||
logger.info('Hightpoly meshes setup launched...')
|
logger.info('Render assets setup launched...')
|
||||||
fixed_obj_names = []
|
fixed_obj_names = []
|
||||||
for obj_name in obj_names:
|
for obj_name in obj_names:
|
||||||
if not bpy.data.objects.get(obj_name):
|
if not bpy.data.objects.get(obj_name):
|
||||||
|
@ -71,4 +71,4 @@ def setup_meshes(obj_names, cleanup=False, sharpness=False, shading=False):
|
||||||
|
|
||||||
fixed_obj_names.append(obj_name)
|
fixed_obj_names.append(obj_name)
|
||||||
|
|
||||||
return logger.info('Setup of %s hightpoly meshes is finished!', len(fixed_obj_names))
|
return logger.info('Setup of %s meshes is finished!', len(fixed_obj_names))
|
|
@ -28,17 +28,24 @@ from blender.utils.collection_tools import unlink_from_collections
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def hierarchy_assembly(lcs_names, parts_sequence, **cg_config):
|
def hierarchy_assembly(lcs_names, parts_sequence):
|
||||||
''' Hierarchy by LCS and Parts Assembling Sequence. '''
|
''' Hierarchy by LCS and Parts Assembling Sequence. '''
|
||||||
# collect scene hierarchy start info
|
# collect scene hierarchy start info
|
||||||
main_locators = [obj for obj in bpy.data.objects if not obj.parent]
|
main_locators = [obj for obj in bpy.data.objects if not obj.parent]
|
||||||
lcs_inlet_objects = []
|
lcs_inlet_objects = []
|
||||||
lcs_outlet_objects = []
|
lcs_outlet_objects = []
|
||||||
for name in lcs_names:
|
for lcs_name in lcs_names:
|
||||||
if name.endswith(cg_config['lcs_inlet']):
|
lcs_obj = bpy.data.objects[lcs_name]
|
||||||
lcs_inlet_objects.append(bpy.data.objects[name])
|
if (lcs_obj.get('Robossembler_SocketFlow') == 'inlet'
|
||||||
|
and lcs_obj.get('Robossembler_DefaultOrigin')
|
||||||
|
):
|
||||||
|
lcs_inlet_objects.append(lcs_obj)
|
||||||
else:
|
else:
|
||||||
lcs_outlet_objects.append(bpy.data.objects[name])
|
lcs_outlet_objects.append(lcs_obj)
|
||||||
|
|
||||||
|
if not lcs_inlet_objects:
|
||||||
|
raise Exception('No LCS Inlet objects found!')
|
||||||
|
|
||||||
# get main_locator
|
# get main_locator
|
||||||
main_locator = None
|
main_locator = None
|
||||||
for locator in main_locators:
|
for locator in main_locators:
|
||||||
|
@ -55,18 +62,20 @@ def hierarchy_assembly(lcs_names, parts_sequence, **cg_config):
|
||||||
if not bpy.data.objects.get(part):
|
if not bpy.data.objects.get(part):
|
||||||
return logger.error('%s part object not found!', part)
|
return logger.error('%s part object not found!', part)
|
||||||
|
|
||||||
first_part_obj = bpy.data.objects[parts_sequence[0]]
|
|
||||||
|
|
||||||
# create root lcs by parts sequence
|
# create root lcs by parts sequence
|
||||||
|
first_part_obj = bpy.data.objects[parts_sequence[0]]
|
||||||
root_lcs = None
|
root_lcs = None
|
||||||
for lcs_inlet in first_part_obj.children:
|
for lcs_inlet in first_part_obj.children:
|
||||||
# drop non lcs objs
|
# drop non lcs objs
|
||||||
if lcs_inlet.name not in lcs_names:
|
if lcs_inlet.name not in lcs_names:
|
||||||
continue
|
continue
|
||||||
# drop non inlet objs
|
# drop non DefaultOrigins
|
||||||
if lcs_inlet.name.endswith(cg_config['lcs_outlet']):
|
lcs_obj = bpy.data.objects[lcs_name]
|
||||||
|
if not (lcs_obj.get('Robossembler_SocketFlow') == 'inlet'
|
||||||
|
and lcs_obj.get('Robossembler_DefaultOrigin')
|
||||||
|
):
|
||||||
continue
|
continue
|
||||||
root_lcs_name = cg_config['lcs_root']
|
root_lcs_name = 'root'
|
||||||
root_lcs = bpy.data.objects.new(root_lcs_name, None)
|
root_lcs = bpy.data.objects.new(root_lcs_name, None)
|
||||||
root_lcs.empty_display_type = 'ARROWS'
|
root_lcs.empty_display_type = 'ARROWS'
|
||||||
root_lcs.empty_display_size = 0.15
|
root_lcs.empty_display_size = 0.15
|
||||||
|
@ -74,19 +83,18 @@ def hierarchy_assembly(lcs_names, parts_sequence, **cg_config):
|
||||||
root_lcs.location = lcs_inlet.location
|
root_lcs.location = lcs_inlet.location
|
||||||
root_lcs.rotation_euler = lcs_inlet.rotation_euler
|
root_lcs.rotation_euler = lcs_inlet.rotation_euler
|
||||||
root_lcs.parent = lcs_inlet.parent
|
root_lcs.parent = lcs_inlet.parent
|
||||||
bpy.data.collections[cg_config['lcs_col_name']].objects.link(root_lcs)
|
bpy.context.scene.collection.objects.link(root_lcs)
|
||||||
logger.info('Root Inlet LCS object created!')
|
logger.info('Root Inlet LCS object created!')
|
||||||
|
|
||||||
unparenting(root_lcs)
|
unparenting(root_lcs)
|
||||||
round_transforms(root_lcs)
|
round_transforms(root_lcs)
|
||||||
parenting(root_lcs, main_locator)
|
parenting(root_lcs, main_locator)
|
||||||
|
|
||||||
# retree_by lcs
|
# retree_by lcs
|
||||||
for lcs_inlet_obj in lcs_inlet_objects:
|
for lcs_inlet_obj in lcs_inlet_objects:
|
||||||
# lcs inlet
|
# lcs inlet as main parent
|
||||||
parent_locator = lcs_inlet_obj.parent
|
parent_locator = lcs_inlet_obj.parent
|
||||||
if not parent_locator:
|
if not parent_locator:
|
||||||
return logger.error('LCS %s should have a parent', lcs_inlet_obj.name)
|
raise Exception('LCS %s should have a parent!', lcs_inlet_obj.name)
|
||||||
unparenting(lcs_inlet_obj)
|
unparenting(lcs_inlet_obj)
|
||||||
round_transforms(lcs_inlet_obj)
|
round_transforms(lcs_inlet_obj)
|
||||||
if parent_locator:
|
if parent_locator:
|
||||||
|
@ -94,11 +102,10 @@ def hierarchy_assembly(lcs_names, parts_sequence, **cg_config):
|
||||||
unparenting(parent_locator)
|
unparenting(parent_locator)
|
||||||
parenting(lcs_inlet_obj, parent_locator)
|
parenting(lcs_inlet_obj, parent_locator)
|
||||||
parenting(root_lcs, lcs_inlet_obj)
|
parenting(root_lcs, lcs_inlet_obj)
|
||||||
# lcs outlet
|
# lcs outlet parent to lcs inlet
|
||||||
lcs_outlet = '{}_{}'.format(
|
for lcs_outlet_obj in lcs_inlet_obj.children_recursive:
|
||||||
lcs_inlet_obj.name.rpartition('_')[0], cg_config['lcs_outlet'])
|
if lcs_outlet_obj.name not in lcs_names:
|
||||||
if bpy.data.objects.get(lcs_outlet):
|
continue
|
||||||
lcs_outlet_obj = bpy.data.objects[lcs_outlet]
|
|
||||||
unparenting(lcs_outlet_obj)
|
unparenting(lcs_outlet_obj)
|
||||||
round_transforms(lcs_outlet_obj)
|
round_transforms(lcs_outlet_obj)
|
||||||
parenting(lcs_inlet_obj, lcs_outlet_obj)
|
parenting(lcs_inlet_obj, lcs_outlet_obj)
|
||||||
|
@ -118,20 +125,21 @@ def hierarchy_assembly(lcs_names, parts_sequence, **cg_config):
|
||||||
# collect part names
|
# collect part names
|
||||||
part_name = None
|
part_name = None
|
||||||
for locator in lcs_inlet_obj.children:
|
for locator in lcs_inlet_obj.children:
|
||||||
if locator not in lcs_outlet_objects:
|
if locator in lcs_outlet_objects:
|
||||||
|
continue
|
||||||
part_name = locator.name
|
part_name = locator.name
|
||||||
part_names.append(part_name)
|
part_names.append(part_name)
|
||||||
# pack parts to collections
|
# pack parts to collections
|
||||||
part_col = bpy.data.collections.new('{}_{}'.format(
|
part_col = bpy.data.collections.new(f'{part_name}')
|
||||||
part_name, cg_config['hightpoly']))
|
bpy.data.collections['Render'].children.link(part_col)
|
||||||
bpy.data.collections[cg_config['parts_col_name']].children.link(part_col)
|
|
||||||
for obj in lcs_inlet_obj.children_recursive:
|
for obj in lcs_inlet_obj.children_recursive:
|
||||||
# outlet lcs objects are already in place, don't move it
|
|
||||||
if obj in lcs_outlet_objects:
|
|
||||||
continue
|
|
||||||
unlink_from_collections(obj)
|
unlink_from_collections(obj)
|
||||||
part_col.objects.link(obj)
|
part_col.objects.link(obj)
|
||||||
|
unlink_from_collections(lcs_inlet_obj)
|
||||||
|
part_col.objects.link(lcs_inlet_obj)
|
||||||
|
|
||||||
|
# TODO DEPRECATED
|
||||||
|
"""
|
||||||
# parts assembling
|
# parts assembling
|
||||||
for idx, part_name in enumerate(parts_sequence):
|
for idx, part_name in enumerate(parts_sequence):
|
||||||
# TODO clones for clones
|
# TODO clones for clones
|
||||||
|
@ -160,63 +168,73 @@ def hierarchy_assembly(lcs_names, parts_sequence, **cg_config):
|
||||||
constraint = lcs.constraints.new(type='COPY_TRANSFORMS')
|
constraint = lcs.constraints.new(type='COPY_TRANSFORMS')
|
||||||
constraint.target = root_lcs
|
constraint.target = root_lcs
|
||||||
constraint.enabled = False
|
constraint.enabled = False
|
||||||
|
"""
|
||||||
|
|
||||||
logger.info('Restructuring assembly pipeline finished!')
|
logger.info('Restructuring assembly pipeline finished!')
|
||||||
|
|
||||||
return part_names
|
return part_names
|
||||||
|
|
||||||
|
|
||||||
def hierarchy_separated_parts(lcs_names, **cg_config):
|
def hierarchy_separated_parts(lcs_names):
|
||||||
''' Restructuring pipeline as separated parts. '''
|
''' Restructuring pipeline as separated parts. '''
|
||||||
# collect scene hierarchy start info
|
# collect scene hierarchy start info
|
||||||
lcs_inlet_objects = []
|
lcs_inlet_objects = []
|
||||||
lcs_outlet_objects = []
|
lcs_outlet_objects = []
|
||||||
for name in lcs_names:
|
|
||||||
if name.endswith(cg_config['lcs_inlet']):
|
for lcs_name in lcs_names:
|
||||||
lcs_inlet_objects.append(bpy.data.objects[name])
|
lcs_obj = bpy.data.objects[lcs_name]
|
||||||
|
if (lcs_obj.get('Robossembler_SocketFlow') == 'inlet'
|
||||||
|
and lcs_obj.get('Robossembler_DefaultOrigin')
|
||||||
|
):
|
||||||
|
lcs_inlet_objects.append(lcs_obj)
|
||||||
else:
|
else:
|
||||||
lcs_outlet_objects.append(bpy.data.objects[name])
|
lcs_outlet_objects.append(lcs_obj)
|
||||||
|
|
||||||
|
if not lcs_inlet_objects:
|
||||||
|
raise Exception('No LCS Inlet objects found!')
|
||||||
|
|
||||||
# retree_by lcs
|
# retree_by lcs
|
||||||
part_names = []
|
part_names = []
|
||||||
for lcs_inlet_obj in lcs_inlet_objects:
|
for lcs_inlet_obj in lcs_inlet_objects:
|
||||||
# outlet lcs
|
# lcs inlet as main parent
|
||||||
parent_locator = lcs_inlet_obj.parent
|
parent_locator = lcs_inlet_obj.parent
|
||||||
if not parent_locator:
|
if not parent_locator:
|
||||||
return logger.error('LCS %s should have a parent', lcs_inlet_obj.name)
|
raise Exception('LCS %s should have a parent!', lcs_inlet_obj.name)
|
||||||
unparenting(lcs_inlet_obj)
|
unparenting(lcs_inlet_obj)
|
||||||
round_transforms(lcs_inlet_obj)
|
round_transforms(lcs_inlet_obj)
|
||||||
if parent_locator:
|
if parent_locator:
|
||||||
if parent_locator.parent:
|
if parent_locator.parent:
|
||||||
unparenting(parent_locator)
|
unparenting(parent_locator)
|
||||||
parenting(lcs_inlet_obj, parent_locator)
|
parenting(lcs_inlet_obj, parent_locator)
|
||||||
# lcs outlet
|
# lcs outlet parent to lcs inlet
|
||||||
lcs_outlet = '{}_{}'.format(
|
for lcs_outlet_obj in lcs_inlet_obj.children_recursive:
|
||||||
lcs_inlet_obj.name.rpartition('_')[0], cg_config['lcs_outlet'])
|
if lcs_outlet_obj.name not in lcs_names:
|
||||||
if bpy.data.objects.get(lcs_outlet):
|
continue
|
||||||
lcs_outlet_obj = bpy.data.objects[lcs_outlet]
|
|
||||||
unparenting(lcs_outlet_obj)
|
unparenting(lcs_outlet_obj)
|
||||||
round_transforms(lcs_outlet_obj)
|
round_transforms(lcs_outlet_obj)
|
||||||
parenting(lcs_inlet_obj, lcs_outlet_obj)
|
parenting(lcs_inlet_obj, lcs_outlet_obj)
|
||||||
|
|
||||||
# reset transforms for inlet_lcs
|
# reset transforms for inlet_lcs
|
||||||
lcs_inlet_obj.matrix_world = mathutils.Matrix()
|
lcs_inlet_obj.matrix_world = mathutils.Matrix()
|
||||||
|
|
||||||
# pack parts to collections
|
# pack parts to collections
|
||||||
part_name = None
|
part_name = None
|
||||||
for locator in lcs_inlet_obj.children:
|
for locator in lcs_inlet_obj.children:
|
||||||
if locator not in lcs_outlet_objects:
|
if locator not in lcs_outlet_objects:
|
||||||
part_name = locator.name
|
part_name = locator.name
|
||||||
part_names.append(part_name)
|
part_names.append(part_name)
|
||||||
part_col = bpy.data.collections.new('{}_{}'.format(
|
part_col = bpy.data.collections.new(f'{part_name}')
|
||||||
part_name, cg_config['hightpoly']))
|
bpy.data.collections['Render'].children.link(part_col)
|
||||||
bpy.data.collections[cg_config['parts_col_name']].children.link(part_col)
|
|
||||||
for obj in lcs_inlet_obj.children_recursive:
|
for obj in lcs_inlet_obj.children_recursive:
|
||||||
unlink_from_collections(obj)
|
unlink_from_collections(obj)
|
||||||
part_col.objects.link(obj)
|
part_col.objects.link(obj)
|
||||||
|
unlink_from_collections(lcs_inlet_obj)
|
||||||
|
part_col.objects.link(lcs_inlet_obj)
|
||||||
# remove unmarked objects
|
# remove unmarked objects
|
||||||
marked_objs = sum(
|
marked_objs = sum(
|
||||||
[lcs_inlet_obj.children_recursive for lcs_inlet_obj in lcs_inlet_objects],
|
[lcs_inlet_obj.children_recursive for lcs_inlet_obj in lcs_inlet_objects],
|
||||||
[])
|
[])
|
||||||
parts_col_objs = bpy.data.collections[cg_config['parts_col_name']].objects
|
parts_col_objs = bpy.data.collections['Render'].objects
|
||||||
unmarked_objs = list(set(parts_col_objs) - set(marked_objs))
|
unmarked_objs = list(set(parts_col_objs) - set(marked_objs))
|
||||||
if unmarked_objs:
|
if unmarked_objs:
|
||||||
removed_objs = list(map(bpy.data.objects.remove, unmarked_objs))
|
removed_objs = list(map(bpy.data.objects.remove, unmarked_objs))
|
||||||
|
@ -227,7 +245,7 @@ def hierarchy_separated_parts(lcs_names, **cg_config):
|
||||||
return part_names
|
return part_names
|
||||||
|
|
||||||
|
|
||||||
def hierarchy_single_part(**cg_config):
|
def hierarchy_mono_part():
|
||||||
''' Restructuring pipeline as single part. '''
|
''' Restructuring pipeline as single part. '''
|
||||||
# collect scene hierarchy start info
|
# collect scene hierarchy start info
|
||||||
main_locators = [obj for obj in bpy.data.objects if not obj.parent]
|
main_locators = [obj for obj in bpy.data.objects if not obj.parent]
|
||||||
|
@ -237,9 +255,8 @@ def hierarchy_single_part(**cg_config):
|
||||||
for main_locator in main_locators:
|
for main_locator in main_locators:
|
||||||
part_name = main_locator.name
|
part_name = main_locator.name
|
||||||
part_names.append(part_name)
|
part_names.append(part_name)
|
||||||
part_col = bpy.data.collections.new('{}_{}'.format(
|
part_col = bpy.data.collections.new(f'{part_name}')
|
||||||
part_name, cg_config['hightpoly']))
|
bpy.data.collections['Render'].children.link(part_col)
|
||||||
bpy.data.collections[cg_config['parts_col_name']].children.link(part_col)
|
|
||||||
for obj in main_locator.children_recursive:
|
for obj in main_locator.children_recursive:
|
||||||
unlink_from_collections(obj)
|
unlink_from_collections(obj)
|
||||||
part_col.objects.link(obj)
|
part_col.objects.link(obj)
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
'''
|
'''
|
||||||
DESCRIPTION.
|
DESCRIPTION.
|
||||||
Create lowpoly shells from parts collections.
|
Retopology visual assets for simulation pipeline.
|
||||||
'''
|
'''
|
||||||
__version__ = '0.1'
|
__version__ = '0.3'
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import bpy
|
import bpy
|
|
@ -19,10 +19,10 @@ from utils.cmd_proc import cmd_proc
|
||||||
from blender.import_cad.build_blender_scene import json_to_blend
|
from blender.import_cad.build_blender_scene import json_to_blend
|
||||||
from blender.processing.restruct_hierarchy import (hierarchy_assembly,
|
from blender.processing.restruct_hierarchy import (hierarchy_assembly,
|
||||||
hierarchy_separated_parts,
|
hierarchy_separated_parts,
|
||||||
hierarchy_single_part)
|
hierarchy_mono_part)
|
||||||
from blender.processing.highpoly_setup import setup_meshes
|
from blender.processing.render_assets import setup_meshes
|
||||||
from blender.processing.midpoly_setup import hightpoly_collections_to_midpoly
|
from blender.processing.midpoly_setup import hightpoly_collections_to_midpoly
|
||||||
from blender.processing.lowpoly_setup import parts_to_shells
|
from blender.processing.visual_assets import parts_to_shells
|
||||||
from blender.processing.uv_setup import uv_unwrap
|
from blender.processing.uv_setup import uv_unwrap
|
||||||
from blender.texturing.bake_submitter import bw_bake
|
from blender.texturing.bake_submitter import bw_bake
|
||||||
from blender.texturing.composing import compose_baked_textures
|
from blender.texturing.composing import compose_baked_textures
|
||||||
|
@ -45,21 +45,22 @@ freecad_bin = 'freecadcmd'
|
||||||
blender_bin = 'blender'
|
blender_bin = 'blender'
|
||||||
|
|
||||||
# TODO WEBAPP
|
# TODO WEBAPP
|
||||||
cg_config = {
|
cg_config = {}
|
||||||
'lcs_col_name': 'LCS',
|
"""
|
||||||
'parts_col_name': 'Parts',
|
'parts_col_name': 'Parts',
|
||||||
'midpoly_col_name': 'Midpoly',
|
'midpoly_col_name': 'Midpoly',
|
||||||
'lowpoly_col_name': 'Lowpoly',
|
'visual_col_name': 'Lowpoly',
|
||||||
'lcs_inlet': 'in',
|
'lcs_inlet': 'in',
|
||||||
'lcs_outlet': 'out',
|
'lcs_outlet': 'out',
|
||||||
'lcs_root': 'root',
|
'lcs_root': 'root',
|
||||||
'hightpoly': 'hp',
|
'render': 'hp',
|
||||||
'midpoly': 'mp',
|
'midpoly': 'mp',
|
||||||
'lowpoly': 'lp',
|
'visual': 'lp',
|
||||||
'render': 'render',
|
'render': 'render',
|
||||||
}
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
defined_pipeline_list = ['cad', 'highpoly', 'midpoly', 'lowpoly', 'baking', 'export']
|
defined_pipeline_list = ['cad', 'render', 'visual', 'collision', 'baking', 'export']
|
||||||
|
|
||||||
|
|
||||||
def cg_pipeline(**kwargs):
|
def cg_pipeline(**kwargs):
|
||||||
|
@ -95,7 +96,7 @@ def cg_pipeline(**kwargs):
|
||||||
'--',
|
'--',
|
||||||
**kwargs
|
**kwargs
|
||||||
).split('FreeCAD ')[0]
|
).split('FreeCAD ')[0]
|
||||||
), **cg_config
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Save original cad setup as blender scene
|
# Save original cad setup as blender scene
|
||||||
|
@ -107,53 +108,54 @@ def cg_pipeline(**kwargs):
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
|
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
|
||||||
return blend_file
|
return blend_file
|
||||||
|
|
||||||
# 2) prepare highpoly (depend of cad_objects['objs_lcs'] and parts_sequence)
|
# 2) prepare render (depend of cad_objects['objs_lcs'] and parts_sequence)
|
||||||
# ______________________________
|
# ______________________________
|
||||||
if parts_sequence_path and os.path.isfile(parts_sequence_path):
|
if parts_sequence_path and os.path.isfile(parts_sequence_path):
|
||||||
with open(parts_sequence_path, 'r', encoding='utf-8') as sequence_file:
|
with open(parts_sequence_path, 'r', encoding='utf-8') as sequence_file:
|
||||||
parts_sequence = json.load(sequence_file)
|
parts_sequence = json.load(sequence_file)
|
||||||
else:
|
else:
|
||||||
parts_sequence = None
|
parts_sequence = None
|
||||||
lcs_inlet_objects = [
|
lcs_inlets = [
|
||||||
inlet for inlet in cad_objects['objs_lcs']
|
lcs_name for lcs_name in cad_objects['objs_lcs']
|
||||||
if inlet.endswith(cg_config['lcs_inlet'])]
|
if (bpy.data.objects[lcs_name].get('Robossembler_SocketFlow') == 'inlet'
|
||||||
|
and bpy.data.objects[lcs_name].get('Robossembler_DefaultOrigin'))]
|
||||||
|
|
||||||
# input cases
|
# input cases
|
||||||
# 1 case
|
# 1 case
|
||||||
if parts_sequence and len(lcs_inlet_objects) > 1:
|
if parts_sequence and len(lcs_inlets) > 1:
|
||||||
logger.info('Parts assembling sequence and LCS points found! '
|
logger.info('Parts assembling sequence and LCS points found! '
|
||||||
'Launch "hierarchy_assembly" restructuring pipeline.')
|
'Launch "hierarchy_assembly" restructuring pipeline.')
|
||||||
part_names = hierarchy_assembly(
|
part_names = hierarchy_assembly(
|
||||||
cad_objects['objs_lcs'], parts_sequence, **cg_config)
|
cad_objects['objs_lcs'], parts_sequence)
|
||||||
# 2 case
|
# 2 case
|
||||||
elif parts_sequence and len(lcs_inlet_objects) < 2:
|
elif parts_sequence and len(lcs_inlets) < 2:
|
||||||
return logger.error('Assembly do not have enough LCS points!')
|
return logger.error('Assembly do not have enough LCS points!')
|
||||||
# 3 case
|
# 3 case
|
||||||
elif not parts_sequence and lcs_inlet_objects:
|
elif not parts_sequence and lcs_inlets:
|
||||||
logger.info('Parts assembling sequence not found! '
|
logger.info('Parts assembling sequence not found! '
|
||||||
'Launch "hierarchy_separated_parts" restructuring pipeline.')
|
'Launch "hierarchy_separated_parts" restructuring pipeline.')
|
||||||
part_names = hierarchy_separated_parts(
|
part_names = hierarchy_separated_parts(
|
||||||
cad_objects['objs_lcs'], **cg_config)
|
cad_objects['objs_lcs'])
|
||||||
# 4 case
|
# 4 case
|
||||||
elif not parts_sequence and not lcs_inlet_objects:
|
elif not parts_sequence and not lcs_inlets:
|
||||||
logger.info('Parts assembling sequence and LCS points not found! '
|
logger.info('Parts assembling sequence and LCS points not found! '
|
||||||
'Launch "hierarchy_single_part" restructuring pipeline.')
|
'Launch "hierarchy_mono_part" restructuring pipeline.')
|
||||||
part_names = hierarchy_single_part(**cg_config)
|
part_names = hierarchy_mono_part()
|
||||||
|
|
||||||
if not part_names:
|
if not part_names:
|
||||||
return logger.error('Can not generate parts!')
|
return logger.error('Can not generate parts!')
|
||||||
|
|
||||||
# setup highpolys with materials only
|
# setup renders with materials only
|
||||||
if cad_objects['objs_foreground']:
|
if cad_objects['objs_foreground']:
|
||||||
setup_meshes(cad_objects['objs_foreground'],
|
setup_meshes(cad_objects['objs_foreground'],
|
||||||
sharpness=True, shading=True)
|
sharpness=True, shading=True)
|
||||||
# setup all highpolys
|
# setup all renders
|
||||||
else:
|
else:
|
||||||
setup_meshes(cad_objects['objs_background'],
|
setup_meshes(cad_objects['objs_background'],
|
||||||
sharpness=True, shading=True)
|
sharpness=True, shading=True)
|
||||||
|
|
||||||
# Save highpoly setup as blender scene
|
# Save render setup as blender scene
|
||||||
if kwargs['pipeline_type'] == 'highpoly':
|
if kwargs['pipeline_type'] == 'render':
|
||||||
blend_file = os.path.join(
|
blend_file = os.path.join(
|
||||||
blend_path,
|
blend_path,
|
||||||
'{}_{}.blend'.format(assembly_name, kwargs['pipeline_type'])
|
'{}_{}.blend'.format(assembly_name, kwargs['pipeline_type'])
|
||||||
|
@ -181,19 +183,19 @@ def cg_pipeline(**kwargs):
|
||||||
logger.info('%s midpoly objects ready!', len(midpoly_obj_names))
|
logger.info('%s midpoly objects ready!', len(midpoly_obj_names))
|
||||||
return blend_file
|
return blend_file
|
||||||
|
|
||||||
# 4) prepare lowpoly
|
# 4) prepare visual
|
||||||
# ______________________________
|
# ______________________________
|
||||||
lowpoly_obj_names = parts_to_shells(part_names, **cg_config)
|
visual_obj_names = parts_to_shells(part_names, **cg_config)
|
||||||
uv_unwrap(lowpoly_obj_names)
|
uv_unwrap(visual_obj_names)
|
||||||
|
|
||||||
# Save lowpoly setup as blender scene
|
# Save visual setup as blender scene
|
||||||
if kwargs['pipeline_type'] == 'lowpoly':
|
if kwargs['pipeline_type'] == 'visual':
|
||||||
blend_file = os.path.join(
|
blend_file = os.path.join(
|
||||||
blend_path,
|
blend_path,
|
||||||
'{}_{}.blend'.format(assembly_name, kwargs['pipeline_type'])
|
'{}_{}.blend'.format(assembly_name, kwargs['pipeline_type'])
|
||||||
).replace('\\', '/')
|
).replace('\\', '/')
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
|
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
|
||||||
logger.info('%s lowpoly objects ready!', len(lowpoly_obj_names))
|
logger.info('%s visual objects ready!', len(visual_obj_names))
|
||||||
return blend_file
|
return blend_file
|
||||||
|
|
||||||
# 5) bake textures
|
# 5) bake textures
|
||||||
|
@ -202,7 +204,7 @@ def cg_pipeline(**kwargs):
|
||||||
logger.info('Baking pipeline has been canceled!')
|
logger.info('Baking pipeline has been canceled!')
|
||||||
else:
|
else:
|
||||||
textures_path = os.path.join(blend_path, 'textures').replace('\\', '/')
|
textures_path = os.path.join(blend_path, 'textures').replace('\\', '/')
|
||||||
bake_paths = bw_bake(lowpoly_obj_names,
|
bake_paths = bw_bake(visual_obj_names,
|
||||||
textures_path,
|
textures_path,
|
||||||
kwargs['textures_resolution'],
|
kwargs['textures_resolution'],
|
||||||
**cg_config)
|
**cg_config)
|
||||||
|
@ -218,7 +220,7 @@ def cg_pipeline(**kwargs):
|
||||||
for bake_path in bake_paths:
|
for bake_path in bake_paths:
|
||||||
shutil.rmtree(bake_path)
|
shutil.rmtree(bake_path)
|
||||||
bpy.ops.wm.open_mainfile(filepath=blend_file)
|
bpy.ops.wm.open_mainfile(filepath=blend_file)
|
||||||
assign_pbr_material(lowpoly_obj_names, textures_path)
|
assign_pbr_material(visual_obj_names, textures_path)
|
||||||
bpy.ops.file.make_paths_relative()
|
bpy.ops.file.make_paths_relative()
|
||||||
|
|
||||||
# Save baking setup as blender scene
|
# Save baking setup as blender scene
|
||||||
|
@ -228,7 +230,7 @@ def cg_pipeline(**kwargs):
|
||||||
'{}_{}.blend'.format(assembly_name, kwargs['pipeline_type'])
|
'{}_{}.blend'.format(assembly_name, kwargs['pipeline_type'])
|
||||||
).replace('\\', '/')
|
).replace('\\', '/')
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
|
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
|
||||||
logger.info('%s lowpoly objects baked!', len(lowpoly_obj_names))
|
logger.info('%s visual objects baked!', len(visual_obj_names))
|
||||||
return blend_file
|
return blend_file
|
||||||
|
|
||||||
# 6 export object meshes
|
# 6 export object meshes
|
||||||
|
@ -244,7 +246,7 @@ def cg_pipeline(**kwargs):
|
||||||
|
|
||||||
for part_name in part_names:
|
for part_name in part_names:
|
||||||
export_fbx(
|
export_fbx(
|
||||||
obj_name=f'{part_name}_{cg_config["lowpoly"]}',
|
obj_name=f'{part_name}_{cg_config["visual"]}',
|
||||||
path=os.path.join(export_path, part_name, 'meshes').replace('\\', '/'))
|
path=os.path.join(export_path, part_name, 'meshes').replace('\\', '/'))
|
||||||
export_ply(
|
export_ply(
|
||||||
obj_name=f'{part_name}_{cg_config["midpoly"]}',
|
obj_name=f'{part_name}_{cg_config["midpoly"]}',
|
||||||
|
@ -253,7 +255,7 @@ def cg_pipeline(**kwargs):
|
||||||
obj_name=f'{part_name}_{cg_config["midpoly"]}',
|
obj_name=f'{part_name}_{cg_config["midpoly"]}',
|
||||||
path=os.path.join(export_path, part_name, 'meshes').replace('\\', '/'))
|
path=os.path.join(export_path, part_name, 'meshes').replace('\\', '/'))
|
||||||
export_stl(
|
export_stl(
|
||||||
obj_name=f'{part_name}_{cg_config["lowpoly"]}',
|
obj_name=f'{part_name}_{cg_config["visual"]}',
|
||||||
path=os.path.join(export_path, part_name, 'meshes').replace('\\', '/'))
|
path=os.path.join(export_path, part_name, 'meshes').replace('\\', '/'))
|
||||||
|
|
||||||
logger.info('%s parts exported!', len(part_names))
|
logger.info('%s parts exported!', len(part_names))
|
||||||
|
@ -317,7 +319,7 @@ if __name__ == '__main__':
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--pipeline_type',
|
'--pipeline_type',
|
||||||
type=str,
|
type=str,
|
||||||
help='Set pipeline type: "cad", "highpoly", "midpoly", "lowpoly", "baking", "export"',
|
help='Set pipeline type: "cad", "render","visual", "collision", "baking", "export"',
|
||||||
default='export',
|
default='export',
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue