Skip to content
Snippets Groups Projects
io_export_unreal_psk_psa.py 107 KiB
Newer Older
  • Learn to ignore specific revisions
  •             path = os.path.split(bpy.data.filepath)[0] + "\\" + bpy.context.active_object.name  # + ".psk"
    
                # path = os.path.split(bpy.data.filepath)[0] + "\\" + "Unknown";
                path = os.path.splitext(bpy.data.filepath)[0]  # + ".psk"
    
            path = os.path.splitext(bpy.data.filepath)[0]  # + ".psk"
    
    
    # ===========================================================================
    
    # ===========================================================================
    class OBJECT_OT_UTSelectedFaceSmooth(Operator):
    
        """It will only select smooth faces that is select mesh"""
    
        bl_idname = "object.utselectfacesmooth"  # XXX, name???
    
        bl_label = "Select Smooth Faces"         # "Select Smooth faces"
    
        def invoke(self, context, event):
            print("----------------------------------------")
            print("Init Select Face(s):")
            bselected = False
            for obj in bpy.data.objects:
    
                if obj.type == 'MESH' and obj.select is True:
    
                    smoothcount = 0
                    flatcount = 0
    
                    bpy.ops.object.mode_set(mode='OBJECT')  # it need to go into object mode to able to select the faces
    
                    for i in bpy.context.scene.objects:
                        i.select = False  # deselect all objects
    
                    obj.select = True  # set current object select
                    bpy.context.scene.objects.active = obj  # set active object
                    mesh = bmesh.new()
    
                    mesh.from_mesh(obj.data)
    
                    for face in mesh.faces:
                        face.select = False
    
                    for face in mesh.faces:
    
                            face.select = True
                            smoothcount += 1
                        else:
                            flatcount += 1
                            face.select = False
                    mesh.to_mesh(obj.data)
                    bpy.context.scene.update()
                    bpy.ops.object.mode_set(mode='EDIT')
    
                    print("Select Smooth Count(s):", smoothcount, " Flat Count(s):", flatcount)
    
                    bselected = True
                    break
            if bselected:
    
                self.report({'INFO'}, "Selected Face(s) Executed")
    
                self.report({'INFO'}, "Mesh Object is not selected")
    
            print("----------------------------------------")
    
    
    class OBJECT_OT_MeshClearWeights(Operator):
    
        """Remove all mesh vertex groups weights for the bones"""
    
        bl_idname = "object.meshclearweights"  # XXX, name???
    
        bl_label = "Remove Vertex Weights"     # "Remove Mesh vertex weights"
    
        def invoke(self, context, event):
            for obj in bpy.data.objects:
    
                if obj.type == 'MESH' and obj.select is True:
    
                    for vg in obj.vertex_groups:
                        obj.vertex_groups.remove(vg)
    
                    self.report({'INFO'}, "Mesh Vertex Groups Removed")
    
    def unpack_list(list_of_tuples):
        l = []
        for t in list_of_tuples:
            l.extend(t)
        return l
    
        # make sure it in object mode
        print("Mesh Object Name:", obj.name)
    
        bpy.ops.object.mode_set(mode='OBJECT')
    
    
        for i in bpy.context.scene.objects:
            i.select = False  # deselect all objects
    
        obj.select = True
        bpy.context.scene.objects.active = obj
    
        me_ob = bpy.data.meshes.new(("Re_" + obj.name))
    
        mesh = obj.data
        faces = []
        verts = []
        smoothings = []
        uvfaces = []
    
        # print("creating array build mesh...")
        mmesh = obj.to_mesh(bpy.context.scene, True, 'PREVIEW')
    
        uv_layer = mmesh.tessface_uv_textures.active
    
            smoothings.append(face.use_smooth)  # smooth or flat in boolean
            if uv_layer is not None:            # check if there texture data exist
    
                faceUV = uv_layer.data[face.index]
                uvs = []
                for uv in faceUV.uv:
    
                faces.extend([(face.vertices[0], face.vertices[1], face.vertices[2], 0)])
    
                faces.extend([(face.vertices[0], face.vertices[1], face.vertices[2], face.vertices[3])])
    
        # vertex positions
    
        # vertices weight groups into array
        vertGroups = {}  # array in strings
    
    
        for vgroup in obj.vertex_groups:
            vlist = []
            for v in mesh.vertices:
                for vg in v.groups:
                    if vg.group == vgroup.index:
    
                        vlist.append((v.index, vg.weight))
                        # print((v.index,vg.weight))
    
        # print("creating mesh object...")
        # me_ob.from_pydata(verts, [], faces)
    
        me_ob.vertices.add(len(verts))
        me_ob.tessfaces.add(len(faces))
    
        me_ob.vertices.foreach_set("co", unpack_list(verts))
    
        me_ob.tessfaces.foreach_set("vertices_raw", unpack_list(faces))
        me_ob.tessfaces.foreach_set("use_smooth", smoothings)  # smooth array from face
    
        if len(uvfaces) > 0:
            uvtex = me_ob.tessface_uv_textures.new(name="retex")
            for i, face in enumerate(me_ob.tessfaces):
    
                blender_tface = uvtex.data[i]  # face
    
                mfaceuv = uvfaces[i]
                if len(mfaceuv) == 3:
    
                    blender_tface.uv1 = mfaceuv[0]
                    blender_tface.uv2 = mfaceuv[1]
                    blender_tface.uv3 = mfaceuv[2]
    
                    blender_tface.uv1 = mfaceuv[0]
                    blender_tface.uv2 = mfaceuv[1]
                    blender_tface.uv3 = mfaceuv[2]
                    blender_tface.uv4 = mfaceuv[3]
    
        me_ob.update()  # need to update the information to able to see into the secne
        obmesh = bpy.data.objects.new(("Re_" + obj.name), me_ob)
    
        materialname = "ReMaterial"
        for matcount in mesh.materials:
            matdata = bpy.data.materials.new(materialname)
            me_ob.materials.append(matdata)
    
        for face in mesh.tessfaces:
            me_ob.faces[face.index].material_index = face.material_index
    
        for vgroup in vertGroups:
            group = obmesh.vertex_groups.new(vgroup)
            for v in vertGroups[vgroup]:
    
                group.add([v[0]], v[1], 'ADD')  # group.add(array[vertex id],weight,add)
    
        bpy.context.scene.objects.link(obmesh)
    
        # print("Mesh Material Count:",len(me_ob.materials))
    
        # print("MATERIAL ID OREDER:")
    
            # print("-Material:",mat.name,"INDEX:",matcount)
    
    
        print("Mesh Object Name:", obmesh.name)
    
    
    class OBJECT_OT_UTRebuildMesh(Operator):
    
        """It rebuild the mesh from scrape from the selected mesh object. """ \
        """Note the scale will be 1:1 for object mode. To keep from deforming"""
    
        bl_idname = "object.utrebuildmesh"  # XXX, name???
    
        bl_label = "Rebuild Mesh"           # "Rebuild Mesh"
    
        def invoke(self, context, event):
            print("----------------------------------------")
            print("Init Mesh Bebuild...")
            bselected = False
    
            bpy.ops.object.mode_set(mode='OBJECT')
    
            for obj in bpy.data.objects:
    
                if obj.type == 'MESH' and obj.select is True:
    
    
            self.report({'INFO'}, "Rebuild Mesh Finished!")
    
            print("----------------------------------------")
            return{'FINISHED'}
    
        currentbone = []  # select armature for roll copy
        print("Armature Name:", obj.name)
    
        meshname = "ArmatureObjectPSK"
    
        armdata = bpy.data.armatures.new(objectname)
        ob_new = bpy.data.objects.new(meshname, armdata)
        bpy.context.scene.objects.link(ob_new)
    
        # bpy.ops.object.mode_set(mode='OBJECT')
    
        for i in bpy.context.scene.objects:
            i.select = False  # deselect all objects
    
    
        ob_new.select = True
        bpy.context.scene.objects.active = obj
    
        bpy.ops.object.mode_set(mode='EDIT')
        for bone in obj.data.edit_bones:
    
            if bone.parent is not None:
    
                currentbone.append([bone.name, bone.roll])
    
                currentbone.append([bone.name, bone.roll])
    
        bpy.ops.object.mode_set(mode='OBJECT')
    
    
        for i in bpy.context.scene.objects:
            i.select = False  # deselect all objects
    
    
        bpy.context.scene.objects.active = ob_new
        bpy.ops.object.mode_set(mode='EDIT')
    
        for bone in obj.data.bones:
            bpy.ops.object.mode_set(mode='EDIT')
            newbone = ob_new.data.edit_bones.new(bone.name)
            newbone.head = bone.head_local
            newbone.tail = bone.tail_local
            for bonelist in currentbone:
                if bone.name == bonelist[0]:
                    newbone.roll = bonelist[1]
                    break
    
            if bone.parent is not None:
    
                parentbone = ob_new.data.edit_bones[bone.parent.name]
                newbone.parent = parentbone
    
    
        ob_new.animation_data_create()      # create animation data
        if obj.animation_data is not None:  # check for animation
            # just make sure it here to do the animations if exist
            ob_new.animation_data.action = obj.animation_data.action
    
        print("Armature Object Name:", ob_new.name)
    
    
    class OBJECT_OT_UTRebuildArmature(Operator):
    
        """If mesh is deform when importing to unreal engine try this. """ \
        """It rebuild the bones one at the time by select one armature object scrape to raw setup build. """ \
        """Note the scale will be 1:1 for object mode. To keep from deforming"""
    
        bl_idname = "object.utrebuildarmature"  # XXX, name???
    
        bl_label = "Rebuild Armature"           # Rebuild Armature
    
        def invoke(self, context, event):
            print("----------------------------------------")
            print("Init Rebuild Armature...")
            bselected = False
            for obj in bpy.data.objects:
    
                if obj.type == 'ARMATURE' and obj.select is True:
    
                    rebuildarmature(obj)
            self.report({'INFO'}, "Rebuild Armature Finish!")
    
            print("End of Rebuild Armature.")
            print("----------------------------------------")
            return{'FINISHED'}
    
    
    class UDKActionSetListPG(PropertyGroup):
        bool = BoolProperty(default=False)
        string = StringProperty()
        actionname = StringProperty()
        bmatch = BoolProperty(
                default=False,
                name="Match",
                options={"HIDDEN"},
                description="This check against bone names and action group "
                            "names matches and override boolean if true"
                )
        bexport = BoolProperty(
                default=False,
                name="Export",
                description="Check this to export the animation"
                )
    
    
    class UL_UDKActionSetList(UIList):
    
        def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
            layout.label(item.name)
    
    John Phan's avatar
    John Phan committed
            layout.prop(item, "bmatch", text="Match")
            layout.prop(item, "bexport", text="Export")
    
    class UDKObjListPG(PropertyGroup):
        bool = BoolProperty(default=False)
        string = StringProperty()
        bexport = BoolProperty(
                default=False,
                name="Export",
                options={"HIDDEN"},
                description="This will be ignore when exported"
                )
        bselect = BoolProperty(
                default=False,
                name="Select",
                options={"HIDDEN"},
                description="This will be ignore when exported"
                )
        otype = StringProperty(
                name="Type",
                description="This will be ignore when exported"
                )
    
        def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
            layout.label(item.name)
            layout.prop(item, "otype", text="")
            layout.prop(item, "bselect", text="")
    
    
    class UDKMeshListPG(PropertyGroup):
        bool = BoolProperty(
                default=False
                )
        string = StringProperty()
        bexport = BoolProperty(
                default=False,
                name="Export",
                options={"HIDDEN"},
                description="This object will be export when true"
                )
        bselect = BoolProperty(
                default=False,
                name="Select",
                options={"HIDDEN"},
                description="Make sure you have Mesh is parent to Armature"
                )
        otype = StringProperty(
                name="Type",
                description="This will be ignore when exported"
                )
    
    
    class UL_UDKMeshList(UIList):
    
        def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
            layout.label(item.name)
    
            # layout.prop(item, "bselect", text="Select")
    
    John Phan's avatar
    John Phan committed
            layout.prop(item, "bexport", text="Export")
    
    class UDKArmListPG(PropertyGroup):
        bool = BoolProperty(default=False)
        string = StringProperty()
        bexport = BoolProperty(
                default=False,
                name="Export",
                options={"HIDDEN"},
                description="This will be ignore when exported"
                )
        bselect = BoolProperty(
                default=False,
                name="Select",
                options={"HIDDEN"},
                description="This will be ignore when exported"
                )
        otype = StringProperty(
                name="Type",
                description="This will be ignore when exported"
                )
    
    
    John Phan's avatar
    John Phan committed
        def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
            layout.label(item.name)
    
    
    class Panel_UDKExport(Panel):
        bl_label = "UDK Export"
        bl_idname = "OBJECT_PT_udk_tools"
        bl_category = "File I/O"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
    
        bl_context = "objectmode"
    
        """
        def draw_header(self, context):
            layout = self.layout
            obj = context.object
            layout.prop(obj, "select", text="")
    
        @classmethod
        def poll(cls, context):
            return context.active_object
        """
    
    
        def draw(self, context):
            layout = self.layout
            path = get_dst_path()
    
            object_name = ""
    
            """
            if context.object:
                object_name = context.object.name
            """
    
            if context.active_object:
                object_name = context.active_object.name
            row10 = layout.row()
            row10.prop(context.scene, "udk_option_smoothing_groups")
    
            row10.prop(context.scene, "udk_option_clight_uv")
    
            row10.prop(context.scene, "udk_option_verbose")
    
            row = layout.row()
            row.label(text="Active object: " + object_name)
            layout.prop(context.scene, "udk_option_filename_src")
            row = layout.row()
            row.label(text=path)
    
            layout.prop(context.scene, "udk_option_export")
    
            layout.prop(context.scene, "udk_option_selectobjects")
    
            if context.scene.udk_option_selectobjects:
                layout.operator("object.selobjectpdate")
    
                layout.label(text="ARMATURE - Index")
    
    John Phan's avatar
    John Phan committed
                layout.template_list("UL_UDKArmList", "udk_armatures", context.scene, "udkArm_list",
    
                layout.label(text="MESH - Export")
    
                layout.template_list("UL_UDKMeshList", "", context.scene, "udkmesh_list",
                                     context.scene, "udkmesh_list_idx", rows=5)
    
            layout.prop(context.scene, "udk_option_selectanimations")
    
            if context.scene.udk_option_selectanimations:
                layout.operator("action.setanimupdate")
    
                layout.label(text="Action Set(s) - Match / Export")
    
                layout.template_list("UL_UDKActionSetList", "", context.scene, "udkas_list",
                                     context.scene, "udkas_list_idx", rows=5)
    
            layout.prop(context.scene, "udk_option_scale")
            layout.prop(context.scene, "udk_option_rebuildobjects")
    
            # layout.prop(context.scene, "udk_option_ignoreactiongroupnames")
    
    
            row11 = layout.row()
            row11.operator("object.udk_export")
            row11.operator("object.toggle_console")
            layout.operator(OBJECT_OT_UTRebuildArmature.bl_idname)
    
            layout.operator(OBJECT_OT_MeshClearWeights.bl_idname)
            layout.operator(OBJECT_OT_UTSelectedFaceSmooth.bl_idname)
            layout.operator(OBJECT_OT_UTRebuildMesh.bl_idname)
            layout.operator(OBJECT_OT_UDKCheckMeshLines.bl_idname)
    
    
    John Phan's avatar
    John Phan committed
    def udkupdateobjects():
    
        my_objlist = bpy.context.scene.udkArm_list
        objectl = []
        for objarm in bpy.context.scene.objects:  # list and filter only mesh and armature
            if objarm.type == 'ARMATURE':
                objectl.append(objarm)
    
        for _objd in objectl:  # check if list has in udk list
            bfound_obj = False
            for _obj in my_objlist:
                if _obj.name == _objd.name and _obj.otype == _objd.type:
                    _obj.bselect = _objd.select
                    bfound_obj = True
                    break
    
            if bfound_obj is False:
                # print("ADD ARMATURE...")
                my_item = my_objlist.add()
                my_item.name = _objd.name
                my_item.bselect = _objd.select
                my_item.otype = _objd.type
        removeobject = []
        for _udkobj in my_objlist:
            bfound_objv = False
    
            for _objd in bpy.context.scene.objects:  # check if there no existing object from sense to remove it
                if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
                    bfound_objv = True
                    break
    
            if bfound_objv is False:
                removeobject.append(_udkobj)
        # print("remove check...")
        for _item in removeobject:  # loop remove object from udk list object
            count = 0
            for _obj in my_objlist:
                if _obj.name == _item.name and _obj.otype == _item.otype:
                    my_objlist.remove(count)
                    break
                count += 1
    
        my_objlist = bpy.context.scene.udkmesh_list
        objectl = []
        for objarm in bpy.context.scene.objects:  # list and filter only mesh and armature
            if objarm.type == 'MESH':
                objectl.append(objarm)
        for _objd in objectl:  # check if list has in udk list
            bfound_obj = False
            for _obj in my_objlist:
                if _obj.name == _objd.name and _obj.otype == _objd.type:
                    _obj.bselect = _objd.select
                    bfound_obj = True
                    break
            if bfound_obj is False:
                my_item = my_objlist.add()
                my_item.name = _objd.name
                my_item.bselect = _objd.select
                my_item.otype = _objd.type
        removeobject = []
        for _udkobj in my_objlist:
            bfound_objv = False
            for _objd in bpy.context.scene.objects:  # check if there no existing object from sense to remove it
                if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
                    bfound_objv = True
                    break
            if bfound_objv is False:
                removeobject.append(_udkobj)
        # print("remove check...")
        for _item in removeobject:  # loop remove object from udk list object
            count = 0
            for _obj in my_objlist:
                if _obj.name == _item.name and _obj.otype == _item.otype:
                    my_objlist.remove(count)
                    break
                count += 1
    
    
    class OBJECT_OT_UDKObjUpdate(Operator):
    
        """This will update the filter of the mesh and armature"""
    
        bl_idname = "object.selobjectpdate"
        bl_label = "Update Object(s)"
    
        actionname = bpy.props.StringProperty()
    
        def execute(self, context):
            udkupdateobjects()
            return{'FINISHED'}
    
    
    def udkcheckmeshline():
        objmesh = None
        for obj in bpy.context.scene.objects:
    
            if obj.type == 'MESH' and obj.select is True:
    
    
        objmesh = triangulate_mesh(objmesh)  # create a copy of the mesh
    
        bpy.ops.object.mode_set(mode='OBJECT')
    
    
        for i in bpy.context.scene.objects:
            i.select = False  # deselect all objects
    
    
        bpy.context.scene.objects.active = objmesh  # set active mesh
        wedges = ObjMap()
        points = ObjMap()
        bpy.ops.object.mode_set(mode='EDIT')  # set in edit mode
    
        bpy.ops.mesh.select_all(action='DESELECT')
    
        bpy.context.tool_settings.mesh_select_mode = (True, False, False)  # select vertices
    
        if objmesh is not None:
    
            print("found mesh")
            print(objmesh)
            print(objmesh.data.tessfaces)
            vertex_list = []
            for face in objmesh.data.tessfaces:
    
                    vert_index = face.vertices[i]
                    vert = objmesh.data.vertices[vert_index]
                    vect_list.append(FVector(vert.co.x, vert.co.y, vert.co.z))
    
                    vpos = objmesh.matrix_local * vert.co
    
                    p = VPoint()
                    p.Point.X = vpos.x
                    p.Point.Y = vpos.y
                    p.Point.Z = vpos.z
                    w = VVertex()
                    w.PointIndex = points.get(p)  # store keys
    
                    index_wedge = wedges.get(w)
                    wedge_list.append(index_wedge)
                no = face.normal
                norm = FVector(no[0], no[1], no[2])
                tnorm = vect_list[1].sub(vect_list[0]).cross(vect_list[2].sub(vect_list[1]))
                dot = norm.dot(tnorm)
    
                tri = VTriangle()
                if dot > 0:
                    (tri.WedgeIndex2, tri.WedgeIndex1, tri.WedgeIndex0) = wedge_list
                elif dot < 0:
                    (tri.WedgeIndex0, tri.WedgeIndex1, tri.WedgeIndex2) = wedge_list
                else:
    
                    dindex0 = face.vertices[0]
                    dindex1 = face.vertices[1]
                    dindex2 = face.vertices[2]
    
                    vertex_list.append(dindex0)
                    vertex_list.append(dindex1)
                    vertex_list.append(dindex2)
    
            bpy.ops.object.mode_set(mode='OBJECT')
    
            for vertex in objmesh.data.vertices:  # loop all vertex in the mesh list
                for vl in vertex_list:      # loop for error vertex
                    if vertex.index == vl:  # if match set to select
    
            bpy.ops.object.mode_set(mode='EDIT')  # set in edit mode to see the select vertex
            objmesh.data.update()       # update object
            bpy.context.scene.update()  # update scene
    
            message = "MESH PASS"
            if len(vertex_list) > 0:
                message = "MESH FAIL"
        return message
    
    
    
    class OBJECT_OT_UDKCheckMeshLines(Operator):
    
        """Select the mesh for export test. This will create dummy mesh to see which area are broken. """ \
    
        """If the vertices share the same position it will cause a bug"""
    
        bl_idname = "object.udkcheckmeshline"
        bl_label = "Check Mesh Vertices"
    
        def execute(self, context):
            message = udkcheckmeshline()
            self.report({'ERROR'}, message)
            return{'FINISHED'}
    
    
    class OBJECT_OT_ActionSetAnimUpdate(Operator):
    
        """Select Armture to match the action set groups. """ \
    
        """All bones keys must be set to match with number of bones"""
    
        bl_idname = "action.setanimupdate"
        bl_label = "Update Action Set(s)"
    
        actionname = bpy.props.StringProperty()
    
        def execute(self, context):
            my_sett = bpy.context.scene.udkas_list
    
            bones = []
            armature = None
            armatures = []
            armatureselected = []
            for objarm in bpy.context.scene.objects:
                if objarm.type == 'ARMATURE':
    
            if len(armatureselected) == len(armatures) == 1:
                armature = armatures[0]
            if len(armatures) == 1:
                armature = armatures[0]
    
            if armature is not None:
    
                for bone in armature.pose.bones:
                    bones.append(bone.name)
    
    
            for action in bpy.data.actions:  # action list
    
                bfound = False
                count = 0
                for actionbone in action.groups:
    
                    # print("Pose bone name: ",actionbone.name)
    
                    for b in bones:
                        if b == actionbone.name:
                            count += 1
    
                            # print(b," : ",actionbone.name)
    
                            break
                for actionlist in my_sett:
                    if action.name == actionlist.name:
                        bactionfound = True
                        if len(bones) == len(action.groups) == count:
                            actionlist.bmatch = True
                        else:
                            actionlist.bmatch = False
                        bfound = True
                        break
    
                    # my_item.template_list_controls = "bmatch:bexport"
    
                    if len(bones) == len(action.groups) == count:
                        my_item.bmatch = True
                    else:
                        my_item.bmatch = False
    
            # check action list and data actions
    
            for actionlist in bpy.context.scene.udkas_list:
                bfind = False
                notfound = 0
                for act in bpy.data.actions:
                    if actionlist.name == act.name:
                        bfind = True
                    else:
                        notfound += 1
    
                # print("ACT NAME:",actionlist.name," COUNT",notfound)
    
                if notfound == len(bpy.data.actions):
    
                    # print("remove :",actionlist.name)
    
            # print("Not in the action data list:",len(removeactions))
            # remove list or chnages in the name the template list
    
            for actname in removeactions:
                actioncount = 0
                for actionlist in my_sett:
    
                    # print("action name:",actionlist.name)
    
    
    class ExportUDKAnimData(Operator):
    
        """Export Skeleton Mesh / Animation Data file(s). """ \
        """One mesh and one armature else select one mesh or armature to be exported"""
    
        bl_idname = "export_anim.udk"  # this is important since its how bpy.ops.export.udk_anim_data is constructed
    
        bl_label = "Export PSK/PSA"
    
        # List of operator properties, the attributes will be assigned
        # to the class instance from the operator settings before calling.
    
        filepath = StringProperty(
                subtype='FILE_PATH',
                )
        filter_glob = StringProperty(
                default="*.psk;*.psa",
                options={'HIDDEN'},
                )
    
        udk_option_scale = FloatProperty(
                name="UDK Scale",
                description="In case you don't want to scale objects manually - "
                            "This will just scale position when on export for the skeleton mesh and animation data",
                default=1
                )
        udk_option_rebuildobjects = BoolProperty(
                name="Rebuild Objects",
                description="In case of deform skeleton mesh and animations data - "
                            "This will rebuild objects from raw format on export when checked",
                default=False
                )
    
        @classmethod
        def poll(cls, context):
    
            return context.active_object is not None
    
        def execute(self, context):
            scene = bpy.context.scene
    
            scene.udk_option_export_psk = (scene.udk_option_export == '0' or scene.udk_option_export == '2')
            scene.udk_option_export_psa = (scene.udk_option_export == '1' or scene.udk_option_export == '2')
            bpy.context.scene.udk_option_scale = self.udk_option_scale
            bpy.context.scene.udk_option_rebuildobjects = self.udk_option_rebuildobjects
    
            restore_frame = scene.frame_current
    
            message = "Finish Export!"
            try:
                export(filepath)
    
            except Error as err:
                print(err.message)
                message = err.message
    
            scene.frame_set(restore_frame)
    
            self.report({'WARNING', 'INFO'}, message)
            return {'FINISHED'}
    
        def draw(self, context):
            layout = self.layout
            scene = context.scene
    
            layout.prop(scene, "udk_option_smoothing_groups")
    
            layout.prop(scene, "udk_option_clight_uv")
    
            layout.prop(scene, "udk_option_verbose")
            layout.prop(scene, "udk_option_filename_src")
            layout.prop(scene, "udk_option_export")
            layout.prop(self, "udk_option_scale")
            layout.prop(self, "udk_option_rebuildobjects")
    
    
        def invoke(self, context, event):
    
            self.udk_option_scale = bpy.context.scene.udk_option_scale
            self.udk_option_rebuildobjects = bpy.context.scene.udk_option_rebuildobjects
    
    
            wm = context.window_manager
            wm.fileselect_add(self)
    
    John Phan's avatar
    John Phan committed
            return {'RUNNING_MODAL'}
    
    def menu_func(self, context):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        default_path = os.path.splitext(bpy.data.filepath)[0] + ".psk"
    
        self.layout.operator(ExportUDKAnimData.bl_idname,
                             text="Skeleton Mesh / Animation Data (.psk/.psa)").filepath = default_path
    
    
    # Add-ons Preferences Update Panel
    
    # Define Panel classes for updating
    panels = (
            Panel_UDKExport,
            )
    
    
    def update_panel(self, context):
    
        message = "Export Unreal Engine Format(.psk/.psa): Updating Panel locations has failed"
    
            for panel in panels:
                if "bl_rna" in panel.__dict__:
                    bpy.utils.unregister_class(panel)
    
            for panel in panels:
                panel.bl_category = context.user_preferences.addons[__name__].preferences.category
                bpy.utils.register_class(panel)
    
        except Exception as e:
            print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
    
    
    class PskAddonPreferences(AddonPreferences):
    
        # this must match the addon name, use '__package__'
        # when defining this in a submodule of a python package.
        bl_idname = __name__
    
    
                name="Tab Category",
                description="Choose a name for the category of the panel",
    
                default="File I/O",
    
    
        def draw(self, context):
            layout = self.layout
    
            row = layout.row()
            col = row.column()
            col.label(text="Tab Category:")
            col.prop(self, "category", text="")
    
    
    
    # ===========================================================================
    
    # ===========================================================================
    
        bpy.types.TOPBAR_MT_file_export.append(menu_func)
    
        update_panel(None, bpy.context)
    
        # Added by [MGVS]
        bpy.types.Scene.udk_option_filename_src = EnumProperty(
                name="Filename",
                description="Sets the name for the files",
                items=[
                      ('0', "From object", "Name will be taken from object name"),
                      ('1', "From Blend", "Name will be taken from .blend file name")
                      ],
                default='0'
                )
        bpy.types.Scene.udk_option_export_psk = BoolProperty(
                name="bool export psa",
                description="Boolean for exporting psk format (Skeleton Mesh)",
                default=True
                )
        bpy.types.Scene.udk_option_export_psa = BoolProperty(
                name="bool export psa",
                description="Boolean for exporting psa format (Animation Data)",
                default=True
                )
    
        bpy.types.Scene.udk_option_clight_uv = BoolProperty(
    
                name="Clamp UV",
                description="True is to limit Clamp UV co-ordinates to [0-1]. False is unrestricted (x,y)",
                default=False
                )
        bpy.types.Scene.udk_copy_merge = BoolProperty(
                name="Merge Mesh",
                description="This will copy the mesh(s) and merge the object together "
                            "and unlink the mesh to be remove while exporting the object",
                default=False
                )
        bpy.types.Scene.udk_option_export = EnumProperty(
                name="Export",
                description="What to export",
                items=[
                      ('0', "Mesh only", "Exports the PSK file for the Skeletal Mesh"),
                      ('1', "Animation only", "Export the PSA file for Action Set(s)(Animations Data)"),
                      ('2', "Mesh & Animation", "Export both PSK and PSA files(Skeletal Mesh/Animation(s) Data)")
                      ],
                default='2'
                )
        bpy.types.Scene.udk_option_verbose = BoolProperty(
                name="Verbose",
                description="Verbose console output",
                default=False
                )
        bpy.types.Scene.udk_option_smoothing_groups = BoolProperty(
                name="Smooth Groups",
                description="Activate hard edges as smooth groups",
                default=True
                )
        bpy.types.Scene.udk_option_triangulate = BoolProperty(
                name="Triangulate Mesh",
                description="Convert Quads to Triangles",
                default=False
                )
        bpy.types.Scene.udk_option_selectanimations = BoolProperty(
                name="Select Animation(s)",
                description="Select animation(s) for export to psa file",
                default=False
                )
        bpy.types.Scene.udk_option_selectobjects = BoolProperty(
                name="Select Object(s)",
                description="Select Armature and Mesh(s). Just make sure mesh(s) is parent to armature",
                default=False
                )
        bpy.types.Scene.udk_option_rebuildobjects = BoolProperty(
                name="Rebuild Objects",
                description="In case of deform skeleton mesh and animations data - "
                            "This will rebuild objects from raw format on export when checked",
                default=False
                )
        bpy.types.Scene.udk_option_ignoreactiongroupnames = BoolProperty(
                name="Ignore Action Group Names",
                description="This will Ignore Action Set Group Names Check With Armature Bones. "
                            "It will override armature to set action set",
                default=False
                )
        bpy.types.Scene.udk_option_scale = FloatProperty(
                name="UDK Scale",
                description="In case you don't want to scale objects manually - "
                            "This will just scale position when on export for the skeleton mesh and animation data",
                default=1
                )
        bpy.types.Scene.udkas_list = CollectionProperty(
                                            type=UDKActionSetListPG
                                            )
        bpy.types.Scene.udkas_list_idx = IntProperty()
        bpy.types.Scene.udkobj_list = CollectionProperty(
                                            type=UDKObjListPG
                                            )
        bpy.types.Scene.udkobj_list_idx = IntProperty()
        bpy.types.Scene.udkmesh_list = CollectionProperty(
                                            type=UDKMeshListPG
                                            )
        bpy.types.Scene.udkmesh_list_idx = IntProperty()
        bpy.types.Scene.udkArm_list = CollectionProperty(
                                            type=UDKArmListPG
                                            )
        bpy.types.Scene.udkArm_list_idx = IntProperty()
    
    
    
        bpy.utils.unregister_module(__name__)
    
        bpy.types.TOPBAR_MT_file_export.remove(menu_func)
    
        del bpy.types.Scene.udk_option_filename_src
        del bpy.types.Scene.udk_option_export_psk
        del bpy.types.Scene.udk_option_export_psa
    
        del bpy.types.Scene.udk_option_clight_uv
    
        del bpy.types.Scene.udk_copy_merge
        del bpy.types.Scene.udk_option_export
        del bpy.types.Scene.udk_option_verbose
        del bpy.types.Scene.udk_option_smoothing_groups
        del bpy.types.Scene.udk_option_triangulate
        del bpy.types.Scene.udk_option_selectanimations
        del bpy.types.Scene.udk_option_selectobjects
        del bpy.types.Scene.udk_option_rebuildobjects
        del bpy.types.Scene.udk_option_ignoreactiongroupnames
        del bpy.types.Scene.udk_option_scale
        del bpy.types.Scene.udkas_list
        del bpy.types.Scene.udkas_list_idx
        del bpy.types.Scene.udkobj_list
        del bpy.types.Scene.udkobj_list_idx
        del bpy.types.Scene.udkmesh_list
        del bpy.types.Scene.udkmesh_list_idx
        del bpy.types.Scene.udkArm_list
        del bpy.types.Scene.udkArm_list_idx