33
44
55class BvhNode :
6-
76 def __init__ (self , value = [], parent = None ):
87 self .value = value
98 self .children = []
@@ -43,13 +42,21 @@ def name(self):
4342
4443
4544class Bvh :
46-
4745 def __init__ (self , data ):
4846 self .data = data
4947 self .root = BvhNode ()
5048 self .frames = []
5149 self .tokenize ()
5250
51+ @classmethod
52+ def from_file (cls , filename ):
53+ with open (filename ) as f :
54+ mocap = cls (f .read ())
55+ return mocap
56+
57+ def __len__ (self ):
58+ return round (self .nframes * 1000 / self .frame_rate )
59+
5360 def tokenize (self ):
5461 first_round = []
5562 accumulator = ''
@@ -79,10 +86,13 @@ def tokenize(self):
7986
8087 def __getitem__ (self , x ):
8188 if type (x ) is int :
82- frames = self .frames [[round (x / (1000 * self .frame_time ))]]
89+ frames = self .frames [[round (x / (1000 * self .frame_rate ))]]
8390 elif type (x ) is slice :
84- start_frame = round (x .start / (1000 * self .frame_time ))
85- end_frame = round (x .stop / (1000 * self .frame_time ))
91+ start_time = x .start if x .start is not None else 0
92+ end_time = x .stop if x .stop is not None else - 1
93+
94+ start_frame = round (start_time / (1000 * self .frame_rate ))
95+ end_frame = round (end_time / (1000 * self .frame_rate ))
8696 frames = self .frames [start_frame :end_frame :x .step ]
8797 else :
8898 raise KeyError
@@ -219,13 +229,10 @@ def joint_parent_index(self, name):
219229
220230 @property
221231 def nframes (self ):
222- try :
223- return int (next (self .root .filter ('Frames:' )).value [1 ])
224- except StopIteration :
225- raise LookupError ('number of frames not found' )
232+ return len (self .frames )
226233
227234 @property
228- def frame_time (self ):
235+ def frame_rate (self ):
229236 try :
230237 return float (next (self .root .filter ('Frame' )).value [2 ])
231238 except StopIteration :
@@ -240,7 +247,7 @@ def raw_data(self):
240247
241248 data += "MOTION\n "
242249 data += f"Frames:\t { self .nframes } \n "
243- data += f"Frame Time:\t { self .frame_time } \n "
250+ data += f"Frame Time:\t { self .frame_rate } \n "
244251
245252 for frame in self .frames :
246253 data += "\t " .join (frame )+ "\n "
@@ -262,7 +269,7 @@ def write_node(self, node, data, depth):
262269 depth -= 1
263270 return data , depth
264271
265- def save (self , out_f ):
272+ def export (self , out_f ):
266273 with open (out_f , 'w' ) as f :
267274 f .write (self .raw_data )
268275
0 commit comments