problems with for & selected meshes (solved)

Hi,
“For” loops work… e.g.

for i in range(3):
  for j in range(4):
    print j

works as expected. (Note: copying and pasting from this webpage into Blender doesn’t seem to work… perhaps the newline characters don’t get imported… so you might need to retype my code)

The output:

‘import site’ failed; use -v for traceback
Using a clean Global Dictionary.
Run Python script “Text” …
0
1
2
3
0
1
2
3
0
1
2
3

But ones that involve meshes don’t.

Here’s some examples:

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].data
for v in mesh.vert:
  print v[0]

The output:

Using a clean Global Dictionary.
Run Python script “Text” …
warning: The Object.getSelected() function will be removed in Blender 2.29
Please update the script to use Object.GetSelected
In Object_GetSelected()
Traceback (most recent call last):
File “Text”, line 5, in ?
AttributeError: vert
‘import site’ failed; use -v for traceback

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].data
for v in mesh.verts:
  for i in range(3):
    print v[i]

The output:

Using a clean Global Dictionary.
Run Python script “Text” …
warning: The Object.getSelected() function will be removed in Blender 2.29
Please update the script to use Object.GetSelected
In Object_GetSelected()
1.0
0.999999940395
0.0
Traceback (most recent call last):
File “Text”, line 6, in ?
ImportError: No module named warnings
‘import site’ failed; use -v for traceback

(Line 6 becomes highlighted - it is the inner loop)
It should print the coordinates of all 4 vertices in the plane - not just halt like that…

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].data
for v in mesh.verts:
  for i in range(3):
    for j in range(5):
      print v[i]

This should print each component of the coordinates five times. Instead it prints the first coordinate component once, and halts. The innermost loop is highlighted.
The output:

Using a clean Global Dictionary.
Run Python script “Text” …
warning: The Object.getSelected() function will be removed in Blender 2.29
Please update the script to use Object.GetSelected
In Object_GetSelected()
1.0
1.0
1.0
1.0
1.0
Traceback (most recent call last):
File “Text”, line 7, in ?
ImportError: No module named warnings
‘import site’ failed; use -v for traceback

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].data
for v in mesh.verts:
  print v[0]
  print v[1]
  print v[2]

print "Loop finished"

The output:

Using a clean Global Dictionary.
Run Python script “Text” …
warning: The Object.getSelected() function will be removed in Blender 2.29
Please update the script to use Object.GetSelected
In Object_GetSelected()
1.0
0.999999940395
0.0
1.0
-1.0
0.0
-1.00000011921
-0.999999821186
0.0
-0.999999642372
1.00000035763
0.0
Traceback (most recent call last):
File “Text”, line 5, in ?
ImportError: No module named warnings
‘import site’ failed; use -v for traceback

It goes through the one and only loop in that script properly, but it then halts, and highlights the “for” statement as usual. It doesn’t print that last part of the script.

import Blender

selectionList = Blender.Object.getSelected()
mesh = Blender.NMesh.GetRaw(selectionList[0].data.name)

for v in mesh.verts:
  for i in range(3):
    for j in range(5):
        print v,i,j

gives that:
Using a clean Global Dictionary.
Run Python script “Text.001” …
In Object_GetSelected()
<Blender NMVert object at 0x00F75350> 0 0
<Blender NMVert object at 0x00F75350> 0 1
<Blender NMVert object at 0x00F75350> 0 2
<Blender NMVert object at 0x00F75350> 0 3
<Blender NMVert object at 0x00F75350> 0 4
Traceback (most recent call last):
File “Text.001”, line 8, in ?
File “F:\PROGRAMSFILES\PYTHON\LIB\warnings.py”, line 38, in warn
filename = sys.argv[0]
AttributeError: ‘module’ object has no attribute ‘argv’

but :

import Blender

selectionList = Blender.Object.getSelected()
mesh = Blender.NMesh.GetRaw(selectionList[0].data.name)

for v in mesh.verts:
  for i in xrange(3):
    for j in xrange(5):
        print v,i,j

returns that:

<Blender NMVert object at 0x00F84170> 1 1
<Blender NMVert object at 0x00F84170> 1 2
<Blender NMVert object at 0x00F84170> 1 3
<Blender NMVert object at 0x00F84170> 1 4
<Blender NMVert object at 0x00F84170> 2 0
<Blender NMVert object at 0x00F84170> 2 1
<Blender NMVert object at 0x00F84170> 2 2
<Blender NMVert object at 0x00F84170> 2 3
<Blender NMVert object at 0x00F84170> 2 4
<Blender NMVert object at 0x00F84130> 0 0
<Blender NMVert object at 0x00F84130> 0 1
<Blender NMVert object at 0x00F84130> 0 2
<Blender NMVert object at 0x00F84130> 0 3
<Blender NMVert object at 0x00F84130> 0 4
<Blender NMVert object at 0x00F84130> 1 0
<Blender NMVert object at 0x00F84130> 1 1
<Blender NMVert object at 0x00F84130> 1 2
<Blender NMVert object at 0x00F84130> 1 3
<Blender NMVert object at 0x00F84130> 1 4
<Blender NMVert object at 0x00F84130> 2 0
<Blender NMVert object at 0x00F84130> 2 1
<Blender NMVert object at 0x00F84130> 2 2
<Blender NMVert object at 0x00F84130> 2 3
<Blender NMVert object at 0x00F84130> 2 4

Thanks jms!

So it seems that NMesh.GetRaw is very important…

To see if it is working properly I made this little test:

import Blender
selectionList = Blender.Object.getSelected()
mesh = Blender.NMesh.GetRaw(selectionList[0].data.name)

for vertex in mesh.verts:
  for i in xrange(3):
      print vertex[i]

It printed out the coordinates of the mesh without any errors… :smiley:

or, if you prefer.

import Blender
selectionList = Blender.Object.getSelected()
mesh = selectionList[0].getData()
for vertex in mesh.verts:
  for i in xrange(3):
      print vertex[i]

jms:
Ah… .getData()… that works fine too…

I’ve made some more of the script, but a similar problem has happened again:

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].getData()

nParts = 5
nVerts = len(mesh.verts)

for p in range(nParts):
  rangeStart = (p * nVerts)/nParts
  rangeEnd = ((p+1)*nVerts)/nParts
  print rangeStart, rangeEnd
print "-"

I had an icosphere with two subdivisions (42 vertices) selected.

It goes through the loop, but halts (like before) before the last line with the error:
“ImportError: No module named warnings”

If I manually set nVerts (e.g. write “nVerts = 42”) it behaves exactly the same!

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].getData()

nParts = 5
nVerts = len(mesh.verts)

for p in range(nParts):
  rangeStart = (p * nVerts)/nParts
  rangeEnd = ((p+1)*nVerts)/nParts
  print rangeStart, rangeEnd
print "-"

But if I comment out lines 3 and 4 (involving the selection) then it works!

If line 4 ("mesh = ") is changed to this:
mesh = Blender.NMesh.GetRaw(selectionList[0].data.name)
it doesn’t work, even with line 3 restored to normal and nVerts = 42. (Or nVerts = len(mesh.verts))

Here’s a more developed version of my script, that also doesn’t work:

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].getData()
#mesh = Blender.NMesh.GetRaw(selectionList[0].data.name)

nParts = 5
nVerts = len(mesh.verts)

for p in range(nParts):
  rangeStart = (p * nVerts)/nParts
  rangeEnd = ((p+1)*nVerts)/nParts
  print rangeStart, rangeEnd
  for v in range(rangeStart, rangeEnd):
    print v
  print "-"

It highlights the inner loop after doing the inner loop once (like in my original post)

What I eventually want to do is to use the selected mesh and create nParts new meshes, where each part has about the same amount of vertices… if the original mesh has 42 vertices, part 0 would have vertices 0 to 7, part 1 - vertices 8 to 15, part 2 - vertices 16 to 24, part 3 - vertices 25 to 32, and part 4 - vertices 33 to 41.

BTW, in the last bit of code, if lines 3 to 4 are commented out, and nVerts is changed to “nVerts = 42” it works properly.

just asking, but what version of Python do you have?

Martin

I’m using Blender 2.28 and have Python 2.0 installed. The pythonpath wasn’t set though…
I’ve now set it to:
C:\PYTHON20;C:\PYTHON20\DLLS;C:\PYTHON20\LIB;C:\PYTHON20\LIB\LIB-TK
(Where python is located) and restarted my computer and the scripts act in the same way…

The mesh simplification script works perfectly though… it removes redundant faces and vertices. I’m going to look at their code…

http://mail.python.org/pipermail/idle-dev/2001-October/000701.html
says:
“The warnings module is a part of python >= 2.1”

I’ll try and install Python 2.2…

that’s exactly what I was getting at :wink:

Martin

theeth:
Now I’m getting the same error jms did:

Traceback (most recent call last):
File “Text”, line 10, in ?
File “C:\PYTHON22\Lib\warnings.py”, line 38, in warn
filename = sys.argv[0]
AttributeError: ‘module’ object has no attribute ‘argv’

Where “line 10” is the line number of the inner-most for loop…

I looked at jms’s posts and he had 2 pieces of code that seemed identical… but one used range and the other used xrange…

Well it works now if I use xrange instead of range!

well, that’s not really how you were doing it, but this splits the mesh vertice in a list in parts, and it works.


import Blender

me = Blender.Object.GetSelected()[0].getData()

tv = len(me.verts)

parts = 7

vlist = [[],[],[],[],[],[],[]]

i = 0
for v in me.verts:
	vlist[i/(parts-1)].append(v)
	i+=1

hope that helps

Martin
PS: still, weird bug…

import Blender
selectionList = Blender.Object.getSelected()
mesh = selectionList[0].getData()
nParts = 5
nVerts = len(mesh.verts)
for p in xrange(nParts):
  rangeStart = (p * nVerts)/nParts
  rangeEnd = ((p+1)*nVerts)/nParts
  print rangeStart, rangeEnd
print "-"

Do not use >> range << but >> xrange <<, it works.
Curious, >> range << should normally work.

This will be noticed to the python developpers

theeth:

Thanks for that code… it is quite compact, though to do what I wanted to do I had to do it a longer way…

This is my finished script:

import Blender

selectionList = Blender.Object.getSelected()
mesh = selectionList[0].getData()

nParts = 8
nVerts = len(mesh.verts)

for p in xrange(nParts):
  me = Blender.NMesh.GetRaw()

  rangeStart = (p * nVerts)/nParts
  rangeEnd = ((p+1)*nVerts)/nParts
  for v in xrange(rangeStart, rangeEnd):
    me.verts.append(mesh.verts[v])
  me.update()
  str = selectionList[0].getName() + ("%s" % (p+1))
  Blender.NMesh.PutRaw(me, str, 1)

In the second to last line I was joining a number onto the old object name - it seems unnecessarily complicated although I couldn’t work out a simpler way.