Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import bmesh, mathutils.bvhtree, bpy_extras.view3d_utils
- class vert_slide_surface(bpy.types.Operator):
- bl_idname = _common.get_ops_idname('transform', 'vert_slide_surface')
- bl_label = "表面を頂点スライド"
- bl_description = "表面を頂点スライド"
- bl_options = {'REGISTER', 'UNDO'}
- mouse_region_position = [0, 0]
- @classmethod
- def poll(cls, context):
- try:
- ob = context.active_object
- if ob.type != 'MESH': return False
- if ob.mode != 'EDIT': return False
- except: return False
- return True
- def get_bvhtree(self, context):
- ob = context.active_object
- me = ob.data
- bm = bmesh.from_edit_mesh(me)
- selected_verts = [v for v in bm.verts if v.select]
- if len(selected_verts) != 1: return {'CANCELLED'}
- self.target_vert_index = selected_verts[0].index
- self.target_vert_pre_co = selected_verts[0].co.copy()
- verts_dict = {}
- for face in selected_verts[0].link_faces:
- for vert in face.verts:
- verts_dict[vert.index] = vert
- verts_list = []
- for key in sorted(verts_dict.keys()):
- co = ob.matrix_world * verts_dict[key].co
- verts_list.append(co[:])
- faces_list = []
- for face in selected_verts[0].link_faces:
- vert_indices = []
- for vert in face.verts:
- vert_indices.append(sorted(verts_dict.keys()).index(vert.index))
- faces_list.append(vert_indices)
- return mathutils.bvhtree.BVHTree.FromPolygons(verts_list, faces_list)
- def invoke(self, context, event):
- ob = context.active_object
- me = ob.data
- self.pre_mode = ob.mode
- bpy.ops.object.mode_set(mode='EDIT')
- bm = bmesh.from_edit_mesh(me)
- selected_verts = [v for v in bm.verts if v.select]
- if len(selected_verts) != 1:
- self.report({'INFO'}, "2つ以上の頂点が選択されていたので中止しました")
- return {'CANCELLED'}
- self.bvhtree = self.get_bvhtree(context)
- context.area.header_text_set(text="「表面を頂点スライド」実行中、Escで中止")
- context.window_manager.modal_handler_add(self)
- return {'RUNNING_MODAL'}
- def move_target_vert(self, context, new_co):
- ob = context.active_object
- me = ob.data
- bm = bmesh.from_edit_mesh(me)
- bm.verts.ensure_lookup_table()
- bm.verts[self.target_vert_index].co = ob.matrix_world.inverted() * new_co
- bmesh.update_edit_mesh(me)
- def modal(self, context, event):
- if event.type == 'MOUSEMOVE':
- self.mouse_region_position = (event.mouse_region_x, event.mouse_region_y)
- region = context.region
- rv3d = context.space_data.region_3d
- coord = self.mouse_region_position
- direction = bpy_extras.view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
- origin = bpy_extras.view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
- location, normal, index, distance = self.bvhtree.ray_cast(origin, direction)
- if location: self.move_target_vert(context, location)
- elif event.type == 'LEFTMOUSE':
- context.area.header_text_set()
- return {'FINISHED'}
- elif event.type in {'RIGHTMOUSE', 'ESC'}:
- self.move_target_vert(context, self.target_vert_pre_co)
- bpy.ops.object.mode_set(mode=self.pre_mode)
- context.area.header_text_set()
- return {'CANCELLED'}
- return {'RUNNING_MODAL'}
- def execute(self, context):
- bpy.ops.object.mode_set(mode=self.pre_mode)
- return {'FINISHED'}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement