예제 #1
0
파일: client.py 프로젝트: ElonGame/mixer
 def send_animation_buffer(self, obj_name, animation_data, channel_name, channel_index=-1):
     if not animation_data:
         return
     action = animation_data.action
     if not action:
         buffer = (
             common.encode_string(obj_name)
             + common.encode_string(channel_name)
             + common.encode_int(channel_index)
             + common.int_to_bytes(0, 4)  # send empty buffer
         )
         self.add_command(common.Command(MessageType.ANIMATION, buffer, 0))
         return
     for fcurve in action.fcurves:
         if fcurve.data_path == channel_name:
             if channel_index == -1 or fcurve.array_index == channel_index:
                 key_count = len(fcurve.keyframe_points)
                 times = []
                 values = []
                 for keyframe in fcurve.keyframe_points:
                     times.append(int(keyframe.co[0]))
                     values.append(keyframe.co[1])
                 buffer = (
                     common.encode_string(obj_name)
                     + common.encode_string(channel_name)
                     + common.encode_int(channel_index)
                     + common.int_to_bytes(key_count, 4)
                     + struct.pack(f"{len(times)}i", *times)
                     + struct.pack(f"{len(values)}f", *values)
                 )
                 self.add_command(common.Command(MessageType.ANIMATION, buffer, 0))
                 return
예제 #2
0
 def get_rename_buffer(self, old_name, new_name):
     encoded_old_name = old_name.encode()
     encoded_new_name = new_name.encode()
     buffer = (common.int_to_bytes(len(encoded_old_name), 4) +
               encoded_old_name +
               common.int_to_bytes(len(encoded_new_name), 4) +
               encoded_new_name)
     return buffer
예제 #3
0
def send_grease_pencil_stroke(stroke):
    buffer = common.encode_int(stroke.material_index)
    buffer += common.encode_int(stroke.line_width)

    points = list()

    for point in stroke.points:
        points.extend(point.co)
        points.append(point.pressure)
        points.append(point.strength)

    binary_points_buffer = common.int_to_bytes(len(stroke.points), 4) + struct.pack(f"{len(points)}f", *points)
    buffer += binary_points_buffer
    return buffer
예제 #4
0
 def get_delete_buffer(self, name):
     encoded_name = name.encode()
     buffer = common.int_to_bytes(len(encoded_name), 4) + encoded_name
     return buffer
예제 #5
0
파일: mesh.py 프로젝트: tscrypter/mixer
def encode_baked_mesh(obj):
    """
    Bake an object as a triangle mesh and encode it.
    """
    stats_timer = share_data.current_stats_timer

    # Bake modifiers
    depsgraph = bpy.context.evaluated_depsgraph_get()
    obj = obj.evaluated_get(depsgraph)

    stats_timer.checkpoint("eval_depsgraph")

    # Triangulate mesh (before calculating normals)
    mesh = obj.data if obj.type == "MESH" else obj.to_mesh()
    if mesh is None:
        # This happens for empty curves
        return bytes()

    bm = bmesh.new()
    bm.from_mesh(mesh)
    bmesh.ops.triangulate(bm, faces=bm.faces)
    bm.to_mesh(mesh)
    bm.free()

    stats_timer.checkpoint("triangulate_mesh")

    # Calculate normals, necessary if auto-smooth option enabled
    mesh.calc_normals()
    mesh.calc_normals_split()
    # calc_loop_triangles resets normals so... don't use it

    stats_timer.checkpoint("calc_normals")

    # get active uv layer
    uvlayer = mesh.uv_layers.active

    vertices = []
    normals = []
    uvs = []
    indices = []
    material_indices = []  # array of triangle index, material index

    current_material_index = -1
    current_face_index = 0
    logger.debug("Writing %d polygons", len(mesh.polygons))
    for f in mesh.polygons:
        for loop_id in f.loop_indices:
            index = mesh.loops[loop_id].vertex_index
            vertices.extend(mesh.vertices[index].co)
            normals.extend(mesh.loops[loop_id].normal)
            if uvlayer:
                uvs.extend([x for x in uvlayer.data[loop_id].uv])
            indices.append(loop_id)

        if f.material_index != current_material_index:
            current_material_index = f.material_index
            material_indices.append(current_face_index)
            material_indices.append(current_material_index)
        current_face_index = current_face_index + 1

    if obj.type != "MESH":
        obj.to_mesh_clear()

    stats_timer.checkpoint("make_buffers")

    # Vericex count + binary vertices buffer
    size = len(vertices) // 3
    binary_vertices_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(vertices)}f", *vertices)

    stats_timer.checkpoint("write_verts")

    # Normals count + binary normals buffer
    size = len(normals) // 3
    binary_normals_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(normals)}f", *normals)

    stats_timer.checkpoint("write_normals")

    # UVs count + binary uvs buffer
    size = len(uvs) // 2
    binary_uvs_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(uvs)}f", *uvs)

    stats_timer.checkpoint("write_uvs")

    # material indices + binary material indices buffer
    size = len(material_indices) // 2
    binary_material_indices_buffer = common.int_to_bytes(
        size, 4) + struct.pack(f"{len(material_indices)}I", *material_indices)

    stats_timer.checkpoint("write_material_indices")

    # triangle indices count + binary triangle indices buffer
    size = len(indices) // 3
    binary_indices_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(indices)}I", *indices)

    stats_timer.checkpoint("write_tri_idx_buff")

    return (binary_vertices_buffer + binary_normals_buffer +
            binary_uvs_buffer + binary_material_indices_buffer +
            binary_indices_buffer)
예제 #6
0
def encode_baked_mesh(obj):
    """
    Bake an object as a triangle mesh and encode it.
    """
    stats_timer = share_data.current_stats_timer

    # Bake modifiers
    depsgraph = bpy.context.evaluated_depsgraph_get()
    obj = obj.evaluated_get(depsgraph)

    stats_timer.checkpoint("eval_depsgraph")

    # Triangulate mesh (before calculating normals)
    mesh = obj.data if obj.type == "MESH" else obj.to_mesh()
    if mesh is None:
        # This happens for empty curves
        return bytes()

    original_bm = None
    if obj.type == "MESH":
        # Mesh is restored later only if is has not been generated from a curve or something else
        original_bm = bmesh.new()
        original_bm.from_mesh(mesh)

    bm = bmesh.new()
    bm.from_mesh(mesh)
    bmesh.ops.triangulate(bm, faces=bm.faces)
    bm.to_mesh(mesh)
    bm.free()

    stats_timer.checkpoint("triangulate_mesh")

    # Calculate normals, necessary if auto-smooth option enabled
    mesh.calc_normals()
    mesh.calc_normals_split()
    # calc_loop_triangles resets normals so... don't use it

    stats_timer.checkpoint("calc_normals")

    # get active uv layer
    uvlayer = mesh.uv_layers.active

    vertices = array.array("d", (0.0, )) * len(mesh.vertices) * 3
    mesh.vertices.foreach_get("co", vertices)

    normals = array.array("d", (0.0, )) * len(mesh.loops) * 3
    mesh.loops.foreach_get("normal", normals)

    if uvlayer:
        uvs = array.array("d", (0.0, )) * len(mesh.loops) * 2
        mesh.uv_layers[0].data.foreach_get("uv", uvs)
    else:
        uvs = []

    indices = array.array("i", (0, )) * len(mesh.loops)
    mesh.loops.foreach_get("vertex_index", indices)

    if len(obj.material_slots) <= 1:
        material_indices = []
    else:
        material_indices = array.array("i", (0, )) * len(mesh.polygons)
        mesh.polygons.foreach_get("material_index", material_indices)

    if obj.type != "MESH":
        obj.to_mesh_clear()
    else:
        original_bm.to_mesh(mesh)
        original_bm.free()

    stats_timer.checkpoint("make_buffers")

    # Vericex count + binary vertices buffer
    size = len(vertices) // 3
    binary_vertices_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(vertices)}f", *vertices)

    stats_timer.checkpoint("write_verts")

    # Normals count + binary normals buffer
    size = len(normals) // 3
    binary_normals_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(normals)}f", *normals)

    stats_timer.checkpoint("write_normals")

    # UVs count + binary uvs buffer
    size = len(uvs) // 2
    binary_uvs_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(uvs)}f", *uvs)

    stats_timer.checkpoint("write_uvs")

    # material indices + binary material indices buffer
    size = len(material_indices)
    binary_material_indices_buffer = common.int_to_bytes(
        size, 4) + struct.pack(f"{len(material_indices)}I", *material_indices)

    stats_timer.checkpoint("write_material_indices")

    # triangle indices count + binary triangle indices buffer
    size = len(indices) // 3
    binary_indices_buffer = common.int_to_bytes(size, 4) + struct.pack(
        f"{len(indices)}I", *indices)

    stats_timer.checkpoint("write_tri_idx_buff")

    return (binary_vertices_buffer + binary_normals_buffer +
            binary_uvs_buffer + binary_material_indices_buffer +
            binary_indices_buffer)