Solved

Export vertex pool with python


Hello,

I am trying to export vertex coordinates from mesh to the attribute, but I am getting this error:

TypeError: Failure to convert list values to native values.

And here is the code:

class FeatureProcessor(object):
    def input(self, feature):
        mesh = feature.getGeometry()
        vp = mesh.getVertices()
        feature.setAttribute('VertexPool', vp)
        self.pyoutput(feature)
 

icon

Best answer by david_r 5 April 2018, 17:30

View original

3 replies

Badge +22

You are trying to assign a list of tuples to a single attribute.

I would suggest a structure like

 

VertexPool{}.x

 

VertexPool{}.y

 

VertexPool{}.z

 

 

Which could be created in a for loop
for i, v in enumerate(vp):
feature.setAttribute("VertexPool{%d}.x" %i, v[0])
feature.setAttribute("VertexPool{%d}.y" %i, v[1])
feature.setAttribute("VertexPool{%d}.z" %i, v[2]) 

Userlevel 4

Looking at the fmeobjects documentation, we see that FMEMesh.getVertices() returns a list of tuples of floats on the form (x, y, z). Unfortunately FMEFeature.setAttribute() doesn't know how to handle nested lists (among others), so you'll have to be a bit more specific about what you need.

Let's give some examples for the case where "vp" contains a list of the following three tuples:

[(1,2,3), (4,5,6), (7,8,9)]

If you just need "VertexPool" to contain the string representation of "vp", you can do:

feature.setAttribute('VertexPool', str(vp))

This will set the following string value on VertexPool:

VertexPool = '[(1, 2, 3), (4, 5, 6), (7, 8, 9)]'

If you want VertexPool to be a list of all the vertices, you can do:

feature.setAttribute('VertexPool{}', [str(vertex) for vertex in vp])

You will now have the following list, which you can further analyze with e.g. the ListExploder:

VertexPool{0} = '(1, 2, 3)'
VertexPool{1} = '(4, 5, 6)'
VertexPool{2} = '(7, 8, 9)'

Finally, you may want to split it up further into list elements for the x,y,z components:

for n, vertex in enumerate(vp):
    feature.setAttribute('VertexPool{%s}.x' % n, vertex[0])
    feature.setAttribute('VertexPool{%s}.y' % n, vertex[1])
    feature.setAttribute('VertexPool{%s}.z' % n, vertex[2])

Which will give you the following result:

VertexPool{0}.x = 1
VertexPool{0}.y = 2
VertexPool{0}.z = 3
VertexPool{1}.x = 4
VertexPool{1}.y = 5
VertexPool{1}.z = 6
VertexPool{2}.x = 7
VertexPool{2}.y = 8
VertexPool{2}.z = 9

Let us know if you need something specific that isn't covered above.

Looking at the fmeobjects documentation, we see that FMEMesh.getVertices() returns a list of tuples of floats on the form (x, y, z). Unfortunately FMEFeature.setAttribute() doesn't know how to handle nested lists (among others), so you'll have to be a bit more specific about what you need.

Let's give some examples for the case where "vp" contains a list of the following three tuples:

[(1,2,3), (4,5,6), (7,8,9)]

If you just need "VertexPool" to contain the string representation of "vp", you can do:

feature.setAttribute('VertexPool', str(vp))

This will set the following string value on VertexPool:

VertexPool = '[(1, 2, 3), (4, 5, 6), (7, 8, 9)]'

If you want VertexPool to be a list of all the vertices, you can do:

feature.setAttribute('VertexPool{}', [str(vertex) for vertex in vp])

You will now have the following list, which you can further analyze with e.g. the ListExploder:

VertexPool{0} = '(1, 2, 3)'
VertexPool{1} = '(4, 5, 6)'
VertexPool{2} = '(7, 8, 9)'

Finally, you may want to split it up further into list elements for the x,y,z components:

for n, vertex in enumerate(vp):
    feature.setAttribute('VertexPool{%s}.x' % n, vertex[0])
    feature.setAttribute('VertexPool{%s}.y' % n, vertex[1])
    feature.setAttribute('VertexPool{%s}.z' % n, vertex[2])

Which will give you the following result:

VertexPool{0}.x = 1
VertexPool{0}.y = 2
VertexPool{0}.z = 3
VertexPool{1}.x = 4
VertexPool{1}.y = 5
VertexPool{1}.z = 6
VertexPool{2}.x = 7
VertexPool{2}.y = 8
VertexPool{2}.z = 9

Let us know if you need something specific that isn't covered above.

Thanks, just a simple string was enough ;)

 

 

 

Reply