import bpy
from math import *
from mathutils import *
def fabricate_test_mesh(scn, res1, res2):
radius = 0.4
verts = []
faces = []
res22 = res2 * 2
for su in range(res1):
for sv in range(res1):
for sw in range(res1):
add_uvsphere(radius, res2, verts, faces, Vector([su, sv, sw]))
print(len(faces))
mesh = bpy.data.meshes.new("multisphere")
mesh.from_pydata(verts, [], faces)
mesh.validate(True)
mats = bpy.data.materials[0:5]
for mat in mats:
mesh.materials.append(mat)
polys_per_sphere = res2*res22
for i in range(len(mesh.polygons)):
u = i%(res22)
v = floor( i%(polys_per_sphere) *2 / polys_per_sphere )
w = floor(i / (polys_per_sphere))
idx = floor(u*4 / res22) + 4*v + 8*w
mesh.polygons[i].material_index = idx%len(mats)
obj = bpy.data.objects.new("multisphere", mesh)
scn.objects.link(obj)
def add_uvsphere(radius, resolution, verts, faces, center=Vector([0,0,0])):
res22 = 2*resolution
vert = center + Vector([0, 0, -radius])
verts.append(vert)
for av in range(resolution-1):
base = len(verts)
for au in range(res22):
theta = 2 * pi * au / (res22)
phi = ((av + 1) / resolution - 0.5) * pi
verts.append(center + Vector([cos(phi) * cos(theta) * radius,
cos(phi) * sin(theta) * radius,
sin(phi) * radius]) )
i1 = base + au
i2 = base + (au + 1) % (res22)
if av == 0:
faces.append([base - 1, i2, i1])
else:
faces.append([i1 - res22, i2 - res22, i2, i1])
base = len(verts)
verts.append(center+Vector([0, 0, radius]))
for au in range(res22):
i1 = base - res22 + au
i2 = base - res22 + (au + 1) % (res22)
faces.append([i1, i2, base])
def split_copy_mesh(obj, discriminant):
accumulator = {}
for polygon in obj.data.polygons:
tag = discriminant(polygon)
acc = accumulator.get(tag)
if acc is None:
acc = {
"tag":tag,
"verts":[],
"faces":[],
"materials":[],
"vertMap": {}
}
accumulator[tag] = acc
face = []
for vi in polygon.vertices:
vi2 = acc["vertMap"].get(vi)
if vi2 is None:
verts = acc["verts"]
vi2 = len( verts )
acc["vertMap"][vi] = vi2
verts.append(obj.data.vertices[vi].co)
face.append(vi2)
acc["faces"].append(face)
acc["materials"].append(polygon.material_index)
rval = []
for tag,acc in accumulator.items():
print(tag)
mesh = bpy.data.meshes.new(tag)
#print(acc)
mesh.from_pydata(acc["verts"], [], acc["faces"])
mesh.validate(True)
for mat in obj.data.materials:
mesh.materials.append(mat)
for i in range(len(mesh.polygons)):
mesh.polygons[i].material_index = acc["materials"][i]
obj = bpy.data.objects.new(tag, mesh)
bpy.context.scene.objects.link(obj)
rval.append(obj)
return rval
#fabricate_test_mesh(bpy.context.scene, 3, 8)
copies = split_copy_mesh(bpy.data.objects['multisphere'], lambda p: "m%d"%p.material_index)
for obj in copies:
obj.location = (5,0,0)
|
Blender python API quick-start
Syntax highlighting by Pygments.