Capturing pick points to a file

Revision as of 20:01, 9 May 2013 by BradWhitlock (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This page contains a Python callbacks example script that you can paste into your .visitrc file. The script captures the points that you click on with Pick and saves the coordinates to a file that builds up point array in Python. I used this script to capture points around the perimeter of an image that I was trying to model. I opened the picture in VisIt, scaled it to the desired size, and then I started picking around the perimeter and on several other points. From there, I had a point cloud that I connected into triangles in a RAW file.

Legoman.png

SavePoints Script

Here is the source for the script that you can place into your .visitrc file.

class SavePoints:
    def __init__(self, filename):
        self.filename = filename
        self.points = []

    def getpoint(self):
        lines = GetPickOutput().split("\n")
        point = None
        for line in lines:
            start = line.find("Point: <")
            if start != -1:
                s = line[start+7:]
                s = string.replace(s, "<", "")
                s = string.replace(s, ">", "")
                s = string.replace(s, ",", "")
                point = [float(x) for x in string.split(s)]
        return point
 
    def point_is_new(self, pt):
        if pt == None:
            return 0
        if pt in self.points:
            return 0
        return 1
 
    def savepoint(self, point):
        if self.point_is_new(point):
            self.points = self.points + [point]
            lines = []
            try:
                f = open(self.filename, "rt")
                lines = f.readlines()
            except:
                pass
            index = len(lines)
            lines = lines + ["p[%d] = [%lg, %lg]\n" % (index, point[0], point[1])]
            f = open(self.filename, "wt")
            for line in lines:
                f.write(line)
            f.close()

def onPickAttributes(pa, savepoints):
    point = savepoints.getpoint()
    savepoints.savepoint(point)
 
savepoints = SavePoints("points.py")
RegisterCallback("PickAttributes", onPickAttributes, savepoints)
SuppressQueryOutputOn()

Script Output

When you click around on the image in VisIt, you get a Python script that contains the points that were clicked. Here is an example of the output for the person image that I clicked on:

p[0] = [-0.237074, 0.]
p[1] = [-0.108285, 0.]
p[2] = [-0.096135, 0.0955475]
p[3] = [-0.0669752, 0.411412]
p[4] = [-0.0305255, 0.77597]
...

Writing a RAW file

After getting the initial Python file from the clicks in VisIt, I edited it so it makes a RAW file.

# Make a point list large enough for the assignments we'll do
p = []
for i in xrange(50):
   p = p + [[0,0,0]]

# This is modified script output:
zf = 0.25
zfs = 0.23
z0 = 0.09
z1 = -0.09
p[0] = [-0.237074, 0., zfs]
p[1] = [-0.108285, 0., zf]
p[2] = [-0.096135, 0.0955475, z0]
p[3] = [-0.0669752, 0.411412, z0]
p[4] = [-0.0305255, 0.77597, z0]
p[5] = [0.0205041, 0.7784, z0]
p[6] = [0.0788236, 0.399263, z0]
p[7] = [0.105553, 0.100407, z0]
p[8] = [0.115273, 0., zf]
p[9] = [0.234342, 0., zfs]
p[10] = [0.227052, 0.0931178, z0]
p[11] = [0.197893, 0.481874, z0]
p[12] = [0.151723, 0.870629, z0]
p[13] = [0.171163, 1.06987, z0]
p[14] = [0.185743, 1.27639, z0]
p[15] = [0.387431, 1.47077, z0]
p[16] = [0.256212, 1.79635, z0]
p[17] = [0.246492, 1.964, z0]
p[18] = [0.202753, 1.97372, z0]
p[19] = [0.176023, 1.78421, z0]
p[20] = [0.246492, 1.52665, z0]
p[21] = [0.163873, 1.4489, z0]
p[22] = [0.0423739, 1.4319, z0]
p[23] = [0.0350839, 1.49021, z0]
p[24] = [0.0520938, 1.58011, z0]
p[25] = [0.0472339, 1.65786, z0]
p[26] = [-0.00379575, 1.70159, z0]
p[27] = [-0.0718352, 1.70159, z0]
p[28] = [-0.122865, 1.66272, z0]
p[29] = [-0.135015, 1.57768, z0]
p[30] = [-0.103425, 1.48292, z0]
p[31] = [-0.098565, 1.42704, z0]
p[32] = [-0.222494, 1.43918, z0]
p[33] = [-0.312403, 1.5218, z0]
p[34] = [-0.229784, 1.8085, z0]
p[35] = [-0.249224, 1.94943, z0]
p[36] = [-0.288104, 1.964, z0]
p[37] = [-0.312403, 1.8085, z0]
p[38] = [-0.463062, 1.49264, z0]
p[39] = [-0.249224, 1.29583, z0]
p[40] = [-0.212774, 1.08687, z0]
p[41] = [-0.176324, 0.86577, z0]
p[42] = [-0.193334, 0.486733, z0]
p[43] = [-0.224924, 0.110126, z0]
# belt buckle
p[44] = [-0.0110857, 0.875489, z0]
# mid chest
p[45] = [-0.0280956, 1.28854, z0]
# head from chin to forehead
p[46] = [-0.0256656, 1.50236, z0]
p[47] = [-0.0256656, 1.55581, z0]
p[48] = [-0.0256656, 1.59712, z0]
p[49] = [-0.0305255, 1.65057, z0]

# Duplicate the existing points with z1
npts_in_face = len(p)
for i in xrange(npts_in_face):
    p = p + [[p[i][0], p[i][1], z1]]

# You can plot nodeid(points) of this file's point cloud to easily see the point ids,
# which will make determining triangle point ids easier.
f = open("points.3D", "wt")
f.write("X Y Z value\n")
for i in xrange(len(p)):
    f.write("%lg %lg %lg 0.\n" % (p[i][0], p[i][1], p[i][2]))
f.close()

# Come up with some triangles for the front face of the model.
tri = [0,1,43, # legs
1,2,43,
2,3,43,
3,42,43,
3,4,42,
4,41,42,
4,44,41,
4,5,44,
5,12,44,
5,11,12,
5,6,11,
6,10,11,
6,7,10,
7,8,10,
8,9,10,
41,44,40, # chest
44,13,40,
44,12,13,
40,45,39,
40,13,45,
13,14,45,
39,31,32,
39,45,31,
45,22,31,
45,14,22,
14,21,22, # start head
31,46,30,
31,22,46,
22,23,46,
30,46,47,
46,23,47,
30,47,29,
47,23,24,
29,47,48,
47,24,48,
29,48,28,
48,24,25,
28,48,49,
48,25,49,
28,49,27,
49,26,27,
49,25,26,
14,15,21, # arms
15,20,21,
15,16,19,
15,19,20,
19,16,17,
19,17,18,
38,39,32,
38,32,33,
38,33,34,
38,34,37,
34,35,36,
34,36,37]

ntri = len(tri) / 3

# Make back faces
for i in xrange(ntri):
    index = i*3
    tri = tri + [npts_in_face + tri[index+2], npts_in_face + tri[index+1], npts_in_face + tri[index]]

# Make side faces
for i in xrange(44):
    if i == 43:
        i_next = 0
    else:
        i_next = i + 1
    a = i
    b = npts_in_face + i
    c = npts_in_face + i_next
    d = i_next
    tri = tri + [a,b,c,a,c,d]
    
# Write the triangles as a RAW file.
f = open("man_lego.raw", "wt")
ntri = len(tri) / 3
s=1.04
for i in xrange(ntri):
    a = tri[i*3]
    b = tri[i*3+1]
    c = tri[i*3+2]
    f.write("%lg %lg %lg %lg %lg %lg %lg %lg %lg\n" % (p[a][2],p[a][0],s*p[a][1], p[b][2],p[b][0],s*p[b][1], p[c][2],p[c][0],s*p[c][1]))
f.close()