Blender api script
To generate a topographic model from a height map we are going to blender Python API. The used python script does the following:
- Get path for the used heightmap and output STL
- Create a plane and subdivide it. This give a higher number of vertices and looks like a higher 'resolution'. In this current example we use 200 cut which is the maximum for this operation. If a higher vertex count is need the operation can always be redone
- The heightmap image get loaded as a texture and this texture get used for the displacement operation. The displacement strength controls the height of the displacement
- A solidify operation is used to give the plane some volume. This could also be done with an extrusion for a cleaner result. But a solidify is easier and in the next operation the this won't matter anyway
- A boolean operation is used on the plane to cut it in a circle. The used object for this is a cylinder. The intersection is used for the operation.
- Finally the STL is exported. Here only the plane is exported as we choose to export selected objects.
The final result looks like this:
To render this image and run the python script this command is used:
blender -b test2.blend --python Scripts/Topo.py -o //Renders/img -f 1 -- C1.tif test1.stl
The used python script is found bellow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | import bpy import bmesh import sys from pathlib import Path # get arguments -- HeightmapPath StlPath argv = sys.argv argv = argv[argv.index("--") + 1:] # get all args after "--" #set directory paths HeightmapPath = str(Path(__file__).parent.parent / "Heightmaps/" / argv[0]) StlPath = str(Path(__file__).parent.parent / "STLs/" / argv[1]) print(HeightmapPath) # create plane bpy.ops.mesh.primitive_plane_add() so = bpy.context.active_object objects = bpy.data.objects # create bmesh me = bpy.context.object.data bm = bmesh.new() bm.from_mesh(me) # subdivide bmesh.ops.subdivide_edges(bm, edges=bm.edges, cuts=200, use_grid_fill=True, ) bm.to_mesh(me) bm.free() # heightmap texture img = bpy.data.images.load(HeightmapPath) tex = bpy.data.textures.new("heightmap", 'IMAGE') tex.image = img # displace modifier displace = so.modifiers.new("displace", 'DISPLACE') displace.texture = bpy.data.textures['heightmap'] displace.strength = 0.05 so.modifiers["displace"] # solidify modifier solidify = so.modifiers.new("solidify", 'SOLIDIFY') solidify.thickness = 0.2 so.modifiers["solidify"] # Boolean modifier boolean = so.modifiers.new("boolean",'BOOLEAN') booleanObject = objects['CircleBoolean'] boolean.object = booleanObject boolean.operation = 'INTERSECT' #export STL bpy.ops.export_mesh.stl(filepath=StlPath, use_mesh_modifiers=True,use_selection = True) |
Comments
Post a Comment