OSDN Git Service

implementing import_pmx...
[meshio/pymeshio.git] / pymeshio / pmx / __init__.py
1 #!/usr/bin/env python\r
2 # coding: utf-8\r
3 """\r
4 ========================\r
5 MikuMikuDance PMX format\r
6 ========================\r
7 \r
8 file format\r
9 ~~~~~~~~~~~\r
10 * PMDEditor's Lib/PMX仕様/PMX仕様.txt\r
11 \r
12 specs\r
13 ~~~~~\r
14 * textencoding: unicode\r
15 * coordinate: left handed y-up(DirectX)\r
16 * uv origin: \r
17 * face: only triangle\r
18 * backculling: \r
19 \r
20 """\r
21 __author__="ousttrue"\r
22 __license__="zlib"\r
23 __versioon__="1.0.0"\r
24 \r
25 \r
26 import io\r
27 import os\r
28 import struct\r
29 from .. import common\r
30 \r
31 \r
32 \r
33 class DifferenceException(Exception):\r
34     pass\r
35 \r
36 \r
37 class Diff(object):\r
38     def _diff(self, rhs, key):\r
39         l=getattr(self, key)\r
40         r=getattr(rhs, key)\r
41         if l!=r:\r
42             print(l)\r
43             print(r)\r
44             raise DifferenceException(key)\r
45 \r
46     def _diff_array(self, rhs, key):\r
47         la=getattr(self, key)\r
48         ra=getattr(rhs, key)\r
49         if len(la)!=len(ra):\r
50             raise DifferenceException("%s diffrence %d with %d" % (key, len(la), len(ra)))\r
51         for i, (l, r) in enumerate(zip(la, ra)):\r
52             if isinstance(l, Diff):\r
53                 try:\r
54                     l.diff(r)\r
55                 except DifferenceException as e:\r
56                     print(i)\r
57                     print(l)\r
58                     print(r)\r
59                     raise DifferenceException("{0}: {1}".format(key, e.message))\r
60             else:\r
61                 if l!=r:\r
62                     print(i)\r
63                     print(l)\r
64                     print(r)\r
65                     raise DifferenceException("{0}".format(key))\r
66 \r
67 \r
68 class Ik(Diff):\r
69     """ik info\r
70     """\r
71     __slots__=[\r
72             'target_index',\r
73             'loop',\r
74             'limit_radian',\r
75             'link',\r
76             ]\r
77     def __init__(self, target_index, loop, limit_radian, link=[]):\r
78         self.target_index=target_index\r
79         self.loop=loop\r
80         self.limit_radian=limit_radian\r
81         self.link=link\r
82 \r
83     def __eq__(self, rhs):\r
84         return (\r
85                 self.target_index==rhs.target_index\r
86                 and self.loop==rhs.loop\r
87                 and self.limit_radian==rhs.limit_radian\r
88                 and self.link==rhs.link\r
89                 )\r
90 \r
91     def diff(self, rhs):\r
92         self._diff(rhs, 'target_index')\r
93         self._diff(rhs, 'loop')\r
94         self._diff(rhs, 'limit_radian')\r
95         self._diff_array(rhs, 'link')\r
96 \r
97 \r
98 class IkLink(Diff):\r
99     """ik link info\r
100     """\r
101     __slots__=[\r
102             'bone_index',\r
103             'limit_angle',\r
104             'limit_min',\r
105             'limit_max',\r
106             ]\r
107     def __init__(self, bone_index, limit_angle, limit_min=common.Vector3(), limit_max=common.Vector3()):\r
108         self.bone_index=bone_index\r
109         self.limit_angle=limit_angle\r
110         self.limit_min=limit_min\r
111         self.limit_max=limit_max\r
112 \r
113     def __eq__(self, rhs):\r
114         return (\r
115                 self.bone_index==rhs.bone_index\r
116                 and self.limit_angle==rhs.limit_angle\r
117                 and self.limit_min==rhs.limit_min\r
118                 and self.limit_max==rhs.limit_max\r
119                 )\r
120 \r
121     def diff(self, rhs):\r
122         self._diff(rhs, 'bone_index')\r
123         self._diff(rhs, 'limit_angle')\r
124         self._diff(rhs, 'limit_min')\r
125         self._diff(rhs, 'limit_max')\r
126 \r
127 \r
128 class Bone(Diff):\r
129     """material\r
130 \r
131     Bone: see __init__\r
132     """\r
133     __slots__=[\r
134             'name',\r
135             'english_name',\r
136             'position',\r
137             'parent_index',\r
138             'layer',\r
139             'flag',\r
140 \r
141             'tail_position',\r
142             'tail_index',\r
143             'effect_index',\r
144             'effect_factor',\r
145             'fixed_axis',\r
146             'local_x_vector',\r
147             'local_z_vector',\r
148             'external_key',\r
149             'ik',\r
150             ]\r
151     def __init__(self,\r
152             name,\r
153             english_name,\r
154             position,\r
155             parent_index,\r
156             layer,\r
157             flag,\r
158             tail_position=common.Vector3(),\r
159             tail_index=-1,\r
160             effect_index=-1,\r
161             effect_factor=0.0,\r
162             fixed_axis=common.Vector3(),\r
163             local_x_vector=common.Vector3(),\r
164             local_z_vector=common.Vector3(),\r
165             external_key=-1,\r
166             ik=None\r
167             ):\r
168         self.name=name\r
169         self.english_name=english_name\r
170         self.position=position\r
171         self.parent_index=parent_index\r
172         self.layer=layer\r
173         self.flag=flag\r
174         self.tail_position=tail_position\r
175         self.tail_index=tail_index\r
176         self.effect_index=effect_index\r
177         self.effect_factor=effect_factor\r
178         self.fixed_axis=fixed_axis\r
179         self.local_x_vector=local_x_vector\r
180         self.local_z_vector=local_z_vector\r
181         self.external_key=external_key\r
182         self.ik=ik\r
183 \r
184     def __eq__(self, rhs):\r
185         return (\r
186                 self.name==rhs.name\r
187                 and self.english_name==rhs.english_name\r
188                 and self.position==rhs.position\r
189                 and self.parent_index==rhs.parent_index\r
190                 and self.layer==rhs.layer\r
191                 and self.flag==rhs.flag\r
192                 )\r
193 \r
194     def __ne__(self, rhs):\r
195         return not self.__eq__(rhs)\r
196 \r
197     def diff(self, rhs):\r
198         self._diff(rhs, 'name')\r
199         self._diff(rhs, 'english_name')\r
200         self._diff(rhs, 'position')\r
201         self._diff(rhs, 'parent_index')\r
202         #self._diff(rhs, 'layer')\r
203         self._diff(rhs, 'flag')\r
204         self._diff(rhs, 'tail_position')\r
205         self._diff(rhs, 'tail_index')\r
206         #self._diff(rhs, 'effect_index')\r
207         #self._diff(rhs, 'effect_factor')\r
208         #self._diff(rhs, 'fixed_axis')\r
209         self._diff(rhs, 'local_x_vector')\r
210         self._diff(rhs, 'local_z_vector')\r
211         self._diff(rhs, 'external_key')\r
212         if self.ik and rhs.ik:\r
213             self.ik.diff(rhs.ik)\r
214         else:\r
215             self._diff(rhs, 'ik')\r
216 \r
217     def getConnectionFlag(self):\r
218         return (self.flag & 0x0001)!=0\r
219 \r
220     def getVisibleFlag(self):\r
221         return (self.flag & 0x0008)!=0\r
222 \r
223     def getIkFlag(self):\r
224         return (self.flag & 0x0020)!=0\r
225 \r
226     def getRotationFlag(self):\r
227         return (self.flag & 0x0100)!=0\r
228 \r
229     def getTranslationFlag(self):\r
230         return (self.flag & 0x0200)!=0\r
231 \r
232     def getFixedAxisFlag(self):\r
233         return (self.flag & 0x0400)!=0\r
234 \r
235     def getLocalCoordinateFlag(self):\r
236         return (self.flag &  0x0800)!=0\r
237     \r
238     def getExternalParentDeformFlag(self):\r
239         return (self.flag &  0x2000)!=0\r
240 \r
241  \r
242 class Material(Diff):\r
243     """material\r
244 \r
245     Attributes: see __init__\r
246     """\r
247     __slots__=[\r
248             'name',\r
249             'english_name',\r
250             'diffuse_color',\r
251             'alpha',\r
252             'specular_color',\r
253             'specular_factor',\r
254             'ambient_color',\r
255             'flag',\r
256             'edge_color',\r
257             'edge_size',\r
258             'texture_index',\r
259             'sphere_texture_index',\r
260             'sphere_mode',\r
261             'toon_sharing_flag',\r
262             'toon_texture_index',\r
263             'comment',\r
264             'vertex_count',\r
265             ]\r
266     def __init__(self,\r
267             name,\r
268             english_name,\r
269             diffuse_color,\r
270             alpha,\r
271             specular_factor,\r
272             specular_color,\r
273             ambient_color,\r
274             flag,\r
275             edge_color,\r
276             edge_size,\r
277             texture_index,\r
278             sphere_texture_index,\r
279             sphere_mode,\r
280             toon_sharing_flag,\r
281             toon_texture_index=0,\r
282             comment=common.unicode(""),\r
283             vertex_count=0,\r
284             ):\r
285         self.name=name\r
286         self.english_name=english_name\r
287         self.diffuse_color=diffuse_color\r
288         self.alpha=alpha\r
289         self.specular_color=specular_color\r
290         self.specular_factor=specular_factor\r
291         self.ambient_color=ambient_color\r
292         self.flag=flag\r
293         self.edge_color=edge_color\r
294         self.edge_size=edge_size\r
295         self.texture_index=texture_index\r
296         self.sphere_texture_index=sphere_texture_index\r
297         self.sphere_mode=sphere_mode\r
298         self.toon_sharing_flag=toon_sharing_flag\r
299         self.toon_texture_index=toon_texture_index\r
300         self.comment=comment\r
301         self.vertex_count=vertex_count\r
302 \r
303     def __eq__(self, rhs):\r
304         return (\r
305                 self.name==rhs.name\r
306                 and self.english_name==rhs.english_name\r
307                 and self.diffuse_color==rhs.diffuse_color\r
308                 and self.alpha==rhs.alpha\r
309                 and self.specular_color==rhs.specular_color\r
310                 and self.specular_factor==rhs.specular_factor\r
311                 and self.ambient_color==rhs.ambient_color\r
312                 and self.flag==rhs.flag\r
313                 and self.edge_color==rhs.edge_color\r
314                 and self.edge_size==rhs.edge_size\r
315                 and self.texture_index==rhs.texture_index\r
316                 and self.sphere_texture_index==rhs.sphere_texture_index\r
317                 and self.sphere_mode==rhs.sphere_mode\r
318                 and self.toon_sharing_flag==rhs.toon_sharing_flag\r
319                 and self.toon_texture_index==rhs.toon_texture_index\r
320                 and self.comment==rhs.comment\r
321                 and self.vertex_count==rhs.vertex_count\r
322                 )\r
323 \r
324     def diff(self, rhs):\r
325         #self._diff(rhs, "name")\r
326         self._diff(rhs, "english_name")\r
327         self._diff(rhs, "diffuse_color")\r
328         self._diff(rhs, "alpha")\r
329         self._diff(rhs, "specular_color")\r
330         self._diff(rhs, "specular_factor")\r
331         self._diff(rhs, "ambient_color")\r
332         self._diff(rhs, "flag")\r
333         self._diff(rhs, "edge_color")\r
334         self._diff(rhs, "edge_size")\r
335         self._diff(rhs, "texture_index")\r
336         self._diff(rhs, "sphere_texture_index")\r
337         self._diff(rhs, "sphere_mode")\r
338         self._diff(rhs, "toon_sharing_flag")\r
339         self._diff(rhs, "toon_texture_index")\r
340         self._diff(rhs, "comment")\r
341         self._diff(rhs, "vertex_count")\r
342 \r
343     def __ne__(self, rhs):\r
344         return not self.__eq__(rhs)\r
345 \r
346     def __str__(self):\r
347         return ("<pmx.Material {name}>".format(\r
348             name=self.english_name\r
349             ))\r
350 \r
351 \r
352 class Bdef1(Diff):\r
353     """bone deform. use a weight\r
354 \r
355     Attributes: see __init__\r
356     """\r
357     __slots__=[ 'index0']\r
358     def __init__(self, index0):\r
359         self.index0=index0\r
360 \r
361     def __str__(self):\r
362         return "<Bdef1 {0}>".format(self.index0)\r
363 \r
364     def __eq__(self, rhs):\r
365         return self.index0==rhs.index0\r
366 \r
367     def __ne__(self, rhs):\r
368         return not self.__eq__(rhs)\r
369 \r
370 \r
371 class Bdef2(Diff):\r
372     """bone deform. use two weights\r
373 \r
374     Attributes: see __init__\r
375     """\r
376     __slots__=[ 'index0', 'index1', 'weight0']\r
377     def __init__(self, \r
378             index0,\r
379             index1,\r
380             weight0):\r
381         self.index0=index0\r
382         self.index1=index1\r
383         self.weight0=weight0\r
384 \r
385     def __str__(self):\r
386         return "<Bdef2 {0}, {1}, {2}>".format(self.index0, self.index1, self.weight0)\r
387 \r
388     def __eq__(self, rhs):\r
389         return (\r
390                 self.index0==rhs.index0\r
391                 and self.index1==rhs.index1\r
392                 #and self.weight0==rhs.weight0\r
393                 and abs(self.weight0-rhs.weight0)<1e-5\r
394                 )\r
395 \r
396     def __ne__(self, rhs):\r
397         return not self.__eq__(rhs)\r
398 \r
399 \r
400 class Vertex(Diff):\r
401     """\r
402     ==========\r
403     pmx vertex\r
404     ==========\r
405 \r
406     :IVariables:\r
407         position\r
408             Vector3\r
409         normal \r
410             Vector3\r
411         uv \r
412             Vector2\r
413         deform\r
414             Bdef1, Bdef2 or Bdef4\r
415         edge_factor\r
416             float\r
417     """\r
418     __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]\r
419     def __init__(self, \r
420             position, \r
421             normal, \r
422             uv, \r
423             deform, \r
424             edge_factor):\r
425         self.position=position \r
426         self.normal=normal\r
427         self.uv=uv\r
428         self.deform=deform\r
429         self.edge_factor=edge_factor\r
430 \r
431     def __str__(self):\r
432         return "<Vertex position:{0}, normal:{1}, uv:{2}, deform:{3}, edge:{4}".format(\r
433                 self.position, self.normal, self.uv, self.deform, self.edge_factor\r
434                 )\r
435 \r
436     def __eq__(self, rhs):\r
437         return (\r
438                 self.position==rhs.position\r
439                 and self.normal==rhs.normal\r
440                 and self.uv==rhs.uv\r
441                 and self.deform==rhs.deform\r
442                 and self.edge_factor==rhs.edge_factor\r
443                 )\r
444 \r
445     def __ne__(self, rhs):\r
446         return not self.__eq__(rhs)\r
447 \r
448     def diff(self, rhs):\r
449         self._diff(rhs, "position")\r
450         self._diff(rhs, "normal")\r
451         self._diff(rhs, "uv")\r
452         self._diff(rhs, "deform")\r
453         self._diff(rhs, "edge_factor")\r
454 \r
455 \r
456 class Morph(Diff):\r
457     """pmx morph\r
458 \r
459     Attributes:\r
460         name: \r
461         english_name: \r
462         panel:\r
463         morph_type:\r
464         offsets:\r
465     """\r
466     __slots__=[\r
467             'name',\r
468             'english_name',\r
469             'panel',\r
470             'morph_type',\r
471             'offsets',\r
472             ]\r
473     def __init__(self, name, english_name, panel, morph_type, offsets=[]):\r
474         self.name=name\r
475         self.english_name=english_name\r
476         self.panel=panel\r
477         self.morph_type=morph_type\r
478         self.offsets=offsets\r
479 \r
480     def __eq__(self, rhs):\r
481         return (\r
482                 self.name==rhs.name\r
483                 and self.english_name==rhs.english_name\r
484                 and self.panel==rhs.panel\r
485                 and self.morph_type==rhs.morph_type\r
486                 and self.offsets==rhs.offsets\r
487                 )\r
488 \r
489     def __ne__(self, rhs):\r
490         return not self.__eq__(rhs)\r
491 \r
492     def diff(self, rhs):\r
493         self._diff(rhs, 'name')\r
494         self._diff(rhs, 'english_name')\r
495         #self._diff(rhs, 'panel')\r
496         self._diff(rhs, 'morph_type')\r
497         self._diff_array(rhs, 'offsets')\r
498 \r
499 \r
500 class VerexMorphOffset(Diff):\r
501     """pmx vertex morph offset\r
502 \r
503     Attributes:\r
504         vertex_index:\r
505         position_offset: Vector3\r
506     """\r
507     __slots__=[\r
508             'vertex_index',\r
509             'position_offset',\r
510             ]\r
511     def __init__(self, vertex_index, position_offset):\r
512         self.vertex_index=vertex_index\r
513         self.position_offset=position_offset\r
514 \r
515     def __eq__(self, rhs):\r
516         return (\r
517                 self.vertex_index==rhs.vertex_index \r
518                 and self.position_offset==rhs.position_offset\r
519                 )\r
520 \r
521     def __ne__(self, rhs):\r
522         return not self.__eq__(rhs)\r
523 \r
524     def diff(self, rhs):\r
525         self._diff(rhs, 'vertex_index')\r
526         self._diff(rhs, 'position_offset')\r
527 \r
528 \r
529 class DisplaySlot(Diff):\r
530     """pmx display slot\r
531 \r
532     Attributes:\r
533         name: \r
534         english_name: \r
535         special_flag:\r
536         refrences: list of (ref_type, ref_index)\r
537     """\r
538     __slots__=[\r
539             'name',\r
540             'english_name',\r
541             'special_flag',\r
542             'refrences',\r
543             ]\r
544     def __init__(self, name, english_name, special_flag, refrences=[]):\r
545         self.name=name\r
546         self.english_name=english_name\r
547         self.special_flag=special_flag\r
548         self.refrences=refrences\r
549 \r
550     def __eq__(self, rhs):\r
551         return (\r
552                 self.name==rhs.name\r
553                 and self.english_name==rhs.english_name\r
554                 and self.special_flag==rhs.special_flag\r
555                 and self.refrences==rhs.refrences\r
556                 )\r
557 \r
558     def __ne__(self, rhs):\r
559         return not self.__eq__(rhs)\r
560 \r
561     def diff(self, rhs):\r
562         self._diff(rhs, 'name')\r
563         self._diff(rhs, 'english_name')\r
564         self._diff(rhs, 'special_flag')\r
565         #self._diff_array(rhs, 'refrences')\r
566 \r
567 \r
568 class RigidBodyParam(Diff):\r
569     """pmx rigidbody param(for bullet)\r
570 \r
571     Attributes:\r
572         mass:\r
573         linear_damping:\r
574         angular_damping:\r
575         restitution:\r
576         friction:\r
577     """\r
578     __slots__=[\r
579             'mass',\r
580             'linear_damping',\r
581             'angular_damping',\r
582             'restitution',\r
583             'friction',\r
584             ]\r
585     def __init__(self, mass, \r
586             linear_damping, angular_damping, restitution, friction):\r
587         self.mass=mass\r
588         self.linear_damping=linear_damping\r
589         self.angular_damping=angular_damping\r
590         self.restitution=restitution\r
591         self.friction=friction\r
592 \r
593     def __eq__(self, rhs):\r
594         return (\r
595                 self.mass==rhs.mass\r
596                 and self.linear_damping==rhs.linear_damping\r
597                 and self.angular_damping==rhs.angular_damping\r
598                 and self.restitution==rhs.restitution\r
599                 and self.friction==rhs.friction\r
600                 )\r
601 \r
602     def __ne__(self, rhs):\r
603         return not self.__eq__(rhs)\r
604 \r
605     def diff(self, rhs):\r
606         self._diff(rhs, 'mass')\r
607         self._diff(rhs, 'linear_damping')\r
608         self._diff(rhs, 'angular_damping')\r
609         self._diff_array(rhs, 'restitution')\r
610         self._diff_array(rhs, 'friction')\r
611 \r
612 \r
613 class RigidBody(Diff):\r
614     """pmx rigidbody\r
615 \r
616     Attributes:\r
617         name: \r
618         english_name: \r
619         bone_index:\r
620         collision_group:\r
621         no_collision_group:\r
622         shape:\r
623         param:\r
624         mode:\r
625     """\r
626     __slots__=[\r
627             'name',\r
628             'english_name',\r
629             'bone_index',\r
630             'collision_group',\r
631             'no_collision_group',\r
632             'shape_type',\r
633             'shape_size',\r
634             'shape_position',\r
635             'shape_rotation',\r
636             'param',\r
637             'mode',\r
638             ]\r
639     def __init__(self,\r
640             name,\r
641             english_name,\r
642             bone_index,\r
643             collision_group,\r
644             no_collision_group,\r
645             shape_type,\r
646             shape_size,\r
647             shape_position,\r
648             shape_rotation,\r
649             mass,\r
650             linear_damping,\r
651             angular_damping,\r
652             restitution,\r
653             friction,\r
654             mode\r
655             ):\r
656         self.name=name\r
657         self.english_name=english_name\r
658         self.bone_index=bone_index\r
659         self.collision_group=collision_group\r
660         self.no_collision_group=no_collision_group\r
661         self.shape_type=shape_type\r
662         self.shape_size=shape_size\r
663         self.shape_position=shape_position\r
664         self.shape_rotation=shape_rotation\r
665         self.param=RigidBodyParam(mass,\r
666                 linear_damping, angular_damping,\r
667                 restitution, friction)\r
668         self.mode=mode\r
669 \r
670     def __eq__(self, rhs):\r
671         return (\r
672                 self.name==rhs.name\r
673                 and self.english_name==rhs.english_name\r
674                 and self.bone_index==rhs.bone_index\r
675                 and self.collision_group==rhs.collision_group\r
676                 and self.no_collision_group==rhs.no_collision_group\r
677                 and self.shape_type==rhs.shape_type\r
678                 and self.shape_size==rhs.shape_size\r
679                 and self.param==rhs.param\r
680                 and self.mode==rhs.mode\r
681                 )\r
682 \r
683     def __ne__(self, rhs):\r
684         return not self.__eq__(rhs)\r
685 \r
686     def diff(self, rhs):\r
687         self._diff(rhs, 'name')\r
688         self._diff(rhs, 'english_name')\r
689         self._diff(rhs, 'bone_index')\r
690         self._diff(rhs, 'collision_group')\r
691         self._diff(rhs, 'no_collision_group')\r
692         self._diff(rhs, 'shape_type')\r
693         self._diff(rhs, 'shape_size')\r
694         #self._diff(rhs, 'shape_position')\r
695         self._diff(rhs, 'shape_rotation')\r
696         self._diff(rhs, 'param')\r
697         self._diff(rhs, 'mode')\r
698 \r
699 \r
700 class Joint(Diff):\r
701     """pmx joint\r
702 \r
703     Attributes:\r
704         name: \r
705         english_name: \r
706         joint_type:\r
707         rigidbody_index_a:\r
708         rigidbody_index_b:\r
709         position: Vector3\r
710         rotation: Vector3\r
711         translation_limit_min: Vector3\r
712         translation_limit_max: Vector3\r
713         rotation_limit_min: Vector3\r
714         rotation_limit_max: Vector3\r
715         spring_constant_translation: Vector3\r
716         spring_constant_rotation: Vector3\r
717     """\r
718     __slots__=[\r
719             'name',\r
720             'english_name',\r
721             'joint_type',\r
722             'rigidbody_index_a',\r
723             'rigidbody_index_b',\r
724             'position',\r
725             'rotation',\r
726             'translation_limit_min',\r
727             'translation_limit_max',\r
728             'rotation_limit_min',\r
729             'rotation_limit_max',\r
730             'spring_constant_translation',\r
731             'spring_constant_rotation',\r
732             ]\r
733     def __init__(self, name, english_name,\r
734             joint_type,\r
735             rigidbody_index_a,\r
736             rigidbody_index_b,\r
737             position,\r
738             rotation,\r
739             translation_limit_min,\r
740             translation_limit_max,\r
741             rotation_limit_min,\r
742             rotation_limit_max,\r
743             spring_constant_translation,\r
744             spring_constant_rotation\r
745             ):\r
746         self.name=name\r
747         self.english_name=english_name\r
748         self.joint_type=joint_type\r
749         self.rigidbody_index_a=rigidbody_index_a\r
750         self.rigidbody_index_b=rigidbody_index_b\r
751         self.position=position\r
752         self.rotation=rotation\r
753         self.translation_limit_min=translation_limit_min\r
754         self.translation_limit_max=translation_limit_max\r
755         self.rotation_limit_min=rotation_limit_min\r
756         self.rotation_limit_max=rotation_limit_max\r
757         self.spring_constant_translation=spring_constant_translation\r
758         self.spring_constant_rotation=spring_constant_rotation\r
759 \r
760     def __eq__(self, rhs):\r
761         return (\r
762                 self.name==rhs.name\r
763                 and self.english_name==rhs.english_name\r
764                 and self.joint_type==rhs.joint_type\r
765                 and self.rigidbody_index_a==rhs.rigidbody_index_a\r
766                 and self.rigidbody_index_b==rhs.rigidbody_index_b\r
767                 and self.position==rhs.position\r
768                 and self.rotation==rhs.rotation\r
769                 and self.translation_limit_min==rhs.translation_limit_min\r
770                 and self.translation_limit_max==rhs.translation_limit_max\r
771                 and self.rotation_limit_min==rhs.rotation_limit_min\r
772                 and self.rotation_limit_max==rhs.rotation_limit_max\r
773                 and self.spring_constant_translation==rhs.spring_constant_translation\r
774                 and self.spring_constant_rotation==rhs.spring_constant_rotation\r
775                 )\r
776 \r
777     def __ne__(self, rhs):\r
778         return not self.__eq__(rhs)\r
779 \r
780     def diff(self, rhs):\r
781         self._diff(rhs, 'name')\r
782         self._diff(rhs, 'joint_type')\r
783         self._diff(rhs, 'rigidbody_index_a')\r
784         self._diff(rhs, 'rigidbody_index_b')\r
785         self._diff(rhs, 'position')\r
786         self._diff(rhs, 'rotation')\r
787         self._diff(rhs, 'translation_limit_min')\r
788         self._diff(rhs, 'translation_limit_max')\r
789         self._diff(rhs, 'rotation_limit_min')\r
790         self._diff(rhs, 'rotation_limit_max')\r
791         self._diff(rhs, 'spring_constant_translation')\r
792         self._diff(rhs, 'spring_constant_rotation')\r
793 \r
794 \r
795 class Model(Diff):\r
796     """\r
797     ==========\r
798     pmx model\r
799     ==========\r
800 \r
801     :IVariables:\r
802         version\r
803             pmx version(expected 2.0)\r
804         name \r
805             model name\r
806         english_name \r
807             model name\r
808         comment \r
809             comment\r
810         english_comment \r
811             comment\r
812         vertices\r
813             vertex list\r
814         textures\r
815             texture list\r
816         materials\r
817             material list\r
818         bones\r
819             bone list\r
820         morph\r
821             morph list\r
822         display_slots\r
823             display list for bone/morph grouping\r
824         rigidbodies\r
825             bullet physics rigidbody list\r
826         joints\r
827             bullet physics joint list\r
828     """\r
829     __slots__=[\r
830             'path',\r
831             'version',\r
832             'name',\r
833             'english_name',\r
834             'comment',\r
835             'english_comment',\r
836             'vertices',\r
837             'indices',\r
838             'textures',\r
839             'materials',\r
840             'bones',\r
841             'morphs',\r
842             'display_slots',\r
843             'rigidbodies',\r
844             'joints',\r
845             ]\r
846     def __init__(self, version=2.0):\r
847         self.path=''\r
848         self.version=version\r
849         self.name=''\r
850         self.english_name=''\r
851         self.comment=''\r
852         self.english_comment=''\r
853         self.vertices=[]\r
854         self.indices=[]\r
855         self.textures=[]\r
856         self.materials=[]\r
857         self.bones=[]\r
858         self.morphs=[]\r
859         self.display_slots=[]\r
860         self.rigidbodies=[]\r
861         self.joints=[]\r
862 \r
863     def __str__(self):\r
864         return ('<pmx-{version} "{name}" {vertices}vertices>'.format(\r
865             version=self.version,\r
866             name=self.english_name,\r
867             vertices=len(self.vertices)\r
868             ))\r
869 \r
870     def __eq__(self, rhs):\r
871         return (\r
872                 self.version==rhs.version\r
873                 and self.name==rhs.name\r
874                 and self.english_name==rhs.english_name\r
875                 and self.comment==rhs.comment\r
876                 and self.english_comment==rhs.english_comment\r
877                 and self.vertices==rhs.vertices\r
878                 and self.indices==rhs.indices\r
879                 and self.textures==rhs.textures\r
880                 and self.materials==rhs.materials\r
881                 and self.bones==rhs.bones\r
882                 and self.morphs==rhs.morphs\r
883                 and self.display_slots==rhs.display_slots\r
884                 and self.rigidbodies==rhs.rigidbodies\r
885                 and self.joints==rhs.joints\r
886                 )\r
887 \r
888     def __ne__(self, rhs):\r
889         return not self.__eq__(rhs)\r
890 \r
891     def diff(self, rhs):\r
892         self._diff(rhs, "version")\r
893         self._diff(rhs, "name")\r
894         self._diff(rhs, "english_name")\r
895         self._diff(rhs, "comment")\r
896         self._diff(rhs, "english_comment")\r
897         self._diff_array(rhs, "vertices")\r
898         self._diff_array(rhs, "indices")\r
899         self._diff_array(rhs, "textures")\r
900         self._diff_array(rhs, "materials")\r
901         self._diff_array(rhs, "bones")\r
902         self._diff_array(rhs, "morphs")\r
903         self._diff_array(rhs, "display_slots")\r
904         self._diff_array(rhs, "rigidbodies")\r
905         self._diff_array(rhs, "joints")\r
906 \r