Python: How to Make a Mesh from XYZ Coordinates

Or the world's worst chess board.

This was shockingly confusing. I mean it. You’d think there’d be a nice, simple way to plop coordinates into Blender to get a mesh. If there is, I wasn’t able to find it.

However, The Proving Ground has a really nice breakdown on the process because whoever runs that place is a damn saint.

The important bits to remember are basically this:

STEP 1: Create a Vertices Array with X,Y,Z Values for Each Point

Vertices = [(0,0,0),(0,1,0),(1,0,0),(1,1,1)]

STEP 2: Create a Faces Array to Tell Blender What Order to Connect Vertices In*

Faces = [(0,1,2,3)]
*The numbers within the parenthesis will connect to form a face. Remember, 0 = the first item in an array, so the 0 in Faces refers to (0,0,0).

STEP 3: Make a Mesh and Assign It to a Variable

EasyMeshVariable = bpy.data.meshes.new(“MeshName“)

STEP 4: Make an Object and Pop that Mesh into It*

EasyObjectVariable = bpy.data.objects.new(“ObjectName“, EasyMeshVariable)
*Alright, this is the part where I went a little rabid on Google because I hadn’t yet realized that meshes and objects are different things. Finally found the answer here. Basically, an Object is a Mesh + Material + Texture.

STEP 5: Set the Object Location to the Cursor Location

EasyObjectVariable.location = bpy.context.scene.cursor_location

STEP 6: Link the Object to the Current Scene

bpy.context.scene.objects.link(EasyObjectVariable)

STEP 7: Push the Vertices and Faces Arrays into the Mesh

EasyMeshVariable.from_pydata(Vertices,[],Faces)

So if you ever have a dire need to make a three-sided face with far too many lines of code, just follow that template. Like so:

Well, that was a lot of work for one damn triangle.

You may have noticed that the vertices array has an extra point at (1,1,1,). Since the faces array doesn’t have a 3 (the 4th item in the vertices array), Blender doesn’t connect that vertex.

Here’s where things can get wonky. Connect the vertices in a bad order and you might get this problem:

That's unfortunate.

If this happens it’s actually a really easy fix. Just switch around the order in the faces array.

Hey, a face!

That’s it in a nutshell. But the real fun comes in plugging formulas into the vertex array for crazy meshes. I use “fun” here to mean “torture” if you hate math.

A Working Example: The ExpPlanes Function

So if say, you run x,y,z, values through a while loop and use the .append function to push coordinates into the vertices array, you can get hundreds of points with not that much code. The tricky part is pushing the right numbers into the faces array so that it’ll display everything as intended.

Here’s a function that makes multiple planes within the same mesh at precise intervals on the Z axis. X and Y remain constant.

import bpy
#z equals the z axis increments for each plane
#height equals the z value of the highest plane
#size equals size of planes
#sinc equals how much to increment size by as z gets higher
def expplanes(zinc,height,size,sinc):
vertices = []
faces = []
z=0
x=0
y=0
index=0
while index<=height:
vertices.append([x,y,z])
vertices.append([x+size,y,z])
vertices.append([x+size,y+size,z])
vertices.append([x,y+size,z])
faces.append([index,index+1,index+2,index+3])
z+=zinc
size+=sinc
index+=4
EasyMeshVariable = bpy.data.meshes.new("MeshName")
EasyObjectVariable = bpy.data.objects.new("ObjectName", EasyMeshVariable)
EasyObjectVariable.location = bpy.context.scene.cursor_location
bpy.context.scene.objects.link(EasyObjectVariable)
EasyMeshVariable.from_pydata(vertices,[],faces)

expplanes(.5,50,2,.1)

This uses an index variable to deal with the faces array. Add 4 to index at the end of every loop and it’ll jump forward to the next set of 4 vertices to create a separate plane.

What in the hell good is this, you ask? Well, I’m thinking a creepy spaceship like this guy:

Needs a bit of texturing.

 

 

Advertisements
Tagged , , , , , , ,

4 thoughts on “Python: How to Make a Mesh from XYZ Coordinates

  1. Bryan says:

    This is good stuff. Great post with screenshots and all. I’ve done this now, creating a simple square face (a plane) and added it to the scene, all in python. The trouble comes when I want to “extrude” the plane into a solid object using python. For whatever reason, the new object comes up selected red and not orange, and I can’t toggle edit mode using python to use extrude. I get an error saying the “context” is wrong. However, if I use the mouse and right click on the new object, shazaam, it comes up select orange like it should, and I can toggle edit mode using python. What is going on when the object is added to the scene in python that would prevent me from selecting it in python and turning on edit mode? Thanks.

    Like

  2. Bryan says:

    I think we came to the same conclusion, just slightly different lines. I kept just hacking my way through it thinking it was something to do with the scene and not the object itself. This is what I finally stumbled upon:

    myObj = create_custom_mesh(“My_Obj”, curloc[0], curloc[1], 0)
    bpy.context.scene.objects.active = myObj

    …exact same solution essentially…and then the same (mode = ‘EDIT’) line that you have finally works flawlessly for me too.

    “As with many Python things, I have no idea why it worked.”

    Loved that line, so true. Sometimes the seemingly obvious solution has ‘quirks’ and you just have to work through them not being familiar enough with the API. However, sometime in the future, it will make perfect sense. It’s the not understanding part that usually keeps me moving forward…I hate not understanding things.

    Thanks for the solution though! Now, back to creating woodworking part extrusions from face profiles…

    Hope Christmas was good, and happy New Year to ya.

    Like

    • Yup, I also hate not understanding things.

      I love seeing multiple solutions for the same problem though. It makes me think that Python might not be the unwieldy bastard I thought it was.

      Happy holidays to you too! And good look with the woodworking.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: