import json import bmesh import bpy from bpy_extras.io_utils import ExportHelper from bpy.props import StringProperty, BoolProperty, FloatVectorProperty from bpy_extras import object_utils class SMBDumpMesh(bpy.types.Operator, ExportHelper): '''dump mesh info into .json file for smbsurf''' bl_idname = 'object.dump_mesh' bl_label = 'Dump Mesh' filename_ext = ".json" filter_glob = StringProperty( default="*.json", options={'HIDDEN'}, ) @classmethod def poll(cls, context): if context.active_object and context.active_object.type == 'MESH': return context.active_object else: return None def execute(self, context): if context.object.mode == 'OBJECT': bpy.ops.object.mode_set(mode='EDIT') m = context.object.data b = bmesh.from_edit_mesh(m) data = {} data['vertices'] = [list(vert.co) for vert in b.verts] data['edges_for_vert'] = [] for vert in b.verts: data['edges_for_vert'].append([e.index for e in vert.link_edges]) data['faces_for_vert'] = [] for vert in b.verts: data['faces_for_vert'].append([e.index for e in vert.link_faces]) edges = [] for edge in b.edges: edges.append([v.index for v in edge.verts]) data['edges'] = edges data['faces_for_edge'] = [] for edge in b.edges: data['faces_for_edge'].append([f.index for f in edge.link_faces]) faces = [] for face in b.faces: faces.append([v.index for v in face.verts]) data['faces'] = faces data['edges_for_face'] = [] for face in b.faces: data['edges_for_face'].append([e.index for e in face.edges]) json.dump(data, open(self.filepath, 'w')) bpy.ops.object.mode_set(mode='OBJECT') return {'FINISHED'} class SMBLoadMesh(bpy.types.Operator, ExportHelper): '''load json mesh from smbsurf''' bl_idname = 'object.load_mesh' bl_label = 'Load Mesh' filename_ext = ".json" filter_glob = StringProperty( default="*.json", options={'HIDDEN'}, ) # generic transform props view_align = BoolProperty( name="Align to View", default=False, ) location = FloatVectorProperty( name="Location", subtype='TRANSLATION', ) rotation = FloatVectorProperty( name="Rotation", subtype='EULER', ) @classmethod def poll(cls, context): return True def execute(self, context): data = json.load(open(self.filepath, 'r')) mesh = bpy.data.meshes.new("Imported") bm = bmesh.new() for v_co in data['vertices']: bm.verts.new(v_co) if 'faces' in data: for f_idx in data['faces']: bm.faces.new([bm.verts[i] for i in f_idx]) bm.to_mesh(mesh) mesh.update() # add the mesh as an object into the scene with this utility module try: object_utils.object_data_add(context, mesh, operator=self) except: pass return {'FINISHED'} class SMBPanel(bpy.types.Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'TOOLS' bl_idname = "VIEW3D_PT_TEST_PANEL" bl_label = "smbsurf" def draw(self, context): self.layout.operator('object.dump_mesh', icon='EXPORT') self.layout.operator('object.load_mesh', icon='IMPORT') @classmethod def poll(cls, context): return True def register(): bpy.utils.register_class(SMBDumpMesh) bpy.utils.register_class(SMBLoadMesh) bpy.utils.register_class(SMBPanel) def unregister(): bpy.utils.unregister_class(SMBDumpMesh) bpy.utils.unregister_class(SMBLoadMesh) bpy.utils.unregister_class(SMBPanel)