3

This is a very simple issue but I am making it needlessly complex and continue to hit road blocks.

I am trying to parse a simple text file which contains point cloud information, x, y, z.

It looks like this:

vertices:
v -543.243 -494.262 1282
v -538.79 -494.262 1282
v -536.422 -496.19 1287
v -531.951 -496.19 1287
v -527.481 -496.19 1287
v -213.909 -223.999 581
v -212.255 -224.384 582
v -209.15 -223.228 579
v -207.855 -223.999 581
v -205.482 -223.613 580
v -203.468 -223.613 580
v -201.106 -223.228 579
v -199.439 -223.613 580
v -197.765 -223.999 581
v -195.41 -223.613 580
v -193.062 -223.228 579
v -190.721 -222.842 578
v -189.04 -223.228 579
v -187.998 -224.384 582
v -185.976 -224.384 582
v -183.955 -224.384 582
v -181.621 -223.999 581
v -179.293 -223.613 580
v -177.279 -223.613 580
v -175.264 -223.613 580
v -173.549 -223.999 581
v -171.531 -223.999 581
v -169.513 -223.999 581
v -167.495 -223.999 581
v -165.761 -224.384 582
v -163.74 -224.384 582
v -161.718 -224.384 582
v -159.697 -224.384 582
v -157.946 -224.77 583
v -155.921 -224.77 583
v -153.896 -224.77 583
v -151.871 -224.77 583
v -149.847 -224.77 583
v -147.568 -224.384 582

Right okay. Not so bad.

Next I am using python in blender to convert these points into vertices:

It looks like so: `

    #Open the file
try:
    f=open(path, 'r')
except:
    print ("Path is not Valid")


#Create an array of 
verts = []
#verts=[float(e) for e in verts if e]
#values = []

for line in f:
    lines = f.readline() 
    #values = ([c for c in lines if c in '-1234567890.'])
    if line.startswith("v "): #Go through file line by line
        read = lines.strip(' v\n').split(',') #remove the v,split@, 
            #read = values.split(',')
        #loop over all stuff in read, remove non-numerics
        for d in read:
            d= d.strip('-').split(' ')
            print("d:", (d))
            for n in d:
                n = n.strip('-')
                verts = verts.append(float(n[0]))
                #verts = verts.append(float(n[2]))
                #verts = verts.append(float(n[3]))
                print("vertsloops", d[0])
            print("read1", read[0])
            print(read)
            print("oo1verts", verts)
             ##################
             #Extend the array# 
             #print ("Could not use the line reading: %s"%read)


# Create a new mesh, it is now empty
mesh = bpy.data.meshes.new("Cube")
# Create empty vertices field in the mesh
mesh.vertices.add(len(verts))
# Add vertices
mesh.vertices.foreach_set("co", verts)


#Add a new empty object named "Read the PointCloud Data"
obj = bpy.data.objects.new("Read the PointCloud Data", mesh)
# Link object to current scene
bpy.context.scene.objects.link(obj)
`

Somehow, I have tried many different combinations of splitting the string, but still getting errors. I know this is a simple task!?! Any Advice please!

The errors I get look at first like:

d: ['-536.422', '-496.19', '1287']
Traceback (most recent call last):
  File "/Users/.../importpoints.blend/importpoints", line 37, in <module>
ValueError: could not convert string to float: '-'
Error: Python script fail, look in the console for now...

And Then like so :

d: ['536.422', '-496.19', '1287']
vertsloops 536.422
Traceback (most recent call last):
  File "/Users/.../importpoints.blend/importpoints", line 37, in <module>
AttributeError: 'NoneType' object has no attribute 'append'
Error: Python script fail, look in the console for now...

One thing is, how come float('-531') won't be handled as a negative number. As it stands, it hits the '-' sting and considers it non-numeric so it cannot convert it. But its negative, so how can I indicate that???

Thanks.

2
  • To be clear, at first i was not doing the n.strip('-'), i tried that to omit the first error. But i would like to include negative floats... Commented Dec 6, 2015 at 7:31
  • Is the dash some other character than a regular ASCII minus? Commented Dec 6, 2015 at 8:46

5 Answers 5

2

Make your reading a bit shorter:

verts = []
for line in f:
    if line.startswith('v '):
        verts.append([float(val) for val in line.split()[1:]])

This should replace your full for line in f: loop. Make sure there is no other line later starting with v in your file. Maybe there is an empty line after the values, so you can stop reading there.

Now verts looks like this:

[[-543.243, -494.262, 1282.0],
 [-538.79, -494.262, 1282.0],
 [-536.422, -496.19, 1287.0],
 [-531.951, -496.19, 1287.0],
 [-527.481, -496.19, 1287.0],
 [-213.909, -223.999, 581.0],
 [-212.255, -224.384, 582.0],
 [-209.15, -223.228, 579.0],
 [-207.855, -223.999, 581.0],
 [-205.482, -223.613, 580.0],
 [-203.468, -223.613, 580.0],
 [-201.106, -223.228, 579.0],
 [-199.439, -223.613, 580.0],
 [-197.765, -223.999, 581.0],
 [-195.41, -223.613, 580.0],
 [-193.062, -223.228, 579.0],
 [-190.721, -222.842, 578.0],
 [-189.04, -223.228, 579.0],
 [-187.998, -224.384, 582.0],
 [-185.976, -224.384, 582.0],
 [-183.955, -224.384, 582.0],
 [-181.621, -223.999, 581.0],
 [-179.293, -223.613, 580.0],
 [-177.279, -223.613, 580.0],
 [-175.264, -223.613, 580.0],
 [-173.549, -223.999, 581.0],
 [-171.531, -223.999, 581.0],
 [-169.513, -223.999, 581.0],
 [-167.495, -223.999, 581.0],
 [-165.761, -224.384, 582.0],
 [-163.74, -224.384, 582.0],
 [-161.718, -224.384, 582.0],
 [-159.697, -224.384, 582.0],
 [-157.946, -224.77, 583.0],
 [-155.921, -224.77, 583.0],
 [-153.896, -224.77, 583.0],
 [-151.871, -224.77, 583.0],
 [-149.847, -224.77, 583.0],
 [-147.568, -224.384, 582.0]]
Sign up to request clarification or add additional context in comments.

Comments

2

There's no problem converting to float a string of a negative number

>>> float('-5.6')
-5.6
>>> float('-531')
-531.0

Here's an example to parse a single line

>>> line = 'v -543.243 -494.262 1282'
>>> line.split()
['v', '-543.243', '-494.262', '1282']
>>> v, x, y, z = line.split()
>>> x 
'-543.243'
>>> y
'-494.262'
>>> z
'1282'

Now we convert:

>>> x = float(x)
>>> x
-543.243

Comments

0

Thanks all, that helped a lot. Below is the final code if anyone needs it.

#path='Insert Path here' 

path='/OBJS2015-12-04-20-26-38-532.txt'

print('hello world')
######################################################################################

#Open the file
try:
    f=open(path, 'r')
except:
    print ("Path is not Valid")


#Create an array of vertices

vertices = []
#vee = []
t = ()
for line in f:
    if line.startswith('v '):
        vee = [float(val) for val in line.split()[1:]]
        t = tuple(vee)
        vertices.append(t)


#Define vertices, faces, edges
verts = vertices
faces = []


#Define mesh and object
mesh = bpy.data.meshes.new("Cube")
object = bpy.data.objects.new("Cube", mesh)

#Set location and scene of object
object.location = bpy.context.scene.cursor_location
bpy.context.scene.objects.link(object)

#Create mesh
mesh.from_pydata(verts,[],faces)
mesh.update(calc_edges=True)

Comments

0

So just to add to the answers...

First off, you should exit the program in the Except clause cause it'll continue and raise a value error cause f wont be defined.

except:
    print "Invalid Path"
    exit() #Or some other way to exit

and second, assuming you correctly opened the file in read mode, shouldn't you do lines.split ('\n') to get each different line?

lines = lines.split('\n') ##Creates a list of new-lines

Again, just adding to the answers... Hopefully that helped a little!

Comments

0

For others, coming across this thread. This is also due to the usage of non-ASCII characters to represent "-". Simply fix the non-ascii character in the float representation using regex or other methods and the conversion would work. More details available at Python convert string to float error with negative numbers

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.