1
# ##### BEGIN GPL LICENSE BLOCK #####
3
# This program is free software; you can redistribute it and/or
4
# modify it under the terms of the GNU General Public License
5
# as published by the Free Software Foundation; either version 2
6
# of the License, or (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software Foundation,
15
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
# ##### END GPL LICENSE BLOCK #####
21
###############################################################################
22
#234567890123456789012345678901234567890123456789012345678901234567890123456789
23
#--------1---------2---------3---------4---------5---------6---------7---------
26
# ##### BEGIN COPYRIGHT BLOCK #####
28
# initial script copyright (c)2011-2013 Alexander Nussbaumer
30
# ##### END COPYRIGHT BLOCK #####
44
###############################################################################
46
# MilkShape 3D 1.8.5 File Format Specification
48
# all specifications were taken from SDK 1.8.5
50
# some additional specifications were taken from
51
# MilkShape 3D Viewer v2.0 (Nov 06 2007) - msMesh.h
55
###############################################################################
61
###########################################################################
65
MAX_VERTICES = 65534 # 0..65533; note: (65534???, 65535???)
66
MAX_TRIANGLES = 65534 # 0..65533; note: (65534???, 65535???)
67
MAX_GROUPS = 255 # 1..255; note: (0 default group)
68
MAX_MATERIALS = 128 # 0..127; note: (-1 no material)
69
MAX_JOINTS = 128 # 0..127; note: (-1 no joint)
70
MAX_SMOOTH_GROUP = 32 # 0..32; note: (0 no smoothing group)
71
MAX_TEXTURE_FILENAME_SIZE = 128
73
###########################################################################
82
FLAG_ISKEY = 16 # additional spec from [2]
83
FLAG_NEWLYCREATED = 32 # additional spec from [2]
84
FLAG_MARKED = 64 # additional spec from [2]
86
FLAG_TEXTURE_NONE = 0x00
87
FLAG_TEXTURE_COMBINE_ALPHA = 0x20
88
FLAG_TEXTURE_HAS_ALPHA = 0x40
89
FLAG_TEXTURE_SPHERE_MAP = 0x80
91
MODE_TRANSPARENCY_SIMPLE = 0
92
MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF = 1
93
MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES = 2
96
###########################################################################
100
HEADER = "MS3D000000"
103
## TEST_STR = 'START@€@µ@²@³@©@®@¶@ÿ@A@END.bmp'
104
## TEST_RAW = b'START@\x80@\xb5@\xb2@\xb3@\xa9@\xae@\xb6@\xff@A@END.bmp\x00'
106
STRING_MS3D_REPLACE = 'use_ms3d_replace'
107
STRING_ENCODING = "ascii" # wrong encoding (too limited), but there is an UnicodeEncodeError issue, that prevent using the correct one for the moment
108
##STRING_ENCODING = "cp437" # US, wrong encoding and shows UnicodeEncodeError
109
##STRING_ENCODING = "cp858" # Europe + €, wrong encoding and shows UnicodeEncodeError
110
##STRING_ENCODING = "cp1252" # WIN EU, this would be the better codepage, but shows UnicodeEncodeError, on print on system console and writing to file
111
STRING_ERROR = STRING_MS3D_REPLACE
112
##STRING_ERROR = 'replace'
113
##STRING_ERROR = 'ignore'
114
##STRING_ERROR = 'surrogateescape'
115
STRING_TERMINATION = b'\x00'
116
STRING_REPLACE = u'_'
119
###########################################################################
121
# min, max, default values
123
NONE_VERTEX_BONE_ID = -1
124
NONE_GROUP_MATERIAL_INDEX = -1
126
DEFAULT_HEADER = HEADER
127
DEFAULT_HEADER_VERSION = 4
128
DEFAULT_VERTEX_BONE_ID = NONE_VERTEX_BONE_ID
129
DEFAULT_TRIANGLE_SMOOTHING_GROUP = 0
130
DEFAULT_TRIANGLE_GROUP = 0
131
DEFAULT_MATERIAL_MODE = FLAG_TEXTURE_NONE
132
DEFAULT_GROUP_MATERIAL_INDEX = NONE_GROUP_MATERIAL_INDEX
133
DEFAULT_MODEL_JOINT_SIZE = 1.0
134
DEFAULT_MODEL_TRANSPARENCY_MODE = MODE_TRANSPARENCY_SIMPLE
135
DEFAULT_MODEL_ANIMATION_FPS = 25.0
136
DEFAULT_MODEL_SUB_VERSION_COMMENTS = 1
137
DEFAULT_MODEL_SUB_VERSION_VERTEX_EXTRA = 2
138
DEFAULT_MODEL_SUB_VERSION_JOINT_EXTRA = 1
139
DEFAULT_MODEL_SUB_VERSION_MODEL_EXTRA = 1
140
DEFAULT_FLAGS = FLAG_NONE
141
MAX_MATERIAL_SHININESS = 128
143
# blender default / OpenGL default
144
DEFAULT_MATERIAL_AMBIENT = (0.2, 0.2, 0.2, 1.0)
145
DEFAULT_MATERIAL_DIFFUSE = (0.8, 0.8, 0.8, 1.0)
146
DEFAULT_MATERIAL_SPECULAR = (1.0, 1.0, 1.0, 1.0)
147
DEFAULT_MATERIAL_EMISSIVE = (0.0, 0.0, 0.0, 1.0)
148
DEFAULT_MATERIAL_SHININESS = 12.5
150
DEFAULT_JOINT_COLOR = (0.8, 0.8, 0.8)
152
###############################################################################
154
# helper class for basic raw io
165
LENGTH_FILENAME = 128
170
def read_byte(raw_io):
171
""" read a single byte from raw_io """
172
buffer = raw_io.read(Ms3dIo.SIZE_BYTE)
175
value = unpack('<B', buffer)[0]
179
def write_byte(raw_io, value):
180
""" write a single byte to raw_io """
181
raw_io.write(pack('<B', value))
184
def read_sbyte(raw_io):
185
""" read a single signed byte from raw_io """
186
buffer = raw_io.read(Ms3dIo.SIZE_BYTE)
189
value = unpack('<b', buffer)[0]
193
def write_sbyte(raw_io, value):
194
""" write a single signed byte to raw_io """
195
raw_io.write(pack('<b', value))
198
def read_word(raw_io):
199
""" read a word from raw_io """
200
buffer = raw_io.read(Ms3dIo.SIZE_WORD)
203
value = unpack('<H', buffer)[0]
207
def write_word(raw_io, value):
208
""" write a word to raw_io """
209
raw_io.write(pack('<H', value))
212
def read_dword(raw_io):
213
""" read a double word from raw_io """
214
buffer = raw_io.read(Ms3dIo.SIZE_DWORD)
217
value = unpack('<I', buffer)[0]
221
def write_dword(raw_io, value):
222
""" write a double word to raw_io """
223
raw_io.write(pack('<I', value))
226
def read_float(raw_io):
227
""" read a float from raw_io """
228
buffer = raw_io.read(Ms3dIo.SIZE_FLOAT)
231
value = unpack('<f', buffer)[0]
235
def write_float(raw_io, value):
236
""" write a float to raw_io """
237
raw_io.write(pack('<f', value))
240
def read_array(raw_io, itemReader, count):
241
""" read an array[count] of objects from raw_io, by using a itemReader """
243
for i in range(count):
244
itemValue = itemReader(raw_io)
245
value.append(itemValue)
249
def write_array(raw_io, itemWriter, count, value):
250
""" write an array[count] of objects to raw_io, by using a itemWriter """
251
for i in range(count):
253
itemWriter(raw_io, itemValue)
256
def read_array2(raw_io, itemReader, count, count2):
257
""" read an array[count][count2] of objects from raw_io,
258
by using a itemReader """
260
for i in range(count):
261
itemValue = Ms3dIo.read_array(raw_io, itemReader, count2)
262
value.append(tuple(itemValue))
266
def write_array2(raw_io, itemWriter, count, count2, value):
267
""" write an array[count][count2] of objects to raw_io,
268
by using a itemWriter """
269
for i in range(count):
271
Ms3dIo.write_array(raw_io, itemWriter, count2, itemValue)
275
def ms3d_replace(exc):
276
""" http://www.python.org/dev/peps/pep-0293/ """
277
if isinstance(exc, UnicodeEncodeError):
278
return ((exc.end-exc.start)*Ms3dSpec.STRING_REPLACE, exc.end)
279
elif isinstance(exc, UnicodeDecodeError):
280
return (Ms3dSpec.STRING_REPLACE, exc.end)
281
elif isinstance(exc, UnicodeTranslateError):
282
return ((exc.end-exc.start)*Ms3dSpec.STRING_REPLACE, exc.end)
284
raise TypeError("can't handle %s" % exc.__name__)
287
def read_string(raw_io, length):
288
""" read a string of a specific length from raw_io """
289
buffer = raw_io.read(length)
292
eol = buffer.find(Ms3dSpec.STRING_TERMINATION)
293
register_error(Ms3dSpec.STRING_MS3D_REPLACE, Ms3dIo.ms3d_replace)
294
s = buffer[:eol].decode(encoding=Ms3dSpec.STRING_ENCODING, errors=Ms3dSpec.STRING_ERROR)
298
def write_string(raw_io, length, value):
299
""" write a string of a specific length to raw_io """
300
register_error(Ms3dSpec.STRING_MS3D_REPLACE, Ms3dIo.ms3d_replace)
301
buffer = value.encode(encoding=Ms3dSpec.STRING_ENCODING, errors=Ms3dSpec.STRING_ERROR)
304
raw_io.write(pack('<{}s'.format(length), buffer))
308
###############################################################################
310
# multi complex types
313
###############################################################################
323
default_id=Ms3dSpec.DEFAULT_HEADER,
324
default_version=Ms3dSpec.DEFAULT_HEADER_VERSION
327
self.version = default_version
330
return "\n<id='{}', version={}>".format(
336
return hash(self.id) ^ hash(self.version)
338
def __eq__(self, other):
339
return ((self is not None) and (other is not None)
340
and (self.id == other.id)
341
and (self.version == other.version))
343
def read(self, raw_io):
344
self.id = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_ID)
345
self.version = Ms3dIo.read_dword(raw_io)
348
def write(self, raw_io):
349
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_ID, self.id)
350
Ms3dIo.write_dword(raw_io, self.version)
353
###############################################################################
357
__slots__ was taking out,
358
to be able to inject additional attributes during runtime
364
'_vertex_ex_object', # Ms3dVertexEx
370
default_flags=Ms3dSpec.DEFAULT_FLAGS,
371
default_vertex=(0.0, 0.0, 0.0),
372
default_bone_id=Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
373
default_reference_count=0,
374
default_vertex_ex_object=None, # Ms3dVertexEx
376
self.flags = default_flags
377
self._vertex = default_vertex
378
self.bone_id = default_bone_id
379
self.reference_count = default_reference_count
381
if default_vertex_ex_object is None:
382
default_vertex_ex_object = Ms3dVertexEx2()
383
# Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_VERTEX_EXTRA = 2
384
self._vertex_ex_object = default_vertex_ex_object
388
return "\n<flags={}, vertex=({:.{p}f}, {:.{p}f}, {:.{p}f}), bone_id={},"\
389
" reference_count={}>".format(
395
self.reference_count,
400
return (hash(self.vertex)
402
#^ hash(self.bone_id)
403
#^ hash(self.reference_count)
406
def __eq__(self, other):
407
return ((self.vertex == other.vertex)
408
#and (self.flags == other.flags)
409
#and (self.bone_id == other.bone_id)
410
#and (self.reference_count == other.reference_count)
419
def vertex_ex_object(self):
420
return self._vertex_ex_object
423
def read(self, raw_io):
424
self.flags = Ms3dIo.read_byte(raw_io)
425
self._vertex = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
426
self.bone_id = Ms3dIo.read_sbyte(raw_io)
427
self.reference_count = Ms3dIo.read_byte(raw_io)
430
def write(self, raw_io):
431
Ms3dIo.write_byte(raw_io, self.flags)
432
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.vertex)
433
Ms3dIo.write_sbyte(raw_io, self.bone_id)
434
Ms3dIo.write_byte(raw_io, self.reference_count)
437
###############################################################################
441
__slots__ was taking out,
442
to be able to inject additional attributes during runtime
456
default_flags=Ms3dSpec.DEFAULT_FLAGS,
457
default_vertex_indices=(0, 0, 0),
458
default_vertex_normals=(
462
default_s=(0.0, 0.0, 0.0),
463
default_t=(0.0, 0.0, 0.0),
464
default_smoothing_group=Ms3dSpec.DEFAULT_TRIANGLE_SMOOTHING_GROUP,
465
default_group_index=Ms3dSpec.DEFAULT_TRIANGLE_GROUP
467
self.flags = default_flags
468
self._vertex_indices = default_vertex_indices
469
self._vertex_normals = default_vertex_normals
472
self.smoothing_group = default_smoothing_group
473
self.group_index = default_group_index
476
return "\n<flags={}, vertex_indices={}, vertex_normals=(({:.{p}f}, "\
477
"{:.{p}f}, {:.{p}f}), ({:.{p}f}, {:.{p}f}, {:.{p}f}), ({:.{p}f}, "\
478
"{:.{p}f}, {:.{p}f})), s=({:.{p}f}, {:.{p}f}, {:.{p}f}), "\
479
"t=({:.{p}f}, {:.{p}f}, {:.{p}f}), smoothing_group={}, "\
480
"group_index={}>".format(
483
self.vertex_normals[0][0],
484
self.vertex_normals[0][1],
485
self.vertex_normals[0][2],
486
self.vertex_normals[1][0],
487
self.vertex_normals[1][1],
488
self.vertex_normals[1][2],
489
self.vertex_normals[2][0],
490
self.vertex_normals[2][1],
491
self.vertex_normals[2][2],
498
self.smoothing_group,
505
def vertex_indices(self):
506
return self._vertex_indices
509
def vertex_normals(self):
510
return self._vertex_normals
521
def read(self, raw_io):
522
self.flags = Ms3dIo.read_word(raw_io)
523
self._vertex_indices = Ms3dIo.read_array(raw_io, Ms3dIo.read_word, 3)
524
self._vertex_normals = Ms3dIo.read_array2(raw_io, Ms3dIo.read_float, 3, 3)
525
self._s = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
526
self._t = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
527
self.smoothing_group = Ms3dIo.read_byte(raw_io)
528
self.group_index = Ms3dIo.read_byte(raw_io)
531
def write(self, raw_io):
532
Ms3dIo.write_word(raw_io, self.flags)
533
Ms3dIo.write_array(raw_io, Ms3dIo.write_word, 3, self.vertex_indices)
534
Ms3dIo.write_array2(raw_io, Ms3dIo.write_float, 3, 3, self.vertex_normals)
535
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.s)
536
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.t)
537
Ms3dIo.write_byte(raw_io, self.smoothing_group)
538
Ms3dIo.write_byte(raw_io, self.group_index)
541
###############################################################################
545
__slots__ was taking out,
546
to be able to inject additional attributes during runtime
552
'_comment_object', # Ms3dComment
558
default_flags=Ms3dSpec.DEFAULT_FLAGS,
560
default_triangle_indices=None,
561
default_material_index=Ms3dSpec.DEFAULT_GROUP_MATERIAL_INDEX,
562
default_comment_object=None, # Ms3dComment
564
if (default_name is None):
567
if (default_triangle_indices is None):
568
default_triangle_indices = []
570
self.flags = default_flags
571
self.name = default_name
572
self._triangle_indices = default_triangle_indices
573
self.material_index = default_material_index
575
if default_comment_object is None:
576
default_comment_object = Ms3dCommentEx()
577
self._comment_object = default_comment_object # Ms3dComment
580
return "\n<flags={}, name='{}', number_triangles={},"\
581
" triangle_indices={}, material_index={}>".format(
584
self.number_triangles,
585
self.triangle_indices,
591
def number_triangles(self):
592
if self.triangle_indices is None:
594
return len(self.triangle_indices)
597
def triangle_indices(self):
598
return self._triangle_indices
601
def comment_object(self):
602
return self._comment_object
605
def read(self, raw_io):
606
self.flags = Ms3dIo.read_byte(raw_io)
607
self.name = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_NAME)
608
_number_triangles = Ms3dIo.read_word(raw_io)
609
self._triangle_indices = Ms3dIo.read_array(
610
raw_io, Ms3dIo.read_word, _number_triangles)
611
self.material_index = Ms3dIo.read_sbyte(raw_io)
614
def write(self, raw_io):
615
Ms3dIo.write_byte(raw_io, self.flags)
616
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_NAME, self.name)
617
Ms3dIo.write_word(raw_io, self.number_triangles)
619
raw_io, Ms3dIo.write_word, self.number_triangles,
620
self.triangle_indices)
621
Ms3dIo.write_sbyte(raw_io, self.material_index)
624
###############################################################################
628
__slots__ was taking out,
629
to be able to inject additional attributes during runtime
641
'_comment_object', # Ms3dComment
648
default_ambient=list(Ms3dSpec.DEFAULT_MATERIAL_AMBIENT),
649
default_diffuse=list(Ms3dSpec.DEFAULT_MATERIAL_DIFFUSE),
650
default_specular=list(Ms3dSpec.DEFAULT_MATERIAL_SPECULAR),
651
default_emissive=list(Ms3dSpec.DEFAULT_MATERIAL_EMISSIVE),
652
default_shininess=Ms3dSpec.DEFAULT_MATERIAL_SHININESS,
653
default_transparency=0.0,
654
default_mode=Ms3dSpec.DEFAULT_MATERIAL_MODE,
657
default_comment_object=None, # Ms3dComment
659
if (default_name is None):
662
if (default_texture is None):
665
if (default_alphamap is None):
666
default_alphamap = ""
668
self.name = default_name
669
self._ambient = default_ambient
670
self._diffuse = default_diffuse
671
self._specular = default_specular
672
self._emissive = default_emissive
673
self.shininess = default_shininess
674
self.transparency = default_transparency
675
self.mode = default_mode
676
self.texture = default_texture
677
self.alphamap = default_alphamap
679
if default_comment_object is None:
680
default_comment_object = Ms3dCommentEx()
681
self._comment_object = default_comment_object # Ms3dComment
684
return "\n<name='{}', ambient=({:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}), "\
685
"diffuse=({:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}), specular=("\
686
"{:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}), emissive=({:.{p}f}, "\
687
"{:.{p}f}, {:.{p}f}, {:.{p}f}), shininess={:.{p}f}, transparency="\
688
"{:.{p}f}, mode={}, texture='{}', alphamap='{}'>".format(
715
return (hash(self.name)
719
^ hash(self.specular)
720
^ hash(self.emissive)
722
^ hash(self.shininess)
723
^ hash(self.transparency)
727
^ hash(self.alphamap)
730
def __eq__(self, other):
731
return ((self.name == other.name)
733
and (self.ambient == other.ambient)
734
and (self.diffuse == other.diffuse)
735
and (self.specular == other.specular)
736
and (self.emissive == other.emissive)
738
and (self.shininess == other.shininess)
739
and (self.transparency == other.transparency)
740
and (self.mode == other.mode)
742
#and (self.texture == other.texture)
743
#and (self.alphamap == other.alphamap)
757
return self._specular
761
return self._emissive
764
def comment_object(self):
765
return self._comment_object
768
def read(self, raw_io):
769
self.name = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_NAME)
770
self._ambient = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 4)
771
self._diffuse = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 4)
772
self._specular = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 4)
773
self._emissive = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 4)
774
self.shininess = Ms3dIo.read_float(raw_io)
775
self.transparency = Ms3dIo.read_float(raw_io)
776
self.mode = Ms3dIo.read_byte(raw_io)
777
self.texture = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_FILENAME)
778
self.alphamap = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_FILENAME)
781
def write(self, raw_io):
782
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_NAME, self.name)
783
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 4, self.ambient)
784
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 4, self.diffuse)
785
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 4, self.specular)
786
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 4, self.emissive)
787
Ms3dIo.write_float(raw_io, self.shininess)
788
Ms3dIo.write_float(raw_io, self.transparency)
789
Ms3dIo.write_byte(raw_io, self.mode)
790
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_FILENAME, self.texture)
791
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_FILENAME, self.alphamap)
794
###############################################################################
795
class Ms3dRotationKeyframe:
796
""" Ms3dRotationKeyframe """
805
default_rotation=(0.0, 0.0, 0.0)
807
self.time = default_time
808
self._rotation = default_rotation
811
return "\n<time={:.{p}f}, rotation=({:.{p}f}, {:.{p}f}, {:.{p}f})>".format(
822
return self._rotation
825
def read(self, raw_io):
826
self.time = Ms3dIo.read_float(raw_io)
827
self._rotation = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
830
def write(self, raw_io):
831
Ms3dIo.write_float(raw_io, self.time)
832
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.rotation)
835
###############################################################################
836
class Ms3dTranslationKeyframe:
837
""" Ms3dTranslationKeyframe """
846
default_position=(0.0, 0.0, 0.0)
848
self.time = default_time
849
self._position = default_position
852
return "\n<time={:.{p}f}, position=({:.{p}f}, {:.{p}f}, {:.{p}f})>".format(
863
return self._position
866
def read(self, raw_io):
867
self.time = Ms3dIo.read_float(raw_io)
868
self._position = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
871
def write(self, raw_io):
872
Ms3dIo.write_float(raw_io, self.time)
873
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.position)
876
###############################################################################
880
__slots__ was taking out,
881
to be able to inject additional attributes during runtime
888
'_rotation_keyframes',
889
'_translation_keyframes',
890
'_joint_ex_object', # Ms3dJointEx
891
'_comment_object', # Ms3dComment
897
default_flags=Ms3dSpec.DEFAULT_FLAGS,
899
default_parent_name="",
900
default_rotation=(0.0, 0.0, 0.0),
901
default_position=(0.0, 0.0, 0.0),
902
default_rotation_keyframes=None,
903
default_translation_keyframes=None,
904
default_joint_ex_object=None, # Ms3dJointEx
905
default_comment_object=None, # Ms3dComment
907
if (default_name is None):
910
if (default_parent_name is None):
911
default_parent_name = ""
913
if (default_rotation_keyframes is None):
914
default_rotation_keyframes = [] #Ms3dRotationKeyframe()
916
if (default_translation_keyframes is None):
917
default_translation_keyframes = [] #Ms3dTranslationKeyframe()
919
self.flags = default_flags
920
self.name = default_name
921
self.parent_name = default_parent_name
922
self._rotation = default_rotation
923
self._position = default_position
924
self._rotation_keyframes = default_rotation_keyframes
925
self._translation_keyframes = default_translation_keyframes
927
if default_comment_object is None:
928
default_comment_object = Ms3dCommentEx()
929
self._comment_object = default_comment_object # Ms3dComment
931
if default_joint_ex_object is None:
932
default_joint_ex_object = Ms3dJointEx()
933
self._joint_ex_object = default_joint_ex_object # Ms3dJointEx
936
return "\n<flags={}, name='{}', parent_name='{}', rotation=({:.{p}f}, "\
937
"{:.{p}f}, {:.{p}f}), position=({:.{p}f}, {:.{p}f}, {:.{p}f}), "\
938
"number_rotation_keyframes={}, number_translation_keyframes={},"\
939
" rotation_key_frames={}, translation_key_frames={}>".format(
949
self.number_rotation_keyframes,
950
self.number_translation_keyframes,
951
self.rotation_key_frames,
952
self.translation_key_frames,
959
return self._rotation
963
return self._position
966
def number_rotation_keyframes(self):
967
if self.rotation_key_frames is None:
969
return len(self.rotation_key_frames)
972
def number_translation_keyframes(self):
973
if self.translation_key_frames is None:
975
return len(self.translation_key_frames)
978
def rotation_key_frames(self):
979
return self._rotation_keyframes
982
def translation_key_frames(self):
983
return self._translation_keyframes
987
def joint_ex_object(self):
988
return self._joint_ex_object
992
def comment_object(self):
993
return self._comment_object
996
def read(self, raw_io):
997
self.flags = Ms3dIo.read_byte(raw_io)
998
self.name = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_NAME)
999
self.parent_name = Ms3dIo.read_string(raw_io, Ms3dIo.LENGTH_NAME)
1000
self._rotation = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
1001
self._position = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
1002
_number_rotation_keyframes = Ms3dIo.read_word(raw_io)
1003
_number_translation_keyframes = Ms3dIo.read_word(raw_io)
1004
self._rotation_keyframes = []
1005
for i in range(_number_rotation_keyframes):
1006
self.rotation_key_frames.append(Ms3dRotationKeyframe().read(raw_io))
1007
self._translation_keyframes = []
1008
for i in range(_number_translation_keyframes):
1009
self.translation_key_frames.append(
1010
Ms3dTranslationKeyframe().read(raw_io))
1013
def write(self, raw_io):
1014
Ms3dIo.write_byte(raw_io, self.flags)
1015
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_NAME, self.name)
1016
Ms3dIo.write_string(raw_io, Ms3dIo.LENGTH_NAME, self.parent_name)
1017
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.rotation)
1018
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.position)
1019
Ms3dIo.write_word(raw_io, self.number_rotation_keyframes)
1020
Ms3dIo.write_word(raw_io, self.number_translation_keyframes)
1021
for i in range(self.number_rotation_keyframes):
1022
self.rotation_key_frames[i].write(raw_io)
1023
for i in range(self.number_translation_keyframes):
1024
self.translation_key_frames[i].write(raw_io)
1027
###############################################################################
1028
class Ms3dCommentEx:
1029
""" Ms3dCommentEx """
1040
if (default_comment is None):
1041
default_comment = ""
1043
self.index = default_index
1044
self.comment = default_comment
1047
return "\n<index={}, comment_length={}, comment='{}'>".format(
1049
self.comment_length,
1055
def comment_length(self):
1056
if self.comment is None:
1058
return len(self.comment)
1061
def read(self, raw_io):
1062
self.index = Ms3dIo.read_dword(raw_io)
1063
_comment_length = Ms3dIo.read_dword(raw_io)
1064
self.comment = Ms3dIo.read_string(raw_io, _comment_length)
1067
def write(self, raw_io):
1068
Ms3dIo.write_dword(raw_io, self.index)
1069
Ms3dIo.write_dword(raw_io, self.comment_length)
1070
Ms3dIo.write_string(raw_io, self.comment_length, self.comment)
1073
###############################################################################
1084
if (default_comment is None):
1085
default_comment = ""
1087
self.comment = default_comment
1090
return "\n<comment_length={}, comment='{}'>".format(
1091
self.comment_length,
1097
def comment_length(self):
1098
if self.comment is None:
1100
return len(self.comment)
1103
def read(self, raw_io):
1104
_comment_length = Ms3dIo.read_dword(raw_io)
1105
self.comment = Ms3dIo.read_string(raw_io, _comment_length)
1108
def write(self, raw_io):
1109
Ms3dIo.write_dword(raw_io, self.comment_length)
1110
Ms3dIo.write_string(raw_io, self.comment_length, self.comment)
1113
###############################################################################
1114
class Ms3dVertexEx1:
1115
""" Ms3dVertexEx1 """
1124
Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
1125
Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
1126
Ms3dSpec.DEFAULT_VERTEX_BONE_ID),
1127
default_weights=(100, 0, 0)
1129
self._bone_ids = default_bone_ids
1130
self._weights = default_weights
1133
return "\n<bone_ids={}, weights={}>".format(
1141
return self._bone_ids
1145
return self._weights
1149
def weight_bone_id(self):
1150
if self._weights[0] or self._weights[1] or self._weights[2]:
1151
return self._weights
1155
def weight_bone_id0(self):
1156
if self._weights[0] or self._weights[1] or self._weights[2]:
1157
return self._weights[0]
1161
def weight_bone_id1(self):
1162
if self._weights[0] or self._weights[1] or self._weights[2]:
1163
return self._weights[1]
1167
def weight_bone_id2(self):
1168
if self._weights[0] or self._weights[1] or self._weights[2]:
1169
return 100 - (self._weights[0] + self._weights[1] \
1174
def read(self, raw_io):
1175
self._bone_ids = Ms3dIo.read_array(raw_io, Ms3dIo.read_sbyte, 3)
1176
self._weights = Ms3dIo.read_array(raw_io, Ms3dIo.read_byte, 3)
1179
def write(self, raw_io):
1180
Ms3dIo.write_array(raw_io, Ms3dIo.write_sbyte, 3, self.bone_ids)
1181
Ms3dIo.write_array(raw_io, Ms3dIo.write_byte, 3, self.weights)
1184
###############################################################################
1185
class Ms3dVertexEx2:
1186
""" Ms3dVertexEx2 """
1196
Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
1197
Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
1198
Ms3dSpec.DEFAULT_VERTEX_BONE_ID),
1199
default_weights=(100, 0, 0),
1202
self._bone_ids = default_bone_ids
1203
self._weights = default_weights
1204
self.extra = default_extra
1207
return "\n<bone_ids={}, weights={}, extra={}>".format(
1216
return self._bone_ids
1220
return self._weights
1224
def weight_bone_id(self):
1225
if self._weights[0] or self._weights[1] or self._weights[2]:
1226
return self._weights
1230
def weight_bone_id0(self):
1231
if self._weights[0] or self._weights[1] or self._weights[2]:
1232
return self._weights[0]
1236
def weight_bone_id1(self):
1237
if self._weights[0] or self._weights[1] or self._weights[2]:
1238
return self._weights[1]
1242
def weight_bone_id2(self):
1243
if self._weights[0] or self._weights[1] or self._weights[2]:
1244
return 100 - (self._weights[0] + self._weights[1] \
1249
def read(self, raw_io):
1250
self._bone_ids = Ms3dIo.read_array(raw_io, Ms3dIo.read_sbyte, 3)
1251
self._weights = Ms3dIo.read_array(raw_io, Ms3dIo.read_byte, 3)
1252
self.extra = Ms3dIo.read_dword(raw_io)
1255
def write(self, raw_io):
1256
Ms3dIo.write_array(raw_io, Ms3dIo.write_sbyte, 3, self.bone_ids)
1257
Ms3dIo.write_array(raw_io, Ms3dIo.write_byte, 3, self.weights)
1258
Ms3dIo.write_dword(raw_io, self.extra)
1261
###############################################################################
1262
class Ms3dVertexEx3:
1263
""" Ms3dVertexEx3 """
1264
#char bone_ids[3]; // index of joint or -1, if -1, then that weight is
1265
# ignored, since subVersion 1
1266
#byte weights[3]; // vertex weight ranging from 0 - 100, last weight is
1267
# computed by 1.0 - sum(all weights), since subVersion 1
1268
#// weight[0] is the weight for bone_id in Ms3dVertex
1269
#// weight[1] is the weight for bone_ids[0]
1270
#// weight[2] is the weight for bone_ids[1]
1271
#// 1.0f - weight[0] - weight[1] - weight[2] is the weight for bone_ids[2]
1272
#unsigned int extra; // vertex extra, which can be used as color or
1273
# anything else, since subVersion 2
1283
Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
1284
Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
1285
Ms3dSpec.DEFAULT_VERTEX_BONE_ID),
1286
default_weights=(100, 0, 0),
1289
self._bone_ids = default_bone_ids
1290
self._weights = default_weights
1291
self.extra = default_extra
1294
return "\n<bone_ids={}, weights={}, extra={}>".format(
1303
return self._bone_ids
1307
return self._weights
1311
def weight_bone_id(self):
1312
if self._weights[0] or self._weights[1] or self._weights[2]:
1313
return self._weights
1317
def weight_bone_id0(self):
1318
if self._weights[0] or self._weights[1] or self._weights[2]:
1319
return self._weights[0]
1323
def weight_bone_id1(self):
1324
if self._weights[0] or self._weights[1] or self._weights[2]:
1325
return self._weights[1]
1329
def weight_bone_id2(self):
1330
if self._weights[0] or self._weights[1] or self._weights[2]:
1331
return 100 - (self._weights[0] + self._weights[1] \
1336
def read(self, raw_io):
1337
self._bone_ids = Ms3dIo.read_array(raw_io, Ms3dIo.read_sbyte, 3)
1338
self._weights = Ms3dIo.read_array(raw_io, Ms3dIo.read_byte, 3)
1339
self.extra = Ms3dIo.read_dword(raw_io)
1342
def write(self, raw_io):
1343
Ms3dIo.write_array(raw_io, Ms3dIo.write_sbyte, 3, self.bone_ids)
1344
Ms3dIo.write_array(raw_io, Ms3dIo.write_byte, 3, self.weights)
1345
Ms3dIo.write_dword(raw_io, self.extra)
1348
###############################################################################
1357
default_color=Ms3dSpec.DEFAULT_JOINT_COLOR
1359
self._color = default_color
1362
return "\n<color=({:.{p}f}, {:.{p}f}, {:.{p}f})>".format(
1375
def read(self, raw_io):
1376
self._color = Ms3dIo.read_array(raw_io, Ms3dIo.read_float, 3)
1379
def write(self, raw_io):
1380
Ms3dIo.write_array(raw_io, Ms3dIo.write_float, 3, self.color)
1383
###############################################################################
1388
'transparency_mode',
1394
default_joint_size=Ms3dSpec.DEFAULT_MODEL_JOINT_SIZE,
1395
default_transparency_mode\
1396
=Ms3dSpec.DEFAULT_MODEL_TRANSPARENCY_MODE,
1397
default_alpha_ref=0.0
1399
self.joint_size = default_joint_size
1400
self.transparency_mode = default_transparency_mode
1401
self.alpha_ref = default_alpha_ref
1404
return "\n<joint_size={:.{p}f}, transparency_mode={}, alpha_ref={:.{p}f}>".format(
1406
self.transparency_mode,
1411
def read(self, raw_io):
1412
self.joint_size = Ms3dIo.read_float(raw_io)
1413
self.transparency_mode = Ms3dIo.read_dword(raw_io)
1414
self.alpha_ref = Ms3dIo.read_float(raw_io)
1417
def write(self, raw_io):
1418
Ms3dIo.write_float(raw_io, self.joint_size)
1419
Ms3dIo.write_dword(raw_io, self.transparency_mode)
1420
Ms3dIo.write_float(raw_io, self.alpha_ref)
1423
###############################################################################
1427
###############################################################################
1434
'number_total_frames',
1435
'sub_version_comments',
1436
'sub_version_vertex_extra',
1437
'sub_version_joint_extra',
1438
'sub_version_model_extra',
1445
'_has_model_comment',
1446
'_comment_object', # Ms3dComment
1447
'_model_ex_object', # Ms3dModelEx
1454
if (default_name is None):
1457
self.name = default_name
1459
self.animation_fps = Ms3dSpec.DEFAULT_MODEL_ANIMATION_FPS
1460
self.current_time = 0.0
1461
self.number_total_frames = 0
1462
self.sub_version_comments \
1463
= Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_COMMENTS
1464
self.sub_version_vertex_extra \
1465
= Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_VERTEX_EXTRA
1466
self.sub_version_joint_extra \
1467
= Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_JOINT_EXTRA
1468
self.sub_version_model_extra \
1469
= Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_MODEL_EXTRA
1471
self._vertices = [] #Ms3dVertex()
1472
self._triangles = [] #Ms3dTriangle()
1473
self._groups = [] #Ms3dGroup()
1474
self._materials = [] #Ms3dMaterial()
1475
self._joints = [] #Ms3dJoint()
1477
self.header = Ms3dHeader()
1478
self._model_ex_object = Ms3dModelEx()
1479
self._comment_object = None #Ms3dComment()
1483
def number_vertices(self):
1484
if self.vertices is None:
1486
return len(self.vertices)
1490
return self._vertices
1494
def number_triangles(self):
1495
if self.triangles is None:
1497
return len(self.triangles)
1500
def triangles(self):
1501
return self._triangles
1505
def number_groups(self):
1506
if self.groups is None:
1508
return len(self.groups)
1516
def number_materials(self):
1517
if self.materials is None:
1519
return len(self.materials)
1522
def materials(self):
1523
return self._materials
1527
def number_joints(self):
1528
if self.joints is None:
1530
return len(self.joints)
1538
def number_group_comments(self):
1539
if self.groups is None:
1542
for item in self.groups:
1543
if item.comment_object is not None and item.comment_object.comment:
1548
def group_comments(self):
1549
if self.groups is None:
1552
for item in self.groups:
1553
if item.comment_object is not None and item.comment_object.comment:
1559
def number_material_comments(self):
1560
if self.materials is None:
1563
for item in self.materials:
1564
if item.comment_object is not None and item.comment_object.comment:
1569
def material_comments(self):
1570
if self.materials is None:
1573
for item in self.materials:
1574
if item.comment_object is not None and item.comment_object.comment:
1580
def number_joint_comments(self):
1581
if self.joints is None:
1584
for item in self.joints:
1585
if item.comment_object is not None and item.comment_object.comment:
1590
def joint_comments(self):
1591
if self.joints is None:
1594
for item in self.joints:
1595
if item.comment_object is not None and item.comment_object.comment:
1601
def has_model_comment(self):
1602
if self.comment_object is not None and self.comment_object.comment:
1607
def comment_object(self):
1608
return self._comment_object
1612
def vertex_ex(self):
1613
if not self.sub_version_vertex_extra:
1615
return [item.vertex_ex_object for item in self.vertices]
1619
if not self.sub_version_joint_extra:
1621
return [item.joint_ex_object for item in self.joints]
1624
def model_ex_object(self):
1625
if not self.sub_version_model_extra:
1627
return self._model_ex_object
1630
def print_internal(self):
1632
print("##############################################################")
1633
print("## the internal data of Ms3dModel object...")
1636
print("header={}".format(self.header))
1638
print("number_vertices={}".format(self.number_vertices))
1639
print("vertices=[", end="")
1641
for obj in self.vertices:
1642
print("{}".format(obj), end="")
1645
print("number_triangles={}".format(self.number_triangles))
1646
print("triangles=[", end="")
1648
for obj in self.triangles:
1649
print("{}".format(obj), end="")
1652
print("number_groups={}".format(self.number_groups))
1653
print("groups=[", end="")
1655
for obj in self.groups:
1656
print("{}".format(obj), end="")
1659
print("number_materials={}".format(self.number_materials))
1660
print("materials=[", end="")
1662
for obj in self.materials:
1663
print("{}".format(obj), end="")
1666
print("animation_fps={}".format(self.animation_fps))
1667
print("current_time={}".format(self.current_time))
1668
print("number_total_frames={}".format(self.number_total_frames))
1670
print("number_joints={}".format(self.number_joints))
1671
print("joints=[", end="")
1673
for obj in self.joints:
1674
print("{}".format(obj), end="")
1677
print("sub_version_comments={}".format(self.sub_version_comments))
1679
print("number_group_comments={}".format(self.number_group_comments))
1680
print("group_comments=[", end="")
1681
if self.group_comments:
1682
for obj in self.group_comments:
1683
print("{}".format(obj.comment_object), end="")
1686
print("number_material_comments={}".format(
1687
self.number_material_comments))
1688
print("material_comments=[", end="")
1689
if self.material_comments:
1690
for obj in self.material_comments:
1691
print("{}".format(obj.comment_object), end="")
1694
print("number_joint_comments={}".format(self.number_joint_comments))
1695
print("joint_comments=[", end="")
1696
if self.joint_comments:
1697
for obj in self.joint_comments:
1698
print("{}".format(obj.comment_object), end="")
1701
print("has_model_comment={}".format(self.has_model_comment))
1702
print("model_comment={}".format(self.comment_object))
1704
print("sub_version_vertex_extra={}".format(
1705
self.sub_version_vertex_extra))
1706
print("vertex_ex=[", end="")
1708
for obj in self.vertex_ex:
1709
print("{}".format(obj), end="")
1712
print("sub_version_joint_extra={}".format(
1713
self.sub_version_joint_extra))
1714
print("joint_ex=[", end="")
1716
for obj in self.joint_ex:
1717
print("{}".format(obj), end="")
1720
print("sub_version_model_extra={}".format(
1721
self.sub_version_model_extra))
1722
print("model_ex={}".format(self.model_ex_object))
1726
print("##############################################################")
1730
def read(self, raw_io):
1732
opens, reads and pars MS3D file.
1733
add content to blender scene
1736
self.header.read(raw_io)
1737
if (self.header != Ms3dHeader()):
1738
print("\nwarning, invalid file header")
1740
_number_vertices = Ms3dIo.read_word(raw_io)
1741
if (_number_vertices > Ms3dSpec.MAX_VERTICES):
1742
print("\nwarning, invalid count: number_vertices: {}".format(
1745
for i in range(_number_vertices):
1746
self.vertices.append(Ms3dVertex().read(raw_io))
1748
_number_triangles = Ms3dIo.read_word(raw_io)
1749
if (_number_triangles > Ms3dSpec.MAX_TRIANGLES):
1750
print("\nwarning, invalid count: number_triangles: {}".format(
1752
self._triangles = []
1753
for i in range(_number_triangles):
1754
self.triangles.append(Ms3dTriangle().read(raw_io))
1756
_number_groups = Ms3dIo.read_word(raw_io)
1757
if (_number_groups > Ms3dSpec.MAX_GROUPS):
1758
print("\nwarning, invalid count: number_groups: {}".format(
1761
for i in range(_number_groups):
1762
self.groups.append(Ms3dGroup().read(raw_io))
1764
_number_materials = Ms3dIo.read_word(raw_io)
1765
if (_number_materials > Ms3dSpec.MAX_MATERIALS):
1766
print("\nwarning, invalid count: number_materials: {}".format(
1768
self._materials = []
1769
for i in range(_number_materials):
1770
self.materials.append(Ms3dMaterial().read(raw_io))
1772
self.animation_fps = Ms3dIo.read_float(raw_io)
1773
self.current_time = Ms3dIo.read_float(raw_io)
1774
self.number_total_frames = Ms3dIo.read_dword(raw_io)
1780
# doesn't matter if doesn't existing.
1782
_number_joints = Ms3dIo.read_word(raw_io)
1783
_progress.add('NUMBER_JOINTS')
1784
if (_number_joints > Ms3dSpec.MAX_JOINTS):
1785
print("\nwarning, invalid count: number_joints: {}".format(
1788
for i in range(_number_joints):
1789
self.joints.append(Ms3dJoint().read(raw_io))
1790
_progress.add('JOINTS')
1792
self.sub_version_comments = Ms3dIo.read_dword(raw_io)
1793
_progress.add('SUB_VERSION_COMMENTS')
1794
_number_group_comments = Ms3dIo.read_dword(raw_io)
1795
_progress.add('NUMBER_GROUP_COMMENTS')
1796
if (_number_group_comments > Ms3dSpec.MAX_GROUPS):
1797
print("\nwarning, invalid count:"\
1798
" number_group_comments: {}".format(
1799
_number_group_comments))
1800
if _number_group_comments > _number_groups:
1801
print("\nwarning, invalid count:"\
1802
" number_group_comments: {}, number_groups: {}".format(
1803
_number_group_comments, _number_groups))
1804
for i in range(_number_group_comments):
1805
item = Ms3dCommentEx().read(raw_io)
1806
if item.index >= 0 and item.index < _number_groups:
1807
self.groups[item.index]._comment_object = item
1809
print("\nwarning, invalid index:"\
1810
" group_index: {}, number_groups: {}".format(
1811
item.index, _number_groups))
1812
_progress.add('GROUP_COMMENTS')
1814
_number_material_comments = Ms3dIo.read_dword(raw_io)
1815
_progress.add('NUMBER_MATERIAL_COMMENTS')
1816
if (_number_material_comments > Ms3dSpec.MAX_MATERIALS):
1817
print("\nwarning, invalid count:"\
1818
" number_material_comments: {}".format(
1819
_number_material_comments))
1820
if _number_material_comments > _number_materials:
1821
print("\nwarning, invalid count:"\
1822
" number_material_comments:"\
1823
" {}, number_materials: {}".format(
1824
_number_material_comments, _number_materials))
1825
for i in range(_number_material_comments):
1826
item = Ms3dCommentEx().read(raw_io)
1827
if item.index >= 0 and item.index < _number_materials:
1828
self.materials[item.index]._comment_object = item
1830
print("\nwarning, invalid index:"\
1831
" material_index: {}, number_materials:"\
1832
" {}".format(item.index, _number_materials))
1833
_progress.add('MATERIAL_COMMENTS')
1835
_number_joint_comments = Ms3dIo.read_dword(raw_io)
1836
_progress.add('NUMBER_JOINT_COMMENTS')
1837
if (_number_joint_comments > Ms3dSpec.MAX_JOINTS):
1838
print("\nwarning, invalid count:"\
1839
" number_joint_comments: {}".format(
1840
_number_joint_comments))
1841
if _number_joint_comments > _number_joints:
1842
print("\nwarning, invalid count:"\
1843
" number_joint_comments: {}, number_joints: {}".format(
1844
_number_joint_comments, _number_joints))
1845
for i in range(_number_joint_comments):
1846
item = Ms3dCommentEx().read(raw_io)
1847
if item.index >= 0 and item.index < _number_joints:
1848
self.joints[item.index]._comment_object = item
1850
print("\nwarning, invalid index:"\
1851
" joint_index: {}, number_joints: {}".format(
1852
item.index, _number_joints))
1853
_progress.add('JOINT_COMMENTS')
1855
_has_model_comment = Ms3dIo.read_dword(raw_io)
1856
_progress.add('HAS_MODEL_COMMENTS')
1857
if (_has_model_comment != 0):
1858
self._comment_object = Ms3dComment().read(raw_io)
1860
self._comment_object = None
1861
_progress.add('MODEL_COMMENTS')
1863
self.sub_version_vertex_extra = Ms3dIo.read_dword(raw_io)
1864
_progress.add('SUB_VERSION_VERTEX_EXTRA')
1865
if self.sub_version_vertex_extra > 0:
1866
length = len(self.joints)
1867
for i in range(_number_vertices):
1868
if self.sub_version_vertex_extra == 1:
1869
item = Ms3dVertexEx1()
1870
elif self.sub_version_vertex_extra == 2:
1871
item = Ms3dVertexEx2()
1872
elif self.sub_version_vertex_extra == 3:
1873
item = Ms3dVertexEx3()
1875
print("\nwarning, invalid version:"\
1876
" sub_version_vertex_extra: {}".format(
1877
sub_version_vertex_extra))
1879
self.vertices[i]._vertex_ex_object = item.read(raw_io)
1880
_progress.add('VERTEX_EXTRA')
1882
self.sub_version_joint_extra = Ms3dIo.read_dword(raw_io)
1883
_progress.add('SUB_VERSION_JOINT_EXTRA')
1884
if self.sub_version_joint_extra > 0:
1885
for i in range(_number_joints):
1886
self.joints[i]._joint_ex_object = Ms3dJointEx().read(raw_io)
1887
_progress.add('JOINT_EXTRA')
1889
self.sub_version_model_extra = Ms3dIo.read_dword(raw_io)
1890
_progress.add('SUB_VERSION_MODEL_EXTRA')
1891
if self.sub_version_model_extra > 0:
1892
self._model_ex_object.read(raw_io)
1893
_progress.add('MODEL_EXTRA')
1896
# reached end of optional data.
1897
print("Ms3dModel.read - optional data read: {}".format(_progress))
1901
type, value, traceback = exc_info()
1902
print("Ms3dModel.read - exception in optional try block,"
1903
" _progress={0}\n type: '{1}'\n value: '{2}'".format(
1904
_progress, type, value, traceback))
1909
# try best to continue far as possible
1910
if not 'JOINTS' in _progress:
1914
if not 'GROUP_COMMENTS' in _progress:
1915
self.sub_version_comments = 0
1916
_number_group_comments = 0
1918
if not 'MATERIAL_COMMENTS' in _progress:
1919
_number_material_comments = 0
1921
if not 'JOINT_COMMENTS' in _progress:
1922
_number_joint_comments = 0
1924
if not 'MODEL_COMMENTS' in _progress:
1925
_has_model_comment = 0
1926
self._comment_object = None # Ms3dComment()
1928
if not 'VERTEX_EXTRA' in _progress:
1929
self.sub_version_vertex_extra = 0
1931
if not 'JOINT_EXTRA' in _progress:
1932
self.sub_version_joint_extra = 0
1934
if not 'MODEL_EXTRA' in _progress:
1935
self.sub_version_model_extra = 0
1936
self._model_ex_object = Ms3dModelEx()
1941
def write(self, raw_io):
1943
add blender scene content to MS3D
1944
creates, writes MS3D file.
1947
self.header.write(raw_io)
1949
Ms3dIo.write_word(raw_io, self.number_vertices)
1950
for i in range(self.number_vertices):
1951
self.vertices[i].write(raw_io)
1953
Ms3dIo.write_word(raw_io, self.number_triangles)
1954
for i in range(self.number_triangles):
1955
self.triangles[i].write(raw_io)
1957
Ms3dIo.write_word(raw_io, self.number_groups)
1958
for i in range(self.number_groups):
1959
self.groups[i].write(raw_io)
1961
Ms3dIo.write_word(raw_io, self.number_materials)
1962
for i in range(self.number_materials):
1963
self.materials[i].write(raw_io)
1965
Ms3dIo.write_float(raw_io, self.animation_fps)
1966
Ms3dIo.write_float(raw_io, self.current_time)
1967
Ms3dIo.write_dword(raw_io, self.number_total_frames)
1971
# doesn't matter if it doesn't complete.
1972
Ms3dIo.write_word(raw_io, self.number_joints)
1973
for i in range(self.number_joints):
1974
self.joints[i].write(raw_io)
1976
Ms3dIo.write_dword(raw_io, self.sub_version_comments)
1978
Ms3dIo.write_dword(raw_io, self.number_group_comments)
1979
for i in range(self.number_group_comments):
1980
self.group_comments[i].comment_object.write(raw_io)
1982
Ms3dIo.write_dword(raw_io, self.number_material_comments)
1983
for i in range(self.number_material_comments):
1984
self.material_comments[i].comment_object.write(raw_io)
1986
Ms3dIo.write_dword(raw_io, self.number_joint_comments)
1987
for i in range(self.number_joint_comments):
1988
self.joint_comments[i].comment_object.write(raw_io)
1990
Ms3dIo.write_dword(raw_io, self.has_model_comment)
1991
if (self.has_model_comment != 0):
1992
self.comment_object.write(raw_io)
1994
Ms3dIo.write_dword(raw_io, self.sub_version_vertex_extra)
1995
if (self.sub_version_vertex_extra in {1, 2, 3}):
1996
for i in range(self.number_vertices):
1997
self.vertex_ex[i].write(raw_io)
1999
Ms3dIo.write_dword(raw_io, self.sub_version_joint_extra)
2000
for i in range(self.number_joints):
2001
self.joint_ex[i].write(raw_io)
2003
Ms3dIo.write_dword(raw_io, self.sub_version_model_extra)
2004
self.model_ex_object.write(raw_io)
2007
type, value, traceback = exc_info()
2008
print("Ms3dModel.write - exception in optional try block"
2009
"\n type: '{0}'\n value: '{1}'".format(
2010
type, value, traceback))
2023
format1 = "\n number of {0}: {1}"
2024
format2 = " limit exceeded! (limit is {0})"
2026
result.append("MS3D statistics:")
2027
result.append(format1.format("vertices ........",
2028
self.number_vertices))
2029
if (self.number_vertices > Ms3dSpec.MAX_VERTICES):
2030
result.append(format2.format(Ms3dSpec.MAX_VERTICES))
2033
result.append(format1.format("triangles .......",
2034
self.number_triangles))
2035
if (self.number_triangles > Ms3dSpec.MAX_TRIANGLES):
2036
result.append(format2.format(Ms3dSpec.MAX_TRIANGLES))
2039
result.append(format1.format("groups ..........",
2040
self.number_groups))
2041
if (self.number_groups > Ms3dSpec.MAX_GROUPS):
2042
result.append(format2.format(Ms3dSpec.MAX_GROUPS))
2045
result.append(format1.format("materials .......",
2046
self.number_materials))
2047
if (self.number_materials > Ms3dSpec.MAX_MATERIALS):
2048
result.append(format2.format(Ms3dSpec.MAX_MATERIALS))
2051
result.append(format1.format("joints ..........",
2052
self.number_joints))
2053
if (self.number_joints > Ms3dSpec.MAX_JOINTS):
2054
result.append(format2.format(Ms3dSpec.MAX_JOINTS))
2057
result.append(format1.format("model comments ..",
2058
self.has_model_comment))
2059
result.append(format1.format("group comments ..",
2060
self.number_group_comments))
2061
result.append(format1.format("material comments",
2062
self.number_material_comments))
2063
result.append(format1.format("joint comments ..",
2064
self.number_joint_comments))
2067
# result.append("\n\nthe data may be corrupted.")
2069
return (valid, ("".join(result)))
2072
###############################################################################
2073
#234567890123456789012345678901234567890123456789012345678901234567890123456789
2074
#--------1---------2---------3---------4---------5---------6---------7---------
2075
# ##### END OF FILE #####