OSDN Git Service

fix emmit typo. update maaterial import.
[meshio/meshio.git] / swig / blender / mqo_import.py
index 745102c..630501e 100644 (file)
@@ -22,12 +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
 0.8 20100619: fix multibyte object name.\r
+0.9 20100626: refactoring.\r
 '''\r
 \r
-\r
-###############################################################################\r
-# import\r
-###############################################################################\r
 import os\r
 import sys\r
 \r
@@ -45,6 +42,21 @@ if isBlender24():
 \r
     # wrapper\r
     import bl24 as bl\r
+\r
+    def createMqoMaterial(m):\r
+        material = Blender.Material.New(\r
+                m.getName().encode(bl.INTERNAL_ENCODING))\r
+        #material.mode |= Blender.Material.Modes.SHADELESS\r
+        # diffuse\r
+        material.rgbCol = [m.color.r, m.color.g, m.color.b]\r
+        material.alpha = m.color.a\r
+        # other\r
+        material.amb=m.ambient\r
+        material.spec=m.specular\r
+        material.hard=int(255 * m.power)\r
+        material.emit=m.emmit\r
+        return material\r
+\r
 else:\r
     # for 2.5\r
     import bpy\r
@@ -53,6 +65,23 @@ else:
     # wrapper\r
     import bl25 as bl\r
 \r
+    def createMqoMaterial(m):\r
+        material = bpy.data.materials.new(m.getName())\r
+        # shader\r
+        if m.shader==1:\r
+            material.diffuse_shader='FRESNEL'\r
+        else:\r
+            material.diffuse_shader='LAMBERT'\r
+        # diffuse\r
+        material.diffuse_color=[m.color.r, m.color.g, m.color.b]\r
+        material.diffuse_intensity=m.diffuse\r
+        material.alpha=m.color.a\r
+        # other\r
+        material.ambient = m.ambient\r
+        #material.specular = m.specular\r
+        material.emit=m.emit\r
+        return material\r
+\r
 \r
 def has_mikoto(mqo):\r
     #for o in mqo.objects:\r
@@ -65,7 +94,7 @@ def has_mikoto(mqo):
     return False\r
 \r
 \r
-def __createMaterials(scene, mqo, directory):\r
+def __createMaterials(mqo, directory):\r
     """\r
     create blender materials and renturn material list.\r
     """\r
@@ -75,7 +104,7 @@ def __createMaterials(scene, mqo, directory):
     if len(mqo.materials)>0:\r
         for material_index, m in enumerate(mqo.materials):\r
             # material\r
-            material=bl.createMqoMaterial(m)\r
+            material=createMqoMaterial(m)\r
             materials.append(material)\r
             # texture\r
             texture_name=m.getTexture()\r
@@ -93,46 +122,91 @@ def __createMaterials(scene, mqo, directory):
                     # texture\r
                     if os.path.exists(path):\r
                         print("create texture:", path)\r
-                        texture, image=bl.createTexture(path)\r
+                        texture, image=bl.texture.create(path)\r
                         textureMap[texture_name]=texture\r
                         imageMap[material_index]=image\r
                     else:\r
                         print("%s not exits" % path)\r
                         continue\r
-                bl.materialAddTexture(material, texture)\r
+                bl.material.addTexture(material, texture)\r
     else:\r
         # default material\r
         pass\r
     return materials, imageMap\r
 \r
 \r
-def __createObjects(scene, mqo, root, materials, imageMap, scale):\r
+def __createObjects(mqo, root, materials, imageMap, scale):\r
     """\r
     create blender mesh objects.\r
     """\r
-    # store hierarchy\r
+    # tree stack\r
     stack=[root]    \r
     objects=[]\r
     for o in mqo.objects:\r
-        mesh, mesh_object=bl.createMesh(scene, o.getName())\r
+        mesh, mesh_object=bl.mesh.create(o.getName())\r
 \r
         # add hierarchy\r
         stack_depth=len(stack)-1\r
-        print(o.depth, stack_depth)\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
-        bl.objectMakeParent(stack[-1], mesh_object)\r
+        bl.object.makeParent(stack[-1], mesh_object)\r
         stack.append(mesh_object)\r
 \r
         if o.getName().startswith('sdef'):\r
             objects.append(mesh_object)\r
         elif o.getName().startswith('anchor'):\r
-            bl.objectLayerMask(mesh_object, [0, 1])\r
+            bl.object.setLayerMask(mesh_object, [0, 1])\r
         elif o.getName().startswith('bone'):\r
-            bl.objectLayerMask(mesh_object, [0, 1])\r
-\r
-        bl.meshAddMqoGeometry(mesh_object, o, materials, imageMap, scale)\r
+            bl.object.setLayerMask(mesh_object, [0, 1])\r
+\r
+        # geometry\r
+        vertices=[(v.x * scale, -v.z * scale, v.y * scale) for v in o.vertices]\r
+        faces=[]\r
+        materialMap={}\r
+        for f in o.faces:\r
+            face_indices=[]\r
+            # flip face\r
+            for i in reversed(range(f.index_count)):\r
+                face_indices.append(f.getIndex(i))\r
+            faces.append(face_indices)\r
+            materialMap[f.material_index]=True\r
+        bl.mesh.addGeometry(mesh, vertices, faces)\r
+\r
+        # blender limits 16 materials per mesh\r
+        for i, material_index in enumerate(materialMap.keys()):\r
+            if i>=16:\r
+                # split a mesh ?\r
+                print("over 16 materials!")\r
+                break\r
+            bl.mesh.addMaterial(mesh, materials[material_index])\r
+            materialMap[material_index]=i\r
\r
+        # set face params\r
+        assert(len(o.faces)==len(mesh.faces))\r
+        bl.mesh.addUV(mesh)\r
+        for i, (f, face) in enumerate(zip(o.faces, mesh.faces)):\r
+            uv_array=[]\r
+            # ToDo FIX\r
+            # flip face\r
+            for j in reversed(range(f.index_count)):\r
+                uv_array.append((f.getUV(j).x, 1.0-f.getUV(j).y))\r
+            bl.mesh.setFaceUV(mesh, i, face, uv_array, \r
+                    imageMap.get(f.material_index, None))\r
+            if f.material_index in materialMap:\r
+                bl.face.setMaterial(face, materialMap[f.material_index])\r
+            bl.face.setSmooth(face, True)\r
+\r
+        # mirror modifier\r
+        if o.mirror:\r
+            bl.modifier.addMirror(mesh_object)\r
+\r
+        # set smoothing\r
+        bl.mesh.setSmooth(mesh, o.smoothing)\r
+\r
+        # calc normal\r
+        bl.mesh.recalcNormals(mesh_object)\r
 \r
     return objects\r
 \r
@@ -251,7 +325,7 @@ def build_armature(armature, mikotoBone, parent=None):
         build_armature(armature, child, bone)\r
 \r
 \r
-def create_armature(scene, mqo):\r
+def create_armature(mqo):\r
     """\r
     create armature\r
     """\r
@@ -523,28 +597,30 @@ def create_bone_weight(scene, mqo, armature_object, objects):
         mesh.update()\r
 \r
 \r
-def __execute(filename, scene, scale=1.0):\r
+def __execute(filename, scene, scale=0.1):\r
     # parse file\r
     io=mqo.IO()\r
     if not io.read(filename):\r
-        print("fail to load",filename)\r
+        bl.message("fail to load %s" % filename)\r
         return\r
 \r
     # create materials\r
-    materials, imageMap=__createMaterials(scene, io, os.path.dirname(filename))\r
+    materials, imageMap=__createMaterials(io, os.path.dirname(filename))\r
+    if len(materials)==0:\r
+        materials.append(bl.material.create('default'))\r
 \r
     # create objects\r
-    root=bl.createEmptyObject(scene, os.path.basename(filename))\r
-    objects=__createObjects(scene, io, root, materials, imageMap, scale)\r
+    root=bl.object.createEmpty(os.path.basename(filename))\r
+    objects=__createObjects(io, root, materials, imageMap, scale)\r
 \r
     if has_mikoto(io):\r
         # create mikoto bone\r
-        armature_object=create_armature(scene, io)\r
+        armature_object=create_armature(io)\r
         if armature_object:\r
             root.makeParent([armature_object])\r
 \r
             # create bone weight\r
-            create_bone_weight(scene, io, armature_object, objects)\r
+            create_bone_weight(io, armature_object, objects)\r
 \r
  \r
 ###############################################################################\r
@@ -553,33 +629,22 @@ def __execute(filename, scene, scale=1.0):
 if isBlender24():\r
     # for 2.4\r
     def execute_24(filename):\r
-        """\r
-        import a mqo file.\r
-        """\r
-        filename=filename.decode(bl.INTERNAL_ENCODING)\r
-        print("##start mqo_import.py##")\r
-        print(bl.INTERNAL_ENCODING, bl.FS_ENCODING)\r
-        print("parse mqo file: %s" % (filename))\r
-\r
-        Blender.Window.WaitCursor(1) \r
-        t = Blender.sys.time() \r
-\r
-        # execute\r
-        scene = Blender.Scene.GetCurrent()\r
-        __execute(filename, scene)\r
-        scene.update(0)\r
-\r
-        print('finished in %.2f seconds' % (Blender.sys.time()-t))\r
-        print('')\r
-        Blender.Redraw()\r
-        Blender.Window.WaitCursor(0) \r
+        scene=Blender.Scene.GetCurrent()\r
+        bl.initialize('mqo_import', scene)\r
+        __execute(\r
+                filename.decode(bl.INTERNAL_ENCODING), \r
+                scene)\r
+        bl.finalize()\r
 \r
     # execute\r
     Blender.Window.FileSelector(execute_24, 'Import MQO', '*.mqo')\r
+\r
 else:\r
     # for 2.5\r
-    def execute_25(*args):\r
-        __execute(*args)\r
+    def execute_25(filename, scene, scale):\r
+        bl.initialize('mqo_import', scene)\r
+        __execute(filename, scene, scale)\r
+        bl.finalize()\r
 \r
     # operator\r
     class IMPORT_OT_mqo(bpy.types.Operator):\r
@@ -605,7 +670,7 @@ else:
                 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=0.01)\r
+                soft_min=0.001, soft_max=100.0, default=0.1)\r
 \r
         def execute(self, context):\r
             execute_25(\r