画像のアルファから境界線を判別するものも作成したのですが
今回はグリースペンシルで囲った範囲にメッシュを作るものになります
メッシュ作成部分はCOA Toolsアドオンのコードを参考に細かい三角メッシュで埋めるようになっています
bl_info = {
"name": "grease_pencil storoke to mesh",
"description": "UV/画像エディッタの上のグリースペンシルのストロークからメッシュの作成",
"author": "Yukimi",
"version": (0,2),
"blender": (2, 6, 0),
"location": "Object",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Object"}
import bpy
import bmesh
def triangle_fill(bm):
#三角面作成
triangle_fill = bmesh.ops.triangle_fill(bm,edges=bm.edges,use_beauty=True)
if triangle_fill["geom"] == []:
return False
else:
return True
def average_edge_cuts(bm,cuts=1):
### collapse short edges
edges_len_average = 0
edges_count = 0
shortest_edge = 10000
for edge in bm.edges:
if True:#edge.is_boundary:
edges_count += 1
length = edge.calc_length()
edges_len_average += length
if length < shortest_edge:
shortest_edge = length
edges_len_average = edges_len_average/edges_count
subdivide_edges = []
for edge in bm.edges:
cut_count = int(edge.calc_length()/shortest_edge*0.5)*cuts
if cut_count < 0:
cut_count = 0
if not edge.is_boundary:
subdivide_edges.append([edge,cut_count])
for edge in subdivide_edges:
bmesh.ops.subdivide_edges(bm,edges=[edge[0]],cuts=edge[1])
def smooth_verts(bm):
### smooth verts
smooth_verts = []
for vert in bm.verts:
if not vert.is_boundary:
smooth_verts.append(vert)
for i in range(50):
bmesh.ops.smooth_vert(bm,verts=smooth_verts,factor=1.0,use_axis_x=True,use_axis_y=True,use_axis_z=True)
def bm_pos_to_uv(bm):
##UVの設定
uv_list = [[vert.co[0], vert.co[1]] for vert in bm.verts]
uv_layer = bm.loops.layers.uv.verify()
bm.faces.layers.tex.verify()
for bm_face in bm.faces:
for v in bm_face.loops:
id = v.vert.index
v[uv_layer].uv = uv_list[id]
def stroke_to_mesh(stroke, img):
me = bpy.data.meshes.new('gpenMesh')
#オブジェクトの作成
obj = bpy.data.objects.new(img.name, me)
#オブジェクトをシーンにリンク
bpy.context.scene.objects.link(obj)
bm = bmesh.new() # BMeshから空のメッシュを作成
verts = []
#bmesh頂点データの作成
for p in stroke.points:
pos = p.co
v = bm.verts.new( [pos[0], pos[1], 0.0] )
verts.append(v)
bm.verts.index_update()
#エッジデータの作成
for i in range(len(verts)-1):
bm.edges.new( (verts[i], verts[i +1]) )
bm.edges.new((verts[-1], verts[0]))
#メッシュで埋める
fill_ok = triangle_fill(bm)#三角面作成
if fill_ok:
average_edge_cuts(bm)
bm.verts.index_update()
bmesh.ops.triangulate(bm,faces=bm.faces)
smooth_verts(bm) #頂点のスムーズ
bm_pos_to_uv(bm) #UVの設定
bm.to_mesh(me) #メッシュの作成
# 画像をUVにリンク
for i in range( len(obj.data.polygons) ):
obj.data.uv_textures[0].data[i].image = img
return( obj )
############################################
class GpenToMesh(bpy.types.Operator):
'''add Roop '''
bl_idname = "action.gpen2mesh"
bl_label = "make mesh from grease_pencil"
def execute(self, context):
#UV/Imageエディッタで使用中のGreasePencil
gpen_strokes = context.active_gpencil_layer.active_frame.strokes
#UV/Imageエディッタで表示中の画像
img = context.edit_image
for stroke in gpen_strokes:
stroke_to_mesh(stroke,img)
return {'FINISHED'}
#メニューへの登録
def mesh_menu_func(self, context):
self.layout.operator("action.gpen2mesh",
text="GreasePencilからメッシュ作成" )
def register():
bpy.utils.register_module(__name__)
bpy.types.IMAGE_MT_image.prepend(mesh_menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(mesh_menu_func)
if __name__ == "__main__":
#unregister()
register()
############################################
コードを実行するとかアドオンとして登録すると
UV/画像エディッタの画像メニューに「GreasePencilからメッシュ作成」という項目が登録されます
今回のコードでは 上記理由でUV/画像エディッタで囲った範囲を元に
XY平面上の0から1.0の範囲にメッシュを作成するようになっていますが
少しコードを変更すれば 3Dビューの方で描いたグリースペンシルに沿ってメッシュを作成することもできるかと思います
グリースペンシルの頂点のデータをそのまま使うため
ドローモードで描いたストロークでは細かくなりすぎるため多角形モードで描いた方がいいかもしれません
いかがでしょうか

0 件のコメント:
コメントを投稿