Skip to content
Home » How to Spawn Objects at Specific Locations with Python in Blender

How to Spawn Objects at Specific Locations with Python in Blender

Spread the love

Today we’ll see how to programmatically spawn an object you created at specific locations. I’ll be using the 2.90 version of Blender.

Now, suppose you created an object, like a tree, and now want to spawn it multiple times in the scene. You could use particles, but they don’t give you full control. If you want to add the tree objects at specific locations, you can use Python.

So, here’s what we are going to do. First we’ll model a simple tree. Then we’ll add a plane, select some vertices on the plane and spawn the trees at the selected vertices. And we’ll do it by means of a Python script.

So, let’s get to work. Here are the steps to follow:

Step 1 – Model a Tree

First, delete the default cube and add a cylinder. Move it up (G Z 1), go to edit mode and move the origin point to its base by selecting all and hitting G Z 1. Go back to object mode and move the cylinder down (G Z -1):

Model a Tree

Scale the cylinder down on the X and Y axes (S Shift+Z 0.2):

scale

Go to edit mode, toggle on the Show X-Ray button and select the vertices at the top. Extrude and scale (E S 4). Extrude again (E 2):

extrude

Merge the vertices at center:

merge

Here’s our simple tree model in edit mode:

tree model

And in object mode after shading it smooth (the Shade Smooth option can be found in the Object menu):

tree model

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

Step 2 – Add Materials to the Tree

Let’s add a material to the tree. Set the base color to a shade of green of your choice. Then, in edit mode, select just the faces that make up the trunk and assign a new material to them by first clicking on the plus sign button to add a new material slot and then pressing the New button to add a new material. Set the base color of this material to a shade of brown and hit the Assign button to assign the material to the trunk of the tree. Here’s what you should see in Material Preview:

Add Materials to the Tree

We’re almost done with the tree. Go back to object mode and rename the cylinder ‘tree’ in the Outliner:

rename

The last thing we have to do is apply the scale. To this end hit N to open the sidebar and you will see that the scale is not 1:

scale

In order to make it 1, go to the Object menu and select Apply -> Scale:

apply scale

Now the scale in the sidebar is 1:

scale

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

Step 3 – Add the Plane

Now that we have a tree model, let’s add a plane that will be the ground the trees will be spawned on. So, hit Shift + A and under Mesh select Plane. Scale it by a factor of 50 (S 50) and in edit mode subdivide it. You will find the Subdivide option in the Edge menu. Set the number of cuts to 100:

Add the Plane

Let’s add some hills. Select a couple vertices. I selected five. Enable proportional editing (A) and move them up (G Z 6). Make sure the circle is pretty big. I used a circle with the size of 25.55 (B):

hills

Hit Enter when you’re done.

Step 5 – Add a Material to the Plane

Add a material to the plane. Set its base color to a shade of brown:

Add a Material to the Plane

Step 6 – Create a New Collection

As we’re going to create quite a few tree objects, it’s a good idea to put them in a separate collection. This will help us keep things organized. To add a collection right-click on Scene Collection (A) and select New Collection.

Create a New Collection

Rename the collection ‘trees’ and drag the tree object to it:

rename collection

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.

Step 7 – Select the Locations to Spawn At

We’re ready to finally write the script, but before we do, let’s go to edit mode, top view, and manually select the vertices where we want to spawn the trees. Let’s start with just a couple vertices, like ten. Here are the vertices that I selected:

Select the Locations to Spawn At

I want ten trees at these exact locations.

Step 8 – Write the Python Script

With the vertices selected, go to the Scripting Workspace, add a new script and type in the code below. All explanations are in the comments:

 # We need the bpy module to do most stuff in Blender Python.
 import bpy
  
 # Let's assign our tree object to a variable.
 tree = bpy.data.objects['tree']
  
 # Let's access the active object, which is the plane.
 obj = bpy.context.active_object
  
 # Now we can create the list of all the vertices that we just selected.
 # To do that we can use a list comprehension. We use co array of the 
 # MeshVertex struct to access the local certex coordinate. In order to
 # get global vertex coordinates we must multiply it by the world
 # transformation matrix.
 selected = [(obj.matrix_world @ v.co) for v in obj.data.vertices if v.select]
  
 # Now we can loop through all the selected vertices and add a tree at each of them.
 for vertex in selected:
     # We need a name for each tree. So, let's create it by concatenating the word
     # 'tree' with the coordinates of the tree.
     name = f'tree {vertex}'
     
     # Now we can create a new tree, give it the name and object data from the 
     # original tree. We'll assign the new tree to a variable.
     new_tree = bpy.data.objects.new(name=name, object_data=tree.data)
     
     # We'll position the tree at the coordinates of the selected vertex.
     new_tree.location = (vertex[0], vertex[1], vertex[2])
     
     # Finally, let's add the tree to the trees collection.
     bpy.data.collections["trees"].objects.link(new_tree) 

Step 9 – Run the Script

Before you run the script, make sure the plane is selected in object mode. Then you can go to edit mode to watch the selected vertices and the trees that will appear there. Now hit the Run Script button:

Run the Script

You should now see the trees added at the locations that we previously selected:

trees

Step 10 – A More Complex Example

The example works fine, but let’s add some variation to it. We can additionally randomly rotate and scale each new tree. Besides, we’ll add more trees. Before you continue, hit Ctrl + Z to undo the previous operation, which means remove all the trees you just added. Then go back to Layout workspace, top view and deselect all. Then in the Select menu (A) select Select Random and set Percent to 10 (B):

A More Complex Example

Now 10% of the vertices is selected. Go to the Scripting workspace and modify the script like so:

 # We need the bpy module to do most stuff in Blender Python.
 import bpy
  
 # We'll also need some functions from the random module to randomize
 # the rotation and scale of the trees.
 from random import randint, uniform
  
 # We'll rotate the trees, but the rotation_euler method that we're 
 # going to use accepts angles in radians. So we can use the radians
 # function from the math module in order to convert degrees to radians.
 from math import radians
  
 # Let's assign our tree object to a variable.
 tree = bpy.data.objects['tree']
  
 # Let's access the active object, which is the plane.
 obj = bpy.context.active_object
  
 # Now we can create the list of all the vertices that we just selected.
 # To do that we can use a list comprehension. We use co array of the 
 # MeshVertex struct to access the local certex coordinate. In order to
 # get global vertex coordinates we must multiply it by the world
 # transformation matrix.
 selected = [(obj.matrix_world @ v.co) for v in obj.data.vertices if v.select]
  
 # Now we can loop through all the selected vertices and add a tree at each of them.
 for vertex in selected:
     # We need a name for each tree. So, let's create it by concatenating the word
     # 'tree' with the coordinates of the tree.
     name = f'tree {vertex}'
     
     # Now we can create a new tree, give it the name and object data from the 
     # original tree. We'll assign the new tree to a variable.
     new_tree = bpy.data.objects.new(name=name, object_data=tree.data)
     
     # We'll position the tree at the coordinates of the selected vertex.
     new_tree.location = (vertex[0], vertex[1], vertex[2])
     
     # Now we need random angles for all three axes. They should be between -10 and
     # 10 degrees for the X and Y axes and between -45 and 45 for the Z axis.  
     angleX = randint(-10, 10)
     angleY = randint(-10, 10)
     angleZ = randint(-45, 45)
     
     # Now we can use the angles to rotate the tree. We must remember to use radians,
     # though, so let's use the radians function to convert from degrees.
     new_tree.rotation_euler = (radians(angleX), radians(angleY), radians(angleZ))
     
     # We also want to scale the trees randomly so that they look more natural. Let's
     # pick a random scale between 0.6 and 3 for example.    
     scale = uniform(0.6, 3)
     
     # Let's use the same scale for all three axes.
     new_tree.scale = (scale, scale, scale)
     
     # Finally, let's add the tree to the trees collection.
     bpy.data.collections["trees"].objects.link(new_tree) 

Run the script. You should see the trees:

more trees

Go to the Layout workspace to see it better:

more trees

As you can see, the trees are rotated and scaled randomly. But what’s of most interest to us in this article is that they are at the exact positions we wanted them to be.


Spread the love

Leave a Reply