102 lines
3.9 KiB
Python
102 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright (C) 2023 Ilia Kurochkin <brothermechanic@gmail.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
'''
|
|
DESCRIPTION.
|
|
- Build Blender scene from JSON data.
|
|
- Setup hierarchy.
|
|
- Setup materials.
|
|
- Setup LCS points.
|
|
- Apply Bledner scene transforms.
|
|
'''
|
|
__version__ = '0.2'
|
|
|
|
import collections
|
|
import logging
|
|
import random
|
|
import bpy
|
|
from blender.utils.object_transforms import apply_transforms
|
|
from blender.import_cad.import_hierarchy import (fc_placement,
|
|
hierarchy_list)
|
|
from blender.import_cad.import_materials import (assign_materials,
|
|
assign_black)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
scene_scale = 0.001
|
|
blackbody_mat_name = 'Robossembler_Black_Body'
|
|
|
|
|
|
def json_to_blend(js_data, **cg_config):
|
|
''' Reads JSON data and creates Blender scene '''
|
|
lcs_collection = bpy.data.collections.new(cg_config['lcs_col_name'])
|
|
bpy.context.scene.collection.children.link(lcs_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]
|
|
|
|
imported_objects = collections.defaultdict(list)
|
|
|
|
for js_obj in js_data[fc_file]:
|
|
bobj = None
|
|
|
|
if js_data[fc_file][js_obj]['type'] == 'LCS':
|
|
bobj = bpy.data.objects.new(js_obj, None)
|
|
bobj.empty_display_type = 'ARROWS'
|
|
bobj.empty_display_size = round(random.uniform(0.05, 0.15), 3)
|
|
bobj.show_in_front = True
|
|
lcs_collection.objects.link(bobj)
|
|
imported_objects['objs_lcs'].append(bobj.name)
|
|
|
|
elif js_data[fc_file][js_obj]['type'] == 'PART':
|
|
if js_data[fc_file][js_obj].get('mesh'):
|
|
verts = js_data[fc_file][js_obj]['mesh'][0]
|
|
edges = []
|
|
faces = js_data[fc_file][js_obj]['mesh'][1]
|
|
|
|
# create blender object data
|
|
bmesh = bpy.data.meshes.new(name=js_obj)
|
|
bmesh.from_pydata(verts, edges, faces)
|
|
bmesh.update()
|
|
bobj = bpy.data.objects.new(js_obj, bmesh)
|
|
parts_collection.objects.link(bobj)
|
|
|
|
if bobj:
|
|
fc_placement(bobj,
|
|
js_data[fc_file][js_obj]['fc_location'],
|
|
js_data[fc_file][js_obj]['fc_rotation'],
|
|
scene_scale)
|
|
if bobj.type == 'MESH':
|
|
bobj.scale = (scene_scale, scene_scale, scene_scale)
|
|
apply_transforms(bobj, scale=True)
|
|
|
|
# construct assembly hierarchy
|
|
hierarchy_objs = hierarchy_list(
|
|
bobj, js_data[fc_file][js_obj]['hierarchy'], scene_scale)
|
|
for hierarchy_obj in hierarchy_objs:
|
|
parts_collection.objects.link(hierarchy_obj)
|
|
imported_objects['objs_hierarchy'].append(hierarchy_obj.name)
|
|
|
|
# one material for the whole object
|
|
if bobj.type == 'MESH':
|
|
if js_data[fc_file][js_obj].get('material'):
|
|
fem_mat = js_data[fc_file][js_obj]['material']
|
|
assign_materials(bobj, fem_mat)
|
|
imported_objects['objs_foreground'].append(bobj.name)
|
|
else:
|
|
assign_black(bobj)
|
|
imported_objects['objs_background'].append(bobj.name)
|
|
|
|
logger.info('Generated %s objects without errors',
|
|
len(sum(list(imported_objects.values()), [])))
|
|
return imported_objects
|