diff --git a/BEngine-Py/BERunNodes.py b/BEngine-Py/BERunNodes.py deleted file mode 100644 index e889002..0000000 --- a/BEngine-Py/BERunNodes.py +++ /dev/null @@ -1,145 +0,0 @@ -try: - - import bpy - - import traceback - # from unicodedata import decimal - - import sys - import os - - import json - - import time - - import pathlib - - try: - from .Utils import BEUtils - except: - # Load BEUtils - PACKAGE_PARENT = pathlib.Path(__file__).parent - #PACKAGE_PARENT = pathlib.Path.cwd().parent # if on jupyter notebook - SCRIPT_DIR = PACKAGE_PARENT - sys.path.append(str(SCRIPT_DIR) + "/Utils") - - import BEUtils - - - def Run(): - context = bpy.context - - # BEUtils.ClearScene() - bpy.ops.wm.read_homefile(use_empty=True) - # bpy.ops.wm.read_factory_settings(use_empty=True) - - be_proj_paths = BEUtils.BEProjectPaths() - - # Base Stuff - beBaseStuff_path = be_proj_paths.be_tmp_folder + "BEngineBaseFromEngine.json" - js_base_stuff = BEUtils.LoadJSON(beBaseStuff_path) - - be_base_stuff = BEUtils.BEBaseStuff(js_base_stuff) - - process_gn_obj, geom_mod, node_tree = BEUtils.LoadNodesTreeFromJSON(context, be_proj_paths, be_base_stuff) - - if node_tree: - - if be_base_stuff.run_type == "UpdateNodes": - GetBlenderInputs(be_base_stuff, node_tree) - else: - RunNodes(context, be_proj_paths, node_tree, process_gn_obj, geom_mod, be_base_stuff) - - return True - - else: - print("Nodes were not Loaded! Please check Paths and NodeTree Name!") - return False - - - def GetBlenderInputs(be_base_stuff: BEUtils.BEBaseStuff, node_tree): - # ORIGINAL STUFF - # Get GN Data - js_output_data = {} - - if node_tree.bl_idname == BEUtils.TYPE_SV: - gn_inputs_data = BEUtils.GetSVInputsData(node_tree) - else: - gn_inputs_data = BEUtils.GetGNInputsData(node_tree) - - js_output_data['Inputs'] = gn_inputs_data - - # If No JSON File - gn_js_path = be_base_stuff.blendfolder + be_base_stuff.blendfile_name + '_' + be_base_stuff.node_sys_name + '.json' - BEUtils.SaveJSON(gn_js_path, js_output_data) - - - def RunNodes(context, be_proj_paths, node_tree, process_gn_obj, geom_mod, be_base_stuff): - # GET BLENDER INPUTS - beInputs_path = be_proj_paths.be_tmp_folder + "BEngineInputs.json" - js_input_data = BEUtils.LoadJSON(beInputs_path) - - if js_input_data: - # If GN - if node_tree.bl_idname == BEUtils.TYPE_GN and process_gn_obj: - # Set Transform - process_gn_obj.location = js_input_data["Pos"] - BEUtils.SetRotationFromJSON(process_gn_obj, js_input_data["Rot"], be_base_stuff.be_type) - process_gn_obj.scale = js_input_data["Scale"] - - # Setup inputs - BEUtils.SetupInputsFromJSON(context, node_tree, geom_mod, - js_input_data, be_proj_paths, be_base_stuff.be_type) - # geom_mod.show_viewport = True - - # Set the GN Object Active and Selected - bpy.ops.object.select_all(action='DESELECT') - process_gn_obj.select_set(True) - context.view_layer.objects.active = process_gn_obj - - process_gn_obj.data.update() - - # Save Node Outputs - BEUtils.SaveBlenderOutputs(context, [process_gn_obj], be_proj_paths, be_base_stuff.be_type, True) - - # If SV - elif node_tree.bl_idname == BEUtils.TYPE_SV: - # node_tree = node_tree.evaluated_get(context.evaluated_depsgraph_get()) - - # Setup inputs - BEUtils.SetupInputsFromJSON(context, node_tree, None, - js_input_data, be_proj_paths, be_base_stuff.be_type) - - # Update All Nodes - # node_tree.update() - context.view_layer.update() - node_tree.process_ani(True, False) - - # Save Node Outputs - BEUtils.SaveBlenderOutputs(context, BEUtils.GetSVOutputObjects(node_tree), - be_proj_paths, be_base_stuff.be_type, False) - - else: - print("Nodes were not Loaded! Please check Paths and NodeTree Name!") - return False - else: - print("JSON Object is Empty: " + beInputs_path) - return False - - return True - - - # start = time.time() - - is_done = Run() - - # end = time.time() - # print(end - start) - - if is_done: - print("!PYTHON DONE!") - else: - print("!PYTHON ERROR!") - -except Exception as e: - print(traceback.format_exc()) diff --git a/BEngine-Py/BEVersion.py b/BEngine-Py/BEVersion.py deleted file mode 100644 index c4380c3..0000000 --- a/BEngine-Py/BEVersion.py +++ /dev/null @@ -1 +0,0 @@ -VERSION = 0.6 \ No newline at end of file diff --git a/BEngine-Py/bengine/BENetworking.py b/BEngine-Py/bengine/BENetworking.py new file mode 100644 index 0000000..e28aa2f --- /dev/null +++ b/BEngine-Py/bengine/BENetworking.py @@ -0,0 +1,134 @@ +import socket +#import threading +import bpy +import select + +from .Utils import BEUtils +from . import BESettings, BERunNodes + +import json +import pickle + +# MAX_BYTES = 4096 +# host = socket.gethostname() # get name of local machine +# host = '10.0.0.5' +# port = 55555 + +SERVER_SOCKET = None + + +def handle_client(client_socket, addr): + print('handle client') + + # global SERVER_SOCKET + + be_paths = BESettings.START_PARAMS + + while True: + if select.select([client_socket], [], [], 0.01)[0]: + bpy.ops.wm.read_homefile(use_empty=True) + + context = bpy.context + + window = context.window_manager.windows[0] + with context.temp_override(window=window): + + # Receive + js_base_stuff_bytes = RecvAll(client_socket, be_paths.buffer_size) + # js_base_stuff = js_base_stuff_bytes.decode() + js_base_stuff = json.loads(js_base_stuff_bytes) + + be_base_stuff = BEUtils.BaseStuff(js_base_stuff["BaseValues"]) + + process_gn_obj, geom_mod, node_tree = BEUtils.LoadNodesTreeFromJSON(context, be_paths, be_base_stuff) + + if be_base_stuff.run_type == BESettings.RunNodesType.RunNodes: + js_inputs = js_base_stuff["BEngineInputs"] + js_output_data = BERunNodes.RunNodes(context, be_paths, js_inputs, node_tree, + process_gn_obj, geom_mod, be_base_stuff) + + # Send + if js_output_data: + # SendAll(client_socket, str.encode(json.dumps(js_output_data))) + client_socket.sendall(str.encode(json.dumps(js_output_data))) + + elif be_base_stuff.run_type == BESettings.RunNodesType.UpdateNodes: + BERunNodes.SaveBlenderInputs(be_base_stuff, node_tree) + + + AddBackServer(0.01) + + client_socket.close() + + print("Closing connection with %s" % str(addr)) + # client_socket.close() + # client_sockets.remove(client_socket) + + break + + +def background_server(): + if select.select([SERVER_SOCKET], [], [], 0.01)[0]: + client_socket, addr = SERVER_SOCKET.accept() + print("Got a connection from %s" % str(addr)) +# client_sockets.append(client_socket) + +# client_thread = threading.Thread(target=handle_client, args=(client_socket, addr)) +# client_thread.start() + handle_client(client_socket, addr) + +# bpy.app.timers.register(1.0) + + return 0.1 + + +def RunServer(): + global SERVER_SOCKET + + SERVER_SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + SERVER_SOCKET.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + SERVER_SOCKET.bind((BESettings.START_PARAMS.host, BESettings.START_PARAMS.port)) + SERVER_SOCKET.listen(1) + + #client_sockets = [] + + AddBackServer(0) + + print('Server has started!') + + +def AddBackServer(first_interval_int): + if not bpy.app.timers.is_registered(background_server): + bpy.app.timers.register(background_server, first_interval = first_interval_int) + # bpy.app.timers.register(background_server) + + +# def SendAll(sock, msg): +# # totalsent = 0 + +# # while totalsent < len(msg): +# # sent = sock.send(msg[totalsent:]) + +# # if sent == 0: +# # raise RuntimeError("socket connection broken") +# # totalsent = totalsent + sent +# sock.sendall(msg) + + +def RecvAll(sock, buff_size): + data = b'' + + while True: + part = sock.recv(buff_size) + + if not part: + break + + data += part + + if len(part) < buff_size: + # either 0 or end of data + break + + return data \ No newline at end of file diff --git a/BEngine-Py/bengine/BERunNodes.py b/BEngine-Py/bengine/BERunNodes.py new file mode 100644 index 0000000..8af0a29 --- /dev/null +++ b/BEngine-Py/bengine/BERunNodes.py @@ -0,0 +1,129 @@ +import bpy + +# from unicodedata import decimal + +# try: +# from .Utils import BEUtils +# except: +# # Load BEUtils +# PACKAGE_PARENT = pathlib.Path(__file__).parent +# #PACKAGE_PARENT = pathlib.Path.cwd().parent # if on jupyter notebook +# SCRIPT_DIR = PACKAGE_PARENT +# sys.path.append(str(SCRIPT_DIR) + "/Utils") + +# import BEUtils + +from .Utils import BEUtils +from . import BENetworking, BESettings + + +def Run(): + context = bpy.context + + # BEUtils.ClearScene() + bpy.ops.wm.read_homefile(use_empty=True) + # bpy.ops.wm.read_factory_settings(use_empty=True) + + be_paths = BESettings.START_PARAMS + + # Base Stuff + beBaseStuff_path = be_paths.be_tmp_folder + "BEngineBaseFromEngine.json" + js_base_stuff = BEUtils.LoadJSON(beBaseStuff_path) + + be_base_stuff = BEUtils.BaseStuff(js_base_stuff) + + process_gn_obj, geom_mod, node_tree = BEUtils.LoadNodesTreeFromJSON(context, be_paths, be_base_stuff) + + if node_tree: + + if be_base_stuff.run_type == BESettings.RunNodesType.UpdateNodes: + SaveBlenderInputs(be_base_stuff, node_tree) + else: + # GET BLENDER INPUTS + beInputs_path = be_paths.be_tmp_folder + "BEngineInputs.json" + js_input_data = BEUtils.LoadJSON(beInputs_path) + + js_output_data = RunNodes(context, be_paths, js_input_data, node_tree, + process_gn_obj, geom_mod, be_base_stuff) + + # Save Outputs + if js_output_data: + gn_js_path = be_paths.be_tmp_folder + BESettings.OUTPUT_JSON_NAME + BEUtils.SaveJSON(gn_js_path, js_output_data) + + print("!PYTHON DONE!") # PYTHON IS DONE + + return True + + else: + print("Nodes were not Loaded! Please check Paths and NodeTree Name!") + return False + + +def SaveBlenderInputs(be_base_stuff: BEUtils.BaseStuff, node_tree): + # ORIGINAL STUFF + # Get GN Data + js_output_data = {} + + if node_tree.bl_idname == BESettings.TYPE_SV: + gn_inputs_data = BEUtils.GetSVInputsData(node_tree) + else: + gn_inputs_data = BEUtils.GetGNInputsData(node_tree) + + js_output_data['Inputs'] = gn_inputs_data + + # If No JSON File + gn_js_path = be_base_stuff.blendfolder + be_base_stuff.blendfile_name + '_' + be_base_stuff.node_sys_name + '.json' + BEUtils.SaveJSON(gn_js_path, js_output_data) + + +def RunNodes(context, be_proj_paths, js_input_data, node_tree, process_gn_obj, geom_mod, be_base_stuff): + if js_input_data: + # If GN + if node_tree.bl_idname == BESettings.TYPE_GN and process_gn_obj: + # Set Transform + process_gn_obj.location = js_input_data["Pos"] + BEUtils.SetRotationFromJSON(process_gn_obj, js_input_data["Rot"], be_base_stuff.be_type) + process_gn_obj.scale = js_input_data["Scale"] + + # Setup inputs + BEUtils.SetupInputsFromJSON(context, node_tree, geom_mod, + js_input_data, be_proj_paths, be_base_stuff.be_type) + # geom_mod.show_viewport = True + + # Set the GN Object Active and Selected + bpy.ops.object.select_all(action='DESELECT') + process_gn_obj.select_set(True) + context.view_layer.objects.active = process_gn_obj + + process_gn_obj.data.update() + + js_output_data = BEUtils.SaveBlenderOutputs(context, [process_gn_obj], be_proj_paths, be_base_stuff.be_type, True) + return js_output_data + + # If SV + elif node_tree.bl_idname == BESettings.TYPE_SV: + # node_tree = node_tree.evaluated_get(context.evaluated_depsgraph_get()) + + # Setup inputs + BEUtils.SetupInputsFromJSON(context, node_tree, None, + js_input_data, be_proj_paths, be_base_stuff.be_type) + + # Update All Nodes + # node_tree.update() + context.view_layer.update() + node_tree.process_ani(True, False) + + + js_output_data = BEUtils.SaveBlenderOutputs(context, BEUtils.GetSVOutputObjects(node_tree), + be_proj_paths, be_base_stuff.be_type, False) + return js_output_data + + else: + print("Nodes were not Loaded! Please check Paths and NodeTree Name!") + return None + else: + print("JSON Inputs Object is Empty: ") + return None + + return None diff --git a/BEngine-Py/bengine/BESettings.py b/BEngine-Py/bengine/BESettings.py new file mode 100644 index 0000000..eebe84c --- /dev/null +++ b/BEngine-Py/bengine/BESettings.py @@ -0,0 +1,130 @@ +from enum import Enum +import sys +import os + + +UV_NAMES = {"uv_map", "uv_map2", "uv_map3", "uv_map4", "uv_map5", + "uv_map6", "uv_map7", "uv_map8", "uv_map9", "uv_map10"} + +BENGINE_INSTANCE = "be_instance" +BENGINE_MATERIAL = "be_material" +BENGINE_COLOR = "be_color" +BENGINE_NORMAL = "be_normal" + +TYPE_GN = "GeometryNodeTree" +TYPE_SV = "SverchCustomTreeType" +TYPE_SV_SCRIPT = "SvScriptNodeLite" + +OUTPUT_JSON_NAME = "BlenderOutputs.json" + + +class RunBlenderType(Enum): + RunBlender = 1 + RunNetwork = 2 + + +class RunNodesType(Enum): + UpdateNodes = 1 + RunNodes = 2 + + +class SVConstants: + SV_INPUT_BOOL = "BEBoolean.py" + SV_INPUT_COLL = "BECollection.py" + SV_INPUT_COLOR = "BEColor.py" + SV_INPUT_FLOAT = "BEFloat.py" + SV_INPUT_INT = "BEInteger.py" + SV_INPUT_OBJ = "BEObject.py" + SV_INPUT_STR = "BEString.py" + SV_INPUT_VEC = "BEVector.py" + + SV_Inputs = (SV_INPUT_BOOL, SV_INPUT_COLL, SV_INPUT_COLOR, + SV_INPUT_FLOAT, SV_INPUT_INT, SV_INPUT_OBJ, + SV_INPUT_STR, SV_INPUT_VEC) + + SV_OUTPUT_OBJ = "BEObjectsOutput.py" + + +class StartParams: + + def __init__(self): + self.be_tmp_folder = None + self.project_path = None + self.project_path_2 = None + + self.run_blender_Type = None + self.host = None + self.port = None + self.buffer_size = None + + args = sys.argv + + for arg in args: + if arg.startswith('BE_TMP_FOLDER='): + self.be_tmp_folder = arg.replace('BE_TMP_FOLDER=', '') + elif arg.startswith('PROJECT_PATH='): + self.project_path = arg.replace('PROJECT_PATH=', '') + elif arg.startswith('PROJECT_PATH_2='): + self.project_path_2 = arg.replace('PROJECT_PATH_2=', '') + + # Networking + elif arg.startswith('RunBlenderType='): + self.run_blender_type = arg.replace('RunBlenderType=', '') + + if RunBlenderType.RunBlender._name_ == self.run_blender_type: + self.run_blender_type = RunBlenderType.RunBlender + else: + self.run_blender_type = RunBlenderType.RunNetwork + + elif arg.startswith('Host='): + self.host = arg.replace('Host=', '') + elif arg.startswith('Port='): + self.port = int(arg.replace('Port=', '')) + elif arg.startswith('MaxPackageBytes='): + self.buffer_size = int(arg.replace('MaxPackageBytes=', '')) + + +START_PARAMS = StartParams() + + +class BaseStuff: + + def __init__(self, be_paths: dict): + self.section = "/NodeTree/" + self.blendfile = "" + self.blendfolder = "" + self.node_sys_name = "" + + self.blendfile = be_paths["BlendFile"] + + self.blendfolder = be_paths["BlendFolder"] + if not self.blendfolder.endswith('/'): + self.blendfolder = self.blendfolder + "/" + + self.node_sys_name = be_paths["NodeSysName"] + + # blend file name + self.blendfile_basename = os.path.basename(self.blendfile) + self.blendfile_name = os.path.splitext(self.blendfile_basename)[0] + + # Load GN Paths + self.filepath = self.blendfile + self.section + self.node_sys_name + self.directory = self.blendfile + self.section + self.filename = self.node_sys_name + + self.be_type = be_paths["BEngineType"] + + # Run Nodes Type + self.run_type = be_paths["RunNodesType"] + if RunNodesType.RunNodes._name_ == self.run_type: + self.run_type = RunNodesType.RunNodes + else: + self.run_type = RunNodesType.UpdateNodes + + # # Networking + # self.RunBlenderType = be_paths["RunBlenderType"] + # self.Host = be_paths["Host"] + # self.Port = be_paths["Port"] + # self.MaxPackageBytes = be_paths["MaxPackageBytes"] + + diff --git a/BEngine-Py/Utils/BEUtils.py b/BEngine-Py/bengine/Utils/BEUtils.py similarity index 85% rename from BEngine-Py/Utils/BEUtils.py rename to BEngine-Py/bengine/Utils/BEUtils.py index 4737c71..6620fa3 100644 --- a/BEngine-Py/Utils/BEUtils.py +++ b/BEngine-Py/bengine/Utils/BEUtils.py @@ -1,119 +1,18 @@ import bpy -import sys -import os - import json from json.decoder import JSONDecodeError import numpy as np -from math import degrees +# from math import degrees +import mathutils from mathutils import Color, Vector, Euler import bmesh -import mathutils - - -UV_NAMES = {"uv_map", "uv_map2", "uv_map3", "uv_map4", "uv_map5", - "uv_map6", "uv_map7", "uv_map8", "uv_map9", "uv_map10"} - -BENGINE_INSTANCE = "be_instance" -BENGINE_MATERIAL = "be_material" -BENGINE_COLOR = "be_color" -BENGINE_NORMAL = "be_normal" - -TYPE_GN = "GeometryNodeTree" -TYPE_SV = "SverchCustomTreeType" -TYPE_SV_SCRIPT = "SvScriptNodeLite" - -OUTPUT_JSON_NAME = "BlenderOutputs.json" - - -class SVConstants: - SV_INPUT_BOOL = "BEBoolean.py" - SV_INPUT_COLL = "BECollection.py" - SV_INPUT_COLOR = "BEColor.py" - SV_INPUT_FLOAT = "BEFloat.py" - SV_INPUT_INT = "BEInteger.py" - SV_INPUT_OBJ = "BEObject.py" - SV_INPUT_STR = "BEString.py" - SV_INPUT_VEC = "BEVector.py" - - SV_Inputs = (SV_INPUT_BOOL, SV_INPUT_COLL, SV_INPUT_COLOR, - SV_INPUT_FLOAT, SV_INPUT_INT, SV_INPUT_OBJ, - SV_INPUT_STR, SV_INPUT_VEC) - - SV_OUTPUT_OBJ = "BEObjectsOutput.py" - - -class BEProjectPaths: - - def __init__(self): - self.be_tmp_folder = None - self.project_path = None - self.project_path_2 = None - - self.run_blender_Type = None - self.host = None - self.port = None - self.max_package_bytes = None - - args = sys.argv - - for arg in args: - if arg.startswith('BE_TMP_FOLDER='): - self.be_tmp_folder = arg.replace('BE_TMP_FOLDER=', '') - elif arg.startswith('PROJECT_PATH='): - self.project_path = arg.replace('PROJECT_PATH=', '') - elif arg.startswith('PROJECT_PATH_2='): - self.project_path_2 = arg.replace('PROJECT_PATH_2=', '') - - # # Networking - elif arg.startswith('RunBlenderType='): - self.run_blender_Type = arg.replace('RunBlenderType=', '') - elif arg.startswith('Host='): - self.host = arg.replace('Host=', '') - elif arg.startswith('Port='): - self.port = int(arg.replace('Port=', '')) - elif arg.startswith('MaxPackageBytes='): - self.max_package_bytes = int(arg.replace('MaxPackageBytes=', '')) - - -class BEBaseStuff: - - def __init__(self, be_paths: dict): - self.section = "/NodeTree/" - self.blendfile = "" - self.blendfolder = "" - self.node_sys_name = "" - - self.blendfile = be_paths["BlendFile"] - - self.blendfolder = be_paths["BlendFolder"] - if not self.blendfolder.endswith('/'): - self.blendfolder = self.blendfolder + "/" - - self.node_sys_name = be_paths["NodeSysName"] - - # blend file name - self.blendfile_basename = os.path.basename(self.blendfile) - self.blendfile_name = os.path.splitext(self.blendfile_basename)[0] - - # Load GN Paths - self.filepath = self.blendfile + self.section + self.node_sys_name - self.directory = self.blendfile + self.section - self.filename = self.node_sys_name - - self.be_type = be_paths["BEngineType"] - - self.run_type = be_paths["RunNodesType"] - # # Networking - # self.RunBlenderType = be_paths["RunBlenderType"] - # self.Host = be_paths["Host"] - # self.Port = be_paths["Port"] - # self.MaxPackageBytes = be_paths["MaxPackageBytes"] +from .. import BESettings +from ..BESettings import BaseStuff, StartParams def LoadJSON(bengineInputs_path: str): @@ -218,8 +117,8 @@ def GetSVOutputObjects(node_tree): sv_out_objs = [] for node in node_tree.nodes: - if node.bl_idname == TYPE_SV_SCRIPT: - if SVConstants.SV_OUTPUT_OBJ in node.script_name: + if node.bl_idname == BESettings.TYPE_SV_SCRIPT: + if BESettings.SVConstants.SV_OUTPUT_OBJ in node.script_name: sv_out_nodes.append(node) sv_out_nodes.sort(key=lambda x: x.location.y) @@ -239,28 +138,28 @@ def GetSVInputNodes(node_tree): sv_input_nodes = [] for node in node_tree.nodes: - if node.bl_idname == TYPE_SV_SCRIPT: - for in_out_name in SVConstants.SV_Inputs: + if node.bl_idname == BESettings.TYPE_SV_SCRIPT: + for in_out_name in BESettings.SVConstants.SV_Inputs: if in_out_name in node.script_name: the_name = '' # Set Type match in_out_name: - case SVConstants.SV_INPUT_BOOL: + case BESettings.SVConstants.SV_INPUT_BOOL: the_name = 'BOOLEAN' - case SVConstants.SV_INPUT_COLL: + case BESettings.SVConstants.SV_INPUT_COLL: the_name = 'COLLECTION' - case SVConstants.SV_INPUT_COLOR: + case BESettings.SVConstants.SV_INPUT_COLOR: the_name = 'RGBA' - case SVConstants.SV_INPUT_FLOAT: + case BESettings.SVConstants.SV_INPUT_FLOAT: the_name = 'VALUE' - case SVConstants.SV_INPUT_INT: + case BESettings.SVConstants.SV_INPUT_INT: the_name = 'INT' - case SVConstants.SV_INPUT_OBJ: + case BESettings.SVConstants.SV_INPUT_OBJ: the_name = 'OBJECT' - case SVConstants.SV_INPUT_STR: + case BESettings.SVConstants.SV_INPUT_STR: the_name = 'STRING' - case SVConstants.SV_INPUT_VEC: + case BESettings.SVConstants.SV_INPUT_VEC: the_name = 'VECTOR' sv_input_nodes.append((the_name, node)) @@ -310,7 +209,7 @@ def GetGNInputsData(node_group): return gn_inputs_data -def LoadNodesTreeFromJSON(context, be_paths: BEProjectPaths, be_base_stuff: BEBaseStuff): +def LoadNodesTreeFromJSON(context, be_paths: StartParams, be_base_stuff: BaseStuff): bpy.ops.wm.link(filepath=be_base_stuff.filepath, filename=be_base_stuff.filename, directory=be_base_stuff.directory, link=False) @@ -322,7 +221,7 @@ def LoadNodesTreeFromJSON(context, be_paths: BEProjectPaths, be_base_stuff: BEBa geom_mod = None # If GN NodeTree - if node_tree.bl_idname == TYPE_GN: + if node_tree.bl_idname == BESettings.TYPE_GN: # Create New Object process_mesh = bpy.data.meshes.new('emptyMesh') process_gn_obj = bpy.data.objects.new("BEngineProcess", process_mesh) @@ -347,11 +246,11 @@ def LoadNodesTreeFromJSON(context, be_paths: BEProjectPaths, be_base_stuff: BEBa def SetupInputsFromJSON(context, node_tree, GN_mod, js_input_data, - be_paths: BEProjectPaths, engine_type: str): + be_paths: StartParams, engine_type: str): js_inputs = js_input_data["BEngineInputs"] - is_GN = node_tree.bl_idname == TYPE_GN + is_GN = node_tree.bl_idname == BESettings.TYPE_GN coll_idx = 0 @@ -820,17 +719,17 @@ def RecordObjectOutputToJSON(inst_dict, the_object, is_instance: bool): # Setup bengine_instance Value and Mesh if obj_type == "MESH": - if BENGINE_INSTANCE in the_mesh.attributes.keys(): - if BENGINE_INSTANCE not in cur_inst_data.keys(): - if len(the_mesh.attributes[BENGINE_INSTANCE].data) > 0: - cur_inst_data["Bengine_Instance"] = the_mesh.attributes[BENGINE_INSTANCE].data[0].value + if BESettings.BENGINE_INSTANCE in the_mesh.attributes.keys(): + if BESettings.BENGINE_INSTANCE not in cur_inst_data.keys(): + if len(the_mesh.attributes[BESettings.BENGINE_INSTANCE].data) > 0: + cur_inst_data["Bengine_Instance"] = the_mesh.attributes[BESettings.BENGINE_INSTANCE].data[0].value else: if "Mesh" not in cur_inst_data.keys(): # GET INSTANCE MESH cur_inst_data["Mesh"] = MeshToJSONData(true_obj) -def SaveBlenderOutputs(context, process_objs: list, be_paths: BEProjectPaths, engine_type: str, is_GN: bool): +def SaveBlenderOutputs(context, process_objs: list, be_paths: StartParams, engine_type: str, is_GN: bool): depsgraph = context.evaluated_depsgraph_get() @@ -880,9 +779,10 @@ def SaveBlenderOutputs(context, process_objs: list, be_paths: BEProjectPaths, en if inst_dict: js_output_data["Instances"] = list(inst_dict.values()) - gn_js_path = be_paths.be_tmp_folder + OUTPUT_JSON_NAME + # gn_js_path = be_paths.be_tmp_folder + BESettings.OUTPUT_JSON_NAME + # SaveJSON(gn_js_path, js_output_data) - SaveJSON(gn_js_path, js_output_data) + return js_output_data def MeshToJSONData(process_obj): @@ -924,13 +824,13 @@ def MeshToJSONData(process_obj): # mesh_dict["Loops"] = np_tris_loops.tolist() # Get Normals - if BENGINE_NORMAL in process_obj.data.attributes.keys(): - if process_obj.data.attributes[BENGINE_NORMAL].domain == 'CORNER': - np_normals = np.zeros(len(process_obj.data.attributes[BENGINE_NORMAL].data) * 3, dtype=np.float32) - process_obj.data.attributes[BENGINE_NORMAL].data.foreach_get('vector', np_normals) - np_normals.shape = (len(process_obj.data.attributes[BENGINE_NORMAL].data), 3) + if BESettings.BENGINE_NORMAL in process_obj.data.attributes.keys(): + if process_obj.data.attributes[BESettings.BENGINE_NORMAL].domain == 'CORNER': + np_normals = np.zeros(len(process_obj.data.attributes[BESettings.BENGINE_NORMAL].data) * 3, dtype=np.float32) + process_obj.data.attributes[BESettings.BENGINE_NORMAL].data.foreach_get('vector', np_normals) + np_normals.shape = (len(process_obj.data.attributes[BESettings.BENGINE_NORMAL].data), 3) else: - print("Attribute " + BENGINE_NORMAL + " must have FACECORNER domain!!!") + print("Attribute " + BESettings.BENGINE_NORMAL + " must have FACECORNER domain!!!") np_normals = GetMeshNormalsNumpy(process_obj) else: np_normals = GetMeshNormalsNumpy(process_obj) @@ -943,7 +843,7 @@ def MeshToJSONData(process_obj): # Get Attributes for attrib_name in process_obj.data.attributes.keys(): - if attrib_name in UV_NAMES: + if attrib_name in BESettings.UV_NAMES: if process_obj.data.attributes[attrib_name].domain == 'CORNER': if (len(process_obj.data.attributes[attrib_name].data) > 0): @@ -967,7 +867,7 @@ def MeshToJSONData(process_obj): else: print("Attribute " + attrib_name + " must have FACECORNER domain!!!") - elif attrib_name == BENGINE_COLOR: + elif attrib_name == BESettings.BENGINE_COLOR: if process_obj.data.attributes[attrib_name].domain == 'CORNER': # col_attrib = [tuple(uv_attr.color) for uv_attr in process_obj_ev.data.attributes[attrib_name].data] @@ -981,7 +881,7 @@ def MeshToJSONData(process_obj): print("Attribute " + attrib_name + " must have FACECORNER domain!!!") # Setup bengine_material Value - elif attrib_name == BENGINE_MATERIAL: + elif attrib_name == BESettings.BENGINE_MATERIAL: if process_obj.data.attributes[attrib_name].domain == 'FACE': np_mat_attrib = np.zeros(len(process_obj.data.attributes[attrib_name].data), dtype=np.uint8) process_obj.data.attributes[attrib_name].data.foreach_get('value', np_mat_attrib) diff --git a/BEngine-Py/bengine/Version.py b/BEngine-Py/bengine/Version.py new file mode 100644 index 0000000..3781d0e --- /dev/null +++ b/BEngine-Py/bengine/Version.py @@ -0,0 +1 @@ +VERSION = 0.7 \ No newline at end of file diff --git a/BEngine-Py/bengine/__init__.py b/BEngine-Py/bengine/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/BEngine-Py/main.py b/BEngine-Py/main.py new file mode 100644 index 0000000..43fec4a --- /dev/null +++ b/BEngine-Py/main.py @@ -0,0 +1,29 @@ +import pathlib +import sys +import traceback + +# Add the lib to path +PACKAGE_PARENT = pathlib.Path(__file__).parent +#PACKAGE_PARENT = pathlib.Path.cwd().parent # if on jupyter notebook +SCRIPT_DIR = PACKAGE_PARENT + +sys.path.append(str(SCRIPT_DIR)) + + +from bengine import BERunNodes, BENetworking, BESettings + + +if BESettings.START_PARAMS.run_blender_type == BESettings.RunBlenderType.RunNetwork: + BENetworking.RunServer() +else: + try: + # start = time.time() + + BERunNodes.Run() + + # end = time.time() + # print(end - start) + + except Exception as e: + print("!PYTHON EXCEPTION!") + print(traceback.format_exc())