From dc93b705e08b1bcee4099e180d39b364cb5f5ea8 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Sat, 8 May 2010 20:03:35 +0900 Subject: [PATCH] implement mqo importer for mqo. --- blender25/import_scene_mqo.py | 235 ++++++++++++++++++++++++++++++++++++++++++ include/mqo.h | 4 + src/mqo.cpp | 36 +++++++ swig/mqo.i | 3 +- 4 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 blender25/import_scene_mqo.py diff --git a/blender25/import_scene_mqo.py b/blender25/import_scene_mqo.py new file mode 100644 index 0000000..445d862 --- /dev/null +++ b/blender25/import_scene_mqo.py @@ -0,0 +1,235 @@ +# coding: utf-8 + +__author__= ['ousttrue'] +__url__ = ("") +__version__= '0.1' +__bpydoc__= '''\ +mqo Importer + +This script imports a mqo into Blender for editing. +''' + +from meshio import mqo +try: + import bpy + import Mathutils +except: + pass + + +SCALING=0.01 + + +if 'bpy' in globals(): + #################### + # blender2.5 + #################### + import sys + import os + from bpy.props import * + + fs_encoding=sys.getfilesystemencoding() + + def create_materials(mqo, scene, directory): + materials = [] + textureMap={} + imageMap={} + if len(mqo.materials)>0: + for m in mqo.materials: + material = bpy.data.materials.new(m.getName()) + materials.append(material) + # mqo material + material.diffuse_color=[m.color.r, m.color.g, m.color.b] + material.alpha=m.color.a + material.diffuse_intensity=m.diffuse + texture_name=m.getTexture() + if texture_name!='': + if texture_name in textureMap: + texture=textureMap[texture_name] + else: + texture=bpy.data.textures.new(texture_name) + textureMap[m.texture]=texture + texture.type='IMAGE' + texture=texture.recast_type() + texturePath="%s/%s" % (directory, texture_name) + image=bpy.data.add_image(texturePath) + imageMap[m.texture]=image + texture.image=image + texture.mipmap = True + texture.interpolation = True + texture.use_alpha = True + material.add_texture(texture, "UV", ("COLOR", "ALPHA")) + # temporary + material.emit=1.0 + else: + material = bpy.data.materials.new('Default') + materials.append(material) + return materials, imageMap + + def create_objects(mqo, scene, parent, materials, imageMap): + for o in mqo.objects: + + # create mesh + mesh=bpy.data.meshes.new("Mesh") + meshObject= bpy.data.objects.new(o.name, mesh) + scene.objects.link(meshObject) + meshObject.parent=parent + + mesh.add_geometry(len(o.vertices), 0, len(o.faces)) + + # add vertex + unpackedVertices=[] + for v in o.vertices: + # convert right-handed y-up to right-handed z-up + unpackedVertices.extend( + (SCALING*v.x, SCALING*-v.z, SCALING*v.y)) + mesh.verts.foreach_set("co", unpackedVertices) + + # add face + unpackedFaces = [] + usedMaterial=set() + for f in o.faces: + face = [] + for i in range(f.index_count): + face.append(f.getIndex(i)) + + if len(face) != 3 and len(face) != 4: + raise RuntimeError( + "{0} vertices in face.".format(len(face))) + + # rotate indices if the 4th is 0 + if len(face) == 4 and face[3] == 0: + face = [face[3], face[0], face[1], face[2]] + + if len(face) == 3: + face.append(0) + + unpackedFaces.extend(face) + usedMaterial.add(f.material_index) + mesh.faces.foreach_set("verts_raw", unpackedFaces) + + # add material + meshMaterialMap={} + materialIndex=0 + for i in usedMaterial: + mesh.add_material(materials[i]) + meshMaterialMap[i]=materialIndex + materialIndex+=1 + + # each face + mesh.add_uv_texture() + for mqo_face, blender_face, uv_face in zip( + o.faces, mesh.faces, mesh.uv_textures[0].data): + blender_face.material_index=meshMaterialMap[mqo_face.material_index] + if mqo_face.index_count>=3: + uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y] + uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y] + uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y] + if mqo_face.index_count==4: + uv_face.uv4=[ + mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y] + if materials[mqo_face.material_index] in imageMap: + uv_face.image=imageMap[mqo_face.tex] + uv_face.tex=True + + mesh.update() + + def load(filename, context): + io=mqo.IO() + if not io.read(filename): + return + + scene=context.scene + + # create material + materials, imageMap=create_materials( + io, scene, os.path.dirname(filename)) + + # create group + empty=bpy.data.objects.new(os.path.basename(filename), None) + scene.objects.link(empty) + + # create mesh + create_objects(io, scene, empty, materials, imageMap) + + + class IMPORT_OT_mqo(bpy.types.Operator): + '''Import from Metasequoia file format (.mqo)''' + bl_idname = "import_scene.mqo" + bl_label = 'Import MQO' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + path = StringProperty( + name="File Path", + description="File path used for importing the MQO file", + maxlen= 1024, default= "") + filename = StringProperty( + name="File Name", + description="Name of the file.") + directory = StringProperty( + name="Directory", + description="Directory of the file.") + + def execute(self, context): + load(self.properties.path, context) + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self) + return {'RUNNING_MODAL'} + + + menu_func = lambda self, context: self.layout.operator( + IMPORT_OT_mqo.bl_idname, text="Metasequoia (.mqo)") + + + def register(): + bpy.types.register(IMPORT_OT_mqo) + bpy.types.INFO_MT_file_import.append(menu_func) + + def unregister(): + bpy.types.unregister(IMPORT_OT_mqo) + bpy.types.INFO_MT_file_import.remove(menu_func) + + + if __name__=="__main__": + register() + +else: + #################### + # for test + #################### + def load(path): + io=open(sys.argv[1], encoding='cp932') + if not io: + return None + + mqo=MQO() + if not mqo.parse(io): + return None + + return mqo + + + if __name__=="__main__": + import sys + if len(sys.argv)<2: + print("usage: %s {mqo file}" % sys.argv[0]) + sys.exit() + + import time + t=time.time() + mqo=load(sys.argv[1]) + if not mqo: + sys.exit() + print("%.2f seconds" % (time.time()-t)) + + print(mqo) + for m in mqo.materials: + print(m) + for o in mqo.objects: + print(o) + diff --git a/include/mqo.h b/include/mqo.h index a7c6781..fb932da 100644 --- a/include/mqo.h +++ b/include/mqo.h @@ -97,6 +97,10 @@ struct Material : shader(0), diffuse(1), ambient(0), emmit(0), specular(0), power(0), vcol(0) {} + + // for python3 unicode + std::wstring getName()const; + std::wstring getTexture()const; }; inline std::ostream &operator<<(std::ostream &os, const Material &rhs) { diff --git a/src/mqo.cpp b/src/mqo.cpp index 1fe8603..b4c7dcd 100644 --- a/src/mqo.cpp +++ b/src/mqo.cpp @@ -3,9 +3,45 @@ #include #include +#include + +static std::wstring to_WideChar(UINT uCodePage, const std::string &text) +{ + int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0); + std::vector buf(size); + size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size()); + return std::wstring(buf.begin(), buf.begin()+size); +} + +static std::string to_MultiByte(UINT uCodePage, const std::wstring &text) +{ + int size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, NULL, 0, 0, NULL); + std::vector buf(size); + size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size(), 0, NULL); + return std::string(buf.begin(), buf.begin()+size); +} + +static std::string cp932_to_utf8(const std::string &text) +{ + return to_MultiByte(CP_UTF8, to_WideChar(CP_OEMCP, text)); +} + namespace meshio { namespace mqo { +// for python3 unicode +std::wstring + Material::getName()const + { + return to_WideChar(CP_OEMCP, name); + } + +std::wstring + Material::getTexture()const + { + return to_WideChar(CP_OEMCP, texture); + } + //! Tokenizer struct DELIMITER { diff --git a/swig/mqo.i b/swig/mqo.i index 8a23f73..b14cb2c 100644 --- a/swig/mqo.i +++ b/swig/mqo.i @@ -4,8 +4,9 @@ using namespace meshio; using namespace mqo; %} -%include "std_string.i" %include "std_vector.i" +%include "std_string.i" +%include "std_wstring.i" %include "../include/mqo.h" %include "../include/la.h" %include "../include/color.h" -- 2.11.0