Script To Delete Every Other Vertex In A Mesh

Hi All,

I am using a mesh to place particles across a logo.
The particle source is a group with an animated set of actions.

So I apply the group to the particle system and they appear at every vertex. this is fine, however, they all move in the exact same manner. I can not find any way to offset the action animation portion to each particle.

So it occurs to me that if I could render out several passes of these particles I could offset the time in After Effects and achieve a more organic effect.

My approach is to create 3 copies of the logo and simply delete every other vertex. Then the particle system would simply place them where the verticies are.

The logo is complicated and to remove every other vertex by hand is extremely tedious. I was wondering if anyone had any idea on how to start a little script like this. Ideally it should be able to delete every 3rd, every 4th vertex as well. This would allow me to create several different passes that I could then time offset in After Effects.

I know this is a highly specific request, but it could be a very powerfull option for the particle system to distribute particles across a mesh and skip every Nth one.

Here’s a quick try. Alter n to delete every nth. Feel free to hack the script as needed.


import bpy 
from Blender import Mesh, Object, Window 
 
is_editmode = Window.EditMode() 
if is_editmode: Window.EditMode(0) 
     
 
ob = Object.GetSelected()[0] 
me = ob.getData() 
 
n = 2 
 
indices_to_spare = {} 
 
for v in me.verts: 
    if v.index % n: 
        indices_to_spare[v.index] = v 
 
print indices_to_spare 
 
coords = [] 
 
for v in indices_to_spare.itervalues(): 
    coords.append(v.co) 
 
new_me = bpy.data.meshes.new(me.name) # create a new mesh 
 
new_me.verts.extend(coords)          # add vertices to mesh 
 
ob.link(new_me) 
 
if is_editmode: Window.EditMode(1) 

Thanks BeBraw,
The script works great. I can now get an even/odd vertex template out of my master logo.

I am wondering how I could get a first vertex offset? Say I wanted every third vertex. I could set n=3 and run the script, but even if I ran it 3 times, it would produce the same exact mesh each time.

I think I got it.


import bpy 
from Blender import Mesh, Object, Window 
is_editmode = Window.EditMode() 
if is_editmode: Window.EditMode(0) 
ob = Object.GetSelected()[0] 
me = ob.getData()
vertexCount = len(me.verts)
 
n = 5 
startVertex = 0     #initial vertex offset.
indices_to_spare = {} 
for v in me.verts: 
 if (v.index+startVertex) % n:
  n = n
 else:
  indices_to_spare[(v.index+startVertex)] = v
print indices_to_spare 
coords = [] 
for v in indices_to_spare.itervalues(): 
    coords.append(v.co) 
new_me = bpy.data.meshes.new(me.name) # create a new mesh 
new_me.verts.extend(coords)          # add vertices to mesh 
ob.link(new_me) 
if is_editmode: Window.EditMode(1) 

You can duplicate the master mesh and run the script again. All you have to do is increment startVertex manually before each run.

Well. You can skip this part easily by controlling the offset (startVertex in this case) by using a loop like:


for startVertex in range(1, n-1):
...

The trick is to link the created meshes into separate object blocks within the loop.

Anyway great that you got it to work the way you wanted.:cool:

BeBraw,

I did a google on a python “for” and came up with something similar to your suggestion, but when I did that, “v” fell out of scope and the if, inside the loop quit working.

Would I need another line like this inside the loop?


v = me.verts[startVertex]

I am not new to coding, just python. In your example, is startVertex the variable of the loop?

It would be nice if the code could create all the new mesh copies.

Yeah. startVertex is the iterator variable of the loop. range() is a generator that returns integers on given range (range(5) returns 0,1,2,3,4, range(1,3) returns 1,2). Check out the Python documentation for more information about generators and range().

I wrote an implementation of what I meant in my previous post. I also cleaned up the code a bit although it’s still far from perfect:


import bpy  
from Blender import Mesh, Object, Scene, Window 
 
is_editmode = Window.EditMode()  
if is_editmode: Window.EditMode(0) 
 
ob = Object.GetSelected()[0]  
me = ob.getData() 
 
n = 5 
 
for vertex_offset in range(n): 
    indices_to_spare = {}  
     
    for v in me.verts:  
        if not (v.index + vertex_offset) % n: 
            indices_to_spare[(v.index + vertex_offset)] = v 
     
    coords = []  
    for v in indices_to_spare.itervalues():  
        coords.append(v.co) 
     
    new_me = bpy.data.meshes.new(me.name) 
    new_me.verts.extend(coords) 
     
    sc = Scene.GetCurrent() 
    new_ob = sc.objects.new(new_me) 
    new_ob.setLocation(ob.loc) 
    new_ob.sel = False 
 
if is_editmode: Window.EditMode(1)

Basically it just creates separate mesh objects at the place of the original. Use n to control how many meshes to create.

Thanks again, I’ll give it a try!