Advertisement
Guest User

Blender vert_slide_surface

a guest
Jun 28th, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.30 KB | None | 0 0
  1. import bmesh, mathutils.bvhtree, bpy_extras.view3d_utils
  2. class vert_slide_surface(bpy.types.Operator):
  3.     bl_idname = _common.get_ops_idname('transform', 'vert_slide_surface')
  4.     bl_label = "表面を頂点スライド"
  5.     bl_description = "表面を頂点スライド"
  6.     bl_options = {'REGISTER', 'UNDO'}
  7.    
  8.     mouse_region_position = [0, 0]
  9.    
  10.     @classmethod
  11.     def poll(cls, context):
  12.         try:
  13.             ob = context.active_object
  14.             if ob.type != 'MESH': return False
  15.             if ob.mode != 'EDIT': return False
  16.         except: return False
  17.         return True
  18.    
  19.     def get_bvhtree(self, context):
  20.         ob = context.active_object
  21.         me = ob.data
  22.        
  23.         bm = bmesh.from_edit_mesh(me)
  24.        
  25.         selected_verts = [v for v in bm.verts if v.select]
  26.         if len(selected_verts) != 1: return {'CANCELLED'}
  27.         self.target_vert_index = selected_verts[0].index
  28.         self.target_vert_pre_co = selected_verts[0].co.copy()
  29.        
  30.         verts_dict = {}
  31.         for face in selected_verts[0].link_faces:
  32.             for vert in face.verts:
  33.                 verts_dict[vert.index] = vert
  34.        
  35.         verts_list = []
  36.         for key in sorted(verts_dict.keys()):
  37.             co = ob.matrix_world * verts_dict[key].co
  38.             verts_list.append(co[:])
  39.        
  40.         faces_list = []
  41.         for face in selected_verts[0].link_faces:
  42.             vert_indices = []
  43.             for vert in face.verts:
  44.                 vert_indices.append(sorted(verts_dict.keys()).index(vert.index))
  45.             faces_list.append(vert_indices)
  46.        
  47.         return mathutils.bvhtree.BVHTree.FromPolygons(verts_list, faces_list)
  48.    
  49.     def invoke(self, context, event):
  50.         ob = context.active_object
  51.         me = ob.data
  52.        
  53.         self.pre_mode = ob.mode
  54.         bpy.ops.object.mode_set(mode='EDIT')
  55.        
  56.         bm = bmesh.from_edit_mesh(me)
  57.         selected_verts = [v for v in bm.verts if v.select]
  58.         if len(selected_verts) != 1:
  59.             self.report({'INFO'}, "2つ以上の頂点が選択されていたので中止しました")
  60.             return {'CANCELLED'}
  61.        
  62.         self.bvhtree = self.get_bvhtree(context)
  63.        
  64.         context.area.header_text_set(text="「表面を頂点スライド」実行中、Escで中止")
  65.         context.window_manager.modal_handler_add(self)
  66.         return {'RUNNING_MODAL'}
  67.    
  68.     def move_target_vert(self, context, new_co):
  69.         ob = context.active_object
  70.         me = ob.data
  71.         bm = bmesh.from_edit_mesh(me)
  72.         bm.verts.ensure_lookup_table()
  73.         bm.verts[self.target_vert_index].co = ob.matrix_world.inverted() * new_co
  74.         bmesh.update_edit_mesh(me)
  75.    
  76.     def modal(self, context, event):
  77.         if event.type == 'MOUSEMOVE':
  78.             self.mouse_region_position = (event.mouse_region_x, event.mouse_region_y)
  79.            
  80.             region = context.region
  81.             rv3d = context.space_data.region_3d
  82.             coord = self.mouse_region_position
  83.            
  84.             direction = bpy_extras.view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
  85.             origin = bpy_extras.view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
  86.            
  87.             location, normal, index, distance = self.bvhtree.ray_cast(origin, direction)
  88.            
  89.             if location: self.move_target_vert(context, location)
  90.            
  91.         elif event.type == 'LEFTMOUSE':
  92.             context.area.header_text_set()
  93.             return {'FINISHED'}
  94.            
  95.         elif event.type in {'RIGHTMOUSE', 'ESC'}:
  96.             self.move_target_vert(context, self.target_vert_pre_co)
  97.             bpy.ops.object.mode_set(mode=self.pre_mode)
  98.             context.area.header_text_set()
  99.             return {'CANCELLED'}
  100.        
  101.         return {'RUNNING_MODAL'}
  102.    
  103.     def execute(self, context):
  104.         bpy.ops.object.mode_set(mode=self.pre_mode)
  105.         return {'FINISHED'}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement