(WARNING The implementation of this operator is based on an inspection of Blender source code. It just works but does not reflect the suggested usage from the design.)

In this post I will take an experiment on generating mesh dynamically in Blender.

As I said in the previous post there are two possible approaches to generate mesh data dynamically. One is to add a new BMesh operator which is similar to create_cube. The other is to construct a Mesh(defined in the file DNA_mesh_types.h) first and apply the BMesh operator mesh_to_bmesh. I will try the later one today.

The major problem of this project is how to construct a Mesh. More concretely, you have to search for functions which can be used as tools to construct a Mesh.

If you are familiar with the directory structure of Blender, you would probably make a correct guess that those Mesh related functions should be in blender/source/blender/editors/(The answer is ED_mesh.h). But you still have to spend time on making sure your way of applying those functions is correct, that is, you should provide the correct preconditions for every call.

Instead of the above approach, I introduce you a way to learn how to construct a Mesh by using Blender’s Python API.

Let us get started.

I assume you are familiar of how to achieve this using Python API:

mesh = bpy.data.meshes.new("MyMesh")
vertices = [
    (0, 0, 0),
    (1, 0, 0),
    (1, 1, 0),
    (0, 1, 0)
]
faces = [(0, 1, 2), (2, 3, 0)]
mesh.from_pydata(vertices, [], faces)

The most important function is from_pydata. This function fills the mesh data and build the topology for a mesh. You can find the implementation of this function in file bpy_types.py(directory blender/release/scripts/modules).

I put an excerpt of its source code below:

self.vertices.add(len(vertices))
self.edges.add(len(edges))
self.loops.add(sum((len(f) for f in faces)))
self.polygons.add(len(faces))

vertices_flat = [f for v in vertices for f in v]
self.vertices.foreach_set("co", vertices_flat)
del vertices_flat

edges_flat = [i for e in edges for i in e]
self.edges.foreach_set("vertices", edges_flat)
del edges_flat

# this is different in bmesh
loop_index = 0
for i, p in enumerate(self.polygons):
    f = faces[i]
    loop_len = len(f)
    p.loop_start = loop_index
    p.loop_total = loop_len
    p.vertices = f
    loop_index += loop_len

# if no edges - calculate them
if faces and (not edges):
    self.update(calc_edges=True)

All functions called above is implemented in C. By applying tracing techniques I introduced in this post (Hint: search "add", "loop_start" in the source code. Be sure to include the double quotes while searching since we are interested in the reflection code with those words), we can collect all of the information we need to construct a Mesh.

After that, the remains are simple.

To call a BMesh operator, according our analysis on BMesh system, you can find the desired operator name and parameters in bmo_opdefines.

Also do not forget to link the newly created object to the scene, and trigger a notification.

I upload all source code of this experiment here.

In the next post I will write some real code on the contouring algorithm.