19
$\begingroup$

I would like to create a mesh, then interactively add vertices (afterwards, possibly through a loop) to it through python.

Is that possible?

I can't find enough info from other answers to really get this going - either I find out how to create a mesh, or how to add a vertex, but can't seem to put them together in to a script.

$\endgroup$
4
  • $\begingroup$ Nowadays you'll want to use bmesh...I don't have time to write a full answer, but I will later if no one else has. $\endgroup$
    – JakeD
    Aug 29, 2016 at 12:32
  • 3
    $\begingroup$ related: blender.stackexchange.com/questions/414/… $\endgroup$
    – zeffii
    Aug 29, 2016 at 12:42
  • 1
    $\begingroup$ related: blender.stackexchange.com/questions/2407/… $\endgroup$
    – zeffii
    Aug 29, 2016 at 12:44
  • 2
    $\begingroup$ if those two links aren't helpful, please your edit question to include more details about what exactly you don't understand. $\endgroup$
    – zeffii
    Aug 29, 2016 at 12:45

2 Answers 2

29
$\begingroup$

This is how to create a new object and add the vertices in the verts list:

import bpy
import bmesh

verts = [(1, 1, 1), (0, 0, 0)]  # 2 verts made with XYZ coords
mesh = bpy.data.meshes.new("mesh")  # add a new mesh
obj = bpy.data.objects.new("MyObject", mesh)  # add a new object using the mesh

scene = bpy.context.scene
scene.objects.link(obj)  # put the object into the scene (link)
scene.objects.active = obj  # set as the active object in the scene
obj.select = True  # select object

mesh = bpy.context.object.data
bm = bmesh.new()

for v in verts:
    bm.verts.new(v)  # add a new vert

# make the bmesh the object's mesh
bm.to_mesh(mesh)  
bm.free()  # always do this when finished

This is how to alter an existing mesh:

import bpy
import bmesh

verts = [(1, 1, 1), (0, 0, 0)]  # 2 verts made with XYZ coords
mesh = bpy.context.object.data
bm = bmesh.new()

# convert the current mesh to a bmesh (must be in edit mode)
bpy.ops.object.mode_set(mode='EDIT')
bm.from_mesh(mesh)
bpy.ops.object.mode_set(mode='OBJECT')  # return to object mode

for v in verts:
    bm.verts.new(v)  # add a new vert

# make the bmesh the object's mesh
bm.to_mesh(mesh)  
bm.free()  # always do this when finished
$\endgroup$
5
  • $\begingroup$ thanks a great deal for this, pycoder - much appreciated. $\endgroup$
    – Jono
    Sep 4, 2016 at 9:21
  • $\begingroup$ @Jono: pycoder? $\endgroup$ Sep 4, 2018 at 12:04
  • 3
    $\begingroup$ @HelloGoodbye I used to be pycoder...changed my name when I started joining more SE websites. You'll see this kind of references all over the sites since there is no good renaming system. $\endgroup$
    – JakeD
    Sep 4, 2018 at 16:02
  • $\begingroup$ This no longer works in Blender 2.80 $\endgroup$
    – Ron Jensen
    Aug 7, 2019 at 21:17
  • 3
    $\begingroup$ AttributeError: 'bpy_prop_collection' object has no attribute 'link' Error: Python script failed, check the message in the system console $\endgroup$ May 25, 2020 at 13:34
19
$\begingroup$

In Blender 2.80 onward:

import bpy

mesh = bpy.data.meshes.new("myBeautifulMesh")  # add the new mesh
obj = bpy.data.objects.new(mesh.name, mesh)
col = bpy.data.collections["Collection"]
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj

verts = [( 1.0,  1.0,  0.0), 
         ( 1.0, -1.0,  0.0),
         (-1.0, -1.0,  0.0),
         (-1.0,  1.0,  0.0),
         ]  # 4 verts made with XYZ coords
edges = []
faces = [[0, 1, 2, 3]]

mesh.from_pydata(verts, edges, faces)

We can make a function, too.

import bpy

def add_mesh(name, verts, faces, edges=None, col_name="Collection"):    
    if edges is None:
        edges = []
    mesh = bpy.data.meshes.new(name)
    obj = bpy.data.objects.new(mesh.name, mesh)
    col = bpy.data.collections[col_name]
    col.objects.link(obj)
    bpy.context.view_layer.objects.active = obj
    mesh.from_pydata(verts, edges, faces)

verts = [( 1.0,  1.0,  0.0), 
         ( 1.0, -1.0,  0.0),
         (-1.0, -1.0,  0.0),
         (-1.0,  1.0,  0.0),
         ]
faces = [[0, 1, 2, 3]]
add_mesh("myBeautifulMesh_1", verts, faces)

verts = [( 3.0,  1.0,  0.0), 
         ( 3.0, -1.0,  0.0),
         ( 2.0, -1.0,  0.0),
         ( 2.0,  1.0,  0.0),
         ]
add_mesh("myBeautifulMesh_2", verts, faces)
$\endgroup$
5
  • $\begingroup$ Can you please expand your answer a little bit more. How would you add mesh2 = bpy.data.meshes.new("myBeautifulMesh_2") to mesh? $\endgroup$
    – Michael
    Jan 17, 2020 at 16:09
  • $\begingroup$ Do not use mutable default arguments docs.python-guide.org/writing/gotchas/… Other than that, it works great, thanks! :) $\endgroup$ May 24, 2020 at 11:29
  • $\begingroup$ Why do you have edges = [] mesh.from_pydata(verts, [], faces) in the first script? Didn't you mean mesh.from_pydata(verts, edges, faces)? $\endgroup$ May 25, 2020 at 13:38
  • $\begingroup$ @LukaMesaric: Nice catch! Edited. $\endgroup$
    – ludiccc
    May 26, 2020 at 14:49
  • $\begingroup$ @damn-vegetables : also, nice catch. Thanks. $\endgroup$
    – ludiccc
    May 26, 2020 at 14:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .