Skip to content

Commit

Permalink
Merge pull request #16 from sean1832/dev
Browse files Browse the repository at this point in the history
Optimize Mesh Serialization with Numpy
  • Loading branch information
sean1832 authored Sep 28, 2024
2 parents 4d8a158 + ff68728 commit db642d7
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 13 deletions.
24 changes: 17 additions & 7 deletions portal/data_struct/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from .material import Material
from .p_types import PGeoType

import numpy as np
from mathutils import Vector


class Mesh:
def __init__(self):
Expand Down Expand Up @@ -230,20 +233,27 @@ def from_obj(obj):
# Get the world transformation matrix
world_matrix = obj.matrix_world

# Apply the transformation matrix to each vertex to get the world coordinates
mesh.vertices = [
tuple(world_matrix @ v.co) for v in obj.data.vertices
] # Convert Vector to world coordinates tuple
# Use bulk access to retrieve vertex data and apply transformation
vertex_data = np.empty(len(obj.data.vertices) * 3)
obj.data.vertices.foreach_get('co', vertex_data)
vertex_data = vertex_data.reshape(-1, 3)

# Transform vertices by matrix_world
mesh.vertices = [(world_matrix @ Vector(v)).to_tuple() for v in vertex_data]

# Faces remain the same as they are relative indices of the vertices
# Bulk access for faces
mesh.faces = [tuple(f.vertices) for f in obj.data.polygons]

# Handle vertex colors
if obj.data.vertex_colors:
mesh.vertex_colors = [tuple(col.color) for col in obj.data.vertex_colors.active.data]
color_data = np.empty(len(obj.data.vertex_colors.active.data) * 4)
obj.data.vertex_colors.active.data.foreach_get('color', color_data)
mesh.vertex_colors = list(color_data.reshape(-1, 4))

# Handle UVs
if obj.data.uv_layers:
mesh.uvs = [tuple(uv.uv) for uv in obj.data.uv_layers.active.data]
uv_data = np.empty(len(obj.data.uv_layers.active.data) * 2)
obj.data.uv_layers.active.data.foreach_get('uv', uv_data)
mesh.uvs = list(uv_data.reshape(-1, 2))

return mesh
2 changes: 1 addition & 1 deletion portal/ui/operators/modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def cancel(self, context):

def _handle_send_event(self, context, connection, server_manager):
try:
message_to_send = construct_packet_dict(connection.dict_items, connection.percision)
message_to_send = construct_packet_dict(connection.dict_items, connection.precision)
if message_to_send:
server_manager.data_queue.put(message_to_send)
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion portal/ui/panels/server_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def draw(self, context):
elif connection.event_types == "TIMER":
sub_box.prop(connection, "event_timer", text="Interval (sec)")

sub_box.prop(connection, "percision", text="Percision")
sub_box.prop(connection, "precision", text="Precision")

sub_box.separator()
sub_box.operator(
Expand Down
4 changes: 2 additions & 2 deletions portal/ui/properties/connection_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class PortalConnection(bpy.types.PropertyGroup):
# TODO: Implement custom event
],
)
percision: bpy.props.FloatProperty(
name="Update Percision",
precision: bpy.props.FloatProperty(
name="Update Precision",
description="minimum numerical change to trigger an update",
default=0.01,
)
Expand Down
4 changes: 2 additions & 2 deletions portal/ui/utils/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def is_connection_duplicated(connections, name_to_check, uuid_to_ignore=None):
return False


def construct_packet_dict(data_items, update_percision) -> str:
def construct_packet_dict(data_items, update_precision) -> str:
"""Helper function to construct a dictionary from a collection of dictionary items"""
payload = Payload()
meta = {}
Expand All @@ -34,7 +34,7 @@ def construct_packet_dict(data_items, update_percision) -> str:
scene_obj = item.value_scene_object
if scene_obj.type == "MESH":
payload.add_items(
Mesh.from_obj(scene_obj).to_dict(is_float=True, precision=update_percision)
Mesh.from_obj(scene_obj).to_dict(is_float=True, precision=update_precision)
)
elif scene_obj.type == "CAMERA":
raise NotImplementedError("Camera object type is not supported yet")
Expand Down

0 comments on commit db642d7

Please sign in to comment.