OSDN Git Service

fix
[meshio/pymeshio.git] / pymeshio / vpd.py
1 # coding: utf-8
2 ###############################################################################
3 # VPD
4 ###############################################################################
5 class LineLoader(object):
6     """
7     行指向の汎用ローダ
8     """
9     __slots__=['path', 'io', 'end']
10     def __str__(self):
11         return "<%s current:%d, end:%d>" % (
12                 self.__class__, self.getPos(), self.getEnd())
13
14     def getPos(self):
15         return self.io.tell()
16
17     def getEnd(self):
18         return self.end
19
20     def readline(self):
21         return (self.io.readline()).strip()
22
23     def isEnd(self):
24         return self.io.tell()>=self.end
25
26     def load(self, path, io, end):
27         self.path=path
28         self.io=io
29         self.end=end
30         return self.process()
31
32     def process(self):
33         """
34         dummy. read to end.
35         """
36         while not self.isEnd():
37             self.io.readline()
38         return True
39
40
41 class VPDLoader(LineLoader):
42     __slots__=['pose']
43     def __init__(self):
44         super(VPDLoader, self).__init__()
45         self.pose=[]
46
47     def __str__(self):
48         return "<VPD poses:%d>" % len(self.pose)
49
50     def process(self):
51         if self.readline()!="Vocaloid Pose Data file":
52             return
53
54         RE_OPEN=re.compile('^(\w+){(.*)')
55         RE_OSM=re.compile('^\w+\.osm;')
56         RE_COUNT=re.compile('^(\d+);')
57
58         bone_count=-1
59         while not self.isEnd():
60             line=self.readline()
61             if line=='':
62                 continue
63             m=RE_OPEN.match(line)
64             if m:
65                 if not self.parseBone(m.group(2)):
66                     raise Exception("invalid bone")
67                 continue
68
69             m=RE_OSM.match(line)
70             if m:
71                 continue
72
73             m=RE_COUNT.match(line)
74             if m:
75                 bone_count=int(m.group(1))
76                 continue
77
78         return len(self.pose)==bone_count
79
80     def parseBone(self, name):
81         bone=MotionData(name)
82         self.pose.append(bone)
83         bone.pos=Vector3(*[float(token) for token in self.readline().split(';')[0].split(',')])
84         bone.q=Quaternion(*[float(token) for token in self.readline().split(';')[0].split(',')])
85         return self.readline()=="}"
86
87