[Blender 3.6] UV Packer
This commit is contained in:
parent
80e3c58913
commit
78e31ea49c
18 changed files with 635 additions and 347 deletions
187
cg/pipeline/cg_pipeline.py
Normal file
187
cg/pipeline/cg_pipeline.py
Normal file
|
@ -0,0 +1,187 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
DESCRIPTION.
|
||||
Convert and setup FreeCAD solid objects to 3d assets.
|
||||
Support Blender compiled as a Python Module only!
|
||||
'''
|
||||
__version__ = '0.6'
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
from blender.utils.remove_collections import remove_collections
|
||||
from blender.utils.cleanup_orphan_data import cleanup_orphan_data
|
||||
from utils.cmd_proc import cmd_proc
|
||||
from blender.import_cad.build_blender_scene import json_to_blend
|
||||
from blender.processing.restruct_hierarchy_by_lcs import restruct_hierarchy
|
||||
from blender.processing.highpoly_setup import setup_meshes
|
||||
from blender.processing.lowpoly_setup import parts_to_shells
|
||||
from blender.processing.uv_setup import uv_unwrap
|
||||
import bpy
|
||||
import mathutils
|
||||
# from export.dae import export_dae
|
||||
# from export.collision import export_col_stl
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
'''
|
||||
IMPORT COLLECTIONS NAMIG CONVENTION:
|
||||
Parts - collection for mesh objects
|
||||
LCS - collection for location points
|
||||
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)
|
||||
'''
|
||||
|
||||
# ENV
|
||||
freecadcmd = 'freecadcmd'
|
||||
fcstd_data_script = 'freecad_to_json.py'
|
||||
# COLLECTIONS NAMIG CONVENTION
|
||||
parts_col_name = 'Parts'
|
||||
lcs_col_name = 'LCS'
|
||||
hierarchy_col_name = 'Hierarchy'
|
||||
lowpoly_col_name = 'Lowpoly'
|
||||
# LCS POINT'S SUFFIXES CONVENTION
|
||||
inlet = '_in'
|
||||
outlet = '_out'
|
||||
root = '_root'
|
||||
# CG ASSETS SUFFIXES CONVENTION
|
||||
hightpoly = '_hp'
|
||||
lowpoly = '_lp'
|
||||
render = '_render'
|
||||
|
||||
|
||||
def cg_pipeline(**kwargs):
|
||||
''' CG asset creation pipeline '''
|
||||
|
||||
# prepare blend file
|
||||
remove_collections()
|
||||
cleanup_orphan_data()
|
||||
|
||||
# convert FreeCAD scene to Blender scene
|
||||
objs_for_render = json_to_blend(
|
||||
json.loads(
|
||||
cmd_proc(freecadcmd,
|
||||
fcstd_data_script,
|
||||
'--',
|
||||
**kwargs
|
||||
).split('FreeCAD ')[0]
|
||||
)
|
||||
)
|
||||
|
||||
# restructuring hierarchy by lcs points
|
||||
lcs_objects = restruct_hierarchy()
|
||||
|
||||
# save blender scene
|
||||
if kwargs['blend_path'] is not None:
|
||||
if not os.path.isdir(os.path.dirname(kwargs['blend_path'])):
|
||||
os.makedirs(os.path.dirname(kwargs['blend_path']))
|
||||
bpy.ops.wm.save_as_mainfile(filepath=kwargs['blend_path'])
|
||||
|
||||
# prepare highpoly
|
||||
setup_meshes(objs_for_render, sharpness=True, shading=True)
|
||||
# prepare lowpoly
|
||||
part_names = [p.name.split(inlet)[0] for p in lcs_objects if p.name.endswith(inlet)]
|
||||
lowpoly_objs = parts_to_shells(part_names)
|
||||
uv_unwrap(lowpoly_objs)
|
||||
|
||||
# save blender scene
|
||||
if kwargs['blend_path'] is not None:
|
||||
if not os.path.isdir(os.path.dirname(kwargs['blend_path'])):
|
||||
os.makedirs(os.path.dirname(kwargs['blend_path']))
|
||||
bpy.ops.wm.save_as_mainfile(filepath=kwargs['blend_path'])
|
||||
|
||||
# export all objects
|
||||
if kwargs['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(kwargs['mesh_export_path'])
|
||||
export_col_stl(kwargs['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(
|
||||
'--tesselation_method',
|
||||
type=str,
|
||||
help='Select tesselation method: Standard or FEM.',
|
||||
default='Standard',
|
||||
required=False
|
||||
)
|
||||
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(
|
||||
'--fem_size',
|
||||
type=float,
|
||||
help='For FEM method only! Finite element size in mm',
|
||||
default=50.0,
|
||||
required=False
|
||||
)
|
||||
parser.add_argument(
|
||||
'--skiphidden',
|
||||
type=bool,
|
||||
help='Skip processing for hidden FreeCAD objects',
|
||||
default=True,
|
||||
required=False
|
||||
)
|
||||
parser.add_argument(
|
||||
'--property_forse_nonsolid',
|
||||
type=str,
|
||||
help='FreeCAD property to enable processing for nonsolid objects',
|
||||
default='Robossembler_NonSolid',
|
||||
required=False
|
||||
)
|
||||
parser.add_argument(
|
||||
'--mesh_export_path',
|
||||
type=str, help='Path for export meshes',
|
||||
required=False
|
||||
)
|
||||
parser.add_argument(
|
||||
'--blend_path',
|
||||
type=str,
|
||||
help='Path for export blend assembly file',
|
||||
required=False
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
kwargs = {key: getattr(args, key) for key in dir(args) if not key.startswith('_')}
|
||||
|
||||
cg_pipeline(**kwargs)
|
||||
|
||||
logger.info('CG Pipeline Completed!')
|
Loading…
Add table
Add a link
Reference in a new issue