I don’t know if this is possible, but I have some scenes where I’d like to draw tens of thousands, perhaps hundreds of thousands of cylinders in a scene. Each cylinder is oriented, sized, and textured individually, although the texturing falls into 11 categories. Anyhow, what I’m finding is that my code seems to be n^2 performance wise and would like to know if someone can speed it up.
Here is my code, can anyone tell me how to move the creation and materials part to a lower level? From reading around a bit, it looks like the slow part would be the calls to primitive_cylinder_add and primitive_sphere_add, although perhaps the creation of links in the materials section is also slow, causing scene updates. I just don’t know. I do know that eliminating the entire “if burgers” block still results in n^2 slowdown. Any help? Thanks
def MakeCylinder(name, ep1, ep2, radius, orientation, burgers=None, endcaps=True): # print ("Make cylinder %s from ep1 %s to ep2 %s, in orientation %s"%(name, ep1,ep2,orientation))
cylvector = ep2 - ep1
center = ep1 + 0.5 * cylvector
depth = numpy.linalg.norm(cylvector)
# print ("cylvector is %s, center is %s, and depth is %s"% (cylvector, center, depth))
bpy.ops.mesh.primitive_cylinder_add(radius = radius, depth = depth, location = center)
cyl = bpy.data.objects['Cylinder']
cyl.name = name
if orientation == 'X':
cyl.rotation_euler = [0, pi/2.0, 0]
elif orientation == 'Y':
cyl.rotation_euler = [pi/2.0, 0, 0]
elif orientation == 'Z':
cyl.rotation_euler = [0, 0, 0]
else:
# cyl.rotation_euler = FindRotation(ep1, ep2)
cyl.rotation_euler = orientation
# compare = FindRotation(ep1, ep2)
# print ("computed rotation %s"%str(cyl.rotation_euler ))
# print ("compare rotation %s"%str(compare ))
if burgers:
objs = [cyl]
if endcaps:
bpy.ops.mesh.primitive_uv_sphere_add(location=ep1, size = radius )
ep1s = bpy.data.objects['Sphere']
ep1s.name = "%s ep1"%name
bpy.ops.mesh.primitive_uv_sphere_add(location=ep2, size = radius )
ep2s = bpy.data.objects['Sphere']
ep2s.name = "%s ep2"%name
objs = objs + [ep1s, ep2s]
for obj in objs:
name = obj.name
color = ColorFromBurgers(burgers)
bpy.ops.object.shade_smooth()
bpy.data.materials.new('%s_material'%name)
mat = bpy.data.materials['%s_material'%name]
obj.data.materials.append(mat)
mat.use_nodes = True
# node = mat.node_tree.nodes.new("ShaderNodeBsdfDiffuse")
# node.name = "diffuse_%s"%name
colornode = mat.node_tree.nodes.new("ShaderNodeBsdfGlossy")
colornode.name = "%s color"%name
colornode.inputs['Roughness'].default_value = 0.6
color = ColorFromBurgers(burgers)
colornode.inputs['Color'].default_value = color
emission = mat.node_tree.nodes.new("ShaderNodeEmission")
emission.name = "%s emission"%name
emission.inputs['Color'].default_value = color
mixnode = mat.node_tree.nodes.new("ShaderNodeMixShader")
mixnode.name = "%s mixnode"%name
mat.node_tree.links.new(colornode.outputs['BSDF'], mixnode.inputs[1])
mat.node_tree.links.new(emission.outputs['Emission'], mixnode.inputs[2])
outnode = mat.node_tree.nodes['Material Output']
mat.node_tree.links.new(mixnode.outputs['Shader'], outnode.inputs['Surface'])
return