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