#!/usr/bin/env python
import time

def new_meshitem(name):
    lx.eval('item.create mesh %s' %name)
    return lx.eval('query layerservice layers ? main')

def shift_to(layer, mode):
    lx.eval(mode)
    lx.eval('select.layer %s set' %layer)
    lx.eval('paste')


t1 = time.time()

#copy source
lx.eval('select.drop polygon')
lx.eval('copy')

#create wire layer
wireLayer = new_meshitem('wire')

#create temp layer
tempLayer = new_meshitem('temp')

#set temp layer's subdivision level to 1
lx.eval('mesh.patchSubdiv 1')

#paste and freeze
lx.eval('paste')
lx.eval('poly.freeze false')
lx.eval('!vert.merge auto fixed 0.001')

#get edge info
mon = lx.Monitor()
edges = list(lx.evalN('query layerservice edges ? all'))
numedges = len(edges)
mon.init(numedges)
numverts = lx.eval('query layerservice vert.N ? all')
vpos = {}
for i in xrange(numverts):
    vpos[str(i)] = lx.eval('query layerservice vert.wpos ? %s' %i)
    
#delete source
lx.eval('delete')

#create curve layer
curveLayer = new_meshitem('curve')

#draw a 2pt curve
lx.eval('tool.set prim.curve on')
lx.eval('tool.setAttr prim.curve mode add')
lx.eval('tool.setAttr prim.curve number 0')
for i, x, y, z in [(1, 0, 0, 0), (2, 1, 0, 0)]:
    lx.eval('tool.setAttr prim.curve number %s' %i)
    lx.eval('tool.setAttr prim.curve ptX %s' %x)
    lx.eval('tool.setAttr prim.curve ptY %s' %y)
    lx.eval('tool.setAttr prim.curve ptZ %s' %z)
lx.eval('tool.doApply')
lx.eval('tool.set prim.curve off')

#make curve clones
numcopy = (numedges < 100) and numedges-1 or 99
lx.eval('tool.set poly.clone on')
lx.eval('tool.reset')
lx.eval('tool.attr gen.linear num %s' %numcopy)
lx.eval('tool.doApply')
lx.eval('tool.set poly.clone off')
shift_to(tempLayer, 'copy')

#copy and paste clone curves into temp layer and move each curve to edge's position
i = 0
while edges:
    ev1, ev2 = edges.pop()[1:-1].split(',')
    vpos1, vpos2 = vpos[ev1], vpos[ev2]
    j = i * 2
    lx.eval('vert.move %s 0 0 0 %s %s %s' %(j, vpos1[0], vpos1[1], vpos1[2]))
    lx.eval('vert.move %s 0 0 0 %s %s %s' %(j+1, vpos2[0], vpos2[1], vpos2[2]))
    i += 1
    mon.step(1)
    
    #move 100 curves to wire layer
    #This method is from Andrew Helmer's wireFrame.py
    #It's faster and safe, but i don't understand why
    if edges and i > 99:
        shift_to(wireLayer, 'cut')
        lx.eval('select.layer %s set' %curveLayer)
        numedges = len(edges)
        if numedges < 50:
            [lx.eval('select.element %s polygon add %s' %(curveLayer, j)) for j in xrange(numedges)]
        elif numedges >= 50 and numedges < 100:
            [lx.eval('select.element %s polygon add %s' %(curveLayer, j)) for j in xrange(100 - numedges)]
            lx.eval('select.invert')
        shift_to(tempLayer, 'copy')
        i = 0

shift_to(wireLayer, 'cut')

#delete temp layers
lx.eval('select.layer %s set' %tempLayer)
lx.eval('select.layer %s add' %curveLayer)
lx.eval('!item.delete')

#make curves renderable
lx.eval('select.layer %s set' %wireLayer)
lx.eval('poly.setMaterial wireframe {1.0 1.0 1.0} 0.0 0.0 true false')
lx.eval('item.channel mesh$curves true')
lx.eval('item.channel mesh$radius 0.0005')
lx.out(time.time() - t1)