How to draw mesh with python like simulation modifier does?

I’m thinking of creating my own cloth simulator but I need visualization before begin.
How can I draw mesh with python like simulation modifier does?
thanks.

TL;TR

  • You can create a mesh from points, edges and faces like so.
import bpy

# MESH STASTICS
V = [(-0.5, 1.0, 0.0),
    (0.5, 1.0, 0.0),
    (0.5, 4.0, 0.0),
    (-0.5, 4.0, 0.0),
    (-0.5, -8.0, 0.0),
    (0.5, -8.0, 0.0),
    (0.5, 0.0, 0.0),
    (-0.5, 0.0, 0.0),
    (2.5, 0.0, 0.0),
    (2.5, 1.0, 0.0),
    (-2.5, 1.0, 0.0),
    (-2.5, 0.0, 0.0),]
E = []
F = [(0, 1, 2, 3),
    (4, 5, 6, 7),
    (7, 6, 1, 0),
    (11, 7, 0, 10),
    (6, 8, 9, 1),]

# CREATE MESH
m = bpy.data.meshes.new("New_Plane")
o = bpy.data.objects.new(m.name, m)
c = bpy.data.collections["Collection"]
c.objects.link(o)
bpy.context.view_layer.objects.active = o
m.from_pydata(V, E, F)

Tips

  • If you find manually finding vertices / faces difficult like I did, which took me a few hours because I’m a beginner at this, you can use two very useful techniques to get these vertex indexes to properly setup your faces in Blender.

Step 1

  • Create or import the model that you wish to gain vertex/face data from. For instance this mesh cross that I made.

Step 2

  • Export your model in Wavefront OBJ format.
    • Make sure all of your OBJ exporter settings match these for simplicity.

Step 3

  • After you’ve generated your model as OBJ, re-import it in any blend.
    • In the blend that you have your imported OBJ model, run this script.
import bpy

OBJ = bpy.data.objects["Model_Name"]
N = 0

for v in OBJ.data.vertices:
    c = bpy.data.curves.new(type="FONT", name=str(N))
    c.body = str(N)
    f = bpy.data.objects.new(name="Font Object", object_data=c)
    f.location = v.co
    f.scale = [1,1,1]
    f.parent = OBJ
    bpy.context.scene.collection.objects.link(f)
    N += 1
  • Make sure to replace Model_Name with the name of your imported model.
    • The end result of the script should look something like this.
      • What this does is create new text objects for each vertex index which is needed later on for visual reference, as I showed in my original script above.

Step #3

  • In the first script above, replace V (vertex) arrays with the arrays of your model. Daunted yet? Not to worry. See the next sub-step below on how to easily calculate F (face) arrays.
    • Each face array goes from [Lower-Left, Lower-Right, Upper-Right, Upper-Left]. For example for the left and right cross beams in my example screenshot, we have [11, 7, 0, 10] for the left beam and [6, 8, 9, 1] for the right beam.

  • Finally, if you were referring to some other modifier like Geometry Nodes, feel free to say so and I’ll drop some more code w/ explanations. Cheers!
5 Likes

Sorry for bad explanation.
What I want to do is displaying modified animating mesh with keeping input mesh.
(Like Blender’s internal cloth simulation modifier but number of vertices varies by frame.)

You can use the the gpu module to draw on screen.

https://docs.blender.org/api/current/gpu.html

However I don’t know exactly how you would run the simulation?

Option 1
Perhaps you need to call Blender from command line (with python subprocess) , with script arguments, and let it bake the sim for you, then you load the data and play them in viewport.

Option 2

  • Blender’s physics simulation is locked to animation player, so you can’t have interactive physics running on the viewport while timeline is stopped. So you forget about having interactive Blender physics on the viewport.
  • Since you can use PIP to install packages, so perhaps you can use the Python Bullet engine right away and by-pass Blender’s bullet physics.

You can use the the gpu module to draw on screen.

Can I draw mesh using materials from input mesh with this method?

However I don’t know exactly how you would run the simulation?

Data will be translated by addon, pass to external library (uses cdll.LoadLibrary()), compute, write back and then display result.
Is this not enough to work?

You can draw anything but you must provide your own a GLSL shader.

It will be very difficult to recreate the EEVEE shading though, because it uses lots of complex techniques and lots passes, to compose a final image.

But for more simple shading, you can recreate any common GLSL fragment shader from scratch, based on known practices. And this is only because the rendering is done in one-go from the fragment shader.
https://learnopengl.com/Lighting/Basic-Lighting

OK this is based on semi-real-time which more or less does the job correctly.