summaryrefslogtreecommitdiffstats
path: root/tools/utils/exporters/blender/qt3d_armature_export.py
blob: 48a197115db0dd513e361317dc2b0aaf1f0a1af6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

# Required Blender information.
bl_info = {
           "name": "Qt3D Armature Exporter",
           "author": "Sean Harmer <sean.harmer@kdab.com>, Robert Brock <robert.brock@kdab.com>",
           "version": (0, 2),
           "blender": (2, 80, 0),
           "location": "File > Export > Qt3D Armature Exporter (.json)",
           "description": "Export Armature to json to use with Qt3D",
           "warning": "",
           "wiki_url": "",
           "tracker_url": "",
           "category": "Import-Export"
          }

import bpy
import os
import struct
import mathutils
import math
import json
from array import array
from bpy import context
from bpy_extras.io_utils import ExportHelper
from bpy.props import (
        BoolProperty,
        FloatProperty,
        StringProperty,
        EnumProperty,
        )
from collections import defaultdict

def jsonBuilder():
    bonesList = []
    name = ""
    boneParent = ""

    ob = bpy.context.object.data

    if not hasattr(ob, 'bones'):
        return bonesList

    for bone in ob.bones:

        #check parent exists
        if bone.parent:
            boneParent = bone.parent.name
        else:
            boneParent = ""

        #add the bones
        bonesList.append({"bone": bone.name,
                          "parent": boneParent,
                          "matrix": jsonMatrix(bone)
                          })

    return bonesList

def jsonMatrix(bone):
    matrix = []

    for i in range(0, 4):
        matrix.append(str("%.4f, %.4f, %.4f, %.4f" % (bone.matrix_local[i][0],
                                                      bone.matrix_local[i][1],
                                                      bone.matrix_local[i][2],
                                                      bone.matrix_local[i][3])))

    return matrix


class Qt3DMeshDataConverter:

    def boneInfoToJson(self):
        # Pass 1 - collect data we need to produce the output in pass 2
        print(">>> About to enter Objects")

        jsonData = json.dumps({ "bones": jsonBuilder()}, indent=2, sort_keys=True, separators=(',', ': '))
        return jsonData


class Qt3DArmatureExporter(bpy.types.Operator, ExportHelper):
    """Qt3D Exporter"""
    bl_idname       = "export_scene.qt3d_armature_exporter";
    bl_label        = "Qt3DArmatureExporter";
    bl_options      = {'PRESET'};

    filename_ext = ""
    use_filter_folder = True

    def __init__(self):
        pass

    def execute(self, context):
        print("In Execute" + bpy.context.scene.name)

        self.userpath = self.properties.filepath

        # unselect all
        bpy.ops.object.select_all(action='DESELECT')

        converter = Qt3DMeshDataConverter()
        fileContent = converter.boneInfoToJson()
        with open(self.userpath + ".json", '+w') as f:
            f.write(fileContent)

        return {'FINISHED'}

def createBlenderMenu(self, context):
    self.layout.operator(Qt3DArmatureExporter.bl_idname, text="Qt3D Armature Export(.json)")

# Register against Blender
def register():
    bpy.utils.register_class(Qt3DArmatureExporter)
    if bpy.app.version < (2, 80, 0):
        bpy.types.INFO_MT_file_export.append(createBlenderMenu)
    else:
        bpy.types.TOPBAR_MT_file_export.append(createBlenderMenu)

def unregister():
    bpy.utils.unregister_class(Qt3DArmatureExporter)
    if bpy.app.version < (2, 80, 0):
        bpy.types.INFO_MT_file_export.remove(createBlenderMenu)
    else:
        bpy.types.TOPBAR_MT_file_export.remove(createBlenderMenu)

# Handle running the script from Blender's text editor.
if (__name__ == "__main__"):
   register();
   bpy.ops.export_scene.qt3d_Armature_exporter();