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
python类new()的实例源码
def _convert_model(self, bm, kcl, model_index):
# Get the additional data layers to keep track of the triangles for exporting.
model_index_layer = bm.faces.layers.int["kcl_model_index"]
face_index_layer = bm.faces.layers.int["kcl_face_index"]
flags_layer = bm.faces.layers.int["kcl_flags"]
# Add the model to the bmesh.
kcl_model = kcl.models[model_index]
for i, triangle in enumerate(kcl_model.triangles):
vertices = kcl_model.get_triangle_vertices(triangle)
vert1 = bm.verts.new(vertices[0])
vert2 = bm.verts.new(vertices[1])
vert3 = bm.verts.new(vertices[2])
face = bm.faces.new((vert1, vert2, vert3))
# Remember the model and face indices.
face[model_index_layer] = model_index
face[face_index_layer] = i
face[flags_layer] = triangle.collision_flags
# TODO: Assign a material visualizing the flags somehow.
def test_get_inner_edges_loops_grid(self):
"""
select some edges that don't select full faces
but could form a maze
"""
bm = bmesh.new()
bmesh.ops.create_grid(bm, x_segments=10, y_segments=10, size=1.0)
bm = make_edge_selection_grid(bm)
sel_geom, inner_edges = mm.get_inner_edges(bm, 2)
#put_to_scene(bm)
self.assertEqual(len(sel_geom), 64 + 84)
self.assertEqual(len(inner_edges), 84)
bm.free()
def test_generate_maze_full_grid(self):
"""
generate full maze on 10 x 10 grid
"""
bm = bmesh.new()
bmesh.ops.create_grid(bm, x_segments=10, y_segments=10, size=1.0)
for face in bm.faces:
face.select = True
bm, maze_links, maze_verts = mm.generate_maze(bm, mm.MAZE_PARAMS)
self.assertEqual(len(maze_links), 63)
self.assertEqual(len(maze_verts), 64)
# also count of selected faces should == 63+64
self.assertEqual(sum(face.select for face in bm.faces), 127)
bm.free()
def test_generate_maze_loops_grid(self):
"""
select some edges that don't select full faces
but could form a maze
"""
bm = bmesh.new()
bmesh.ops.create_grid(bm, x_segments=10, y_segments=10, size=1.0)
bm = make_edge_selection_grid(bm)
nverts = sum(vert.select for vert in bm.verts)
maze_params = mm.MAZE_PARAMS.copy()
maze_params['boundary_type'] = 1
maze_params['offset'] = 0.0
bm, maze_links, maze_verts = mm.generate_maze(bm, maze_params)
self.assertEqual(len(maze_links), 63)
self.assertEqual(len(maze_verts), nverts)
self.assertEqual(sum(edge.select for edge in bm.edges), len(maze_links))
bm.free()
def _convert_fmdl(self, fmdl):
# If no parent is given, create an empty object holding the FSHP child mesh objects of this FMDL.
if self.operator.parent_ob_name:
fmdl_ob = None
else:
fmdl_ob = bpy.data.objects.new(fmdl.header.file_name_offset.name, None)
Importer._add_object_to_group(fmdl_ob, "BFRES")
bpy.context.scene.objects.link(fmdl_ob)
# Go through the polygons in this model and create mesh objects representing them.
for fshp_node in fmdl.fshp_index_group[1:]:
fshp_ob = self._convert_fshp(fmdl, fshp_node.data)
if self.operator.parent_ob_name:
# Just parent the mesh object to the given object.
fshp_ob.parent = bpy.data.objects[self.operator.parent_ob_name]
else:
# Parent to the empty FMDL object and link it to the scene.
fshp_ob.parent = fmdl_ob
Importer._add_object_to_group(fshp_ob, "BFRES")
bpy.context.scene.objects.link(fshp_ob)
def create_texture(name, tex_type, filename, use_alpha=True):
if filename in img_cache:
# Image has been cached already, so just use that.
img = img_cache[(filename, use_alpha)]
else:
# We haven't cached this asset yet, so load it from disk.
try:
img = bpy.data.images.load(filename)
except:
raise IOError("Cannot load image: %s" % filename)
img.use_alpha = use_alpha
img.pack()
# Cache the asset
img_cache[(filename, use_alpha)] = img
# Create and return a new texture using img
tex = bpy.data.textures.new(name, tex_type)
tex.image = img
return tex
# Adds a hull normal map texture slot to a material.
def create_vertex_groups(groups=['common', 'not_used'], weights=[0.0, 0.0], ob=None):
'''Creates vertex groups and sets weights. "groups" is a list of strings
for the names of the groups. "weights" is a list of weights corresponding
to the strings. Each vertex is assigned a weight for each vertex group to
avoid calling vertex weights that are not assigned. If the groups are
already present, the previous weights will be preserved. To reset weights
delete the created groups'''
if ob is None:
ob = bpy.context.object
vg = ob.vertex_groups
for g in range(0, len(groups)):
if groups[g] not in vg.keys(): # Don't create groups if there are already there
vg.new(groups[g])
vg[groups[g]].add(range(0,len(ob.data.vertices)), weights[g], 'REPLACE')
else:
vg[groups[g]].add(range(0,len(ob.data.vertices)), 0, 'ADD') # This way we avoid resetting the weights for existing groups.
def generate_guide_mesh():
"""Makes the icosphere that appears when creating pins"""
verts = [[0.0, 0.0, 0.0], [-0.01, -0.01, 0.1], [-0.01, 0.01, 0.1], [0.01, -0.01, 0.1], [0.01, 0.01, 0.1], [-0.03, -0.03, 0.1], [-0.03, 0.03, 0.1], [0.03, 0.03, 0.1], [0.03, -0.03, 0.1], [-0.01, -0.01, 0.2], [-0.01, 0.01, 0.2], [0.01, -0.01, 0.2], [0.01, 0.01, 0.2]]
edges = [[0, 5], [5, 6], [6, 7], [7, 8], [8, 5], [1, 2], [2, 4], [4, 3], [3, 1], [5, 1], [2, 6], [4, 7], [3, 8], [9, 10], [10, 12], [12, 11], [11, 9], [3, 11], [9, 1], [2, 10], [12, 4], [6, 0], [7, 0], [8, 0]]
faces = [[0, 5, 6], [0, 6, 7], [0, 7, 8], [0, 8, 5], [1, 3, 11, 9], [1, 2, 6, 5], [2, 4, 7, 6], [4, 3, 8, 7], [3, 1, 5, 8], [12, 10, 9, 11], [4, 2, 10, 12], [3, 4, 12, 11], [2, 1, 9, 10]]
name = 'ModelingClothPinGuide'
if 'ModelingClothPinGuide' in bpy.data.objects:
mesh_ob = bpy.data.objects['ModelingClothPinGuide']
else:
mesh = bpy.data.meshes.new('ModelingClothPinGuide')
mesh.from_pydata(verts, edges, faces)
mesh.update()
mesh_ob = bpy.data.objects.new(name, mesh)
bpy.context.scene.objects.link(mesh_ob)
mesh_ob.show_x_ray = True
return mesh_ob
def execute(self, context):
ob = bpy.context.object
bpy.ops.object.mode_set(mode='OBJECT')
sel = [i.index for i in ob.data.vertices if i.select]
name = ob.name
matrix = ob.matrix_world.copy()
for v in sel:
e = bpy.data.objects.new('modeling_cloth_pin', None)
bpy.context.scene.objects.link(e)
if ob.active_shape_key is None:
closest = matrix * ob.data.vertices[v].co# * matrix
else:
closest = matrix * ob.active_shape_key.data[v].co# * matrix
e.location = closest #* matrix
e.show_x_ray = True
e.select = True
e.empty_draw_size = .1
data[name].pin_list.append(v)
data[name].hook_list.append(e)
ob.select = False
bpy.ops.object.mode_set(mode='EDIT')
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 new(name, naming_method=0) :
if name not in bpy.data.meshes or naming_method == 0:
return bpy.data.meshes.new(name=name)
if naming_method == 1 :
return bpy.data.meshes[name]
if naming_method == 2 :
me = bpy.data.meshes.new(name=name)
me.name = name
return me
# naming_method = 3 : replace, keep users
me = bpy.data.meshes[name]
bm = bmesh.new()
bm.to_mesh(me)
return me
## material listed in matslots must exist before creation of material slots
def materialsCheck(bld) :
if hasattr(bld,'materialslots') == False :
#print(bld.__class__.__name__)
builderclass = eval('bpy.types.%s'%(bld.__class__.__name__))
builderclass.materialslots=[bld.className()]
matslots = bld.materialslots
if len(matslots) > 0 :
for matname in matslots :
if matname not in bpy.data.materials :
mat = bpy.data.materials.new(name=matname)
mat.use_fake_user = True
if hasattr(bld,'mat_%s'%(matname)) :
method = 'defined by builder'
matdef = eval('bld.mat_%s'%(matname))
mat.diffuse_color = matdef['diffuse_color']
else :
method = 'random'
mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
dprint('Created missing material %s (%s)'%(matname,method),2)
def add_part(self, part):
if len(self.segs) < 1:
s = None
else:
s = self.segs[-1]
# start a new slab
if s is None:
if part.type == 'S_SEG':
p = Vector((0, 0))
v = part.length * Vector((cos(part.a0), sin(part.a0)))
s = StraightSlab(p, v)
elif part.type == 'C_SEG':
c = -part.radius * Vector((cos(part.a0), sin(part.a0)))
s = CurvedSlab(c, part.radius, part.a0, part.da)
else:
if part.type == 'S_SEG':
s = s.straight_slab(part.a0, part.length)
elif part.type == 'C_SEG':
s = s.curved_slab(part.a0, part.da, part.radius)
self.segs.append(s)
self.last_type = part.type
def create(self, context):
m = bpy.data.meshes.new("Slab")
o = bpy.data.objects.new("Slab", m)
d = m.archipack_slab.add()
# make manipulators selectable
d.manipulable_selectable = True
context.scene.objects.link(o)
o.select = True
context.scene.objects.active = o
self.load_preset(d)
self.add_material(o)
return o
# -----------------------------------------------------
# Execute
# -----------------------------------------------------
def execute(self, context):
addon_prefs = context.user_preferences.addons[__package__].preferences
smooth = addon_prefs.npfp_smooth
dist = NP020FP.dist # is this used ?
polyob = NP020FP.polyob
polyme = polyob.data
bm = bmesh.new()
bm.from_mesh(polyme)
bmesh.ops.contextual_create(bm, geom=bm.edges)
bm.to_mesh(polyme)
bm.free()
bpy.ops.object.select_all(action='DESELECT')
polyob.select = True
if smooth:
bpy.ops.object.shade_smooth()
np_print('smooth ON')
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
bpy.ops.object.select_all(action='DESELECT')
NP020FP.flag = 'EXTRUDE'
NP020FP.phase = 3
return {'FINISHED'}
def make_normal_snapshot(self, scene, tangential=False):
settings = find_settings()
tfm_opts = settings.transform_options
dest_point = self.particles[0].get_location()
if self.is_normal_visible():
p0, x, y, z, _x, _z = \
self.get_normal_params(tfm_opts, dest_point)
snapshot = bpy.data.objects.new("normal_snapshot", None)
if tangential:
m = MatrixCompose(_z, y, x, p0)
else:
m = MatrixCompose(_x, y, z, p0)
snapshot.matrix_world = m
snapshot.empty_draw_type = 'SINGLE_ARROW'
#snapshot.empty_draw_type = 'ARROWS'
#snapshot.layers = [True] * 20 # ?
scene.objects.link(snapshot)
#============================================================================#
def __init__(self, scene, shade):
SnapUtilityBase.__init__(self)
convert_types = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}
self.cache = MeshCache(scene, convert_types)
# ? seems that dict is enough
self.bbox_cache = {}#collections.OrderedDict()
self.sys_matrix_key = [0.0] * 9
bm = prepare_gridbox_mesh(subdiv=2)
mesh = bpy.data.meshes.new(tmp_name)
bm.to_mesh(mesh)
mesh.update(calc_tessface=True)
#mesh.calc_tessface()
self.bbox_obj = self.cache._make_obj(mesh, None)
self.bbox_obj.hide = True
self.bbox_obj.draw_type = 'WIRE'
self.bbox_obj.name = "BoundBoxSnap"
self.shade_bbox = (shade == 'BOUNDBOX')
def poll(cls, context):
try:
wm = context.window_manager
if not wm.cursor_3d_runtime_settings.use_cursor_monitor:
return False
runtime_settings = find_runtime_settings()
if not runtime_settings:
return False
# When addon is enabled by default and
# user started another new scene, is_running
# would still be True
return (not CursorMonitor.is_running) or \
(runtime_settings.current_monitor_id == 0)
except Exception as e:
print("Cursor monitor exeption in poll:\n" + repr(e))
return False
def prepare_gridbox_mesh(subdiv=1):
bm = bmesh.new()
sides = [
(-1, (0,1,2)), # -Z
(1, (1,0,2)), # +Z
(-1, (1,2,0)), # -Y
(1, (0,2,1)), # +Y
(-1, (2,0,1)), # -X
(1, (2,1,0)), # +X
]
for side in sides:
prepare_grid_mesh(bm, nx=subdiv, ny=subdiv,
z=side[0], xyz_indices=side[1])
return bm
# ===== DRAWING UTILITIES ===== #
def add_lamp(self, name, location, layers):
name_lamp = FORMAT_LAMP.format(name)
lamp = self.__data.lamps.get(name_lamp)
if not lamp:
lamp = self.__data.lamps.new(name_lamp, 'POINT')
tmp_engine = self.__scene.render.engine
self.__scene.render.engine = 'BLENDER_RENDER'
#lamp.shadow_method = 'RAY_SHADOW'
#lamp.shadow_ray_samples = 6
#lamp.shadow_soft_size = 3.0
lamp.distance = 1000.0
lamp.energy = 1.0
lamp.use_specular = False
self.__scene.render.engine = 'CYCLES'
lamp.cycles.use_multiple_importance_sampling = True
lamp.use_nodes = True
self.__scene.render.engine = tmp_engine
obj = self.__data.objects.new(FORMAT_LAMP_OBJECT.format(name), lamp)
self.__scene.objects.link(obj)
obj.location = location
obj.layers = layers
def create_wire_pole(self, cu_splines, co, t, ti, surface, width):
d = (t - co)
dn = d.normalized()
w = width / 2.0
dw = dn * w
co_dw = co + dw
cu_splines.new('BEZIER')
act_spline = cu_splines[-1]
act_spline.use_cyclic_u = False
point_0 = act_spline.bezier_points[-1]
point_0.co = Vector((co_dw.x, co_dw.y, co.z - w))
point_0.handle_left_type = 'ALIGNED'
point_0.handle_right_type = 'ALIGNED'
point_0.handle_left = Vector((point_0.co.x, point_0.co.y, point_0.co.z + w))
point_0.handle_right = Vector((point_0.co.x, point_0.co.y, point_0.co.z - w))
act_spline.bezier_points.add()
point_1 = act_spline.bezier_points[-1]
point_1.co = Vector((co_dw.x, co_dw.y, surface))
point_1.handle_left_type = 'ALIGNED'
point_1.handle_right_type = 'ALIGNED'
point_1.handle_left = Vector((point_1.co.x, point_1.co.y, point_1.co.z + (co.z - surface) / 4.0))
point_1.handle_right = Vector((point_1.co.x, point_1.co.y, point_1.co.z - (co.z - surface) / 4.0))
def prepare_wire_ramp_bevel(self):
bevel_name = "__fpx_guide_ramp_wire_bevel__"
wire_bevel = self.__data.objects.get(bevel_name)
if wire_bevel is None:
cu = self.__data.curves.new(bevel_name, 'CURVE')
wire_bevel = self.__data.objects.new(bevel_name, cu)
self.__scene.objects.link(wire_bevel)
cu.dimensions = '2D'
cu.resolution_u = self.resolution_wire_bevel
self.create_wire_ramp_bevel(cu, 0) # base left inner
self.create_wire_ramp_bevel(cu, 1) # base right inner
if self.debug_create_full_ramp_wires:
self.create_wire_ramp_bevel(cu, 2) # left inner
self.create_wire_ramp_bevel(cu, 3) # right inner
self.create_wire_ramp_bevel(cu, 4) # upper left inner
self.create_wire_ramp_bevel(cu, 5) # upper right inner
self.create_wire_ramp_bevel(cu, 6) # top outer
else:
pass
return wire_bevel
def SetupSplineSurfaces(self):
rvSplineSurfaces = []
currV0Index = 0
for i in range(self.nrSplines):
splineA = self.curveA.splines[i]
splineO = self.curveO.splines[i]
res = splineA.resolution
if splineO.resolution < res: res = splineO.resolution
for iv in range(2 * res): self.bMesh.verts.new()
splSurf = LoftedSplineSurface(splineA, splineO, self.bMesh, currV0Index, res)
splSurf.AddFaces()
rvSplineSurfaces.append(splSurf)
currV0Index += 2 * res
return rvSplineSurfaces
def SetupSplineSurfaces(self):
rvSplineSurfaces = []
currV0Index = 0
for i in range(self.nrSplines):
splineA = self.curveA.splines[i]
splineO = self.curveO.splines[i]
resA = splineA.resolution
resO = splineO.resolution
for iv in range(resA * resO): self.bMesh.verts.new()
splSurf = SweptSplineSurface(splineA, splineO, self.bMesh, currV0Index, resA, resO)
splSurf.AddFaces()
rvSplineSurfaces.append(splSurf)
currV0Index += resA * resO
return rvSplineSurfaces
def SetupSplineSurfaces(self):
rvSplineSurfaces = []
currV0Index = 0
for i in range(self.nrSplines):
splineRail1 = self.rail1Curve.splines[i]
splineRail2 = self.rail2Curve.splines[i]
splineProfile = self.profileCurve.splines[i]
resProfile = splineProfile.resolution
resRails = splineRail1.resolution
if splineRail2.resolution < resRails: resRails = splineRail2.resolution
for iv in range(resProfile * resRails): self.bMesh.verts.new()
splSurf = BirailedSplineSurface(splineRail1, splineRail2, splineProfile, self.bMesh, currV0Index, resRails, resProfile)
splSurf.AddFaces()
rvSplineSurfaces.append(splSurf)
currV0Index += resProfile * resRails
return rvSplineSurfaces
def __init__(self):
self.GeneralHeader = VChunkHeader("ACTRHEAD", 0)
self.Points = FileSection("PNTS0000", SIZE_VPOINT) # VPoint
self.Wedges = FileSection("VTXW0000", SIZE_VVERTEX) # VVertex
self.Faces = FileSection("FACE0000", SIZE_VTRIANGLE) # VTriangle
self.Materials = FileSection("MATT0000", SIZE_VMATERIAL) # VMaterial
self.Bones = FileSection("REFSKELT", SIZE_VBONE) # VBone
self.Influences = FileSection("RAWWEIGHTS", SIZE_VRAWBONEINFLUENCE) # VRawBoneInfluence
# RG - this mapping is not dumped, but is used internally to store the new point indices
# for vertex groups calculated during the mesh dump, so they can be used again
# to dump bone influences during the armature dump
#
# the key in this dictionary is the VertexGroup/Bone Name, and the value
# is a list of tuples containing the new point index and the weight, in that order
#
# Layout:
# { groupname : [ (index, weight), ... ], ... }
#
# example:
# {'MyVertexGroup' : [ (0, 1.0), (5, 1.0), (3, 0.5) ] , 'OtherGroup' : [(2, 1.0)]}
self.VertexGroups = {}
def _cubic_bezier_open(self, points, curve):
count = (len(points) - 1) / 3 + 1
spl = curve.splines.new('BEZIER')
b = spl.bezier_points
b.add(count - 1)
b[0].co = self.proj(points[0])
b[0].handle_left = self.proj(points[0])
b[0].handle_right = self.proj(points[1])
b[-1].co = self.proj(points[-1])
b[-1].handle_right = self.proj(points[-1])
b[-1].handle_left = self.proj(points[-2])
for i, j in enumerate(range(3, len(points) - 2, 3), 1):
b[i].handle_left = self.proj(points[j - 1])
b[i].co = self.proj(points[j])
b[i].handle_right = self.proj(points[j + 1])
def polyface(self, en, bm):
"""
pf: polyface
bm: Blender bmesh data to which the POLYFACE should be added to.
<-? bm.from_mesh(object.data) ?->
"""
for v in en.vertices:
bm.verts.new(v.location)
bm.verts.ensure_lookup_table()
for subface in en:
idx = subface.indices()
points = []
for p in idx:
if p not in points:
points.append(p)
if len(points) in (3, 4):
bm.faces.new([bm.verts[i] for i in points])