# -*- coding: utf-8 -*- # Original code by (C) 2019 yorikvanhavre # Copyright (C) 2023 Ilia Kurochkin # # 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.1' import logging import random import bpy from blender.utils.object_transforms import apply_transforms from blender.import_cad.import_hierarchy import (fc_placement, hierarchy) from blender.import_cad.import_materials import (assign_materials, assign_black) logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) # COLLECTIONS NAMIG CONVENTION part_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' scene_scale = 0.001 blackbody_mat_name = 'Robossembler_Black_Body' def json_to_blend(js_data): ''' Reads JSON data and creates Blender scene ''' part_collection = bpy.data.collections.new(part_col_name) bpy.context.scene.collection.children.link(part_collection) lcs_collection = bpy.data.collections.new(lcs_col_name) bpy.context.scene.collection.children.link(lcs_collection) hierarchy_collection = bpy.data.collections.new(hierarchy_col_name) bpy.context.scene.collection.children.link(hierarchy_collection) fc_file = list(js_data.keys())[0] bobjs = [] bobjs_for_render = [] 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) 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) part_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(bobj, js_data[fc_file][js_obj]['hierarchy'], scene_scale) for hierarchy_obj in hierarchy_objs: hierarchy_collection.objects.link(hierarchy_obj) # 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) bobjs_for_render.append(bobj) else: assign_black(bobj) bobjs.append(bobj) # losted root lcs inlet workaround lcs_objects = lcs_collection.objects if lcs_objects: root_lcs = [lcs for lcs in lcs_objects if lcs.name.endswith(root)] if root_lcs: root_lcs = root_lcs[0] root_inlet_name = '{}{}'.format(root_lcs.name.split(root)[0], inlet) if not bpy.data.objects.get(root_inlet_name): root_inlet = bpy.data.objects.new(root_inlet_name, None) root_inlet.empty_display_type = 'ARROWS' root_inlet.empty_display_size = 0.1 root_inlet.show_in_front = True root_inlet.location = root_lcs.location root_inlet.rotation_euler = root_lcs.rotation_euler root_inlet.parent = root_lcs.parent lcs_collection.objects.link(root_inlet) else: logger.info('Lost root LCS object!') # TODO # update do not dork logger.info('Generated %s objects without errors', len(bobjs)) return bobjs_for_render