把Kinect扫描的点云数据导入Maya | Import Kinect point cloud to Maya

I used Skanect to scan my room down. The .ply file generated is like this:

0.614557 -0.0194625 -0.305274 -0.127814 -0.551592 0.824263 100 113 96
0.614418 -0.019946 -0.305417 -0.127814 -0.551592 0.824263 98 111 96
0.61429 0.00103368 -0.303381 0.0386538 -0.603242 0.796621 104 107 95

扫描用的工具叫Skanect,参见上一篇
导出的.ply文件大概是这样

0.614557 -0.0194625 -0.305274 -0.127814 -0.551592 0.824263 100 113 96
0.614418 -0.019946 -0.305417 -0.127814 -0.551592 0.824263 98 111 96
0.61429 0.00103368 -0.303381 0.0386538 -0.603242 0.796621 104 107 95

9 columns are x, y, z, xn(normal), yn, zn, r, g, b.
Took me a while to make it work because I didn’t know shit about Python itself or Maya Python. So if you’re in fog too I present you Python functions for Maya.

19_16_06
^result.

Notes:

Attributes have types, I forgot because Python fed me honey on this one. Stuck for a day.
emit() is buggy, it crashed the soul out of me when I used at=’rgbPP’ , use setParticleAttr() instead

Important, after importing, do ‘set current state to initial state’ and cache the first frame, otherwise the color will be gone next time you start it, this is some bullshit.

To hide part of the point cloud, select and cmds.setParticleAttr(at=’opacityPP’, fv=0).

## Maya Point Cloud (.xyz) Importer
## Format: X Y Z ,a ,a a, R, G, B for every line
## Page: http://axlarts.com/?p=1923

from maya import cmds

RES=100    # Only draw one particle for every RES lines in the file,
           # in case of huge cloud but only need reference in the scene. 


path=cmds.fileDialog2(ds=2,fm=1)[0]
f0=open(path)
n=0; pn=0
p0=cmds.nParticle()[1]
cmds.setAttr(p0+'.isDynamic',0)
cmds.addAttr(p0,ln='rgbPP',dt='vectorArray')

while 1:
    line=f0.readline().split(' ')
    n+=1
    if line[0]=='':
        break
        
    
    if n%10000==0:
        print "%d lines %d particles\n" % (n, pn)
    if n%RES!=0:
        continue

    rotted=False
    xyz=[]
    for doll in line:
        try:
            dollF=float(doll)
        except ValueError:
            rotted=True
            print '(Warning) Invalid value %s in line%d: %s' % (doll,n,line)
            break
        xyz.append(dollF)
    if len(line)!=9:
        rotted=True
    if rotted:
        continue

    for a in range(6,9):    #Just because it's x y z bla bla bla r g b in my case
        xyz[a]/=255

    cmds.emit(object=p0,position=xyz[:3])
    cmds.select(p0+'.pt['+str(pn)+']')
    cmds.setParticleAttr(at='rgbPP', vv=xyz[6:9])
    pn+=1

Additional Python script to import particles, using only the first 3 numbers everyline as x,y,z and ignoring others.
There surely is way to make this more compatible but that’s too much effort..

## Maya Point Cloud (.xyz) Importer
## Format: X Y Z for every line
## Page: http://axlarts.com/?p=1923

from maya import cmds

RES=1    # Only draw one particle for every RES lines in the file,
         # in case of huge cloud but only need reference in the scene. 

path=cmds.fileDialog2(ds=2,fm=1)[0]
f0=open(path)
n=0; pn=0
p0=cmds.nParticle()[1]
cmds.setAttr(p0+'.isDynamic',0)
cmds.addAttr(p0,ln='rgbPP',dt='vectorArray')

while 1:
    line=f0.readline().split(' ')
    n+=1
    if line[0]=='':
        break
        
    
    if n%10000==0:
        print "%d lines %d particles\n" % (n, pn)
    if n%RES!=0:
        continue

    rotted=False
    xyz=[]
    for doll in line:
        try:
            dollF=float(doll)
        except ValueError:
            rotted=True
            print '(Warning) Invalid value %s in line%d: %s' % (doll,n,line)
            break
        xyz.append(dollF)
    if len(line)<3:
        rotted=True
    if rotted:
        continue

    cmds.emit(object=p0,position=xyz[:3])
    pn+=1


9行分别是 x, y, z, xn, yn, zn, r, g, b,xn是normal方向。
所以用个脚本从文件读数据-添加粒子就行了。
搜到这里的同学估计和我半斤八两,所以我present你Maya Python函数表
19_16_06
效果图(脚本见文末)

小记:
添加attribute注意类型,Python让我忘了这茬了,卡了我半天。
emit()函数有bug,直接 at=‘rgbPP’ 的话会崩溃,要用setParticleAttr()

5/1/2013 Update:
导入以后要先set current state to initial state 然后存下首帧cache,不然颜色会丢掉。
不要的部分可以选中然后 cmds.setParticleAttr(at=’opacityPP’, fv=0) 隐藏。

## Maya Point Cloud (.xyz) Importer
## Format: X Y Z ,a ,a a, R, G, B for every line
## Page: http://axlarts.com/?p=1923

from maya import cmds

RES=100    # Only draw one particle for every RES lines in the file,
           # in case of huge cloud but only need reference in the scene. 


path=cmds.fileDialog2(ds=2,fm=1)[0]
f0=open(path)
n=0; pn=0
p0=cmds.nParticle()[1]
cmds.setAttr(p0+'.isDynamic',0)
cmds.addAttr(p0,ln='rgbPP',dt='vectorArray')

while 1:
    line=f0.readline().split(' ')
    n+=1
    if line[0]=='':
        break
        
    
    if n%10000==0:
        print "%d lines %d particles\n" % (n, pn)
    if n%RES!=0:
        continue

    rotted=False
    xyz=[]
    for doll in line:
        try:
            dollF=float(doll)
        except ValueError:
            rotted=True
            print '(Warning) Invalid value %s in line%d: %s' % (doll,n,line)
            break
        xyz.append(dollF)
    if len(line)!=9:
        rotted=True
    if rotted:
        continue

    for a in range(6,9):    #Just because it's x y z bla bla bla r g b in my case
        xyz[a]/=255

    cmds.emit(object=p0,position=xyz[:3])
    cmds.select(p0+'.pt['+str(pn)+']')
    cmds.setParticleAttr(at='rgbPP', vv=xyz[6:9])
    pn+=1

另外附加只看每行前3个数字作为xyz,忽略其他的python脚本
当然可以并成一个了但是没那闲情..

## Maya Point Cloud (.xyz) Importer
## Format: X Y Z for every line
## Page: http://axlarts.com/?p=1923

from maya import cmds

RES=1    # Only draw one particle for every RES lines in the file,
         # in case of huge cloud but only need reference in the scene. 

path=cmds.fileDialog2(ds=2,fm=1)[0]
f0=open(path)
n=0; pn=0
p0=cmds.nParticle()[1]
cmds.setAttr(p0+'.isDynamic',0)
cmds.addAttr(p0,ln='rgbPP',dt='vectorArray')

while 1:
    line=f0.readline().split(' ')
    n+=1
    if line[0]=='':
        break
        
    
    if n%10000==0:
        print "%d lines %d particles\n" % (n, pn)
    if n%RES!=0:
        continue

    rotted=False
    xyz=[]
    for doll in line:
        try:
            dollF=float(doll)
        except ValueError:
            rotted=True
            print '(Warning) Invalid value %s in line%d: %s' % (doll,n,line)
            break
        xyz.append(dollF)
    if len(line)<3:
        rotted=True
    if rotted:
        continue

    cmds.emit(object=p0,position=xyz[:3])
    pn+=1

11 thoughts on “把Kinect扫描的点云数据导入Maya | Import Kinect point cloud to Maya

  1. Dewaele

    Hello,

    I’m looking to import xyz point cloud but i have just 3
    columns for the point….

    What does it change in your script to import my file.

    Regards,

    D.D.

    Reply
    1. Viaxl Post author

      This was for my particular usage but I’ve modified a little to make it work for you. See the end of article.

      I only tested it with 5 hand-written particles so let me know if it’s good 😀

      Reply
  2. tom

    looks great, how do i specify the location of the data set in the script
    (very little python know how)

    Reply
    1. Viaxl Post author

      A window will pop up to locate the file.
      See cmds.fileDialog2()
      I know, nextgen programming indeed.

      If you mean how to embed the path in the script itself, you can do
      f0=open(‘D:/path/to/the/file’)
      also
      f0=open(‘./relative/path/to/the/scene/file’)
      will work too.

      Reply
  3. Joseph

    How to copy article from other blogs to your blog
    and make it pass copyscape test and human readable ? To find out just type in google:
    Ziakdra’s article tool

    Reply
  4. to88通盈

    影响我们人生的绝不仅仅是环境,其实是心态在控制个人的行动和思想。同时,心态也决定了一个人的视野

    Reply
  5. Dane

    If you are interested in topic: earn online by clicking vertebral fracture – you should read about Bucksflooder first

    Reply
  6. hugo

    hello,
    very interesting but I could not make it works.
    “error: invalid syntax”
    >maya 2017

    Reply
  7. B

    Hi,
    for those who got problems with using the script, there are typo errors on line 26 for the first script and lines 25 and 39 for the second one.
    the " shoud be replaced by real quotes, and the < shoud be replace by the < sign.

    Reply
    1. B

      my precedent message has been interpreted :
      so the & quot ; should be replaced by ‘
      and the & lt; should be replace by <

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.