def create_verts(self,width,height,pos,me,tag_hide=False):
bpy.ops.object.mode_set(mode="EDIT")
bm = bmesh.from_edit_mesh(me)
vert1 = bm.verts.new(Vector((0,0,-height))*self.scale)
vert2 = bm.verts.new(Vector((width,0,-height))*self.scale)
vert3 = bm.verts.new(Vector((width,0,0))*self.scale)
vert4 = bm.verts.new(Vector((0,0,0))*self.scale)
bm.faces.new([vert1,vert2,vert3,vert4])
bmesh.update_edit_mesh(me)
if tag_hide:
for vert in bm.verts:
vert.hide = True
for edge in bm.edges:
edge.hide = True
bmesh.update_edit_mesh(me)
bpy.ops.object.mode_set(mode="OBJECT")
python类from_edit_mesh()的实例源码
def remove_base_mesh(obj):
bpy.ops.object.mode_set(mode="EDIT")
bm = bmesh.from_edit_mesh(obj.data)
bm.verts.ensure_lookup_table()
verts = []
if "coa_base_sprite" in obj.vertex_groups:
v_group_idx = obj.vertex_groups["coa_base_sprite"].index
for i,vert in enumerate(obj.data.vertices):
for g in vert.groups:
if g.group == v_group_idx:
verts.append(bm.verts[i])
break
bmesh.ops.delete(bm,geom=verts,context=1)
bm = bmesh.update_edit_mesh(obj.data)
bpy.ops.object.mode_set(mode="OBJECT")
def unwrap_with_bounds(obj,uv_idx):
bpy.ops.object.mode_set(mode="EDIT")
me = obj.data
bm = bmesh.from_edit_mesh(me)
bm.verts.ensure_lookup_table()
uv_layer = bm.loops.layers.uv[uv_idx]
scale_x = 1.0 / get_local_dimension(obj)[0] * obj.coa_tiles_x
scale_z = 1.0 / get_local_dimension(obj)[1] * obj.coa_tiles_y
offset = [get_local_dimension(obj)[2][0] * scale_x , get_local_dimension(obj)[2][1] * scale_z]
for i,v in enumerate(bm.verts):
for l in v.link_loops:
uv_data = l[uv_layer]
uv_data.uv[0] = (bm.verts[i].co[0] * scale_x) - offset[0]
uv_data.uv[1] = (bm.verts[i].co[2] * scale_z)+1 - offset[1]
bmesh.update_edit_mesh(me)
bm.free()
bpy.ops.object.mode_set(mode="OBJECT")
def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False):
assert(obj.type == 'MESH')
if apply_modifiers and obj.modifiers:
import bpy
me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW', calc_tessface=False)
bm = bmesh.new(); bm.from_mesh(me); bpy.data.meshes.remove(me)
del bpy
else:
me = obj.data
if obj.mode == 'EDIT': bm_orig = bmesh.from_edit_mesh(me); bm = bm_orig.copy()
else: bm = bmesh.new(); bm.from_mesh(me)
if transform: bm.transform(obj.matrix_world)
if triangulate: bmesh.ops.triangulate(bm, faces=bm.faces)
return bm
def execute(self, context):
oa = bpy.context.active_object
obj = bpy.context.object
me = obj.data
bm = bmesh.from_edit_mesh(me)
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
override = bpy.context.copy()
viewport = area.regions[4]
v_m = area.spaces[0].region_3d.view_matrix #orientation matrix
vert = [v for v in bm.verts if (v.select == True and v.hide == False)]
if len(vert) ==1:
self.main1(context, self.chboxVert0, self.grados, self.chboxreloj)
elif len(vert) == 3:
self.main3(context, self.chboxVert0, self.chboxVert1, self.chboxVert2,self.grados, self.chboxreloj)
else:
msg = "select 1 OR 3 vertices"
self.report({"WARNING"}, msg)
return {'CANCELLED'}
return {'FINISHED'}
def separarcaras():
obj = bpy.context.object
me = obj.data
bm = bmesh.from_edit_mesh(me)
### separar caras###
listabordes = []
for borde in bm.edges:
listabordes.append(borde)
bmesh.ops.split_edges(bm, edges=listabordes)
bpy.ops.mesh.select_all(action='SELECT')
bmesh.update_edit_mesh(me, True)
def separarcaras():
obj = bpy.context.object
me = obj.data
bm = bmesh.from_edit_mesh(me)
### separar caras###
listabordes = []
for borde in bm.edges:
listabordes.append(borde)
bmesh.ops.split_edges(bm, edges=listabordes)
bpy.ops.mesh.select_all(action='SELECT')
bmesh.update_edit_mesh(me, True)
def execute(self, context):
oa = bpy.context.active_object
obj = bpy.context.object
me = obj.data
bm = bmesh.from_edit_mesh(me)
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
override = bpy.context.copy()
viewport = area.regions[4]
v_m = area.spaces[0].region_3d.view_matrix #orientation matrix
vert = [v for v in bm.verts if (v.select == True and v.hide == False)]
if len(vert) ==3:
self.main(context, self.chboxVert0, self.chboxVert1, self.chboxVert2, self.cortes)
else:
msg = "select 3 vertices"
self.report({"WARNING"}, msg)
return {'CANCELLED'}
return {'FINISHED'}
def scene_update_post_handler(scene):
obj = scene.objects.active
if not obj:
return
if obj.mode == "EDIT" and obj.type == "MESH":
# Ensure to have an instance of the edit bmesh in the global dictionary to retrieve it in update methods.
bm = kcl_dict.setdefault(obj.name, bmesh.from_edit_mesh(obj.data))
face = bm.faces.active # TODO: bm instance might be dead here due to previous editing.
flag_layer = bm.faces.layers.int.get("kcl_flags")
if face and flag_layer:
flags = face[flag_layer]
# Update the flags stored in the window manager.
kcl_dict["update_by_code"] = True
bpy.context.window_manager.kcl_flag = flags
bpy.context.window_manager.kcl_is_lakitu = (flags & 0x0010) != 0 # Bit 5
kcl_dict["update_by_code"] = False
else:
kcl_dict.clear()
def execute(self, context):
"""build maze
"""
obj = context.object
bm = bmesh.from_edit_mesh(obj.data)
if len(self.vert_centers) == 0:
self.update = True
maze_params = self.get_maze_params()
bpy.ops.mesh.select_mode(type='EDGE')
bm, self.link_centers, self.vert_centers = generate_maze(bm, maze_params)
self.update = False
bmesh.update_edit_mesh(obj.data, destructive=True)
return {'FINISHED'}
def get_bmesh(ob=None):
'''Returns a bmesh. Works either in edit or object mode.
ob can be either an object or a mesh.'''
obm = bmesh.new()
if ob is None:
mesh = bpy.context.object.data
if 'data' in dir(ob):
mesh = ob.data
if ob.mode == 'OBJECT':
obm.from_mesh(mesh)
elif ob.mode == 'EDIT':
obm = bmesh.from_edit_mesh(mesh)
else:
mesh = ob
obm.from_mesh(mesh)
return obm
def get_bmesh(ob='empty'):
'''Returns a bmesh. Works either in edit or object mode.
ob can be either an object or a mesh.'''
obm = bmesh.new()
if ob == 'empty':
mesh = bpy.context.object.data
if 'data' in dir(ob):
mesh = ob.data
if ob.mode == 'OBJECT':
obm.from_mesh(mesh)
elif ob.mode == 'EDIT':
obm = bmesh.from_edit_mesh(mesh)
else:
mesh = ob
obm.from_mesh(mesh)
return obm
def add_material_to_mesh(mesh, materials , uvs):
for material in materials:
print('linking material %s to mesh object %s' % (material.name, mesh.name))
mesh.data.materials.append(material)
bpy.context.scene.objects.active = mesh
bpy.ops.object.mode_set(mode="EDIT")
bm = bmesh.from_edit_mesh(mesh.data)
uv_layer = bm.loops.layers.uv.verify()
bm.faces.layers.tex.verify()
for face in bm.faces:
face.material_index = 0
for l in face.loops:
luv = l[uv_layer]
ind = l.vert.index
luv.uv = Vector(uvs[ind])
bpy.ops.object.mode_set(mode='OBJECT')
mesh.select = True
bpy.ops.object.shade_smooth()
#mesh.hide = True
mesh.select = False
def index_callback(self, context):
scn = context.scene
if scn.ne_split_mode:
o = context.active_object
bm = bmesh.from_edit_mesh(o.data)
ensure_lookup_table(bm)
index = bm.select_history.active.index
masked_vertices = get_masked_vertices(context)
loop_index = scn.ne_view_normal_index
to_loops = create_loop_table(o.data)
if loop_index < len(to_loops[index]):
o.data.calc_normals_split()
loop_index = to_loops[index][face_index]
rotated = o.data.loops[loop_index].normal
if scn.ne_view_sync_mode:
mView = get_view_rotational_matrix(True)
mObject = get_object_rotational_matrix()
rotated = mView * mObject * rotated
else:
rotated = rot_vector(rotated, reverse=True)
scn.ne_view_normal = rotated
def global_callback_handler(context):
ob = bpy.context.active_object
scn = bpy.context.scene
if is_normal_active(ob):
new_orientation = get_view_quaternion()
if new_orientation==None:
return
if not is_same_vector(new_orientation, scn.ne_view_orientation):
#update view orientation
scn.ne_update_by_global_callback = True
scn.ne_view_orientation = new_orientation
#active vertex changed
bm = bmesh.from_edit_mesh(ob.data)
ensure_lookup_table(bm)
active = bm.select_history.active
if active!=None:
index = active.index
if index != scn.ne_last_selected_vert_index:
scn.ne_last_selected_vert_index = index
scn.ne_update_by_global_callback = True
scn.ne_type_normal = get_active_normal(bpy.context, ob)[0]
def update(self, context):
# update height via bmesh to avoid loosing material ids
# this should be the rule for other simple objects
# as long as there is no topologic changes
o = context.active_object
if archipack_wall.datablock(o) != self:
return
bpy.ops.object.mode_set(mode='EDIT')
me = o.data
bm = bmesh.from_edit_mesh(me)
bm.verts.ensure_lookup_table()
bm.faces.ensure_lookup_table()
new_z = self.z
last_z = list(v.co.z for v in bm.verts)
max_z = max(last_z)
for v in bm.verts:
if v.co.z == max_z:
v.co.z = new_z
bmesh.update_edit_mesh(me, True)
bpy.ops.object.mode_set(mode='OBJECT')
def execute(self, context):
ob = context.active_object
me = ob.data
bm = bmesh.from_edit_mesh(me)
# Save current selection
selected_verts = []
for v in bm.verts:
if v.select is True:
selected_verts.append(v.index)
if v.index != self.vert_and_group[0]:
v.select = False
ob.vertex_groups.active_index = self.vert_and_group[1]
bpy.ops.object.vertex_group_remove_from()
# Re-select vertices
for v in bm.verts:
if v.index in selected_verts:
v.select = True
#XXX Hacky, but there's no other way to update the UI panels
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()
return {'FINISHED'}
def avail_vgroups(self, context):
if context is None:
return []
ob = context.active_object
bm = bmesh.from_edit_mesh(ob.data)
dvert_lay = bm.verts.layers.deform.active
items = []
self.vertex = bm.select_history.active.index
dvert = bm.select_history.active[dvert_lay]
#XXX since we need an identifier here, user won't be able to add a vgroup with that name ('-1')
#XXX could check against vgroup names and find an unused name, but it's a rare case after all.
items.append(("-1", "New Vertex Group", "Add a new vertex group to the active object", -1))
for i in ob.vertex_groups:
if i.index not in dvert.keys():
items.append((i.name, i.name, str(i.index), i.index))
return items
def update(self, ed_type):
tmp = []
if ed_type == "OBJECT":
if self.obj.active.type == 'MESH':
self.active_obj = self.obj.active
else:
self.obj.active = self.obj[ self.msh_objs[0] ]
self.active_obj = self.obj.active
for i in self.msh_objs:
if self.obj[i].select:
tmp.append(i)
self.sel_msh_objs = tmp.copy()
#print("self.sel_msh_objs", self.sel_msh_objs) # debug
elif ed_type == "EDIT_MESH":
bm = bmesh.from_edit_mesh(bpy.context.edit_object.data)
if hasattr(bm.verts, "ensure_lookup_table"):
bm.verts.ensure_lookup_table()
for ind in range(len(bm.verts)):
if bm.verts[ind].select == True:
tmp.append(ind)
self.sel_msh_vts = tmp.copy()
def CreateWornEdges(context, factor):
actobj = bpy.context.object
bpy.ops.object.mode_set(mode="EDIT")
bm = bmesh.from_edit_mesh(actobj.data)
sf = [(vert.calc_shell_factor() - 1.0) * factor for vert in bm.verts[:]]
bpy.ops.object.mode_set(mode="VERTEX_PAINT")
purge = {}
for ind, loop in enumerate(bpy.context.object.data.loops[:]):
if loop.vertex_index not in purge:
purge[loop.vertex_index] = [ind]
else:
purge[loop.vertex_index].append(ind)
for vert in actobj.data.vertices[:]:
if vert.select:
ran = (sf[vert.index], sf[vert.index], sf[vert.index])
for i in purge[vert.index]:
actobj.data.vertex_colors.active.data[i].color = ran
actobj.data.update()
def main(context):
obj = context.active_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
uv_layer = bm.loops.layers.uv.verify()
bm.faces.layers.tex.verify() # currently blender needs both layers.
# adjust UVs
for f in bm.faces:
for l in f.loops:
luv = l[uv_layer]
if luv.select:
# apply the location of the vertex as a UV
luv.uv = l.vert.co.xy
bmesh.update_edit_mesh(me)
def execute(self, context):
# must force edge selection mode here
bpy.context.tool_settings.mesh_select_mode = (False, True, False)
obj = context.active_object
if obj.mode == "EDIT":
bm = bmesh.from_edit_mesh(obj.data)
selected_edges = [edge for edge in bm.edges if edge.select]
edge_indices = [i.index for i in selected_edges]
d = get_intersection_dictionary(bm, edge_indices)
unselect_nonintersecting(bm, d.keys(), edge_indices)
update_mesh(bm, d)
bmesh.update_edit_mesh(obj.data)
else:
print('must be in edit mode')
return {'FINISHED'}
def add_vertex_to_intersection():
obj = bpy.context.object
me = obj.data
bm = bmesh.from_edit_mesh(me)
edges = [e for e in bm.edges if e.select]
if len(edges) == 2:
[[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]
iv = geometry.intersect_line_line(v1, v2, v3, v4)
if iv:
iv = (iv[0] + iv[1]) / 2
bm.verts.new(iv)
bm.verts.ensure_lookup_table()
bm.verts[-1].select = True
bmesh.update_edit_mesh(me)
def execute(self, context):
obj = bpy.context.active_object
self.me = obj.data
self.bm = bmesh.from_edit_mesh(self.me)
self.me.update()
list_0 = [f.index for f in self.bm.faces if f.select]
if len(list_0) == 0:
self.report({'WARNING'},
"No suitable selection found. Operation cancelled")
return {'CANCELLED'}
elif len(list_0) != 0:
solidify_split(self, list_0)
context.tool_settings.mesh_select_mode = (True, True, True)
if self.del_original:
bpy.ops.mesh.delete(type='FACE')
else:
pass
return {'FINISHED'}
def __init__(self, spike_base_width=0.5, base_height_inset=0.0, top_spike=0.2, top_relative=False):
obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.inset(
use_boundary=True, use_even_offset=True, use_relative_offset=False,
use_edge_rail=False, thickness=spike_base_width, depth=base_height_inset,
use_outset=True, use_select_inset=False, use_individual=True, use_interpolate=True
)
bpy.ops.mesh.inset(
use_boundary=True, use_even_offset=True, use_relative_offset=top_relative,
use_edge_rail=False, thickness=0, depth=top_spike, use_outset=True,
use_select_inset=False, use_individual=True, use_interpolate=True
)
bm = bmesh.from_edit_mesh(obj.data)
bpy.ops.mesh.merge(type='COLLAPSE')
bpy.ops.object.mode_set(mode='OBJECT')
def __get_uv_info(self, context):
"""
Get UV coordinate
"""
obj = context.active_object
uv_info = []
bm = bmesh.from_edit_mesh(obj.data)
if muv_common.check_version(2, 73, 0) >= 0:
bm.faces.ensure_lookup_table()
if not bm.loops.layers.uv:
return None
uv_layer = bm.loops.layers.uv.verify()
for f in bm.faces:
if f.select:
for i, l in enumerate(f.loops):
uv_info.append((f.index, i, l[uv_layer].uv.copy()))
if len(uv_info) == 0:
return None
return uv_info
def execute(self, context):
props = context.scene.muv_props.texlock
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
if muv_common.check_version(2, 73, 0) >= 0:
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()
bm.faces.ensure_lookup_table()
if not bm.loops.layers.uv:
self.report(
{'WARNING'}, "Object must have more than one UV map")
return {'CANCELLED'}
props.verts_orig = [
{"vidx": v.index, "vco": v.co.copy(), "moved": False}
for v in bm.verts if v.select]
return {'FINISHED'}
def execute(self, context):
props = context.scene.muv_props.wsuv
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
if muv_common.check_version(2, 73, 0) >= 0:
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()
bm.faces.ensure_lookup_table()
if not bm.loops.layers.uv:
self.report({'WARNING'}, "Object must have more than one UV map")
return {'CANCELLED'}
uv_layer = bm.loops.layers.uv.verify()
sel_faces = [f for f in bm.faces if f.select]
# measure average face size
scale = 0.0
for f in sel_faces:
scale = scale + calc_face_scale(uv_layer, f)
props.ref_scale = scale / len(sel_faces)
return {'FINISHED'}
def side(self, nombre, offset):
bpy.ops.object.mode_set(mode="EDIT", toggle=0)
OBJECT = bpy.context.active_object
ODATA = bmesh.from_edit_mesh(OBJECT.data)
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
for VERTICE in ODATA.verts[:]:
VERTICE.select = False
if nombre is False:
for VERTICES in ODATA.verts[:]:
if VERTICES.co[0] < (offset):
VERTICES.select = 1
else:
for VERTICES in ODATA.verts[:]:
if VERTICES.co[0] > (offset):
VERTICES.select = 1
ODATA.select_flush(False)
bpy.ops.object.mode_set(mode="EDIT", toggle=0)
def SelDoubles(self, context):
bm = bmesh.from_edit_mesh(bpy.context.object.data)
for v in bm.verts:
v.select = 0
dictloc = {}
rd = lambda x: (round(x[0],4),round(x[1],4),round(x[2],4))
for vert in bm.verts:
dictloc.setdefault(rd(vert.co),[]).append(vert.index)
for loc, ind in dictloc.items():
if len(ind) > 1:
for v in ind:
bm.verts[v].select = 1
bpy.context.scene.objects.active = bpy.context.scene.objects.active