|
@@ -2,11 +2,10 @@ import bpy
|
|
import bpy_types
|
|
import bpy_types
|
|
import numpy as np
|
|
import numpy as np
|
|
from mathutils import Matrix
|
|
from mathutils import Matrix
|
|
-from utils import get_prop_collection
|
|
|
|
|
|
+import utils
|
|
|
|
|
|
import json
|
|
import json
|
|
import datetime
|
|
import datetime
|
|
-from utils import get_geomnodes_obj
|
|
|
|
from lib_loader import MapWriterSize, MapWriter
|
|
from lib_loader import MapWriterSize, MapWriter
|
|
import logging as _logging
|
|
import logging as _logging
|
|
_LOGGER = _logging.getLogger('GeomNodes.External.Scripts.mesh_data_builder')
|
|
_LOGGER = _logging.getLogger('GeomNodes.External.Scripts.mesh_data_builder')
|
|
@@ -16,10 +15,10 @@ def get_mesh_colors_data(mesh):
|
|
has_vertex_indexed_colors = False
|
|
has_vertex_indexed_colors = False
|
|
|
|
|
|
if len(mesh.vertex_colors) > 0:
|
|
if len(mesh.vertex_colors) > 0:
|
|
- colors = get_prop_collection(mesh.vertex_colors[0].data, 'color', 4, np.float32)
|
|
|
|
|
|
+ colors = utils.get_prop_collection(mesh.vertex_colors[0].data, 'color', 4, np.float32)
|
|
elif mesh.attributes.get('Col') and len(mesh.attributes.get('Col').data) > 0:
|
|
elif mesh.attributes.get('Col') and len(mesh.attributes.get('Col').data) > 0:
|
|
attribute_colors = mesh.attributes.get('Col')
|
|
attribute_colors = mesh.attributes.get('Col')
|
|
- colors = get_prop_collection(attribute_colors.data, 'color', 4, np.float32)
|
|
|
|
|
|
+ colors = utils.get_prop_collection(attribute_colors.data, 'color', 4, np.float32)
|
|
has_vertex_indexed_colors = attribute_colors.domain == 'POINT'
|
|
has_vertex_indexed_colors = attribute_colors.domain == 'POINT'
|
|
else:
|
|
else:
|
|
colors = np.zeros(len(mesh.loops)*4, dtype=np.float32)
|
|
colors = np.zeros(len(mesh.loops)*4, dtype=np.float32)
|
|
@@ -37,15 +36,15 @@ def get_mesh_uv_data(mesh):
|
|
uv_size = len(attribute_uvmap.data[0].vector)
|
|
uv_size = len(attribute_uvmap.data[0].vector)
|
|
convert_uvs = uv_size == 3
|
|
convert_uvs = uv_size == 3
|
|
has_vertex_indexed_uvs = attribute_uvmap.domain == 'POINT'
|
|
has_vertex_indexed_uvs = attribute_uvmap.domain == 'POINT'
|
|
- uvs = get_prop_collection(attribute_uvmap.data, 'vector', uv_size, np.float32)
|
|
|
|
|
|
+ uvs = utils.get_prop_collection(attribute_uvmap.data, 'vector', uv_size, np.float32)
|
|
elif mesh.attributes.get('uv_map') and len(mesh.attributes.get('uv_map').data) > 0:
|
|
elif mesh.attributes.get('uv_map') and len(mesh.attributes.get('uv_map').data) > 0:
|
|
attribute_uvmap = mesh.attributes.get('uv_map')
|
|
attribute_uvmap = mesh.attributes.get('uv_map')
|
|
uv_size = len(attribute_uvmap.data[0].vector)
|
|
uv_size = len(attribute_uvmap.data[0].vector)
|
|
convert_uvs = uv_size == 3
|
|
convert_uvs = uv_size == 3
|
|
has_vertex_indexed_uvs = attribute_uvmap.domain == 'POINT'
|
|
has_vertex_indexed_uvs = attribute_uvmap.domain == 'POINT'
|
|
- uvs = get_prop_collection(attribute_uvmap.data, 'vector', uv_size, np.float32)
|
|
|
|
|
|
+ uvs = utils.get_prop_collection(attribute_uvmap.data, 'vector', uv_size, np.float32)
|
|
elif len(mesh.uv_layers) > 0:
|
|
elif len(mesh.uv_layers) > 0:
|
|
- uvs = get_prop_collection(mesh.uv_layers[0].data, 'uv', 2, np.float32)
|
|
|
|
|
|
+ uvs = utils.get_prop_collection(mesh.uv_layers[0].data, 'uv', 2, np.float32)
|
|
else:
|
|
else:
|
|
uvs = np.zeros(len(mesh.loops)*2, dtype=np.float32)
|
|
uvs = np.zeros(len(mesh.loops)*2, dtype=np.float32)
|
|
|
|
|
|
@@ -69,7 +68,7 @@ def get_mesh_materials(mesh):
|
|
return names
|
|
return names
|
|
|
|
|
|
def get_materials_data(mesh):
|
|
def get_materials_data(mesh):
|
|
- material_indices = get_prop_collection(mesh.loop_triangles, 'material_index', 1, np.int32)
|
|
|
|
|
|
+ material_indices = utils.get_prop_collection(mesh.loop_triangles, 'material_index', 1, np.int32)
|
|
material_names = np.frombuffer(bytes(json.dumps({'Materials' : get_mesh_materials(mesh)}), "UTF-8"), np.byte)
|
|
material_names = np.frombuffer(bytes(json.dumps({'Materials' : get_mesh_materials(mesh)}), "UTF-8"), np.byte)
|
|
|
|
|
|
return material_indices, material_names
|
|
return material_indices, material_names
|
|
@@ -78,11 +77,11 @@ def get_mesh_data(mesh):
|
|
mesh.calc_loop_triangles()
|
|
mesh.calc_loop_triangles()
|
|
mesh.calc_normals_split()
|
|
mesh.calc_normals_split()
|
|
|
|
|
|
- vertices = get_prop_collection(mesh.vertices, 'co', 3, np.float32)
|
|
|
|
- normals = get_prop_collection(mesh.loop_triangles, 'split_normals', 3*3, np.float32)
|
|
|
|
- indices = get_prop_collection(mesh.loop_triangles, 'vertices', 3, np.int32)
|
|
|
|
- triangle_loops = get_prop_collection(mesh.loop_triangles, 'loops', 3, np.int32)
|
|
|
|
- loops = get_prop_collection(mesh.loops, 'vertex_index', 1, np.int32)
|
|
|
|
|
|
+ vertices = utils.get_prop_collection(mesh.vertices, 'co', 3, np.float32)
|
|
|
|
+ normals = utils.get_prop_collection(mesh.loop_triangles, 'split_normals', 3*3, np.float32)
|
|
|
|
+ indices = utils.get_prop_collection(mesh.loop_triangles, 'vertices', 3, np.int32)
|
|
|
|
+ triangle_loops = utils.get_prop_collection(mesh.loop_triangles, 'loops', 3, np.int32)
|
|
|
|
+ loops = utils.get_prop_collection(mesh.loops, 'vertex_index', 1, np.int32)
|
|
|
|
|
|
mesh_hash = np.asarray(hash(mesh), np.int64)
|
|
mesh_hash = np.asarray(hash(mesh), np.int64)
|
|
|
|
|
|
@@ -100,76 +99,38 @@ def to_instance_arrays(mesh, local_matrix, world_matrix):
|
|
return mesh_hash, local_matrix, world_matrix
|
|
return mesh_hash, local_matrix, world_matrix
|
|
|
|
|
|
def build_mesh_data(obj_name):
|
|
def build_mesh_data(obj_name):
|
|
- geomnodes_obj = bpy.data.objects.get(obj_name)
|
|
|
|
- if geomnodes_obj == None:
|
|
|
|
- geomnodes_obj = get_geomnodes_obj()
|
|
|
|
-
|
|
|
|
- if geomnodes_obj.hide_get():
|
|
|
|
- geomnodes_obj.hide_set(False, view_layer=bpy.context.view_layer)
|
|
|
|
-
|
|
|
|
#_LOGGER.debug('Started building Mesh Data')
|
|
#_LOGGER.debug('Started building Mesh Data')
|
|
start = datetime.datetime.now()
|
|
start = datetime.datetime.now()
|
|
- depsgraph = bpy.context.evaluated_depsgraph_get()
|
|
|
|
- eval_geomnodes_data = geomnodes_obj.evaluated_get(depsgraph).data
|
|
|
|
-
|
|
|
|
- mesh_arr = []
|
|
|
|
- hash_arr = []
|
|
|
|
- instance_arr = []
|
|
|
|
- instance_matrix_loc_arr = []
|
|
|
|
- instance_matrix_world_arr = []
|
|
|
|
|
|
|
|
- scene_scale_len = bpy.context.scene.unit_settings.scale_length
|
|
|
|
-
|
|
|
|
- # Get number of meshes and instances
|
|
|
|
- if geomnodes_obj.type == 'MESH':
|
|
|
|
- hash_arr = [hash(geomnodes_obj)]
|
|
|
|
- mesh_arr = [eval_geomnodes_data]
|
|
|
|
- instance_arr = [eval_geomnodes_data]
|
|
|
|
- instance_matrix_loc_arr = [Matrix() * scene_scale_len]
|
|
|
|
- instance_matrix_world_arr = [geomnodes_obj.matrix_world.copy() * scene_scale_len]
|
|
|
|
-
|
|
|
|
- for instance in depsgraph.object_instances:
|
|
|
|
- if instance.instance_object and instance.parent and instance.parent.original == geomnodes_obj:
|
|
|
|
- if instance.object.type == 'MESH':
|
|
|
|
- # add only if the instance is not in the hash array
|
|
|
|
- if hash(instance.object.data) not in hash_arr:
|
|
|
|
- hash_arr += [hash(instance.object.data)]
|
|
|
|
- mesh_arr += [instance.object.data]
|
|
|
|
- # save the instance data and transforms
|
|
|
|
- if hash(instance.object.data) in hash_arr:
|
|
|
|
- instance_arr += [instance.object.data]
|
|
|
|
- local_matrix = instance.parent.matrix_world.inverted() @ instance.matrix_world
|
|
|
|
- instance_matrix_loc_arr += [local_matrix * scene_scale_len]
|
|
|
|
- instance_matrix_world_arr += [instance.matrix_world.copy() * scene_scale_len]
|
|
|
|
-
|
|
|
|
|
|
+ meshes, instances, local_matrices, world_matrices = utils.get_geomnodes_data_arrays(obj_name)
|
|
|
|
|
|
total_bytes = 0
|
|
total_bytes = 0
|
|
- total_bytes += MapWriterSize(np.int32).from_value(len(mesh_arr))
|
|
|
|
- total_bytes += MapWriterSize(np.int32).from_value(len(instance_arr))
|
|
|
|
|
|
+ total_bytes += MapWriterSize(np.int32).from_value(len(meshes))
|
|
|
|
+ total_bytes += MapWriterSize(np.int32).from_value(len(instances))
|
|
|
|
|
|
# Export meshes
|
|
# Export meshes
|
|
- for mesh in mesh_arr:
|
|
|
|
|
|
+ for mesh in meshes:
|
|
for array in get_mesh_data(mesh):
|
|
for array in get_mesh_data(mesh):
|
|
total_bytes += MapWriterSize().from_array(array)
|
|
total_bytes += MapWriterSize().from_array(array)
|
|
|
|
|
|
# Export instances
|
|
# Export instances
|
|
- for instance, local_matrix, world_matrix in zip(instance_arr, instance_matrix_loc_arr, instance_matrix_world_arr):
|
|
|
|
|
|
+ for instance, local_matrix, world_matrix in zip(instances, local_matrices, world_matrices):
|
|
for array in to_instance_arrays(instance, local_matrix, world_matrix):
|
|
for array in to_instance_arrays(instance, local_matrix, world_matrix):
|
|
total_bytes += MapWriterSize().from_array(array)
|
|
total_bytes += MapWriterSize().from_array(array)
|
|
|
|
|
|
from lib_loader import GNLibs
|
|
from lib_loader import GNLibs
|
|
map_id = GNLibs.RequestSHM(total_bytes)
|
|
map_id = GNLibs.RequestSHM(total_bytes)
|
|
#_LOGGER.debug('map_id = ' + str(map_id) + ' total_bytes = ' + str(total_bytes))
|
|
#_LOGGER.debug('map_id = ' + str(map_id) + ' total_bytes = ' + str(total_bytes))
|
|
- MapWriter(map_id, np.int32).from_value(len(mesh_arr))
|
|
|
|
- MapWriter(map_id, np.int32).from_value(len(instance_arr))
|
|
|
|
|
|
+ MapWriter(map_id, np.int32).from_value(len(meshes))
|
|
|
|
+ MapWriter(map_id, np.int32).from_value(len(instances))
|
|
|
|
|
|
# Export meshes
|
|
# Export meshes
|
|
- for mesh in mesh_arr:
|
|
|
|
|
|
+ for mesh in meshes:
|
|
for array in get_mesh_data(mesh):
|
|
for array in get_mesh_data(mesh):
|
|
MapWriter(map_id).from_array(array)
|
|
MapWriter(map_id).from_array(array)
|
|
|
|
|
|
# Export Instances
|
|
# Export Instances
|
|
- for instance, local_matrix, world_matrix in zip(instance_arr, instance_matrix_loc_arr, instance_matrix_world_arr):
|
|
|
|
|
|
+ for instance, local_matrix, world_matrix in zip(instances, local_matrices, world_matrices):
|
|
for array in to_instance_arrays(instance, local_matrix, world_matrix):
|
|
for array in to_instance_arrays(instance, local_matrix, world_matrix):
|
|
MapWriter(map_id).from_array(array)
|
|
MapWriter(map_id).from_array(array)
|
|
|
|
|