Package: cpf3d
cpf3dA python library to read and edit3cpffiles. Requires
python 3.8.FeaturesRead 3cpf files into easily usable dataCreate new points and framesApply basic position, scale, and rotation transformations to all points in a 3cpf fileWrite 3cpf data into 3cpf filesInstallationThe package can be installed withpip.pipinstallcpf3dUsageReading filesThecpf3d.loadfunction can be used to load a 3cpf files as acpf3d.PointFramesobject, which has points and frames.importcpf3d# Load a 3cpf filepf=cpf3d.load('miku_example.3cpf')# From here, we can access any necessary dataprint('# of Points:',len(pf.points))print('# of Frames:',len(pf.frames))# Point colorsprint('\nColors of First 5 Points:')forpointinpf.points[:5]:print(point.color)# Position of specific point at specific frameprint('\nPositions of Point 0 Throughout First 5 Frames:')foriinrange(5):print(pf.get_position(0,i))Output:# of Points: 600
# of Frames: 60

Colors of First 5 Points:
(112, 112, 112)
(112, 112, 112)
(0, 0, 0)
(112, 112, 112)
(112, 112, 112)

Positions of Point 0 Throughout First 5 Frames:
[-0.01653824  0.05377164  1.10009   ]
[-0.01205087  0.05788074  1.0995283 ]
[-0.00502312  0.06201064  1.1008564 ]
[0.00529542 0.06594937 1.1022888 ]
[0.01859665 0.06944766 1.1035271 ]If your use-case uses a different coordinate order (XYZ vs. YXZ for example), you can load a 3cpf with any coordinate order of your choice.importcpf3d# Load a 3cpf file, with dimensions in the order of xzy, rather than the default xyzpf=cpf3d.load('miku_example.3cpf','xzy')Editing and Creating 3cpf FilesYou can edit instances ofcpf3d.PointFramesand save them as 3cpf files.importcpf3d# Editing an existing 3cpf filepf=nbtlib.load('miku_example.3cpf')# Rotate entire animation 90 degrees along the Z-axis# Scale to half size across all dimensions# And move 1 along the X-axispf.apply_rotation(0,0,90)\.apply_scale(.5,.5,.5)\.apply_offset(1,0,0)# Save the now-transformed point frames into a new filepf.save('miku_example_transformed.3cpf')Or write a 3cpf file from scratch.importcpf3dfromcpf3dimportPointFrames,Point,Frame# Creating a 3cpf file from scratchcustom_pf=PointFrames()point_r=Point(255,0,0)# Red pointpoint_g=Point(0,255,0)# Green pointcustom_pf.add_point(point_r)custom_pf.add_point(point_g)# First frame: Red point at 1,1,1. Green point at 2,2,2frame_1=Frame([[1.0,1.0,1.0],[2.0,2.0,2.0]])# Second frame: Red point at 2,2,2. Green point at 4,4,4frame_2=Frame([[2.0,2.0,2.0],[4.0,4.0,4.0]])custom_pf.add_frame(frame_1)custom_pf.add_frame(frame_2)# Scale it all by ten timescustom_pf.apply_scale(10,10,10)# Export to a 3cpf filecustom_pf.save('my_pointframes.3cpf')Adding Points or Frames to Existing 3cpf DataThere are a variety of restrictions related to adding points or frames to existing 3cpf animations.Firstly,you cannot add framesbeforeadding any points.pf=PointFrames()# Will cause an error, as there are no points to attach this positional data toframe=Frame([[1.0,2.0,3.0]])Secondly,when adding new frames, you must have one positional entry for each point.# Assume this 3cpf file contains 2 pointspf=cpf3d.load('2points.3cpf')# Will cause an error, as we are adding a frame with 1 position, but there are 2 pointsframe=Frame([[1.0,2.0,3.0]])pf.add_frame(frame)# Similarly, this would also errorframe=Frame([[1.0,2.0,3.0],[1.0,2.0,3.0],[1.0,2.0,3.0]])pf.add_frame(frame)Lastly,when adding new points, if you already have frames in your 3cpf file, you must provide positions for your new point at each frame.# Assume this 3cpf file contains 2 points and 2 framespf=cpf3d.load('2points2frames.3cpf')# Will cause an error, as there are already frames in this 3cpf animationpoint=Point(255,255,255)pf.add_point(point)We would instead need to do something like this:pf=cpf3d.load('2points2frames.3cpf')point=Point(255,255,255)# This point moves from 1,1,1 to 2,2,2 through frames 0 and 1positions=[[1.0,1.0,1.0],[2.0,2.0,2.0]]pf.add_frame(point,positions)# This works fineThis is necessary due to the nature of 3cpf files, in that each point must have corresponding positional data within each frame chunk.ContributingContributions are welcome. This project is packaged with python's built-insetuptools.To install this package locally for development, you can clone or download this repository and navigate to it in your terminal.You should now be able to install it locally, including development dependencies.pipinstall-e.[dev]You can run the tests by simply executing pytest from the top directory.pytest