18
$\begingroup$

I do not want to use BMesh this time.

I want to create a mesh programmatically, for this purpose I created this short script to see what I do wrong in my importer script. In this script I try to create a tetraeder. First I create the mesh, then define the vertices. Then I go for the polygons, but here I do something bad, because at the end I got no polygons defined.

The code:

mesh = bpy.data.meshes.new("Teszt")

mesh.vertices.add(4)
mesh.vertices[0].co = (0,0,0)
mesh.vertices[1].co = (2,0,0)
mesh.vertices[2].co = (1,2,0)
mesh.vertices[3].co = (1,1,3)

mesh.polygons.add(4)
mesh.polygons[0].vertices = (0,1,2)
mesh.polygons[1].vertices = (0,1,3)
mesh.polygons[2].vertices = (1,2,3)

mesh.polygons[3].vertices = (0,2,3)
print(len(mesh.polygons[3].vertices))

mesh.polygons[3].vertices = [0,2,3]
print(len(mesh.polygons[3].vertices))

#mesh.update()

#from bpy_extras import object_utils
#object_utils.object_data_add(bpy.context, mesh)

I am pretty new to Python, so it may be totally my fault, but when I check the len of (0,2,3), that is 3, when I execute mesh.polygons[3].vertices = (0,2,3) it says 0. No exception or error message, just shallows it.

When I try to update() or ...data_add( at the end, Blender simply exits.

So my question is: how to define the polygons properly (and without using bmesh)?

$\endgroup$
16
$\begingroup$

Your importer script might be easier to write using from_pydata, it will certainly look cleaner.

quads

verts = [
    (1.0, 1.0, -1.0),
    (1.0, -1.0, -1.0),
    (-1.0, -1.0, -1.0),
    (-1.0, 1.0, -1.0),
    (1.0, 1.0, 1.0),
    (1.0, -1.0, 1.0),
    (-1.0, -1.0, 1.0),
    (-1.0, 1.0, 1.0)
]

faces = [
    (0, 1, 2, 3),
    (4, 7, 6, 5),
    (0, 4, 5, 1),
    (1, 5, 6, 2),
    (2, 6, 7, 3),
    (4, 0, 3, 7)
]

tris

verts = [
    (-0.285437,-0.744976,-0.471429),
    (-0.285437,-0.744976,-2.471429),
    (1.714563,-0.744976,-2.471429),
    (1.714563,-0.744976,-0.471429),
    (-0.285437,1.255024,-0.471429),
    (-0.285437,1.255024,-2.471429),
    (1.714563,1.255024,-2.471429),
    (1.714563,1.255024,-0.471429)
]

faces =  [
    (4,5,1), (5,6,2), (6,7,3), (4,0,7),
    (0,1,2), (7,6,5), (0,4,1), (1,5,2),
    (2,6,3), (7,0,3), (3,0,2), (4,7,5)
]

both

import bpy  

# verts = 
# faces =   

mesh_data = bpy.data.meshes.new("cube_mesh_data")
mesh_data.from_pydata(verts, [], faces)
mesh_data.update()

obj = bpy.data.objects.new("My_Object", mesh_data)

scene = bpy.context.scene
scene.objects.link(obj)
obj.select = True
# scene.objects.active = obj  # make the selection effective
$\endgroup$
  • 2
    $\begingroup$ With Blender 2.8, I had to replace scene.objects.link() with scene.collection.objects.link() to make this work. $\endgroup$ – kakyo Jul 8 at 2:40
6
$\begingroup$

The reason the script fails is because you're not adding loops or setting the loop start or loop_total for each polygon.

This is not very handy for mesh creation, which is why BMesh API was added as well as from_pydata utility function.

If you want to see how it works bpy_types.py defines the from_pydata function.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.