def ply_binary(elements, file_obj):
    """
    Load the data from a binary PLY file into the elements data structure.

    Parameters
    ------------
    elements: OrderedDict object, populated from the file header.
              object will be modified to add data by this function.

    file_obj: open file object, with current position at the start
              of the data section (past the header)
    """

    def populate_listsize(file_obj, elements):
        """
        Given a set of elements populated from the header if there are any
        list properties seek in the file the length of the list.

        Note that if you have a list where each instance is different length
        (if for example you mixed triangles and quads) this won't work at all
        """
        p_start = file_obj.tell()
        p_current = file_obj.tell()
        for element_key, element in elements.items():
            props = element['properties']
            prior_data = ''
            for k, dtype in props.items():
                if '$LIST' in dtype:
                    # every list field has two data types:
                    # the list length (single value), and the list data (multiple)
                    # here we are only reading the single value for list length
                    field_dtype = np.dtype(dtype.split(',')[0])
                    if len(prior_data) == 0:
                        offset = 0
                    else:
                        offset = np.dtype(prior_data).itemsize
                    file_obj.seek(p_current + offset)
                    size = np.frombuffer(file_obj.read(field_dtype.itemsize),
                                         dtype=field_dtype)[0]
                    props[k] = props[k].replace('$LIST', str(size))
                prior_data += props[k] + ','
            itemsize = np.dtype(', '.join(props.values())).itemsize
            p_current += element['length'] * itemsize
        file_obj.seek(p_start)

    def populate_data(file_obj, elements):
        """
        Given the data type and field information from the header,
        read the data and add it to a 'data' field in the element.
        """
        for key in elements.keys():
            items = list(elements[key]['properties'].items())
            dtype = np.dtype(items)
            data = file_obj.read(elements[key]['length'] * dtype.itemsize)
            elements[key]['data'] = np.frombuffer(data,
                                                  dtype=dtype)
        return elements

    def elements_size(elements):
        """
        Given an elements data structure populated from the header,
        calculate how long the file should be if it is intact.
        """
        size = 0
        for element in elements.values():
            dtype = np.dtype(','.join(element['properties'].values()))
            size += element['length'] * dtype.itemsize
        return size

    # some elements are passed where the list dimensions
    # are not included in the header, so this function goes
    # into the meat of the file and grabs the list dimensions
    # before we to the main data read as a single operation
    populate_listsize(file_obj, elements)

    # how many bytes are left in the file
    size_file = util.distance_to_end(file_obj)
    # how many bytes should the data structure described by
    # the header take up
    size_elements = elements_size(elements)

    # if the number of bytes is not the same the file is probably corrupt
    if size_file != size_elements:
        raise ValueError('File is unexpected length!')

    # with everything populated and a reasonable confidence the file
    # is intact, read the data fields described by the header
    populate_data(file_obj, elements)
def ply_binary ( elements , file_obj ) : def populate_listsize ( file_obj , elements ) : p_start = file_obj . tell ( ) p_current = file_obj . tell ( ) for element_key , element in elements . items ( ) : props = element [ 'properties' ] prior_data = '' for k , dtype in props . items ( ) : if '$LIST' in dtype : field_dtype = np . dtype ( dtype . split ( ',' ) [ 0 ] ) if len ( prior_data ) == 0 : offset = 0 else : offset = np . dtype ( prior_data ) . itemsize file_obj . seek ( p_current + offset ) size = np . frombuffer ( file_obj . read ( field_dtype . itemsize ) , dtype = field_dtype ) [ 0 ] props [ k ] = props [ k ] . replace ( '$LIST' , str ( size ) ) prior_data += props [ k ] + ',' itemsize = np . dtype ( ', ' . join ( props . values ( ) ) ) . itemsize p_current += element [ 'length' ] * itemsize file_obj . seek ( p_start ) def populate_data ( file_obj , elements ) : for key in elements . keys ( ) : items = list ( elements [ key ] [ 'properties' ] . items ( ) ) dtype = np . dtype ( items ) data = file_obj . read ( elements [ key ] [ 'length' ] * dtype . itemsize ) elements [ key ] [ 'data' ] = np . frombuffer ( data , dtype = dtype ) return elements def elements_size ( elements ) : size = 0 for element in elements . values ( ) : dtype = np . dtype ( ',' . join ( element [ 'properties' ] . values ( ) ) ) size += element [ 'length' ] * dtype . itemsize return size populate_listsize ( file_obj , elements ) size_file = util . distance_to_end ( file_obj ) size_elements = elements_size ( elements ) if size_file != size_elements : raise ValueError ( 'File is unexpected length!' ) populate_data ( file_obj , elements )
Load the data from a binary PLY file into the elements data structure.

    Parameters
    ------------
    elements: OrderedDict object, populated from the file header.
              object will be modified to add data by this function.

    file_obj: open file object, with current position at the start
              of the data section (past the header)