OSDN Git Service

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