Skip to content

convert x,y,z format from double to float #71

Closed

Description

@SyZbidi

Hi,

I'v been trying to use this library to convert my files' x, y, z, nx, ny, nz from double to float but I think i'm missing something.

  1. I tried to first make a copy of my input then use instance mutability but saving went wrong
  2. the second thing I was aiming for is iterating through those fields' columns and convert each to float but then I didn't know how to write the new data.
    I hope you can help me with this 🙏

To clarify my questions after you read my script below:

  1. Is it possible to achieve the conversion?
  2. If so, How can I iterate through numpy.array to do it following 1st method?
  3. How can I save it following the second method?
  4. Which approach you would say is cleaner/faster/easier?

thank you in advance!

import numpy as np
from plyfile import PlyData, PlyElement, PlyProperty


input_mesh = PlyData.read('default.ply')

##################################### mutability approach #######################################
# copy input file
converted_mesh = input_mesh
vx = converted_mesh['vertex']
vx.properties = ()
vx.data.dtype.names = ['x', 'y', 'z', 'nx', 'ny', 'nz', 'red', 'green', 'blue']
# elements of vertex have to be float instead of double
vx.properties = (PlyProperty('x', 'float'), PlyProperty('y', 'float'), PlyProperty('z', 'float'), 
                 PlyProperty('nx', 'float'), PlyProperty('ny', 'float'), PlyProperty('nz', 'float'), 
                 PlyProperty('red', 'uchar'), PlyProperty('green', 'uchar'), PlyProperty('blue', 'uchar'))

xcol = input_mesh['vertex']['x']
ycol = input_mesh['vertex']['y']
zcol = input_mesh['vertex']['z']
nxcol = input_mesh['vertex']['nx']
nycol = input_mesh['vertex']['ny']
nzcol = input_mesh['vertex']['nz']

# convert double to float and append to new file
for i in range(len(xcol)):
    x = np.format_float_positional(np.float32(xcol[i]), precision=6)
    y = np.format_float_positional(np.float32(ycol[i]), precision=6)
    z = np.format_float_positional(np.float32(zcol[i]), precision=6)
    nx = np.format_float_positional(np.float32(nxcol[i]), precision=6)
    ny = np.format_float_positional(np.float32(nycol[i]), precision=6)
    nz = np.format_float_positional(np.float32(nzcol[i]), precision=6)
    converted_mesh['vertex']['x'][i] = x
    converted_mesh['vertex']['y'][i] = y
    converted_mesh['vertex']['z'][i] = z
    converted_mesh['vertex']['nx'][i] = nx
    converted_mesh['vertex']['ny'][i] = ny
    converted_mesh['vertex']['nz'][i] = nz
# RGB elements are kept the same
converted_mesh['vertex']['red'] = input_mesh['vertex']['red']
converted_mesh['vertex']['green'] = input_mesh['vertex']['green']
converted_mesh['vertex']['blue'] = input_mesh['vertex']['blue']

## I don't know how to save it this way 
## and the other method below of PlyElement.describe() ends up in a TypeError: only numpy arrays are supported
# el = PlyElement.describe(converted_mesh['vertex'], 'vertex')
# el = PlyElement.describe(converted_mesh['face'], 'face')
# PlyData([el], text=True).write('converted_file.ply')

################################## make changes directly to the input file ######################################
for i in range(len(xcol)):
    xcol[i] = np.format_float_positional(np.float32(xcol[i]), precision=6)
    ycol[i] = np.format_float_positional(np.float32(ycol[i]), precision=6)
    zcol[i] = np.format_float_positional(np.float32(zcol[i]), precision=6)
    nxcol[i] = np.format_float_positional(np.float32(nxcol[i]), precision=6)
    nycol[i] = np.format_float_positional(np.float32(nycol[i]), precision=6)
    nzcol[i] = np.format_float_positional(np.float32(nzcol[i]), precision=6)
## I don't know where to go from here, how do I save it?

Activity

  1. self-assigned this
    on Jul 29, 2023
  2. dranjan commented on Jul 29, 2023

    @dranjan
    Owner

    Maybe this is oversimplified for your use case, but here's an example of what I think you want. In this one, I'm converting "x", "y", and "z" from float to double.

    from plyfile import PlyData
    
    data = PlyData.read('examples/tet.ply')
    
    new_types = {
        'x': 'double',
        'y': 'double',
        'z': 'double',
    }
    
    for prop in data['vertex'].properties:
        if prop.name in new_types:
            prop.val_dtype = new_types[prop.name]
    
    data.write('test.ply')
    
    data = PlyData.read('test.ply')
    print(data['vertex'].data)
    print(data['vertex'].data.dtype)

    It should be enough simply to change the types in the PlyProperty metadata, which will force the data to be cast when writing. If that works for you, it's probably the simplest method.

  3. removed their assignment
    on Jul 29, 2023
  4. Repository owner locked and limited conversation to collaborators on Jul 29, 2023
  5. converted this issue into a discussion #72 on Jul 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions