OSDN Git Service

implement mqo_import.py
authorousttrue <ousttrue@gmail.com>
Sun, 6 Jun 2010 04:33:01 +0000 (13:33 +0900)
committerousttrue <ousttrue@gmail.com>
Sun, 6 Jun 2010 04:33:01 +0000 (13:33 +0900)
swig/blender/Makefile
swig/blender/cp.py [new file with mode: 0644]
swig/blender/cp.sh [deleted file]
swig/blender/mqo_import.py

index 176a817..0bf01d0 100644 (file)
@@ -1,5 +1,5 @@
 all: copy
 
 copy: mqo_import.py
-       ./cp.sh
+       /cygdrive/C/Python26/python cp.py $^
 
diff --git a/swig/blender/cp.py b/swig/blender/cp.py
new file mode 100644 (file)
index 0000000..f44832f
--- /dev/null
@@ -0,0 +1,40 @@
+import shutil
+
+DST_24=[
+        "T:/Blender/bf-blender/build2.4git/bin/Release/.blender/scripts",
+        "T:/Blender/bf-blender/build2.4git/bin/Debug/.blender/scripts",
+        "T:/Blender/blender-2.49b-windows/.blender/scripts",
+        ]
+
+MAP_25={
+        "mqo_import.py": "import_scene_mqo.py",
+        }
+
+DST_25=[
+        "T:/Blender/blender-2.5-alpha2-win32/.blender/scripts/io",
+        "T:/Blender/bf-blender/build2.5/bin/Debug/.blender/scripts/io",
+        "T:/Blender/bf-blender/build2.5git/bin/Release/.blender/scripts/io",
+        "T:/Blender/1340_Release/Release/.blender/scripts/io",
+        ]
+
+def copy24(src):
+    print("copy %s..." % src)
+    for dst in DST_24:
+        dst="%s/%s" % (dst, src)
+        print(dst)
+        shutil.copy(src, dst)
+
+def copy25(src):
+    print("copy %s..." % src)
+    for dst in DST_25:
+        dst="%s/%s" % (dst, MAP_25[src])
+        print(dst)
+        shutil.copy(src, dst)
+
+if __name__=="__main__":
+    import sys
+
+    for v in sys.argv[1:]:
+        copy24(v)
+        copy25(v)
+
diff --git a/swig/blender/cp.sh b/swig/blender/cp.sh
deleted file mode 100755 (executable)
index df4e175..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-DST="/cygdrive/T//Blender/bf-blender/build2.4git/bin/Release/.blender/scripts"
-cp *.py $DST
-
-DST="/cygdrive/T//Blender/bf-blender/build2.4git/bin/Debug/.blender/scripts"
-cp *.py $DST
-
-DST="T:/Blender/blender-2.49b-windows/.blender/scripts"
-cp *.py $DST
index cb05bc8..13d2aac 100644 (file)
@@ -22,6 +22,9 @@ This script imports a mqo into Blender for editing.
 0.6 20100505: C extension.\r
 0.7 20100606: integrate 2.4 and 2.5.\r
 '''\r
+###############################################################################\r
+# import\r
+###############################################################################\r
 import os\r
 import sys\r
 import math\r
@@ -32,7 +35,6 @@ from meshio import mqo
 def isBlender24():\r
     return sys.version_info[0]<3\r
 \r
-\r
 if isBlender24():\r
     # for 2.4\r
     import Blender\r
@@ -52,594 +54,807 @@ else:
     from bpy.props import *\r
 \r
 \r
-def has_mikoto(mqo):\r
-    return False\r
-\r
-\r
-def create_materials(scene, mqo, directory):\r
-    """\r
-    create blender materials and renturn material list.\r
-    """\r
-    materials = []\r
-    images = []\r
-    for m in mqo.materials:\r
-        material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING))\r
-        materials.append(material)\r
-\r
-        material.mode |= Blender.Material.Modes.SHADELESS\r
-        material.rgbCol = [m.color.r, m.color.g, m.color.b]\r
-        material.alpha = m.color.a\r
-        material.amb = m.ambient\r
-        material.spec = m.specular\r
-        material.hard = int(255 * m.power)\r
-        if m.texture!="":\r
-            texture_path=m.getTexture()\r
-\r
-            # load texture image\r
-            if os.path.isabs(texture_path):\r
-                # absolute\r
-                path = texture_path\r
+###############################################################################\r
+# implement\r
+###############################################################################\r
+if isBlender24():\r
+    def has_mikoto(mqo):\r
+        return False\r
+\r
+\r
+    def create_materials(scene, mqo, directory):\r
+        """\r
+        create blender materials and renturn material list.\r
+        """\r
+        materials = []\r
+        images = []\r
+        for m in mqo.materials:\r
+            material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING))\r
+            materials.append(material)\r
+\r
+            material.mode |= Blender.Material.Modes.SHADELESS\r
+            material.rgbCol = [m.color.r, m.color.g, m.color.b]\r
+            material.alpha = m.color.a\r
+            material.amb = m.ambient\r
+            material.spec = m.specular\r
+            material.hard = int(255 * m.power)\r
+            if m.texture!="":\r
+                texture_path=m.getTexture()\r
+\r
+                # load texture image\r
+                if os.path.isabs(texture_path):\r
+                    # absolute\r
+                    path = texture_path\r
+                else:\r
+                    # relative\r
+                    path = os.path.join(directory, texture_path)\r
+\r
+                # backslash to slash\r
+                #path = path.replace('\\', '/')\r
+\r
+                # texture\r
+                if os.path.exists(path):\r
+                    image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))\r
+                    images.append(image)\r
+                    material.mode = material.mode | Blender.Material.Modes.TEXFACE\r
+                    tex = Blender.Texture.New(path.encode(INTERNAL_ENCODING))\r
+                    tex.type = Blender.Texture.Types.IMAGE\r
+                    tex.image = image\r
+                    material.setTexture(0, tex, Blender.Texture.TexCo.UV)\r
+                else:\r
+                    print("%s not exits" % path)\r
+                \r
+        return materials\r
+\r
+\r
+    def create_objects(scene, root, mqo, materials):\r
+        """\r
+        create blender mesh objects.\r
+        """\r
+        # store hierarchy\r
+        stack=[root]    \r
+\r
+        objects=[]\r
+        for o in mqo.objects:\r
+            #print "%s:v(%d),f(%d)" % (o.name, len(o.vertices), len(o.faces))\r
+            # create mesh\r
+            mesh = Blender.Mesh.New()\r
+            mesh_object=scene.objects.new(mesh, o.name.encode('utf-8'))\r
+\r
+            # add hierarchy\r
+            stack_depth=len(stack)-1\r
+            print(o.depth, stack_depth)\r
+            if o.depth<stack_depth:\r
+                for i in range(stack_depth-o.depth):\r
+                    stack.pop()\r
+            stack[-1].makeParent([mesh_object])\r
+            stack.append(mesh_object)\r
+\r
+            if o.name.startswith('sdef'):\r
+                # add sdef object\r
+                objects.append(mesh_object)\r
+            elif o.name.startswith('anchor'):\r
+                #print("hide %s" % o.name)\r
+                #mesh_object.restrictDisplay=False\r
+                mesh_object.layers=[2]\r
+            elif o.name.startswith('bone'):\r
+                mesh_object.layers=[2]\r
+\r
+            # add vertices\r
+            mesh.verts.extend(Mathutils.Vector(0, 0, 0)) # dummy\r
+            mesh.verts.extend([(v.x, -v.z, v.y) for v in o.vertices])\r
+            # add faces\r
+            mesh_faces=[]\r
+            for face in o.faces:\r
+                face_indices=[]\r
+                for i in xrange(face.index_count):\r
+                    face_indices.append(face.getIndex(i)+1)\r
+                mesh_faces.append(face_indices)\r
+            #new_faces=mesh.faces.extend([face.indices for face in o.faces], \r
+            new_faces=mesh.faces.extend(mesh_faces,\r
+                    #ignoreDups=True, \r
+                    indexList=True)\r
+            mesh.update()\r
+            \r
+            # gather used materials\r
+            usedMaterials = {}\r
+            if new_faces:\r
+                for i in new_faces:\r
+                    if type(i) is int:\r
+                        usedMaterials[o.faces[i].material_index]=True\r
+\r
+            # blender limits 16 materials per mesh\r
+            # separate mesh ?\r
+            for i, material_index in enumerate(usedMaterials.keys()):\r
+                if i>=16:\r
+                    print("over 16 materials!")\r
+                    break\r
+                mesh.materials+=[materials[material_index]]\r
+                usedMaterials[material_index]=i\r
+            \r
+            # set face params\r
+            for i, f in enumerate(o.faces):       \r
+                if not type(new_faces[i]) is int:\r
+                    continue\r
+\r
+                face=mesh.faces[new_faces[i]]\r
+\r
+                uv_array=[]\r
+                for i in xrange(f.index_count):\r
+                    uv_array.append(Blender.Mathutils.Vector(\r
+                        f.getUV(i).x, \r
+                        1.0-f.getUV(i).y)\r
+                        )\r
+                try:\r
+                    face.uv=uv_array\r
+                except Exception as msg:\r
+                    #print msg\r
+                    #print face.index, uv_array\r
+                    pass\r
+            \r
+                if f.material_index in usedMaterials:\r
+                    face.mat = usedMaterials[f.material_index]\r
+\r
+                face.smooth = 1\r
+\r
+            # rmeove dummy 0 vertex\r
+            mesh.verts.delete(0)\r
+                \r
+            mesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH\r
+            mesh.maxSmoothAngle = int(o.smoothing)\r
+            mesh.smooth()\r
+            mesh.calcNormals()\r
+            mesh.flipNormals()\r
+            mesh.update()\r
+\r
+            # mirror modifier\r
+            if o.mirror:\r
+                mod=mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)\r
+\r
+        return objects\r
+\r
+\r
+    class MikotoBone(object):\r
+        __slots__=[\r
+                'name',\r
+                'iHead', 'iTail', 'iUp',\r
+                'vHead', 'vTail', 'vUp',\r
+                'parent', 'isFloating',\r
+                'children',\r
+                ]\r
+        def __init__(self, face=None, vertices=None, materials=None):\r
+            self.parent=None\r
+            self.isFloating=False\r
+            self.children=[]\r
+            if not face:\r
+                self.name='root'\r
+                return\r
+\r
+            self.name=materials[face.material_index].name.encode('utf-8')\r
+\r
+            i0=face.indices[0]\r
+            i1=face.indices[1]\r
+            i2=face.indices[2]\r
+            v0=vertices[i0]\r
+            v1=vertices[i1]\r
+            v2=vertices[i2]\r
+            e01=v1-v0\r
+            e12=v2-v1\r
+            e20=v0-v2\r
+            sqNorm0=e01.getSqNorm()\r
+            sqNorm1=e12.getSqNorm()\r
+            sqNorm2=e20.getSqNorm()\r
+            if sqNorm0>sqNorm1:\r
+                if sqNorm1>sqNorm2:\r
+                    # e01 > e12 > e20\r
+                    self.iHead=i2\r
+                    self.iTail=i1\r
+                    self.iUp=i0\r
+                else:\r
+                    if sqNorm0>sqNorm2:\r
+                        # e01 > e20 > e12\r
+                        self.iHead=i2\r
+                        self.iTail=i0\r
+                        self.iUp=i1\r
+                    else:\r
+                        # e20 > e01 > e12\r
+                        self.iHead=i1\r
+                        self.iTail=i0\r
+                        self.iUp=i2\r
             else:\r
-                # relative\r
-                path = os.path.join(directory, texture_path)\r
-\r
-            # backslash to slash\r
-            #path = path.replace('\\', '/')\r
-\r
-            # texture\r
-            if os.path.exists(path):\r
-                image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))\r
-                images.append(image)\r
-                material.mode = material.mode | Blender.Material.Modes.TEXFACE\r
-                tex = Blender.Texture.New(path.encode(INTERNAL_ENCODING))\r
-                tex.type = Blender.Texture.Types.IMAGE\r
-                tex.image = image\r
-                material.setTexture(0, tex, Blender.Texture.TexCo.UV)\r
+                # 0 < 1\r
+                if sqNorm1<sqNorm2:\r
+                    # e20 > e12 > e01\r
+                    self.iHead=i1\r
+                    self.iTail=i2\r
+                    self.iUp=i0\r
+                else:\r
+                    if sqNorm0<sqNorm2:\r
+                        # e12 > e20 > e01\r
+                        self.iHead=i0\r
+                        self.iTail=i2\r
+                        self.iUp=i1\r
+                    else:\r
+                        # e12 > e01 > e20\r
+                        self.iHead=i0\r
+                        self.iTail=i1\r
+                        self.iUp=i2\r
+            self.vHead=vertices[self.iHead]\r
+            self.vTail=vertices[self.iTail]\r
+            self.vUp=vertices[self.iUp]\r
+\r
+            if self.name.endswith('[]'):\r
+                basename=self.name[0:-2]\r
+                # expand LR name\r
+                if self.vTail.x>0:\r
+                    self.name="%s_L" % basename\r
+                else:\r
+                    self.name="%s_R" % basename\r
+\r
+\r
+        def setParent(self, parent, floating=False):\r
+            if floating:\r
+                self.isFloating=True\r
+            self.parent=parent\r
+            parent.children.append(self)\r
+\r
+        def printTree(self, indent=''):\r
+            print("%s%s" % (indent, self.name))\r
+            for child in self.children:\r
+                child.printTree(indent+'  ')\r
+\r
+\r
+    def build_armature(armature, mikotoBone, parent=None):\r
+        """\r
+        create a armature bone.\r
+        """\r
+        bone = Armature.Editbone()\r
+        bone.name = mikotoBone.name.encode('utf-8')\r
+        armature.bones[bone.name] = bone\r
+\r
+        bone.head = Mathutils.Vector(*mikotoBone.vHead.to_a())\r
+        bone.tail = Mathutils.Vector(*mikotoBone.vTail.to_a())\r
+        if parent:\r
+            bone.parent=parent\r
+            if mikotoBone.isFloating:\r
+                pass\r
             else:\r
-                print("%s not exits" % path)\r
-            \r
-    return materials\r
+                bone.options=[Armature.CONNECTED]\r
 \r
+        for child in mikotoBone.children:\r
+            build_armature(armature, child, bone)\r
 \r
-def create_objects(scene, root, mqo, materials):\r
-    """\r
-    create blender mesh objects.\r
-    """\r
-    # store hierarchy\r
-    stack=[root]    \r
 \r
-    objects=[]\r
-    for o in mqo.objects:\r
-        #print "%s:v(%d),f(%d)" % (o.name, len(o.vertices), len(o.faces))\r
-        # create mesh\r
-        mesh = Blender.Mesh.New()\r
-        mesh_object=scene.objects.new(mesh, o.name.encode('utf-8'))\r
-\r
-        # add hierarchy\r
-        stack_depth=len(stack)-1\r
-        print(o.depth, stack_depth)\r
-        if o.depth<stack_depth:\r
-            for i in range(stack_depth-o.depth):\r
-                stack.pop()\r
-        stack[-1].makeParent([mesh_object])\r
-        stack.append(mesh_object)\r
-\r
-        if o.name.startswith('sdef'):\r
-            # add sdef object\r
-            objects.append(mesh_object)\r
-        elif o.name.startswith('anchor'):\r
-            #print("hide %s" % o.name)\r
-            #mesh_object.restrictDisplay=False\r
-            mesh_object.layers=[2]\r
-        elif o.name.startswith('bone'):\r
-            mesh_object.layers=[2]\r
-\r
-        # add vertices\r
-        mesh.verts.extend(Mathutils.Vector(0, 0, 0)) # dummy\r
-        mesh.verts.extend([(v.x, -v.z, v.y) for v in o.vertices])\r
-        # add faces\r
-        mesh_faces=[]\r
-        for face in o.faces:\r
-            face_indices=[]\r
-            for i in xrange(face.index_count):\r
-                face_indices.append(face.getIndex(i)+1)\r
-            mesh_faces.append(face_indices)\r
-        #new_faces=mesh.faces.extend([face.indices for face in o.faces], \r
-        new_faces=mesh.faces.extend(mesh_faces,\r
-                #ignoreDups=True, \r
-                indexList=True)\r
-        mesh.update()\r
-        \r
-        # gather used materials\r
-        usedMaterials = {}\r
-        if new_faces:\r
-            for i in new_faces:\r
-                if type(i) is int:\r
-                    usedMaterials[o.faces[i].material_index]=True\r
-\r
-        # blender limits 16 materials per mesh\r
-        # separate mesh ?\r
-        for i, material_index in enumerate(usedMaterials.keys()):\r
-            if i>=16:\r
-                print("over 16 materials!")\r
+    def create_armature(scene, mqo):\r
+        """\r
+        create armature\r
+        """\r
+        boneObject=None\r
+        for o in mqo.objects:\r
+            if o.name.startswith('bone'):\r
+                boneObject=o\r
                 break\r
-            mesh.materials+=[materials[material_index]]\r
-            usedMaterials[material_index]=i\r
-        \r
-        # set face params\r
-        for i, f in enumerate(o.faces):       \r
-            if not type(new_faces[i]) is int:\r
+        if not boneObject:\r
+            return\r
+\r
+        tailMap={}\r
+        for f in boneObject.faces:\r
+            if f.index_count!=3:\r
+                print("invalid index_count: %d" % f.index_count)\r
                 continue\r
+            b=MikotoBone(f, boneObject.vertices, mqo.materials)\r
+            tailMap[b.iTail]=b\r
+\r
+        #################### \r
+        # build mikoto bone tree\r
+        #################### \r
+        mikotoRoot=MikotoBone()\r
+\r
+        for b in tailMap.values():\r
+            # each bone has unique parent or is root bone.\r
+            if b.iHead in tailMap:\r
+                b.setParent(tailMap[b.iHead])\r
+            else: \r
+                isFloating=False\r
+                for e in boneObject.edges:\r
+                    if  b.iHead==e.indices[0]:\r
+                        # floating bone\r
+                        if e.indices[1] in tailMap:\r
+                            b.setParent(tailMap[e.indices[1]], True)\r
+                            isFloating=True\r
+                            break\r
+                    elif b.iHead==e.indices[1]:\r
+                        # floating bone\r
+                        if e.indices[0] in tailMap:\r
+                            b.setParent(tailMap[e.indices[0]], True)\r
+                            isFloating=True\r
+                            break\r
+                if isFloating:\r
+                    continue\r
+\r
+                # no parent bone\r
+                b.setParent(mikotoRoot, True)\r
+\r
+        if len(mikotoRoot.children)==0:\r
+            print("no root bone")\r
+            return\r
 \r
-            face=mesh.faces[new_faces[i]]\r
+        if len(mikotoRoot.children)==1:\r
+            # single root\r
+            mikotoRoot=mikotoRoot.children[0]\r
+            mikotoRoot.parent=None\r
+        else:\r
+            mikotoRoot.vHead=Vector3(0, 10, 0)\r
+            mikotoRoot.vTail=Vector3(0, 0, 0)\r
+\r
+        #################### \r
+        # create armature\r
+        #################### \r
+        armature = Armature.New()\r
+        # link to object\r
+        armature_object = scene.objects.new(armature)\r
+        # create action\r
+        act = Armature.NLA.NewAction()\r
+        act.setActive(armature_object)\r
+        # set XRAY\r
+        armature_object.drawMode |= Object.DrawModes.XRAY\r
+        # armature settings\r
+        armature.drawType = Armature.OCTAHEDRON\r
+        armature.envelopes = False\r
+        armature.vertexGroups = True\r
+        armature.mirrorEdit = True\r
+        armature.drawNames=True\r
+\r
+        # edit bones\r
+        armature.makeEditable()\r
+        build_armature(armature, mikotoRoot)\r
+        armature.update()\r
+\r
+        return armature_object\r
+            \r
 \r
-            uv_array=[]\r
-            for i in xrange(f.index_count):\r
-                uv_array.append(Blender.Mathutils.Vector(\r
-                    f.getUV(i).x, \r
-                    1.0-f.getUV(i).y)\r
-                    )\r
-            try:\r
-                face.uv=uv_array\r
-            except Exception, msg:\r
-                #print msg\r
-                #print face.index, uv_array\r
-                pass\r
-        \r
-            if f.material_index in usedMaterials:\r
-                face.mat = usedMaterials[f.material_index]\r
+    class TrianglePlane(object):\r
+        """\r
+        mikoto方式ボーンのアンカーウェイト計算用。\r
+        (不完全)\r
+        """\r
+        __slots__=['normal', \r
+                'v0', 'v1', 'v2',\r
+                ]\r
+        def __init__(self, v0, v1, v2):\r
+            self.v0=v0\r
+            self.v1=v1\r
+            self.v2=v2\r
+\r
+        def isInsideXY(self, p):\r
+            v0=Vector2(self.v0.x, self.v0.y)\r
+            v1=Vector2(self.v1.x, self.v1.y)\r
+            v2=Vector2(self.v2.x, self.v2.y)\r
+            e01=v1-v0\r
+            e12=v2-v1\r
+            e20=v0-v2\r
+            c0=Vector2.cross(e01, p-v0)\r
+            c1=Vector2.cross(e12, p-v1)\r
+            c2=Vector2.cross(e20, p-v2)\r
+            if c0>=0 and c1>=0 and c2>=0:\r
+                return True\r
+            if c0<=0 and c1<=0 and c2<=0:\r
+                return True\r
 \r
-            face.smooth = 1\r
+        def isInsideYZ(self, p):\r
+            v0=Vector2(self.v0.y, self.v0.z)\r
+            v1=Vector2(self.v1.y, self.v1.z)\r
+            v2=Vector2(self.v2.y, self.v2.z)\r
+            e01=v1-v0\r
+            e12=v2-v1\r
+            e20=v0-v2\r
+            c0=Vector2.cross(e01, p-v0)\r
+            c1=Vector2.cross(e12, p-v1)\r
+            c2=Vector2.cross(e20, p-v2)\r
+            if c0>=0 and c1>=0 and c2>=0:\r
+                return True\r
+            if c0<=0 and c1<=0 and c2<=0:\r
+                return True\r
 \r
-        # rmeove dummy 0 vertex\r
-        mesh.verts.delete(0)\r
-            \r
-        mesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH\r
-        mesh.maxSmoothAngle = int(o.smoothing)\r
-        mesh.smooth()\r
-        mesh.calcNormals()\r
-        mesh.flipNormals()\r
-        mesh.update()\r
-\r
-        # mirror modifier\r
-        if o.mirror:\r
-            mod=mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)\r
-\r
-    return objects\r
-\r
-\r
-class MikotoBone(object):\r
-    __slots__=[\r
-            'name',\r
-            'iHead', 'iTail', 'iUp',\r
-            'vHead', 'vTail', 'vUp',\r
-            'parent', 'isFloating',\r
-            'children',\r
-            ]\r
-    def __init__(self, face=None, vertices=None, materials=None):\r
-        self.parent=None\r
-        self.isFloating=False\r
-        self.children=[]\r
-        if not face:\r
-            self.name='root'\r
-            return\r
+        def isInsideZX(self, p):\r
+            v0=Vector2(self.v0.z, self.v0.x)\r
+            v1=Vector2(self.v1.z, self.v1.x)\r
+            v2=Vector2(self.v2.z, self.v2.x)\r
+            e01=v1-v0\r
+            e12=v2-v1\r
+            e20=v0-v2\r
+            c0=Vector2.cross(e01, p-v0)\r
+            c1=Vector2.cross(e12, p-v1)\r
+            c2=Vector2.cross(e20, p-v2)\r
+            if c0>=0 and c1>=0 and c2>=0:\r
+                return True\r
+            if c0<=0 and c1<=0 and c2<=0:\r
+                return True\r
 \r
-        self.name=materials[face.material_index].name.encode('utf-8')\r
-\r
-        i0=face.indices[0]\r
-        i1=face.indices[1]\r
-        i2=face.indices[2]\r
-        v0=vertices[i0]\r
-        v1=vertices[i1]\r
-        v2=vertices[i2]\r
-        e01=v1-v0\r
-        e12=v2-v1\r
-        e20=v0-v2\r
-        sqNorm0=e01.getSqNorm()\r
-        sqNorm1=e12.getSqNorm()\r
-        sqNorm2=e20.getSqNorm()\r
-        if sqNorm0>sqNorm1:\r
-            if sqNorm1>sqNorm2:\r
-                # e01 > e12 > e20\r
-                self.iHead=i2\r
-                self.iTail=i1\r
-                self.iUp=i0\r
-            else:\r
-                if sqNorm0>sqNorm2:\r
-                    # e01 > e20 > e12\r
-                    self.iHead=i2\r
-                    self.iTail=i0\r
-                    self.iUp=i1\r
-                else:\r
-                    # e20 > e01 > e12\r
-                    self.iHead=i1\r
-                    self.iTail=i0\r
-                    self.iUp=i2\r
-        else:\r
-            # 0 < 1\r
-            if sqNorm1<sqNorm2:\r
-                # e20 > e12 > e01\r
-                self.iHead=i1\r
-                self.iTail=i2\r
-                self.iUp=i0\r
-            else:\r
-                if sqNorm0<sqNorm2:\r
-                    # e12 > e20 > e01\r
-                    self.iHead=i0\r
-                    self.iTail=i2\r
-                    self.iUp=i1\r
-                else:\r
-                    # e12 > e01 > e20\r
-                    self.iHead=i0\r
-                    self.iTail=i1\r
-                    self.iUp=i2\r
-        self.vHead=vertices[self.iHead]\r
-        self.vTail=vertices[self.iTail]\r
-        self.vUp=vertices[self.iUp]\r
-\r
-        if self.name.endswith('[]'):\r
-            basename=self.name[0:-2]\r
-            # expand LR name\r
-            if self.vTail.x>0:\r
-                self.name="%s_L" % basename\r
+\r
+    class MikotoAnchor(object):\r
+        """\r
+        mikoto方式スケルトンのアンカー。\r
+        """\r
+        __slots__=[\r
+                "triangles", "bbox",\r
+                ]\r
+        def __init__(self):\r
+            self.triangles=[]\r
+            self.bbox=None\r
+\r
+        def push(self, face, vertices):\r
+            if face.index_count==3:\r
+                self.triangles.append(TrianglePlane(\r
+                    vertices[face.indices[0]],\r
+                    vertices[face.indices[1]],\r
+                    vertices[face.indices[2]]\r
+                    ))\r
+            elif face.index_count==4:\r
+                self.triangles.append(TrianglePlane(\r
+                    vertices[face.indices[0]],\r
+                    vertices[face.indices[1]],\r
+                    vertices[face.indices[2]]\r
+                    ))\r
+                self.triangles.append(TrianglePlane(\r
+                    vertices[face.indices[2]],\r
+                    vertices[face.indices[3]],\r
+                    vertices[face.indices[0]]\r
+                    ))\r
+            # bounding box\r
+            if not self.bbox:\r
+                self.bbox=BoundingBox(vertices[face.indices[0]])\r
+            for i in face.indices:\r
+                self.bbox.expand(vertices[i])\r
+\r
+\r
+        def calcWeight(self, v):\r
+            if not self.bbox.isInside(v):\r
+                return 0\r
+\r
+            if self.anyXY(v.x, v.y) and self.anyYZ(v.y, v.z) and self.anyZX(v.z, v.x):\r
+                return 1.0\r
             else:\r
-                self.name="%s_R" % basename\r
-\r
-\r
-    def setParent(self, parent, floating=False):\r
-        if floating:\r
-            self.isFloating=True\r
-        self.parent=parent\r
-        parent.children.append(self)\r
-\r
-    def printTree(self, indent=''):\r
-        print("%s%s" % (indent, self.name))\r
-        for child in self.children:\r
-            child.printTree(indent+'  ')\r
-\r
-\r
-def build_armature(armature, mikotoBone, parent=None):\r
-    """\r
-    create a armature bone.\r
-    """\r
-    bone = Armature.Editbone()\r
-    bone.name = mikotoBone.name.encode('utf-8')\r
-    armature.bones[bone.name] = bone\r
-\r
-    bone.head = Mathutils.Vector(*mikotoBone.vHead.to_a())\r
-    bone.tail = Mathutils.Vector(*mikotoBone.vTail.to_a())\r
-    if parent:\r
-        bone.parent=parent\r
-        if mikotoBone.isFloating:\r
-            pass\r
-        else:\r
-            bone.options=[Armature.CONNECTED]\r
-\r
-    for child in mikotoBone.children:\r
-        build_armature(armature, child, bone)\r
-\r
-\r
-def create_armature(scene, mqo):\r
-    """\r
-    create armature\r
-    """\r
-    boneObject=None\r
-    for o in mqo.objects:\r
-        if o.name.startswith('bone'):\r
-            boneObject=o\r
-            break\r
-    if not boneObject:\r
-        return\r
-\r
-    tailMap={}\r
-    for f in boneObject.faces:\r
-        if f.index_count!=3:\r
-            print("invalid index_count: %d" % f.index_count)\r
-            continue\r
-        b=MikotoBone(f, boneObject.vertices, mqo.materials)\r
-        tailMap[b.iTail]=b\r
-\r
-    #################### \r
-    # build mikoto bone tree\r
-    #################### \r
-    mikotoRoot=MikotoBone()\r
-\r
-    for b in tailMap.values():\r
-        # each bone has unique parent or is root bone.\r
-        if b.iHead in tailMap:\r
-            b.setParent(tailMap[b.iHead])\r
-        else: \r
-            isFloating=False\r
-            for e in boneObject.edges:\r
-                if  b.iHead==e.indices[0]:\r
-                    # floating bone\r
-                    if e.indices[1] in tailMap:\r
-                        b.setParent(tailMap[e.indices[1]], True)\r
-                        isFloating=True\r
-                        break\r
-                elif b.iHead==e.indices[1]:\r
-                    # floating bone\r
-                    if e.indices[0] in tailMap:\r
-                        b.setParent(tailMap[e.indices[0]], True)\r
-                        isFloating=True\r
-                        break\r
-            if isFloating:\r
-                continue\r
+                return 0\r
+            \r
+        def anyXY(self, x, y):\r
+            for t in self.triangles:\r
+                if t.isInsideXY(Vector2(x, y)):\r
+                    return True\r
+            return False\r
+\r
+        def anyYZ(self, y, z):\r
+            for t in self.triangles:\r
+                if t.isInsideYZ(Vector2(y, z)):\r
+                    return True\r
+            return False\r
+\r
+        def anyZX(self, z, x):\r
+            for t in self.triangles:\r
+                if t.isInsideZX(Vector2(z, x)):\r
+                    return True\r
+            return False\r
+\r
+\r
+    def create_bone_weight(scene, mqo, armature_object, objects):\r
+        """\r
+        create mikoto bone weight.\r
+        """\r
+        anchorMap={}\r
+        # setup mikoto anchors\r
+        for o in mqo.objects:\r
+            if o.name.startswith("anchor"):\r
+                for f in o.faces:\r
+                    name=mqo.materials[f.material_index].name\r
+                    if name.endswith('[]'):\r
+                        basename=name[0:-2]\r
+                        v=o.vertices[f.indices[0]]\r
+                        if(v.x>0):\r
+                            # L\r
+                            name_L=basename+'_L'\r
+                            if not name_L in anchorMap:\r
+                                anchorMap[name_L]=MikotoAnchor()\r
+                            anchorMap[name_L].push(f, o.vertices)\r
+                        elif(v.x<0):\r
+                            # R\r
+                            name_R=basename+'_R'\r
+                            if not name_R in anchorMap:\r
+                                anchorMap[name_R]=MikotoAnchor()\r
+                            anchorMap[name_R].push(f, o.vertices)\r
+                        else:\r
+                            print("no side", v)\r
+                    else:\r
+                        if not name in anchorMap:\r
+                            anchorMap[name]=MikotoAnchor()\r
+                        anchorMap[name].push(f, o.vertices)\r
+\r
+        for o in objects:\r
+            # add armature modifier\r
+            mod=o.modifiers.append(Modifier.Types.ARMATURE)\r
+            mod[Modifier.Settings.OBJECT] = armature_object\r
+            mod[Modifier.Settings.ENVELOPES] = False\r
+            o.makeDisplayList()\r
+            # create vertex group\r
+            mesh=o.getData(mesh=True)\r
+            for name in anchorMap.keys():\r
+                mesh.addVertGroup(name)\r
+            mesh.update()\r
+                     \r
+        # assing vertices to vertex group\r
+        for o in objects:\r
+            mesh=o.getData(mesh=True)\r
+            for i, mvert in enumerate(mesh.verts):\r
+                hasWeight=False\r
+                for name, anchor in anchorMap.items():\r
+                    weight=anchor.calcWeight(mvert.co)\r
+                    if weight>0:\r
+                        mesh.assignVertsToGroup(\r
+                                name, [i], weight, Mesh.AssignModes.ADD)\r
+                        hasWeight=True\r
+                if not hasWeight:\r
+                    # debug orphan vertex\r
+                    print('orphan', mvert)\r
+            mesh.update()\r
+        \r
 \r
-            # no parent bone\r
-            b.setParent(mikotoRoot, True)\r
+    def execute_24(filename):\r
+        """\r
+        import a mqo file.\r
+        """\r
+        filename=filename.decode(INTERNAL_ENCODING)\r
+        print("##start mqo_import.py##")\r
+        print(INTERNAL_ENCODING, FS_ENCODING)\r
+        print("parse mqo file: %s" % (filename))\r
 \r
-    if len(mikotoRoot.children)==0:\r
-        print("no root bone")\r
-        return\r
+        Blender.Window.WaitCursor(1) \r
+        t = Blender.sys.time() \r
 \r
-    if len(mikotoRoot.children)==1:\r
-        # single root\r
-        mikotoRoot=mikotoRoot.children[0]\r
-        mikotoRoot.parent=None\r
-    else:\r
-        mikotoRoot.vHead=Vector3(0, 10, 0)\r
-        mikotoRoot.vTail=Vector3(0, 0, 0)\r
-\r
-    #################### \r
-    # create armature\r
-    #################### \r
-    armature = Armature.New()\r
-    # link to object\r
-    armature_object = scene.objects.new(armature)\r
-    # create action\r
-    act = Armature.NLA.NewAction()\r
-    act.setActive(armature_object)\r
-    # set XRAY\r
-    armature_object.drawMode |= Object.DrawModes.XRAY\r
-    # armature settings\r
-    armature.drawType = Armature.OCTAHEDRON\r
-    armature.envelopes = False\r
-    armature.vertexGroups = True\r
-    armature.mirrorEdit = True\r
-    armature.drawNames=True\r
-\r
-    # edit bones\r
-    armature.makeEditable()\r
-    build_armature(armature, mikotoRoot)\r
-    armature.update()\r
-\r
-    return armature_object\r
+        # parse file\r
+        io=mqo.IO()\r
         \r
+        if not io.read(filename):\r
+            return\r
+\r
+        # get active scene\r
+        scene = Blender.Scene.GetCurrent()\r
+\r
+        # create materials\r
+        materials=create_materials(scene, io, os.path.dirname(filename))\r
+     \r
+        # create objects\r
+        root=scene.objects.new("Empty")\r
+        root.setName(os.path.basename(filename))\r
+        objects=create_objects(scene, root, io, materials)\r
+\r
+        if has_mikoto(io):\r
+            # create mikoto bone\r
+            armature_object=create_armature(scene, io)\r
+            if armature_object:\r
+                root.makeParent([armature_object])\r
 \r
-class TrianglePlane(object):\r
-    """\r
-    mikoto方式ボーンのアンカーウェイト計算用。\r
-    (不完全)\r
-    """\r
-    __slots__=['normal', \r
-            'v0', 'v1', 'v2',\r
-            ]\r
-    def __init__(self, v0, v1, v2):\r
-        self.v0=v0\r
-        self.v1=v1\r
-        self.v2=v2\r
-\r
-    def isInsideXY(self, p):\r
-        v0=Vector2(self.v0.x, self.v0.y)\r
-        v1=Vector2(self.v1.x, self.v1.y)\r
-        v2=Vector2(self.v2.x, self.v2.y)\r
-        e01=v1-v0\r
-        e12=v2-v1\r
-        e20=v0-v2\r
-        c0=Vector2.cross(e01, p-v0)\r
-        c1=Vector2.cross(e12, p-v1)\r
-        c2=Vector2.cross(e20, p-v2)\r
-        if c0>=0 and c1>=0 and c2>=0:\r
-            return True\r
-        if c0<=0 and c1<=0 and c2<=0:\r
-            return True\r
-\r
-    def isInsideYZ(self, p):\r
-        v0=Vector2(self.v0.y, self.v0.z)\r
-        v1=Vector2(self.v1.y, self.v1.z)\r
-        v2=Vector2(self.v2.y, self.v2.z)\r
-        e01=v1-v0\r
-        e12=v2-v1\r
-        e20=v0-v2\r
-        c0=Vector2.cross(e01, p-v0)\r
-        c1=Vector2.cross(e12, p-v1)\r
-        c2=Vector2.cross(e20, p-v2)\r
-        if c0>=0 and c1>=0 and c2>=0:\r
-            return True\r
-        if c0<=0 and c1<=0 and c2<=0:\r
-            return True\r
-\r
-    def isInsideZX(self, p):\r
-        v0=Vector2(self.v0.z, self.v0.x)\r
-        v1=Vector2(self.v1.z, self.v1.x)\r
-        v2=Vector2(self.v2.z, self.v2.x)\r
-        e01=v1-v0\r
-        e12=v2-v1\r
-        e20=v0-v2\r
-        c0=Vector2.cross(e01, p-v0)\r
-        c1=Vector2.cross(e12, p-v1)\r
-        c2=Vector2.cross(e20, p-v2)\r
-        if c0>=0 and c1>=0 and c2>=0:\r
-            return True\r
-        if c0<=0 and c1<=0 and c2<=0:\r
-            return True\r
-\r
-\r
-class MikotoAnchor(object):\r
-    """\r
-    mikoto方式スケルトンのアンカー。\r
-    """\r
-    __slots__=[\r
-            "triangles", "bbox",\r
-            ]\r
-    def __init__(self):\r
-        self.triangles=[]\r
-        self.bbox=None\r
-\r
-    def push(self, face, vertices):\r
-        if face.index_count==3:\r
-            self.triangles.append(TrianglePlane(\r
-                vertices[face.indices[0]],\r
-                vertices[face.indices[1]],\r
-                vertices[face.indices[2]]\r
-                ))\r
-        elif face.index_count==4:\r
-            self.triangles.append(TrianglePlane(\r
-                vertices[face.indices[0]],\r
-                vertices[face.indices[1]],\r
-                vertices[face.indices[2]]\r
-                ))\r
-            self.triangles.append(TrianglePlane(\r
-                vertices[face.indices[2]],\r
-                vertices[face.indices[3]],\r
-                vertices[face.indices[0]]\r
-                ))\r
-        # bounding box\r
-        if not self.bbox:\r
-            self.bbox=BoundingBox(vertices[face.indices[0]])\r
-        for i in face.indices:\r
-            self.bbox.expand(vertices[i])\r
-\r
-\r
-    def calcWeight(self, v):\r
-        if not self.bbox.isInside(v):\r
-            return 0\r
-\r
-        if self.anyXY(v.x, v.y) and self.anyYZ(v.y, v.z) and self.anyZX(v.z, v.x):\r
-            return 1.0\r
+                # create bone weight\r
+                create_bone_weight(scene, io, armature_object, objects)\r
+\r
+\r
+        print('finished in %.2f seconds' % (Blender.sys.time()-t))\r
+        print('')\r
+        Blender.Redraw()\r
+        Blender.Window.WaitCursor(0) \r
+\r
+\r
+else:\r
+    def create_texture(directory, texture_name):\r
+        texture=bpy.data.textures.new(texture_name)\r
+        texture.type='IMAGE'\r
+        texture=texture.recast_type()\r
+        #texturePath="%s/%s" % (directory, texture_name)\r
+        texturePath=os.path.join(directory, texture_name)\r
+        print('create_texture', texturePath)\r
+        image=bpy.data.images.load(texturePath)\r
+        texture.image=image\r
+        texture.mipmap = True\r
+        texture.interpolation = True\r
+        texture.use_alpha = True\r
+        return texture\r
+\r
+    def create_materials(mqo, scene, directory):\r
+        materials = []\r
+        textureMap={}\r
+        imageMap={}\r
+        if len(mqo.materials)>0:\r
+            for material_index, m in enumerate(mqo.materials):\r
+                material = bpy.data.materials.new(m.getName())\r
+                materials.append(material)\r
+                # mqo material\r
+                material.diffuse_color=[m.color.r, m.color.g, m.color.b]\r
+                material.alpha=m.color.a\r
+                material.diffuse_intensity=m.diffuse\r
+                texture_name=m.getTexture()\r
+                if texture_name!='':\r
+                    if texture_name in textureMap:\r
+                        texture=textureMap[texture_name]\r
+                    else:\r
+                        texture=create_texture(directory, texture_name)\r
+                        textureMap[texture_name]=texture\r
+                        imageMap[material_index]=texture.image\r
+                    #material.add_texture(texture, "UV", {"COLOR", "ALPHA"})\r
+                    material.add_texture(texture, "UV", "COLOR")\r
+                    # temporary\r
+                    material.emit=1.0\r
         else:\r
-            return 0\r
-        \r
-    def anyXY(self, x, y):\r
-        for t in self.triangles:\r
-            if t.isInsideXY(Vector2(x, y)):\r
-                return True\r
-        return False\r
+            material = bpy.data.materials.new('Default')\r
+            materials.append(material)\r
+        return materials, imageMap\r
 \r
-    def anyYZ(self, y, z):\r
-        for t in self.triangles:\r
-            if t.isInsideYZ(Vector2(y, z)):\r
-                return True\r
-        return False\r
+    def create_objects(mqo, scene, parent, materials, imageMap, scale):\r
+        for o in mqo.objects:\r
 \r
-    def anyZX(self, z, x):\r
-        for t in self.triangles:\r
-            if t.isInsideZX(Vector2(z, x)):\r
-                return True\r
-        return False\r
+            # create mesh\r
+            mesh=bpy.data.meshes.new("Mesh")\r
+            meshObject= bpy.data.objects.new(o.getName(), mesh)\r
+            scene.objects.link(meshObject)\r
+            meshObject.parent=parent\r
 \r
+            # count triangle and quadrangle\r
+            faceCount=0\r
+            for f in o.faces:\r
+                if f.index_count==3 or f.index_count==4:\r
+                    faceCount+=1\r
+            mesh.add_geometry(len(o.vertices), 0, faceCount)\r
+\r
+            # add vertex\r
+            unpackedVertices=[]\r
+            for v in o.vertices:\r
+                # convert right-handed y-up to right-handed z-up\r
+                unpackedVertices.extend(\r
+                        (scale*v.x, scale*-v.z, scale*v.y))\r
+            mesh.verts.foreach_set("co", unpackedVertices)\r
+\r
+            # add face\r
+            unpackedFaces = []\r
+            usedMaterial=set()\r
+\r
+            def getFace(f):\r
+                face = []\r
+                for i in range(f.index_count):\r
+                    face.append(f.getIndex(i))\r
+                return face\r
 \r
-def create_bone_weight(scene, mqo, armature_object, objects):\r
-    """\r
-    create mikoto bone weight.\r
-    """\r
-    anchorMap={}\r
-    # setup mikoto anchors\r
-    for o in mqo.objects:\r
-        if o.name.startswith("anchor"):\r
             for f in o.faces:\r
-                name=mqo.materials[f.material_index].name\r
-                if name.endswith('[]'):\r
-                    basename=name[0:-2]\r
-                    v=o.vertices[f.indices[0]]\r
-                    if(v.x>0):\r
-                        # L\r
-                        name_L=basename+'_L'\r
-                        if not name_L in anchorMap:\r
-                            anchorMap[name_L]=MikotoAnchor()\r
-                        anchorMap[name_L].push(f, o.vertices)\r
-                    elif(v.x<0):\r
-                        # R\r
-                        name_R=basename+'_R'\r
-                        if not name_R in anchorMap:\r
-                            anchorMap[name_R]=MikotoAnchor()\r
-                        anchorMap[name_R].push(f, o.vertices)\r
+                face=getFace(f)\r
+                if len(face) != 3 and len(face) != 4:\r
+                    print("{0} vertices in face.".format(len(face)))\r
+                    continue\r
+\r
+                if len(face) == 4:\r
+                    if face[3] == 0:\r
+                        # rotate indices if the 4th is 0\r
+                        face = [face[3], face[0], face[1], face[2]]\r
+                elif len(face) == 3:\r
+                    if face[2] == 0:\r
+                        # rotate indices if the 3rd is 0\r
+                        face = [face[2], face[0], face[1], 0]\r
                     else:\r
-                        print("no side", v)\r
-                else:\r
-                    if not name in anchorMap:\r
-                        anchorMap[name]=MikotoAnchor()\r
-                    anchorMap[name].push(f, o.vertices)\r
-\r
-    for o in objects:\r
-        # add armature modifier\r
-        mod=o.modifiers.append(Modifier.Types.ARMATURE)\r
-        mod[Modifier.Settings.OBJECT] = armature_object\r
-        mod[Modifier.Settings.ENVELOPES] = False\r
-        o.makeDisplayList()\r
-        # create vertex group\r
-        mesh=o.getData(mesh=True)\r
-        for name in anchorMap.keys():\r
-            mesh.addVertGroup(name)\r
-        mesh.update()\r
-                 \r
-    # assing vertices to vertex group\r
-    for o in objects:\r
-        mesh=o.getData(mesh=True)\r
-        for i, mvert in enumerate(mesh.verts):\r
-            hasWeight=False\r
-            for name, anchor in anchorMap.items():\r
-                weight=anchor.calcWeight(mvert.co)\r
-                if weight>0:\r
-                    mesh.assignVertsToGroup(\r
-                            name, [i], weight, Mesh.AssignModes.ADD)\r
-                    hasWeight=True\r
-            if not hasWeight:\r
-                # debug orphan vertex\r
-                print('orphan', mvert)\r
-        mesh.update()\r
-    \r
-\r
-def execute_24(filename):\r
-    """\r
-    import a mqo file.\r
-    """\r
-    filename=filename.decode(INTERNAL_ENCODING)\r
-    print "##start mqo_import.py##"\r
-    print INTERNAL_ENCODING, FS_ENCODING\r
-    print "parse mqo file: %s" % (filename)\r
-\r
-    Blender.Window.WaitCursor(1) \r
-    t = Blender.sys.time() \r
-\r
-    # parse file\r
-    io=mqo.IO()\r
-    \r
-    if not io.read(filename):\r
-        return\r
-\r
-    # get active scene\r
-    scene = Blender.Scene.GetCurrent()\r
-\r
-    # create materials\r
-    materials=create_materials(scene, io, os.path.dirname(filename))\r
\r
-    # create objects\r
-    root=scene.objects.new("Empty")\r
-    root.setName(os.path.basename(filename))\r
-    objects=create_objects(scene, root, io, materials)\r
+                        face.append(0)\r
 \r
-    if has_mikoto(io):\r
-        # create mikoto bone\r
-        armature_object=create_armature(scene, io)\r
-        if armature_object:\r
-            root.makeParent([armature_object])\r
+                unpackedFaces.extend(face)\r
+                usedMaterial.add(f.material_index)\r
+            try:\r
+                mesh.faces.foreach_set("verts_raw", unpackedFaces)\r
+            except:\r
+                #print([getFace(f) for f in o.faces])\r
+                print("fail to mesh.faces.foreach_set")\r
+                return\r
+\r
+            # add material\r
+            meshMaterialMap={}\r
+            materialIndex=0\r
+            for i in usedMaterial:\r
+                mesh.add_material(materials[i])\r
+                meshMaterialMap[i]=materialIndex\r
+                materialIndex+=1\r
+\r
+            # each face\r
+            mesh.add_uv_texture()\r
+            for mqo_face, blender_face, uv_face in zip(\r
+                    o.faces, mesh.faces, mesh.uv_textures[0].data):\r
+                if mqo_face.index_count<3:\r
+                    continue\r
+                blender_face.material_index=meshMaterialMap[mqo_face.material_index]\r
+                if mqo_face.index_count>=3:\r
+                    uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]\r
+                    uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]\r
+                    uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]\r
+                    if mqo_face.index_count==4:\r
+                        uv_face.uv4=[\r
+                                mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]\r
+                if materials[mqo_face.material_index] in imageMap:\r
+                    uv_face.image=imageMap[mqo_face.material_index]\r
+                    uv_face.tex=True\r
+\r
+            mesh.update()\r
+\r
+    def load(filename, context, scale):\r
+        """\r
+        load mqo file to context.\r
+        """\r
+        io=mqo.IO()\r
+        if not io.read(filename):\r
+            print("fail to load",filename)\r
+            return\r
 \r
-            # create bone weight\r
-            create_bone_weight(scene, io, armature_object, objects)\r
+        scene=context.scene\r
 \r
+        # create material\r
+        materials, imageMap=create_materials(\r
+                io, scene, os.path.dirname(filename))\r
 \r
-    print('finished in %.2f seconds' % (Blender.sys.time()-t))\r
-    print('')\r
-    Blender.Redraw()\r
-    Blender.Window.WaitCursor(0) \r
+        # create group\r
+        empty=bpy.data.objects.new(os.path.basename(filename), None)\r
+        scene.objects.link(empty)\r
 \r
+        # create mesh\r
+        create_objects(io, scene, empty, materials, imageMap, scale)\r
\r
 \r
+###############################################################################\r
+# register\r
+###############################################################################\r
 if isBlender24():\r
     # for 2.4\r
+    # execute\r
     Blender.Window.FileSelector(execute_24, 'Import MQO', '*.mqo')\r
 else:\r
     # for 2.5\r
-    pass\r
+    # import operator\r
+    class IMPORT_OT_mqo(bpy.types.Operator):\r
+        '''Import from Metasequoia file format (.mqo)'''\r
+        bl_idname = "import_scene.mqo"\r
+        bl_label = 'Import MQO'\r
+\r
+        # List of operator properties, the attributes will be assigned\r
+        # to the class instance from the operator settings before calling.\r
+\r
+        path = StringProperty(\r
+                name="File Path", \r
+                description="File path used for importing the MQO file", \r
+                maxlen= 1024, default= "")\r
+        filename = StringProperty(\r
+                name="File Name", \r
+                description="Name of the file.")\r
+        directory = StringProperty(\r
+                name="Directory", \r
+                description="Directory of the file.")\r
+\r
+        scale = FloatProperty(\r
+                name="Scale", \r
+                description="Scale the MQO by this value", \r
+                min=0.0001, max=1000000.0, \r
+                soft_min=0.001, soft_max=100.0, default=1.0)\r
+\r
+        def execute(self, context):\r
+            load(self.properties.path, context, self.properties.scale)\r
+            return 'FINISHED'\r
+\r
+        def invoke(self, context, event):\r
+            wm=context.manager\r
+            wm.add_fileselect(self)\r
+            return 'RUNNING_MODAL'\r
+\r
+\r
+    # register menu\r
+    def menu_func(self, context): \r
+        self.layout.operator(IMPORT_OT_mqo.bl_idname, \r
+                text="Metasequoia (.mqo)")\r
+\r
+    def register():\r
+        bpy.types.register(IMPORT_OT_mqo)\r
+        bpy.types.INFO_MT_file_import.append(menu_func)\r
+\r
+    def unregister():\r
+        bpy.types.unregister(IMPORT_OT_mqo)\r
+        bpy.types.INFO_MT_file_import.remove(menu_func)\r
+\r
+    if __name__=="__main__":\r
+        register()\r
 \r