surfaces/blender/surf.py

145 lines
3.8 KiB
Python

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)