framework/cg/pipeline/freecad_to_asset.py

156 lines
5.2 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
'''
DESCRIPTION.
Convert and setup FreeCAD solid objects to 3d assets mesh files.
Support Blender compiled as a Python Module only!
'''
__version__ = '0.4'
import logging
import os
import sys
sys.path.append('../blender/')
from import_fcstd.import_cad_objects import obj_importer
from import_fcstd.restruct_hierarchy_by_lcs import restruct_hierarchy
from import_fcstd.import_coordinate_point import lcs_json_importer
from utils.remove_collections import remove_collections
from utils.cleanup_orphan_data import cleanup_orphan_data
from utils.sdf_mesh_selector import sdf_mesh_selector
from remesh.highpoly_setup import setup_meshes
from remesh.lowpoly_setup import parts_to_shells
from export.dae import export_dae
from export.collision import export_col_stl
import bpy
import mathutils
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
'''
IMPORT COLLECTIONS NAMIG CONVENTION:
Import Parts - collection for mesh objects
Import LCS - collection for location points
Import Hierarchy - collection for hierarchy locators
LCS POINT'S SUFFIXES CONVENTION:
'_in' - inlet suffix
'_out' - outlet suffix
'_root' - root suffix
CG ASSETS SUFFIXES CONVENTION:
'_hp' - hightpoly asset (reference baking source)
'_lp' - lowpoly asset (prepared for game engines)
'_render' - root suffix (prepared for render engines)
'''
# COLLECTIONS NAMIG CONVENTION
parts_col_name = 'Import Parts'
lcs_col_name = 'Import LCS'
hierarchy_col_name = 'Import Hierarchy'
lowpoly_col_name = 'Lowpoly Parts'
# LCS POINT'S SUFFIXES CONVENTION
inlet = '_in'
outlet = '_out'
root = '_root'
# CG ASSETS SUFFIXES CONVENTION
hightpoly = '_hp'
lowpoly = '_lp'
render = '_render'
def freecad_asset_pipeline(fcstd_path,
linear_deflection,
angular_deflection,
mesh_export_path=None,
json_path=None,
blend_path=None,
sdf_path=None):
''' Setup FreeCAD scene to CG asset '''
# prepare blend file
remove_collections()
cleanup_orphan_data()
# import objects
objs_for_render = obj_importer(fcstd_path,
linear_deflection,
angular_deflection)
# restructuring hierarchy by lcs points
lcs_objects = restruct_hierarchy()
# import lcs
if not bpy.data.collections.get(lcs_col_name):
if not bpy.data.collections[lcs_col_name].objects:
if json_path is None:
json_path = os.path.dirname(fcstd_path)
for f in os.listdir(os.path.dirname(fcstd_path)):
if f.endswith('.json'):
json_file = os.path.join(json_path, f)
lcs_json_importer(json_file)
# sdf setup WIP
if sdf_path is not None:
sdf_mesh_selector(sdf_path)
# save blender scene
if blend_path is not None:
if not os.path.isdir(os.path.dirname(blend_path)):
os.makedirs(os.path.dirname(blend_path))
bpy.ops.wm.save_as_mainfile(filepath=blend_path)
# retopo
setup_meshes(objs_for_render, sharpness=True, shading=True)
part_names = [p.name.split(inlet)[0] for p in lcs_objects if p.name.endswith(inlet)]
parts_to_shells(part_names)
# save blender scene
if blend_path is not None:
if not os.path.isdir(os.path.dirname(blend_path)):
os.makedirs(os.path.dirname(blend_path))
bpy.ops.wm.save_as_mainfile(filepath=blend_path)
# export all objects
if mesh_export_path is not None:
obs = bpy.context.selected_objects
for ob in obs:
ob.matrix_world = mathutils.Matrix()
for ob in obs:
ob.select_set(state=True)
export_dae(mesh_export_path)
export_col_stl(mesh_export_path)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
description='Convert and setup FreeCAD solid objects to 3d assets mesh files.')
parser.add_argument(
'--fcstd_path', type=str, help='Path to source FreeCAD scene', required=True)
parser.add_argument(
'--linear_deflection', type=float, help='Max linear distance error', default=0.1, required=False)
parser.add_argument(
'--angular_deflection', type=float, help='Max angular distance error', default=20.0, required=False)
parser.add_argument(
'--mesh_export_path', type=str, help='Path for export meshes', required=False)
parser.add_argument(
'--json_path', type=str, help='Path to DIR with coordinate points jsons', required=False)
parser.add_argument(
'--blend_path', type=str, help='Path for export blend assembly file', required=False)
parser.add_argument(
'--sdf_path', type=str, help='Path to source SDF assembly file', required=False)
args = parser.parse_args()
freecad_asset_pipeline(args.fcstd_path,
args.linear_deflection,
args.angular_deflection,
args.mesh_export_path,
args.json_path,
args.blend_path,
args.sdf_path)
logger.info('Assets setup completed!')