Fix Print3D Toolbox: fix button alignment
[blender-addons.git] / io_import_scene_unreal_psa_psk.py
blob64f0e6d0dc5f799faf24a192f40e92ca0c841311
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 #####
19 bl_info = {
20 "name": "Import Unreal Skeleton Mesh (.psk)/Animation Set (psa)",
21 "author": "Darknet, flufy3d, camg188",
22 "version": (2, 2),
23 "blender": (2, 64, 0),
24 "location": "File > Import > Skeleton Mesh (.psk)/Animation Set (psa)",
25 "description": "Import Skeleleton Mesh/Animation Data",
26 "warning": "",
27 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
28 "Scripts/Import-Export/Unreal_psk_psa",
29 "tracker_url": "https://projects.blender.org/tracker/index.php?"\
30 "func=detail&aid=21366",
31 "category": "Import-Export"}
33 """
34 Version': '2.0' ported by Darknet
36 Unreal Tournament PSK file to Blender mesh converter V1.0
37 Author: D.M. Sturgeon (camg188 at the elYsium forum), ported by Darknet
38 Imports a *psk file to a new mesh
40 -No UV Texutre
41 -No Weight
42 -No Armature Bones
43 -No Material ID
44 -Export Text Log From Current Location File (Bool )
45 """
47 import bpy
48 import mathutils
49 import math
50 # XXX Yuck! 'from foo import *' is really bad!
51 from mathutils import *
52 from math import *
53 from bpy.props import *
54 from string import *
55 from struct import *
56 from math import *
57 from bpy.props import *
59 bpy.types.Scene.unrealbonesize = FloatProperty(
60 name="Bone Length",
61 description="Bone Length from head to tail distance",
62 default=1, min=0.001, max=1000
65 #output log in to txt file
66 DEBUGLOG = False
68 scale = 1.0
69 bonesize = 1.0
70 from bpy_extras.io_utils import unpack_list, unpack_face_list
72 class md5_bone:
73 bone_index = 0
74 name = ""
75 bindpos = []
76 bindmat = []
77 origmat = []
78 head = []
79 tail = []
80 scale = []
81 parent = ""
82 parent_index = 0
83 blenderbone = None
84 roll = 0
86 def __init__(self):
87 self.bone_index = 0
88 self.name = ""
89 self.bindpos = [0.0] * 3
90 self.scale = [0.0] * 3
91 self.head = [0.0] * 3
92 self.tail = [0.0] * 3
93 self.bindmat = [None] * 3 # is this how you initilize a 2d-array
94 for i in range(3):
95 self.bindmat[i] = [0.0] * 3
96 self.origmat = [None] * 3 #is this how you initilize a 2d-array
97 for i in range(3):
98 self.origmat[i] = [0.0] * 3
99 self.parent = ""
100 self.parent_index = 0
101 self.blenderbone = None
103 def dump(self):
104 print ("bone index: ", self.bone_index)
105 print ("name: ", self.name)
106 print ("bind position: ", self.bindpos)
107 print ("bind translation matrix: ", self.bindmat)
108 print ("parent: ", self.parent)
109 print ("parent index: ", self.parent_index)
110 print ("blenderbone: ", self.blenderbone)
112 def getheadpos(pbone,bones):
113 pos_head = [0.0] * 3
115 #pos = mathutils.Vector((x,y,z)) * pbone.origmat
116 pos = pbone.bindmat.to_translation()
119 tmp_bone = pbone
120 while tmp_bone.name != tmp_bone.parent.name:
121 pos = pos * tmp_bone.parent.bindmat
122 tmp_bone = tmp_bone.parent
125 pos_head[0] = pos.x
126 pos_head[1] = pos.y
127 pos_head[2] = pos.z
129 return pos_head
131 def gettailpos(pbone,bones):
132 pos_tail = [0.0] * 3
133 ischildfound = False
134 childbone = None
135 childbonelist = []
136 for bone in bones:
137 if bone.parent.name == pbone.name:
138 ischildfound = True
139 childbone = bone
140 childbonelist.append(bone)
142 if ischildfound:
143 tmp_head = [0.0] * 3
144 for bone in childbonelist:
145 tmp_head[0] += bone.head[0]
146 tmp_head[1] += bone.head[1]
147 tmp_head[2] += bone.head[2]
148 tmp_head[0] /= len(childbonelist)
149 tmp_head[1] /= len(childbonelist)
150 tmp_head[2] /= len(childbonelist)
151 return tmp_head
152 else:
153 tmp_len = 0.0
154 tmp_len += (pbone.head[0] - pbone.parent.head[0]) ** 2
155 tmp_len += (pbone.head[1] - pbone.parent.head[1]) ** 2
156 tmp_len += (pbone.head[2] - pbone.parent.head[2]) ** 2
157 tmp_len = tmp_len ** 0.5 * 0.5
158 pos_tail[0] = pbone.head[0] + tmp_len * pbone.bindmat[0][0]
159 pos_tail[1] = pbone.head[1] + tmp_len * pbone.bindmat[1][0]
160 pos_tail[2] = pbone.head[2] + tmp_len * pbone.bindmat[2][0]
162 return pos_tail
164 def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
165 global DEBUGLOG
166 DEBUGLOG = bDebugLogPSK
167 print ("--------------------------------------------------")
168 print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
169 print ("--------------------------------------------------")
170 print (" DEBUG Log:",bDebugLogPSK)
171 print ("Importing file: ", infile)
173 pskfile = open(infile,'rb')
174 if (DEBUGLOG):
175 logpath = infile.replace(".psk", ".txt")
176 print("logpath:",logpath)
177 logf = open(logpath,'w')
179 def printlog(strdata):
180 if (DEBUGLOG):
181 logf.write(strdata)
183 objName = infile.split('\\')[-1].split('.')[0]
185 me_ob = bpy.data.meshes.new(objName)
186 print("objName:",objName)
187 printlog(("New Mesh = " + me_ob.name + "\n"))
188 #read general header
189 indata = unpack('20s3i', pskfile.read(32))
190 #not using the general header at this time
191 #==================================================================================================
192 # vertex point
193 #==================================================================================================
194 #read the PNTS0000 header
195 indata = unpack('20s3i', pskfile.read(32))
196 recCount = indata[3]
197 printlog(("Nbr of PNTS0000 records: " + str(recCount) + "\n"))
198 counter = 0
199 verts = []
200 verts2 = []
201 while counter < recCount:
202 counter = counter + 1
203 indata = unpack('3f', pskfile.read(12))
204 #print(indata[0], indata[1], indata[2])
205 verts.extend([(indata[0], indata[1], indata[2])])
206 verts2.extend([(indata[0], indata[1], indata[2])])
207 #print([(indata[0], indata[1], indata[2])])
208 printlog(str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) + "\n")
209 #Tmsh.vertices.append(NMesh.Vert(indata[0], indata[1], indata[2]))
211 #==================================================================================================
212 # UV
213 #==================================================================================================
214 #read the VTXW0000 header
215 indata = unpack('20s3i', pskfile.read(32))
216 recCount = indata[3]
217 printlog("Nbr of VTXW0000 records: " + str(recCount)+ "\n")
218 counter = 0
219 UVCoords = []
220 #UVCoords record format = [index to PNTS, U coord, v coord]
221 printlog("[index to PNTS, U coord, v coord]\n");
222 while counter < recCount:
223 counter = counter + 1
224 indata = unpack('hhffhh', pskfile.read(16))
225 UVCoords.append([indata[0], indata[2], indata[3]])
226 printlog(str(indata[0]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "\n")
227 #print('mat index %i', indata(4))
228 #print([indata[0], indata[2], indata[3]])
229 #print([indata[1], indata[2], indata[3]])
231 #==================================================================================================
232 # Face
233 #==================================================================================================
234 #read the FACE0000 header
235 indata = unpack('20s3i', pskfile.read(32))
236 recCount = indata[3]
237 printlog("Nbr of FACE0000 records: " + str(recCount) + "\n")
238 #PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
239 #associate MatIdx to an image, associate SmthGrp to a material
240 SGlist = []
241 counter = 0
242 faces = []
243 faceuv = []
244 facesmooth = []
245 #the psk values are: nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
246 printlog("nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp \n")
247 while counter < recCount:
248 counter = counter + 1
249 indata = unpack('hhhbbi', pskfile.read(12))
250 printlog(str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "|" +
251 str(indata[4]) + "|" + str(indata[5]) + "\n")
252 #indata[0] = index of UVCoords
253 #UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
254 #UVCoords[indata[0]][0] = index to PNTS
255 PNTSA = UVCoords[indata[2]][0]
256 PNTSB = UVCoords[indata[1]][0]
257 PNTSC = UVCoords[indata[0]][0]
258 #print(PNTSA, PNTSB, PNTSC) #face id vertex
259 #faces.extend([0, 1, 2, 0])
260 faces.extend([(PNTSA, PNTSB, PNTSC, 0)])
261 uv = []
262 u0 = UVCoords[indata[2]][1]
263 v0 = UVCoords[indata[2]][2]
264 uv.append([u0, 1.0 - v0])
265 u1 = UVCoords[indata[1]][1]
266 v1 = UVCoords[indata[1]][2]
267 uv.append([u1, 1.0 - v1])
268 u2 = UVCoords[indata[0]][1]
269 v2 = UVCoords[indata[0]][2]
270 uv.append([u2, 1.0 - v2])
271 faceuv.append([uv, indata[3], indata[4], indata[5]])
273 #print("material:", indata[3])
274 #print("UV: ", u0, v0)
275 #update the uv var of the last item in the Tmsh.faces list
276 # which is the face just added above
277 ##Tmsh.faces[-1].uv = [(u0, v0), (u1, v1), (u2, v2)]
278 #print("smooth:",indata[5])
279 #collect a list of the smoothing groups
280 facesmooth.append(indata[5])
281 #print(indata[5])
282 if SGlist.count(indata[5]) == 0:
283 SGlist.append(indata[5])
284 print("smooth:", indata[5])
285 #assign a material index to the face
286 #Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
287 printlog("Using Materials to represent PSK Smoothing Groups...\n")
288 #==========
289 # skip something...
290 #==========
292 #==================================================================================================
293 # Material
294 #==================================================================================================
296 #read the MATT0000 header
297 indata = unpack('20s3i', pskfile.read(32))
298 recCount = indata[3]
299 printlog("Nbr of MATT0000 records: " + str(recCount) + "\n" )
300 printlog(" - Not importing any material data now. PSKs are texture wrapped! \n")
301 counter = 0
302 materialcount = 0
303 while counter < recCount:
304 counter = counter + 1
305 indata = unpack('64s6i', pskfile.read(88))
306 materialcount += 1
307 print("Material", counter)
308 print("Mat name %s", indata[0])
311 #==================================================================================================
312 # Bones (Armature)
313 #==================================================================================================
314 #read the REFSKEL0 header
315 indata = unpack('20s3i', pskfile.read(32))
316 recCount = indata[3]
317 printlog( "Nbr of REFSKEL0 records: " + str(recCount) + "\n")
318 #REFSKEL0 fields - Name|Flgs|NumChld|PrntIdx|Qw|Qx|Qy|Qz|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize
320 Bns = []
321 bone = []
323 md5_bones = []
324 bni_dict = {}
325 #==================================================================================================
326 # Bone Data
327 #==================================================================================================
328 counter = 0
329 print ("---PRASE--BONES---")
330 printlog("Name|Flgs|NumChld|PrntIdx|Qx|Qy|Qz|Qw|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize\n")
331 while counter < recCount:
332 indata = unpack('64s3i11f', pskfile.read(120))
333 #print( "DATA",str(indata))
335 bone.append(indata)
337 createbone = md5_bone()
338 #temp_name = indata[0][:30]
339 temp_name = indata[0]
340 temp_name = bytes.decode(temp_name)
341 temp_name = temp_name.lstrip(" ")
342 temp_name = temp_name.rstrip(" ")
343 temp_name = temp_name.strip()
344 temp_name = temp_name.strip( bytes.decode(b'\x00'))
345 printlog(temp_name + "|" + str(indata[1]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "|" +
346 str(indata[4]) + "|" + str(indata[5]) + "|" + str(indata[6]) + "|" + str(indata[7]) + "|" +
347 str(indata[8]) + "|" + str(indata[9]) + "|" + str(indata[10]) + "|" + str(indata[11]) + "|" +
348 str(indata[12]) + "|" + str(indata[13]) + "|" + str(indata[14]) + "\n")
349 createbone.name = temp_name
350 createbone.bone_index = counter
351 createbone.parent_index = indata[3]
352 createbone.bindpos[0] = indata[8]
353 createbone.bindpos[1] = indata[9]
354 createbone.bindpos[2] = indata[10]
355 createbone.scale[0] = indata[12]
356 createbone.scale[1] = indata[13]
357 createbone.scale[2] = indata[14]
359 bni_dict[createbone.name] = createbone.bone_index
361 #w,x,y,z
362 if (counter == 0):#main parent
363 createbone.bindmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
364 createbone.origmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
365 else:
366 createbone.bindmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
367 createbone.origmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
369 createbone.bindmat = mathutils.Matrix.Translation(mathutils.Vector((indata[8], indata[9], indata[10]))) * \
370 createbone.bindmat.to_4x4()
372 md5_bones.append(createbone)
373 counter = counter + 1
374 bnstr = (str(indata[0]))
375 Bns.append(bnstr)
377 for pbone in md5_bones:
378 pbone.parent = md5_bones[pbone.parent_index]
380 for pbone in md5_bones:
381 if pbone.name != pbone.parent.name:
382 pbone.bindmat = pbone.parent.bindmat * pbone.bindmat
383 #print(pbone.name)
384 #print(pbone.bindmat)
385 #print("end")
386 else:
387 pbone.bindmat = pbone.bindmat
389 for pbone in md5_bones:
390 pbone.head = getheadpos(pbone, md5_bones)
392 for pbone in md5_bones:
393 pbone.tail = gettailpos(pbone, md5_bones)
395 for pbone in md5_bones:
396 pbone.parent = md5_bones[pbone.parent_index].name
398 bonecount = 0
399 for armbone in bone:
400 temp_name = armbone[0][:30]
401 #print ("BONE NAME: ", len(temp_name))
402 temp_name=str((temp_name))
403 #temp_name = temp_name[1]
404 #print ("BONE NAME: ", temp_name)
405 bonecount += 1
406 print ("-------------------------")
407 print ("----Creating--Armature---")
408 print ("-------------------------")
410 #================================================================================================
411 #Check armature if exist if so create or update or remove all and addnew bone
412 #================================================================================================
413 #bpy.ops.object.mode_set(mode='OBJECT')
414 meshname ="ArmObject"
415 objectname = "armaturedata"
416 # arm = None # UNUSED
417 if importbone:
418 obj = bpy.data.objects.get(meshname)
419 # arm = obj # UNUSED
421 if not obj:
422 armdata = bpy.data.armatures.new(objectname)
423 ob_new = bpy.data.objects.new(meshname, armdata)
424 #ob_new = bpy.data.objects.new(meshname, 'ARMATURE')
425 #ob_new.data = armdata
426 bpy.context.scene.objects.link(ob_new)
427 #bpy.ops.object.mode_set(mode='OBJECT')
428 for i in bpy.context.scene.objects:
429 i.select = False #deselect all objects
430 ob_new.select = True
431 #set current armature to edit the bone
432 bpy.context.scene.objects.active = ob_new
433 #set mode to able to edit the bone
434 if bpy.ops.object.mode_set.poll():
435 bpy.ops.object.mode_set(mode='EDIT')
437 #newbone = ob_new.data.edit_bones.new('test')
438 #newbone.tail.y = 1
439 print("creating bone(s)")
440 bpy.ops.object.mode_set(mode='OBJECT')
441 for bone in md5_bones:
442 #print(dir(bone))
443 bpy.ops.object.mode_set(mode='EDIT')#Go to edit mode for the bones
444 newbone = ob_new.data.edit_bones.new(bone.name)
445 #parent the bone
446 #print("DRI:", dir(newbone))
447 parentbone = None
448 #note bone location is set in the real space or global not local
449 bonesize = bpy.types.Scene.unrealbonesize
450 if bone.name != bone.parent:
451 pos_x = bone.bindpos[0]
452 pos_y = bone.bindpos[1]
453 pos_z = bone.bindpos[2]
454 #print("LINKING:" , bone.parent ,"j")
455 parentbone = ob_new.data.edit_bones[bone.parent]
456 newbone.parent = parentbone
457 rotmatrix = bone.bindmat
458 newbone.head.x = bone.head[0]
459 newbone.head.y = bone.head[1]
460 newbone.head.z = bone.head[2]
461 newbone.tail.x = bone.tail[0]
462 newbone.tail.y = bone.tail[1]
463 newbone.tail.z = bone.tail[2]
465 vecp = parentbone.tail - parentbone.head
466 vecc = newbone.tail - newbone.head
467 vecc.normalize()
468 vecp.normalize()
469 if vecp.dot(vecc) > -0.8:
470 newbone.roll = parentbone.roll
471 else:
472 newbone.roll = - parentbone.roll
473 else:
474 rotmatrix = bone.bindmat
475 newbone.head.x = bone.head[0]
476 newbone.head.y = bone.head[1]
477 newbone.head.z = bone.head[2]
478 newbone.tail.x = bone.tail[0]
479 newbone.tail.y = bone.tail[1]
480 newbone.tail.z = bone.tail[2]
481 newbone.roll = math.radians(90.0)
483 vec = newbone.tail - newbone.head
484 if vec.z > 0.0:
485 newbone.roll = math.radians(90.0)
486 else:
487 newbone.roll = math.radians(-90.0)
489 bpy.context.scene.update()
491 #==================================================================================================
492 #END BONE DATA BUILD
493 #==================================================================================================
494 VtxCol = []
495 for x in range(len(Bns)):
496 #change the overall darkness of each material in a range between 0.1 and 0.9
497 tmpVal = ((float(x) + 1.0) / (len(Bns)) * 0.7) + 0.1
498 tmpVal = int(tmpVal * 256)
499 tmpCol = [tmpVal, tmpVal, tmpVal, 0]
500 #Change the color of each material slightly
501 if x % 3 == 0:
502 if tmpCol[0] < 128:
503 tmpCol[0] += 60
504 else:
505 tmpCol[0] -= 60
506 if x % 3 == 1:
507 if tmpCol[1] < 128:
508 tmpCol[1] += 60
509 else:
510 tmpCol[1] -= 60
511 if x % 3 == 2:
512 if tmpCol[2] < 128:
513 tmpCol[2] += 60
514 else:
515 tmpCol[2] -= 60
516 #Add the material to the mesh
517 VtxCol.append(tmpCol)
519 #==================================================================================================
520 # Bone Weight
521 #==================================================================================================
522 #read the RAWW0000 header
523 indata = unpack('20s3i', pskfile.read(32))
524 recCount = indata[3]
525 printlog("Nbr of RAWW0000 records: " + str(recCount) +"\n")
526 #RAWW0000 fields: Weight|PntIdx|BoneIdx
527 RWghts = []
528 counter = 0
529 while counter < recCount:
530 counter = counter + 1
531 indata = unpack('fii', pskfile.read(12))
532 RWghts.append([indata[1], indata[2], indata[0]])
533 #print("weight:", [indata[1], indata[2], indata[0]])
534 #RWghts fields = PntIdx|BoneIdx|Weight
535 RWghts.sort()
536 printlog("Vertex point and groups count =" + str(len(RWghts)) + "\n")
537 printlog("PntIdx|BoneIdx|Weight")
538 for vg in RWghts:
539 printlog(str(vg[0]) + "|" + str(vg[1]) + "|" + str(vg[2]) + "\n")
541 #Tmsh.update_tag()
543 #set the Vertex Colors of the faces
544 #face.v[n] = RWghts[0]
545 #RWghts[1] = index of VtxCol
547 for x in range(len(Tmsh.faces)):
548 for y in range(len(Tmsh.faces[x].v)):
549 #find v in RWghts[n][0]
550 findVal = Tmsh.faces[x].v[y].index
551 n = 0
552 while findVal != RWghts[n][0]:
553 n = n + 1
554 TmpCol = VtxCol[RWghts[n][1]]
555 #check if a vertex has more than one influence
556 if n != len(RWghts) - 1:
557 if RWghts[n][0] == RWghts[n + 1][0]:
558 #if there is more than one influence, use the one with the greater influence
559 #for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
560 if RWghts[n][2] < RWghts[n + 1][2]:
561 TmpCol = VtxCol[RWghts[n + 1][1]]
562 Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0], TmpCol[1], TmpCol[2], 0))
564 if (DEBUGLOG):
565 logf.close()
566 #==================================================================================================
567 #Building Mesh
568 #==================================================================================================
569 print("vertex:", len(verts), "faces:", len(faces))
570 print("vertex2:", len(verts2))
571 me_ob.vertices.add(len(verts2))
572 me_ob.tessfaces.add(len(faces))
573 me_ob.vertices.foreach_set("co", unpack_list(verts2))
574 me_ob.tessfaces.foreach_set("vertices_raw", unpack_list( faces))
576 for face in me_ob.tessfaces:
577 face.use_smooth = facesmooth[face.index]
580 Material setup coding.
581 First the mesh has to be create first to get the uv texture setup working.
582 -Create material(s) list in the psk pack data from the list.(to do list)
583 -Append the material to the from create the mesh object.
584 -Create Texture(s)
585 -face loop for uv assign and assign material index
587 bpy.ops.object.mode_set(mode='OBJECT')
588 #===================================================================================================
589 #Material Setup
590 #===================================================================================================
591 print ("-------------------------")
592 print ("----Creating--Materials--")
593 print ("-------------------------")
594 materialname = "pskmat"
595 materials = []
597 for matcount in range(materialcount):
598 #if texturedata != None:
599 matdata = bpy.data.materials.new(materialname + str(matcount))
600 #mtex = matdata.texture_slots.new()
601 #mtex.texture = texture[matcount].data
602 #print(type(texture[matcount].data))
603 #print(dir(mtex))
604 #print(dir(matdata))
605 #for texno in range(len( bpy.data.textures)):
606 #print((bpy.data.textures[texno].name))
607 #print(dir(bpy.data.textures[texno]))
608 #matdata.active_texture = bpy.data.textures[matcount - 1]
609 #matdata.texture_coords = 'UV'
610 #matdata.active_texture = texturedata
611 materials.append(matdata)
613 for material in materials:
614 #add material to the mesh list of materials
615 me_ob.materials.append(material)
616 #===================================================================================================
617 #UV Setup
618 #===================================================================================================
619 print ("-------------------------")
620 print ("-- Creating UV Texture --")
621 print ("-------------------------")
622 texture = []
623 # texturename = "text1" # UNUSED
624 countm = 0
625 for countm in range(materialcount):
626 psktexname = "psk" + str(countm)
627 me_ob.uv_textures.new(name=psktexname)
628 countm += 1
629 print("INIT UV TEXTURE...")
630 _matcount = 0
631 #for mattexcount in materials:
632 #print("MATERAIL ID:", _matcount)
633 _textcount = 0
634 for uv in me_ob.tessface_uv_textures: # uv texture
635 print("UV TEXTURE ID:",_textcount)
636 print(dir(uv))
637 for face in me_ob.tessfaces:# face, uv
638 #print(dir(face))
639 if faceuv[face.index][1] == _textcount: #if face index and texture index matches assign it
640 mfaceuv = faceuv[face.index] #face index
641 _uv1 = mfaceuv[0][0] #(0,0)
642 uv.data[face.index].uv1 = mathutils.Vector((_uv1[0], _uv1[1])) #set them
643 _uv2 = mfaceuv[0][1] #(0,0)
644 uv.data[face.index].uv2 = mathutils.Vector((_uv2[0], _uv2[1])) #set them
645 _uv3 = mfaceuv[0][2] #(0,0)
646 uv.data[face.index].uv3 = mathutils.Vector((_uv3[0], _uv3[1])) #set them
647 else: #if not match zero them
648 uv.data[face.index].uv1 = mathutils.Vector((0, 0)) #zero them
649 uv.data[face.index].uv2 = mathutils.Vector((0, 0)) #zero them
650 uv.data[face.index].uv3 = mathutils.Vector((0, 0)) #zero them
651 _textcount += 1
652 #_matcount += 1
653 #print(matcount)
654 print("END UV TEXTURE...")
656 print("UV TEXTURE LEN:", len(texture))
657 #for tex in me_ob.uv_textures:
658 #print("mesh tex:", dir(tex))
659 #print((tex.name))
661 #for face in me_ob.faces:
662 #print(dir(face))
664 #===================================================================================================
666 #===================================================================================================
667 obmesh = bpy.data.objects.new(objName,me_ob)
668 #===================================================================================================
669 #Mesh Vertex Group bone weight
670 #===================================================================================================
671 print("---- building bone weight mesh ----")
672 #print(dir(ob_new.data.bones))
673 #create bone vertex group #deal with bone id for index number
674 for bone in ob_new.data.bones:
675 #print("names:", bone.name, ":", dir(bone))
676 #print("names:", bone.name)
677 group = obmesh.vertex_groups.new(bone.name)
679 for vgroup in obmesh.vertex_groups:
680 #print(vgroup.name, ":", vgroup.index)
681 for vgp in RWghts:
682 #bone index
683 if vgp[1] == bni_dict[vgroup.name]:
684 #print(vgp)
685 #[vertex id],weight
686 vgroup.add([vgp[0]], vgp[2], 'ADD')
688 #check if there is a material to set to
689 if len(materials) > 0:
690 obmesh.active_material = materials[0] #material setup tmp
691 print("---- adding mesh to the scene ----")
693 bpy.ops.object.mode_set(mode='OBJECT')
694 #bpy.ops.object.select_pattern(extend=True, pattern=obmesh.name, case_sensitive=True)
695 #bpy.ops.object.select_pattern(extend=True, pattern=ob_new.name, case_sensitive=True)
697 #bpy.ops.object.select_name(name=str(obmesh.name))
698 #bpy.ops.object.select_name(name=str(ob_new.name))
699 #bpy.context.scene.objects.active = ob_new
700 me_ob.update()
701 bpy.context.scene.objects.link(obmesh)
702 bpy.context.scene.update()
703 obmesh.select = False
704 ob_new.select = False
705 obmesh.select = True
706 ob_new.select = True
707 bpy.ops.object.parent_set(type="ARMATURE")
709 print ("PSK2Blender completed")
710 #End of def pskimport#########################
712 def getInputFilenamepsk(self, filename, importmesh, importbone, bDebugLogPSK, importmultiuvtextures):
713 checktype = filename.split('\\')[-1].split('.')[1]
714 print ("------------",filename)
715 if checktype.lower() != 'psk':
716 print (" Selected file = ", filename)
717 raise (IOError, "The selected input file is not a *.psk file")
718 #self.report({'INFO'}, ("Selected file:"+ filename))
719 else:
720 pskimport(filename, importmesh, importbone, bDebugLogPSK, importmultiuvtextures)
722 def getInputFilenamepsa(self, filename, context):
723 checktype = filename.split('\\')[-1].split('.')[1]
724 if checktype.lower() != 'psa':
725 print (" Selected file = ", filename)
726 raise (IOError, "The selected input file is not a *.psa file")
727 #self.report({'INFO'}, ("Selected file:" + filename))
728 else:
729 psaimport(filename,context)
731 class IMPORT_OT_psk(bpy.types.Operator):
732 '''Load a skeleton mesh psk File'''
733 bl_idname = "import_scene.psk"
734 bl_label = "Import PSK"
735 bl_space_type = "PROPERTIES"
736 bl_region_type = "WINDOW"
737 bl_options = {'UNDO'}
739 # List of operator properties, the attributes will be assigned
740 # to the class instance from the operator settings before calling.
741 filepath = StringProperty(
742 subtype='FILE_PATH',
744 filter_glob = StringProperty(
745 default="*.psk",
746 options={'HIDDEN'},
748 importmesh = BoolProperty(
749 name="Mesh",
750 description="Import mesh only. (not yet build.)",
751 default=True,
753 importbone = BoolProperty(
754 name="Bones",
755 description="Import bones only. Current not working yet",
756 default=True,
758 importmultiuvtextures = BoolProperty(
759 name="Single UV Texture(s)",
760 description="Single or Multi uv textures",
761 default=True,
763 bDebugLogPSK = BoolProperty(
764 name="Debug Log.txt",
765 description="Log the output of raw format. It will save in "
766 "current file dir. Note this just for testing",
767 default=False,
769 unrealbonesize = FloatProperty(
770 name="Bone Length",
771 description="Bone Length from head to tail distance",
772 default=1,
773 min=0.001,
774 max=1000,
777 def execute(self, context):
778 bpy.types.Scene.unrealbonesize = self.unrealbonesize
779 getInputFilenamepsk(self, self.filepath, self.importmesh, self.importbone, self.bDebugLogPSK,
780 self.importmultiuvtextures)
781 return {'FINISHED'}
783 def invoke(self, context, event):
784 wm = context.window_manager
785 wm.fileselect_add(self)
786 return {'RUNNING_MODAL'}
788 class psa_bone:
789 name=""
790 Transform=None
791 parent=None
792 def __init__(self):
793 self.name=""
794 self.Transform=None
795 self.parent=None
797 def psaimport(filename,context):
798 print ("--------------------------------------------------")
799 print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
800 print ("--------------------------------------------------")
801 print ("Importing file: ", filename)
802 psafile = open(filename,'rb')
803 debug = True
804 if (debug):
805 logpath = filename.replace(".psa", ".txt")
806 print("logpath:", logpath)
807 logf = open(logpath, 'w')
808 def printlog(strdata):
809 if (debug):
810 logf.write(strdata)
811 def printlogplus(name, data):
812 if (debug):
813 logf.write(str(name) + '\n')
814 if isinstance(data, bytes):
815 logf.write(str(bytes.decode(data).strip(bytes.decode(b'\x00'))))
816 else:
817 logf.write(str(data))
818 logf.write('\n')
820 printlog('-----------Log File------------\n')
821 #General Header
822 indata = unpack('20s3i', psafile.read(32))
823 printlogplus('ChunkID', indata[0])
824 printlogplus('TypeFlag', indata[1])
825 printlogplus('DataSize', indata[2])
826 printlogplus('DataCount', indata[3])
827 #Bones Header
828 indata = unpack('20s3i', psafile.read(32))
829 printlogplus('ChunkID', indata[0])
830 printlogplus('TypeFlag', indata[1])
831 printlogplus('DataSize', indata[2])
832 printlogplus('DataCount', indata[3])
833 #Bones Data
834 BoneIndex2NamePairMap = {}
835 BoneNotFoundList = []
836 printlog("Name|Flgs|NumChld|PrntIdx|Qx|Qy|Qz|Qw|LocX|LocY|LocZ|Length|XSize|YSize|ZSize\n")
837 recCount = indata[3]
838 counter = 0
839 nobonematch = True
840 while counter < recCount:
841 indata = unpack('64s3i11f', psafile.read(120))
842 #printlogplus('bone', indata[0])
843 bonename = str(bytes.decode(indata[0]).strip(bytes.decode(b'\x00')))
844 if bonename in bpy.data.armatures['armaturedata'].bones.keys():
845 BoneIndex2NamePairMap[counter] = bonename
846 print('find bone', bonename)
847 nobonematch = False
848 else:
849 print('can not find the bone:', bonename)
850 BoneNotFoundList.append(counter)
851 counter += 1
853 if nobonematch:
854 print('no bone was match so skip import!')
855 return
857 #Animations Header
858 indata = unpack('20s3i', psafile.read(32))
859 printlogplus('ChunkID', indata[0])
860 printlogplus('TypeFlag', indata[1])
861 printlogplus('DataSize', indata[2])
862 printlogplus('DataCount', indata[3])
863 #Animations Data
864 recCount = indata[3]
865 counter = 0
866 Raw_Key_Nums = 0
867 Action_List = []
868 while counter < recCount:
869 indata = unpack('64s64s4i3f3i', psafile.read(64 + 64 + 4 * 4 + 3 * 4 + 3 * 4))
870 printlogplus('Name', indata[0])
871 printlogplus('Group', indata[1])
872 printlogplus('totalbones', indata[2])
873 printlogplus('NumRawFrames', indata[-1])
874 Name = str(bytes.decode(indata[0]).strip(bytes.decode(b'\x00')))
875 Group = str(bytes.decode(indata[1]).strip(bytes.decode(b'\x00')))
876 totalbones = indata[2]
877 NumRawFrames = indata[-1]
879 Raw_Key_Nums += indata[2] * indata[-1]
880 Action_List.append((Name,Group,totalbones,NumRawFrames))
882 counter += 1
884 #Raw keys Header
885 Raw_Key_List = []
886 indata = unpack('20s3i', psafile.read(32))
887 printlogplus('ChunkID', indata[0])
888 printlogplus('TypeFlag', indata[1])
889 printlogplus('DataSize', indata[2])
890 printlogplus('DataCount', indata[3])
891 if(Raw_Key_Nums != indata[3]):
892 print('error! Raw_Key_Nums Inconsistent')
893 return
894 #Raw keys Data
895 recCount = Raw_Key_Nums
896 counter = 0
897 while counter < recCount:
898 indata = unpack('3f4f1f', psafile.read(3 * 4 + 4 * 4 + 4))
899 pos = mathutils.Vector((indata[0], indata[1], indata[2]))
900 quat = mathutils.Quaternion((indata[6], indata[3], indata[4], indata[5]))
901 time = indata[7]
902 Raw_Key_List.append((pos, quat, time))
903 counter += 1
904 #Scale keys Header,Scale keys Data,Curve keys Header,Curve keys Data
905 curFilePos = psafile.tell()
906 psafile.seek(0, 2)
907 endFilePos = psafile.tell()
908 if curFilePos == endFilePos:
909 print('no Scale keys,Curve keys')
911 #build the animation line
912 if bpy.ops.object.mode_set.poll():
913 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
915 NeededBoneMatrix = {}
916 ARMATURE_OBJ = 'ArmObject'
917 ARMATURE_DATA = 'armaturedata'
918 if bpy.context.scene.udk_importarmatureselect:
919 if len(bpy.context.scene.udkas_list) > 0:
920 print("CHECKING ARMATURE...")
921 #for bone in bpy.data.objects[ARMATURE_OBJ].pose.bones:
922 #for objd in bpy.data.objects:
923 #print("NAME:", objd.name, " TYPE:", objd.type)
924 #if objd.type == 'ARMARURE':
925 #print(dir(objd))
926 armature_list = bpy.context.scene.udkas_list #armature list array
927 armature_idx = bpy.context.scene.udkimportarmature_list_idx #armature index selected
928 ARMATURE_OBJ = bpy.data.objects[armature_list[armature_idx]].name #object armature
929 ARMATURE_DATA = bpy.data.objects[armature_list[armature_idx]].data.name #object data
931 for bone in bpy.data.armatures[ARMATURE_DATA].bones:
932 name = bone.name
933 ori_matrix = bone.matrix
934 matrix = bone.matrix_local.to_3x3()
935 bone_rest_matrix = Matrix(matrix)
936 #bone_rest_matrix = bone.matrix_local.to_3x3()
937 #bone_rest_matrix = bone.matrix_local.to_quaternion().conjugated().to_matrix()
938 bone_rest_matrix_inv = Matrix(bone_rest_matrix)
939 bone_rest_matrix_inv.invert()
940 bone_rest_matrix_inv.resize_4x4()
941 bone_rest_matrix.resize_4x4()
942 NeededBoneMatrix[name] = (bone_rest_matrix,bone_rest_matrix_inv,ori_matrix)
944 #build tmp pose bone tree
945 psa_bones = {}
946 for bone in bpy.data.objects[ARMATURE_OBJ].pose.bones:
947 _psa_bone = psa_bone()
948 _psa_bone.name = bone.name
949 _psa_bone.Transform = bone.matrix
950 if bone.parent != None:
951 _psa_bone.parent = psa_bones[bone.parent.name]
952 else:
953 _psa_bone.parent = None
954 psa_bones[bone.name] = _psa_bone
956 raw_key_index = 0
958 for raw_action in Action_List:
959 Name = raw_action[0]
960 Group = raw_action[1]
961 Totalbones = raw_action[2]
962 NumRawFrames = raw_action[3]
963 context.scene.update()
964 object = bpy.data.objects['ArmObject']
965 object.animation_data_create()
966 action = bpy.data.actions.new(name=Name)
967 object.animation_data.action = action
968 for i in range(NumRawFrames):
969 context.scene.frame_set(i + 1)
970 pose_bones = object.pose.bones
971 for j in range(Totalbones):
972 if j not in BoneNotFoundList:
973 bName = BoneIndex2NamePairMap[j]
974 pbone = psa_bones[bName]
975 pos = Raw_Key_List[raw_key_index][0]
976 quat = Raw_Key_List[raw_key_index][1]
978 mat = Matrix()
979 if pbone.parent != None:
980 quat = quat.conjugated()
981 mat = Matrix.Translation(pos) * quat.to_matrix().to_4x4()
982 mat = pose_bones[bName].parent.matrix * mat
983 #mat = pbone.parent.Transform * mat
984 else:
985 mat = pbone.Transform * Matrix.Translation(pos) * quat.to_matrix().to_4x4()
987 pose_bones[bName].matrix = mat
988 pbone.Transform = mat
990 raw_key_index += 1
992 #bpy.data.meshes[1]
993 for bone in pose_bones:
994 bone.matrix = psa_bones[bone.name].Transform
995 bone.keyframe_insert("rotation_quaternion")
996 bone.keyframe_insert("location")
998 def whirlSingleBone(pose_bone,quat):
999 bpy.context.scene.update()
1000 #record child's matrix and origin rotate
1001 hymat = Quaternion((0.707, -0.707, 0, 0)).inverted().to_matrix().to_4x4()
1002 children_infos = {}
1003 childrens = pose_bone.children
1004 for child in childrens:
1005 armmat = bpy.data.armatures['armaturedata'].bones[child.name].matrix.copy().to_4x4()
1006 cmat = child.matrix.copy() * armmat.inverted() * hymat.inverted()
1007 pos = cmat.to_translation()
1008 rotmat = cmat.to_3x3()
1009 children_infos[child] = (armmat, pos, rotmat)
1011 #whirl this bone by quat
1012 pose_bone.matrix *= quat.to_matrix().to_4x4()
1013 pose_bone.keyframe_insert("location")
1014 pose_bone.keyframe_insert("rotation_quaternion")
1015 bpy.context.scene.update()
1016 #set back children bon to original position
1017 #reverse whirl child bone by quat.inverse()
1019 for child in childrens:
1020 armmat = children_infos[child][0]
1021 pos = children_infos[child][1]
1022 rotmat = children_infos[child][2]
1024 child.matrix = Matrix.Translation(pos) * rotmat.to_4x4() * hymat * armmat
1025 child.keyframe_insert("location")
1026 child.keyframe_insert("rotation_quaternion")
1028 for bone in pose_bones:
1029 if bone.parent != None:
1030 whirlSingleBone(bone,Quaternion((0.707, 0, 0, -0.707)))
1031 else:
1032 bone.rotation_quaternion *= Quaternion((0.707, -0.707, 0, 0)) * Quaternion((0.707, 0, 0, -0.707))
1033 bone.keyframe_insert("rotation_quaternion")
1035 break
1037 context.scene.frame_set(0)
1038 if(debug):
1039 logf.close()
1041 class IMPORT_OT_psa(bpy.types.Operator):
1042 '''Load a skeleton anim psa File'''
1043 bl_idname = "import_scene.psa"
1044 bl_label = "Import PSA"
1045 bl_space_type = "PROPERTIES"
1046 bl_region_type = "WINDOW"
1048 filepath = StringProperty(
1049 subtype='FILE_PATH',
1051 filter_glob = StringProperty(
1052 default="*.psa",
1053 options={'HIDDEN'},
1056 def execute(self, context):
1057 getInputFilenamepsa(self,self.filepath,context)
1058 return {'FINISHED'}
1060 def invoke(self, context, event):
1061 wm = context.window_manager
1062 wm.fileselect_add(self)
1063 return {'RUNNING_MODAL'}
1065 class IMPORT_OT_psa(bpy.types.Operator):
1066 '''Load a skeleton anim psa File'''
1067 bl_idname = "import_scene.psa"
1068 bl_label = "Import PSA"
1069 bl_space_type = "PROPERTIES"
1070 bl_region_type = "WINDOW"
1072 filepath = StringProperty(
1073 subtype='FILE_PATH',
1075 filter_glob = StringProperty(
1076 default="*.psa",
1077 options={'HIDDEN'},
1080 def execute(self, context):
1081 getInputFilenamepsa(self,self.filepath,context)
1082 return {'FINISHED'}
1084 def invoke(self, context, event):
1085 wm = context.window_manager
1086 wm.fileselect_add(self)
1087 return {'RUNNING_MODAL'}
1089 bpy.types.Scene.udk_importpsk = StringProperty(
1090 name = "Import .psk",
1091 description = "Skeleton mesh file path for psk",
1092 default = "")
1093 bpy.types.Scene.udk_importpsa = StringProperty(
1094 name = "Import .psa",
1095 description = "Animation Data to Action Set(s) file path for psa",
1096 default = "")
1097 bpy.types.Scene.udk_importarmatureselect = BoolProperty(
1098 name = "Armature Selected",
1099 description = "Select Armature to Import psa animation data",
1100 default = False)
1102 class Panel_UDKImport(bpy.types.Panel):
1103 bl_label = "UDK Import"
1104 bl_idname = "OBJECT_PT_udk_import"
1105 bl_space_type = "VIEW_3D"
1106 bl_region_type = "TOOLS"
1108 filepath = StringProperty(
1109 subtype='FILE_PATH',
1112 #@classmethod
1113 #def poll(cls, context):
1114 # return context.active_object
1116 def draw(self, context):
1117 layout = self.layout
1118 layout.operator(OBJECT_OT_PSKPath.bl_idname)
1120 layout.prop(context.scene, "udk_importarmatureselect")
1121 if bpy.context.scene.udk_importarmatureselect:
1122 layout.operator(OBJECT_OT_UDKImportArmature.bl_idname)
1123 layout.template_list("UI_UL_list", "udkimportarmature_list", context.scene, "udkimportarmature_list",
1124 context.scene, "udkimportarmature_list_idx", rows=5)
1125 layout.operator(OBJECT_OT_PSAPath.bl_idname)
1127 class OBJECT_OT_PSKPath(bpy.types.Operator):
1128 """Select .psk file path to import for skeleton mesh"""
1129 bl_idname = "object.pskpath"
1130 bl_label = "Import PSK Path"
1132 filepath = StringProperty(
1133 subtype='FILE_PATH',
1135 filter_glob = StringProperty(
1136 default="*.psk",
1137 options={'HIDDEN'},
1139 importmesh = BoolProperty(
1140 name="Mesh",
1141 description="Import mesh only. (not yet build.)",
1142 default=True,
1144 importbone = BoolProperty(
1145 name="Bones",
1146 description="Import bones only. Current not working yet",
1147 default=True,
1149 importmultiuvtextures = BoolProperty(
1150 name="Single UV Texture(s)",
1151 description="Single or Multi uv textures",
1152 default=True,
1154 bDebugLogPSK = BoolProperty(
1155 name="Debug Log.txt",
1156 description="Log the output of raw format. It will save in " \
1157 "current file dir. Note this just for testing",
1158 default=False,
1160 unrealbonesize = FloatProperty(
1161 name="Bone Length",
1162 description="Bone Length from head to tail distance",
1163 default=1,
1164 min=0.001,
1165 max=1000,
1168 def execute(self, context):
1169 #context.scene.importpskpath = self.properties.filepath
1170 bpy.types.Scene.unrealbonesize = self.unrealbonesize
1171 getInputFilenamepsk(self, self.filepath, self.importmesh, self.importbone, self.bDebugLogPSK,
1172 self.importmultiuvtextures)
1173 return {'FINISHED'}
1175 def invoke(self, context, event):
1176 #bpy.context.window_manager.fileselect_add(self)
1177 wm = context.window_manager
1178 wm.fileselect_add(self)
1179 return {'RUNNING_MODAL'}
1181 class UDKImportArmaturePG(bpy.types.PropertyGroup):
1182 #boolean = BoolProperty(default=False)
1183 string = StringProperty()
1184 bexport = BoolProperty(default=False, name="Export", options={"HIDDEN"},
1185 description = "This will be ignore when exported")
1186 bselect = BoolProperty(default=False, name="Select", options={"HIDDEN"},
1187 description = "This will be ignore when exported")
1188 otype = StringProperty(name="Type",description = "This will be ignore when exported")
1190 bpy.utils.register_class(UDKImportArmaturePG)
1191 bpy.types.Scene.udkimportarmature_list = CollectionProperty(type=UDKImportArmaturePG)
1192 bpy.types.Scene.udkimportarmature_list_idx = IntProperty()
1194 class OBJECT_OT_PSAPath(bpy.types.Operator):
1195 """Select .psa file path to import for animation data"""
1196 bl_idname = "object.psapath"
1197 bl_label = "Import PSA Path"
1199 filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file",
1200 maxlen=1024, default="")
1201 filter_glob = StringProperty(
1202 default="*.psa",
1203 options={'HIDDEN'},
1206 def execute(self, context):
1207 #context.scene.importpsapath = self.properties.filepath
1208 getInputFilenamepsa(self,self.filepath,context)
1209 return {'FINISHED'}
1211 def invoke(self, context, event):
1212 bpy.context.window_manager.fileselect_add(self)
1213 return {'RUNNING_MODAL'}
1215 class OBJECT_OT_UDKImportArmature(bpy.types.Operator):
1216 """This will update the filter of the mesh and armature"""
1217 bl_idname = "object.udkimportarmature"
1218 bl_label = "Update Armature"
1220 def execute(self, context):
1221 my_objlist = bpy.context.scene.udkimportarmature_list
1222 objectl = []
1223 for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
1224 if objarm.type == 'ARMATURE':
1225 objectl.append(objarm)
1226 for _objd in objectl:#check if list has in udk list
1227 bfound_obj = False
1228 for _obj in my_objlist:
1229 if _obj.name == _objd.name and _obj.otype == _objd.type:
1230 _obj.bselect = _objd.select
1231 bfound_obj = True
1232 break
1233 if bfound_obj == False:
1234 #print("ADD ARMATURE...")
1235 my_item = my_objlist.add()
1236 my_item.name = _objd.name
1237 my_item.bselect = _objd.select
1238 my_item.otype = _objd.type
1239 removeobject = []
1240 for _udkobj in my_objlist:
1241 bfound_objv = False
1242 for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
1243 if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
1244 bfound_objv = True
1245 break
1246 if bfound_objv == False:
1247 removeobject.append(_udkobj)
1248 #print("remove check...")
1249 for _item in removeobject: #loop remove object from udk list object
1250 count = 0
1251 for _obj in my_objlist:
1252 if _obj.name == _item.name and _obj.otype == _item.otype:
1253 my_objlist.remove(count)
1254 break
1255 count += 1
1256 return{'FINISHED'}
1258 class OBJECT_OT_UDKImportA(bpy.types.Operator):
1259 """This will update the filter of the mesh and armature"""
1260 bl_idname = "object.udkimporta"
1261 bl_label = "Update Armature"
1263 def execute(self, context):
1264 for objd in bpy.data.objects:
1265 print("NAME:",objd.name," TYPE:",objd.type)
1266 if objd.type == "ARMATURE":
1267 print(dir(objd))
1268 print((objd.data.name))
1269 return{'FINISHED'}
1271 def menu_func(self, context):
1272 self.layout.operator(IMPORT_OT_psk.bl_idname, text="Skeleton Mesh (.psk)")
1273 self.layout.operator(IMPORT_OT_psa.bl_idname, text="Skeleton Anim (.psa)")
1275 def register():
1276 bpy.utils.register_module(__name__)
1277 bpy.types.INFO_MT_file_import.append(menu_func)
1279 def unregister():
1280 bpy.utils.unregister_module(__name__)
1281 bpy.types.INFO_MT_file_import.remove(menu_func)
1283 if __name__ == "__main__":
1284 register()
1286 #note this only read the data and will not be place in the scene
1287 #getInputFilename('C:\\blenderfiles\\BotA.psk')
1288 #getInputFilename('C:\\blenderfiles\\AA.PSK')